[Bf-blender-cvs] [d3632df2f6f] liboverride-systemoverrides: LibOverride: Implement default 'user override' behavior.

Bastien Montagne noreply at git.blender.org
Wed Mar 2 07:52:58 CET 2022


Commit: d3632df2f6f4e878a6ab6301ff295fad9dd6153d
Author: Bastien Montagne
Date:   Tue Mar 1 18:02:56 2022 +0100
Branches: liboverride-systemoverrides
https://developer.blender.org/rBd3632df2f6f4e878a6ab6301ff295fad9dd6153d

LibOverride: Implement default 'user override' behavior.

Implement default behavior to decide which overrides remain 'system'
ones, and which become 'user editable' ones, when creating hierarchy
override from 3DView or the Outliner.

3DView:
If from an Empty-instanced collection, only Armature objects in
that collection are user overrides.
If from a set of selected objects, all overrides created from selected
objects are user overrides.

Outliner:
All override IDs created from selected elements in the Outliner are user
overrides.

===================================================================

M	source/blender/editors/object/object_relations.c
M	source/blender/editors/space_outliner/outliner_tools.cc

===================================================================

diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 3ecf86d14ed..b2914e0c01f 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -2273,6 +2273,10 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
   ID *id_root = NULL;
   bool is_override_instancing_object = false;
 
+  GSet *user_overrides_objects_uuids = BLI_gset_new(
+      BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, __func__);
+  bool user_overrides_from_selected_objects = false;
+
   if (!ID_IS_LINKED(obact) && obact->instance_collection != NULL &&
       ID_IS_LINKED(obact->instance_collection)) {
     if (!ID_IS_OVERRIDABLE_LIBRARY(obact->instance_collection)) {
@@ -2285,6 +2289,7 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
 
     id_root = &obact->instance_collection->id;
     is_override_instancing_object = true;
+    user_overrides_from_selected_objects = false;
   }
   else if (!make_override_library_object_overridable_check(bmain, obact)) {
     const int i = RNA_property_enum_get(op->ptr, op->type->prop);
@@ -2309,16 +2314,53 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
       return OPERATOR_CANCELLED;
     }
     id_root = &collection->id;
+    user_overrides_from_selected_objects = true;
   }
   /* Else, poll func ensures us that ID_IS_LINKED(obact) is true. */
   else {
     id_root = &obact->id;
+    user_overrides_from_selected_objects = true;
+  }
+
+  if (user_overrides_from_selected_objects) {
+    /* Only selected objects can be 'user overrides'. */
+    FOREACH_SELECTED_OBJECT_BEGIN (view_layer, CTX_wm_view3d(C), ob_iter) {
+      BLI_gset_add(user_overrides_objects_uuids, POINTER_FROM_UINT(ob_iter->id.session_uuid));
+    }
+    FOREACH_SELECTED_OBJECT_END;
+  }
+  else {
+    /* Only armatures inside the root collection (and their children) can be 'user overrides'. */
+    FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN ((Collection *)id_root, ob_iter) {
+      if (ob_iter->type == OB_ARMATURE) {
+        BLI_gset_add(user_overrides_objects_uuids, POINTER_FROM_UINT(ob_iter->id.session_uuid));
+      }
+    }
+    FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
   }
 
   BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
 
+  ID *id_root_override;
   const bool success = BKE_lib_override_library_create(
-      bmain, scene, view_layer, NULL, id_root, id_root, &obact->id, NULL);
+      bmain, scene, view_layer, NULL, id_root, id_root, &obact->id, &id_root_override);
+
+  /* Define liboverrides from selected/validated objects as user defined. */
+  ID *id_hierarchy_root_override = id_root_override->override_library->hierarchy_root;
+  ID *id_iter;
+  FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
+    if (ID_IS_LINKED(id_iter) || !ID_IS_OVERRIDE_LIBRARY_REAL(id_iter) ||
+        id_iter->override_library->hierarchy_root != id_hierarchy_root_override) {
+      continue;
+    }
+    if (BLI_gset_haskey(user_overrides_objects_uuids,
+                        POINTER_FROM_UINT(id_iter->override_library->reference->session_uuid))) {
+      id_iter->override_library->flag &= ~IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED;
+    }
+  }
+  FOREACH_MAIN_ID_END;
+
+  BLI_gset_free(user_overrides_objects_uuids, NULL);
 
   /* Remove the instance empty from this scene, the items now have an overridden collection
    * instead. */
diff --git a/source/blender/editors/space_outliner/outliner_tools.cc b/source/blender/editors/space_outliner/outliner_tools.cc
index 8fcf967bce8..a3892ef65f7 100644
--- a/source/blender/editors/space_outliner/outliner_tools.cc
+++ b/source/blender/editors/space_outliner/outliner_tools.cc
@@ -31,6 +31,7 @@
 
 #include "BLI_blenlib.h"
 #include "BLI_ghash.h"
+#include "BLI_set.hh"
 #include "BLI_utildefines.h"
 
 #include "BKE_anim_data.h"
@@ -87,6 +88,8 @@ static CLG_LogRef LOG = {"ed.outliner.tools"};
 
 using namespace blender::ed::outliner;
 
