[Bf-blender-cvs] [897e047374f] master: Outliner visibility unification: Implement 3 levels of viewport visibility

Dalai Felinto noreply at git.blender.org
Tue Feb 5 22:35:42 CET 2019


Commit: 897e047374fa3d3ceef35aa2cdb3372b6a7cc64a
Author: Dalai Felinto
Date:   Fri Nov 30 02:24:06 2018 -0200
Branches: master
https://developer.blender.org/rB897e047374fa3d3ceef35aa2cdb3372b6a7cc64a

Outliner visibility unification: Implement 3 levels of viewport visibility

Now collection and objects can be either:
* Disabled for all the view layers.
* Hidden for a view layer but not necessarily for all others.
* Visible for a view layer but not necessarily for all others.

Regarding icons: Whatever we decide to use for the "Hidden for all view
layers" needs to be a toggle-like icon. Because when viewing "Scenes"
instead of "View Layer" in the outliner we should be able to edit the
collection "Hidden for all the view layers" as an on/off option.

The operators are accessible via a Visibility context menu or shortcuts:
* Ctrl + Click: Isolate collection (use shift to extend).
* Alt + Click: Disable collection.
* Shift + Click: Hide/Show collection and its children (objects and collections)

Things yet to be tackled:
* Object outliner context menu can also get a Visibility sub-menu.
* Get better icons for viewport enable/disable.

Note:
* When using emulate 3 button mouse alt+click is used for 2d panning.
  In this case users have to use the operator from the menu.

See T57857 for discussion.

Patch: https://developer.blender.org/D4011
Reviewers: brecht and sergey

Thanks to the reviewers and William Reynish and Julien Kasper in
particular for the feedback.

===================================================================

M	release/scripts/startup/bl_ui/space_outliner.py
M	source/blender/blenkernel/BKE_layer.h
M	source/blender/blenkernel/intern/layer.c
M	source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
M	source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
M	source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
M	source/blender/editors/object/object_edit.c
M	source/blender/editors/space_outliner/outliner_collections.c
M	source/blender/editors/space_outliner/outliner_draw.c
M	source/blender/editors/space_outliner/outliner_intern.h
M	source/blender/editors/space_outliner/outliner_ops.c
M	source/blender/makesrna/intern/rna_layer.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py
index 4ab990c451b..59fd4701748 100644
--- a/release/scripts/startup/bl_ui/space_outliner.py
+++ b/release/scripts/startup/bl_ui/space_outliner.py
@@ -148,6 +148,29 @@ class OUTLINER_MT_collection_view_layer(Menu):
             layout.operator("outliner.collection_holdout_clear")
 
 
+class OUTLINER_MT_collection_visibility(Menu):
+    bl_label = "Visibility"
+
+    def draw(self, context):
+        layout = self.layout
+
+        layout.operator("outliner.collection_isolate", text="Isolate")
+        layout.operator("outliner.collection_show", text="Show")
+        layout.operator("outliner.collection_hide", text="Hide")
+
+        layout.separator()
+        layout.operator("outliner.collection_show_inside", text="Show All Inside")
+        layout.operator("outliner.collection_hide_inside", text="Hide All Inside")
+
+        layout.separator()
+        layout.operator("outliner.collection_enable", text="Enable in Viewports")
+        layout.operator("outliner.collection_disable", text="Disable in Viewports")
+
+        layout.separator()
+        layout.operator("outliner.collection_enable_render", text="Enable in Render")
+        layout.operator("outliner.collection_disable_render", text="Disable in Render")
+
+
 class OUTLINER_MT_collection(Menu):
     bl_label = "Collection"
 
@@ -177,6 +200,9 @@ class OUTLINER_MT_collection(Menu):
             layout.separator()
             layout.menu("OUTLINER_MT_collection_view_layer")
 
+        layout.separator()
+        layout.menu("OUTLINER_MT_collection_visibility")
+
         layout.separator()
         layout.operator_menu_enum("outliner.id_operation", "type", text="ID Data")
 
