Local Collections: Allow users to show hidden collections
authorDalai Felinto <dfelinto@gmail.com>
Thu, 3 Oct 2019 22:22:36 +0000 (19:22 -0300)
committerDalai Felinto <dfelinto@gmail.com>
Tue, 8 Oct 2019 22:16:05 +0000 (19:16 -0300)
Users now can turn on in a viewport collections that are temporarily
hidden (eye) in the view layer.

Design task: T61327

As for the implementation, I had to decouple the visibility in the
depsgraph from the visibility in the view layer.

Also there is a "bug" that in a way was there before which is some
operators (e.g., writing a text inside of a text object, tab into edit
mode) run regardless of the visibility of the active object. The bug was
present already (with object type visibility restriction) in 2.80 so if
we decide to tackle it, can be done separately (I have a patch for it
though P1132).

Reviewed by: brecht (thank you)

Differential Revision: D5992

31 files changed:
release/scripts/startup/bl_ui/space_view3d.py
source/blender/alembic/intern/abc_exporter.cc
source/blender/blenkernel/BKE_layer.h
source/blender/blenkernel/intern/layer.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/object_update.c
source/blender/depsgraph/intern/depsgraph_query_iter.cc
source/blender/draw/intern/draw_manager.c
source/blender/editors/animation/anim_filter.c
source/blender/editors/object/object_add.c
source/blender/editors/object/object_bake_api.c
source/blender/editors/object/object_edit.c
source/blender/editors/object/object_select.c
source/blender/editors/render/render_internal.c
source/blender/editors/render/render_preview.c
source/blender/editors/space_outliner/outliner_collections.c
source/blender/editors/space_outliner/outliner_select.c
source/blender/editors/space_outliner/outliner_tree.c
source/blender/editors/space_view3d/space_view3d.c
source/blender/editors/space_view3d/view3d_draw_legacy.c
source/blender/editors/space_view3d/view3d_gizmo_armature.c
source/blender/editors/space_view3d/view3d_gizmo_camera.c
source/blender/editors/space_view3d/view3d_gizmo_empty.c
source/blender/editors/space_view3d/view3d_gizmo_forcefield.c
source/blender/editors/space_view3d/view3d_gizmo_light.c
source/blender/editors/space_view3d/view3d_view.c
source/blender/editors/transform/transform_orientations.c
source/blender/editors/transform/transform_snap_object.c
source/blender/makesdna/DNA_layer_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesrna/intern/rna_layer.c

index ffb0096d2f3f000aa06b078d2fdf6ee6803a14d0..7d13c9c41128080864d434cc148adf4bd0fad95e 100644 (file)
@@ -5078,9 +5078,6 @@ class VIEW3D_PT_collections(Panel):
             if not use_local_collections:
                 subrow.active = collection.is_visible  # Parent collection runtime visibility
                 subrow.prop(child, "hide_viewport", text="", emboss=False)
-            elif not child.is_visible:
-                subrow.active = False
-                subrow.label(text="", icon='REMOVE')
             else:
                 subrow.active = collection.visible_get() # Parent collection runtime visibility
                 icon = 'HIDE_OFF' if child.visible_get() else 'HIDE_ON'
