Page MenuHome

Object.ray_cast (and all RNA functions using "ob->runtime") broken in Blender 2.80
Closed, ResolvedPublic

Description

System Information
Operating system and graphics card
macOS X Mojave with GTX 980

Blender Version
Broken: 2.80. 59f0db430a9
Worked: no solution

Short description of error

Object.ray_cast is broken in Blender 2.80.

I have attached a blend that contains a simple ray_cast that works in 2.79 and fails in 2.80. Run blender from a console to see the error messages.

Exact steps for others to reproduce the error
Click Run Script to see the result of ray_cast in Blender 2.80

Event Timeline

This comment was removed by Kofi Garbrah (kgarbrah).
Philipp Oeser (lichtwerk) triaged this task as Confirmed priority.Nov 16 2018, 10:42 AM
Philipp Oeser (lichtwerk) claimed this task.

Confirmed, will have a look...

Hm, seems like since the removal of DerrivedMesh from RNA (rB79615c5adb46) there are a couple of issues.
Checked rna_object_api() and all RNA functions using ob->runtime fail.

rna_Object_ray_cast():

  • fails (says "Object 'bla' has no mesh data to be used for ray casting")

rna_Object_closest_point_on_mesh():

  • fails (says "Object 'bla' has no mesh data to be used for finding nearest point")

rna_Object_me_eval_info():

  • bpy.context.selected_objects[0].dm_info("SOURCE") is OK (uses ob->data directly)
  • bpy.context.selected_objects[0].dm_info("DEFORM") fails (returns empty string)
  • bpy.context.selected_objects[0].dm_info("FINAL") fails (returns empty string)

@Bastien Montagne (mont29): any ideas here (assigning to you first)?
or maybe @Brecht Van Lommel (brecht) can comment?


@Kofi Garbrah (kgarbrah): As a (temporary) workaround for this report you can create a BVH manually and raycast that:

from mathutils import Vector
from mathutils import Matrix
from math import *
from mathutils.bvhtree import BVHTree

def bvhtree_from_object(ob):
    import bmesh
    bm = bmesh.new()

    mesh = ob.to_mesh(bpy.context.depsgraph, True)
    bm.from_mesh(mesh)
    bm.transform(ob.matrix_world)

    bvhtree = BVHTree.FromBMesh(bm)
    bpy.data.meshes.remove(mesh)
    return bvhtree

mesh = None
for obj in bpy.context.selected_objects:
    if obj.type == "MESH":
        mesh = obj

if mesh == None:
    bpy.ops.mesh.primitive_cube_add(location=(0,0,0))
    for obj in bpy.context.selected_objects:
        if obj.type == "MESH":
            mesh = obj

startRay = Vector((-2,-2,-2))
endRay = Vector((2,2,2))

p = endRay - startRay
distance = sqrt(p.dot(p))
direction = p / distance

print( "start", startRay, "end", endRay, "distance", distance, "direction", direction )

bvhtree = bvhtree_from_object(mesh)

ray = bvhtree.ray_cast( startRay, direction, distance )

print( "Hits:", ray )
Philipp Oeser (lichtwerk) renamed this task from Object.ray_cast broken in Blender 2.80 to Object.ray_cast (and all RNA functions using "ob->runtime") broken in Blender 2.80.Nov 16 2018, 12:21 PM

Imho there is no bug here… that has more to see with how blender/depsgraph/CoW work now in 2.8. Original data (from Main, of bpy.data in python) is not supposed to have evaluated stuff, although we do 'backport' a few things for objects…

You should use context's despgraph object, something like:

start_ray = (-2, -2, -2)
dir_ray = (1, 0, 0)

depsgraph = bpy.context.depsgraph
for obj in bpy.context.selected_objects:
    if obj.type == "MESH":
        obj_eval = depsgraph.objects.get(obj.name, None)
        if obj_eval is not None:
            print(obj_eval.ray_cast(start_ray, dir_ray))

I would expect this ray cast function to get a depsgraph parameter, which it will then look up the object in. That will at least make it more clear to users what is missing.

Kofi Garbrah (kgarbrah) closed this task as Resolved.EditedNov 16 2018, 3:05 PM

Thanks for the workarounds! I've marked this as resolved.

We can even use depsgraph from context, in fact, should work perfect for 99% of usecases ;)

Just tested it with the daily build (blender-2.80-e4dbfe0a98c1-linux-glibc224-x86_64) and repeatedly ray casting on the bvh now works but if I invoke the operator again (and create a new bvh from the same object) I get a segmentation fault. I'll create a separate bug report that references this one just in case this is not related.