0
$\begingroup$

Tl;Dr:
I want to detect an orbit (could be pan or zoom) event from the Python API.

Longer:
If you want a bit more context, I am hiding some elements when I look through the camera. But when I move away (i.e., by orbiting), I would like these elements to be visible again.

def see_through_selected_camera():
    # Look through camera
    bpy.context.scene.camera = bpy.context.active_object
    area = next(area for area in bpy.context.screen.areas if area.type == 'VIEW_3D')
    area.spaces[0].region_3d.view_perspective = 'CAMERA'
    
    # hide curves
    objects = bpy.ops.object.select_by_type(type='CURVE')
    objects = bpy.context.selected_objects
    for obj in objects:
        obj.hide_set(True)

    # HERE I WANT TO DETECT A CHANGE IN THE ROTATION SUCH AS:
    rot = area.spaces.active.region_3d.view_rotation
    if detect_orbit_change():
        for obj in objects:
            obj.hide_set(False)

I cannot find a way to write detect_orbit_change() and detect such an event.
I was looking at msgBus but it seems like it is not triggered by changes made directly in the viewport.
It would not be ideal, but at that point, if I could just detect a mouse click I would be happy enough.

Thanks in advance, any help is appreciated!

$\endgroup$

1 Answer 1

0
$\begingroup$

I have sort of solved it this way. I am not quite happy with that though, because the UI won't respond to anything until the user orbits the camera. So I'm still hoping for better answers!

To test it create a camera, create a Cube and place it in front of it, select the camera, and run the script.

import bpy

class ModalOperator(bpy.types.Operator):
    bl_idname = "object.detect_orbit"
    bl_label = "Detect Orbit (Middle mouse click)"

    def __init__(self):
        print("Waiting for orbiting motion")

    def __del__(self):
        print("Orbiting motion done")

    def execute(self, context):
        return {'FINISHED'}

    def modal(self, context, event):
        if event.type == 'MIDDLEMOUSE':  
            hide(objects, False)
            return {'FINISHED'}
        return {'RUNNING_MODAL'}

    def invoke(self, context, event):
        self.value = event.mouse_x
        self.execute(context)

        context.window_manager.modal_handler_add(self)
        return {'RUNNING_MODAL'}

bpy.utils.register_class(ModalOperator)


def hide(objects, state):
    for obj in objects:
        obj.hide_set(state)

def see_through_selected_camera():
    # Look through camera
    bpy.context.scene.camera = bpy.context.active_object
    area = next(area for area in bpy.context.screen.areas if area.type == 'VIEW_3D')
    area.spaces[0].region_3d.view_perspective = 'CAMERA'
    
    # hide curves
    global objects
    objects = bpy.ops.object.select_by_type(type='MESH')
    objects = bpy.context.selected_objects
    hide(objects, True)

    rot = area.spaces.active.region_3d.view_rotation
    bpy.ops.object.detect_orbit('INVOKE_DEFAULT')


see_through_selected_camera()
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .