[Bf-blender-cvs] [5c7852ef9c6] master: LibOverride: Create override operator: various fixes.

Bastien Montagne noreply at git.blender.org
Thu Aug 29 18:11:39 CEST 2019


Commit: 5c7852ef9c6a77062adc3754258b181379e05f43
Author: Bastien Montagne
Date:   Thu Aug 29 18:05:34 2019 +0200
Branches: master
https://developer.blender.org/rB5c7852ef9c6a77062adc3754258b181379e05f43

LibOverride: Create override operator: various fixes.

* `make_override_library_exec` was not properly cleaning `LIB_TAG_DOIT`
from all IDs in the Main DB.
* `BKE_override_library_create_from_tag` was doing dangerous things
(like iterating over a BMain listbase while adding items to it...).
* It would remap *all* local usages of overridden linked IDs to new
overriding local IDs, which was very inconvinient.

New handling of remapping now allows to only remap inside of the group
of IDs that is being overridden, in other words you can still have e.g.
other empties still instancing the same linked collection...

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

M	source/blender/blenkernel/intern/library_override.c
M	source/blender/editors/object/object_relations.c

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

diff --git a/source/blender/blenkernel/intern/library_override.c b/source/blender/blenkernel/intern/library_override.c
index ba482359607..6532fce5778 100644
--- a/source/blender/blenkernel/intern/library_override.c
+++ b/source/blender/blenkernel/intern/library_override.c
@@ -207,6 +207,11 @@ ID *BKE_override_library_create_from_id(Main *bmain, ID *reference_id)
  * \note Set id->newid of overridden libs with newly created overrides,
  * caller is responsible to clean those pointers before/after usage as needed.
  *
+ * \note By default, it will only remap newly created local overriding data-blocks between
+ * themselves, to avoid 'enforcing' those overrides into all other usages of the linked data in
+ * main. You can add more local IDs to be remapped to use new overriding ones by setting their
+ * LIB_TAG_DOIT tag.
+ *
  * \return \a true on success, \a false otherwise.
  */
 bool BKE_override_library_create_from_tag(Main *bmain)
@@ -214,26 +219,59 @@ bool BKE_override_library_create_from_tag(Main *bmain)
   ID *reference_id;
   bool ret = true;
 
+  ListBase todo_ids = {NULL};
+  LinkData *todo_id_iter;
+
+  /* Get all IDs we want to override. */
   FOREACH_MAIN_ID_BEGIN (bmain, reference_id) {
     if ((reference_id->tag & LIB_TAG_DOIT) != 0 && reference_id->lib != NULL) {
-      if ((reference_id->newid = override_library_create_from(bmain, reference_id)) == NULL) {
-        ret = false;
-      }
+      todo_id_iter = MEM_callocN(sizeof(*todo_id_iter), __func__);
+      todo_id_iter->data = reference_id;
+      BLI_addtail(&todo_ids, todo_id_iter);
     }
   }
   FOREACH_MAIN_ID_END;
 
-  FOREACH_MAIN_ID_BEGIN (bmain, reference_id) {
-    if ((reference_id->tag & LIB_TAG_DOIT) != 0 && reference_id->lib != NULL &&
-        reference_id->newid != NULL) {
-      ID *local_id = reference_id->newid;
-      BKE_libblock_remap(bmain,
-                         reference_id,
-                         local_id,
-                         ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_OVERRIDE_LIBRARY);
+  /* Override the IDs. */
+  for (todo_id_iter = todo_ids.first; todo_id_iter != NULL; todo_id_iter = todo_id_iter->next) {
+    reference_id = todo_id_iter->data;
+    if ((reference_id->newid = override_library_create_from(bmain, reference_id)) == NULL) {
+      ret = false;
+    }
+    else {
+      /* We also tag the new IDs so that in next step we can remap their pointers too. */
+      reference_id->newid->tag |= LIB_TAG_DOIT;
     }
   }
-  FOREACH_MAIN_ID_END;
+
+  /* Only remap new local ID's pointers, we don't want to force our new overrides onto our whole
+   * existing linked IDs usages. */
+  for (todo_id_iter = todo_ids.first; todo_id_iter != NULL; todo_id_iter = todo_id_iter->next) {
+    ID *other_id;
+    reference_id = todo_id_iter->data;
+
+    if (reference_id->newid == NULL) {
+      continue;
+    }
+
+    /* Still checking the whole Main, that way we can tag other local IDs as needing to be remapped
+     * to use newly created overriding IDs, if needed. */
+    FOREACH_MAIN_ID_BEGIN (bmain, other_id) {
+      if ((other_id->tag & LIB_TAG_DOIT) != 0 && other_id->lib == NULL) {
+        ID *local_id = reference_id->newid;
+        /* Note that using ID_REMAP_SKIP_INDIRECT_USAGE below is superfluous, as we only remap
+         * local IDs usages anyway... */
+        BKE_libblock_relink_ex(bmain,
+                               other_id,
+                               reference_id,
+                               local_id,
+                               ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_OVERRIDE_LIBRARY);
+      }
+    }
+    FOREACH_MAIN_ID_END;
+  }
+
+  BLI_freelistN(&todo_ids);
 
   return ret;
 }
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 67364f275dd..df684bfc210 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -2426,6 +2426,8 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
 
   if (!ID_IS_LINKED(obact) && obact->instance_collection != NULL &&
       ID_IS_LINKED(obact->instance_collection)) {
+    BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
+
     Object *obcollection = obact;
     Collection *collection = obcollection->instance_collection;
 
@@ -2503,7 +2505,7 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
 
     /* Cleanup. */
     BKE_main_id_clear_newpoins(bmain);
-    BKE_main_id_tag_listbase(&bmain->objects, LIB_TAG_DOIT, false);
+    BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
   }
   /* Else, poll func ensures us that ID_IS_LINKED(obact) is true. */
   else if (obact->type == OB_ARMATURE) {
@@ -2522,7 +2524,7 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
 
     /* Cleanup. */
     BKE_main_id_clear_newpoins(bmain);
-    BKE_main_id_tag_listbase(&bmain->objects, LIB_TAG_DOIT, false);
+    BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
   }
   /* TODO: probably more cases where we want to do automated smart things in the future! */
   else {



More information about the Bf-blender-cvs mailing list