Commit: f887dc1f5c8414f3a5ad6927730a3a74684ddf26
Author: Bastien Montagne
Date:   Mon Oct 29 11:42:38 2018 +0100
Branches: blender2.8
https://developer.blender.org/rBf887dc1f5c8414f3a5ad6927730a3a74684ddf26

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...).

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

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

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

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);

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to