Blender V5.0
pinch.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
6
7#include "BKE_mesh.hh"
8#include "BKE_paint.hh"
9#include "BKE_paint_bvh.hh"
10#include "BKE_subdiv_ccg.hh"
11#include "DNA_brush_types.h"
12#include "DNA_mesh_types.h"
13#include "DNA_object_types.h"
14#include "DNA_scene_types.h"
15
17#include "BLI_math_matrix.h"
18#include "BLI_math_vector.hh"
19#include "BLI_task.hh"
20
24
25#include "bmesh.hh"
26
28
29inline namespace pinch_cc {
30
37
38BLI_NOINLINE static void calc_translations(const Span<float3> positions,
39 const float3 &location,
40 const std::array<float3, 2> &stroke_xz,
41 const MutableSpan<float3> translations)
42{
43 BLI_assert(positions.size() == translations.size());
44
45 for (const int i : positions.index_range()) {
46 /* Calculate displacement from the vertex to the brush center. */
47 const float3 disp_center = location - positions[i];
48
49 /* Project the displacement into the X vector (aligned to the stroke). */
50 const float3 x_disp = stroke_xz[0] * math::dot(disp_center, stroke_xz[0]);
51
52 /* Project the displacement into the Z vector (aligned to the surface normal). */
53 const float3 z_disp = stroke_xz[1] * math::dot(disp_center, stroke_xz[1]);
54
55 /* Add the two projected vectors to calculate the final displacement.
56 * The Y component is removed. */
57 translations[i] = x_disp + z_disp;
58 }
59}
60
61static void calc_faces(const Depsgraph &depsgraph,
62 const Sculpt &sd,
63 const Brush &brush,
64 const std::array<float3, 2> &stroke_xz,
65 const float strength,
66 const MeshAttributeData &attribute_data,
67 const Span<float3> vert_normals,
68 const bke::pbvh::MeshNode &node,
69 Object &object,
70 LocalData &tls,
71 const PositionDeformData &position_data)
72{
73 SculptSession &ss = *object.sculpt;
74 const StrokeCache &cache = *ss.cache;
75
76 const Span<int> verts = node.verts();
77 const MutableSpan positions = gather_data_mesh(position_data.eval, verts, tls.positions);
78
80 brush,
81 object,
82 attribute_data,
83 positions,
84 vert_normals,
85 node,
86 tls.factors,
87 tls.distances);
88
89 scale_factors(tls.factors, strength);
90
91 tls.translations.resize(verts.size());
92 const MutableSpan<float3> translations = tls.translations;
93 calc_translations(positions, cache.location_symm, stroke_xz, translations);
95 project_translations(translations, cache.view_normal_symm);
96 }
97
98 scale_translations(translations, tls.factors);
99
100 clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
101 position_data.deform(translations, verts);
102}
103
104static void calc_grids(const Depsgraph &depsgraph,
105 const Sculpt &sd,
106 Object &object,
107 const Brush &brush,
108 const std::array<float3, 2> &stroke_xz,
109 const float strength,
110 const bke::pbvh::GridsNode &node,
111 LocalData &tls)
112{
113 SculptSession &ss = *object.sculpt;
114 const StrokeCache &cache = *ss.cache;
115 SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
116
117 const Span<int> grids = node.grids();
118 const MutableSpan positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
119
120 calc_factors_common_grids(depsgraph, brush, object, positions, node, tls.factors, tls.distances);
121
122 scale_factors(tls.factors, strength);
123
124 tls.translations.resize(positions.size());
125 const MutableSpan<float3> translations = tls.translations;
126 calc_translations(positions, cache.location_symm, stroke_xz, translations);
128 project_translations(translations, cache.view_normal_symm);
129 }
130
131 scale_translations(translations, tls.factors);
132
133 clip_and_lock_translations(sd, ss, positions, translations);
134 apply_translations(translations, grids, subdiv_ccg);
135}
136
137static void calc_bmesh(const Depsgraph &depsgraph,
138 const Sculpt &sd,
139 Object &object,
140 const Brush &brush,
141 const std::array<float3, 2> &stroke_xz,
142 const float strength,
144 LocalData &tls)
145{
146 SculptSession &ss = *object.sculpt;
147 const StrokeCache &cache = *ss.cache;
148
150
151 const MutableSpan positions = gather_bmesh_positions(verts, tls.positions);
152
153 calc_factors_common_bmesh(depsgraph, brush, object, positions, node, tls.factors, tls.distances);
154
155 scale_factors(tls.factors, strength);
156
157 tls.translations.resize(verts.size());
158 const MutableSpan<float3> translations = tls.translations;
159 calc_translations(positions, cache.location_symm, stroke_xz, translations);
161 project_translations(translations, cache.view_normal_symm);
162 }
163
164 scale_translations(translations, tls.factors);
165
166 clip_and_lock_translations(sd, ss, positions, translations);
167 apply_translations(translations, verts);
168}
169
170} // namespace pinch_cc
171
172void do_pinch_brush(const Depsgraph &depsgraph,
173 const Sculpt &sd,
174 Object &object,
175 const IndexMask &node_mask)
176{
177 const SculptSession &ss = *object.sculpt;
178 bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
179 const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
180
181 float3 area_no;
182 float3 area_co;
183 calc_brush_plane(depsgraph, brush, object, node_mask, area_no, area_co);
184
185 /* delay the first daub because grab delta is not setup */
187 return;
188 }
189
191 return;
192 }
193
194 /* Initialize `mat`. */
196 mat.x_axis() = math::cross(area_no, ss.cache->grab_delta_symm);
197 mat.y_axis() = math::cross(area_no, mat.x_axis());
198 mat.z_axis() = area_no;
199 mat.location() = ss.cache->location_symm;
200 normalize_m4(mat.ptr());
201
202 const std::array<float3, 2> stroke_xz{math::normalize(mat.x_axis()),
203 math::normalize(mat.z_axis())};
204
206 switch (pbvh.type()) {
208 const Mesh &mesh = *static_cast<Mesh *>(object.data);
209 const MeshAttributeData attribute_data(mesh);
210 const PositionDeformData position_data(depsgraph, object);
211 const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
213 node_mask.foreach_index(GrainSize(1), [&](const int i) {
214 LocalData &tls = all_tls.local();
216 sd,
217 brush,
218 stroke_xz,
219 ss.cache->bstrength,
220 attribute_data,
221 vert_normals,
222 nodes[i],
223 object,
224 tls,
225 position_data);
226 bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
227 });
228 break;
229 }
231 SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
232 MutableSpan<float3> positions = subdiv_ccg.positions;
234 node_mask.foreach_index(GrainSize(1), [&](const int i) {
235 LocalData &tls = all_tls.local();
236 calc_grids(depsgraph, sd, object, brush, stroke_xz, ss.cache->bstrength, nodes[i], tls);
237 bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
238 });
239 break;
240 }
243 node_mask.foreach_index(GrainSize(1), [&](const int i) {
244 LocalData &tls = all_tls.local();
245 calc_bmesh(depsgraph, sd, object, brush, stroke_xz, ss.cache->bstrength, nodes[i], tls);
247 });
248 break;
249 }
250 }
251 pbvh.tag_positions_changed(node_mask);
253}
254
255} // namespace blender::ed::sculpt_paint::brushes
const Brush * BKE_paint_brush_for_read(const Paint *paint)
Definition paint.cc:650
A BVH for high poly meshes.
const blender::Set< BMVert *, 0 > & BKE_pbvh_bmesh_node_unique_verts(blender::bke::pbvh::BMeshNode *node)
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_NOINLINE
void normalize_m4(float R[4][4]) ATTR_NONNULL()
@ PAINT_FALLOFF_SHAPE_TUBE
Object is a sort of wrapper for general info.
BPy_StructRNA * depsgraph
constexpr int64_t size() const
Definition BLI_span.hh:493
constexpr int64_t size() const
Definition BLI_span.hh:252
constexpr IndexRange index_range() const
Definition BLI_span.hh:401
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]
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
static void calc_bmesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Brush &brush, const float3 &direction, const float strength, bke::pbvh::BMeshNode &node, LocalData &tls)
static void calc_faces(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, const float4 &test_plane, const float strength, const MeshAttributeData &attribute_data, const Span< float3 > vert_normals, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, const PositionDeformData &position_data)
Definition clay.cc:56
static void calc_grids(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Brush &brush, const float4 &test_plane, const float strength, bke::pbvh::GridsNode &node, LocalData &tls)
Definition clay.cc:93
static void calc_grids(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Brush &brush, const std::array< float3, 2 > &stroke_xz, const float strength, const bke::pbvh::GridsNode &node, LocalData &tls)
Definition pinch.cc:104
static void calc_bmesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Brush &brush, const std::array< float3, 2 > &stroke_xz, const float strength, bke::pbvh::BMeshNode &node, LocalData &tls)
Definition pinch.cc:137
static void calc_faces(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, const std::array< float3, 2 > &stroke_xz, const float strength, const MeshAttributeData &attribute_data, const Span< float3 > vert_normals, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, const PositionDeformData &position_data)
Definition pinch.cc:61
static BLI_NOINLINE void calc_translations(const Span< float3 > positions, const float3 &location, const std::array< float3, 2 > &stroke_xz, const MutableSpan< float3 > translations)
Definition pinch.cc:38
void do_pinch_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
Definition pinch.cc:172
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 calc_factors_common_grids(const Depsgraph &depsgraph, const Brush &brush, const Object &object, Span< float3 > positions, const bke::pbvh::GridsNode &node, Vector< float > &r_factors, Vector< float > &r_distances)
Definition sculpt.cc:6603
void scale_translations(MutableSpan< float3 > translations, Span< float > factors)
Definition sculpt.cc:7495
void scale_factors(MutableSpan< float > factors, float strength)
Definition sculpt.cc:7512
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 project_translations(MutableSpan< float3 > translations, const float3 &plane)
Definition sculpt.cc:7311
void calc_brush_plane(const Depsgraph &depsgraph, const Brush &brush, Object &ob, const IndexMask &node_mask, float3 &r_area_no, float3 &r_area_co)
Definition sculpt.cc:2910
void apply_translations(Span< float3 > translations, Span< int > verts, MutableSpan< float3 > positions)
Definition sculpt.cc:7268
void calc_factors_common_mesh(const Depsgraph &depsgraph, const Brush &brush, const Object &object, const MeshAttributeData &attribute_data, Span< float3 > positions, Span< float3 > vert_normals, const bke::pbvh::MeshNode &node, Vector< float > &r_factors, Vector< float > &r_distances)
Definition sculpt.cc:6568
void gather_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
Definition sculpt.cc:6395
void calc_factors_common_bmesh(const Depsgraph &depsgraph, const Brush &brush, const Object &object, Span< float3 > positions, bke::pbvh::BMeshNode &node, Vector< float > &r_factors, Vector< float > &r_distances)
Definition sculpt.cc:6637
T dot(const QuaternionBase< T > &a, const QuaternionBase< T > &b)
bool is_zero(const T &a)
AxisSigned cross(const AxisSigned a, const AxisSigned b)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
MatBase< float, 4, 4 > float4x4
VecBase< float, 3 > float3
bool SCULPT_stroke_is_first_brush_step_of_symmetry_pass(const blender::ed::sculpt_paint::StrokeCache &cache)
Definition sculpt.cc:542
char falloff_shape
blender::ed::sculpt_paint::StrokeCache * cache
Definition BKE_paint.hh:417
SubdivCCG * subdiv_ccg
Definition BKE_paint.hh:395
blender::Array< blender::float3 > positions
const c_style_mat & ptr() const
i
Definition text_draw.cc:230