I've asked a very similar question yesterday, but I have a more concrete example here. I'm using the template "Operator Modal View3d Raycast" with some modifications:
class ViewOperatorRayCast(bpy.types.Operator):
bl_idname = "view3d.modal_operator_raycast"
bl_label = "RayCast View Operator"
def modal(self, context, event):
if context.space_data.type != 'VIEW_3D': # This doesn't work
return {'PASS_THROUGH'} # This doesn't work
if event.type == 'RIGHTMOUSE' and event.value == 'PRESS': # The operator only does any thing for RMB
main(context, event) # This is where the raycasting goes on. See the template
return {'RUNNING_MODAL'}
elif event.type in {'ESC'}:
return {'CANCELLED'}
return {'PASS_THROUGH'} # I want the operator to keep going
def invoke(self, context, event):
if context.space_data.type == 'VIEW_3D':
context.window_manager.modal_handler_add(self)
return {'RUNNING_MODAL'}
else:
self.report({'WARNING'}, "Active space must be a View3d")
return {'CANCELLED'}
def Execute(self, context)
return {'RUNNING_MODAL'}
I can start the operator fine by pressing F3:
But I would like to start the operator from python. I have tried by adding the execute method, but this doesn't work since the context is either the text editor or console (not the view3d). I got the idea of using execute here (top link), but he just mentions the problem with context and not the resolution - if any:
https://www.youtube.com/watch?v=A8S-s7tuTdY (about 15:30) Constantly running modal operator (also have some of what I seek)
Is it possible to trick Blender to think that I called the operator from view3d or something like that?