Bpy.context.region_data always NonType

I am taking reference from Stack Exchange to get corresponding 3D location on a mesh
from 2D rendered image.

According to documentation,

rv3d = context.region_data

But when I run the function, rv3d is always NonType. Can anyone give any suggestion of usage here please? Much thanks.

My implementation is as following,

import bpy
from bpy_extras.view3d_utils import location_3d_to_region_2d
from bpy_extras.view3d_utils import region_2d_to_origin_3d
from bpy_extras.view3d_utils import region_2d_to_vector_3d
from mathutils.bvhtree import BVHTree

def project_2d_to_ray(context, point_px):
    region = context.region
    rv3d = context.space_data.region_3d#context.region_data

    ray_origin = region_2d_to_origin_3d(region, rv3d, point_px)
    ray_vector = region_2d_to_vector_3d(region, rv3d, point_px)

    return ray_origin, ray_vector

if __name__ == '__main__':
    cam = bpy.context.scene.camera
    frame = cam.data.view_frame(bpy.context.scene)
    bpy.data.objects['Cube'].select = True
    # Its in local space so transform to global
    frame = [cam.matrix_world * corner for corner in frame]

    # Transform into screenspace
    region = bpy.context.region
    rv3d = bpy.context.region_data
    frame_px = [location_3d_to_region_2d(region, rv3d, corner) for corner in frame]

    bvhtree = BVHTree.FromObject(bpy.context.active_object, bpy.context.scene)
    ray_origin, ray_direction = project_2d_to_ray(bpy.context, [200,200])
    location, normal, index, dist = bvhtree.ray_cast(ray_origin, ray_direction)
    print(location)

See if this works:

rv3d = bpy.context.space_data.region_3d

Unfortunately, this does not work either. In 2.79, it seems bpy.context.space_data is already NonType, so
1)

rv3d = context.space_data.region_3d

generates error

AttributeError: 'NoneType' object has no attribute 'region_3d'

or 2)

region = bpy.context.region
rv3d = bpy.context.region_data
ray_origin = region_2d_to_origin_3d(region, rv3d, point_px)

generates error

File "\Anaconda3\2.79\scripts\modules\bpy_extras\view3d_utils.py", line 93, in 
region_2d_to_origin_3d
   viewinv = rv3d.view_matrix.inverted()
AttributeError: 'NoneType' object has no attribute 'view_matrix'

I think the problem is your context. Maybe you’re ruining the script from the script editor and in this case the script editor has no ‘region_3d’.
If you run this in the script editor:

import bpy

class SimpleOperator(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.simple_operator"
    bl_label = "Simple Operator"

    @classmethod
    def poll(cls, context):
        return bpy.context.area.type == "VIEW_3D"

    def execute(self, context):
        print(bpy.context.space_data.region_3d)
        return {'FINISHED'}


def register():
    bpy.utils.register_class(SimpleOperator)


def unregister():
    bpy.utils.unregister_class(SimpleOperator)

if __name__ == "__main__":
    register()

and then in the 3d view you press F3 or whatever is your button for “Operator search…” and execute “Simple Operator”.
In your console you should get something like: “<bpy_struct, RegionView3D at 0x000002E85AB49B38>”

You can have a look at this thread for casting a ray from the camera.

Yes, that’s the issue! Thanks a lot.

I tried to set bpy.context.area.type before. However, I hope to run my script in a terminal without opening a Blender UI which causes bpy.context.area to be NoneType. Since bpy is intended to be run in Blender, I think I have to split my script into two and run them in a pipeline.

Hi I know this is a solved thread. But I have a very similar problem. I am trying to run the template “operator_modal_view3d_raycast.py”. But I want it to keep running and only do something (in the main ray cast method) when I use the RMB in the 3d view:

class MY_MODAL_OT_ray_cast(bpy.types.Operator):        

    bl_idname = "wm.ray_cast"
    bl_label = "Ray cast"
    bl_options = {'REGISTER', 'UNDO'} 
    
    def execute(self, context):        
        context.window_manager.modal_handler_add(self)
        return {'RUNNING_MODAL'}   
    
    def modal(self, context, event):
        
        if event.type == 'RIGHTMOUSE' and event.value == 'PRESS':
            
            main(context, event)  # This is the raycast method which does the heavy work     
            return {'RUNNING_MODAL'}
        
        elif event.type == 'ESC':
            return {'CANCELLED'}

        return {'PASS_THROUGH'}

The problem is that the main function needs the correct context:

scene = context.scene
region = context.region  
rv3d = context.region_data # THIS IS WHERE I'M STUCK!
coord = event.mouse_region_x, event.mouse_region_y

view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)

I need to call the operator from a script, which means that the context is wrong. I works fine if I call the operator in the 3d view with F3. I tried to overwrite the area, prior to calling the operator:

override = None
for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        override = bpy.context.copy()
        override['area'] = area
        break

#override['region'] = 'WINDOW' # DOESN'T WORK
#override['region_data'] = 'WINDOW' # DOESN'T WORK
bpy.ops.wm.ray_cast(override)

But this only fixed the area. I still have a None region_data like the original question. I’m not sure how it was fixed, but I do need to run my addon in Blender, so I need some fix to my context. Any ideas?