[Bf-blender-cvs] [ee3facd0879] master: LibOverride: support 'make override' for all selected items.

Bastien Montagne noreply at git.blender.org
Thu Jul 21 10:18:48 CEST 2022


Commit: ee3facd0879d48895febdd66661567c2af1b9e33
Author: Bastien Montagne
Date:   Wed Jul 20 18:01:58 2022 +0200
Branches: master
https://developer.blender.org/rBee3facd0879d48895febdd66661567c2af1b9e33

LibOverride: support 'make override' for all selected items.

This commit allows to select several data-blocks in the outliner and
create overrides from all of them, not only the active one.

It properly creates a single hierarchy when several IDs from a same
hierarchy root data are selected.

Reviewed By: Severin

Differential Revision: https://developer.blender.org/D15497

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

M	source/blender/editors/space_outliner/outliner_tools.cc

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

diff --git a/source/blender/editors/space_outliner/outliner_tools.cc b/source/blender/editors/space_outliner/outliner_tools.cc
index 9d52103a266..e1aa695a262 100644
--- a/source/blender/editors/space_outliner/outliner_tools.cc
+++ b/source/blender/editors/space_outliner/outliner_tools.cc
@@ -31,8 +31,11 @@
 
 #include "BLI_blenlib.h"
 #include "BLI_ghash.h"
+#include "BLI_linklist.h"
+#include "BLI_map.hh"
 #include "BLI_set.hh"
 #include "BLI_utildefines.h"
+#include "BLI_vector.hh"
 
 #include "BKE_anim_data.h"
 #include "BKE_animsys.h"
@@ -90,7 +93,9 @@ static CLG_LogRef LOG = {"ed.outliner.tools"};
 
 using namespace blender::ed::outliner;
 
+using blender::Map;
 using blender::Set;
+using blender::Vector;
 
 /* -------------------------------------------------------------------- */
 /** \name ID/Library/Data Set/Un-link Utilities
@@ -777,6 +782,25 @@ static void id_local_fn(bContext *C,
   }
 }
 
+struct OutlinerLiboverrideDataIDRoot {
+  /** The linked ID that was selected for override. */
+  ID *id_root_reference;
+
+  /** The root of the override hierarchy to which the override of `id_root` belongs, once
+   * known/created. */
+  ID *id_hierarchy_root_override;
+
+  /** The ID that was detected as being a good candidate as instanciation hint for newly overridden
+   * objects, may be null.
+   *
+   * \note Typically currently only used when the root ID to override is a collection instanced by
+   * an emtpy object. */
+  ID *id_instance_hint;
+
+  /** If this override comes from an instancing object (which would be `id_instance_hint` then). */
+  bool is_override_instancing_object;
+};
+
 struct OutlinerLibOverrideData {
   bool do_hierarchy;
 
@@ -789,21 +813,44 @@ struct OutlinerLibOverrideData {
    * 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
+  /** A set 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;
+
+  /** A mapping from the found hierarchy roots to a linked list of IDs to override for each of
+   * these roots.
+   *
+   * \note the key may be either linked (in which case it will be replaced by the newly created
+   * override), or an actual already existing override. */
+  Map<ID *, Vector<OutlinerLiboverrideDataIDRoot>> id_hierarchy_roots;
+
+  /** All 'session_uuid' of all hierarchy root IDs used or created by the operation.  */
+  Set<uint> id_hierarchy_roots_uid;
+
+  void id_root_add(ID *id_hierarchy_root_reference,
+                   ID *id_root_reference,
+                   ID *id_instance_hint,
+                   const bool is_override_instancing_object)
+  {
+    OutlinerLiboverrideDataIDRoot id_root_data;
+    id_root_data.id_root_reference = id_root_reference;
+    id_root_data.id_hierarchy_root_override = nullptr;
+    id_root_data.id_instance_hint = id_instance_hint;
+    id_root_data.is_override_instancing_object = is_override_instancing_object;
+
+    Vector<OutlinerLiboverrideDataIDRoot> &value = id_hierarchy_roots.lookup_or_add_default(
+        id_hierarchy_root_reference);
+    value.append(id_root_data);
+  }
 };
 
 /* 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),
+static void id_override_library_create_hierarchy_pre_process_fn(bContext *C,
+                                                                ReportList *reports,
                                                                 Scene *UNUSED(scene),
-                                                                TreeElement *UNUSED(te),
-                                                                TreeStoreElem *UNUSED(tsep),
+                                                                TreeElement *te,
+                                                                TreeStoreElem *tsep,
                                                                 TreeStoreElem *tselem,
                                                                 void *user_data)
 {
@@ -829,28 +876,6 @@ static void id_override_library_create_hierarchy_pre_process_fn(bContext *UNUSED
     }
     FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
   }
-}
-
-static void id_override_library_create_fn(bContext *C,
-                                          ReportList *reports,
-                                          Scene *scene,
-                                          TreeElement *te,
-                                          TreeStoreElem *tsep,
-                                          TreeStoreElem *tselem,
-                                          void *user_data)
-{
-  BLI_assert(TSE_IS_REAL_ID(tselem));
-
-  /* We can only safely apply this operation on one item at a time, so only do it on the active
-   * one. */
-  if ((tselem->flag & TSE_ACTIVE) == 0) {
-    return;
-  }
-
-  ID *id_root_reference = tselem->id;
-  OutlinerLibOverrideData *data = reinterpret_cast<OutlinerLibOverrideData *>(user_data);
-  const bool do_hierarchy = data->do_hierarchy;
-  bool success = false;
 
   ID *id_instance_hint = nullptr;
   bool is_override_instancing_object = false;
@@ -866,172 +891,239 @@ static void id_override_library_create_fn(bContext *C,
     }
   }
 