+using blender::Set;
+
 /* -------------------------------------------------------------------- */
 /** \name ID/Library/Data Set/Un-link Utilities
  * \{ */
@@ -755,8 +758,37 @@ struct OutlinerLibOverrideData {
    * instead of re-applying relevant existing ID pointer property override operations. Helps
    * solving broken overrides while not losing *all* of your overrides. */
   bool do_resync_hierarchy_enforce;
+
+  /** The override hierarchy root, when known/created. */
+  ID *id_hierarchy_root_override;
+
+  /** A hash of the selected tree elements' ID 'uuid'. Used to clear 'system override' flags on
+   * their newly-created liboverrides in post-process step of override hierarchy creation. */
+  Set<uint> selected_id_uid;
 };
 
+/* Store 'UUID' of IDs of selected elements in the OUtliner tree, before generating the override
+ * hierarchy. */
+static void id_override_library_create_hierarchy_pre_process_fn(bContext *UNUSED(C),
+                                                                ReportList *UNUSED(reports),
+                                                                Scene *UNUSED(scene),
+                                                                TreeElement *UNUSED(te),
+                                                                TreeStoreElem *UNUSED(tsep),
+                                                                TreeStoreElem *tselem,
+                                                                void *user_data)
+{
+  BLI_assert(TSE_IS_REAL_ID(tselem));
+
+  OutlinerLibOverrideData *data = reinterpret_cast<OutlinerLibOverrideData *>(user_data);
+  const bool do_hierarchy = data->do_hierarchy;
+  ID *id_root_reference = tselem->id;
+
+  BLI_assert(do_hierarchy);
+  UNUSED_VARS_NDEBUG(do_hierarchy);
+
+  data->selected_id_uid.add(id_root_reference->session_uuid);
+}
+
 static void id_override_library_create_fn(bContext *C,
                                           ReportList *reports,
                                           Scene *scene,
@@ -895,6 +927,7 @@ static void id_override_library_create_fn(bContext *C,
         return;
       }
 
+      ID *id_root_override = nullptr;
       success = BKE_lib_override_library_create(bmain,
                                                 CTX_data_scene(C),
                                                 CTX_data_view_layer(C),
@@ -902,7 +935,22 @@ static void id_override_library_create_fn(bContext *C,
                                                 id_root_reference,
                                                 id_hierarchy_root_reference,
                                                 id_instance_hint,
-                                                nullptr);
+                                                &id_root_override);
+
+      BLI_assert(id_root_override != nullptr);
+      BLI_assert(!ID_IS_LINKED(id_root_override));
+      BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_root_override));
+      if (ID_IS_LINKED(id_hierarchy_root_reference)) {
+        BLI_assert(
+            id_root_override->override_library->hierarchy_root->override_library->reference ==
+            id_hierarchy_root_reference);
+        data->id_hierarchy_root_override = id_root_override->override_library->hierarchy_root;
+      }
+      else {
+        BLI_assert(id_root_override->override_library->hierarchy_root ==
+                   id_hierarchy_root_reference);
+        data->id_hierarchy_root_override = id_root_override->override_library->hierarchy_root;
+      }
     }
     else if (ID_IS_OVERRIDABLE_LIBRARY(id_root_reference)) {
       success = BKE_lib_override_library_create_from_id(bmain, id_root_reference, true) != nullptr;
@@ -926,6 +974,27 @@ static void id_override_library_create_fn(bContext *C,
   }
 }
 
+/* Clear system override flag from newly created overrides which linked reference were previously
+ * selected in the Outliner tree. */
+static void id_override_library_create_hierarchy_post_process(bContext *C,
+                                                              OutlinerLibOverrideData *data)
+{
+  Main *bmain = CTX_data_main(C);
+  ID *id_hierarchy_root_override = data->id_hierarchy_root_override;
+
+  ID *id_iter;
+  FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
+    if (ID_IS_LINKED(id_iter) || !ID_IS_OVERRIDE_LIBRARY_REAL(id_iter) ||
+        id_iter->override_library->hierarchy_root != id_hierarchy_root_override) {
+      continue;
+    }
+    if (data->selected_id_uid.contains(id_iter->override_library->reference->session_uuid)) {
+      id_iter->override_library->flag &= ~IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED;
+    }
+  }
+  FOREACH_MAIN_ID_END;
+}
+
 static void id_override_library_reset_fn(bContext *C,
                                          ReportList *UNUSED(reports),
                                          Scene *UNUSED(scene),
@@ -2087,6 +2156,13 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
     case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY: {
       OutlinerLibOverrideData override_data{};
       override_data.do_hierarchy = true;
+      outliner_do_libdata_operation(C,
+                                    op->reports,
+                                    scene,
+                                    space_outliner,
+                                    &space_outliner->tree,
+                                    id_override_library_create_hierarchy_pre_process_fn,
+                                    &override_data);
       outliner_do_libdata_operation(C,
                                     op->reports,
                                     scene,
@@ -2094,6 +2170,8 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
                                     &space_outliner->tree,
                                     id_override_library_create_fn,
                                     &override_data);
+      id_override_library_create_hierarchy_post_process(C, &override_data);
+
       ED_undo_push(C, "Overridden Data Hierarchy");
       break;
     }



More information about the Bf-blender-cvs mailing list