Blender V5.0
sculpt_project.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
10
11#include "BKE_context.hh"
12#include "BKE_layer.hh"
13#include "BKE_mesh.hh"
14#include "BKE_subdiv_ccg.hh"
15
16#include "WM_api.hh"
17#include "WM_types.hh"
18
19#include "mesh_brush_common.hh"
20#include "sculpt_automask.hh"
21#include "sculpt_gesture.hh"
22#include "sculpt_intern.hh"
23#include "sculpt_undo.hh"
24
26
30
31static void gesture_begin(bContext &C, wmOperator &op, gesture::GestureData &gesture_data)
32{
33 const Scene &scene = *CTX_data_scene(&C);
36 undo::push_begin(scene, *gesture_data.vc.obact, &op);
37}
38
46
47static void apply_projection_mesh(const Sculpt &sd,
48 const gesture::GestureData &gesture_data,
49 const Span<float3> vert_normals,
50 const MeshAttributeData &attribute_data,
51 const bke::pbvh::MeshNode &node,
52 Object &object,
53 LocalData &tls,
54 const PositionDeformData &position_data)
55{
56 SculptSession &ss = *object.sculpt;
57
58 const Span<int> verts = node.verts();
59 const MutableSpan positions = gather_data_mesh(position_data.eval, verts, tls.positions);
60 const MutableSpan normals = gather_data_mesh(vert_normals, verts, tls.normals);
61
62 tls.factors.resize(verts.size());
63 const MutableSpan<float> factors = tls.factors;
64 fill_factor_from_hide_and_mask(attribute_data.hide_vert, attribute_data.mask, verts, factors);
65
66 gesture::filter_factors(gesture_data, positions, normals, factors);
67
68 tls.translations.resize(verts.size());
69 const MutableSpan<float3> translations = tls.translations;
70 calc_translations_to_plane(positions, gesture_data.line.plane, translations);
71 scale_translations(translations, factors);
72
73 clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
74 position_data.deform(translations, verts);
75}
76
77static void apply_projection_grids(const Sculpt &sd,
78 const gesture::GestureData &gesture_data,
79 const bke::pbvh::GridsNode &node,
80 Object &object,
81 LocalData &tls)
82{
83 SculptSession &ss = *object.sculpt;
84
85 SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
86
87 const Span<int> grids = node.grids();
88 const MutableSpan positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
89
90 tls.normals.resize(positions.size());
92 gather_grids_normals(subdiv_ccg, grids, normals);
93
94 tls.factors.resize(positions.size());
95 const MutableSpan<float> factors = tls.factors;
96 fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
97
98 gesture::filter_factors(gesture_data, positions, normals, factors);
99
100 tls.translations.resize(positions.size());
101 const MutableSpan<float3> translations = tls.translations;
102 calc_translations_to_plane(positions, gesture_data.line.plane, translations);
103 scale_translations(translations, factors);
104
105 clip_and_lock_translations(sd, ss, positions, translations);
106 apply_translations(translations, grids, subdiv_ccg);
107}
108
109static void apply_projection_bmesh(const Sculpt &sd,
110 const gesture::GestureData &gesture_data,
112 Object &object,
113 LocalData &tls)
114{
115 const SculptSession &ss = *object.sculpt;
116
118 const MutableSpan positions = gather_bmesh_positions(verts, tls.positions);
119
120 tls.normals.resize(verts.size());
123
124 tls.factors.resize(verts.size());
125 const MutableSpan<float> factors = tls.factors;
127
128 gesture::filter_factors(gesture_data, positions, normals, factors);
129
130 tls.translations.resize(verts.size());
131 const MutableSpan<float3> translations = tls.translations;
132 calc_translations_to_plane(positions, gesture_data.line.plane, translations);
133 scale_translations(translations, factors);
134
135 clip_and_lock_translations(sd, ss, positions, translations);
136 apply_translations(translations, verts);
137}
138
140{
141 const Depsgraph &depsgraph = *CTX_data_depsgraph_pointer(&C);
142 Object &object = *gesture_data.vc.obact;
143 bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
144 const Sculpt &sd = *CTX_data_tool_settings(&C)->sculpt;
145 const IndexMask &node_mask = gesture_data.node_mask;
146
148 switch (gesture_data.shape_type) {
150 switch (pbvh.type()) {
152 Mesh &mesh = *static_cast<Mesh *>(object.data);
154 const PositionDeformData position_data(depsgraph, object);
155 const MeshAttributeData attribute_data(mesh);
156 const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
158 node_mask.foreach_index(GrainSize(1), [&](const int i) {
159 LocalData &tls = all_tls.local();
161 gesture_data,
162 vert_normals,
163 attribute_data,
164 nodes[i],
165 object,
166 tls,
167 position_data);
168 bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
169 });
170 break;
171 }
173 SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
174 MutableSpan<float3> positions = subdiv_ccg.positions;
177 node_mask.foreach_index(GrainSize(1), [&](const int i) {
178 LocalData &tls = all_tls.local();
179 apply_projection_grids(sd, gesture_data, nodes[i], object, tls);
180 bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
181 });
182 break;
183 }
187 node_mask.foreach_index(GrainSize(1), [&](const int i) {
188 LocalData &tls = all_tls.local();
189 apply_projection_bmesh(sd, gesture_data, nodes[i], object, tls);
191 });
192 break;
193 }
194 }
195 break;
198 /* Gesture shape projection not implemented yet. */
200 break;
201 }
202 pbvh.tag_positions_changed(node_mask);
204}
205
206static void gesture_end(bContext &C, gesture::GestureData &gesture_data)
207{
210 undo::push_end(*gesture_data.vc.obact);
211}
212
213static void init_operation(gesture::GestureData &gesture_data, wmOperator & /*op*/)
214{
215 gesture_data.operation = reinterpret_cast<gesture::Operation *>(
217
218 ProjectOperation *project_operation = (ProjectOperation *)gesture_data.operation;
219
220 project_operation->operation.begin = gesture_begin;
222 project_operation->operation.end = gesture_end;
223}
224
226{
227 const View3D *v3d = CTX_wm_view3d(C);
228 const Base *base = CTX_data_active_base(C);
229 if (!BKE_base_is_visible(v3d, base)) {
230 return OPERATOR_CANCELLED;
231 }
232
234}
235
237{
238 std::unique_ptr<gesture::GestureData> gesture_data = gesture::init_from_line(C, op);
239 if (!gesture_data) {
240 return OPERATOR_CANCELLED;
241 }
242 init_operation(*gesture_data, *op);
243 gesture::apply(*C, *gesture_data, *op);
244 return OPERATOR_FINISHED;
245}
246
248{
249 ot->name = "Project Line Gesture";
250 ot->idname = "SCULPT_OT_project_line_gesture";
251 ot->description = "Project the geometry onto a plane defined by a line";
252
253 ot->invoke = gesture_line_invoke;
255 ot->exec = gesture_line_exec;
256
258
259 ot->flag = OPTYPE_REGISTER;
260
263}
264
265} // namespace blender::ed::sculpt_paint::project
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Base * CTX_data_active_base(const bContext *C)
ToolSettings * CTX_data_tool_settings(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
bool BKE_base_is_visible(const View3D *v3d, const Base *base)
void BKE_sculpt_update_object_for_edit(Depsgraph *depsgraph, Object *ob_orig, bool is_paint_tool)
Definition paint.cc:2797
const blender::Set< BMVert *, 0 > & BKE_pbvh_bmesh_node_unique_verts(blender::bke::pbvh::BMeshNode *node)
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
#define C
Definition RandGen.cpp:29
@ OPTYPE_REGISTER
Definition WM_types.hh:180
BPy_StructRNA * depsgraph
void resize(const int64_t new_size)
constexpr int64_t size() const
Definition BLI_span.hh:493
void tag_positions_changed(const IndexMask &node_mask)
Definition pbvh.cc:635
Span< NodeT > nodes() const
void flush_bounds_to_parents()
Definition pbvh.cc:1306
void foreach_index(Fn &&fn) const
static float verts[][3]
static float normals[][3]
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
pbvh::Tree * pbvh_get(Object &object)
Definition paint.cc:3052
void update_node_bounds_bmesh(BMeshNode &node)
Definition pbvh.cc:1294
void update_node_bounds_mesh(Span< float3 > positions, MeshNode &node)
Definition pbvh.cc:1274
Span< float3 > vert_normals_eval(const Depsgraph &depsgraph, const Object &object_orig)
Definition pbvh.cc:1059
void update_node_bounds_grids(int grid_area, Span< float3 > positions, GridsNode &node)
Definition pbvh.cc:1283
void operator_properties(wmOperatorType *ot, ShapeType shapeType)
std::unique_ptr< GestureData > init_from_line(bContext *C, const wmOperator *op)
void filter_factors(const GestureData &gesture_data, const Span< float3 > positions, const Span< float3 > normals, const MutableSpan< float > factors)
void apply(bContext &C, GestureData &gesture_data, wmOperator &op)
static void gesture_apply_for_symmetry_pass(bContext &C, gesture::GestureData &gesture_data)
static wmOperatorStatus gesture_line_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void init_operation(gesture::GestureData &gesture_data, wmOperator &)
static void apply_projection_grids(const Sculpt &sd, const gesture::GestureData &gesture_data, const bke::pbvh::GridsNode &node, Object &object, LocalData &tls)
static wmOperatorStatus gesture_line_exec(bContext *C, wmOperator *op)
static void apply_projection_bmesh(const Sculpt &sd, const gesture::GestureData &gesture_data, bke::pbvh::BMeshNode &node, Object &object, LocalData &tls)
static void gesture_end(bContext &C, gesture::GestureData &gesture_data)
void SCULPT_OT_project_line_gesture(wmOperatorType *ot)
static void gesture_begin(bContext &C, wmOperator &op, gesture::GestureData &gesture_data)
static void apply_projection_mesh(const Sculpt &sd, const gesture::GestureData &gesture_data, const Span< float3 > vert_normals, const MeshAttributeData &attribute_data, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, const PositionDeformData &position_data)
void push_nodes(const Depsgraph &depsgraph, Object &object, const IndexMask &node_mask, const Type type)
void push_begin(const Scene &scene, Object &ob, const wmOperator *op)
void fill_factor_from_hide_and_mask(Span< bool > hide_vert, Span< float > mask, Span< int > verts, MutableSpan< float > r_factors)
Definition sculpt.cc:6823
MutableSpan< float3 > gather_grids_positions(const SubdivCCG &subdiv_ccg, const Span< int > grids, Vector< float3 > &positions)
void gather_bmesh_positions(const Set< BMVert *, 0 > &verts, MutableSpan< float3 > positions)
Definition sculpt.cc:6367
void gather_bmesh_normals(const Set< BMVert *, 0 > &verts, MutableSpan< float3 > normals)
Definition sculpt.cc:6385
void scale_translations(MutableSpan< float3 > translations, Span< float > factors)
Definition sculpt.cc:7495
void calc_translations_to_plane(Span< float3 > vert_positions, Span< int > verts, const float4 &plane, MutableSpan< float3 > translations)
Definition sculpt.cc:7824
void clip_and_lock_translations(const Sculpt &sd, const SculptSession &ss, Span< float3 > positions, Span< int > verts, MutableSpan< float3 > translations)
Definition sculpt.cc:7335
void flush_update_done(const bContext *C, Object &ob, const UpdateType update_type)
Definition sculpt.cc:5146
void apply_translations(Span< float3 > translations, Span< int > verts, MutableSpan< float3 > positions)
Definition sculpt.cc:7268
void gather_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
Definition sculpt.cc:6395
void flush_update_step(const bContext *C, const UpdateType update_type)
Definition sculpt.cc:5098
void gather_grids_normals(const SubdivCCG &subdiv_ccg, Span< int > grids, MutableSpan< float3 > normals)
Definition sculpt.cc:6378
bool SCULPT_mode_poll_view3d(bContext *C)
Definition sculpt.cc:3683
SubdivCCG * subdiv_ccg
Definition BKE_paint.hh:395
blender::Array< blender::float3 > positions
Object * obact
Definition ED_view3d.hh:75
void(* end)(bContext &, GestureData &)
void(* begin)(bContext &, wmOperator &, GestureData &)
void(* apply_for_symmetry_pass)(bContext &, GestureData &)
i
Definition text_draw.cc:230
@ WM_CURSOR_EDIT
Definition wm_cursors.hh:19
wmOperatorType * ot
Definition wm_files.cc:4237
wmOperatorStatus WM_gesture_straightline_active_side_invoke(bContext *C, wmOperator *op, const wmEvent *event)
wmOperatorStatus WM_gesture_straightline_oneshot_modal(bContext *C, wmOperator *op, const wmEvent *event)
void WM_operator_properties_gesture_straightline(wmOperatorType *ot, int cursor)