ray_mesh_intersect python function doesn't work as expected
Hello,
The ray_mesh_intersect function gives segmentation fault on every odd vertex, and an abnormally long list of hits for the others vertex that doesn't give seg fault. It would be much appreciated if someone can look into what is wrong. Thank you in advance!
Here is a minimal script that has this behavior with vith the sphere.obj here https://drive.google.com/file/d/1E8IPf1Ge_A-eBuUDSyh2LKous3f4d66G/view?usp=sharing
import igl
m_in_v, _, m_in_n, m_in_f, _, _ = igl.read_obj("./sphere.obj") # sphere
nv = len(m_in_v)
for i in range(nv):
print(i)
hit = igl.ray_mesh_intersect(m_in_v[i], -m_in_n[i], m_in_v, m_in_f)
Still debugging, but somehow when python sends the list of vertex positions to ray_mesh_intersect its entries are being read incorrectly w.r.t column-major and row-major.
I believe I found the issue. This line
https://github.com/libigl/libigl-python-bindings/blob/3c3a6ea8f6c95720f76c9b4d8c5a26b6c8330235/src/ray_mesh_intersect.cpp#L40
doesn't make sense. source is a single point and v should be a matrix containing vertices on rows.
Meanwhile, I'm also suspicious about this npe_matches function. It seems to be defined the NumpyEigen external dependency as simply:
#define npe_matches(x) dense_float
https://github.com/fwilliams/numpyeigen/blob/96c6356102a9f6c6eca5dd5446c4513552c12da9/src/npe.h#L115
So, the npe_matches appears to be the reason that it was returning so many hits (the vertex positions were scrambled so it was a nonsense mesh).
Unfortunately, there's another issue. The first argument m_in_v[i] is causing a memory violation. This is likely due to a bug/issue with the way that NumpyEigen creates Eigen::Maps. Perhaps, it's failing to create a valid map around the ith row and this is causing a memory issue. The hot fix is to change m_in_v[i] to m_in_v[i].copy().
Sorry for the confusion! NPE works as a preprocessing step (using a python script) during the build to generate C++ code to handle type conversion from NumPy types (runtime type info) into Eigen types (static type info) by essentially generating a giant switch statement which calls a function with your code using the proper template arguments. You can see this generated file in the build directory of your project. It will have the name foo.out.cpp corresponding to the file foo.cpp.
Since numpyeigen works using a script to generate c++ code, the npe_* macros aren't defined and your IDE will complain that it can't find these symbols. For convenience, I added a file which defines these macros in a way that your IDE won't complain (hence #define npe_matches(x) npe_float.
npe_arg(x, npe_matches(y)) should just add a runtime check to ensure that the scalar type and memory order of x match those of y. If it is causing an input array to be scrambled, then that's likely a bug. If you get a chance, could you post a minimal example as a github issue and I can try and take a look?
Thanks Francis. I'll see if I can shrink our buggy example down. In the meantime, where is npe_matches defined to have that behavior?
The code for generating the logic used by npe_matches is here and the code for parsing a matches statement is here.
That said, these may not be so informative. The easiest way to see the effect of npe_matches is to write a function in some file myfile.cpp and look at the corresponding myfile.out.cpp which is the compiled Python binding.
perhaps duplicate of #78
This is fixed by allowing src,dir to not match scalar type of v and then casting the src,dir . Not ideal as it generates more templates and gives the false impression that they matter. May need to wait until https://github.com/fwilliams/numpyeigen/issues/64 is fixed for something better.
import igl
from numpy import array
print(igl.__version__)
v = array([[0.0, 0.0, 0.0], [5.0, 0.0, 0.0], [0.0, 5.0, 0.0]], dtype=float)
f = array([[0, 1, 2]], dtype=int)
p = array([1, 1.0, 1.0], dtype=float)
dir = array([0, 0, -1], dtype=float)
params = igl.ray_mesh_intersect(p, dir, v, f)
print(params)
looks the same problem? expect t=1, get nothing:
2.5.3dev
[]
This is fixed in dev.
i get 5 on version 2.5.5dev
On Fri, Nov 24, 2023 at 7:37 AM Zac Zhuo Zhang @.***> wrote:
from igl import ray_mesh_intersect # type: ignore # It is a C++ binding.from numpy import array v = array([[-5.0, -5.0, 0.0], [5.0, -5.0, 0.0], [5.0, 5.0, 0.0], [-5.0, 5.0, 0.0]], dtype=float)f = array([[0, 1, 3], [1, 2, 3]], dtype=int) p = array([-4.0, 1.0, 5.0], dtype=float)dir = array([0, 0, -1], dtype=float) print( ray_mesh_intersect(p, dir, v, f))
looks the same problem? t =8.0 but apparent it should be 5
— Reply to this email directly, view it on GitHub https://github.com/libigl/libigl-python-bindings/issues/106#issuecomment-1825617865, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARDJGPWFEOCTR5EPEOU47TYGCIHJAVCNFSM5GDZADX2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOBSGU3DCNZYGY2Q . You are receiving this because you modified the open/close state.Message ID: @.***>
(and now it works with latest 2.5.0)
Message ID: @.***
com>