[solved] Adding new objects from Python while in local-view

In 2.8 how should addons add new objects while the user is in local-view mode and have them show up immediately?

In 2.7x this was accomplished by calling layers_from_view on the newly added object: https://docs.blender.org/api/current/bpy.types.ObjectBase.html?highlight=layers_from_view#bpy.types.ObjectBase.layers_from_view

Example Scenario:

  • User is focused on a particular object in local-view
  • User invokes an addon to wrap the selected object in a new Lattice object
    lattice = bpy.data.lattices.new('dc_lattice')
    lattice_object = bpy.data.objects.new('dc_lattice', lattice)
  • This new lattice object should be visible in local-view immediately (as-if the user had selected both objects before going into local-view)

The api no longer seems to exist and I’m unable to find an equivalent when searching. Should the addon manually go in/out of local-view mode and perform the selection itself?

Note: Objects added by calls to bpy.ops.mesh.primitive_* are shown in local view immediately. Somehow, intentionally or not, they are handling this mode (which is a good thing™)

1 Like

Well for now I’m doing the following inside the op:

    # Toggle out of local-view mode and re-enter to ensure lattice shows up
    if context.space_data.local_view is not None:
        bpy.ops.view3d.localview()
        lattice_object.select_set(True)
        bpy.ops.view3d.localview()

Bumping this.
Local view - as is - is unusable for any addons creating and appending objects.

What would be great to have is:

  1. the ability to add objects to local view, perhaps by linking them similar to collections
  2. without that, at least have the option to turn of viewport movement, then we could at least use the hack above.
3 Likes

There is now a “frame_selected” boolean on the api call. Using localview(frame_selected=False) for both of the calls in workaround above will get the desired behavior for instance.

https://developer.blender.org/rB5df82b60d1dfe980a0314518143349dd918e0e9f

1 Like

Yep, it’s working great now, thanks!

This will also maintain the selection states:

def update_local_view(context):
    if context.space_data.local_view:
        visible = [(obj, obj.select_get()) for obj in context.visible_objects]

        bpy.ops.view3d.localview(frame_selected=False)

        for obj, _ in visible:
            obj.select_set(True)

        bpy.ops.view3d.localview(frame_selected=False)

        for obj, sel in visible:
            obj.select_set(sel)

It’s now possible to add and remove objects to and from local view, see https://developer.blender.org/rBaf0ab15e1dd84aadb32ee8d7a836a08fe6251474

Thanks @ideasman42 and @dfelinto!

2 Likes

Indeed! I actually saw the checkin but completely missed the new api lol. Thanks for keeping the thread going :slight_smile:

you need a get and a set to “detect”

def get_local_view(self):    
    areas = bpy.context.workspace.screens[0].areas               
    for area in areas:
        for space in area.spaces:    
            if space.type == 'VIEW_3D':
                r=not space.local_view  #wow strange but working 
                return not r

def set_local_view(self, value):
    
    areas = bpy.context.workspace.screens[0].areas               
    for area in areas:
        for space in area.spaces:    
            if space.type == 'VIEW_3D':
                value=(not space.local_view)
def update_local_view(self, context):
    
    areas = context.workspace.screens[0].areas
    for area in areas:
        for space in area.spaces:
            if space.type == 'VIEW_3D': 
                if space.local_view:
                    context.scene.local_view 
                    bpy.ops.view3d.localview(frame_selected=False)
                else:
                    context.scene.local_view 
                    bpy.ops.view3d.localview(frame_selected=False)

bpy.types.Scene.local_view = bpy.props.BoolProperty(get=get_local_view, set=set_local_view, update=update_local_view)

in your menu

row.prop(context.scene, "local_view", text="/", toggle=True

and now the state is automatically detected in your menu

Probably I might be missing something but the new functions don’t work for me. All objects print False in Local View mode.

for area in bpy.context.screen.areas:
    for space in area.spaces:
        if space.type == 'VIEW_3D':
            for obj in bpy.context.scene.objects:
                print(obj.local_view_get(space))

Bumping this thread, as I’m seeing the exact same result as @Dogway. What is the intended usage of local_view_get()? It always returns false, regardless of the space passed in or localview state of the object?

definitely smells like a bug to me
image