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:
Diffstat (limited to 'source/blender/blenkernel/intern/layer.c')
-rw-r--r--source/blender/blenkernel/intern/layer.c196
1 files changed, 155 insertions, 41 deletions
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 3c184ed5dcf..78139256b8b 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -379,7 +379,7 @@ void BKE_view_layer_base_deselect_all(ViewLayer *view_layer)
void BKE_view_layer_base_select(struct ViewLayer *view_layer, Base *selbase)
{
view_layer->basact = selbase;
- if ((selbase->flag & BASE_SELECTABLED) != 0) {
+ if ((selbase->flag & BASE_SELECTABLE) != 0) {
selbase->flag |= BASE_SELECTED;
}
}
@@ -493,7 +493,9 @@ static LayerCollection *collection_from_index(ListBase *lb, const int number, in
}
(*i)++;
+ }
+ for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
LayerCollection *lc_nested = collection_from_index(&lc->layer_collections, number, i);
if (lc_nested) {
return lc_nested;
@@ -591,7 +593,9 @@ static int index_from_collection(ListBase *lb, const LayerCollection *lc, int *i
}
(*i)++;
+ }
+ for (LayerCollection *lcol = lb->first; lcol; lcol = lcol->next) {
int i_nested = index_from_collection(&lcol->layer_collections, lc, i);
if (i_nested != -1) {
return i_nested;
@@ -621,7 +625,7 @@ int BKE_layer_collection_findindex(ViewLayer *view_layer, const LayerCollection
* in at least one layer collection. That list is also synchronized here, and
* stores state like selection. */
-static void layer_collection_sync(
+static int layer_collection_sync(
ViewLayer *view_layer, const ListBase *lb_scene,
ListBase *lb_layer, ListBase *new_object_bases,
int parent_exclude, int parent_restrict)
@@ -648,6 +652,7 @@ static void layer_collection_sync(
/* Add layer collections for any new scene collections, and ensure order is the same. */
ListBase new_lb_layer = {NULL, NULL};
+ int runtime_flag = 0;
for (const CollectionChild *child = lb_scene->first; child; child = child->next) {
Collection *collection = child->collection;
@@ -669,15 +674,19 @@ static void layer_collection_sync(
}
/* Sync child collections. */
- layer_collection_sync(
+ int child_runtime_flag = layer_collection_sync(
view_layer, &collection->children,
&lc->layer_collections, new_object_bases,
lc->flag, child_restrict);
/* Layer collection exclude is not inherited. */
if (lc->flag & LAYER_COLLECTION_EXCLUDE) {
+ lc->runtime_flag = 0;
continue;
}
+ else {
+ lc->runtime_flag = child_runtime_flag;
+ }
/* Sync objects, except if collection was excluded. */
for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) {
@@ -699,22 +708,50 @@ static void layer_collection_sync(
BLI_ghash_insert(view_layer->object_bases_hash, base->object, base);
}
- if ((child_restrict & COLLECTION_RESTRICT_VIEW) == 0) {
- base->flag |= BASE_VISIBLED | BASE_VISIBLE_VIEWPORT;
+ int object_restrict = base->object->restrictflag;
- if ((child_restrict & COLLECTION_RESTRICT_SELECT) == 0) {
- base->flag |= BASE_SELECTABLED;
+ if (((child_restrict & COLLECTION_RESTRICT_VIEW) == 0) &&
+ ((object_restrict & OB_RESTRICT_VIEW) == 0))
+ {
+ base->flag |= BASE_VISIBLE | BASE_ENABLED | BASE_ENABLED_VIEWPORT;
+
+ if (((child_restrict & COLLECTION_RESTRICT_SELECT) == 0) &&
+ ((object_restrict & OB_RESTRICT_SELECT) == 0))
+ {
+ base->flag |= BASE_SELECTABLE;
}
}
- if ((child_restrict & COLLECTION_RESTRICT_RENDER) == 0) {
- base->flag |= BASE_VISIBLE_RENDER;
+
+ if (((child_restrict & COLLECTION_RESTRICT_RENDER) == 0) &&
+ ((object_restrict & OB_RESTRICT_RENDER) == 0))
+
+ {
+ base->flag |= BASE_ENABLED_RENDER;
}
+
+ /* Update runtime flags used for display and tools. */
+ if (base->flag & BASE_VISIBLE) {
+ lc->runtime_flag |= LAYER_COLLECTION_HAS_ENABLED_OBJECTS;
+ }
+
+ if (base->flag & BASE_HIDDEN) {
+ view_layer->runtime_flag |= VIEW_LAYER_HAS_HIDE;
+ }
+ else if (base->flag & BASE_VISIBLE) {
+ lc->runtime_flag |= LAYER_COLLECTION_HAS_VISIBLE_OBJECTS;
+ }
+
+ lc->runtime_flag |= LAYER_COLLECTION_HAS_OBJECTS;
}
+
+ runtime_flag |= lc->runtime_flag;
}
/* Replace layer collection list with new one. */
*lb_layer = new_lb_layer;
BLI_assert(BLI_listbase_count(lb_scene) == BLI_listbase_count(lb_layer));
+
+ return runtime_flag;
}
/**
@@ -739,9 +776,11 @@ void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer)
/* Clear visible and selectable flags to be reset. */
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- base->flag &= ~(BASE_VISIBLED | BASE_SELECTABLED | BASE_VISIBLE_VIEWPORT | BASE_VISIBLE_RENDER);
+ base->flag &= ~(BASE_VISIBLE | BASE_ENABLED | BASE_SELECTABLE | BASE_ENABLED_VIEWPORT | BASE_ENABLED_RENDER);
}
+ view_layer->runtime_flag = 0;
+
/* Generate new layer connections and object bases when collections changed. */
CollectionChild child = {NULL, NULL, scene->master_collection};
const ListBase collections = {&child, &child};
@@ -847,7 +886,7 @@ bool BKE_layer_collection_objects_select(ViewLayer *view_layer, LayerCollection
}
}
else {
- if ((base->flag & BASE_SELECTABLED) && !(base->flag & BASE_SELECTED)) {
+ if ((base->flag & BASE_SELECTABLE) && !(base->flag & BASE_SELECTED)) {
base->flag |= BASE_SELECTED;
changed = true;
}
@@ -863,6 +902,95 @@ bool BKE_layer_collection_objects_select(ViewLayer *view_layer, LayerCollection
return changed;
}
+bool BKE_layer_collection_has_selected_objects(ViewLayer *view_layer, LayerCollection *lc)
+{
+ if (lc->collection->flag & COLLECTION_RESTRICT_SELECT) {
+ return false;
+ }
+
+ if (!(lc->flag & LAYER_COLLECTION_EXCLUDE)) {
+ for (CollectionObject *cob = lc->collection->gobject.first; cob; cob = cob->next) {
+ Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
+
+ if (base && (base->flag & BASE_SELECTED)) {
+ return true;
+ }
+ }
+ }
+
+ for (LayerCollection *iter = lc->layer_collections.first; iter; iter = iter->next) {
+ if (BKE_layer_collection_has_selected_objects(view_layer, iter)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* Update after toggling visibility of an object base. */
+void BKE_base_set_visible(Scene *scene, ViewLayer *view_layer, Base *base, bool extend)
+{
+ if (!extend) {
+ /* Make only one base visible. */
+ for (Base *other = view_layer->object_bases.first; other; other = other->next) {
+ other->flag |= BASE_HIDDEN;
+ }
+
+ base->flag &= ~BASE_HIDDEN;
+ }
+ else {
+ /* Toggle visibility of one base. */
+ base->flag ^= BASE_HIDDEN;
+ }
+
+ BKE_layer_collection_sync(scene, view_layer);
+}
+
+void BKE_layer_collection_set_visible(Scene *scene, ViewLayer *view_layer, LayerCollection *lc, bool extend)
+{
+ if (!extend) {
+ /* Make only objects from one collection visible. */
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ base->flag |= BASE_HIDDEN;
+ }
+
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(lc->collection, ob)
+ {
+ Base *base = BLI_ghash_lookup(view_layer->object_bases_hash, ob);
+
+ if (base) {
+ base->flag &= ~BASE_HIDDEN;
+ }
+ }
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+
+ BKE_layer_collection_activate(view_layer, lc);
+ }
+ else {
+ /* Toggle visibility of objects from collection. */
+ bool hide = (lc->runtime_flag & LAYER_COLLECTION_HAS_VISIBLE_OBJECTS) != 0;
+
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(lc->collection, ob)
+ {
+ Base *base = BLI_ghash_lookup(view_layer->object_bases_hash, ob);
+
+ if (base) {
+ if (hide) {
+ base->flag |= BASE_HIDDEN;
+ }
+ else {
+ base->flag &= ~BASE_HIDDEN;
+ }
+ }
+ }
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+ }
+
+ BKE_layer_collection_sync(scene, view_layer);
+}
+
/* ---------------------------------------------------------------------- */
static LayerCollection *find_layer_collection_by_scene_collection(LayerCollection *lc, const Collection *collection)
@@ -1487,12 +1615,12 @@ void BKE_view_layer_selected_objects_iterator_end(BLI_Iterator *UNUSED(iter))
void BKE_view_layer_visible_objects_iterator_begin(BLI_Iterator *iter, void *data_in)
{
- objects_iterator_begin(iter, data_in, BASE_VISIBLED);
+ objects_iterator_begin(iter, data_in, BASE_VISIBLE);
}
void BKE_view_layer_visible_objects_iterator_next(BLI_Iterator *iter)
{
- objects_iterator_next(iter, BASE_VISIBLED);
+ objects_iterator_next(iter, BASE_VISIBLE);
}
void BKE_view_layer_visible_objects_iterator_end(BLI_Iterator *UNUSED(iter))
@@ -1563,12 +1691,12 @@ void BKE_view_layer_selected_bases_iterator_end(BLI_Iterator *UNUSED(iter))
void BKE_view_layer_visible_bases_iterator_begin(BLI_Iterator *iter, void *data_in)
{
- object_bases_iterator_begin(iter, data_in, BASE_VISIBLED);
+ object_bases_iterator_begin(iter, data_in, BASE_VISIBLE);
}
void BKE_view_layer_visible_bases_iterator_next(BLI_Iterator *iter)
{
- object_bases_iterator_next(iter, BASE_VISIBLED);
+ object_bases_iterator_next(iter, BASE_VISIBLE);
}
void BKE_view_layer_visible_bases_iterator_end(BLI_Iterator *UNUSED(iter))
@@ -1626,7 +1754,7 @@ void BKE_view_layer_renderable_objects_iterator_next(BLI_Iterator *iter)
if (ob->id.flag & LIB_TAG_DOIT) {
ob->id.flag &= ~LIB_TAG_DOIT;
- if ((base->flag & BASE_VISIBLED) != 0) {
+ if ((base->flag & BASE_VISIBLE) != 0) {
iter->skip = false;
iter->current = ob;
}
@@ -1723,16 +1851,6 @@ void BKE_view_layer_bases_in_mode_iterator_end(BLI_Iterator *UNUSED(iter))
/** \} */
-static bool base_is_visible(Base *base, eEvaluationMode mode)
-{
- if (mode == DAG_EVAL_VIEWPORT) {
- return ((base->flag & BASE_VISIBLE_VIEWPORT) != 0);
- }
- else {
- return ((base->flag & BASE_VISIBLE_RENDER) != 0);
- }
-}
-
/* Evaluation */
void BKE_layer_eval_view_layer(
@@ -1744,6 +1862,7 @@ void BKE_layer_eval_view_layer(
/* Visibility based on depsgraph mode. */
const eEvaluationMode mode = DEG_get_mode(depsgraph);
+ const int base_flag = (mode == DAG_EVAL_VIEWPORT) ? BASE_ENABLED_VIEWPORT : BASE_ENABLED_RENDER;
/* Create array of bases, for fast index-based lookup. */
const int num_object_bases = BLI_listbase_count(&view_layer->object_bases);
@@ -1752,26 +1871,29 @@ void BKE_layer_eval_view_layer(
num_object_bases, sizeof(Base *), "view_layer->object_bases_array");
int base_index = 0;
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- /* Set visibility. */
- if (base_is_visible(base, mode)) {
- base->flag |= BASE_VISIBLED;
+ /* Compute visibility for depsgraph evaluation mode. */
+ if (base->flag & base_flag) {
+ base->flag |= BASE_ENABLED | BASE_VISIBLE;
+
+ if (mode == DAG_EVAL_VIEWPORT && (base->flag & BASE_HIDDEN)) {
+ base->flag &= ~BASE_VISIBLE;
+ }
}
else {
- base->flag &= ~(BASE_VISIBLED | BASE_SELECTABLED);
+ base->flag &= ~(BASE_ENABLED | BASE_VISIBLE | BASE_SELECTABLE);
}
/* If base is not selectabled, clear select. */
- if ((base->flag & BASE_SELECTABLED) == 0) {
+ if ((base->flag & BASE_SELECTABLE) == 0) {
base->flag &= ~BASE_SELECTED;
}
view_layer->object_bases_array[base_index++] = base;
}
-
/* Flush back base flag to the original view layer for editing. */
- ViewLayer *view_layer_orig = DEG_get_input_view_layer(depsgraph);
if (view_layer == DEG_get_evaluated_view_layer(depsgraph)) {
+ ViewLayer *view_layer_orig = DEG_get_input_view_layer(depsgraph);
Base *base_orig = view_layer_orig->object_bases.first;
const Base *base_eval = view_layer->object_bases.first;
while (base_orig != NULL) {
@@ -1780,14 +1902,6 @@ void BKE_layer_eval_view_layer(
base_eval = base_eval->next;
}
}
-
- /* Hidden objects can't be active. */
- if (view_layer->basact && !(view_layer->basact->flag & BASE_VISIBLED)) {
- view_layer->basact = NULL;
- }
- if (view_layer_orig->basact && !(view_layer_orig->basact->flag & BASE_VISIBLED)) {
- view_layer_orig->basact = NULL;
- }
}
void BKE_layer_eval_view_layer_indexed(