sampotter / python-embree Goto Github PK
View Code? Open in Web Editor NEWLicense: Apache License 2.0
License: Apache License 2.0
Any idea/experience installing this library to MacOS (embree doesn't provide a embree_vars.zsh
version)?
Thanks!
fyi @gaelccc
A recent project of mine has used this library pretty extensively, I would like to cite this tool.
Is there a citation and/or a paper where you use this tool?
For example: Trimesh has this citation in their github (see bottom of page)
@software{trimesh,
author = {{Dawson-Haggerty et al.}},
title = {trimesh},
url = {https://trimsh.org/},
version = {3.2.0},
date = {2019-12-8},
}
Thank you very much @sampotter for this package. I want to install this package in ubuntu but didn't manage to build the package here.
Did anyone try this and can help me?
Thank you very much!
When I import embree there is a error:
import embree
ImportError: libembree3.so.3: cannot open shared object file: No such file or directory
I installed embree in /usr/bin/embree
with:
tar xzf embree-3.13.1.x86_64.linux.tar.gz
source embree-3.13.1.x86_64.linux/embree-vars.sh
and build the package with:
python3 setup.py build_ext -I/usr/bin/embree/embree-3.13.1.x86_64.linux/include -L /usr/bin/embree/embree-3.13.1.x86_64.linux/lib
embree.BufferType.Vertex, # buf_type
File "embree.pyx", line 528, in embree.Geometry.set_new_buffer
File "embree.pyx", line 453, in embree.array_from_ptr
File "embree.pyx", line 449, in embree.typed_mv_from_ptr
ValueError: Cannot create cython.array from NULL pointer
It seems like after processing many files, embree encounters a null ptr error.
While installing the library with pip I get the following compilation error:
Error compiling Cython file:
------------------------------------------------------------
...
def __cinit__(self):
self._device = rtcNewDevice(NULL)
# TODO: hardcode an error function until we decide on a nice
# way of exposing error functions to the library user
rtcSetDeviceErrorFunction(self._device, simple_error_function, NULL);
^
------------------------------------------------------------
embree.pyx:548:48: Cannot assign type 'void (void *, RTCError, const char *) except *' to 'RTCErrorFunction'. Exception values are incompatible. Suggest adding 'noexcept' to type 'void (void *, RTCError, const char *) except *'.
The only way I found to succesfully install the library is by commenting that line (rtcSetDeviceErrorFunction(self._device, simple_error_function, NULL);
).
I tried it with different versions of gcc (9.2, 11.2, 12.1) and I get always the same error.
Since this seems to be a Cython-related error it is worth specifying that I am using Cython 0.29.36
@sampotter I would like to use the embree lib for raycasting since it provides a nice accelerated solution. However, I am not quite sure how to use your wrapper. Would be possible to write a small example showing some use case. For example considering that someone has the indices and faces of a mesh object in numpy arrays how to create the corresponding mesh in embree by using this wrapper?
Hi! I'd like to use the library to trace illumination of a terrain from an extended source (i.e., the Sun as seen from Mercury), similarly to what done in the python-flux library .
I guess I could use a loop of intersect1M
calls with different source-points, but it would probably be far less efficient than using a RayNM
call ... any suggestion about how to implement this by tweaking the current wrappers (or informed recommendation if it is/isn't worth doing it)? Thanks!
Hi,
I have tried to use your library, it's exactly what I have been looking for for a long time, unfortunately, I am not skilled in python bindings generation and I encountered some troubles.
I have installed Embree: High-Performance Ray Tracing Kernels 3.12.2 from Embree website.
I have built it successfully (latest version, commit 1238e0e) on Windows 10, python 3.7 in mingw64 (git bash console).
Here is the build log:
$ C:/python37/python.exe setup.py build_ext -I/c/Program\ Files/Intel/Embree3/include -L /c/Program\ Files/Intel/Embree3/lib
running build_ext
building 'embree' extension
creating build
creating build\temp.win-amd64-3.7
creating build\temp.win-amd64-3.7\Release
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -I/opt/local/include "-IC:/Program Files/Intel/Embree3/include" -IC:\python37\include -IC:\python37\include "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\ATLMFC\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\winrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\cppwinrt" /Tcembree.c /Fobuild\temp.win-amd64-3.7\Release\embree.obj
embree.c
creating C:\external\python-embree\build\lib.win-amd64-3.7
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\bin\HostX86\x64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:/opt/local/lib "/LIBPATH:C:/Program Files/Intel/Embree3/lib" /LIBPATH:C:\python37\libs /LIBPATH:C:\python37\PCbuild\amd64 "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\ATLMFC\lib\x64" "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\lib\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.18362.0\ucrt\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.18362.0\um\x64" embree3.lib /EXPORT:PyInit_embree build\temp.win-amd64-3.7\Release\embree.obj /OUT:build\lib.win-amd64-3.7\embree.cp37-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.7\Release\embree.cp37-win_amd64.lib
Creating library build\temp.win-amd64-3.7\Release\embree.cp37-win_amd64.lib and object build\temp.win-amd64-3.7\Release\embree.cp37-win_amd64.exp
Generating code
Finished generating code
I have even successfully created a triangle geometry and the scene (even multiple times with deallocation), everything works until some of the Ray1M or RayHit1M objects are deallocated (freed).
Very minimalistic repro code is:
import embree
rays = embree.Ray1M(100)
and result after run is:
Process finished with exit code -1073740940 (0xC0000374) <- crash
Of course, the same problem prevails even if the Ray1M is created somewhere in the function or class and its freed after usage.
The only workaround I have found to be working is to preallocate the Ray1M big enough for the whole work done in the program and let it crash only when the program is closing.
Any Ideas what might be behind this trouble?
Best regards,
Zdenek Glazer
A common use case for this library is determining pairwise visibility between mesh elements, such as triangles.
Embree's intersect1M
or similar records the first intersection for each ray. This makes shooting a ray "from" a triangle difficult, since it can easily happen that the first intersection is just that triangle. To get around this, the start of a ray can be perturbed away from the source element, but this is a hack.
Embree provides "intersection filters" to make skipping elements possible, but they require a callback. It would be useful to allow a user to pass their own callback, either from Python or even from Cython. But it is probably more important to capture some of the common cases (such as "skip self") at the library level.
Here's a forum post on the same topic.
A simple geometry example would be good. I feel like I'm doing something wrong when creating geo:
face_size = len(self.faces[0])
geo_type = embree.GeometryType.Triangle if face_size == 3 else embree.GeometryType.Quad
self.device_prim = embree.Geometry(self.device, geo_type)
buff = self.device_prim.set_new_buffer(embree.BufferType.Vertex, 0,
embree.Format.Float3, 12, len(self.vertices))
for i in range(len(self.vertices)):
buff[i] = self.vertices[i]
indices_format = embree.Format.Uint3 if face_size == 3 else embree.Format.Uint4
indices_buff = self.device_prim.set_new_buffer(embree.BufferType.Index, 0,
indices_format, 4 * face_size,
len(self.faces))
for i in range(len(self.faces)):
indices_buff[i] = self.faces[i]
Hi,
I struggle a bit with the API of this library.
I managed to cast a ray and return the first intersection point. Unfortunately, the result is a bit imprecise (~1.01-05).
Is there a way of forcing embree
to produce more precise results?
Here is my code:
def cast_rays(mesh: trimesh.Trimesh, ray_origins: np.ndarray, ray_directions: np.ndarray) -> np.ndarray:
verts = np.array(mesh.vertices, dtype=np.float32)
faces = mesh.faces.astype(np.uint32)
device = embree.Device()
scene = device.make_scene()
geometry = device.make_geometry(embree.GeometryType.Triangle)
vertex_buffer = geometry.set_new_buffer(embree.BufferType.Vertex, 0, embree.Format.Float3,
3 * np.dtype('float32').itemsize, verts.shape[0])
vertex_buffer[:] = verts[:]
index_buffer = geometry.set_new_buffer(embree.BufferType.Index, 0, embree.Format.Uint3,
3 * np.dtype('uint32').itemsize, faces.shape[0])
index_buffer[:] = faces[:]
geometry.commit()
scene.attach_geometry(geometry)
geometry.release()
scene.commit()
rayhit = embree.RayHit1M(len(ray_origins))
rayhit.org[:] = ray_origins
rayhit.dir[:] = ray_directions
rayhit.tnear[:] = 0
rayhit.tfar[:] = np.inf
rayhit.flags[:] = 0
rayhit.geom_id[:] = embree.INVALID_GEOMETRY_ID
context = embree.IntersectContext()
scene.intersect1M(context, rayhit)
ray_inter = rayhit.geom_id != embree.INVALID_GEOMETRY_ID
prim_id = rayhit.prim_id[ray_inter]
u = rayhit.uv[:, 0][ray_inter]
v = rayhit.uv[:, 1][ray_inter]
w = 1 - u - v
pts_xyz = np.vstack(w) * mesh.triangles[prim_id][:, 0, :] + np.vstack(
u) * mesh.triangles[prim_id][:, 1, :] + np.vstack(v) * mesh.triangles[prim_id][:, 2, :]
return pts_xyz
Versions:
Hey,
do you mind if I create a conda package on conda-forge for this python package? There is some interest in at least trimesh to use this package as an interface to embree3.
Cheers,
Markus
This is probably trying to push the python interpreter past where it is designed but here's the problem.
If tracing many rays (like in a pathtracer). Calling rtcIntersect 1 ray at a time is inefficient and only single threaded. Possible solutions I see are:
(See also #7.)
To manage the lifetimes of objects, each Embree "type" provides a pair of retain and release functions, e.g. rtcRetainDevice
and rtcReleaseDevice
. See the Embree API for more details, e.g.:
The API is designed in an object-oriented manner, e.g. it contains device objects (RTCDevice type), scene objects (RTCScene type), geometry objects (RTCGeometry type), buffer objects (RTCBuffer type), and BVH objects (RTCBVH type). All objects are reference counted, and handles can be released by calling the appropriate release function (e.g. rtcReleaseDevice) or retained by incrementing the reference count (e.g. rtcRetainDevice). In general, API calls that access the same object are not thread-safe, unless specified differently. However, attaching geometries to the same scene and performing ray queries in a scene is thread-safe.
One goal of this library is to make it so that the user doesn't need to think about this. I had previously tried to strategically insert retain and release calls in the constructors and destructors of the wrapped Embree types in embree.pyx, but ran into trouble getting this to work correctly, so I just removed these calls at some point (not ideal! see #7).
Inserting a call to retain in the constructor and release in the destructor doesn't seem to be enough. Unlike a language like C++, Cython doesn't have particularly fine-grained control of object lifetimes. Let's see if we can figure out how to do this the right way in this issue.
Another option would be to delegate this to the user, forcing them to manually retain and release themselves. This is a simple way to go, but would make the library a bit less useful, IMO.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.