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:
authorDalai Felinto <dfelinto@gmail.com>2019-08-19 20:25:29 +0300
committerDalai Felinto <dfelinto@gmail.com>2019-09-13 18:37:35 +0300
commit92736a7b75920ffe4b8016a2d097ff8e36687c70 (patch)
tree33594ff97ce96124481ce9d898ea31158f91236c /source/blender
parentce34a6b0d727bbde6ae373afa8ec6c42bc8980ce (diff)
Per-Viewport Collection Visibility
Support per-viewport collection visibility options. Note 1: There is no way to show a collection that was not visible before due to depsgraph. Otherwise we would risk having all the collections in the depsgraph and I believe this is not the idea. An alternative would be to have a new depsgraph for viewports that are not local. Something to keep in mind if we do per-viewport current frame in the future. So for now what we do is to only allow collections visibility to be disabled/hidden in this mode. Note 2: hide_viewport (the eye icon) doesn't really matter for depsgraph. So after the merge we can still ignore it to show the collections locally in a viewport with no problems for the depsgraph. Reviewers: brecht, sergey Subscribers: billreynish Related task: T61327 Differential Revision: https://developer.blender.org/D5611
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_layer.h5
-rw-r--r--source/blender/blenkernel/intern/layer.c112
-rw-r--r--source/blender/blenkernel/intern/object_update.c1
-rw-r--r--source/blender/blenloader/intern/versioning_280.c21
-rw-r--r--source/blender/draw/intern/draw_manager.c23
-rw-r--r--source/blender/editors/include/ED_view3d.h4
-rw-r--r--source/blender/editors/object/object_edit.c20
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c136
-rw-r--r--source/blender/makesdna/DNA_layer_types.h6
-rw-r--r--source/blender/makesdna/DNA_object_types.h3
-rw-r--r--source/blender/makesdna/DNA_scene_types.h2
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h4
-rw-r--r--source/blender/makesrna/intern/rna_layer.c27
-rw-r--r--source/blender/makesrna/intern/rna_space.c21
-rw-r--r--source/blender/windowmanager/intern/wm_files.c1
15 files changed, 373 insertions, 13 deletions
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index eb65b7641e1..535980840c1 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -90,6 +90,7 @@ int BKE_layer_collection_findindex(struct ViewLayer *view_layer, const struct La
void BKE_main_collection_sync(const struct Main *bmain);
void BKE_scene_collection_sync(const struct Scene *scene);
void BKE_layer_collection_sync(const struct Scene *scene, struct ViewLayer *view_layer);
+void BKE_layer_collection_local_sync(struct ViewLayer *view_layer, struct View3D *v3d);
void BKE_main_collection_sync_remap(const struct Main *bmain);
@@ -117,6 +118,10 @@ void BKE_layer_collection_isolate(struct Scene *scene,
struct ViewLayer *view_layer,
struct LayerCollection *lc,
bool extend);
+void BKE_layer_collection_local_isolate(struct ViewLayer *view_layer,
+ struct View3D *v3d,
+ struct LayerCollection *lc,
+ bool extend);
void BKE_layer_collection_set_visible(struct ViewLayer *view_layer,
struct LayerCollection *lc,
const bool visible,
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index de105b9b62a..f3c0d5da6ee 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -68,6 +68,7 @@ static LayerCollection *layer_collection_add(ListBase *lb_parent, Collection *co
{
LayerCollection *lc = MEM_callocN(sizeof(LayerCollection), "Collection Base");
lc->collection = collection;
+ lc->local_collections_bits = ~(0);
BLI_addtail(lb_parent, lc);
return lc;
@@ -1083,6 +1084,117 @@ void BKE_layer_collection_isolate(Scene *scene,
BKE_layer_collection_sync(scene, view_layer);
}
+static void layer_collection_local_visibility_set_recursive(LayerCollection *layer_collection,
+ const int local_collections_uuid)
+{
+ layer_collection->local_collections_bits |= local_collections_uuid;
+ for (LayerCollection *child = layer_collection->layer_collections.first; child;
+ child = child->next) {
+ layer_collection_local_visibility_set_recursive(child, local_collections_uuid);
+ }
+}
+
+static void layer_collection_local_visibility_unset_recursive(LayerCollection *layer_collection,
+ const int local_collections_uuid)
+{
+ layer_collection->local_collections_bits &= ~local_collections_uuid;
+ for (LayerCollection *child = layer_collection->layer_collections.first; child;
+ child = child->next) {
+ layer_collection_local_visibility_unset_recursive(child, local_collections_uuid);
+ }
+}
+
+static void layer_collection_local_sync(ViewLayer *view_layer,
+ LayerCollection *layer_collection,
+ const unsigned short local_collections_uuid,
+ bool visible)
+{
+ if ((layer_collection->local_collections_bits & local_collections_uuid) == 0) {
+ visible = false;
+ }
+
+ if (visible) {
+ for (CollectionObject *cob = layer_collection->collection->gobject.first; cob;
+ cob = cob->next) {
+ BLI_assert(cob->ob);
+ Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
+ base->local_collections_bits |= local_collections_uuid;
+ }
+ }
+
+ LISTBASE_FOREACH (LayerCollection *, child, &layer_collection->layer_collections) {
+ layer_collection_local_sync(view_layer, child, local_collections_uuid, visible);
+ }
+}
+
+void BKE_layer_collection_local_sync(ViewLayer *view_layer, View3D *v3d)
+{
+ const unsigned short local_collections_uuid = v3d->local_collections_uuid;
+
+ /* Reset flags and set the bases visible by default. */
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ base->local_collections_bits &= ~local_collections_uuid;
+ }
+
+ LISTBASE_FOREACH (LayerCollection *, layer_collection, &view_layer->layer_collections) {
+ layer_collection_local_sync(view_layer, layer_collection, local_collections_uuid, true);
+ }
+}
+
+/**
+ * Isolate the collection locally
+ *
+ * Same as BKE_layer_collection_local_isolate but for a viewport
+ */
+void BKE_layer_collection_local_isolate(ViewLayer *view_layer,
+ View3D *v3d,
+ LayerCollection *lc,
+ bool extend)
+{
+ LayerCollection *lc_master = view_layer->layer_collections.first;
+ bool hide_it = extend && ((v3d->local_collections_uuid & lc->local_collections_bits) != 0);
+
+ if (!extend) {
+ /* Hide all collections. */
+ for (LayerCollection *lc_iter = lc_master->layer_collections.first; lc_iter;
+ lc_iter = lc_iter->next) {
+ layer_collection_local_visibility_unset_recursive(lc_iter, v3d->local_collections_uuid);
+ }
+ }
+
+ /* Make all the direct parents visible. */
+ if (hide_it) {
+ lc->local_collections_bits &= ~(v3d->local_collections_uuid);
+ }
+ else {
+ LayerCollection *lc_parent = lc;
+ for (LayerCollection *lc_iter = lc_master->layer_collections.first; lc_iter;
+ lc_iter = lc_iter->next) {
+ if (BKE_layer_collection_has_layer_collection(lc_iter, lc)) {
+ lc_parent = lc_iter;
+ break;
+ }
+ }
+
+ while (lc_parent != lc) {
+ lc_parent->local_collections_bits |= v3d->local_collections_uuid;
+
+ for (LayerCollection *lc_iter = lc_parent->layer_collections.first; lc_iter;
+ lc_iter = lc_iter->next) {
+ if (BKE_layer_collection_has_layer_collection(lc_iter, lc)) {
+ lc_parent = lc_iter;
+ break;
+ }
+ }
+ }
+
+ /* Make all the children visible. */
+ layer_collection_local_visibility_set_recursive(lc, v3d->local_collections_uuid);
+ }
+
+ BKE_layer_collection_local_sync(view_layer, v3d);
+}
+
static void layer_collection_bases_show_recursive(ViewLayer *view_layer, LayerCollection *lc)
{
if ((lc->flag & LAYER_COLLECTION_EXCLUDE) == 0) {
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index 3a330ea0d5a..01f3f2e309b 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -453,6 +453,7 @@ void BKE_object_eval_eval_base_flags(Depsgraph *depsgraph,
object->base_flag &= ~(BASE_SELECTED | BASE_SELECTABLE);
}
object->base_local_view_bits = base->local_view_bits;
+ object->runtime.local_collections_bits = base->local_collections_bits;
if (object->mode == OB_MODE_PARTICLE_EDIT) {
for (ParticleSystem *psys = object->particlesystem.first; psys != NULL; psys = psys->next) {
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index e9b4650d7d6..6d21d9c1490 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -849,6 +849,14 @@ static void do_versions_material_convert_legacy_blend_mode(bNodeTree *ntree, cha
}
}
+static void do_versions_local_collection_bits_set(LayerCollection *layer_collection)
+{
+ layer_collection->local_collections_bits = ~(0);
+ LISTBASE_FOREACH (LayerCollection *, child, &layer_collection->layer_collections) {
+ do_versions_local_collection_bits_set(child);
+ }
+}
+
void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports))
{
bool use_collection_compat_28 = true;
@@ -2919,7 +2927,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
case SPACE_VIEW3D: {
View3D *v3d = (View3D *)sl;
- v3d->flag &= ~(V3D_FLAG_UNUSED_0 | V3D_FLAG_UNUSED_1 | V3D_FLAG_UNUSED_10 |
+ v3d->flag &= ~(V3D_LOCAL_COLLECTIONS | V3D_FLAG_UNUSED_1 | V3D_FLAG_UNUSED_10 |
V3D_FLAG_UNUSED_12);
v3d->flag2 &= ~(V3D_FLAG2_UNUSED_3 | V3D_FLAG2_UNUSED_6 | V3D_FLAG2_UNUSED_12 |
V3D_FLAG2_UNUSED_13 | V3D_FLAG2_UNUSED_14 | V3D_FLAG2_UNUSED_15);
@@ -3854,5 +3862,16 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
{
/* Versioning code until next subversion bump goes here. */
+
+ if (!DNA_struct_elem_find(
+ fd->filesdna, "LayerCollection", "short", "local_collections_bits")) {
+ LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
+ LISTBASE_FOREACH (LayerCollection *, layer_collection, &view_layer->layer_collections) {
+ do_versions_local_collection_bits_set(layer_collection);
+ }
+ }
+ }
+ }
}
}
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index eea23211c5c..66e3905b212 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1565,6 +1565,20 @@ void DRW_draw_view(const bContext *C)
DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, viewport, C);
}
+static bool is_object_visible_in_viewport(View3D *v3d, Object *ob)
+{
+ if (v3d->localvd && ((v3d->local_view_uuid & ob->base_local_view_bits) == 0)) {
+ return false;
+ }
+
+ if ((v3d->flag & V3D_LOCAL_COLLECTIONS) &&
+ ((v3d->local_collections_uuid & ob->runtime.local_collections_bits) == 0)) {
+ return false;
+ }
+
+ return true;
+}
+
/**
* Used for both regular and off-screen drawing.
* Need to reset DST before calling this function
@@ -1640,7 +1654,7 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
if ((object_type_exclude_viewport & (1 << ob->type)) != 0) {
continue;
}
- if (v3d->localvd && ((v3d->local_view_uuid & ob->base_local_view_bits) == 0)) {
+ if (!is_object_visible_in_viewport(v3d, ob)) {
continue;
}
DST.dupli_parent = data_.dupli_parent;
@@ -2336,10 +2350,9 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
v3d->object_type_exclude_select);
bool filter_exclude = false;
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) {
- if (v3d->localvd && ((v3d->local_view_uuid & ob->base_local_view_bits) == 0)) {
+ if (!is_object_visible_in_viewport(v3d, ob)) {
continue;
}
-
if ((ob->base_flag & BASE_SELECTABLE) &&
(object_type_exclude_select & (1 << ob->type)) == 0) {
if (object_filter_fn != NULL) {
@@ -2458,11 +2471,9 @@ static void drw_draw_depth_loop_imp(void)
if ((object_type_exclude_viewport & (1 << ob->type)) != 0) {
continue;
}
-
- if (v3d->localvd && ((v3d->local_view_uuid & ob->base_local_view_bits) == 0)) {
+ if (!is_object_visible_in_viewport(v3d, ob)) {
continue;
}
-
DST.dupli_parent = data_.dupli_parent;
DST.dupli_source = data_.dupli_object_current;
drw_duplidata_load(DST.dupli_source);
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 139b306b533..dc7b25392e8 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -741,4 +741,8 @@ void ED_view3d_buttons_region_layout_ex(const struct bContext *C,
struct ARegion *ar,
const char *category_override);
+/* view3d_view.c */
+bool ED_view3d_local_collections_set(struct Main *bmain, struct View3D *v3d);
+void ED_view3d_local_collections_reset(struct bContext *C, const bool reset_all);
+
#endif /* __ED_VIEW3D_H__ */
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 37063a42906..74abe104134 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -271,9 +271,11 @@ void OBJECT_OT_hide_view_set(wmOperatorType *ot)
static int object_hide_collection_exec(bContext *C, wmOperator *op)
{
wmWindow *win = CTX_wm_window(C);
+ View3D *v3d = CTX_wm_view3d(C);
int index = RNA_int_get(op->ptr, "collection_index");
- const bool extend = (win->eventstate->shift != 0) || RNA_boolean_get(op->ptr, "toggle");
+ const bool extend = (win->eventstate->shift != 0);
+ const bool toggle = RNA_boolean_get(op->ptr, "toggle");
if (win->eventstate->alt != 0) {
index += 10;
@@ -289,7 +291,21 @@ static int object_hide_collection_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
- BKE_layer_collection_isolate(scene, view_layer, lc, extend);
+ if (v3d->flag & V3D_LOCAL_COLLECTIONS) {
+ if ((lc->runtime_flag & LAYER_COLLECTION_VISIBLE) == 0) {
+ return OPERATOR_CANCELLED;
+ }
+ if (toggle) {
+ lc->local_collections_bits ^= v3d->local_collections_uuid;
+ BKE_layer_collection_local_sync(view_layer, v3d);
+ }
+ else {
+ BKE_layer_collection_local_isolate(view_layer, v3d, lc, extend);
+ }
+ }
+ else {
+ BKE_layer_collection_isolate(scene, view_layer, lc, extend);
+ }
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 2515ee6e482..e5e1b1297f6 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -27,6 +27,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_rect.h"
#include "BLI_utildefines.h"
@@ -1187,7 +1188,7 @@ finally:
/** \name Local View Operators
* \{ */
-static uint free_localbit(Main *bmain)
+static uint free_localview_bit(Main *bmain)
{
ScrArea *sa;
bScreen *sc;
@@ -1242,7 +1243,7 @@ static bool view3d_localview_init(const Depsgraph *depsgraph,
INIT_MINMAX(min, max);
- local_view_bit = free_localbit(bmain);
+ local_view_bit = free_localview_bit(bmain);
if (local_view_bit == 0) {
/* TODO(dfelinto): We can kick one of the other 3D views out of local view
@@ -1534,3 +1535,134 @@ void VIEW3D_OT_localview_remove_from(wmOperatorType *ot)
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Local Collections
+ * \{ */
+
+static uint free_localcollection_bit(Main *bmain,
+ unsigned short local_collections_uuid,
+ bool *reset)
+{
+ ScrArea *sa;
+ bScreen *sc;
+
+ ushort local_view_bits = 0;
+
+ /* Check all areas: which localviews are in use? */
+ for (sc = bmain->screens.first; sc; sc = sc->id.next) {
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ SpaceLink *sl = sa->spacedata.first;
+ for (; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = (View3D *)sl;
+ if (v3d->flag & V3D_LOCAL_COLLECTIONS) {
+ local_view_bits |= v3d->local_collections_uuid;
+ }
+ }
+ }
+ }
+ }
+
+ /* First try to keep the old uuid. */
+ if (local_collections_uuid && ((local_collections_uuid & local_view_bits) == 0)) {
+ return local_collections_uuid;
+ }
+
+ /* Otherwise get the first free available. */
+ for (int i = 0; i < 16; i++) {
+ if ((local_view_bits & (1 << i)) == 0) {
+ *reset = true;
+ return (1 << i);
+ }
+ }
+
+ return 0;
+}
+
+static void local_collections_reset_uuid(LayerCollection *layer_collection,
+ const unsigned short local_view_bit)
+{
+ layer_collection->local_collections_bits |= local_view_bit;
+ LISTBASE_FOREACH (LayerCollection *, child, &layer_collection->layer_collections) {
+ local_collections_reset_uuid(child, local_view_bit);
+ }
+}
+
+static void view3d_local_collections_reset(Main *bmain, const uint local_view_bit)
+{
+ LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
+ LISTBASE_FOREACH (LayerCollection *, layer_collection, &view_layer->layer_collections) {
+ local_collections_reset_uuid(layer_collection, local_view_bit);
+ }
+ }
+ }
+}
+
+/**
+ * See if current uuid is valid, otherwise set a valid uuid to v3d,
+ * Try to keep the same uuid previously used to allow users to
+ * quickly toggle back and forth.
+ */
+bool ED_view3d_local_collections_set(Main *bmain, struct View3D *v3d)
+{
+ if ((v3d->flag & V3D_LOCAL_COLLECTIONS) == 0) {
+ return true;
+ }
+
+ bool reset = false;
+ v3d->flag &= ~V3D_LOCAL_COLLECTIONS;
+ uint local_view_bit = free_localcollection_bit(bmain, v3d->local_collections_uuid, &reset);
+
+ if (local_view_bit == 0) {
+ return false;
+ }
+
+ v3d->local_collections_uuid = local_view_bit;
+ v3d->flag |= V3D_LOCAL_COLLECTIONS;
+
+ if (reset) {
+ view3d_local_collections_reset(bmain, local_view_bit);
+ }
+
+ return true;
+}
+
+void ED_view3d_local_collections_reset(struct bContext *C, const bool reset_all)
+{
+ Main *bmain = CTX_data_main(C);
+ uint local_view_bit = ~(0);
+ bool do_reset = false;
+
+ /* Reset only the ones that are not in use. */
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
+ if (sl->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = (View3D *)sl;
+ if (v3d->local_collections_uuid) {
+ if (v3d->flag & V3D_LOCAL_COLLECTIONS) {
+ local_view_bit &= ~v3d->local_collections_uuid;
+ }
+ else {
+ do_reset = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (do_reset) {
+ view3d_local_collections_reset(bmain, local_view_bit);
+ }
+ else if (reset_all && (do_reset || (local_view_bit != ~(0)))) {
+ view3d_local_collections_reset(bmain, ~(0));
+ View3D v3d = {.local_collections_uuid = ~(0)};
+ BKE_layer_collection_local_sync(CTX_data_view_layer(C), &v3d);
+ DEG_id_tag_update(&CTX_data_scene(C)->id, ID_RECALC_BASE_FLAGS);
+ }
+}
+
+/** \} */
diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h
index 5f64e3220b7..3af1da46f80 100644
--- a/source/blender/makesdna/DNA_layer_types.h
+++ b/source/blender/makesdna/DNA_layer_types.h
@@ -45,6 +45,8 @@ typedef struct Base {
struct Object *object;
unsigned int lay DNA_DEPRECATED;
int flag_legacy;
+ unsigned short local_collections_bits;
+ short _pad2[3];
/* Pointer to an original base. Is initialized for evaluated view layer.
* NOTE: Only allowed to be accessed from within active dependency graph. */
@@ -66,8 +68,12 @@ typedef struct LayerCollection {
short flag;
short runtime_flag;
char _pad[4];
+
/** Synced with collection->children. */
ListBase layer_collections;
+
+ unsigned short local_collections_bits;
+ short _pad2[3];
} LayerCollection;
typedef struct ViewLayer {
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index b4d65aa7ea9..82a90dfe7a2 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -183,7 +183,8 @@ typedef struct Object_Runtime {
/** Runtime grease pencil evaluated data created by modifiers */
struct bGPDframe *gpencil_evaluated_frames;
- void *_pad2; /* Padding is here for win32s unconventional struct alignment rules. */
+ unsigned short local_collections_bits;
+ short _pad2[3];
} Object_Runtime;
typedef struct Object {
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 3334b1eafe8..ca572f1ddf1 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -1979,6 +1979,8 @@ extern const char *RE_engine_id_CYCLES;
#define BASE_VISIBLE(v3d, base) \
(((v3d == NULL) || ((v3d)->localvd == NULL) || \
((v3d)->local_view_uuid & (base)->local_view_bits)) && \
+ ((v3d == NULL) || (((v3d)->flag & V3D_LOCAL_COLLECTIONS) == 0) || \
+ ((v3d)->local_collections_uuid & (base)->local_collections_bits)) && \
((v3d == NULL) || \
(((1 << (base)->object->type) & (v3d)->object_type_exclude_viewport) == 0)) && \
(((base)->flag & BASE_VISIBLE) != 0))
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 106bf1252b2..10c61446d9d 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -266,6 +266,8 @@ typedef struct View3D {
unsigned short local_view_uuid;
char _pad6[2];
int layact DNA_DEPRECATED;
+ unsigned short local_collections_uuid;
+ short _pad7[3];
/** Optional bool for 3d cursor to define center. */
short ob_centre_cursor;
@@ -329,7 +331,7 @@ typedef struct View3D {
#define V3D_S3D_DISPVOLUME (1 << 2)
/** #View3D.flag */
-#define V3D_FLAG_UNUSED_0 (1 << 0) /* cleared */
+#define V3D_LOCAL_COLLECTIONS (1 << 0)
#define V3D_FLAG_UNUSED_1 (1 << 1) /* cleared */
#define V3D_HIDE_HELPLINES (1 << 2)
#define V3D_INVALID_BACKBUF (1 << 3)
diff --git a/source/blender/makesrna/intern/rna_layer.c b/source/blender/makesrna/intern/rna_layer.c
index 3c1b30ab7bd..bab7375f01b 100644
--- a/source/blender/makesrna/intern/rna_layer.c
+++ b/source/blender/makesrna/intern/rna_layer.c
@@ -120,6 +120,26 @@ static IDProperty *rna_ViewLayer_idprops(PointerRNA *ptr, bool create)
return view_layer->id_properties;
}
+static bool rna_LayerCollection_visible_get(LayerCollection *layer_collection, bContext *C)
+{
+ View3D *v3d = CTX_wm_view3d(C);
+ const bool runtime_visible = (layer_collection->runtime_flag & LAYER_COLLECTION_VISIBLE) != 0;
+
+ if (v3d == NULL) {
+ return runtime_visible;
+ }
+
+ if ((v3d->flag & V3D_LOCAL_COLLECTIONS) == 0) {
+ return runtime_visible;
+ }
+
+ if (v3d->local_collections_uuid & layer_collection->local_collections_bits) {
+ return true;
+ }
+
+ return false;
+}
+
static void rna_ViewLayer_update_render_passes(ID *id)
{
Scene *scene = (Scene *)id;
@@ -386,6 +406,13 @@ static void rna_def_layer_collection(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Hide in Viewport", "Temporarily hide in viewport");
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollection_update");
+ func = RNA_def_function(srna, "visible_get", "rna_LayerCollection_visible_get");
+ RNA_def_function_ui_description(func,
+ "Whether this collection is visible, take into account the "
+ "collection parent and the viewport");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+ RNA_def_function_return(func, RNA_def_boolean(func, "result", 0, "", ""));
+
/* Run-time flags. */
prop = RNA_def_property(srna, "is_visible", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "runtime_flag", LAYER_COLLECTION_VISIBLE);
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 3b616e7e823..2a5fc3103c9 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -1218,6 +1218,19 @@ static const EnumPropertyItem *rna_View3DShading_studio_light_itemf(bContext *UN
return item;
}
+static void rna_SpaceView3D_use_local_collections_update(bContext *C, PointerRNA *ptr)
+{
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = (View3D *)ptr->data;
+
+ if (ED_view3d_local_collections_set(bmain, v3d)) {
+ BKE_layer_collection_local_sync(view_layer, v3d);
+ DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
+ }
+}
+
static const EnumPropertyItem *rna_SpaceView3D_stereo3d_camera_itemf(bContext *C,
PointerRNA *UNUSED(ptr),
PropertyRNA *UNUSED(prop),
@@ -3951,6 +3964,14 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "FX Options", "Options used for real time compositing");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ prop = RNA_def_property(srna, "use_local_collections", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_LOCAL_COLLECTIONS);
+ RNA_def_property_ui_text(
+ prop, "Local Collections", "Display a different set of collections in this viewport");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(
+ prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_SpaceView3D_use_local_collections_update");
+
/* Stereo Settings */
prop = RNA_def_property(srna, "stereo_3d_eye", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "multiview_eye");
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 01e3cf4f329..bb66c2e7d35 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -2245,6 +2245,7 @@ static int wm_open_mainfile__open(bContext *C, wmOperator *op)
if (G.fileflags & G_FILE_NO_UI) {
ED_outliner_select_sync_from_all_tag(C);
}
+ ED_view3d_local_collections_reset(C, (G.fileflags & G_FILE_NO_UI) != 0);
return OPERATOR_FINISHED;
}
else {