Calling ray_cast() on evaluated objects

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?

Not sure if it’s related but since 2.91 the Python API of the ray_cast has changed, more here

Yes, it doesn’t work well, I’ve reported it last year: https://developer.blender.org/T72113

Not sure if it’s related but since 2.91 the Python API of the ray_cast has changed, more here

Interesting, this is about scene’s ray_cast only, object level one did not change. So I tried this one and turns out it returns a valid face index. If I do the following:

_, _, _, poly_index1, obj, _ = scene.ray_cast(depsgraph, ray_origin, ray_direction)
_, _, _, poly_index2 = obj.evaluated_get(depsgraph).ray_cast(ray_origin, ray_direction)

Then I get two different values of polygon indices… So @Symstract it’s indeed broken but I’m not sure I understand the conclusion of the ticket you reported. :confused: I’ll ask there.

1 Like

Yeah, I was trying some of this now, and object wasn’t working? Not sure how it should function or what.
Am using scene for now…

do any have this issue resolved?
Im seeing this error

 raycast = scene.ray_cast(ray_origin,view_vector)
TypeError: Scene.ray_cast(): error with argument 1, "depsgraph" -  Function.depsgraph expected a Depsgraph type, not Vector

You just need to pass the depsgraph argument :slight_smile:

1 Like

I’m just noted, that ray cast ignores instances. Is it known issue?

Aha like this raycast = scene.ray_cast(depsgraph, ray_origin,view_vector)
Ive laid the method aside for now. It was for RIGUI addon and trying to get it to work for 2.8
He made a material picker using this approach, but it duplicated everything in the scene as well. In 2.79 this works flawless, in 2.8 its kinda slow. Not sure whats happening

1 Like