2022-06-14 Library Overrides Status Update

Attendants: Bastien Montagne, Dalai Felinto, Julian Eisel

We got together to assess the current status of library overrides, and identify what can be improved when it comes to usability, before we start with the “cherry-picked” properties project.

There are three places a user can create an override from:

  • Viewport
  • Properties Editor
  • Outliner

For the user the result is supposed to be the same. In some rare cases where the context leads to ambiguity (e.g., an object is linked into multiple collections), the operation should fail.

There is one main “operator” (currently named “Make Override Hierarchy”). At the moment there is another one (Make Library Override - Fully Editable), which will be removed once we have the “cherry-pick” options.

Outliner:

  • Outliner Hierarchies revert order.
    • Follow the “View Layer” hierarchy (collection > objects > children).
  • Use warning for actual warnings
    • Right now the “re-sync for better performance” should be an Info instead.
      image
  • Remove “Single” options
    • Double-check with Andy Goralczyk.
  • Fix System Overrides filter check (e.g., for Project Heist).
  • Fix “double-click” on Outliner Properties throwing an error.

Other topics:

  • Consider to have only " Make Library Override Hierarchy Full Editable"
    • Check with Andy, the idea is to do this even before we have the cherry-pick implemented.
  • Fix: Make Library override from data-block widget in the properties editor.
    • Replace the collection by the overridden collection.
  • Instance Collection disable by default.
    • Check with Andy Goralczyk (he advocated for the current option in one of his early feedback sessions).
  • “Make Instance Face” should be removed or documented.
    • Check with Campbell Barton (358c9566379)
    • If we are to keep it there, we still need to separate it from the Library overrides.
  • Viewport > Object > Relations
    • This strikes as a strange name for the category.
  • Viewport > Object > Relations > Make Library Override.
    • No need for search.
    • To throw an error if there is ambiguity in the hierarchy.

Random example of overwhelming options:
image

Those options are left for a future discussion.

2 Likes

Hello all, I don’t think we’ve met before. This thread is my cuppa tea especially as I’m attempting to add characters via python in 3.2. I’ve had some experience setting up pipelines before and replying so I can track this conversation. Excited to see this part of blender getting thought through so well.

anyway, the error that brought me here:

 bpy.ops.outliner.id_operation(override, type='OVERRIDE_LIBRARY_CREATE_HIERARCHY')


  File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\modules\bpy\ops.py", line 113, in __call__
    ret = _op_call(self.idname_py(), C_dict, kw, C_exec, C_undo)

TypeError: Converting py args to operator properties:  enum "OVERRIDE_LIBRARY_CREATE_HIERARCHY" not found in ('UNLINK', 'LOCAL', 'SINGLE', 'DELETE', 'REMAP', 'COPY', 'PASTE', 'ADD_FAKE', 'CLEAR_FAKE', 'RENAME', 'SELECT_LINKED')

and the contradictory doc page
https://docs.blender.org/api/current/bpy.ops.outliner.html

and my shennagigans code in case anyone is interested or knows the golden path.

def get_all_collection_children(coll):
    tmp_child_collections = []
    child_collections = loop_collection_children_recursively(coll, tmp_child_collections, False)
    return child_collections

for window in context.window_manager.windows:
    screen = window.screen
    for area in screen.areas:
        if area.type == 'OUTLINER':
            active_collection = bpy.context.view_layer.active_layer_collection.collection
            for lobj in active_collection.all_objects:
                if lobj.type == 'ARMATURE':
                    bpy.ops.object.select_all(action='DESELECT')
                    lobj.select_set(state=True)
                    bpy.context.view_layer.objects.active = lobj
                    with context.temp_override(window=window, area=area):
                        # bpy.ops.object.make_override_library()
                        shared_asset_type_subcollections = get_all_collection_children(asset_type_collection)
                        for i in export_subcollections:
                            i_name = i.name
                            if new_asset_coll_name in i_name:
                                layer_collection = bpy.context.view_layer.layer_collection
                                layerColl = recurLayerCollection(layer_collection, i_name)
                                bpy.context.view_layer.active_layer_collection = layerColl
                        bpy.ops.outliner.id_operation('INVOKE_AREA', type='OVERRIDE_LIBRARY_CREATE_HIERARCHY')
                        bpy.ops.outliner.id_operation('INVOKE_AREA',type='OVERRIDE_LIBRARY_MAKE_EDITABLE')
                    break
1 Like

Those enum entries are enabled/disabled at runtime, depending on the data in the context… So i’d suspect here that your active outliner entry is not a linked one?

Also note that making an override completely ‘trash’ the Outliner tree and rebuilds it, so don’t think your second operator call would work.


in any case, I do not see any reason to use the outliner and call operators for such operations here, this looks tremendously complicated and inefficient to me? Any reason not to use directly the ID API?
https://docs.blender.org/api/current/bpy.types.ID.html#bpy.types.ID.override_hierarchy_create
and then use
https://docs.blender.org/api/current/bpy.types.IDOverrideLibrary.html#bpy.types.IDOverrideLibrary.is_system_override

?

1 Like

Hey, thanks for the response. I think I understand. Doing it directly with types is far fewer shennanigans. Here’s my working code in case anyone is looking for how to how to add a linked collection with armatures and editable overrides (i.e. linked characters).


new_coll.override_hierarchy_create(scene=scene, view_layer=view_layer)
active_collection = bpy.context.view_layer.active_layer_collection.collection
for lobj in active_collection.all_objects:
    if lobj.type == 'ARMATURE':
        lobj_name = lobj.name
        bpy.data.objects[lobj_name].override_library.is_system_override = False

# remove the original collection 
# since creating the collection override hieratchy will create a duplicate instance.
# the linked data will still have a user so nothing will be lost.  not necessary just feels cleaner.

try:
    bpy.data.collections.remove(new_coll)
except:
    pass