From 68afd225018e59d63431e02def51575bfc76f5cb Mon Sep 17 00:00:00 2001 From: Sean Kim Date: Tue, 12 Mar 2024 14:19:02 +0100 Subject: [PATCH] Sculpt: Add Lasso Hide tool This commit adds the `SCULPT_OT_hide_show_lasso_gesture` and the corresponding Lasso Hide tool. * Exposes the selection type for both the lasso and box hide tools as a option in the header * Adds functionality into `sculpt_gesture.cc` for handling lasso selections with the `Outside` selection type For `SelectionType::Outside`, the current implementation opts to not do any filtering on the PBVH node level due to cases where the node is mostly covered by a single gesture. Addresses one of the tools in #80390 Pull Request: https://projects.blender.org/blender/blender/pulls/119140 --- release/datafiles/assets | 2 +- .../datafiles/icons/ops.sculpt.lasso_hide.dat | Bin 0 -> 2240 bytes .../keyconfig/keymap_data/blender_default.py | 16 +++++++++ .../startup/bl_ui/space_toolsystem_toolbar.py | 25 +++++++++++++- scripts/startup/bl_ui/space_view3d.py | 6 ++++ .../blender/editors/datafiles/CMakeLists.txt | 1 + .../editors/sculpt_paint/paint_hide.cc | 31 ++++++++++++++++++ .../editors/sculpt_paint/paint_intern.hh | 1 + .../blender/editors/sculpt_paint/paint_ops.cc | 1 + .../editors/sculpt_paint/sculpt_gesture.cc | 18 ++++++++-- .../windowmanager/intern/wm_operators.cc | 1 + 11 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 release/datafiles/icons/ops.sculpt.lasso_hide.dat diff --git a/release/datafiles/assets b/release/datafiles/assets index 3a36a5abc7b..1d44611dd36 160000 --- a/release/datafiles/assets +++ b/release/datafiles/assets @@ -1 +1 @@ -Subproject commit 3a36a5abc7b8866fe1e4d23ddea9aed1ff01c80d +Subproject commit 1d44611dd36032c1889c66d673801ef7d699f592 diff --git a/release/datafiles/icons/ops.sculpt.lasso_hide.dat b/release/datafiles/icons/ops.sculpt.lasso_hide.dat new file mode 100644 index 0000000000000000000000000000000000000000..452017b6a7cd13f158581b88bf73a111f7838db6 GIT binary patch literal 2240 zcmeIuT}vWS7zgma(7=E!JFF#|%|MoDVODfu*<55xq>Y4;OSWTZj2D{tvdlnQN>R}! z64A?mv}B}_O?qZb=EZN~9>2rF-gw~oA9y(DIftLqY#ZwJhK642FXB@}s0zYs9aN;c zPz4qBUj8H9X=U|ZDywH&Svptq>X~??WYj#!$}uGacH~$q27K}k*a2?E2YgM3vIN|3 zmddc7lrblsgR>6kqQ7CC!+fcV9THDr`Hm%X^WSi+SZLXc{ zCffyx>vHW2v8WZKYjCMvi2TQmd<~u&l~4ZTwJr!RqELl00;oWjzS13(xs%FJrf+j5 zor_0mUOWO>D3fi)&qg?FZ_=Gt%zubLl>JXV4({X8X( zVdZV?MBc_Nq~^GV%u1ZhtRyIAJwZi-^k$IWg6WN}?QR8^V~cxhyR!)gv$$u?jvqJ} z;?T&BA3&L+ku{%;Ug=AtSNN@g$8RlFw6;RTK z3Vomu^no@El%cgGlwqI>*G+Z{Qc>f&7viN_)ULsee5vvumCqabsqrFKK8bxp90}=M znA0A{oH%X| gesture_data = gesture::init_from_lasso(C, op); + if (!gesture_data) { + return OPERATOR_CANCELLED; + } + hide_show_init_properties(*C, *gesture_data, *op); + gesture::apply(*C, *gesture_data, *op); + return OPERATOR_FINISHED; +} + static void hide_show_operator_properties(wmOperatorType *ot) { static const EnumPropertyItem action_items[] = { @@ -765,6 +776,26 @@ void PAINT_OT_hide_show(wmOperatorType *ot) gesture::operator_properties(ot); } +void PAINT_OT_hide_show_lasso_gesture(wmOperatorType *ot) +{ + ot->name = "Hide/Show Lasso"; + ot->idname = "PAINT_OT_hide_show_lasso_gesture"; + ot->description = "Hide/show some vertices"; + + ot->invoke = WM_gesture_lasso_invoke; + ot->modal = WM_gesture_lasso_modal; + ot->exec = hide_show_gesture_lasso_exec; + /* Sculpt-only for now. */ + ot->poll = SCULPT_mode_poll_view3d; + + ot->flag = OPTYPE_REGISTER | OPTYPE_DEPENDS_ON_CURSOR; + + WM_operator_properties_gesture_lasso(ot); + hide_show_operator_properties(ot); + hide_show_operator_gesture_properties(ot); + gesture::operator_properties(ot); +} + static void invert_visibility_mesh(Object &object, const Span nodes) { Mesh &mesh = *static_cast(object.data); diff --git a/source/blender/editors/sculpt_paint/paint_intern.hh b/source/blender/editors/sculpt_paint/paint_intern.hh index 489763f2722..04866b09974 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.hh +++ b/source/blender/editors/sculpt_paint/paint_intern.hh @@ -470,6 +470,7 @@ void tag_update_visibility(const bContext &C); void PAINT_OT_hide_show_masked(wmOperatorType *ot); void PAINT_OT_hide_show_all(wmOperatorType *ot); void PAINT_OT_hide_show(wmOperatorType *ot); +void PAINT_OT_hide_show_lasso_gesture(wmOperatorType *ot); void PAINT_OT_visibility_invert(wmOperatorType *ot); } // namespace blender::ed::sculpt_paint::hide diff --git a/source/blender/editors/sculpt_paint/paint_ops.cc b/source/blender/editors/sculpt_paint/paint_ops.cc index ec6cfd67346..98e33d902cb 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.cc +++ b/source/blender/editors/sculpt_paint/paint_ops.cc @@ -1550,6 +1550,7 @@ void ED_operatortypes_paint() WM_operatortype_append(hide::PAINT_OT_hide_show_all); WM_operatortype_append(hide::PAINT_OT_hide_show_masked); WM_operatortype_append(hide::PAINT_OT_hide_show); + WM_operatortype_append(hide::PAINT_OT_hide_show_lasso_gesture); WM_operatortype_append(hide::PAINT_OT_visibility_invert); /* paint masking */ diff --git a/source/blender/editors/sculpt_paint/sculpt_gesture.cc b/source/blender/editors/sculpt_paint/sculpt_gesture.cc index 4f3d8ba4e94..f46328205f2 100644 --- a/source/blender/editors/sculpt_paint/sculpt_gesture.cc +++ b/source/blender/editors/sculpt_paint/sculpt_gesture.cc @@ -338,6 +338,12 @@ static void update_affected_nodes_by_clip_planes(GestureData &gesture_data) case SelectionType::Inside: return BKE_pbvh_node_frustum_contain_AABB(&node, &frustum); case SelectionType::Outside: + /* Certain degenerate cases of a lasso shape can cause the resulting + * frustum planes to enclose a node's AABB, therefore we must submit it + * to be more throughly evaluated. */ + if (gesture_data.shape_type == ShapeType::Lasso) { + return true; + } return BKE_pbvh_node_frustum_exclude_AABB(&node, &frustum); default: BLI_assert_unreachable(); @@ -376,13 +382,21 @@ static bool is_affected_lasso(GestureData &gesture_data, const float co[3]) /* Clip against lasso boundbox. */ LassoData *lasso = &gesture_data.lasso; if (!BLI_rcti_isect_pt(&lasso->boundbox, scr_co_s[0], scr_co_s[1])) { - return false; + return gesture_data.selection_type == SelectionType::Outside; } scr_co_s[0] -= lasso->boundbox.xmin; scr_co_s[1] -= lasso->boundbox.ymin; - return lasso->mask_px[scr_co_s[1] * lasso->width + scr_co_s[0]].test(); + const bool bitmap_result = lasso->mask_px[scr_co_s[1] * lasso->width + scr_co_s[0]].test(); + switch (gesture_data.selection_type) { + case SelectionType::Inside: + return bitmap_result; + case SelectionType::Outside: + return !bitmap_result; + } + BLI_assert_unreachable(); + return false; } bool is_affected(GestureData &gesture_data, const float3 &co, const float3 &vertex_normal) diff --git a/source/blender/windowmanager/intern/wm_operators.cc b/source/blender/windowmanager/intern/wm_operators.cc index 9bcf6d1b17f..d30861ac79d 100644 --- a/source/blender/windowmanager/intern/wm_operators.cc +++ b/source/blender/windowmanager/intern/wm_operators.cc @@ -4213,6 +4213,7 @@ static void gesture_lasso_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_assign(keymap, "GRAPH_OT_select_lasso"); WM_modalkeymap_assign(keymap, "NODE_OT_select_lasso"); WM_modalkeymap_assign(keymap, "UV_OT_select_lasso"); + WM_modalkeymap_assign(keymap, "PAINT_OT_hide_show_lasso_gesture"); } /* Zoom to border modal operators. */