Page MenuHome

Python: bvh.ray_cast doesn't find a plane facing in the other direction under certain circumstances
Closed, ResolvedPublic


System Information
Windows 7 64 bit
Nvidia Quadro 600

Blender Version
Broken: bfdb420

Short description of error
The ray_cast function returns (None, None, ..) although there is a polygon.

In the file is a python script, when you execute it you will find that it prints "None" in the Console, but instead it should print "<Vector (4.0000, 0.0000, 0.0000)>"

There are multiple things you can do so that the function finds the plane:

  • Rotate the plane around the z axis so that the normal points to the center ( >= 90 degree)
  • Move the plane a bit on the Y or Z axis
  • Change the direction parameter a bit. eg from Vector((1, 0, 0)) -> Vector((1, 0.00001, 0))
  • Change the ray start parameter a bit (not on the X axis)

Event Timeline

Jacques Lucke (JacquesLucke) updated the task description. (Show Details)
Jacques Lucke (JacquesLucke) raised the priority of this task from to Needs Triage by Developer.
Bastien Montagne (mont29) triaged this task as Normal priority.Oct 18 2015, 11:51 AM

There is also another thing you can do here - increase epsilon of bvhtree (even such a small value as 1e-9 is enough)…

Will check further what happens here, but this may be due to numeric instability/imprecision, which is precisely why non-zero epsilon is usually needed. ;)

OK, so issue is with isect_ray_tri_watertight_v3() not detecting rayhit on a border (remember your square is split in two triangles, which means your ray would hit exactly on the limit between those two tris).

Now, I won’t pretend to understand that dark piece of art of black magic that is watertight, so will let @Sergey Sharybin (sergey) decide whether this is known limitation/expected behavior, or actual real bug.

Watertight intersection is aimed to solve issues caused by ray hitting exact edge. There's one difference from the original paper which is fallback to double precision in the cease if U == 0.0f || V == 0.0f || W == 0.0f. We don't do this in Cycles because doubles aren't available in consumer GPUs and doing float to double precision conversion is not really cheap. But here i think we should implement such a fallback.

Tested and even after adding the double fallback its still returning None, see: P274