Page MenuHome

Fix T79127: crash on `scene.ray_cast()` with non-viewport view layer
ClosedPublic

Authored by Sybren A. Stüvel (sybren) on Aug 5 2020, 4:49 PM.

Details

Summary

The rna_Scene_ray_cast() function tried to find the current depsgraph. To this end, it required the scene, the view layer, and bmain. Scene has a cache of per-view-layer depsgraphs, to speed up switching between view layers. This cache does not contain render depsgraphs, and evaluated view layers also don't have a depsgraph here.

When a suitable depsgraph cannot be found, a new depsgraph is created. However, this depsgraph is not evaluated, and has an unexpanded scene pointer with a NULL view_layer. Using this then crashes Blender. Also, there was no way for the code to get the render depsgraph.

The solution is to pass the depsgraph to the ray_cast() function, instead of the view layer. This avoids the depsgraph lookup, and also works correctly when rendering.

Example file for testing:

Either press F12 to render or press Space in the viewport to animate, and notice how Blender doesn't crash.

The script was updated for the new API:

import bpy

def frame_change_post(scene, depsgraph):
    camera = depsgraph.scene_eval.camera
    for object_instance in depsgraph.object_instances:
        eval = object_instance.object
        if not eval.name == 'Empty':
            continue
        print("empty found")
        coord = object_instance.matrix_world @ eval.location
        dir = (coord - camera.location).normalized()
        hit, hit_loc, hit_normal, hit_index, hit_obj, hit_matrix = scene.ray_cast(
            depsgraph, camera.location, dir)
        print(hit)


bpy.app.handlers.frame_change_post.append(frame_change_post)

Note how scene.ray_cast() now takes depsgraph as the first parameter (instead of depsgraph.view_layer_eval).

Diff Detail

Repository
rB Blender