index 69a376d00b0e2030b7fd0b5b179810365e102609..a69178281ff44aeffee22556d76985e15cd2dd55 100644 (file)
@@ -53,6 +53,7 @@ extern "C" {
 #include "BKE_anim.h"
 #include "BKE_global.h"
 #include "BKE_idprop.h"
+#include "BKE_layer.h"
 #include "BKE_main.h"
 #include "BKE_mball.h"
 #include "BKE_modifier.h"
index 535980840c1af1135302332a27b0238b0c6bad14..d2c869532c8480bceb191f11809b3d2f26c9fba9 100644 (file)
@@ -114,11 +114,12 @@ void BKE_base_set_visible(struct Scene *scene,
                           struct ViewLayer *view_layer,
                           struct Base *base,
                           bool extend);
-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,
+bool BKE_base_is_visible(const struct View3D *v3d, const struct Base *base);
+void BKE_layer_collection_isolate_global(struct Scene *scene,
+                                         struct ViewLayer *view_layer,
+                                         struct LayerCollection *lc,
+                                         bool extend);
+void BKE_layer_collection_isolate_local(struct ViewLayer *view_layer,
                                         struct View3D *v3d,
                                         struct LayerCollection *lc,
                                         bool extend);
index 9b18052ef1e529cea9a48e4dabd50c92a58ef8bb..726ca9d705b81caf8d96409bf80c48b6d008d9ce 100644 (file)
@@ -44,6 +44,7 @@
 #include "DNA_object_types.h"
 #include "DNA_node_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_view3d_types.h"
 #include "DNA_windowmanager_types.h"
 #include "DNA_workspace_types.h"
 
 #include "MEM_guardedalloc.h"
 
 /* Set of flags which are dependent on a collection settings. */
-static const short g_base_collection_flags = (BASE_VISIBLE | BASE_SELECTABLE |
-                                              BASE_ENABLED_VIEWPORT | BASE_ENABLED_RENDER |
-                                              BASE_HOLDOUT | BASE_INDIRECT_ONLY);
+static const short g_base_collection_flags = (BASE_VISIBLE_DEPSGRAPH | BASE_VISIBLE_VIEWLAYER |
+                                              BASE_SELECTABLE | BASE_ENABLED_VIEWPORT |
+                                              BASE_ENABLED_RENDER | BASE_HOLDOUT |
+                                              BASE_INDIRECT_ONLY);
 
 /* prototype */
 static void object_bases_iterator_next(BLI_Iterator *iter, const int flag);
@@ -735,9 +737,15 @@ static short layer_collection_sync(ViewLayer *view_layer,
       lc->runtime_flag = child_runtime_flag;
     }
 
-    if (((child_restrict & COLLECTION_RESTRICT_VIEWPORT) == 0) &&
+    /* 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 (((lc->runtime_flag & LAYER_COLLECTION_RESTRICT_VIEWPORT) == 0) &&
         ((child_layer_restrict & LAYER_COLLECTION_HIDE) == 0)) {
-      lc->runtime_flag |= LAYER_COLLECTION_VISIBLE;
+      lc->runtime_flag |= LAYER_COLLECTION_VISIBLE_VIEW_LAYER;
     }
 
     /* Sync objects, except if collection was excluded. */
@@ -771,12 +779,12 @@ static short layer_collection_sync(ViewLayer *view_layer,
       }
 
       if ((child_restrict & COLLECTION_RESTRICT_VIEWPORT) == 0) {
-        base->flag_from_collection |= BASE_ENABLED_VIEWPORT;
+        base->flag_from_collection |= (BASE_ENABLED_VIEWPORT | BASE_VISIBLE_DEPSGRAPH);
         if ((child_layer_restrict & LAYER_COLLECTION_HIDE) == 0) {
-          base->flag_from_collection |= BASE_VISIBLE;
-          if (((child_restrict & COLLECTION_RESTRICT_SELECT) == 0)) {
-            base->flag_from_collection |= BASE_SELECTABLE;
-          }
+          base->flag_from_collection |= BASE_VISIBLE_VIEWLAYER;
+        }
+        if (((child_restrict & COLLECTION_RESTRICT_SELECT) == 0)) {
+          base->flag_from_collection |= BASE_SELECTABLE;
         }
       }
 
@@ -974,7 +982,7 @@ bool BKE_layer_collection_has_selected_objects(ViewLayer *view_layer, LayerColle
     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) && (base->flag & BASE_VISIBLE)) {
+      if (base && (base->flag & BASE_SELECTED) && (base->flag & BASE_VISIBLE_DEPSGRAPH)) {
         return true;
       }
     }
@@ -1026,6 +1034,31 @@ void BKE_base_set_visible(Scene *scene, ViewLayer *view_layer, Base *base, bool
   BKE_layer_collection_sync(scene, view_layer);
 }
 
+bool BKE_base_is_visible(const View3D *v3d, const Base *base)
+{
+  if ((base->flag & BASE_VISIBLE_DEPSGRAPH) == 0) {
+    return false;
+  }
+
+  if (v3d == NULL) {
+    return base->flag & BASE_VISIBLE_VIEWLAYER;
+  }
+
+  if ((v3d->localvd) && ((v3d->local_view_uuid & base->local_view_bits) == 0)) {
+    return false;
+  }
+
+  if (((1 << (base->object->type)) & v3d->object_type_exclude_viewport) != 0) {
+    return false;
+  }
+
+  if (v3d->flag & V3D_LOCAL_COLLECTIONS) {
+    return (v3d->local_collections_uuid & base->local_collections_bits) != 0;
+  }
+
+  return base->flag & BASE_VISIBLE_VIEWLAYER;
+}
+
 static void layer_collection_flag_set_recursive(LayerCollection *lc, const int flag)
 {
   lc->flag |= flag;
@@ -1050,13 +1083,13 @@ static void layer_collection_flag_unset_recursive(LayerCollection *lc, const int
  * If the collection or any of its parents is disabled, make it enabled.
  * Don't change the children disable state though.
  */
-void BKE_layer_collection_isolate(Scene *scene,
-                                  ViewLayer *view_layer,
-                                  LayerCollection *lc,
-                                  bool extend)
+void BKE_layer_collection_isolate_global(Scene *scene,
+                                         ViewLayer *view_layer,
+                                         LayerCollection *lc,
+                                         bool extend)
 {
   LayerCollection *lc_master = view_layer->layer_collections.first;
-  bool hide_it = extend && (lc->runtime_flag & LAYER_COLLECTION_VISIBLE);
+  bool hide_it = extend && (lc->runtime_flag & LAYER_COLLECTION_VISIBLE_VIEW_LAYER);
 
   if (!extend) {
     /* Hide all collections . */
@@ -1163,9 +1196,9 @@ void BKE_layer_collection_local_sync(ViewLayer *view_layer, View3D *v3d)
 /**
  * Isolate the collection locally
  *
- * Same as BKE_layer_collection_local_isolate but for a viewport
+ * Same as BKE_layer_collection_isolate_local but for a viewport
  */
-void BKE_layer_collection_local_isolate(ViewLayer *view_layer,
+void BKE_layer_collection_isolate_local(ViewLayer *view_layer,
                                         View3D *v3d,
                                         LayerCollection *lc,
                                         bool extend)
@@ -1436,12 +1469,12 @@ static void objects_iterator_end(BLI_Iterator *iter)
 
 void BKE_view_layer_selected_objects_iterator_begin(BLI_Iterator *iter, void *data_in)
 {
-  objects_iterator_begin(iter, data_in, BASE_VISIBLE | BASE_SELECTED);
+  objects_iterator_begin(iter, data_in, BASE_VISIBLE_DEPSGRAPH | BASE_SELECTED);
 }
 
 void BKE_view_layer_selected_objects_iterator_next(BLI_Iterator *iter)
 {
-  objects_iterator_next(iter, BASE_VISIBLE | BASE_SELECTED);
+  objects_iterator_next(iter, BASE_VISIBLE_DEPSGRAPH | BASE_SELECTED);
 }
 
 void BKE_view_layer_selected_objects_iterator_end(BLI_Iterator *iter)
@@ -1478,7 +1511,7 @@ void BKE_view_layer_visible_objects_iterator_end(BLI_Iterator *iter)
 
 void BKE_view_layer_selected_editable_objects_iterator_begin(BLI_Iterator *iter, void *data_in)
 {
-  objects_iterator_begin(iter, data_in, BASE_VISIBLE | BASE_SELECTED);
+  objects_iterator_begin(iter, data_in, BASE_VISIBLE_DEPSGRAPH | BASE_SELECTED);
   if (iter->valid) {
     if (BKE_object_is_libdata((Object *)iter->current) == false) {
       // First object is valid (selectable and not libdata) -> all good.
@@ -1495,7 +1528,7 @@ void BKE_view_layer_selected_editable_objects_iterator_next(BLI_Iterator *iter)
 {
   // Search while there are objects and the one we have is not editable (editable = not libdata).
   do {
-    objects_iterator_next(iter, BASE_VISIBLE | BASE_SELECTED);
+    objects_iterator_next(iter, BASE_VISIBLE_DEPSGRAPH | BASE_SELECTED);
   } while (iter->valid && BKE_object_is_libdata((Object *)iter->current) != false);
 }
 
@@ -1512,12 +1545,12 @@ void BKE_view_layer_selected_editable_objects_iterator_end(BLI_Iterator *iter)
 
 void BKE_view_layer_selected_bases_iterator_begin(BLI_Iterator *iter, void *data_in)
 {
-  objects_iterator_begin(iter, data_in, BASE_VISIBLE | BASE_SELECTED);
+  objects_iterator_begin(iter, data_in, BASE_VISIBLE_DEPSGRAPH | BASE_SELECTED);
 }
 
 void BKE_view_layer_selected_bases_iterator_next(BLI_Iterator *iter)
 {
-  object_bases_iterator_next(iter, BASE_VISIBLE | BASE_SELECTED);
+  object_bases_iterator_next(iter, BASE_VISIBLE_DEPSGRAPH | BASE_SELECTED);
 }
 
 void BKE_view_layer_selected_bases_iterator_end(BLI_Iterator *iter)
@@ -1617,7 +1650,8 @@ void BKE_view_layer_bases_in_mode_iterator_end(BLI_Iterator *UNUSED(iter))
 /* Evaluation  */
 
 /* Applies object's restrict flags on top of flags coming from the collection
- * and stores those in base->flag. BASE_VISIBLE is based on viewport visibility. */
+ * and stores those in base->flag. BASE_VISIBLE_DEPSGRAPH ignores viewport flags visibility
+ * (i.e., restriction and local collection). */
 void BKE_base_eval_flags(Base *base)
 {
   /* Apply collection flags. */
@@ -1640,7 +1674,7 @@ void BKE_base_eval_flags(Base *base)
    * can change these again, but for tools we always want the viewport
    * visibility to be in sync regardless if depsgraph was evaluated. */
   if (!(base->flag & BASE_ENABLED_VIEWPORT) || (base->flag & BASE_HIDDEN)) {
-    base->flag &= ~(BASE_VISIBLE | BASE_SELECTABLE);
+    base->flag &= ~(BASE_VISIBLE_DEPSGRAPH | BASE_VISIBLE_VIEWLAYER | BASE_SELECTABLE);
   }
 
   /* Deselect unselectable objects. */
index f10930a2ba7390ac631a7ca98318324991082f57..773e2d19b227f327d3eb3c041f3a1c0eeadf4d21 100644 (file)
@@ -680,7 +680,7 @@ bool BKE_object_is_mode_compat(const struct Object *ob, eObjectMode object_mode)
  */
 int BKE_object_visibility(const Object *ob, const int dag_eval_mode)
 {
-  if ((ob->base_flag & BASE_VISIBLE) == 0) {
+  if ((ob->base_flag & BASE_VISIBLE_DEPSGRAPH) == 0) {
     return 0;
   }
 
index 01f3f2e309bd750833ad9a99a3bf0fb60cd08970..21ca5e6d6a64377fe342947220009b6985431de9 100644 (file)
@@ -439,10 +439,10 @@ void BKE_object_eval_eval_base_flags(Depsgraph *depsgraph,
    * assumed viewport visibility. Select-ability does not matter here. */
   if (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER) {
     if (base->flag & BASE_ENABLED_RENDER) {
-      base->flag |= BASE_VISIBLE;
+      base->flag |= BASE_VISIBLE_DEPSGRAPH;
     }
     else {
-      base->flag &= ~BASE_VISIBLE;
+      base->flag &= ~BASE_VISIBLE_DEPSGRAPH;
     }
   }
 
index 2878996828659fa7881c4fa11b4487448f1734d2..db469612f76d713549e9af5494bd99ed3d2e3234 100644 (file)
@@ -152,7 +152,7 @@ bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
     copy_v4_v4(temp_dupli_object->color, dupli_parent->color);
 
     /* Duplicated elements shouldn't care whether their original collection is visible or not. */
-    temp_dupli_object->base_flag |= BASE_VISIBLE;
+    temp_dupli_object->base_flag |= BASE_VISIBLE_DEPSGRAPH;
 
     int ob_visibility = BKE_object_visibility(temp_dupli_object, data->eval_mode);
     if ((ob_visibility & (OB_VISIBLE_SELF | OB_VISIBLE_PARTICLES)) == 0) {
index 66cf921d47de1221473f140d3f2b65fa4525110b..6366ed0bb6f033ff53ce557e4d7539ec77b531e7 100644 (file)
@@ -164,7 +164,7 @@ struct DRWTextStore *DRW_text_cache_ensure(void)
 
 bool DRW_object_is_renderable(const Object *ob)
 {
-  BLI_assert((ob->base_flag & BASE_VISIBLE) != 0);
+  BLI_assert((ob->base_flag & BASE_VISIBLE_DEPSGRAPH) != 0);
 
   if (ob->type == OB_MESH) {
     if ((ob == DST.draw_ctx.object_edit) || BKE_object_is_in_editmode(ob)) {
@@ -1586,6 +1586,11 @@ static bool is_object_visible_in_viewport(View3D *v3d, Object *ob)
     return false;
   }
 
+  /* If not using local view or local collection the object may still be in a hidden collection. */
+  if (((v3d->localvd) == NULL) && ((v3d->flag & V3D_LOCAL_COLLECTIONS) == 0)) {
+    return (ob->base_flag & BASE_VISIBLE_VIEWLAYER) != 0;
+  }
+
   return true;
 }
 
index 48493c9e9619ba9fe2093427f76e5f0bcfd250d1..f73c8a5b71aa4709926c270796377eb25cb5c883 100644 (file)
@@ -1818,7 +1818,7 @@ static size_t animdata_filter_gpencil(bAnimContext *ac,
             !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
           /* Layer visibility - we check both object and base,
            * since these may not be in sync yet. */
-          if ((base->flag & BASE_VISIBLE) == 0) {
+          if ((base->flag & BASE_VISIBLE_DEPSGRAPH) == 0) {
             continue;
           }
 
@@ -3017,7 +3017,7 @@ static bool animdata_filter_base_is_ok(bDopeSheet *ads, Base *base, int filter_m
    */
   if ((filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
     /* layer visibility - we check both object and base, since these may not be in sync yet */
-    if ((base->flag & BASE_VISIBLE) == 0) {
+    if ((base->flag & BASE_VISIBLE_DEPSGRAPH) == 0) {
       return false;
     }
 
index 2f8141bef9545e8e4054c1aded8a6772e2cc98ac..bbd8c425386a81c0e7e7878346f248c7262419ca 100644 (file)
@@ -2576,7 +2576,7 @@ static Base *object_add_duplicate_internal(
     DEG_id_tag_update(&obn->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
 
     base = BKE_view_layer_base_find(view_layer, ob);
-    if ((base != NULL) && (base->flag & BASE_VISIBLE)) {
+    if ((base != NULL) && (base->flag & BASE_VISIBLE_DEPSGRAPH)) {
       BKE_collection_object_add_from(bmain, scene, ob, obn);
     }
     else {
index d9baec7c3cad1f2d15606c4451365c97ecc81c66..9e9cfe1beedb86c44f5323381243bbf7e23bf44c 100644 (file)
@@ -879,7 +879,7 @@ static int bake(Render *re,
       else {
         ob_cage_eval = DEG_get_evaluated_object(depsgraph, ob_cage);
         ob_cage_eval->restrictflag |= OB_RESTRICT_RENDER;
-        ob_cage_eval->base_flag &= ~(BASE_VISIBLE | BASE_ENABLED_RENDER);
+        ob_cage_eval->base_flag &= ~(BASE_VISIBLE_DEPSGRAPH | BASE_ENABLED_RENDER);
       }
     }
   }
@@ -976,7 +976,7 @@ static int bake(Render *re,
       highpoly[i].ob = ob_iter;
       highpoly[i].ob_eval = DEG_get_evaluated_object(depsgraph, ob_iter);
       highpoly[i].ob_eval->restrictflag &= ~OB_RESTRICT_RENDER;
-      highpoly[i].ob_eval->base_flag |= (BASE_VISIBLE | BASE_ENABLED_RENDER);
+      highpoly[i].ob_eval->base_flag |= (BASE_VISIBLE_DEPSGRAPH | BASE_ENABLED_RENDER);
       highpoly[i].me = BKE_mesh_new_from_object(NULL, highpoly[i].ob_eval, false);
 
       /* lowpoly to highpoly transformation matrix */
@@ -992,10 +992,10 @@ static int bake(Render *re,
 
     if (ob_cage != NULL) {
       ob_cage_eval->restrictflag |= OB_RESTRICT_RENDER;
-      ob_cage_eval->base_flag &= ~(BASE_VISIBLE | BASE_ENABLED_RENDER);
+      ob_cage_eval->base_flag &= ~(BASE_VISIBLE_DEPSGRAPH | BASE_ENABLED_RENDER);
     }
     ob_low_eval->restrictflag |= OB_RESTRICT_RENDER;
-    ob_low_eval->base_flag &= ~(BASE_VISIBLE | BASE_ENABLED_RENDER);
+    ob_low_eval->base_flag &= ~(BASE_VISIBLE_DEPSGRAPH | BASE_ENABLED_RENDER);
 
     /* populate the pixel arrays with the corresponding face data for each high poly object */
     if (!RE_bake_pixels_populate_from_objects(me_low,
index 40bb1c7378fab813ae2fc50709c7a1f216a0d8c9..70d024c7902e204e4174c8762f214156cd8d899f 100644 (file)
@@ -218,7 +218,7 @@ static int object_hide_view_set_exec(bContext *C, wmOperator *op)
 
   /* Hide selected or unselected objects. */
   for (Base *base = view_layer->object_bases.first; base; base = base->next) {
-    if (!(base->flag & BASE_VISIBLE)) {
+    if (!(base->flag & BASE_VISIBLE_DEPSGRAPH)) {
       continue;
     }
 
@@ -292,7 +292,7 @@ static int object_hide_collection_exec(bContext *C, wmOperator *op)
   DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
 
   if (v3d->flag & V3D_LOCAL_COLLECTIONS) {
-    if ((lc->runtime_flag & LAYER_COLLECTION_VISIBLE) == 0) {
+    if (lc->runtime_flag & LAYER_COLLECTION_RESTRICT_VIEWPORT) {
       return OPERATOR_CANCELLED;
     }
     if (toggle) {
@@ -300,11 +300,11 @@ static int object_hide_collection_exec(bContext *C, wmOperator *op)
       BKE_layer_collection_local_sync(view_layer, v3d);
     }
     else {
-      BKE_layer_collection_local_isolate(view_layer, v3d, lc, extend);
+      BKE_layer_collection_isolate_local(view_layer, v3d, lc, extend);
     }
   }
   else {
-    BKE_layer_collection_isolate(scene, view_layer, lc, extend);
+    BKE_layer_collection_isolate_global(scene, view_layer, lc, extend);
   }
 
   WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
index 28242b986f152f18b31d1031ad19b13c0a53d22b..40fa11994f4c2e5321b5d164026e5b6ea3706a37 100644 (file)
@@ -214,7 +214,7 @@ bool ED_object_base_deselect_all(ViewLayer *view_layer, View3D *v3d, int action)
 
 static int get_base_select_priority(Base *base)
 {
-  if (base->flag & BASE_VISIBLE) {
+  if (base->flag & BASE_VISIBLE_DEPSGRAPH) {
     if (base->flag & BASE_SELECTABLE) {
       return 3;
     }
@@ -288,7 +288,7 @@ bool ED_object_jump_to_object(bContext *C, Object *ob, const bool UNUSED(reveal_
     if (!(base->flag & BASE_SELECTED)) {
       ED_object_base_deselect_all(view_layer, v3d, SEL_DESELECT);
 
-      if (base->flag & BASE_VISIBLE) {
+      if (BASE_VISIBLE(v3d, base)) {
         ED_object_base_select(base, BA_SELECT);
       }
 
index 053ca3d8f9f2691b1140fe8429ab5aa30563e314..7106af25a82452f997b90590ffed5ca84eab652f 100644 (file)
@@ -859,7 +859,7 @@ static void screen_render_cancel(bContext *C, wmOperator *op)
 
 static void clean_viewport_memory_base(Base *base)
 {
-  if ((base->flag & BASE_VISIBLE) == 0) {
+  if ((base->flag & BASE_VISIBLE_DEPSGRAPH) == 0) {
     return;
   }
 
index 55fbd701a4765764d688b03c0f980fa6a9d75630..6dc3a1ec1ac8098d1e969fa2c1899ed4e36e22a6 100644 (file)
@@ -474,7 +474,7 @@ static Scene *preview_prepare_scene(
             }
           }
           else if (base->object->type == OB_LAMP) {
-            base->flag |= BASE_VISIBLE;
+            base->flag |= BASE_VISIBLE_DEPSGRAPH;
           }
         }
       }
index 309446db83b8f1d155ee699ceb918a40f891fc3d..03606282fcde31123a22c85bf15715a1aaf9f5be 100644 (file)
@@ -965,7 +965,7 @@ static int collection_isolate_exec(bContext *C, wmOperator *op)
     LayerCollection *layer_collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
 
     if (extend) {
-      BKE_layer_collection_isolate(scene, view_layer, layer_collection, true);
+      BKE_layer_collection_isolate_global(scene, view_layer, layer_collection, true);
     }
     else {
       PointerRNA ptr;
index 44e67fa150819b1097a79836d3ecf83a1e424506..8852470398e673dd0fd3a8e33d23a70b596f2b6f 100644 (file)
@@ -263,7 +263,7 @@ static void do_outliner_object_select_recursive(ViewLayer *view_layer,
 
   for (base = FIRSTBASE(view_layer); base; base = base->next) {
     Object *ob = base->object;
-    if ((((base->flag & BASE_VISIBLE) != 0) && BKE_object_is_child_recursive(ob_parent, ob))) {
+    if ((((base->flag & BASE_VISIBLE_DEPSGRAPH) != 0) && BKE_object_is_child_recursive(ob_parent, ob))) {
       ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT);
     }
   }
@@ -1198,7 +1198,7 @@ static void do_outliner_item_activate_tree_element(bContext *C,
       Object *ob = (Object *)outliner_search_back(soops, te, ID_OB);
       if ((ob != NULL) && (ob->data == tselem->id)) {
         Base *base = BKE_view_layer_base_find(view_layer, ob);
-        if ((base != NULL) && (base->flag & BASE_VISIBLE)) {
+        if ((base != NULL) && (base->flag & BASE_VISIBLE_DEPSGRAPH)) {
           do_outliner_activate_obdata(C, scene, view_layer, base, extend);
         }
       }
index fd6a052b84d7e2f6ccd20f860bdce554115adca8..7f7cfff12ef53a5ea91571360dd8abde81798734 100644 (file)
@@ -1365,7 +1365,7 @@ static void outliner_add_layer_collection_objects(
     TreeElement *te_object = outliner_add_element(soops, tree, base->object, ten, 0, 0);
     te_object->directdata = base;
 
-    if (!(base->flag & BASE_VISIBLE)) {
+    if (!(base->flag & BASE_VISIBLE_DEPSGRAPH)) {
       te_object->flag |= TE_DISABLED;
     }
   }
@@ -1398,7 +1398,7 @@ static void outliner_add_layer_collections_recursive(SpaceOutliner *soops,
         tselem->flag &= ~TSE_CLOSED;
       }
 
-      if (exclude || (lc->runtime_flag & LAYER_COLLECTION_VISIBLE) == 0) {
+      if (exclude || (lc->runtime_flag & LAYER_COLLECTION_VISIBLE_VIEW_LAYER) == 0) {
         ten->flag |= TE_DISABLED;
       }
     }
@@ -2085,12 +2085,12 @@ static bool outliner_element_visible_get(ViewLayer *view_layer,
       }
 
       if (exclude_filter & SO_FILTER_OB_STATE_VISIBLE) {
-        if ((base->flag & BASE_VISIBLE) == 0) {
+        if ((base->flag & BASE_VISIBLE_DEPSGRAPH) == 0) {
           return false;
         }
       }
       else if (exclude_filter & SO_FILTER_OB_STATE_HIDDEN) {
-        if ((base->flag & BASE_VISIBLE) != 0) {
+        if ((base->flag & BASE_VISIBLE_DEPSGRAPH) != 0) {
           return false;
         }
       }
index fbb6dfb8f8f7aa77b89e4d7cf11f0efad51090b4..6d25d6c14f8e0cac4182c0835a7f68617668540a 100644 (file)
@@ -341,6 +341,9 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
     v3dn->runtime.properties_storage = NULL;
   }
 
+  v3dn->local_collections_uuid = 0;
+  v3dn->flag &= ~V3D_LOCAL_COLLECTIONS;
+
   if (v3dn->shading.type == OB_RENDER) {
     v3dn->shading.type = OB_SOLID;
   }
@@ -1460,7 +1463,7 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
     if (view_layer->basact) {
       Object *ob = view_layer->basact->object;
       /* if hidden but in edit mode, we still display, can happen with animation */
-      if ((view_layer->basact->flag & BASE_VISIBLE) != 0 || (ob->mode & OB_MODE_EDIT)) {
+      if ((view_layer->basact->flag & BASE_VISIBLE_DEPSGRAPH) != 0 || (ob->mode & OB_MODE_EDIT)) {
         CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, view_layer->basact);
       }
     }
@@ -1472,7 +1475,8 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
     if (view_layer->basact) {
       Object *ob = view_layer->basact->object;
       /* if hidden but in edit mode, we still display, can happen with animation */
-      if ((view_layer->basact->flag & BASE_VISIBLE) != 0 || (ob->mode & OB_MODE_EDIT) != 0) {
+      if ((view_layer->basact->flag & BASE_VISIBLE_DEPSGRAPH) != 0 ||
+          (ob->mode & OB_MODE_EDIT) != 0) {
         CTX_data_id_pointer_set(result, &ob->id);
       }
     }
index acc46935eb5f8ad99a7c9fd07ddb2fbbe554f9e0..17b575cedae31cf87f22e6b89b473273be386e62 100644 (file)
@@ -179,7 +179,7 @@ static void validate_object_select_id(
     return;
   }
 
-  if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE) != 0)) {
+  if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE_DEPSGRAPH) != 0)) {
     Base *base = BKE_view_layer_base_find(view_layer, obact);
     DRW_select_buffer_context_create(&base, 1, -1);
   }
@@ -226,7 +226,7 @@ void ED_view3d_backbuf_depth_validate(ViewContext *vc)
     ARegion *ar = vc->ar;
     Object *obact_eval = DEG_get_evaluated_object(vc->depsgraph, vc->obact);
 
-    if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE) != 0)) {
+    if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE_DEPSGRAPH) != 0)) {
       GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0);
       DRW_draw_depth_object(vc->ar, viewport, obact_eval);
     }
index 615589347daa801332bb34c40b316abeb35f459b..dbad06da5ec0da935dcfa2c5a96bce09848f2bb4 100644 (file)
@@ -25,6 +25,7 @@
 #include "BKE_armature.h"
 #include "BKE_action.h"
 #include "BKE_context.h"
+#include "BKE_layer.h"
 #include "BKE_object.h"
 
 #include "DNA_object_types.h"
index 42931d5abb5d69f79ce5ec8100b10551f04f2c9a..ba5ca5fbd15295380e7e1529c848560ba493aaa9 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "BKE_camera.h"
 #include "BKE_context.h"
+#include "BKE_layer.h"
 
 #include "DNA_object_types.h"
 #include "DNA_camera_types.h"
index b37f1e412940d6833f9fd1b4bd9805ca44ff5c7b..793aec42dcdaf7e6a6c1760b3c9afe1a359cf955 100644 (file)
@@ -22,6 +22,7 @@
 #include "BLI_utildefines.h"
 
 #include "BKE_context.h"
+#include "BKE_layer.h"
 #include "BKE_object.h"
 #include "BKE_image.h"
 
index 44ad1d14dba86d8708bb94cabad98e6a9d532e64..90b1539c8a7b9baf96b03428928e90261e293051 100644 (file)
@@ -21,6 +21,7 @@
 #include "BLI_utildefines.h"
 
 #include "BKE_context.h"
+#include "BKE_layer.h"
 #include "BKE_object.h"
 
 #include "DNA_object_types.h"
index 35677b2e4c223a0e9fa3024b5597117018c81970..890de0ae611af1f2b0ba8be7e4d455b6d7e705ee 100644 (file)
@@ -22,6 +22,7 @@
 #include "BLI_utildefines.h"
 
 #include "BKE_context.h"
+#include "BKE_layer.h"
 #include "BKE_object.h"
 
 #include "DEG_depsgraph.h"
index dd8e2e0727178fd09e4697ae00e23fb24edc8a04..d7af307bc533d3dfca305b6c0a3764174c319bd8 100644 (file)
@@ -1583,7 +1583,13 @@ static uint free_localcollection_bit(Main *bmain,
 static void local_collections_reset_uuid(LayerCollection *layer_collection,
                                          const unsigned short local_view_bit)
 {
-  layer_collection->local_collections_bits |= local_view_bit;
+  if (layer_collection->flag & LAYER_COLLECTION_HIDE) {
+    layer_collection->local_collections_bits &= ~local_view_bit;
+  }
+  else {
+    layer_collection->local_collections_bits |= local_view_bit;
+  }
+
   LISTBASE_FOREACH (LayerCollection *, child, &layer_collection->layer_collections) {
     local_collections_reset_uuid(child, local_view_bit);
   }
index cbe9505d3f2aeeef8a3d24f2aaa122129a07b03e..3159464072e842826376dd549387fdc2d02171a2 100644 (file)
@@ -44,6 +44,7 @@
 #include "BKE_curve.h"
 #include "BKE_context.h"
 #include "BKE_editmesh.h"
+#include "BKE_layer.h"
 #include "BKE_report.h"
 #include "BKE_scene.h"
 #include "BKE_workspace.h"
index 1601acb1c8f7c5c326f02013b3b68c29acfbb268..b31816b2605defbbdfc406310430720d4cd3e4c8 100644 (file)
@@ -47,6 +47,7 @@
 #include "BKE_object.h"
 #include "BKE_anim.h" /* for duplis */
 #include "BKE_editmesh.h"
+#include "BKE_layer.h"
 #include "BKE_main.h"
 #include "BKE_tracking.h"
 #include "BKE_context.h"
index 3af1da46f803b377201adba3c41af31917590532..4de98e0b6848156af6cfe5d724f66717427d38e3 100644 (file)
@@ -118,13 +118,13 @@ enum {
   BASE_HIDDEN = (1 << 8),   /* Object is hidden for editing. */
 
   /* Runtime evaluated flags. */
-  BASE_VISIBLE = (1 << 1),    /* Object is enabled and visible. */
-  BASE_SELECTABLE = (1 << 2), /* Object can be selected. */
-  BASE_FROM_DUPLI = (1 << 3), /* Object comes from duplicator. */
-  /* BASE_DEPRECATED    = (1 << 4), */
-  BASE_FROM_SET = (1 << 5),         /* Object comes from set. */
-  BASE_ENABLED_VIEWPORT = (1 << 6), /* Object is enabled in viewport. */
-  BASE_ENABLED_RENDER = (1 << 7),   /* Object is enabled in final render */
+  BASE_VISIBLE_DEPSGRAPH = (1 << 1), /* Object is enabled and visible for the depsgraph. */
+  BASE_SELECTABLE = (1 << 2),        /* Object can be selected. */
+  BASE_FROM_DUPLI = (1 << 3),        /* Object comes from duplicator. */
+  BASE_VISIBLE_VIEWLAYER = (1 << 4), /* Object is enabled and visible for the viewlayer. */
+  BASE_FROM_SET = (1 << 5),          /* Object comes from set. */
+  BASE_ENABLED_VIEWPORT = (1 << 6),  /* Object is enabled in viewport. */
+  BASE_ENABLED_RENDER = (1 << 7),    /* Object is enabled in final render */
   /* BASE_DEPRECATED          = (1 << 9), */
   BASE_HOLDOUT = (1 << 10),       /* Object masked out from render */
   BASE_INDIRECT_ONLY = (1 << 11), /* Object only contributes indirectly to render */
@@ -142,10 +142,13 @@ enum {
   LAYER_COLLECTION_HIDE = (1 << 7),
 };
 
-/* Layer Collection->runtime_flag */
+/* Layer Collection->runtime_flag
+   Keep it synced with base->flag based on g_base_collection_flags. */
 enum {
   LAYER_COLLECTION_HAS_OBJECTS = (1 << 0),
-  LAYER_COLLECTION_VISIBLE = (1 << 1),
+  LAYER_COLLECTION_VISIBLE_DEPSGRAPH = (1 << 1),
+  LAYER_COLLECTION_RESTRICT_VIEWPORT = (1 << 2),
+  LAYER_COLLECTION_VISIBLE_VIEW_LAYER = (1 << 4),
 };
 
 /* ViewLayer->flag */
index ca572f1ddf1c26e8cc60d4d9ac4bd83edbc033d8..8763f62b385f928ff48ecf3482f29623eca7b5dd 100644 (file)
@@ -1976,14 +1976,7 @@ extern const char *RE_engine_id_CYCLES;
 #define MINAFRAME -1048574
 #define MINAFRAMEF -1048574.0f
 
-#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))
+#define BASE_VISIBLE(v3d, base) BKE_base_is_visible(v3d, base)
 #define BASE_SELECTABLE(v3d, base) \
   (BASE_VISIBLE(v3d, base) && \
    ((v3d == NULL) || (((1 << (base)->object->type) & (v3d)->object_type_exclude_select) == 0)) && \
index bab7375f01bdf1ed61e24e7be0c98aefb6085208..12d89ef5debc889cf0fda5d11e27d0422b32ee1d 100644 (file)
@@ -123,18 +123,13 @@ static IDProperty *rna_ViewLayer_idprops(PointerRNA *ptr, bool create)
 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 == NULL) || ((v3d->flag & V3D_LOCAL_COLLECTIONS) == 0)) {
+    return (layer_collection->runtime_flag & LAYER_COLLECTION_VISIBLE_VIEW_LAYER) != 0;
   }
 
   if (v3d->local_collections_uuid & layer_collection->local_collections_bits) {
-    return true;
+    return (layer_collection->runtime_flag & LAYER_COLLECTION_RESTRICT_VIEWPORT) == 0;
   }
 
   return false;
@@ -415,12 +410,12 @@ static void rna_def_layer_collection(BlenderRNA *brna)
 
   /* 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);
+  RNA_def_property_boolean_sdna(prop, NULL, "runtime_flag", LAYER_COLLECTION_VISIBLE_VIEW_LAYER);
   RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-  RNA_def_property_ui_text(
-      prop,
-      "Visible",
-      "Whether this collection is visible, take into account the collection parent");
+  RNA_def_property_ui_text(prop,
+                           "Visible",
+                           "Whether this collection is visible for the viewlayer, take into "
+                           "account the collection parent");
 
   func = RNA_def_function(srna, "has_objects", "rna_LayerCollection_has_objects");
   RNA_def_function_ui_description(func, "");