diff options
Diffstat (limited to 'source/blender/blenkernel/intern/layer.c')
-rw-r--r-- | source/blender/blenkernel/intern/layer.c | 196 |
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( |