-  if (ID_IS_OVERRIDABLE_LIBRARY(id_root_reference) ||
-      (ID_IS_LINKED(id_root_reference) && do_hierarchy)) {
-    Main *bmain = CTX_data_main(C);
+  if (!ID_IS_OVERRIDABLE_LIBRARY(id_root_reference) &&
+      !(ID_IS_LINKED(id_root_reference) && do_hierarchy)) {
+    return;
+  }
 
-    id_root_reference->tag |= LIB_TAG_DOIT;
+  Main *bmain = CTX_data_main(C);
 
-    /* For now, remap all local usages of linked ID to local override one here. */
-    ID *id_iter;
-    FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
-      if (ID_IS_LINKED(id_iter) || ID_IS_OVERRIDE_LIBRARY(id_iter)) {
-        id_iter->tag &= ~LIB_TAG_DOIT;
-      }
-      else {
-        id_iter->tag |= LIB_TAG_DOIT;
+  if (do_hierarchy) {
+    /* Tag all linked parents in tree hierarchy to be also overridden. */
+    ID *id_hierarchy_root_reference = id_root_reference;
+    while ((te = te->parent) != nullptr) {
+      if (!TSE_IS_REAL_ID(te->store_elem)) {
+        continue;
       }
-    }
-    FOREACH_MAIN_ID_END;
 
-    if (do_hierarchy) {
-      /* Tag all linked parents in tree hierarchy to be also overridden. */
-      ID *id_hierarchy_root_reference = id_root_reference;
-      while ((te = te->parent) != nullptr) {
-        if (!TSE_IS_REAL_ID(te->store_elem)) {
+      /* Tentative hierarchy root. */
+      ID *id_current_hierarchy_root = te->store_elem->id;
+
+      /* If the parent ID is from a different library than the reference root one, we are done
+       * with upwards tree processing in any case. */
+      if (id_current_hierarchy_root->lib != id_root_reference->lib) {
+        if (ID_IS_OVERRIDE_LIBRARY_VIRTUAL(id_current_hierarchy_root)) {
+          /* Virtual overrides (i.e. embedded IDs), we can simply keep processing their parent to
+           * get an actual real override. */
           continue;
         }
 
-        /* Tentative hierarchy root. */
-        ID *id_current_hierarchy_root = te->store_elem->id;
-
-        /* If the parent ID is from a different library than the reference root one, we are done
-         * with upwards tree processing in any case. */
-        if (id_current_hierarchy_root->lib != id_root_reference->lib) {
-          if (ID_IS_OVERRIDE_LIBRARY_VIRTUAL(id_current_hierarchy_root)) {
-            /* Virtual overrides (i.e. embedded IDs), we can simply keep processing their parent to
-             * get an actual real override. */
-            continue;
-          }
-
-          /* If the parent ID is already an override, and is valid (i.e. local override), we can
-           * access its hierarchy root directly. */
-          if (!ID_IS_LINKED(id_current_hierarchy_root) &&
-              ID_IS_OVERRIDE_LIBRARY_REAL(id_current_hierarchy_root) &&
-              id_current_hierarchy_root->override_library->reference->lib ==
-                  id_root_reference->lib) {
-            id_hierarchy_root_reference =
-                id_current_hierarchy_root->override_library->hierarchy_root;
-            BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_hierarchy_root_reference));
-            break;
-          }
-
-          if (ID_IS_LINKED(id_current_hierarchy_root)) {
-            /* No local 'anchor' was found for the hierarchy to override, do not proceed, as this
-             * would most likely generate invisible/confusing/hard to use and manage overrides. */
-            BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
-            BKE_reportf(reports,
-                        RPT_WARNING,
-                        "Invalid anchor ('%s') found, needed to create library override from "
-                        "data-block '%s'",
-                        id_current_hierarchy_root->name,
-                        id_root_reference->name);
-            return;
-          }
-
-          /* In all other cases, `id_current_hierarchy_root` cannot be a valid hierarchy root, so
-           * current `id_hierarchy_root_reference` is our best candidate. */
-
+        /* If the parent ID is already an override, and is valid (i.e. local override), we can
+         * access its hierarchy root directly. */
+        if (!ID_IS_LINKED(id_current_hierarchy_root) &&
+            ID_IS_OVERRIDE_LIBRARY_REAL(id_current_hierarchy_root) &&
+            id_current_hierarchy_root->override_library->reference->lib ==
+                id_root_reference->lib) {
+          id_hierarchy_root_reference =
+              id_current_hierarchy_root->override_library->hierarchy_root;
+          BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_hierarchy_root_reference));
           break;
        

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list