Blender V4.3
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
9#include "BLI_array_utils.hh"
11
12#include "BKE_context.hh"
13#include "BKE_layer.hh"
14#include "BKE_mesh.hh"
15#include "BKE_subdiv_ccg.hh"
16
17#include "WM_api.hh"
18#include "WM_types.hh"
19
20#include "mesh_brush_common.hh"
21#include "sculpt_automask.hh"
22#include "sculpt_gesture.hh"
23#include "sculpt_intern.hh"
24#include "sculpt_undo.hh"
25
27
31
32static void gesture_begin(bContext &C, wmOperator &op, gesture::GestureData &gesture_data)
33{
34 const Scene &scene = *CTX_data_scene(&C);
37 undo::push_begin(scene, *gesture_data.vc.obact, &op);
38}
39
47
48static void apply_projection_mesh(const Sculpt &sd,
49 const gesture::GestureData &gesture_data,
50 const Span<float3> vert_normals,
51 const MeshAttributeData &attribute_data,
52 const bke::pbvh::MeshNode &node,
53 Object &object,
54 LocalData &tls,
55 const PositionDeformData &position_data)
56{
57 SculptSession &ss = *object.sculpt;
58
59 const Span<int> verts = node.verts();
60 const MutableSpan positions = gather_data_mesh(position_data.eval, verts, tls.positions);
61 const MutableSpan normals = gather_data_mesh(vert_normals, verts, tls.normals);
62
63 tls.factors.resize(verts.size());
64 const MutableSpan<float> factors = tls.factors;
65 fill_factor_from_hide_and_mask(attribute_data.hide_vert, attribute_data.mask, verts, factors);
66
67 gesture::filter_factors(gesture_data, positions, normals, factors);
68
69 tls.translations.resize(verts.size());
70 const MutableSpan<float3> translations = tls.translations;
71 calc_translations_to_plane(positions, gesture_data.line.plane, translations);
72 scale_translations(translations, factors);
73
74 clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
75 position_data.deform(translations, verts);
76}
77
78static void apply_projection_grids(const Sculpt &sd,
79 const gesture::GestureData &gesture_data,
80 const bke::pbvh::GridsNode &node,
81 Object &object,
82 LocalData &tls)
83{
84 SculptSession &ss = *object.sculpt;
85
86 SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
87
88 const Span<int> grids = node.grids();
89 const MutableSpan positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
90
91 tls.normals.resize(positions.size());
92 const MutableSpan<float3> normals = tls.normals;
93 gather_grids_normals(subdiv_ccg, grids, normals);
94
95 tls.factors.resize(positions.size());
96 const MutableSpan<float> factors = tls.factors;
97 fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
98
99 gesture::filter_factors(gesture_data, positions, normals, factors);
100
101 tls.translations.resize(positions.size());
102 const MutableSpan<float3> translations = tls.translations;
103 calc_translations_to_plane(positions, gesture_data.line.plane, translations);
104 scale_translations(translations, factors);
105
106 clip_and_lock_translations(sd, ss, positions, translations);
107 apply_translations(translations, grids, subdiv_ccg);
108}
109
110static void apply_projection_bmesh(const Sculpt &sd,
111 const gesture::GestureData &gesture_data,
113 Object &object,
114 LocalData &tls)
115{
116 const SculptSession &ss = *object.sculpt;
117
119 const MutableSpan positions = gather_bmesh_positions(verts, tls.positions);
120
121 tls.normals.resize(verts.size());
122 const MutableSpan<float3> normals = tls.normals;
123 gather_bmesh_normals(verts, normals);
124
125 tls.factors.resize(verts.size());
126 const MutableSpan<float> factors = tls.factors;
128
129 gesture::filter_factors(gesture_data, positions, normals, factors);
130
131 tls.translations.resize(verts.size());
132 const MutableSpan<float3> translations = tls.translations;
133 calc_translations_to_plane(positions, gesture_data.line.plane, translations);
134 scale_translations(translations, factors);
135
136 clip_and_lock_translations(sd, ss, positions, translations);
137 apply_translations(translations, verts);
138}
139
141{
142 const Depsgraph &depsgraph = *CTX_data_depsgraph_pointer(&C);
143 Object &object = *gesture_data.vc.obact;
144 bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
145 const Sculpt &sd = *CTX_data_tool_settings(&C)->sculpt;
146 const IndexMask &node_mask = gesture_data.node_mask;
147
149 switch (gesture_data.shape_type) {
151 switch (pbvh.type()) {
153 Mesh &mesh = *static_cast<Mesh *>(object.data);
154 const MeshAttributeData attribute_data(mesh.attributes());
156 const PositionDeformData position_data(depsgraph, object);
157 const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
159 node_mask.foreach_index(GrainSize(1), [&](const int i) {
160 LocalData &tls = all_tls.local();
162 gesture_data,
163 vert_normals,
164 attribute_data,
165 nodes[i],
166 object,
167 tls,
168 position_data);
169 bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
170 });
171 break;
172 }
174 SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
175 MutableSpan<float3> positions = subdiv_ccg.positions;
178 node_mask.foreach_index(GrainSize(1), [&](const int i) {
179 LocalData &tls = all_tls.local();
180 apply_projection_grids(sd, gesture_data, nodes[i], object, tls);
181 bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
182 });
183 break;
184 }
188 node_mask.foreach_index(GrainSize(1), [&](const int i) {
189 LocalData &tls = all_tls.local();
190 apply_projection_bmesh(sd, gesture_data, nodes[i], object, tls);
192 });
193 break;
194 }
195 }
196 break;
199 /* Gesture shape projection not implemented yet. */
201 break;
202 }
203 pbvh.tag_positions_changed(node_mask);
205}
206
207static void gesture_end(bContext &C, gesture::GestureData &gesture_data)
208{
211 undo::push_end(*gesture_data.vc.obact);
212}
213
214static void init_operation(gesture::GestureData &gesture_data, wmOperator & /*op*/)
215{
216 gesture_data.operation = reinterpret_cast<gesture::Operation *>(
217 MEM_cnew<ProjectOperation>(__func__));
218
219 ProjectOperation *project_operation = (ProjectOperation *)gesture_data.operation;
220
221 project_operation->operation.begin = gesture_begin;
223 project_operation->operation.end = gesture_end;
224}
225
226static int gesture_line_invoke(bContext *C, wmOperator *op, const wmEvent *event)
227{
228 const View3D *v3d = CTX_wm_view3d(C);
229 const Base *base = CTX_data_active_base(C);
230 if (!BKE_base_is_visible(v3d, base)) {
231 return OPERATOR_CANCELLED;
232 }
233
235}
236
238{
239 std::unique_ptr<gesture::GestureData> gesture_data = gesture::init_from_line(C, op);
240 if (!gesture_data) {
241 return OPERATOR_CANCELLED;
242 }
243 init_operation(*gesture_data, *op);
244 gesture::apply(*C, *gesture_data, *op);
245 return OPERATOR_FINISHED;
246}
247
249{
250 ot->name = "Project Line Gesture";
251 ot->idname = "SCULPT_OT_project_line_gesture";
252 ot->description = "Project the geometry onto a plane defined by a line";
253
257
259
261
264}
265
266} // 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:2601
const blender::Set< BMVert *, 0 > & BKE_pbvh_bmesh_node_unique_verts(blender::bke::pbvh::BMeshNode *node)
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
@ OPTYPE_REGISTER
Definition WM_types.hh:160
void resize(const int64_t new_size)
void tag_positions_changed(const IndexMask &node_mask)
Definition pbvh.cc:549
Span< NodeT > nodes() const
void deform(MutableSpan< float3 > translations, Span< int > verts) const
Definition sculpt.cc:7139
void foreach_index(Fn &&fn) const
const Depsgraph * depsgraph
static float verts[][3]
pbvh::Tree * pbvh_get(Object &object)
Definition paint.cc:2846
void update_node_bounds_bmesh(BMeshNode &node)
Definition pbvh.cc:1095
void update_node_bounds_mesh(Span< float3 > positions, MeshNode &node)
Definition pbvh.cc:1075
Span< float3 > vert_normals_eval(const Depsgraph &depsgraph, const Object &object_orig)
Definition pbvh.cc:2502
void update_node_bounds_grids(int grid_area, Span< float3 > positions, GridsNode &node)
Definition pbvh.cc:1084
void flush_bounds_to_parents(Tree &pbvh)
Definition pbvh.cc:1132
static BLI_NOINLINE void fill_factor_from_hide_and_mask(const Mesh &mesh, const Span< int > face_indices, const MutableSpan< float > r_factors)
void operator_properties(wmOperatorType *ot, ShapeType shapeType)
std::unique_ptr< GestureData > init_from_line(bContext *C, 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 int gesture_line_exec(bContext *C, wmOperator *op)
static int 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 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)
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:6054
void gather_bmesh_normals(const Set< BMVert *, 0 > &verts, MutableSpan< float3 > normals)
Definition sculpt.cc:6072
void flush_update_done(const bContext *C, Object &ob, UpdateType update_type)
Definition sculpt.cc:5055
void scale_translations(MutableSpan< float3 > translations, Span< float > factors)
Definition sculpt.cc:7210
void flush_update_step(bContext *C, UpdateType update_type)
Definition sculpt.cc:4960
void calc_translations_to_plane(Span< float3 > vert_positions, Span< int > verts, const float4 &plane, MutableSpan< float3 > translations)
Definition sculpt.cc:7479
void clip_and_lock_translations(const Sculpt &sd, const SculptSession &ss, Span< float3 > positions, Span< int > verts, MutableSpan< float3 > translations)
Definition sculpt.cc:7022
void apply_translations(Span< float3 > translations, Span< int > verts, MutableSpan< float3 > positions)
Definition sculpt.cc:6958
void gather_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
Definition sculpt.cc:6082
void gather_grids_normals(const SubdivCCG &subdiv_ccg, Span< int > grids, MutableSpan< float3 > normals)
Definition sculpt.cc:6065
bool SCULPT_mode_poll_view3d(bContext *C)
Definition sculpt.cc:3566
SubdivCCG * subdiv_ccg
Definition BKE_paint.hh:405
blender::Array< blender::float3 > positions
Object * obact
Definition ED_view3d.hh:71
void(* end)(bContext &, GestureData &)
void(* begin)(bContext &, wmOperator &, GestureData &)
void(* apply_for_symmetry_pass)(bContext &, GestureData &)
const char * name
Definition WM_types.hh:990
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1042
const char * idname
Definition WM_types.hh:992
int(* modal)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1036
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1022
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1006
const char * description
Definition WM_types.hh:996
@ WM_CURSOR_EDIT
Definition wm_cursors.hh:19
wmOperatorType * ot
Definition wm_files.cc:4125
int WM_gesture_straightline_oneshot_modal(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_straightline_active_side_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void WM_operator_properties_gesture_straightline(wmOperatorType *ot, int cursor)