Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_collection.h3
-rw-r--r--source/blender/blenkernel/intern/collection.c66
-rw-r--r--source/blender/blenloader/intern/readfile.c15
3 files changed, 72 insertions, 12 deletions
diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index 0e093bb086b..502c949be9a 100644
--- a/source/blender/blenkernel/BKE_collection.h
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -163,6 +163,9 @@ bool BKE_collection_find_cycle(struct Collection *new_ancestor, struct Collectio
bool BKE_collection_has_collection(struct Collection *parent, struct Collection *collection);
+void BKE_collection_parent_relations_rebuild(struct Collection *collection);
+void BKE_main_collections_parent_relations_rebuild(struct Main *bmain);
+
/* Iteration callbacks. */
typedef void (*BKE_scene_objects_Cb)(struct Object *ob, void *data);
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index d2ca304e973..68392bf0d03 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -1056,6 +1056,72 @@ bool BKE_collection_child_remove(Main *bmain, Collection *parent, Collection *ch
return true;
}
+/**
+ * Rebuild parent relationships from child ones, for all children of given \a collection.
+ *
+ * \note Given collection is assumed to already have valid parents.
+ */
+void BKE_collection_parent_relations_rebuild(Collection *collection)
+{
+ for (CollectionChild *child = collection->children.first, *child_next = NULL; child;
+ child = child_next) {
+ child_next = child->next;
+
+ if (child->collection == NULL || BKE_collection_find_cycle(collection, child->collection)) {
+ BLI_freelinkN(&collection->children, child);
+ }
+ else {
+ CollectionParent *cparent = MEM_callocN(sizeof(CollectionParent), __func__);
+ cparent->collection = collection;
+ BLI_addtail(&child->collection->parents, cparent);
+ }
+ }
+}
+
+static void collection_parents_rebuild_recursive(Collection *collection)
+{
+ BKE_collection_parent_relations_rebuild(collection);
+ collection->id.tag &= ~LIB_TAG_DOIT;
+
+ for (CollectionChild *child = collection->children.first; child != NULL; child = child->next) {
+ collection_parents_rebuild_recursive(child->collection);
+ }
+}
+
+/**
+ * Rebuild parent relationships from child ones, for all collections in given \a bmain.
+ *
+ * \note Uses LIB_TAG_DOIT internally...
+ */
+void BKE_main_collections_parent_relations_rebuild(Main *bmain)
+{
+ /* Only collections not in bmain (master ones in scenes) have no parent... */
+ for (Collection *collection = bmain->collections.first; collection != NULL;
+ collection = collection->id.next) {
+ BLI_freelistN(&collection->parents);
+
+ collection->id.tag |= LIB_TAG_DOIT;
+ }
+
+ /* Scene's master collections will be 'root' parent of most of our collections, so start with
+ * them. */
+ for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
+ collection_parents_rebuild_recursive(scene->master_collection);
+ }
+
+ /* We may have parent chains outside of scene's master_collection context? At least, readfile's
+ * lib_link_collection_data() seems to assume that, so do the same here. */
+ for (Collection *collection = bmain->collections.first; collection != NULL;
+ collection = collection->id.next) {
+ if (collection->id.tag & LIB_TAG_DOIT) {
+ /* Note: we do not have easy access to 'which collections is root' info in that case, which
+ * means test for cycles in collection relationships may fail here. I don't think that is an
+ * issue in practice here, but worth keeping in mind... */
+ collection_parents_rebuild_recursive(collection);
+ }
+ }
+}
+
/********************** Collection index *********************/
static Collection *collection_from_index_recursive(Collection *collection,
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 5edba272cd4..de6e5a80912 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6228,20 +6228,11 @@ static void lib_link_collection_data(FileData *fd, Library *lib, Collection *col
}
}
- for (CollectionChild *child = collection->children.first, *child_next = NULL; child;
- child = child_next) {
- child_next = child->next;
+ for (CollectionChild *child = collection->children.first; child != NULL; child = child->next) {
child->collection = newlibadr_us(fd, lib, child->collection);
-
- if (child->collection == NULL || BKE_collection_find_cycle(collection, child->collection)) {
- BLI_freelinkN(&collection->children, child);
- }
- else {
- CollectionParent *cparent = MEM_callocN(sizeof(CollectionParent), "CollectionParent");
- cparent->collection = collection;
- BLI_addtail(&child->collection->parents, cparent);
- }
}
+
+ BKE_collection_parent_relations_rebuild(collection);
}
static void lib_link_collection(FileData *fd, Main *main)