diff --git a/source/blender/editors/sculpt_paint/paint_mask.cc b/source/blender/editors/sculpt_paint/paint_mask.cc index 5d409ca507b..b9fb7e85632 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.cc +++ b/source/blender/editors/sculpt_paint/paint_mask.cc @@ -545,131 +545,6 @@ void PAINT_OT_mask_flood_fill(wmOperatorType *ot) 0.0f, 1.0f); } -/* Face Set Gesture Operation. */ - -struct SculptGestureFaceSetOperation { - gesture::Operation op; - - int new_face_set_id; -}; - -static void sculpt_gesture_face_set_begin(bContext &C, gesture::GestureData &gesture_data) -{ - Depsgraph *depsgraph = CTX_data_depsgraph_pointer(&C); - BKE_sculpt_update_object_for_edit(depsgraph, gesture_data.vc.obact, false); -} - -static void face_set_gesture_apply_mesh(gesture::GestureData &gesture_data, - const Span nodes) -{ - SculptGestureFaceSetOperation *face_set_operation = (SculptGestureFaceSetOperation *) - gesture_data.operation; - const int new_face_set = face_set_operation->new_face_set_id; - Object &object = *gesture_data.vc.obact; - SculptSession &ss = *gesture_data.ss; - const PBVH &pbvh = *gesture_data.ss->pbvh; - - const Span positions = ss.vert_positions; - const OffsetIndices faces = ss.faces; - const Span corner_verts = ss.corner_verts; - const bool *hide_poly = ss.hide_poly; - bke::SpanAttributeWriter face_sets = face_set::ensure_face_sets_mesh(object); - - threading::parallel_for(gesture_data.nodes.index_range(), 1, [&](const IndexRange range) { - for (PBVHNode *node : nodes.slice(range)) { - undo::push_node(gesture_data.vc.obact, node, undo::Type::FaceSet); - - bool any_updated = false; - for (const int face : BKE_pbvh_node_calc_face_indices(pbvh, *node)) { - if (hide_poly && hide_poly[face]) { - continue; - } - const Span face_verts = corner_verts.slice(faces[face]); - const float3 face_center = bke::mesh::face_center_calc(positions, face_verts); - const float3 face_normal = bke::mesh::face_normal_calc(positions, face_verts); - if (!gesture::is_affected(gesture_data, face_center, face_normal)) { - continue; - } - face_sets.span[face] = new_face_set; - any_updated = true; - } - if (any_updated) { - BKE_pbvh_node_mark_update_face_sets(node); - } - } - }); - - face_sets.finish(); -} - -static void face_set_gesture_apply_bmesh(gesture::GestureData &gesture_data, - const Span nodes) -{ - SculptGestureFaceSetOperation *face_set_operation = (SculptGestureFaceSetOperation *) - gesture_data.operation; - const int new_face_set = face_set_operation->new_face_set_id; - SculptSession &ss = *gesture_data.ss; - BMesh *bm = ss.bm; - const int offset = CustomData_get_offset_named(&bm->pdata, CD_PROP_INT32, ".sculpt_face_set"); - - threading::parallel_for(gesture_data.nodes.index_range(), 1, [&](const IndexRange range) { - for (PBVHNode *node : nodes.slice(range)) { - undo::push_node(gesture_data.vc.obact, node, undo::Type::FaceSet); - - bool any_updated = false; - for (BMFace *face : BKE_pbvh_bmesh_node_faces(node)) { - if (BM_elem_flag_test(face, BM_ELEM_HIDDEN)) { - continue; - } - float3 center; - BM_face_calc_center_median(face, center); - if (!gesture::is_affected(gesture_data, center, face->no)) { - continue; - } - BM_ELEM_CD_SET_INT(face, offset, new_face_set); - any_updated = true; - } - - if (any_updated) { - BKE_pbvh_node_mark_update_visibility(node); - } - } - }); -} - -static void sculpt_gesture_face_set_apply_for_symmetry_pass(bContext & /*C*/, - gesture::GestureData &gesture_data) -{ - switch (BKE_pbvh_type(gesture_data.ss->pbvh)) { - case PBVH_GRIDS: - case PBVH_FACES: - face_set_gesture_apply_mesh(gesture_data, gesture_data.nodes); - break; - case PBVH_BMESH: - face_set_gesture_apply_bmesh(gesture_data, gesture_data.nodes); - } -} - -static void sculpt_gesture_face_set_end(bContext & /*C*/, gesture::GestureData & /*gesture_data*/) -{ -} - -static void sculpt_gesture_init_face_set_properties(gesture::GestureData &gesture_data, - wmOperator & /*op*/) -{ - Object &object = *gesture_data.vc.obact; - gesture_data.operation = reinterpret_cast( - MEM_cnew(__func__)); - - SculptGestureFaceSetOperation *face_set_operation = (SculptGestureFaceSetOperation *) - gesture_data.operation; - - face_set_operation->op.begin = sculpt_gesture_face_set_begin; - face_set_operation->op.apply_for_symmetry_pass = sculpt_gesture_face_set_apply_for_symmetry_pass; - face_set_operation->op.end = sculpt_gesture_face_set_end; - - face_set_operation->new_face_set_id = face_set::find_next_available_id(object); -} /* Mask Gesture Operation. */ @@ -872,7 +747,7 @@ static void sculpt_gesture_init_project_properties(gesture::GestureData &gesture wmOperator & /*op*/) { gesture_data.operation = reinterpret_cast( - MEM_cnew(__func__)); + MEM_cnew(__func__)); SculptGestureProjectOperation *project_operation = (SculptGestureProjectOperation *) gesture_data.operation; @@ -916,50 +791,6 @@ static int paint_mask_gesture_line_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int face_set_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event) -{ - const View3D *v3d = CTX_wm_view3d(C); - const Base *base = CTX_data_active_base(C); - if (!BKE_base_is_visible(v3d, base)) { - return OPERATOR_CANCELLED; - } - - return WM_gesture_box_invoke(C, op, event); -} - -static int face_set_gesture_box_exec(bContext *C, wmOperator *op) -{ - std::unique_ptr gesture_data = gesture::init_from_box(C, op); - if (!gesture_data) { - return OPERATOR_CANCELLED; - } - sculpt_gesture_init_face_set_properties(*gesture_data, *op); - gesture::apply(*C, *gesture_data, *op); - return OPERATOR_FINISHED; -} - -static int face_set_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event) -{ - const View3D *v3d = CTX_wm_view3d(C); - const Base *base = CTX_data_active_base(C); - if (!BKE_base_is_visible(v3d, base)) { - return OPERATOR_CANCELLED; - } - - return WM_gesture_lasso_invoke(C, op, event); -} - -static int face_set_gesture_lasso_exec(bContext *C, wmOperator *op) -{ - std::unique_ptr gesture_data = gesture::init_from_lasso(C, op); - if (!gesture_data) { - return OPERATOR_CANCELLED; - } - sculpt_gesture_init_face_set_properties(*gesture_data, *op); - gesture::apply(*C, *gesture_data, *op); - return OPERATOR_FINISHED; -} - static int project_line_gesture_invoke(bContext *C, wmOperator *op, const wmEvent *event) { const View3D *v3d = CTX_wm_view3d(C); @@ -1045,44 +876,6 @@ void PAINT_OT_mask_line_gesture(wmOperatorType *ot) paint_mask_gesture_operator_properties(ot); } -void SCULPT_OT_face_set_lasso_gesture(wmOperatorType *ot) -{ - ot->name = "Face Set Lasso Gesture"; - ot->idname = "SCULPT_OT_face_set_lasso_gesture"; - ot->description = "Add face set within the lasso as you move the brush"; - - ot->invoke = face_set_gesture_lasso_invoke; - ot->modal = WM_gesture_lasso_modal; - ot->exec = face_set_gesture_lasso_exec; - - ot->poll = SCULPT_mode_poll_view3d; - - ot->flag = OPTYPE_DEPENDS_ON_CURSOR; - - /* Properties. */ - WM_operator_properties_gesture_lasso(ot); - gesture::operator_properties(ot); -} - -void SCULPT_OT_face_set_box_gesture(wmOperatorType *ot) -{ - ot->name = "Face Set Box Gesture"; - ot->idname = "SCULPT_OT_face_set_box_gesture"; - ot->description = "Add face set within the box as you move the brush"; - - ot->invoke = face_set_gesture_box_invoke; - ot->modal = WM_gesture_box_modal; - ot->exec = face_set_gesture_box_exec; - - ot->poll = SCULPT_mode_poll_view3d; - - ot->flag = OPTYPE_REGISTER; - - /* Properties. */ - WM_operator_properties_border(ot); - gesture::operator_properties(ot); -} - void SCULPT_OT_project_line_gesture(wmOperatorType *ot) { ot->name = "Project Line Gesture"; diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.cc b/source/blender/editors/sculpt_paint/sculpt_face_set.cc index 779b384b11e..0ad41b066df 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.cc +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.cc @@ -1652,4 +1652,215 @@ void SCULPT_OT_face_sets_edit(wmOperatorType *ot) "Apply the edit operation to hidden geometry"); } +/* -------------------------------------------------------------------- */ +/** \name Gesture Operators + * \{ */ + +struct SculptGestureFaceSetOperation { + gesture::Operation op; + + int new_face_set_id; +}; + +static void sculpt_gesture_face_set_begin(bContext &C, gesture::GestureData &gesture_data) +{ + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(&C); + BKE_sculpt_update_object_for_edit(depsgraph, gesture_data.vc.obact, false); +} + +static void face_set_gesture_apply_mesh(gesture::GestureData &gesture_data, + const Span nodes) +{ + SculptGestureFaceSetOperation *face_set_operation = (SculptGestureFaceSetOperation *) + gesture_data.operation; + const int new_face_set = face_set_operation->new_face_set_id; + Object &object = *gesture_data.vc.obact; + SculptSession &ss = *gesture_data.ss; + const PBVH &pbvh = *gesture_data.ss->pbvh; + + const Span positions = ss.vert_positions; + const OffsetIndices faces = ss.faces; + const Span corner_verts = ss.corner_verts; + const bool *hide_poly = ss.hide_poly; + bke::SpanAttributeWriter face_sets = face_set::ensure_face_sets_mesh(object); + + threading::parallel_for(gesture_data.nodes.index_range(), 1, [&](const IndexRange range) { + for (PBVHNode *node : nodes.slice(range)) { + undo::push_node(gesture_data.vc.obact, node, undo::Type::FaceSet); + + bool any_updated = false; + for (const int face : BKE_pbvh_node_calc_face_indices(pbvh, *node)) { + if (hide_poly && hide_poly[face]) { + continue; + } + const Span face_verts = corner_verts.slice(faces[face]); + const float3 face_center = bke::mesh::face_center_calc(positions, face_verts); + const float3 face_normal = bke::mesh::face_normal_calc(positions, face_verts); + if (!gesture::is_affected(gesture_data, face_center, face_normal)) { + continue; + } + face_sets.span[face] = new_face_set; + any_updated = true; + } + if (any_updated) { + BKE_pbvh_node_mark_update_face_sets(node); + } + } + }); + + face_sets.finish(); +} + +static void face_set_gesture_apply_bmesh(gesture::GestureData &gesture_data, + const Span nodes) +{ + SculptGestureFaceSetOperation *face_set_operation = (SculptGestureFaceSetOperation *) + gesture_data.operation; + const int new_face_set = face_set_operation->new_face_set_id; + SculptSession &ss = *gesture_data.ss; + BMesh *bm = ss.bm; + const int offset = CustomData_get_offset_named(&bm->pdata, CD_PROP_INT32, ".sculpt_face_set"); + + threading::parallel_for(gesture_data.nodes.index_range(), 1, [&](const IndexRange range) { + for (PBVHNode *node : nodes.slice(range)) { + undo::push_node(gesture_data.vc.obact, node, undo::Type::FaceSet); + + bool any_updated = false; + for (BMFace *face : BKE_pbvh_bmesh_node_faces(node)) { + if (BM_elem_flag_test(face, BM_ELEM_HIDDEN)) { + continue; + } + float3 center; + BM_face_calc_center_median(face, center); + if (!gesture::is_affected(gesture_data, center, face->no)) { + continue; + } + BM_ELEM_CD_SET_INT(face, offset, new_face_set); + any_updated = true; + } + + if (any_updated) { + BKE_pbvh_node_mark_update_visibility(node); + } + } + }); +} + +static void sculpt_gesture_face_set_apply_for_symmetry_pass(bContext & /*C*/, + gesture::GestureData &gesture_data) +{ + switch (BKE_pbvh_type(gesture_data.ss->pbvh)) { + case PBVH_GRIDS: + case PBVH_FACES: + face_set_gesture_apply_mesh(gesture_data, gesture_data.nodes); + break; + case PBVH_BMESH: + face_set_gesture_apply_bmesh(gesture_data, gesture_data.nodes); + } +} + +static void sculpt_gesture_face_set_end(bContext & /*C*/, gesture::GestureData & /*gesture_data*/) +{ +} + +static void sculpt_gesture_init_face_set_properties(gesture::GestureData &gesture_data, + wmOperator & /*op*/) +{ + Object &object = *gesture_data.vc.obact; + gesture_data.operation = reinterpret_cast( + MEM_cnew(__func__)); + + SculptGestureFaceSetOperation *face_set_operation = (SculptGestureFaceSetOperation *) + gesture_data.operation; + + face_set_operation->op.begin = sculpt_gesture_face_set_begin; + face_set_operation->op.apply_for_symmetry_pass = sculpt_gesture_face_set_apply_for_symmetry_pass; + face_set_operation->op.end = sculpt_gesture_face_set_end; + + face_set_operation->new_face_set_id = face_set::find_next_available_id(object); +} + +static int face_set_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + const View3D *v3d = CTX_wm_view3d(C); + const Base *base = CTX_data_active_base(C); + if (!BKE_base_is_visible(v3d, base)) { + return OPERATOR_CANCELLED; + } + + return WM_gesture_box_invoke(C, op, event); +} + +static int face_set_gesture_box_exec(bContext *C, wmOperator *op) +{ + std::unique_ptr gesture_data = gesture::init_from_box(C, op); + if (!gesture_data) { + return OPERATOR_CANCELLED; + } + sculpt_gesture_init_face_set_properties(*gesture_data, *op); + gesture::apply(*C, *gesture_data, *op); + return OPERATOR_FINISHED; +} + +static int face_set_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + const View3D *v3d = CTX_wm_view3d(C); + const Base *base = CTX_data_active_base(C); + if (!BKE_base_is_visible(v3d, base)) { + return OPERATOR_CANCELLED; + } + + return WM_gesture_lasso_invoke(C, op, event); +} + +static int face_set_gesture_lasso_exec(bContext *C, wmOperator *op) +{ + std::unique_ptr gesture_data = gesture::init_from_lasso(C, op); + if (!gesture_data) { + return OPERATOR_CANCELLED; + } + sculpt_gesture_init_face_set_properties(*gesture_data, *op); + gesture::apply(*C, *gesture_data, *op); + return OPERATOR_FINISHED; +} + +void SCULPT_OT_face_set_lasso_gesture(wmOperatorType *ot) +{ + ot->name = "Face Set Lasso Gesture"; + ot->idname = "SCULPT_OT_face_set_lasso_gesture"; + ot->description = "Add face set within the lasso as you move the brush"; + + ot->invoke = face_set_gesture_lasso_invoke; + ot->modal = WM_gesture_lasso_modal; + ot->exec = face_set_gesture_lasso_exec; + + ot->poll = SCULPT_mode_poll_view3d; + + ot->flag = OPTYPE_DEPENDS_ON_CURSOR; + + /* Properties. */ + WM_operator_properties_gesture_lasso(ot); + gesture::operator_properties(ot); +} + +void SCULPT_OT_face_set_box_gesture(wmOperatorType *ot) +{ + ot->name = "Face Set Box Gesture"; + ot->idname = "SCULPT_OT_face_set_box_gesture"; + ot->description = "Add face set within the box as you move the brush"; + + ot->invoke = face_set_gesture_box_invoke; + ot->modal = WM_gesture_box_modal; + ot->exec = face_set_gesture_box_exec; + + ot->poll = SCULPT_mode_poll_view3d; + + ot->flag = OPTYPE_REGISTER; + + /* Properties. */ + WM_operator_properties_border(ot); + gesture::operator_properties(ot); +} +/** \} */ + } // namespace blender::ed::sculpt_paint::face_set diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.hh b/source/blender/editors/sculpt_paint/sculpt_intern.hh index 38811fc3dfd..8495ef793f4 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.hh +++ b/source/blender/editors/sculpt_paint/sculpt_intern.hh @@ -1783,9 +1783,6 @@ void apply(bContext &C, GestureData &gesture_data, wmOperator &op); namespace blender::ed::sculpt_paint::mask { -void SCULPT_OT_face_set_lasso_gesture(wmOperatorType *ot); -void SCULPT_OT_face_set_box_gesture(wmOperatorType *ot); - void SCULPT_OT_project_line_gesture(wmOperatorType *ot); } @@ -1809,6 +1806,8 @@ void SCULPT_OT_face_sets_init(wmOperatorType *ot); void SCULPT_OT_face_sets_create(wmOperatorType *ot); void SCULPT_OT_face_sets_edit(wmOperatorType *ot); +void SCULPT_OT_face_set_lasso_gesture(wmOperatorType *ot); +void SCULPT_OT_face_set_box_gesture(wmOperatorType *ot); } /** \} */ diff --git a/source/blender/editors/sculpt_paint/sculpt_ops.cc b/source/blender/editors/sculpt_paint/sculpt_ops.cc index 7f385794759..f15e71b0920 100644 --- a/source/blender/editors/sculpt_paint/sculpt_ops.cc +++ b/source/blender/editors/sculpt_paint/sculpt_ops.cc @@ -1315,8 +1315,8 @@ void ED_operatortypes_sculpt() WM_operatortype_append(face_set::SCULPT_OT_face_sets_init); WM_operatortype_append(face_set::SCULPT_OT_face_sets_edit); WM_operatortype_append(cloth::SCULPT_OT_cloth_filter); - WM_operatortype_append(mask::SCULPT_OT_face_set_lasso_gesture); - WM_operatortype_append(mask::SCULPT_OT_face_set_box_gesture); + WM_operatortype_append(face_set::SCULPT_OT_face_set_lasso_gesture); + WM_operatortype_append(face_set::SCULPT_OT_face_set_box_gesture); WM_operatortype_append(trim::SCULPT_OT_trim_box_gesture); WM_operatortype_append(trim::SCULPT_OT_trim_lasso_gesture); WM_operatortype_append(mask::SCULPT_OT_project_line_gesture);