[Bf-blender-cvs] [4234cddda9e] blender2.8: Objects: support for hiding all objects in a collection.

Brecht Van Lommel noreply at git.blender.org
Wed Jun 20 13:05:14 CEST 2018


Commit: 4234cddda9ed59e5a7fff7043a2add2aaf158d23
Author: Brecht Van Lommel
Date:   Mon Jun 18 19:49:53 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB4234cddda9ed59e5a7fff7043a2add2aaf158d23

Objects: support for hiding all objects in a collection.

In the outliner there are now icons for it, Ctrl+Click isolates a
single collections.

In the 3D view, Ctrl+H key opens a menu that is more or less the
equivalent of the old layer buttons in the header. Regular Click isolates
the collection, Shift+Click toggle the collection visibility. Pressing
number keys and letters works in this menu, which can help for quickly
selecting a specific collection.

Shortcuts for quick switching by just pressing 1/2/3/.. keys are available
again. The order can be confusing with nested collections, but that seems
unavoidable. The first numbers control the top level collections, and then
sub collections if numbers are left.

Remaining design issues:

* The 3D view menu needs to be improved: support for sub collections,
  staying open on shift+click, access from the 3D view header somewhere,
  shortcut key display.
* Currently collection hiding just controls per-object hiding, we plan
  to separate this state still so alt+H doesn't affect collection hiding.

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

M	source/blender/blenkernel/BKE_layer.h
M	source/blender/blenkernel/intern/layer.c
M	source/blender/editors/include/ED_object.h
M	source/blender/editors/interface/interface_widgets.c
M	source/blender/editors/object/object_edit.c
M	source/blender/editors/object/object_intern.h
M	source/blender/editors/object/object_ops.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/editors/space_outliner/outliner_tree.c
M	source/blender/editors/space_view3d/view3d_buttons.c
M	source/blender/editors/space_view3d/view3d_draw.c
M	source/blender/makesdna/DNA_layer_types.h
M	source/blender/windowmanager/intern/wm_keymap.c

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

diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 60204d177f2..9e89033894d 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -104,8 +104,15 @@ bool BKE_view_layer_has_collection(
 bool BKE_scene_has_object(
         struct Scene *scene, struct Object *ob);
 
+/* selection and hiding */
+
 bool BKE_layer_collection_objects_select(
         struct ViewLayer *view_layer, struct LayerCollection *lc, bool deselect);
+bool BKE_layer_collection_has_selected_objects(
+        struct ViewLayer *view_layer, struct LayerCollection *lc);
+
+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);
 
 /* override */
 
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 84915e628df..db9ce76b30c 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -439,7 +439,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;
@@ -537,7 +539,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;
@@ -567,7 +571,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)
@@ -594,6 +598,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;
@@ -608,8 +613,6 @@ static void layer_collection_sync(
 			lc->flag = parent_exclude;
 		}
 
