2
$\begingroup$

I'm using blender 2.79 on Ubuntu 18.04 with a dual monitor setup. I currently have my left monitor set as the main 3D view and the right one set to quad-view.

When working on a model I normally glance at the quad-view to check that everything is where they need to be. The view on the quad-view is static however... If I were to work on a different section on my main 3D view, I would have to manually set the views on the quad-view to center on the section I'm currently working on.

I noticed there is an option to lock views to the 3D cursor. This works somewhat, but not as pleasing as I need it to be.

Ideally I would like to know if there's some way I can make the quad-view to always lock on to the active object, kinda like a perma-numpad . on all quad-views.

Thank you all in advance.

$\endgroup$
2
  • 1
    $\begingroup$ I think that this may answer your question. $\endgroup$
    – Ben
    Commented Sep 9, 2018 at 1:31
  • $\begingroup$ Yes, we do have similar concerns. It seems most people use their dual monitors for different reasons as the question is 5 years old. Haha. I've tried the script and though it works, it feels hacky having to press three keys to update the viewport. Now I have the same problem as the OP there, find a way to bind the script to the select action. $\endgroup$ Commented Sep 9, 2018 at 11:11

1 Answer 1

3
+50
$\begingroup$

You could link the location and distance of your main 3d view to the quad views with Python using scene_update_post handler. The good news is that it updates the quad views every time you navigate, the bad news is that it updates the quad views every time you navigate. :) This does what you need, but also requires some processing power pretty much constantly:

import bpy
from bpy.app.handlers import persistent 

for w in bpy.data.window_managers[0].windows: # let's find what's what
    for a in w.screen.areas:
        if a.type == 'VIEW_3D':
            if len(a.spaces[0].region_quadviews) > 0: #if quadviews are active
                quad_views = a.spaces[0].region_quadviews
            else:
                main_view = a.spaces[0].region_3d

@persistent # This makes it stay if another file is opened
def update_handler(dummy):
    for every_view in quad_views:
        every_view.view_location = main_view.view_location
        every_view.view_distance = main_view.view_distance


bpy.app.handlers.scene_update_post.append(update_handler)
#bpy.app.handlers.scene_update_post.remove(update_handler)

You could just use it as an operator assigned to some shortcut so it only does it's thing once when you press a button:

bl_info = {
    "name": "Quad View Updater",
    "author": "Martynas Žiemys",
    "version": (1, 0),
    "blender": (2, 79, 0),
    "location": "shift + num .",
    "description": "...",
    "warning": "",
    "wiki_url": "",
    "category": "3d View",
    }

import bpy

class ViewSelectedPlusQuadViews(bpy.types.Operator):
    """View Selected Plus Quad Views"""
    bl_idname = "3d_view.view_selected_plus"
    bl_label = "View Selected Plus Quad Views"

    @classmethod
    def poll(cls, context):
        return True

    def execute(self, context):
        #bpy.ops.view3d.view_selected() #Maybe center selected before?
        for w in bpy.data.window_managers[0].windows: # let's find what's what
            for a in w.screen.areas:
                if a.type == 'VIEW_3D':
                    if len(a.spaces[0].region_quadviews) > 0: #if quadviews are active
                        quad_views = a.spaces[0].region_quadviews
                    else:
                        main_view = a.spaces[0].region_3d

        for every_view in quad_views:
            every_view.view_location = main_view.view_location
            every_view.view_distance = main_view.view_distance        
        return {'FINISHED'}


addon_keymaps = []
def registerKeymaps():
    wm = bpy.context.window_manager
    if wm.keyconfigs.addon:
        km = wm.keyconfigs.addon.keymaps.new(name='3D View Generic', space_type='VIEW_3D')
        kmi = km.keymap_items.new('3d_view.view_selected_plus', 'NUMPAD_PERIOD', 'PRESS', shift=True, alt=False,ctrl=False)
        addon_keymaps.append((km, kmi))


def unregisterKeymaps():
    for km, kmi in addon_keymaps:
        km.keymap_items.remove(kmi)
