Hello,
I am not sure whether this is a bug or my misuse of the API, but I cannot have the Object.ray_cast
method to work on evaluated objects. The returned location is correct, but apparently not the polygon index. Here is a minimal reproduction case: (also available as a .blend)
import bpy
from mathutils import Vector
from mathutils.interpolate import poly_3d_calc
context = bpy.context
# Get the evaluated cube, i.e. with modifiers applied
# (for instance a triangularize + a subsurf modifier on the base cube)
depsgraph = context.evaluated_depsgraph_get()
depsgraph.update() # just in case
obj = bpy.data.objects['Cube'].evaluated_get(depsgraph)
# Cast a ray
ray_origin = Vector((-5, 0, 0))
ray_direction = Vector((1, 0, 0))
success, location, normal, poly_index = obj.ray_cast(ray_origin, ray_direction)
assert(success)
# Get hit polygon (within the evaliated object, again)
mesh = obj.data
poly = mesh.polygons[poly_index]
# Get corners and compute the barycentric coordinates of the hit point
# with respect to these corners
corners = [mesh.vertices[vid].co for vid in poly.vertices]
bcoords = poly_3d_calc(corners, location)
# Multiplying corner positions by these barycentric coords should
# reconstruct back the very same location
check_location = sum([b * c for b, c in zip(bcoords, corners)], Vector((0,0,0)))
error = (check_location - location).magnitude
print(f"error: {error}")
The printed error is huge. Actually, addind some debug shows that the returned index is totally incorrect, or at least should not be interpreted as I did:
(Red spheres are locations from the corners
array, blue sphere is the hit location – this one is correct.)
I also tried assuming it is an index within the loop_triangles array, but results weren’t any better.
So, am I misusing the values returned by ray_cast
or should I report this as a bug?