-		lc->runtime_flag = 0;
-
 		/* Collection restrict is inherited. */
 		int child_restrict = parent_restrict;
 		if (!(collection->flag & COLLECTION_IS_MASTER)) {
@@ -617,15 +620,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) {
@@ -668,22 +675,29 @@ static void layer_collection_sync(
 				base->flag |= BASE_VISIBLE_RENDER;
 			}
 
-			/* Update runtime flags used for faster display. */
+			/* Update runtime flags used for display and tools. */
+			if (base->flag & BASE_VISIBLED) {
+				lc->runtime_flag |= LAYER_COLLECTION_HAS_ENABLED_OBJECTS;
+			}
+
 			if (base->flag & BASE_HIDE) {
 				view_layer->runtime_flag |= VIEW_LAYER_HAS_HIDE;
 			}
 			else if (base->flag & BASE_VISIBLED) {
 				lc->runtime_flag |= LAYER_COLLECTION_HAS_VISIBLE_OBJECTS;
-				if (base->flag & BASE_SELECTED) {
-					lc->runtime_flag |= LAYER_COLLECTION_HAS_SELECTED_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;
 }
 
 /**
@@ -834,6 +848,107 @@ 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;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* Test base visibility when BASE_VISIBLED has not been set yet. */
+static bool base_is_visible(Base *base, eEvaluationMode mode)
+{
+	if (mode == DAG_EVAL_VIEWPORT) {
+		return ((base->flag & BASE_VISIBLE_VIEWPORT) != 0) &&
+		       ((base->flag & BASE_HIDE) == 0);
+	}
+	else {
+		return ((base->flag & BASE_VISIBLE_RENDER) != 0);
+	}
+}
+
+/* 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_HIDE;
+		}
+
+		base->flag &= ~BASE_HIDE;
+	}
+	else {
+		/* Toggle visibility of one base. */
+		base->flag ^= BASE_HIDE;
+	}
+
+	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_HIDE;
+		}
+
+		FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(lc->collection, ob)
+		{
+			Base *base = BLI_ghash_lookup(view_layer->object_bases_hash, ob);
+
+			if (base) {
+				base->flag &= ~BASE_HIDE;
+			}
+		}
+		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_HIDE;
+				}
+				else {
+					base->flag &= ~BASE_HIDE;
+				}
+			}
+		}
+		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)
@@ -1251,17 +1366,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) &&
-		       ((base->flag & BASE_HIDE) == 0);
-	}
-	else {
-		return ((base->flag & BASE_VISIBLE_RENDER) != 0);
-	}
-}
-
 /* Evaluation  */
 
 void BKE_layer_eval_view_layer(
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index d8a31e93a87..29f7edaebf0 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -40,6 +40,7 @@ struct Base;
 struct EnumPropertyItem;
 struct ID;
 struct Main;
+struct Menu;
 struct ModifierData;
 struct Object;
 struct ReportList;
@@ -58,12 +59,14 @@ struct PointerRNA;
 struct PropertyRNA;
 struct EnumPropertyItem;
 struct Depsgraph;
+struct uiLayout;
 
 #include "DNA_object_enums.h"
 
 /* object_edit.c */
 struct Object *ED_object_context(struct bContext *C);               /* context.object */
 struct Object *ED_object_active_context(struct bContext *C); /* context.object or context.active_object */
+void ED_hide_collections_menu_draw(const struct bContext *C, struct uiLayout *layout);
 
 /* object_ops.c */
 void ED_operatortypes_object(void);
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 37a454d97c2..3b7ccb68fd4 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -2657,18 +2657,22 @@ static void widget_state_pie_menu_item(uiWidgetType *wt, int state)
 		copy_v4_v4_char(wt->wcol.inner, wt->wcol.item);
 		wt->wcol.inner[3] = 64;
 	}
-	/* regular disabled */
-	else if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
-		widget_state_blend(wt->wcol.text, wt->wcol.inner, 0.5f);
-	}
-	/* regular active */
-	else if (state & UI_SELECT) {
-		copy_v4_v4_char(wt->wcol.outline, wt->wcol.inner_sel);
-		copy_v3_v3_char(wt->wcol.text, wt->wcol.text_sel);
-	}
-	else if (state & UI_ACTIVE) {
-		copy_v4_v4_char(wt->wcol.inner, wt->wcol.item);
-		copy_v3_v3_char(wt->wcol.text, wt->wcol.text_sel);
+	else {
+		/* regular active */
+		if (state & (UI_SELECT | UI_ACTIVE)) {
+			copy_v3_v3_char(wt->wcol.text, wt->wcol.text_sel);
+		}
+		else if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
+			/* regular disabled */
+			widget_state_blend(wt->wcol.text, wt->wcol.inner, 0.5f);
+		}
+
+		if (state & UI_SELECT) {
+			copy_v4_v4_char(wt->wcol.outline, wt->wcol.inner_sel);
+		}
+		else if (state & UI_ACTIVE) {
+			copy_v4_v4_char(wt->wcol.inner, wt->wcol.item);
+		}
 	}
 }
 
@@ -2685,14 +2689,19 @@ static void widget_state_me

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list