Commit: 47159f1609c2bd4c259dd7cfbe23655ddb55a271
Author: Hans Goudey
Date:   Fri Dec 11 12:15:51 2020 -0600
Branches: blender-v2.91-release
https://developer.blender.org/rB47159f1609c2bd4c259dd7cfbe23655ddb55a271

Fix T83050: Crash dragging shared collection to master collection

The flag syncing code expects to find collection flags in same view
layer before and after the move, it even has an assert for it. However,
there is one case where this doesn't happen, when dragging a collection
that exists in two scenes to the master collection.

This commit removes this assert, frees the temporary flag structs
separately, and updates some comments with this information.
There is more detail in the adjusted comment.

Differential Revision: https://developer.blender.org/D9785

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

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

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

diff --git a/source/blender/blenkernel/intern/collection.c 
b/source/blender/blenkernel/intern/collection.c
index e6620ea10dc..4591529f519 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -1598,6 +1598,15 @@ static void layer_collection_flags_store(Main *bmain,
   }
 }
 
+static void layer_collection_flags_free_recursive(LayerCollectionFlag *flag)
+{
+  LISTBASE_FOREACH (LayerCollectionFlag *, child, &flag->children) {
+    layer_collection_flags_free_recursive(child);
+  }
+
+  BLI_freelistN(&flag->children);
+}
+
 static void layer_collection_flags_restore_recursive(LayerCollection 
*layer_collection,
                                                      LayerCollectionFlag *flag)
 {
@@ -1613,7 +1622,6 @@ static void 
layer_collection_flags_restore_recursive(LayerCollection *layer_coll
 
     child_flag = child_flag->next;
   }
-  BLI_freelistN(&flag->children);
 
   /* We treat exclude as a special case.
    *
@@ -1639,10 +1647,15 @@ static void layer_collection_flags_restore(ListBase 
*flags, const Collection *co
 
     LayerCollection *layer_collection = 
BKE_layer_collection_first_from_scene_collection(
         view_layer, collection);
-    /* The flags should only be added if the collection is in the view layer. 
*/
-    BLI_assert(layer_collection != NULL);
-
-    layer_collection_flags_restore_recursive(layer_collection, flag);
+    /* Check that the collection is still in the scene (and therefore its view 
layers). In most
+     * cases this is true, but if we move a sub-collection shared by several 
scenes to a collection
+     * local to the target scene, it is effectively removed from every other 
scene's hierarchy
+     * (e.g. moving into current scene's master collection). Then the other 
scene's view layers
+     * won't contain a matching layer collection anymore, so there is nothing 
to restore to. */
+    if (layer_collection != NULL) {
+      layer_collection_flags_restore_recursive(layer_collection, flag);
+    }
+    layer_collection_flags_free_recursive(flag);
   }
 
   BLI_freelistN(flags);
@@ -1702,7 +1715,7 @@ bool BKE_collection_move(Main *bmain,
   /* Create and remove layer collections. */
   BKE_main_collection_sync(bmain);
 
-  /* Restore the original layer collection flags. */
+  /* Restore the original layer collection flags and free their temporary 
storage. */
   if (do_flag_sync) {
     layer_collection_flags_restore(&layer_flags, collection);
   }

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to