[Bf-blender-cvs] [2ef192a55b2] master: IDManagement: Collection: Fix several issues in relationships building code.

Bastien Montagne noreply at git.blender.org
Thu Jun 3 12:15:37 CEST 2021


Commit: 2ef192a55b2ca65f07f678aada199357b06713e9
Author: Bastien Montagne
Date:   Thu Jun 3 10:18:44 2021 +0200
Branches: master
https://developer.blender.org/rB2ef192a55b2ca65f07f678aada199357b06713e9

IDManagement: Collection: Fix several issues in relationships building code.

`BKE_main_collections_parent_relations_rebuild`,
`BKE_collection_parent_relations_rebuild` anf their internal
dependencies had two issues fixed by this commit:

* Main one was that a same collection could be processed several times,
  sometimes even in an infinite loop (in some rare corner cases), by
  `collection_parents_rebuild_recursive`.
* More exotic, code here would not ensure that the collections it was
  processing were actually in Main (or a master one from a scene in
  Main), which became an issue with some advanced ID management
  processes involving partially out-of-main remapping, like liboverride
  resync.

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

M	source/blender/blenkernel/intern/collection.c

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

diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index be827cd338d..5a7fe71de8e 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -1643,6 +1643,13 @@ void BKE_collection_parent_relations_rebuild(Collection *collection)
       continue;
     }
 
+    /* Can happen when remaping data partially out-of-Main (during advanced ID management
+     * operations like liboverride resync e.g.). */
+    if ((child->collection->id.tag & (LIB_TAG_NO_MAIN | LIB_TAG_COPIED_ON_WRITE)) != 0) {
+      continue;
+    }
+
+    BLI_assert(collection_find_parent(child->collection, collection) == NULL);
     CollectionParent *cparent = MEM_callocN(sizeof(CollectionParent), __func__);
     cparent->collection = collection;
     BLI_addtail(&child->collection->parents, cparent);
@@ -1651,10 +1658,19 @@ void BKE_collection_parent_relations_rebuild(Collection *collection)
 
 static void collection_parents_rebuild_recursive(Collection *collection)
 {
+  /* A same collection may be child of several others, no need to process it more than once. */
+  if ((collection->tag & COLLECTION_TAG_RELATION_REBUILD) == 0) {
+    return;
+  }
+
   BKE_collection_parent_relations_rebuild(collection);
   collection->tag &= ~COLLECTION_TAG_RELATION_REBUILD;
 
   for (CollectionChild *child = collection->children.first; child != NULL; child = child->next) {
+    /* See comment above in `BKE_collection_parent_relations_rebuild`. */
+    if ((collection->id.tag & (LIB_TAG_NO_MAIN | LIB_TAG_COPIED_ON_WRITE)) != 0) {
+      continue;
+    }
     collection_parents_rebuild_recursive(child->collection);
   }
 }
@@ -1678,6 +1694,8 @@ void BKE_main_collections_parent_relations_rebuild(Main *bmain)
     /* This function can be called from readfile.c, when this pointer is not guaranteed to be NULL.
      */
     if (scene->master_collection != NULL) {
+      BLI_assert(BLI_listbase_is_empty(&scene->master_collection->parents));
+      scene->master_collection->tag |= COLLECTION_TAG_RELATION_REBUILD;
       collection_parents_rebuild_recursive(scene->master_collection);
     }
   }



More information about the Bf-blender-cvs mailing list