diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_layer.h | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/layer.c | 142 | ||||
-rw-r--r-- | source/blender/editors/include/ED_object.h | 3 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_widgets.c | 49 | ||||
-rw-r--r-- | source/blender/editors/object/object_edit.c | 116 | ||||
-rw-r--r-- | source/blender/editors/object/object_intern.h | 1 | ||||
-rw-r--r-- | source/blender/editors/object/object_ops.c | 9 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner_draw.c | 58 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner_intern.h | 2 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner_ops.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner_tree.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_buttons.c | 15 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_draw.c | 8 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_layer_types.h | 19 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_keymap.c | 6 |
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) { |