Cleanup: Extract project gesture to separate file
This PR extracts the `SCULPT_OT_project_line_gesture` operator into its own file and namespace out of the `paint_mask.cc` file and `blender::ed::sculpt_paint::mask` namespace. Pull Request: https://projects.blender.org/blender/blender/pulls/119394
This commit is contained in:
@@ -83,6 +83,7 @@ set(SRC
|
||||
sculpt_paint_color.cc
|
||||
sculpt_paint_image.cc
|
||||
sculpt_pose.cc
|
||||
sculpt_project.cc
|
||||
sculpt_smooth.cc
|
||||
sculpt_transform.cc
|
||||
sculpt_trim.cc
|
||||
|
||||
@@ -664,100 +664,6 @@ static void paint_mask_gesture_operator_properties(wmOperatorType *ot)
|
||||
1.0f);
|
||||
}
|
||||
|
||||
/* Project Gesture Operation. */
|
||||
|
||||
struct SculptGestureProjectOperation {
|
||||
gesture::Operation operation;
|
||||
};
|
||||
|
||||
static void sculpt_gesture_project_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 project_line_gesture_apply_task(gesture::GestureData &gesture_data, PBVHNode *node)
|
||||
{
|
||||
PBVHVertexIter vd;
|
||||
bool any_updated = false;
|
||||
|
||||
undo::push_node(gesture_data.vc.obact, node, undo::Type::Position);
|
||||
|
||||
BKE_pbvh_vertex_iter_begin (gesture_data.ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
|
||||
float vertex_normal[3];
|
||||
const float *co = SCULPT_vertex_co_get(gesture_data.ss, vd.vertex);
|
||||
SCULPT_vertex_normal_get(gesture_data.ss, vd.vertex, vertex_normal);
|
||||
|
||||
if (!gesture::is_affected(gesture_data, co, vertex_normal)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float projected_pos[3];
|
||||
closest_to_plane_v3(projected_pos, gesture_data.line.plane, vd.co);
|
||||
|
||||
float disp[3];
|
||||
sub_v3_v3v3(disp, projected_pos, vd.co);
|
||||
const float mask = vd.mask;
|
||||
mul_v3_fl(disp, 1.0f - mask);
|
||||
if (is_zero_v3(disp)) {
|
||||
continue;
|
||||
}
|
||||
add_v3_v3(vd.co, disp);
|
||||
any_updated = true;
|
||||
}
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
|
||||
if (any_updated) {
|
||||
BKE_pbvh_node_mark_update(node);
|
||||
}
|
||||
}
|
||||
|
||||
static void sculpt_gesture_project_apply_for_symmetry_pass(bContext & /*C*/,
|
||||
gesture::GestureData &gesture_data)
|
||||
{
|
||||
switch (gesture_data.shape_type) {
|
||||
case gesture::ShapeType::Line:
|
||||
threading::parallel_for(gesture_data.nodes.index_range(), 1, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
project_line_gesture_apply_task(gesture_data, gesture_data.nodes[i]);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case gesture::ShapeType::Lasso:
|
||||
case gesture::ShapeType::Box:
|
||||
/* Gesture shape projection not implemented yet. */
|
||||
BLI_assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void sculpt_gesture_project_end(bContext &C, gesture::GestureData &gesture_data)
|
||||
{
|
||||
SculptSession *ss = gesture_data.ss;
|
||||
Sculpt *sd = CTX_data_tool_settings(&C)->sculpt;
|
||||
if (ss->deform_modifiers_active || ss->shapekey_active) {
|
||||
SCULPT_flush_stroke_deform(sd, gesture_data.vc.obact, true);
|
||||
}
|
||||
|
||||
SCULPT_flush_update_step(&C, SCULPT_UPDATE_COORDS);
|
||||
SCULPT_flush_update_done(&C, gesture_data.vc.obact, SCULPT_UPDATE_COORDS);
|
||||
}
|
||||
|
||||
static void sculpt_gesture_init_project_properties(gesture::GestureData &gesture_data,
|
||||
wmOperator & /*op*/)
|
||||
{
|
||||
gesture_data.operation = reinterpret_cast<gesture::Operation *>(
|
||||
MEM_cnew<SculptGestureProjectOperation>(__func__));
|
||||
|
||||
SculptGestureProjectOperation *project_operation = (SculptGestureProjectOperation *)
|
||||
gesture_data.operation;
|
||||
|
||||
project_operation->operation.begin = sculpt_gesture_project_begin;
|
||||
project_operation->operation.apply_for_symmetry_pass =
|
||||
sculpt_gesture_project_apply_for_symmetry_pass;
|
||||
project_operation->operation.end = sculpt_gesture_project_end;
|
||||
}
|
||||
|
||||
static int paint_mask_gesture_box_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
std::unique_ptr<gesture::GestureData> gesture_data = gesture::init_from_box(C, op);
|
||||
@@ -791,28 +697,6 @@ static int paint_mask_gesture_line_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int project_line_gesture_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_straightline_active_side_invoke(C, op, event);
|
||||
}
|
||||
|
||||
static int project_gesture_line_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
std::unique_ptr<gesture::GestureData> gesture_data = gesture::init_from_line(C, op);
|
||||
if (!gesture_data) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
sculpt_gesture_init_project_properties(*gesture_data, *op);
|
||||
gesture::apply(*C, *gesture_data, *op);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void PAINT_OT_mask_lasso_gesture(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Mask Lasso Gesture";
|
||||
@@ -876,23 +760,4 @@ void PAINT_OT_mask_line_gesture(wmOperatorType *ot)
|
||||
paint_mask_gesture_operator_properties(ot);
|
||||
}
|
||||
|
||||
void SCULPT_OT_project_line_gesture(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Project Line Gesture";
|
||||
ot->idname = "SCULPT_OT_project_line_gesture";
|
||||
ot->description = "Project the geometry onto a plane defined by a line";
|
||||
|
||||
ot->invoke = project_line_gesture_invoke;
|
||||
ot->modal = WM_gesture_straightline_oneshot_modal;
|
||||
ot->exec = project_gesture_line_exec;
|
||||
|
||||
ot->poll = SCULPT_mode_poll_view3d;
|
||||
|
||||
ot->flag = OPTYPE_REGISTER;
|
||||
|
||||
/* Properties. */
|
||||
WM_operator_properties_gesture_straightline(ot, WM_CURSOR_EDIT);
|
||||
gesture::operator_properties(ot);
|
||||
}
|
||||
|
||||
} // namespace blender::ed::sculpt_paint::mask
|
||||
|
||||
@@ -1781,10 +1781,8 @@ void apply(bContext &C, GestureData &gesture_data, wmOperator &op);
|
||||
|
||||
}
|
||||
|
||||
namespace blender::ed::sculpt_paint::mask {
|
||||
|
||||
namespace blender::ed::sculpt_paint::project {
|
||||
void SCULPT_OT_project_line_gesture(wmOperatorType *ot);
|
||||
|
||||
}
|
||||
|
||||
namespace blender::ed::sculpt_paint::trim {
|
||||
|
||||
@@ -1319,7 +1319,7 @@ void ED_operatortypes_sculpt()
|
||||
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);
|
||||
WM_operatortype_append(project::SCULPT_OT_project_line_gesture);
|
||||
|
||||
WM_operatortype_append(SCULPT_OT_sample_color);
|
||||
WM_operatortype_append(color::SCULPT_OT_color_filter);
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup edsculpt
|
||||
*/
|
||||
|
||||
#include "BLI_math_geom.h"
|
||||
#include "BLI_math_matrix.h"
|
||||
#include "BLI_math_vector.h"
|
||||
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_layer.hh"
|
||||
|
||||
#include "WM_api.hh"
|
||||
#include "WM_types.hh"
|
||||
|
||||
#include "sculpt_intern.hh"
|
||||
|
||||
namespace blender::ed::sculpt_paint::project {
|
||||
|
||||
struct SculptGestureProjectOperation {
|
||||
gesture::Operation operation;
|
||||
};
|
||||
|
||||
static void sculpt_gesture_project_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 project_line_gesture_apply_task(gesture::GestureData &gesture_data, PBVHNode *node)
|
||||
{
|
||||
PBVHVertexIter vd;
|
||||
bool any_updated = false;
|
||||
|
||||
undo::push_node(gesture_data.vc.obact, node, undo::Type::Position);
|
||||
|
||||
BKE_pbvh_vertex_iter_begin (gesture_data.ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
|
||||
float vertex_normal[3];
|
||||
const float *co = SCULPT_vertex_co_get(gesture_data.ss, vd.vertex);
|
||||
SCULPT_vertex_normal_get(gesture_data.ss, vd.vertex, vertex_normal);
|
||||
|
||||
if (!gesture::is_affected(gesture_data, co, vertex_normal)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float projected_pos[3];
|
||||
closest_to_plane_v3(projected_pos, gesture_data.line.plane, vd.co);
|
||||
|
||||
float disp[3];
|
||||
sub_v3_v3v3(disp, projected_pos, vd.co);
|
||||
const float mask = vd.mask;
|
||||
mul_v3_fl(disp, 1.0f - mask);
|
||||
if (is_zero_v3(disp)) {
|
||||
continue;
|
||||
}
|
||||
add_v3_v3(vd.co, disp);
|
||||
any_updated = true;
|
||||
}
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
|
||||
if (any_updated) {
|
||||
BKE_pbvh_node_mark_update(node);
|
||||
}
|
||||
}
|
||||
|
||||
static void sculpt_gesture_project_apply_for_symmetry_pass(bContext & /*C*/,
|
||||
gesture::GestureData &gesture_data)
|
||||
{
|
||||
switch (gesture_data.shape_type) {
|
||||
case gesture::ShapeType::Line:
|
||||
threading::parallel_for(gesture_data.nodes.index_range(), 1, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
project_line_gesture_apply_task(gesture_data, gesture_data.nodes[i]);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case gesture::ShapeType::Lasso:
|
||||
case gesture::ShapeType::Box:
|
||||
/* Gesture shape projection not implemented yet. */
|
||||
BLI_assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void sculpt_gesture_project_end(bContext &C, gesture::GestureData &gesture_data)
|
||||
{
|
||||
SculptSession *ss = gesture_data.ss;
|
||||
Sculpt *sd = CTX_data_tool_settings(&C)->sculpt;
|
||||
if (ss->deform_modifiers_active || ss->shapekey_active) {
|
||||
SCULPT_flush_stroke_deform(sd, gesture_data.vc.obact, true);
|
||||
}
|
||||
|
||||
SCULPT_flush_update_step(&C, SCULPT_UPDATE_COORDS);
|
||||
SCULPT_flush_update_done(&C, gesture_data.vc.obact, SCULPT_UPDATE_COORDS);
|
||||
}
|
||||
|
||||
static void sculpt_gesture_init_project_properties(gesture::GestureData &gesture_data,
|
||||
wmOperator & /*op*/)
|
||||
{
|
||||
gesture_data.operation = reinterpret_cast<gesture::Operation *>(
|
||||
MEM_cnew<SculptGestureProjectOperation>(__func__));
|
||||
|
||||
SculptGestureProjectOperation *project_operation = (SculptGestureProjectOperation *)
|
||||
gesture_data.operation;
|
||||
|
||||
project_operation->operation.begin = sculpt_gesture_project_begin;
|
||||
project_operation->operation.apply_for_symmetry_pass =
|
||||
sculpt_gesture_project_apply_for_symmetry_pass;
|
||||
project_operation->operation.end = sculpt_gesture_project_end;
|
||||
}
|
||||
|
||||
static int project_line_gesture_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_straightline_active_side_invoke(C, op, event);
|
||||
}
|
||||
|
||||
static int project_gesture_line_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
std::unique_ptr<gesture::GestureData> gesture_data = gesture::init_from_line(C, op);
|
||||
if (!gesture_data) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
sculpt_gesture_init_project_properties(*gesture_data, *op);
|
||||
gesture::apply(*C, *gesture_data, *op);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
void SCULPT_OT_project_line_gesture(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Project Line Gesture";
|
||||
ot->idname = "SCULPT_OT_project_line_gesture";
|
||||
ot->description = "Project the geometry onto a plane defined by a line";
|
||||
|
||||
ot->invoke = project_line_gesture_invoke;
|
||||
ot->modal = WM_gesture_straightline_oneshot_modal;
|
||||
ot->exec = project_gesture_line_exec;
|
||||
|
||||
ot->poll = SCULPT_mode_poll_view3d;
|
||||
|
||||
ot->flag = OPTYPE_REGISTER;
|
||||
|
||||
/* Properties. */
|
||||
WM_operator_properties_gesture_straightline(ot, WM_CURSOR_EDIT);
|
||||
gesture::operator_properties(ot);
|
||||
}
|
||||
} // namespace blender::ed::sculpt_paint::project
|
||||
Reference in New Issue
Block a user