Remove the code in `BKE_collection_move` to preserve LayerCollection flags.
This code was actually buggy (forcefully re-enabling excluded layers in some cases). Further more, it should not be needed now that layerCollection resync code reuses as much as possible existing layers instead of deleting and re-creating them all the time. Differential Revision: https://developer.blender.org/D12016
This commit is contained in:
parent
b18d0244fc
commit
3db37075f6
|
@ -1809,125 +1809,6 @@ bool BKE_collection_objects_select(ViewLayer *view_layer, Collection *collection
|
|||
/** \name Collection move (outliner drag & drop)
|
||||
* \{ */
|
||||
|
||||
/* 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. */
|
||||
int flag;
|
||||
/** Corresponds to #LayerCollection->layer_collections. */
|
||||
ListBase children;
|
||||
} LayerCollectionFlag;
|
||||
|
||||
static void layer_collection_flags_store_recursive(const LayerCollection *layer_collection,
|
||||
LayerCollectionFlag *flag)
|
||||
{
|
||||
flag->collection = layer_collection->collection;
|
||||
flag->flag = layer_collection->flag;
|
||||
|
||||
LISTBASE_FOREACH (const LayerCollection *, child, &layer_collection->layer_collections) {
|
||||
LayerCollectionFlag *child_flag = MEM_callocN(sizeof(LayerCollectionFlag), __func__);
|
||||
BLI_addtail(&flag->children, child_flag);
|
||||
layer_collection_flags_store_recursive(child, child_flag);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For every view layer, find the \a collection and save flags
|
||||
* for it and its children in a temporary tree structure.
|
||||
*/
|
||||
static void layer_collection_flags_store(Main *bmain,
|
||||
const Collection *collection,
|
||||
ListBase *r_layer_level_list)
|
||||
{
|
||||
BLI_listbase_clear(r_layer_level_list);
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
|
||||
LayerCollection *layer_collection = BKE_layer_collection_first_from_scene_collection(
|
||||
view_layer, collection);
|
||||
/* Skip this view layer if the collection isn't found for some reason. */
|
||||
if (layer_collection == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
BLI_addtail(r_layer_level_list, flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
/* There should be a flag struct for every layer collection. */
|
||||
BLI_assert(BLI_listbase_count(&layer_collection->layer_collections) ==
|
||||
BLI_listbase_count(&flag->children));
|
||||
/* The flag and the layer collection should actually correspond. */
|
||||
BLI_assert(flag->collection == layer_collection->collection);
|
||||
|
||||
LayerCollectionFlag *child_flag = flag->children.first;
|
||||
LISTBASE_FOREACH (LayerCollection *, child, &layer_collection->layer_collections) {
|
||||
layer_collection_flags_restore_recursive(child, child_flag);
|
||||
|
||||
child_flag = child_flag->next;
|
||||
}
|
||||
|
||||
/* We treat exclude as a special case.
|
||||
*
|
||||
* If in a different view layer the parent collection was disabled (e.g., background)
|
||||
* and now we moved a new collection to be part of the background this collection should
|
||||
* probably be disabled.
|
||||
*
|
||||
* NOTE: If we were to also keep the exclude flag we would need to re-sync the collections.
|
||||
*/
|
||||
layer_collection->flag = flag->flag | (layer_collection->flag & LAYER_COLLECTION_EXCLUDE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
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);
|
||||
|
||||
LayerCollection *layer_collection = BKE_layer_collection_first_from_scene_collection(
|
||||
view_layer, collection);
|
||||
/* 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);
|
||||
}
|
||||
|
||||
bool BKE_collection_move(Main *bmain,
|
||||
Collection *to_parent,
|
||||
Collection *from_parent,
|
||||
|
@ -1968,26 +1849,7 @@ bool BKE_collection_move(Main *bmain,
|
|||
}
|
||||
}
|
||||
|
||||
/* Make sure we store the flag of the layer collections before we remove and re-create them.
|
||||
* Otherwise they will get lost and everything will be copied from the new parent collection.
|
||||
* Don't use flag syncing when moving a collection to a different scene, as it no longer exists
|
||||
* in the same view layers anyway. */
|
||||
const bool do_flag_sync = BKE_scene_find_from_collection(bmain, to_parent) ==
|
||||
BKE_scene_find_from_collection(bmain, collection);
|
||||
ListBase layer_flags;
|
||||
if (do_flag_sync) {
|
||||
layer_collection_flags_store(bmain, collection, &layer_flags);
|
||||
}
|
||||
|
||||
/* Create and remove layer collections. */
|
||||
BKE_main_collection_sync(bmain);
|
||||
|
||||
/* Restore the original layer collection flags and free their temporary storage. */
|
||||
if (do_flag_sync) {
|
||||
layer_collection_flags_restore(&layer_flags, collection);
|
||||
}
|
||||
|
||||
/* We need to sync it again to pass the correct flags to the collections objects. */
|
||||
/* Update layer collections. */
|
||||
BKE_main_collection_sync(bmain);
|
||||
|
||||
return true;
|
||||
|
|
Loading…
Reference in New Issue