[Bf-blender-cvs] [e3fd60b182f] master: LibOverride: Outliner: Add an operation to override the selected ID and its parents.

Bastien Montagne noreply at git.blender.org
Tue Jul 14 14:51:25 CEST 2020


Commit: e3fd60b182f69ae77c043fd52bbde81a0b8c7d8e
Author: Bastien Montagne
Date:   Tue Jul 14 14:49:59 2020 +0200
Branches: master
https://developer.blender.org/rBe3fd60b182f69ae77c043fd52bbde81a0b8c7d8e

LibOverride: Outliner: Add an operation to override the selected ID and its parents.

This will override all linked data-blocks in the tree branch leading to
the selected one.

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

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

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

diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index ac78c711a1a..ef5e40cdf78 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -54,6 +54,7 @@
 #include "BKE_context.h"
 #include "BKE_fcurve.h"
 #include "BKE_global.h"
+#include "BKE_idtype.h"
 #include "BKE_layer.h"
 #include "BKE_lib_id.h"
 #include "BKE_lib_override.h"
@@ -739,22 +740,63 @@ static void id_local_cb(bContext *C,
   }
 }
 
+typedef struct OutlinerLibOverrideData {
+  bool do_hierarchy;
+} OutlinerLibOverrideData;
+
 static void id_override_library_cb(bContext *C,
                                    ReportList *UNUSED(reports),
                                    Scene *UNUSED(scene),
-                                   TreeElement *UNUSED(te),
+                                   TreeElement *te,
                                    TreeStoreElem *UNUSED(tsep),
                                    TreeStoreElem *tselem,
-                                   void *UNUSED(user_data))
+                                   void *user_data)
 {
-  if (ID_IS_OVERRIDABLE_LIBRARY(tselem->id)) {
+  BLI_assert(TSE_IS_REAL_ID(tselem));
+  ID *id_root = tselem->id;
+
+  if (ID_IS_LINKED(id_root) &&
+      (BKE_idtype_get_info_from_id(id_root)->flags & IDTYPE_FLAGS_NO_LIBLINKING) == 0) {
     Main *bmain = CTX_data_main(C);
+    OutlinerLibOverrideData *data = user_data;
+    const bool do_hierarchy = data->do_hierarchy;
+
+    id_root->tag |= LIB_TAG_DOIT;
+
+    printf("%s: Tagging root id %s\n", __func__, id_root->name);
+
     /* For now, remapp all local usages of linked ID to local override one here. */
-    BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, true);
-    ID *override_id = BKE_lib_override_library_create_from_id(bmain, tselem->id, true);
-    if (override_id != NULL) {
-      BKE_main_id_clear_newpoins(bmain);
+    ID *id_iter;
+    FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
+      if (ID_IS_LINKED(id_iter)) {
+        id_iter->tag &= ~LIB_TAG_DOIT;
+      }
+      else {
+        id_iter->tag |= LIB_TAG_DOIT;
+      }
     }
+    FOREACH_MAIN_ID_END;
+
+    if (do_hierarchy) {
+      /* Tag all linked parents in tree hierarchy to be also overridden. */
+      while ((te = te->parent) != NULL) {
+        if (!TSE_IS_REAL_ID(te->store_elem)) {
+          continue;
+        }
+        if (!ID_IS_LINKED(te->store_elem->id)) {
+          break;
+        }
+        te->store_elem->id->tag |= LIB_TAG_DOIT;
+        printf("%s: Tagging parent id %s\n", __func__, te->store_elem->id->name);
+      }
+      BKE_lib_override_dependencies_tag(bmain, id_root, LIB_TAG_DOIT, true);
+      BKE_lib_override_library_create_from_tag(bmain);
+    }
+    else if (ID_IS_OVERRIDABLE_LIBRARY(id_root)) {
+      BKE_lib_override_library_create_from_id(bmain, id_root, true);
+    }
+
+    BKE_main_id_clear_newpoins(bmain);
     BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
   }
 }
@@ -1326,8 +1368,8 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
   }
   else if (event == OL_OP_REMAP) {
     outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_remap_cb, NULL);
-    /* No undo push here, operator does it itself (since it's a modal one, the op_undo_depth trick
-     * does not work here). */
+    /* No undo push here, operator does it itself (since it's a modal one, the op_undo_depth
+     * trick does not work here). */
   }
   else if (event == OL_OP_LOCALIZED) { /* disabled, see above enum (ton) */
     outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, id_local_cb);
@@ -1508,6 +1550,7 @@ typedef enum eOutlinerIdOpTypes {
   OUTLINER_IDOP_UNLINK,
   OUTLINER_IDOP_LOCAL,
   OUTLINER_IDOP_OVERRIDE_LIBRARY,
+  OUTLINER_IDOP_OVERRIDE_LIBRARY_HIERARCHY,
   OUTLINER_IDOP_SINGLE,
   OUTLINER_IDOP_DELETE,
   OUTLINER_IDOP_REMAP,
@@ -1531,6 +1574,11 @@ static const EnumPropertyItem prop_id_op_types[] = {
      0,
      "Add Library Override",
      "Add a local override of this linked data-block"},
+    {OUTLINER_IDOP_OVERRIDE_LIBRARY_HIERARCHY,
+     "OVERRIDE_LIBRARY_HIERARCHY",
+     0,
+     "Add Library Override Hierarchy",
+     "Add a local override of this linked data-block, and its hierarchy of dependencies"},
     {OUTLINER_IDOP_SINGLE, "SINGLE", 0, "Make Single User", ""},
     {OUTLINER_IDOP_DELETE, "DELETE", ICON_X, "Delete", ""},
     {OUTLINER_IDOP_REMAP,
@@ -1678,8 +1726,25 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
     }
     case OUTLINER_IDOP_OVERRIDE_LIBRARY: {
       /* make local */
-      outliner_do_libdata_operation(
-          C, op->reports, scene, soops, &soops->tree, id_override_library_cb, NULL);
+      outliner_do_libdata_operation(C,
+                                    op->reports,
+                                    scene,
+                                    soops,
+                                    &soops->tree,
+                                    id_override_library_cb,
+                                    &(OutlinerLibOverrideData){.do_hierarchy = false});
+      ED_undo_push(C, "Overridden Data");
+      break;
+    }
+    case OUTLINER_IDOP_OVERRIDE_LIBRARY_HIERARCHY: {
+      /* make local */
+      outliner_do_libdata_operation(C,
+                                    op->reports,
+                                    scene,
+                                    soops,
+                                    &soops->tree,
+                                    id_override_library_cb,
+                                    &(OutlinerLibOverrideData){.do_hierarchy = true});
       ED_undo_push(C, "Overridden Data");
       break;
     }



More information about the Bf-blender-cvs mailing list