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 <bastien@blender.org>2022-08-25 13:18:54 +0300
committerBastien Montagne <bastien@blender.org>2022-08-25 13:22:38 +0300
commitee7bd79b54a32d64fe0337695d438ad34990d121 (patch)
tree023dc1d0995c16ed01dbe809324585fbd38f7e3f /source/blender/blenkernel/intern
parentd4764a385abb9420e139fffb8909dd914d894d6f (diff)
LibOverride: Preserve viewlayers when creating overrides of collecitons.
Usually, when overriding collections, the linked reference ones are removed from the ViewLayer, and the overrides replace them. This change to `layer_collection_sync` code makes it so that in case there is a free viewlayer hierarchy matching the linked collection, it gets re-used for the override one, instead of re-creating everything from scratch. To achieve this, resync process is split into two steps, first regular collections are processed, then the override ones. This should ensure an override does not steal the layers of its reference if the later is still instantiated in the view layer.
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/layer.c187
1 files changed, 98 insertions, 89 deletions
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 53a9b6d469d..69e3fd1f5a4 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -879,7 +879,10 @@ static LayerCollectionResync *layer_collection_resync_find(LayerCollectionResync
current_layer_resync = queue_head;
queue_head = current_layer_resync->queue_next;
- if (current_layer_resync->collection == child_collection &&
+ if ((current_layer_resync->collection == child_collection ||
+ (ID_IS_OVERRIDE_LIBRARY(child_collection) &&
+ (&current_layer_resync->collection->id ==
+ child_collection->id.override_library->reference))) &&
(current_layer_resync->parent_layer_resync == layer_resync ||
(!current_layer_resync->is_used && !current_layer_resync->is_valid_as_child))) {
/* This layer is a valid candidate, because its collection matches the seeked one, AND:
@@ -1048,107 +1051,113 @@ static void layer_collection_sync(ViewLayer *view_layer,
BLI_assert(layer_resync->is_used);
- LISTBASE_FOREACH (CollectionChild *, child, &layer_resync->collection->children) {
- Collection *child_collection = child->collection;
- LayerCollectionResync *child_layer_resync = layer_collection_resync_find(layer_resync,
- child_collection);
+ for (int i = 1; i >= 0; i--) {
+ LISTBASE_FOREACH (CollectionChild *, child, &layer_resync->collection->children) {
+ Collection *child_collection = child->collection;
+ if (ID_IS_OVERRIDE_LIBRARY(child_collection) != (i == 0)) {
+ continue;
+ }
- if (child_layer_resync != NULL) {
- BLI_assert(child_layer_resync->collection != NULL);
- BLI_assert(child_layer_resync->layer != NULL);
- BLI_assert(child_layer_resync->is_usable);
+ LayerCollectionResync *child_layer_resync = layer_collection_resync_find(layer_resync,
+ child_collection);
- if (child_layer_resync->is_used) {
- CLOG_INFO(&LOG,
- 4,
- "Found same existing LayerCollection for %s as child of %s",
- child_collection->id.name,
- layer_resync->collection->id.name);
+ if (child_layer_resync != NULL) {
+ BLI_assert(child_layer_resync->collection != NULL);
+ BLI_assert(child_layer_resync->layer != NULL);
+ BLI_assert(child_layer_resync->is_usable);
+
+ if (child_layer_resync->is_used) {
+ CLOG_INFO(&LOG,
+ 4,
+ "Found same existing LayerCollection for %s as child of %s",
+ child_collection->id.name,
+ layer_resync->collection->id.name);
+ }
+ else {
+ CLOG_INFO(&LOG,
+ 4,
+ "Found a valid unused LayerCollection for %s as child of %s, re-using it",
+ child_collection->id.name,
+ layer_resync->collection->id.name);
+ }
+
+ child_layer_resync->is_used = true;
+
+ /* NOTE: Do not move the resync wrapper to match the new layer hierarchy, so that the old
+ * parenting info remains available. In case a search for a valid layer in the children of
+ * the current is required again, the old parenting hierarchy is needed as reference, not
+ * the new one.
+ */
+ BLI_remlink(&child_layer_resync->parent_layer_resync->layer->layer_collections,
+ child_layer_resync->layer);
+ BLI_addtail(&new_lb_layer, child_layer_resync->layer);
}
else {
CLOG_INFO(&LOG,
4,
- "Found a valid unused LayerCollection for %s as child of %s, re-using it",
+ "No available LayerCollection for %s as child of %s, creating a new one",
child_collection->id.name,
layer_resync->collection->id.name);
+
+ LayerCollection *child_layer = layer_collection_add(&new_lb_layer, child_collection);
+ child_layer->flag = parent_layer_flag;
+
+ child_layer_resync = BLI_mempool_calloc(layer_resync_mempool);
+ child_layer_resync->collection = child_collection;
+ child_layer_resync->layer = child_layer;
+ child_layer_resync->is_usable = true;
+ child_layer_resync->is_used = true;
+ child_layer_resync->is_valid_as_child = true;
+ child_layer_resync->is_valid_as_parent = true;
+ /* NOTE: Needs to be added to the layer_resync hierarchy so that the resync wrapper gets
+ * freed at the end. */
+ child_layer_resync->parent_layer_resync = layer_resync;
+ BLI_addtail(&layer_resync->children_layer_resync, child_layer_resync);
}
- child_layer_resync->is_used = true;
+ LayerCollection *child_layer = child_layer_resync->layer;
- /* NOTE: Do not move the resync wrapper to match the new layer hierarchy, so that the old
- * parenting info remains available. In case a search for a valid layer in the children of
- * the current is required again, the old parenting hierarchy is needed as reference, not the
- * new one.
- */
- BLI_remlink(&child_layer_resync->parent_layer_resync->layer->layer_collections,
- child_layer_resync->layer);
- BLI_addtail(&new_lb_layer, child_layer_resync->layer);
- }
- else {
- CLOG_INFO(&LOG,
- 4,
- "No available LayerCollection for %s as child of %s, creating a new one",
- child_collection->id.name,
- layer_resync->collection->id.name);
-
- LayerCollection *child_layer = layer_collection_add(&new_lb_layer, child_collection);
- child_layer->flag = parent_layer_flag;
-
- child_layer_resync = BLI_mempool_calloc(layer_resync_mempool);
- child_layer_resync->collection = child_collection;
- child_layer_resync->layer = child_layer;
- child_layer_resync->is_usable = true;
- child_layer_resync->is_used = true;
- child_layer_resync->is_valid_as_child = true;
- child_layer_resync->is_valid_as_parent = true;
- /* NOTE: Needs to be added to the layer_resync hierarchy so that the resync wrapper gets
- * freed at the end. */
- child_layer_resync->parent_layer_resync = layer_resync;
- BLI_addtail(&layer_resync->children_layer_resync, child_layer_resync);
- }
-
- LayerCollection *child_layer = child_layer_resync->layer;
-
- const ushort child_local_collections_bits = parent_local_collections_bits &
- child_layer->local_collections_bits;
-
- /* Tag linked collection as a weak reference so we keep the layer
- * collection pointer on file load and remember exclude state. */
- id_lib_indirect_weak_link(&child_collection->id);
-
- /* Collection restrict is inherited. */
- short child_collection_restrict = parent_collection_restrict;
- short child_layer_restrict = parent_layer_restrict;
- if (!(child_collection->flag & COLLECTION_IS_MASTER)) {
- child_collection_restrict |= child_collection->flag;
- child_layer_restrict |= child_layer->flag;
- }
-
- /* Sync child collections. */
- layer_collection_sync(view_layer,
- child_layer_resync,
- layer_resync_mempool,
- r_lb_new_object_bases,
- child_layer->flag,
- child_collection_restrict,
- child_layer_restrict,
- child_local_collections_bits);
-
- /* Layer collection exclude is not inherited. */
- child_layer->runtime_flag = 0;
- if (child_layer->flag & LAYER_COLLECTION_EXCLUDE) {
- continue;
- }
+ const ushort child_local_collections_bits = parent_local_collections_bits &
+ child_layer->local_collections_bits;
- /* We separate restrict viewport and visible view layer because a layer collection can be
- * hidden in the view layer yet (locally) visible in a viewport (if it is not restricted). */
- if (child_collection_restrict & COLLECTION_HIDE_VIEWPORT) {
- child_layer->runtime_flag |= LAYER_COLLECTION_HIDE_VIEWPORT;
- }
+ /* Tag linked collection as a weak reference so we keep the layer
+ * collection pointer on file load and remember exclude state. */
+ id_lib_indirect_weak_link(&child_collection->id);
+
+ /* Collection restrict is inherited. */
+ short child_collection_restrict = parent_collection_restrict;
+ short child_layer_restrict = parent_layer_restrict;
+ if (!(child_collection->flag & COLLECTION_IS_MASTER)) {
+ child_collection_restrict |= child_collection->flag;
+ child_layer_restrict |= child_layer->flag;
+ }
- if (((child_layer->runtime_flag & LAYER_COLLECTION_HIDE_VIEWPORT) == 0) &&
- ((child_layer_restrict & LAYER_COLLECTION_HIDE) == 0)) {
- child_layer->runtime_flag |= LAYER_COLLECTION_VISIBLE_VIEW_LAYER;
+ /* Sync child collections. */
+ layer_collection_sync(view_layer,
+ child_layer_resync,
+ layer_resync_mempool,
+ r_lb_new_object_bases,
+ child_layer->flag,
+ child_collection_restrict,
+ child_layer_restrict,
+ child_local_collections_bits);
+
+ /* Layer collection exclude is not inherited. */
+ child_layer->runtime_flag = 0;
+ if (child_layer->flag & LAYER_COLLECTION_EXCLUDE) {
+ continue;
+ }
+
+ /* We separate restrict viewport and visible view layer because a layer collection can be
+ * hidden in the view layer yet (locally) visible in a viewport (if it is not restricted). */
+ if (child_collection_restrict & COLLECTION_HIDE_VIEWPORT) {
+ child_layer->runtime_flag |= LAYER_COLLECTION_HIDE_VIEWPORT;
+ }
+
+ if (((child_layer->runtime_flag & LAYER_COLLECTION_HIDE_VIEWPORT) == 0) &&
+ ((child_layer_restrict & LAYER_COLLECTION_HIDE) == 0)) {
+ child_layer->runtime_flag |= LAYER_COLLECTION_VISIBLE_VIEW_LAYER;
+ }
}
}