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.
This commit is contained in:
parent
a51f8f94d5
commit
2ef192a55b
Notes:
blender-bot
2023-02-14 02:27:56 +01:00
Referenced by commit 921708fc76
, Fix (unreported) potential bug in collections parenting update code.
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue