Cleanup: Migrate face set gesture operators

This PR moves the `SCULPT_OT_face_set_lasso_gesture` and
`SCULPT_OT_face_set_box_gesture` operator out of the `paint_mask.cc`
file and `blender::ed::sculpt_paint::mask` namespace to
`sculpt_face_set.cc` and `blender::ed::sculpt_paint::face_set`.

Pull Request: https://projects.blender.org/blender/blender/pulls/119392
This commit is contained in:
Sean Kim 2024-03-12 19:06:14 +01:00 committed by Hans Goudey
parent a56a975760
commit 40dbe99dd9
4 changed files with 216 additions and 213 deletions

@ -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<PBVHNode *> 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<float3> positions = ss.vert_positions;
const OffsetIndices<int> faces = ss.faces;
const Span<int> corner_verts = ss.corner_verts;
const bool *hide_poly = ss.hide_poly;
bke::SpanAttributeWriter<int> 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<int> 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<PBVHNode *> 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<gesture::Operation *>(
MEM_cnew<SculptGestureFaceSetOperation>(__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<gesture::Operation *>(
MEM_cnew<SculptGestureFaceSetOperation>(__func__));
MEM_cnew<SculptGestureProjectOperation>(__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::GestureData> 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::GestureData> 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";

@ -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<PBVHNode *> 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<float3> positions = ss.vert_positions;
const OffsetIndices<int> faces = ss.faces;
const Span<int> corner_verts = ss.corner_verts;
const bool *hide_poly = ss.hide_poly;
bke::SpanAttributeWriter<int> 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<int> 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<PBVHNode *> 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<gesture::Operation *>(
MEM_cnew<SculptGestureFaceSetOperation>(__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::GestureData> 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::GestureData> 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

@ -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);
}
/** \} */

@ -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);