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
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_layer.h7
-rw-r--r--source/blender/blenkernel/intern/layer.c142
-rw-r--r--source/blender/editors/include/ED_object.h3
-rw-r--r--source/blender/editors/interface/interface_widgets.c49
-rw-r--r--source/blender/editors/object/object_edit.c116
-rw-r--r--source/blender/editors/object/object_intern.h1
-rw-r--r--source/blender/editors/object/object_ops.c9
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c58
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h2
-rw-r--r--source/blender/editors/space_outliner/outliner_ops.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c15
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c8
-rw-r--r--source/blender/makesdna/DNA_layer_types.h19
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c6
15 files changed, 366 insertions, 75 deletions
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_menu_item(uiWidgetType *wt, int state)
copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
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_ACTIVE) {
- copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
- copy_v3_v3_char(wt->wcol.text, wt->wcol.text_sel);
+ else {
+ /* regular active */
+ if (state & 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_ACTIVE) {
+ copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
+ }
}
}
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 715e6413d42..f050297ee2f 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -201,7 +201,8 @@ void OBJECT_OT_hide_view_clear(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "select", false, "Select", "");
+ PropertyRNA *prop = RNA_def_boolean(ot->srna, "select", false, "Select", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
}
static int object_hide_view_set_exec(bContext *C, wmOperator *op)
@@ -257,7 +258,115 @@ void OBJECT_OT_hide_view_set(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects");
+ PropertyRNA *prop;
+ prop = RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
+}
+
+static int object_hide_collection_exec(bContext *C, wmOperator *op)
+{
+ int index = RNA_int_get(op->ptr, "collection_index");
+ bool extend = (CTX_wm_window(C)->eventstate->shift != 0);
+
+ if (CTX_wm_window(C)->eventstate->alt != 0) {
+ index += 10;
+ }
+
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ LayerCollection *lc = BKE_layer_collection_from_index(view_layer, index);
+
+ if (!lc) {
+ return OPERATOR_CANCELLED;
+ }
+
+ BKE_layer_collection_set_visible(scene, view_layer, lc, extend);
+
+ DEG_id_tag_update(&scene->id, DEG_TAG_BASE_FLAGS_UPDATE);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+
+ return OPERATOR_FINISHED;
+}
+
+#define COLLECTION_INVALID_INDEX -1
+
+void ED_hide_collections_menu_draw(const bContext *C, uiLayout *layout)
+{
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ LayerCollection *lc_scene = view_layer->layer_collections.first;
+
+ uiLayoutSetOperatorContext(layout, WM_OP_EXEC_REGION_WIN);
+
+ for (LayerCollection *lc = lc_scene->layer_collections.first; lc; lc = lc->next) {
+ int index = BKE_layer_collection_findindex(view_layer, lc);
+ uiLayout *row = uiLayoutRow(layout, false);
+
+ if (lc->collection->flag & COLLECTION_RESTRICT_VIEW) {
+ continue;
+ }
+
+ if ((view_layer->runtime_flag & VIEW_LAYER_HAS_HIDE) &&
+ !(lc->runtime_flag & LAYER_COLLECTION_HAS_VISIBLE_OBJECTS)) {
+ uiLayoutSetActive(row, false);
+ }
+
+ int icon = ICON_NONE;
+ if (BKE_layer_collection_has_selected_objects(view_layer, lc)) {
+ icon = ICON_LAYER_ACTIVE;
+ }
+ else if (lc->runtime_flag & LAYER_COLLECTION_HAS_OBJECTS) {
+ icon = ICON_LAYER_USED;
+ }
+
+ uiItemIntO(row,
+ lc->collection->id.name + 2,
+ icon,
+ "OBJECT_OT_hide_collection",
+ "collection_index",
+ index);
+ }
+}
+
+static int object_hide_collection_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ /* Immediately execute if collection index was specified. */
+ int index = RNA_int_get(op->ptr, "collection_index");
+ if (index != COLLECTION_INVALID_INDEX) {
+ return object_hide_collection_exec(C, op);
+ }
+
+ /* Open popup menu. */
+ const char *title = CTX_IFACE_(op->type->translation_context, op->type->name);
+ uiPopupMenu *pup = UI_popup_menu_begin(C, title, ICON_GROUP);
+ uiLayout *layout = UI_popup_menu_layout(pup);
+
+ ED_hide_collections_menu_draw(C, layout);
+
+ UI_popup_menu_end(C, pup);
+
+ return OPERATOR_INTERFACE;
+}
+
+void OBJECT_OT_hide_collection(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Hide Objects By Collection";
+ ot->description = "Show only objects in collection (Shift to extend)";
+ ot->idname = "OBJECT_OT_hide_collection";
+
+ /* api callbacks */
+ ot->exec = object_hide_collection_exec;
+ ot->invoke = object_hide_collection_invoke;
+ ot->poll = ED_operator_view3d_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* Properties. */
+ PropertyRNA *prop;
+ prop = RNA_def_int(ot->srna, "collection_index", COLLECTION_INVALID_INDEX, COLLECTION_INVALID_INDEX, INT_MAX,
+ "Collection Index", "Index of the collection to change visibility", 0, INT_MAX);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
}
/* ******************* toggle editmode operator ***************** */
@@ -1661,8 +1770,6 @@ bool ED_object_editmode_calc_active_center(Object *obedit, const bool select_onl
return false;
}
-#define COLLECTION_INVALID_INDEX -1
-
static int move_to_collection_poll(bContext *C)
{
if (CTX_wm_space_outliner(C) != NULL) {
@@ -1983,4 +2090,3 @@ void OBJECT_OT_link_to_collection(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
-#undef COLLECTION_INVALID_INDEX
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index f64beeda15a..f7179912f52 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -78,6 +78,7 @@ void OBJECT_OT_unlink_data(struct wmOperatorType *ot);
/* object_edit.c */
void OBJECT_OT_hide_view_set(struct wmOperatorType *ot);
void OBJECT_OT_hide_view_clear(struct wmOperatorType *ot);
+void OBJECT_OT_hide_collection(struct wmOperatorType *ot);
void OBJECT_OT_mode_set(struct wmOperatorType *ot);
void OBJECT_OT_mode_set_or_submode(struct wmOperatorType *ot);
void OBJECT_OT_editmode_toggle(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 59122fe3c23..ad14679622f 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -250,6 +250,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_hide_view_clear);
WM_operatortype_append(OBJECT_OT_hide_view_set);
+ WM_operatortype_append(OBJECT_OT_hide_collection);
}
void ED_operatormacros_object(void)
@@ -409,11 +410,17 @@ void ED_keymap_object(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "OBJECT_OT_link_to_collection", MKEY, KM_PRESS, KM_SHIFT, 0);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0);
- RNA_boolean_set(kmi->ptr, "select", false);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "unselected", false);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "unselected", true);
+ kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_collection", HKEY, KM_PRESS, KM_CTRL, 0);
+
+ /* Collection switching. */
+ for (int i = 0; i < 10; i++) {
+ kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_collection", ZEROKEY + i, KM_PRESS, KM_ANY, 0);
+ RNA_int_set(kmi->ptr, "collection_index", (i == 0) ? 10 : i);
+ }
}
void ED_keymap_proportional_cycle(struct wmKeyConfig *UNUSED(keyconf), struct wmKeyMap *keymap)
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 88fa9afd116..5f97c7858af 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -280,10 +280,38 @@ static void restrictbutton_id_user_toggle(bContext *UNUSED(C), void *poin, void
static void hidebutton_base_flag_cb(bContext *C, void *poin, void *poin2)
{
- Scene *scene = poin;
- ViewLayer *view_layer = poin2;
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = poin;
+ Base *base = poin2;
+ bool extend = (CTX_wm_window(C)->eventstate->ctrl == 0);
+
+ /* Undo button toggle, let function do it. */
+ base->flag ^= BASE_HIDE;
+
+ BKE_base_set_visible(scene, view_layer, base, extend);
+
+ if (!extend && (base->flag & BASE_VISIBLED)) {
+ /* Auto select solo-ed object. */
+ ED_object_base_select(base, BA_SELECT);
+ view_layer->basact = base;
+ }
+
+ DEG_id_tag_update(&scene->id, DEG_TAG_BASE_FLAGS_UPDATE);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+}
+
+static void hidebutton_layer_collection_flag_cb(bContext *C, void *poin, void *poin2)
+{
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = poin;
+ LayerCollection *lc = poin2;
+ bool extend = (CTX_wm_window(C)->eventstate->ctrl == 0);
+
+ /* Undo button toggle, let function do it. */
+ lc->runtime_flag ^= LAYER_COLLECTION_HAS_VISIBLE_OBJECTS;
+
+ BKE_layer_collection_set_visible(scene, view_layer, lc, extend);
- BKE_layer_collection_sync(scene, view_layer);
DEG_id_tag_update(&scene->id, DEG_TAG_BASE_FLAGS_UPDATE);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
@@ -482,15 +510,16 @@ static void outliner_draw_restrictbuts(
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
}
else if (tselem->type == 0 && te->idcode == ID_OB) {
- ob = (Object *)tselem->id;
+ Object *ob = (Object *)tselem->id;
Base *base = BKE_view_layer_base_find(view_layer, ob);
if (base) {
- bt = uiDefIconButBitS(block, UI_BTYPE_ICON_TOGGLE, BASE_HIDE, 0, ICON_HIDE_OFF,
+ bt = uiDefIconButBitS(
+ block, UI_BTYPE_ICON_TOGGLE, BASE_HIDE, 0, ICON_HIDE_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_HIDEX), te->ys, UI_UNIT_X,
UI_UNIT_Y, &base->flag, 0, 0, 0, 0,
- TIP_("Hide object in viewport"));
- UI_but_func_set(bt, hidebutton_base_flag_cb, scene, view_layer);
+ TIP_("Hide object in viewport (Ctrl to isolate)"));
+ UI_but_func_set(bt, hidebutton_base_flag_cb, view_layer, base);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
}
@@ -603,6 +632,16 @@ static void outliner_draw_restrictbuts(
if ((!lc || !(lc->flag & LAYER_COLLECTION_EXCLUDE)) &&
!(collection->flag & COLLECTION_IS_MASTER))
{
+ if (lc && (lc->runtime_flag & LAYER_COLLECTION_HAS_ENABLED_OBJECTS)) {
+ bt = uiDefIconButBitS(
+ block, UI_BTYPE_ICON_TOGGLE_N, LAYER_COLLECTION_HAS_VISIBLE_OBJECTS, 0, ICON_HIDE_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_HIDEX), te->ys, UI_UNIT_X,
+ UI_UNIT_Y, &lc->runtime_flag, 0, 0, 0, 0,
+ TIP_("Hide collection in viewport (Ctrl to isolate)"));
+ UI_but_func_set(bt, hidebutton_layer_collection_flag_cb, view_layer, lc);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+
PointerRNA collection_ptr;
RNA_id_pointer_create(&collection->id, &collection_ptr);
@@ -1945,7 +1984,10 @@ static void outliner_draw_restrictcols(ARegion *ar)
unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColorShadeAlpha(TH_BACK, -15, -200);
- immBegin(GWN_PRIM_LINES, 6);
+ immBegin(GWN_PRIM_LINES, 8);
+
+ immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_HIDEX), (int)ar->v2d.cur.ymax);
+ immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_HIDEX), (int)ar->v2d.cur.ymin);
immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)ar->v2d.cur.ymax);
immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)ar->v2d.cur.ymin);
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 89fd75324f2..1f8320f73a0 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -156,7 +156,7 @@ typedef enum {
#define OL_TOG_RESTRICT_VIEWX (UI_UNIT_X * 2.0f)
#define OL_TOG_RESTRICT_RENDERX UI_UNIT_X
-#define OL_TOGW OL_TOG_RESTRICT_SELECTX
+#define OL_TOGW OL_TOG_HIDEX
#define OL_RNA_COLX (UI_UNIT_X * 15)
#define OL_RNA_COL_SIZEX (UI_UNIT_X * 7.5f)
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index 14d6ba40a72..316caf0e239 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -562,7 +562,7 @@ void outliner_keymap(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "select", false);
- kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, KM_CTRL, 0);
+ kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "unselected", false);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "unselected", true);
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 6618da3ee53..13b62b766f5 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -1491,7 +1491,9 @@ static void outliner_add_layer_collections_recursive(
ten->reinsert_poll = outliner_collections_reorder_poll;
const bool exclude = (lc->flag & LAYER_COLLECTION_EXCLUDE) != 0;
- if (exclude) {
+ if (exclude ||
+ ((layer->runtime_flag & VIEW_LAYER_HAS_HIDE) &&
+ !(lc->runtime_flag & LAYER_COLLECTION_HAS_VISIBLE_OBJECTS))) {
ten->flag |= TE_DISABLED;
}
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 300b6fafd7a..6ebed88728e 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -69,6 +69,7 @@
#include "RNA_access.h"
#include "ED_armature.h"
+#include "ED_object.h"
#include "ED_mesh.h"
#include "ED_screen.h"
@@ -1163,6 +1164,11 @@ static void view3d_panel_transform(const bContext *C, Panel *pa)
}
}
+static void hide_collections_menu_draw(const bContext *C, Menu *menu)
+{
+ ED_hide_collections_menu_draw(C, menu->layout);
+}
+
void view3d_buttons_register(ARegionType *art)
{
PanelType *pt;
@@ -1182,6 +1188,15 @@ void view3d_buttons_register(ARegionType *art)
pt->draw = view3d_panel_vgroup;
pt->poll = view3d_panel_vgroup_poll;
BLI_addtail(&art->paneltypes, pt);
+
+ MenuType *mt;
+
+ mt = MEM_callocN(sizeof(MenuType), "spacetype view3d menu collections");
+ strcpy(mt->idname, "VIEW3D_MT_collection");
+ strcpy(mt->label, N_("Collection"));
+ strcpy(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ mt->draw = hide_collections_menu_draw;
+ WM_menutype_add(mt);
}
static int view3d_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 02898cb8bd3..fd2f604651b 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -1045,9 +1045,8 @@ static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d)
return name;
}
-static void draw_viewport_name(const bContext *C, ARegion *ar, View3D *v3d, const rcti *rect)
+static void draw_viewport_name(ARegion *ar, View3D *v3d, const rcti *rect)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
RegionView3D *rv3d = ar->regiondata;
const char *name = view3d_get_name(v3d, rv3d);
/* increase size for unicode languages (Chinese in utf-8...) */
@@ -1057,8 +1056,7 @@ static void draw_viewport_name(const bContext *C, ARegion *ar, View3D *v3d, cons
char tmpstr[32];
#endif
- /* TODO: integrate localvd with local hiding */
- if (v3d->localvd || (view_layer->runtime_flag & VIEW_LAYER_HAS_HIDE)) {
+ if (v3d->localvd) {
BLI_snprintf(tmpstr, sizeof(tmpstr), IFACE_("%s (Local)"), name);
name = tmpstr;
}
@@ -1221,7 +1219,7 @@ void view3d_draw_region_info(const bContext *C, ARegion *ar, const int offset)
ED_scene_draw_fps(scene, &rect);
}
else if (U.uiflag & USER_SHOW_VIEWPORTNAME) {
- draw_viewport_name(C, ar, v3d, &rect);
+ draw_viewport_name(ar, v3d, &rect);
}
if (U.uiflag & USER_DRAWVIEWINFO) {
diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h
index f7536ec0df5..6b4dcc39005 100644
--- a/source/blender/makesdna/DNA_layer_types.h
+++ b/source/blender/makesdna/DNA_layer_types.h
@@ -91,15 +91,15 @@ typedef struct ViewLayer {
/* Base->flag */
enum {
- BASE_SELECTED = (1 << 0),
- BASE_VISIBLED = (1 << 1),
- BASE_SELECTABLED = (1 << 2),
- BASE_FROMDUPLI = (1 << 3),
+ BASE_SELECTED = (1 << 0), /* Object is selected. */
+ BASE_VISIBLED = (1 << 1), /* Object is visible. */
+ BASE_SELECTABLED = (1 << 2), /* Object can be selected. */
+ BASE_FROMDUPLI = (1 << 3), /* Object comes from duplicator. */
/* BASE_DEPRECATED = (1 << 4), */
BASE_FROM_SET = (1 << 5), /* To be set only by the depsgraph */
- BASE_VISIBLE_VIEWPORT = (1 << 6),
- BASE_VISIBLE_RENDER = (1 << 7),
- BASE_HIDE = (1 << 8),
+ BASE_VISIBLE_VIEWPORT = (1 << 6), /* Object is visible in viewport. */
+ BASE_VISIBLE_RENDER = (1 << 7), /* Object is visible in final render */
+ BASE_HIDE = (1 << 8), /* Object is hidden for editing. */
};
/* LayerCollection->flag */
@@ -113,8 +113,9 @@ enum {
/* Layer Collection->runtime_flag */
enum {
- LAYER_COLLECTION_HAS_VISIBLE_OBJECTS = (1 << 0),
- LAYER_COLLECTION_HAS_SELECTED_OBJECTS = (1 << 1),
+ LAYER_COLLECTION_HAS_OBJECTS = (1 << 0),
+ LAYER_COLLECTION_HAS_VISIBLE_OBJECTS = (1 << 1),
+ LAYER_COLLECTION_HAS_ENABLED_OBJECTS = (1 << 2),
};
/* ViewLayer->flag */
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index bbc7e6fbb69..bcb4fffea87 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -992,11 +992,7 @@ int WM_keymap_item_raw_to_string(
alt == KM_ANY &&
oskey == KM_ANY)
{
- /* make it implicit in case of compact result expected. */
- if (!compact) {
- ADD_SEP;
- p += BLI_strcpy_rlen(p, IFACE_("Any"));
- }
+ /* Don't show anything for any mapping. */
}
else {
if (shift) {