Cleanup: LayerCollection resync code.

Mainly naming (also droping the `layer_collection`  in favor of just
`layer` for internal code, this is clear enough and much shorter). Add
proper parent/child identifiers, `r_` prefix for parameters also used as
return values, etc.

Also made some parameters const.
This commit is contained in:
Bastien Montagne 2021-07-15 12:46:38 +02:00
parent 2e8641e45e
commit e7e5fd96c4
1 changed files with 62 additions and 60 deletions

View File

@ -739,7 +739,7 @@ int BKE_layer_collection_findindex(ViewLayer *view_layer, const LayerCollection
static void layer_collection_objects_sync(ViewLayer *view_layer,
LayerCollection *layer,
ListBase *new_object_bases,
ListBase *lb_new_object_bases,
const short collection_restrict,
const short layer_restrict,
const ushort local_collections_bits)
@ -765,9 +765,9 @@ static void layer_collection_objects_sync(ViewLayer *view_layer,
* been moved to the new base list and the first/last test ensure that
* case also works. */
base = *base_p;
if (!ELEM(base, new_object_bases->first, new_object_bases->last)) {
if (!ELEM(base, lb_new_object_bases->first, lb_new_object_bases->last)) {
BLI_remlink(&view_layer->object_bases, base);
BLI_addtail(new_object_bases, base);
BLI_addtail(lb_new_object_bases, base);
}
}
else {
@ -775,7 +775,7 @@ static void layer_collection_objects_sync(ViewLayer *view_layer,
base = object_base_new(cob->ob);
base->local_collections_bits = local_collections_bits;
*base_p = base;
BLI_addtail(new_object_bases, base);
BLI_addtail(lb_new_object_bases, base);
}
if ((collection_restrict & COLLECTION_RESTRICT_VIEWPORT) == 0) {
@ -805,124 +805,125 @@ static void layer_collection_objects_sync(ViewLayer *view_layer,
}
static void layer_collection_sync(ViewLayer *view_layer,
const ListBase *lb_collections,
ListBase *lb_layer_collections,
ListBase *new_object_bases,
short parent_exclude,
short parent_restrict,
short parent_layer_restrict,
unsigned short parent_local_collections_bits)
const ListBase *lb_children_collections,
ListBase *r_lb_children_layers,
ListBase *r_lb_new_object_bases,
const short parent_layer_flag,
const short parent_collection_restrict,
const short parent_layer_restrict,
const ushort parent_local_collections_bits)
{
/* TODO: support recovery after removal of intermediate collections, reordering, ..
* For local edits we can make editing operating do the appropriate thing, but for
* linking we can only sync after the fact. */
/* Remove layer collections that no longer have a corresponding scene collection. */
LISTBASE_FOREACH_MUTABLE (LayerCollection *, lc, lb_layer_collections) {
/* Note that ID remap can set lc->collection to NULL when deleting collections. */
Collection *collection = (lc->collection) ?
BLI_findptr(lb_collections,
lc->collection,
offsetof(CollectionChild, collection)) :
NULL;
LISTBASE_FOREACH_MUTABLE (LayerCollection *, child_layer, r_lb_children_layers) {
/* Note that ID remap can set child_layer->collection to NULL when deleting collections. */
Collection *child_collection = (child_layer->collection != NULL) ?
BLI_findptr(lb_children_collections,
child_layer->collection,
offsetof(CollectionChild, collection)) :
NULL;
if (!collection) {
if (lc == view_layer->active_collection) {
if (child_collection == NULL) {
if (child_layer == view_layer->active_collection) {
view_layer->active_collection = NULL;
}
/* Free recursively. */
layer_collection_free(view_layer, lc);
BLI_freelinkN(lb_layer_collections, lc);
layer_collection_free(view_layer, child_layer);
BLI_freelinkN(r_lb_children_layers, child_layer);
}
}
/* Add layer collections for any new scene collections, and ensure order is the same. */
ListBase new_lb_layer = {NULL, NULL};
ListBase lb_new_children_layers = {NULL, NULL};
LISTBASE_FOREACH (const CollectionChild *, child, lb_collections) {
Collection *collection = child->collection;
LayerCollection *lc = BLI_findptr(
lb_layer_collections, collection, offsetof(LayerCollection, collection));
LISTBASE_FOREACH (const CollectionChild *, child, lb_children_collections) {
Collection *child_collection = child->collection;
LayerCollection *child_layer = BLI_findptr(
r_lb_children_layers, child_collection, offsetof(LayerCollection, collection));
if (lc) {
BLI_remlink(lb_layer_collections, lc);
BLI_addtail(&new_lb_layer, lc);
if (child_layer) {
BLI_remlink(r_lb_children_layers, child_layer);
BLI_addtail(&lb_new_children_layers, child_layer);
}
else {
lc = layer_collection_add(&new_lb_layer, collection);
lc->flag = parent_exclude;
child_layer = layer_collection_add(&lb_new_children_layers, child_collection);
child_layer->flag = parent_layer_flag;
}
unsigned short local_collections_bits = parent_local_collections_bits &
lc->local_collections_bits;
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(&collection->id);
id_lib_indirect_weak_link(&child_collection->id);
/* Collection restrict is inherited. */
short child_restrict = parent_restrict;
short child_collection_restrict = parent_collection_restrict;
short child_layer_restrict = parent_layer_restrict;
if (!(collection->flag & COLLECTION_IS_MASTER)) {
child_restrict |= collection->flag;
child_layer_restrict |= lc->flag;
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,
&collection->children,
&lc->layer_collections,
new_object_bases,
lc->flag,
child_restrict,
&child_collection->children,
&child_layer->layer_collections,
r_lb_new_object_bases,
child_layer->flag,
child_collection_restrict,
child_layer_restrict,
local_collections_bits);
child_local_collections_bits);
/* Layer collection exclude is not inherited, we can skip the remaining process, including
* object bases synchronization. */
lc->runtime_flag = 0;
if (lc->flag & LAYER_COLLECTION_EXCLUDE) {
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_restrict & COLLECTION_RESTRICT_VIEWPORT) {
lc->runtime_flag |= LAYER_COLLECTION_RESTRICT_VIEWPORT;
if (child_collection_restrict & COLLECTION_RESTRICT_VIEWPORT) {
child_layer->runtime_flag |= LAYER_COLLECTION_RESTRICT_VIEWPORT;
}
if (((lc->runtime_flag & LAYER_COLLECTION_RESTRICT_VIEWPORT) == 0) &&
if (((child_layer->runtime_flag & LAYER_COLLECTION_RESTRICT_VIEWPORT) == 0) &&
((child_layer_restrict & LAYER_COLLECTION_HIDE) == 0)) {
lc->runtime_flag |= LAYER_COLLECTION_VISIBLE_VIEW_LAYER;
child_layer->runtime_flag |= LAYER_COLLECTION_VISIBLE_VIEW_LAYER;
}
layer_collection_objects_sync(view_layer,
lc,
new_object_bases,
child_restrict,
child_layer,
r_lb_new_object_bases,
child_collection_restrict,
child_layer_restrict,
local_collections_bits);
child_local_collections_bits);
}
/* Free potentially remaining unused layer collections in old list.
* NOTE: While this does not happen in typical situations, some corner cases (like remapping
* several different collections to a single one) can lead to this list having extra unused
* items. */
LISTBASE_FOREACH_MUTABLE (LayerCollection *, lc, lb_layer_collections) {
LISTBASE_FOREACH_MUTABLE (LayerCollection *, lc, r_lb_children_layers) {
if (lc == view_layer->active_collection) {
view_layer->active_collection = NULL;
}
/* Free recursively. */
layer_collection_free(view_layer, lc);
BLI_freelinkN(lb_layer_collections, lc);
BLI_freelinkN(r_lb_children_layers, lc);
}
BLI_assert(BLI_listbase_is_empty(lb_layer_collections));
BLI_assert(BLI_listbase_is_empty(r_lb_children_layers));
/* Replace layer collection list with new one. */
*lb_layer_collections = new_lb_layer;
BLI_assert(BLI_listbase_count(lb_collections) == BLI_listbase_count(lb_layer_collections));
*r_lb_children_layers = lb_new_children_layers;
BLI_assert(BLI_listbase_count(lb_children_collections) ==
BLI_listbase_count(r_lb_children_layers));
}
/**
@ -981,6 +982,7 @@ void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer)
view_layer->object_bases = new_object_bases;
LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
printf("%s\n", base->object->id.name);
BKE_base_eval_flags(base);
}