@@ -301,6 +327,7 @@ classes = (
     OUTLINER_MT_edit_datablocks,
     OUTLINER_MT_collection,
     OUTLINER_MT_collection_new,
+    OUTLINER_MT_collection_visibility,
     OUTLINER_MT_collection_view_layer,
     OUTLINER_MT_object,
     OUTLINER_MT_context,
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index cff80ef3467..65c0202ef66 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -109,7 +109,8 @@ bool BKE_layer_collection_has_layer_collection(
         struct LayerCollection *lc_parent, struct LayerCollection *lc_child);
 
 void BKE_base_set_visible(struct Scene *scene, struct ViewLayer *view_layer, struct Base *base, bool extend);
-void BKE_layer_collection_set_visible(struct Scene *scene, struct ViewLayer *view_layer, struct LayerCollection *lc, bool extend);
+bool BKE_layer_collection_isolate(struct Scene *scene, struct ViewLayer *view_layer, struct LayerCollection *lc, bool extend);
+bool BKE_layer_collection_set_visible(struct ViewLayer *view_layer, struct LayerCollection *lc, const bool visible, const bool hierarchy);
 
 /* evaluation */
 
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 0b49a389ab1..f9d39c840e2 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -669,7 +669,9 @@ static short layer_collection_sync(
 			lc->runtime_flag = child_runtime_flag;
 		}
 
-		if ((child_layer_restrict & LAYER_COLLECTION_RESTRICT_VIEW) == 0) {
+		if (((child_restrict & COLLECTION_RESTRICT_VIEW) == 0) &&
+		    ((child_layer_restrict & LAYER_COLLECTION_RESTRICT_VIEW) == 0))
+		{
 			lc->runtime_flag |= LAYER_COLLECTION_VISIBLE;
 		}
 
@@ -701,15 +703,18 @@ static short layer_collection_sync(
 			int object_restrict = base->object->restrictflag;
 
 			if (((child_restrict & COLLECTION_RESTRICT_VIEW) == 0) &&
-			    ((child_layer_restrict & LAYER_COLLECTION_RESTRICT_VIEW) == 0) &&
 			    ((object_restrict & OB_RESTRICT_VIEW) == 0))
 			{
-				base->flag |= BASE_VISIBLE | BASE_ENABLED | BASE_ENABLED_VIEWPORT;
+				base->flag |= BASE_ENABLED | BASE_ENABLED_VIEWPORT;
 
-				if (((child_restrict & COLLECTION_RESTRICT_SELECT) == 0) &&
-				    ((object_restrict & OB_RESTRICT_SELECT) == 0))
-				{
-					base->flag |= BASE_SELECTABLE;
+				if ((child_layer_restrict & LAYER_COLLECTION_RESTRICT_VIEW) == 0) {
+					base->flag |= BASE_VISIBLE;
+
+					if (((child_restrict & COLLECTION_RESTRICT_SELECT) == 0) &&
+						((object_restrict & OB_RESTRICT_SELECT) == 0))
+					{
+						base->flag |= BASE_SELECTABLE;
+					}
 				}
 			}
 
@@ -720,7 +725,7 @@ static short layer_collection_sync(
 			}
 
 			/* Update runtime flags used for display and tools. */
-			if (base->flag & BASE_VISIBLE) {
+			if (base->flag & BASE_ENABLED) {
 				lc->runtime_flag |= LAYER_COLLECTION_HAS_ENABLED_OBJECTS;
 			}
 
@@ -987,48 +992,124 @@ static void layer_collection_flag_unset_recursive(LayerCollection *lc, const int
 }
 
 /**
- * Set collection per-view layer visiblity.
- * When not extending, we show all the direct parents and all children of the layer collection.
+ * Return true if something changed. */
+static bool layer_collection_collection_flag_unset_recursive(LayerCollection *lc, const int flag)
+{
+	bool changed = (lc->collection->flag & flag) != 0;
+
+	lc->collection->flag &= ~flag;
+	for (LayerCollection *lc_iter = lc->layer_collections.first; lc_iter; lc_iter = lc_iter->next) {
+		changed |= layer_collection_collection_flag_unset_recursive(lc_iter, flag);
+	}
+
+	return changed;
+}
+
+/**
+ * Isolate the collection - hide all other collections but this one.
+ * Make sure to show all the direct parents and all children of the layer collection as well.
+ * When extending we simply show the collections and its direct family.
+ *
+ * Return whether depsgraph needs update.
  */
-void BKE_layer_collection_set_visible(Scene *scene, ViewLayer *view_layer, LayerCollection *lc, bool extend)
+bool BKE_layer_collection_isolate(Scene *scene, ViewLayer *view_layer, LayerCollection *lc, bool extend)
 {
+	bool depsgraph_need_update = false;
 	if (!extend) {
-		/* Make only this collection visible. */
+		/* Hide all collections . */
 		for (LayerCollection *lc_iter = view_layer->layer_collections.first; lc_iter; lc_iter = lc_iter->next) {
 			layer_collection_flag_set_recursive(lc_iter, LAYER_COLLECTION_RESTRICT_VIEW);
 		}
+	}
 
-		/* Make all the direct parents visible. */
-		LayerCollection *lc_parent = lc;
-		LayerCollection *lc_master = view_layer->layer_collections.first;
-		for (LayerCollection *lc_iter = lc_master->layer_collections.first; lc_iter; lc_iter = lc_iter->next) {
+	/* Make all the direct parents visible. */
+	LayerCollection *lc_parent = lc;
+	LayerCollection *lc_master = view_layer->layer_collections.first;
+	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) {
+		depsgraph_need_update |= (lc_parent->collection->flag & COLLECTION_RESTRICT_VIEW) != 0;
+		lc_parent->collection->flag &= ~COLLECTION_RESTRICT_VIEW;
+		lc_parent->flag &= ~LAYER_COLLECTION_RESTRICT_VIEW;
+
+		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;
 			}
 		}
+	}
 
-		while (lc_parent != lc) {
-			lc_parent->flag &= ~LAYER_COLLECTION_RESTRICT_VIEW;
+	/* Make all the children visible. */
+	layer_collection_flag_unset_recursive(lc, LAYER_COLLECTION_RESTRICT_VIEW);
+	depsgraph_need_update |= layer_collection_collection_flag_unset_recursive(lc, COLLECTION_RESTRICT_VIEW);
 
-			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;
-				}
-			}
-		}
+	BKE_layer_collection_activate(view_layer, lc);
+
+	BKE_layer_collection_sync(scene, view_layer);
+
+	return depsgraph_need_update;
+}
 
-		/* Make all the children visible. */
-		layer_collection_flag_unset_recursive(lc, LAYER_COLLECTION_RESTRICT_VIEW);
+static void layer_collection_bases_show_recursive(ViewLayer *view_layer, LayerCollection *lc)
+{
+	for (CollectionObject *cob = lc->collection->gobject.first; cob; cob = cob->next) {
+		Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
+		base->flag &= ~BASE_HIDDEN;
+		base->object->restrictflag &= ~OB_RESTRICT_VIEW;
+	}
+	for (LayerCollection *lc_iter = lc->layer_collections.first; lc_iter; lc_iter = lc_iter->next) {
+		layer_collection_bases_show_recursive(view_layer, lc_iter);
+	}
+}
 
-		BKE_layer_collection_activate(view_layer, lc);
+static void layer_collection_bases_hide_recursive(ViewLayer *view_layer, LayerCollection *lc)
+{
+	for (CollectionObject *cob = lc->collection->gobject.first; cob; cob = cob->next) {
+		Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
+		base->flag |= BASE_HIDDEN;
 	}
-	else {
-		lc->flag ^= LAYER_COLLECTION_RESTRICT_VIEW;
+	for (LayerCollection *lc_iter = lc->layer_collections.first; lc_iter; lc_iter = lc_iter->next) {
+		layer_collection_bases_hide_recursive(view_layer, lc_iter);
 	}
+}
 
-	BKE_layer_collection_sync(scene, view_layer);
+/**
+ * Hide/show all the elements of a collection.
+ * Enable a disable collection if needs be.
+ *
+ * Return true if depsgraph needs update.
+ */
+bool BKE_layer_collection_set_visible(ViewLayer *view_layer, LayerCollection *lc, const bool visible, const bool hierarchy)
+{
+	bool depsgraph_changed = false;
+	if (hierarchy) {
+		if (visible) {
+			depsgraph_changed |= layer_collection_collection_flag_unset_recursive(lc, COLLECTION_RESTRICT_VIEW);
+			layer_collection_flag_unset_recursive(lc, LAYER_COLLECTION_RESTRICT_VIEW);
+			layer_collection_bases_show_recursive(view_layer, lc);
+		}
+		else {
+			layer_collection_flag_set_recursive(lc, LAYER_COLLECTION_RESTRICT_VIEW);
+			layer_collection_bases_hide_recursive(view_layer, lc);
+		}
+	}
+	else {
+		if (visible) {
+			depsgraph_changed |= (lc->collection->flag & COLLECTION_RESTRICT_VIEW) != 0;
+			lc->flag &= ~LAYER_COLLECTION_RESTRICT_VIEW;
+			lc->collection->flag &= ~COLLECTION_RESTRICT_VIEW;
+		}
+		else {
+			lc->flag |= LAYER_COL

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list