diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h index 5682e3b9815..ae70e90189f 100644 --- a/source/blender/blenkernel/BKE_layer.h +++ b/source/blender/blenkernel/BKE_layer.h @@ -71,6 +71,8 @@ void BKE_view_layer_selected_objects_tag(struct ViewLayer *view_layer, const int struct Object *BKE_view_layer_camera_find(struct ViewLayer *view_layer); struct ViewLayer *BKE_view_layer_find_from_collection(const struct Scene *scene, struct LayerCollection *lc); +ViewLayer *BKE_view_layer_find_from_collection_non_layer(const struct Scene *scene, + const struct Collection *collection); struct Base *BKE_view_layer_base_find(struct ViewLayer *view_layer, struct Object *ob); void BKE_view_layer_base_deselect_all(struct ViewLayer *view_layer); diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index 7ab63810719..b94c0dfb7af 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -1720,8 +1720,6 @@ bool BKE_collection_objects_select(ViewLayer *view_layer, Collection *collection /* Local temporary storage for layer collection flags. */ typedef struct LayerCollectionFlag { struct LayerCollectionFlag *next, *prev; - /** The view layer for the collections being moved, NULL for their children. */ - ViewLayer *view_layer; /** The original #LayerCollection's collection field. */ Collection *collection; /** The original #LayerCollection's flag. */ @@ -1746,6 +1744,9 @@ static void layer_collection_flags_store_recursive(const LayerCollection *layer_ /** * For every view layer, find the \a collection and save flags * for it and its children in a temporary tree structure. + * + * \note The process of storing and restoring the LayerCollection flags relies on the + * pointers for the Collections themselves staying the same across the move. */ static void layer_collection_flags_store(Main *bmain, const Collection *collection, @@ -1763,7 +1764,6 @@ static void layer_collection_flags_store(Main *bmain, /* Store the flags for the collection and all of its children. */ LayerCollectionFlag *flag = MEM_callocN(sizeof(LayerCollectionFlag), __func__); - flag->view_layer = view_layer; /* Recursively save flags from collection children. */ layer_collection_flags_store_recursive(layer_collection, flag); @@ -1805,15 +1805,19 @@ static void layer_collection_flags_restore_recursive(LayerCollection *layer_coll * Restore a collection's (and its children's) flags for each view layer * from the structure built in #layer_collection_flags_store. */ -static void layer_collection_flags_restore(ListBase *flags, const Collection *collection) +static void layer_collection_flags_restore(Main *bmain, + ListBase *flags, + const Collection *collection) { LISTBASE_FOREACH (LayerCollectionFlag *, flag, flags) { - ViewLayer *view_layer = flag->view_layer; - /* The top level of flag structs must have this set. */ - BLI_assert(view_layer != NULL); + /* Find the view layer the collection was moved to. */ + Scene *scene = BKE_scene_find_from_collection(bmain, collection); + ViewLayer *target_view_layer = BKE_view_layer_find_from_collection_non_layer(scene, + collection); + BLI_assert(target_view_layer != NULL); LayerCollection *layer_collection = BKE_layer_collection_first_from_scene_collection( - view_layer, collection); + target_view_layer, collection); /* The flags should only be added if the collection is in the view layer. */ BLI_assert(layer_collection != NULL); @@ -1872,7 +1876,7 @@ bool BKE_collection_move(Main *bmain, BKE_main_collection_sync(bmain); /* Restore the original layer collection flags. */ - layer_collection_flags_restore(&layer_flags, collection); + layer_collection_flags_restore(bmain, &layer_flags, collection); /* We need to sync it again to pass the correct flags to the collections objects. */ BKE_main_collection_sync(bmain); diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c index 0757cf791b7..84abff4e969 100644 --- a/source/blender/blenkernel/intern/layer.c +++ b/source/blender/blenkernel/intern/layer.c @@ -353,6 +353,37 @@ ViewLayer *BKE_view_layer_find_from_collection(const Scene *scene, LayerCollecti return NULL; } +static bool layer_collections_contain_collection_recursive(ListBase *lb, + const Collection *collection) +{ + LISTBASE_FOREACH (LayerCollection *, layer_collection, lb) { + if (layer_collection->collection == collection) { + return true; + } + if (layer_collections_contain_collection_recursive(&layer_collection->layer_collections, + collection)) { + return true; + } + } + return false; +} + +/** + * Find the #ViewLayer a #Collection belongs to. + */ +ViewLayer *BKE_view_layer_find_from_collection_non_layer(const Scene *scene, + const Collection *collection) +{ + LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) { + if (layer_collections_contain_collection_recursive(&view_layer->layer_collections, + collection)) { + return view_layer; + } + } + + return NULL; +} + /* Base */ static void view_layer_bases_hash_create(ViewLayer *view_layer)