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:
authorBastien Montagne <montagne29@wanadoo.fr>2018-10-29 13:42:38 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2018-10-29 13:42:38 +0300
commitf887dc1f5c8414f3a5ad6927730a3a74684ddf26 (patch)
tree41af4c8414ccb3380b54af7096db5df50d608508 /source/blender/blenkernel/intern
parentc2791777bd8bd4a0375ada74b84c2142c6ce73cc (diff)
Fix T57372: Second full scene copy crashes on deletion.
Hope this time we are done for good (root of the issue was that master collections are not in bmain...).
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/collection.c69
-rw-r--r--source/blender/blenkernel/intern/library_remap.c12
2 files changed, 55 insertions, 26 deletions
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index e6546d4454d..c85632b423b 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -650,28 +650,67 @@ void BKE_collections_object_remove_nulls(Main *bmain)
}
}
-/*
- * Remove all NULL children from parent objects of changed old_collection.
+static void collection_null_children_remove(Collection *collection)
+{
+ for (CollectionChild *child = collection->children.first, *child_next = NULL; child; child = child_next) {
+ child_next = child->next;
+
+ if (child->collection == NULL) {
+ BLI_freelinkN(&collection->children, child);
+ }
+ }
+}
+
+static void collection_missing_parents_remove(Collection *collection)
+{
+ for (CollectionParent *parent = collection->parents.first, *parent_next; parent != NULL; parent = parent_next) {
+ parent_next = parent->next;
+
+ if (!collection_find_child(parent->collection, collection)) {
+ BLI_freelinkN(&collection->parents, parent);
+ }
+ }
+}
+
+/**
+ * Remove all NULL children from parent collections of changed \a collection.
* This is used for library remapping, where these pointers have been set to NULL.
* Otherwise this should never happen.
- * Note: caller must ensure BKE_main_collection_sync_remap() is called afterwards!
+ *
+ * \note caller must ensure BKE_main_collection_sync_remap() is called afterwards!
+ *
+ * \param collection may be \a NULL, in which case whole \a bmain database of collections is checked.
*/
-void BKE_collections_child_remove_nulls(Main *bmain, Collection *old_collection)
+void BKE_collections_child_remove_nulls(Main *bmain, Collection *collection)
{
- for (CollectionParent *cparent = old_collection->parents.first, *cnext; cparent; cparent = cnext) {
- Collection *parent = cparent->collection;
- cnext = cparent->next;
-
- for (CollectionChild *child = parent->children.first, *child_next = NULL; child; child = child_next) {
- child_next = child->next;
+ if (collection == NULL) {
+ /* We need to do the checks in two steps when more than one collection may be involved,
+ * otherwise we can miss some cases...
+ * Also, master collections are not in bmain, so we also need to loop over scenes.
+ */
+ for (collection = bmain->collection.first; collection != NULL; collection = collection->id.next) {
+ collection_null_children_remove(collection);
+ }
+ for (Scene *scene = bmain->scene.first; scene != NULL; scene = scene->id.next) {
+ collection_null_children_remove(BKE_collection_master(scene));
+ }
- if (child->collection == NULL) {
- BLI_freelinkN(&parent->children, child);
- }
+ for (collection = bmain->collection.first; collection != NULL; collection = collection->id.next) {
+ collection_missing_parents_remove(collection);
+ }
+ for (Scene *scene = bmain->scene.first; scene != NULL; scene = scene->id.next) {
+ collection_missing_parents_remove(BKE_collection_master(scene));
}
+ }
+ else {
+ for (CollectionParent *parent = collection->parents.first, *parent_next; parent; parent = parent_next) {
+ parent_next = parent->next;
+
+ collection_null_children_remove(parent->collection);
- if (!collection_find_child(parent, old_collection)) {
- BLI_freelinkN(&old_collection->parents, cparent);
+ if (!collection_find_child(parent->collection, collection)) {
+ BLI_freelinkN(&collection->parents, parent);
+ }
}
}
}
diff --git a/source/blender/blenkernel/intern/library_remap.c b/source/blender/blenkernel/intern/library_remap.c
index 114159debe3..8a011b55cf3 100644
--- a/source/blender/blenkernel/intern/library_remap.c
+++ b/source/blender/blenkernel/intern/library_remap.c
@@ -326,17 +326,7 @@ static void libblock_remap_data_postprocess_collection_update(
Main *bmain, Collection *old_collection, Collection *new_collection)
{
if (new_collection == NULL) {
- /* In case we unlinked old_collection (new_collection is NULL), we need
- * to remove any collection children that have been set to NULL in the
- * because of pointer replacement. */
- if (old_collection != NULL) {
- BKE_collections_child_remove_nulls(bmain, old_collection);
- }
- else {
- for (Collection *collection = bmain->collection.first; collection; collection = collection->id.next) {
- BKE_collections_child_remove_nulls(bmain, collection);
- }
- }
+ BKE_collections_child_remove_nulls(bmain, old_collection);
}
BKE_main_collection_sync_remap(bmain);