5
$\begingroup$

I'd like to write a script to automate viewport draw mode switching when navigating the viewport. Could this be done with, say, a modal operator? I haven't written any modal operators before, so before I go all Don Quixote on this thing, I'd like to know if this is even possible.

So, can view3d.rotate(), view3d.move(), etc., be intercepted in such a way as to change the viewport to bounding box draw mode automatically whenever the viewport is being navigated?

Also, I've looked at the documentation on modal operators and I couldn't really understand it. Maybe someone could help me understand the functions and how they work together?

$\endgroup$

1 Answer 1

3
$\begingroup$

Switch shading mode while navigating the 3D View

import bpy

class VIEW3D_OT_View_box_orbit(bpy.types.Operator):
    """Switch shading mode while navigating the 3D View"""
    bl_idname = "view3d.navigate_shade_switch"
    bl_label = "Navigating Toggled Shading"

    nav_mode = bpy.props.EnumProperty(name = "Navigation", items=[
        ("rotate", "Rotate", "Rotate the view"),
        ("move", "Move", "Move the view"),
        ("zoom", "Zoom", "Zoom in/out in the view"),
        ("dolly", "Dolly", "Dolly in/out in the view"),
        ("fly", "Fly", "Interactively fly around the scene"),
    ])
    shade_mode = bpy.props.EnumProperty(name = "Shading", items=[
        ("BOUNDBOX", "Bounding Box", "Display the object's local bounding boxes only", "BBOX", 1),
        ("WIREFRAME", "Wireframe", "Display the object as wire edges", "WIRE", 2),
        ("SOLID", "Solid", "Display the object solid, lit with default OpenGL lights", "SOLID", 3),
        ("TEXTURED", "Textured", "Display the object solid, with a texture", "POTATO", 4),
        ("MATERIAL", "Material", "Display objects solid, with GLSL material", "MATERIAL", 5),
        ("RENDERED", "Rendered", "Display render preview", "SMOOTH", 6),
    ])

    def modal(self, context, event):
        if not hasattr(self, "navigating"):
            self.navigating = True
            getattr(bpy.ops.view3d, self.nav_mode)("INVOKE_DEFAULT")
            return {"RUNNING_MODAL"}
        elif event.type == "TIMER":
            return {"RUNNING_MODAL"}
        context.space_data.viewport_shade = self.shading
        return {"FINISHED"}

    def invoke(self, context, event):
        v3d = context.space_data
        if v3d.type == "VIEW_3D":
            self.shading = v3d.viewport_shade
            try:
                v3d.viewport_shade = self.shade_mode
            except TypeError:
                pass # Shading mode not supported.
            context.window_manager.modal_handler_add(self)
            return {"RUNNING_MODAL"}
        return {"CANCELLED"}

bpy.utils.register_class(VIEW3D_OT_View_box_orbit)
$\endgroup$
5
  • $\begingroup$ Hmm... this doesn't seem to be working for me. When I run the operator it quickly switches to bounding box then back. $\endgroup$
    – CharlesL
    Commented Jul 21, 2013 at 0:39
  • $\begingroup$ @Aldrik - Hey that's neat, thank you; it works just fine here. I could make that into a hotkey I guess! :) I don't understand the functions, though. What is context.window_manage.modal_handler_add(self) doing, exactly? And how are the two functions working together? $\endgroup$ Commented Jul 21, 2013 at 1:37
  • $\begingroup$ @swingsoneto It appends self to the modal handlers, which causes Blender to call the modal method repeatedly. The first time we call rotate (which appends itself and runs repeatedly), when that completes it's called again and shading's reset. $\endgroup$
    – Aldrik
    Commented Jul 21, 2013 at 3:00
  • $\begingroup$ @CharlesL There does seem to be some issue depending on how the script is invoked. eg. If using the Search Menu you need to click it (instead of return). Could do with a better way to detect that the navigation operator has finished but for the expected use case (key binding) this works well enough. $\endgroup$
    – Aldrik
    Commented Jul 21, 2013 at 12:50
  • $\begingroup$ Alt+LMB Press works just fine! Great for cycles' rendered preview. BTW: A macro might work here? blender.stackexchange.com/a/3037/1363 $\endgroup$
    – CodeManX
    Commented Sep 30, 2013 at 22:31

You must log in to answer this question.

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