addon_keymaps.clear()


def register():
    registerKeymaps()
    bpy.utils.register_class(ViewSelectedPlusQuadViews)


def unregister():
    unregisterKeymaps()
    bpy.utils.unregister_class(ViewSelectedPlusQuadViews)


if __name__ == "__main__":
    register()

You could save this to a file with .py extension and install it as an add-on.

I tried to detect changes of the active object with scene_update_post handler and then view selected in the quad views, but it seems there is some bug in Blender and working with bpy.context inside the handler crashes Blender. So if you wanted to center the quad views I can only offer a method using a keyboard shortcut. There should be a way to do it automatically, but the bug prevents it. If someone is interested in this, here is the code that crashes.

You can copy this into a .py file and install it as an addon to be able to view selected in all quad vies with Shift+Numpad .:

bl_info = {
    "name": "View Selected in Quad Views",
    "author": "Martynas Žiemys",
    "version": (1, 0),
    "blender": (2, 79, 0),
    "location": "shift + num .",
    "description": "...",
    "warning": "",
    "wiki_url": "",
    "category": "3d View",
    }

import bpy

class ViewSelectedInQuadViews(bpy.types.Operator):
    """View Selected In Quad Views"""
    bl_idname = "view3d.view_selected_quad"
    bl_label = "View Selected In Quad Views"

    @classmethod
    def poll(cls, context):
        return True

    def execute(self, context):
        context = bpy.context.copy() 
        for w in bpy.data.window_managers[0].windows: # let's find what's what
            for a in w.screen.areas:
                if a.type == 'VIEW_3D':
                    if len(a.spaces[0].region_quadviews) > 0: #if quadviews are active
                        for every_region in a.regions[4:]:
                            override = context              
                            override['window'] = w
                            override['area'] = a
                            override['region'] = every_region
                            bpy.ops.view3d.view_selected(override)       
        return {'FINISHED'}



addon_keymaps = []
def registerKeymaps():
    wm = bpy.context.window_manager
    if wm.keyconfigs.addon:
        km = wm.keyconfigs.addon.keymaps.new(name='3D View Generic', space_type='VIEW_3D')
        kmi = km.keymap_items.new('view3d.view_selected_quad', 'NUMPAD_PERIOD', 'PRESS', shift=True, alt=False,ctrl=False)
        addon_keymaps.append((km, kmi))


def unregisterKeymaps():
    for km, kmi in addon_keymaps:
        km.keymap_items.remove(kmi)
addon_keymaps.clear()


def register():
    bpy.utils.register_class(ViewSelectedInQuadViews)
    registerKeymaps()

def unregister():
    unregisterKeymaps()
    bpy.utils.unregister_class(ViewSelectedInQuadViews)


if __name__ == "__main__":
    register()
$\endgroup$
6
  • $\begingroup$ Great work! Thank you for taking your time to do this. I tried running the add-on version as I can't figure out how to run the first snippet and I have a few questions and maybe perhaps a request... is that OK? $\endgroup$ Commented Sep 11, 2018 at 13:06
  • $\begingroup$ You just need to paste the code to a new text block in the Text Editor in Blender and hit Run Script on the Text Editor's header. Please feel free to ask - I will help if I can. $\endgroup$ Commented Sep 11, 2018 at 13:14
  • $\begingroup$ Huh, that's what I did, but I wasn't seeing anything change in the viewport. Could it be made so that the Ortho view's zoom level doesn't have to be based off of the main 3d view? Ideally it should look like I pressed on num . manually on the Ortho views. i.e centered and taking up the whole screen. $\endgroup$ Commented Sep 11, 2018 at 17:15
  • $\begingroup$ I added the code for an add-on that centers selection in all quad views if you hit Shift+Numpad . to my answer. $\endgroup$ Commented Sep 12, 2018 at 10:19
  • $\begingroup$ Your updated script is just brilliant. Thank you! $\endgroup$ Commented Sep 12, 2018 at 12:51

You must log in to answer this question.

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