1
$\begingroup$

My modal addon is using raycast, I've taken a function from Blender python templates: everything worked fine. However when I try to add my addon to Add menu (VIEW3D_MT_add), it starts to act weird: I think that the issue is with contexts, but I don't know how to solve this.

Here's a stripped down test code:

import bpy

bl_info = {
"name": "Test Addon", 
"category": "Object",
"version": (0, 0, 1),
"blender": (2, 80, 0),}

class OBJECT_OT_my_addon(bpy.types.Operator):
    bl_idname = "object.my_addon"
    bl_label = "My Addon Name"
    bl_options = {"REGISTER", "UNDO"}

    def invoke(self, context, event):
      print(context.region_data)
      return {'FINISHED'}

def menu_func(self, context):
    # self.layout.operator_context = 'INVOKE_DEFAULT'
    self.layout.operator("object.my_addon")

def register():
    bpy.utils.register_class(OBJECT_OT_my_addon)
    bpy.types.VIEW3D_MT_add.append(menu_func)

def unregister():
    bpy.utils.unregister_class(OBJECT_OT_my_addon)
    bpy.types.VIEW3D_MT_add.remove(menu_func)

context.region_data is needed for raycast, so this addon prints it out.

When I run it from Viewport Add menu, it prints out RegionView3D: everything is fine. However if I run it from Shift+A Add menu, I'm getting an error:

ERROR (wm.operator): c:\b\win64_cmake_vs2017\win64_cmake_vs2017\blender.git\source\blender\windowmanager\intern\wm_event_system.c:1486 wm_operator_invoke: invalid operator call 'OBJECT_OT_my_addon'

if I uncomment the self.layout.operator_context = 'INVOKE_DEFAULT' in menu_func, it starts working fine from the Shift+A menu and prints out RegionView3D, but! if I run it from Viewport Add menu it prints None and my raycast doesn't work.

$\endgroup$
2
$\begingroup$

The menu is in the header region

Put together this for prior version of this question. Can also get the region 3d view from space_data.region_3d or area.spaces.active.region_3d

When invoked from the header the region will be the header.

import bpy
from bpy_extras import view3d_utils
from mathutils import Vector

bl_info = {
"name": "Test Addon", 
"category": "Object",
"version": (0, 0, 1),
"blender": (2, 80, 0),}

def get_v(context, event):
    scene = context.scene
    area = context.area
    region = area.regions[-1] # or search for region.type == 'WINDOW'
    space = area.spaces.active
    rv3d = space.region_3d
    print(context.region.type, rv3d == context.region_data) # See Output
    coord = event.mouse_region_x, event.mouse_region_y

    print(region, rv3d, coord)

class OBJECT_OT_my_addon(bpy.types.Operator):
    bl_idname = "object.my_addon"
    bl_label = "My Addon Name"
    bl_options = {"REGISTER", "UNDO"}

    def invoke(self, context, event):
      print(get_v(context, event))
      return {'FINISHED'}

def menu_func(self, context):
    self.layout.operator_context = 'INVOKE_DEFAULT'
    self.layout.operator("object.my_addon")

def register():
    bpy.utils.register_class(OBJECT_OT_my_addon)
    bpy.types.VIEW3D_MT_add.append(menu_func)

def unregister():
    bpy.utils.unregister_class(OBJECT_OT_my_addon)
    bpy.types.VIEW3D_MT_add.remove(menu_func)

if __name__ == "__main__":
    register()

The See Output print above from header menu

HEADER False

and from shiftA menu

WINDOW True

To sum up, only use context.region_data if you are sure you are in the 3D view window. Python console code, a is a view3d area

>>> a.type
'VIEW_3D'

>>> for r in a.regions:
...     r.type
...     
'TOOL_HEADER'
'HEADER'
'TOOLS'
'UI'
'WINDOW'

Another method would be to use 'INVOKE_REGION_WIN' as the operator context, to make sure the 'WINDOW' region is used.

| improve this answer | |
$\endgroup$
  • $\begingroup$ Aaah. Ooohh!! Thank you! Both menus and raycast work now $\endgroup$ – Sergey Kritskiy Mar 29 at 13:59
  • 1
    $\begingroup$ @batFinger Tried to come up with a more specific title for the question - feel free to replace it if you have a better one. $\endgroup$ – Ray Mairlot Mar 29 at 16:45
  • 1
    $\begingroup$ Will do. @SergeyKritskiy prob should mention INVOKE_REGION_WIN prob fixes this too. $\endgroup$ – batFINGER Mar 29 at 16:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.