Blender V5.0
editors/sculpt_paint/brushes/layer.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 "DNA_brush_types.h"
8#include "DNA_mesh_types.h"
9#include "DNA_object_types.h"
10#include "DNA_scene_types.h"
11
12#include "BKE_attribute.hh"
13#include "BKE_mesh.hh"
14#include "BKE_paint.hh"
15#include "BKE_paint_bvh.hh"
16#include "BKE_subdiv_ccg.hh"
17
18#include "BLI_array.hh"
20#include "BLI_task.hh"
21
27
28#include "bmesh.hh"
29
31
32inline namespace layer_cc {
33
44
45BLI_NOINLINE static void offset_displacement_factors(const MutableSpan<float> displacement_factors,
46 const Span<float> factors,
47 const float strength)
48{
49 for (const int i : displacement_factors.index_range()) {
50 displacement_factors[i] += factors[i] * strength * (1.05f - std::abs(displacement_factors[i]));
51 }
52}
53
62BLI_NOINLINE static void reset_displacement_factors(const MutableSpan<float> displacement_factors,
63 const Span<float> factors,
64 const float strength)
65{
66 for (const int i : displacement_factors.index_range()) {
67 displacement_factors[i] += std::abs(factors[i] * strength * displacement_factors[i]) *
68 (displacement_factors[i] > 0.0f ? -1.0f : 1.0f);
69 }
70}
71
72BLI_NOINLINE static void clamp_displacement_factors(const MutableSpan<float> displacement_factors,
73 const Span<float> masks)
74{
75 if (masks.is_empty()) {
76 for (const int i : displacement_factors.index_range()) {
77 displacement_factors[i] = std::clamp(displacement_factors[i], -1.0f, 1.0f);
78 }
79 }
80 else {
81 for (const int i : displacement_factors.index_range()) {
82 const float clamp_mask = 1.0f - masks[i];
83 displacement_factors[i] = std::clamp(displacement_factors[i], -clamp_mask, clamp_mask);
84 }
85 }
86}
87
88BLI_NOINLINE static void calc_translations(const Span<float3> orig_positions,
89 const Span<float3> orig_normals,
90 const Span<float3> positions,
91 const Span<float> displacement_factors,
92 const Span<float> factors,
93 const float height,
94 const MutableSpan<float3> r_translations)
95{
96 for (const int i : positions.index_range()) {
97 const float3 offset = orig_normals[i] * height * displacement_factors[i];
98 const float3 translation = orig_positions[i] + offset - positions[i];
99 r_translations[i] = translation * factors[i];
100 }
101}
102
103BLI_NOINLINE static void calc_translations(const Span<float3> base_positions,
104 const Span<float3> base_normals,
105 const Span<int> verts,
106 const Span<float3> positions,
107 const Span<float> displacement_factors,
108 const Span<float> factors,
109 const float height,
110 const MutableSpan<float3> r_translations)
111{
112 for (const int i : positions.index_range()) {
113 const float3 offset = base_normals[verts[i]] * height * displacement_factors[i];
114 const float3 translation = base_positions[verts[i]] + offset - positions[i];
115 r_translations[i] = translation * factors[i];
116 }
117}
118
119static void calc_faces(const Depsgraph &depsgraph,
120 const Sculpt &sd,
121 const Brush &brush,
122 const MeshAttributeData &attribute_data,
123 const Span<float3> vert_normals,
124 const bool use_persistent_base,
125 const Span<float3> persistent_base_positions,
126 const Span<float3> persistent_base_normals,
127 Object &object,
129 LocalData &tls,
130 MutableSpan<float> layer_displacement_factor,
131 const PositionDeformData &position_data)
132{
133 const SculptSession &ss = *object.sculpt;
134 const StrokeCache &cache = *ss.cache;
135
136 const Span<int> verts = node.verts();
137 const OrigPositionData orig_data = orig_position_data_get_mesh(object, node);
138 const MutableSpan positions = gather_data_mesh(position_data.eval, verts, tls.positions);
139
140 tls.factors.resize(verts.size());
141 const MutableSpan<float> factors = tls.factors;
142 fill_factor_from_hide_and_mask(attribute_data.hide_vert, attribute_data.mask, verts, factors);
143 filter_region_clip_factors(ss, positions, factors);
144 if (brush.flag & BRUSH_FRONTFACE) {
145 calc_front_face(cache.view_normal_symm, vert_normals, verts, factors);
146 }
147
148 tls.distances.resize(verts.size());
149 const MutableSpan<float> distances = tls.distances;
151 ss, orig_data.positions, eBrushFalloffShape(brush.falloff_shape), distances);
152 filter_distances_with_radius(cache.radius, distances, factors);
153 apply_hardness_to_distances(cache, distances);
154 calc_brush_strength_factors(cache, brush, distances, factors);
155
156 auto_mask::calc_vert_factors(depsgraph, object, cache.automasking.get(), node, verts, factors);
157
158 calc_brush_texture_factors(ss, brush, positions, factors);
159
160 if (attribute_data.mask.is_empty()) {
161 tls.masks.clear();
162 }
163 else {
164 tls.masks.resize(verts.size());
165 gather_data_mesh(attribute_data.mask, verts, tls.masks.as_mutable_span());
166 }
167 const MutableSpan<float> masks = tls.masks;
168
169 tls.displacement_factors.resize(verts.size());
170 const MutableSpan<float> displacement_factors = tls.displacement_factors;
171 gather_data_mesh(layer_displacement_factor.as_span(), verts, displacement_factors);
172
173 if (use_persistent_base) {
174 if (cache.invert) {
175 reset_displacement_factors(displacement_factors, tls.factors, cache.bstrength);
176 }
177 else {
178 offset_displacement_factors(displacement_factors, tls.factors, cache.bstrength);
179 }
180 clamp_displacement_factors(displacement_factors, masks);
181
182 scatter_data_mesh(displacement_factors.as_span(), verts, layer_displacement_factor);
183
184 tls.translations.resize(verts.size());
185 const MutableSpan<float3> translations = tls.translations;
186 calc_translations(persistent_base_positions,
187 persistent_base_normals,
188 verts,
189 positions,
190 displacement_factors,
191 tls.factors,
192 brush.height,
193 translations);
194
195 clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
196 position_data.deform(translations, verts);
197 }
198 else {
199 offset_displacement_factors(displacement_factors, tls.factors, cache.bstrength);
200 clamp_displacement_factors(displacement_factors, masks);
201
202 scatter_data_mesh(displacement_factors.as_span(), verts, layer_displacement_factor);
203
204 tls.translations.resize(verts.size());
205 const MutableSpan<float3> translations = tls.translations;
207 orig_data.normals,
208 positions,
209 displacement_factors,
210 tls.factors,
211 brush.height,
212 translations);
213
214 clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
215 position_data.deform(translations, verts);
216 }
217}
218
219static void calc_grids(const Depsgraph &depsgraph,
220 const Sculpt &sd,
221 const Brush &brush,
222 Object &object,
223 const bool use_persistent_base,
224 const Span<float3> persistent_base_positions,
225 const Span<float3> persistent_base_normals,
227 LocalData &tls,
228 MutableSpan<float> layer_displacement_factor)
229{
230 SculptSession &ss = *object.sculpt;
231 const StrokeCache &cache = *ss.cache;
232 SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
233
234 const Span<int> grids = node.grids();
235 const OrigPositionData orig_data = orig_position_data_get_grids(object, node);
236 const MutableSpan positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
237
238 tls.factors.resize(positions.size());
239 const MutableSpan<float> factors = tls.factors;
240 fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
241 filter_region_clip_factors(ss, positions, factors);
242 if (brush.flag & BRUSH_FRONTFACE) {
243 calc_front_face(cache.view_normal_symm, subdiv_ccg, grids, factors);
244 }
245
246 tls.distances.resize(positions.size());
247 const MutableSpan<float> distances = tls.distances;
249 ss, orig_data.positions, eBrushFalloffShape(brush.falloff_shape), distances);
250 filter_distances_with_radius(cache.radius, distances, factors);
251 apply_hardness_to_distances(cache, distances);
252 calc_brush_strength_factors(cache, brush, distances, factors);
253
254 auto_mask::calc_grids_factors(depsgraph, object, cache.automasking.get(), node, grids, factors);
255
256 calc_brush_texture_factors(ss, brush, positions, factors);
257
258 if (subdiv_ccg.masks.is_empty()) {
259 tls.masks.clear();
260 }
261 else {
262 tls.masks.resize(positions.size());
263 gather_data_grids(subdiv_ccg, subdiv_ccg.masks.as_span(), grids, tls.masks.as_mutable_span());
264 }
265 const MutableSpan<float> masks = tls.masks;
266
267 const MutableSpan<float> displacement_factors = gather_data_grids(
268 subdiv_ccg, layer_displacement_factor.as_span(), grids, tls.displacement_factors);
269
270 if (use_persistent_base) {
271 if (cache.invert) {
272 reset_displacement_factors(displacement_factors, tls.factors, cache.bstrength);
273 }
274 else {
275 offset_displacement_factors(displacement_factors, tls.factors, cache.bstrength);
276 }
277 clamp_displacement_factors(displacement_factors, masks);
278
280 subdiv_ccg, displacement_factors.as_span(), grids, layer_displacement_factor);
281
282 tls.translations.resize(positions.size());
283 const MutableSpan<float3> translations = tls.translations;
285 gather_data_grids(subdiv_ccg, persistent_base_positions, grids, tls.persistent_positions),
286 gather_data_grids(subdiv_ccg, persistent_base_normals, grids, tls.persistent_normals),
287 positions,
288 displacement_factors,
289 tls.factors,
290 brush.height,
291 translations);
292
293 clip_and_lock_translations(sd, ss, positions, translations);
294 apply_translations(translations, grids, subdiv_ccg);
295 }
296 else {
297 offset_displacement_factors(displacement_factors, tls.factors, cache.bstrength);
298 clamp_displacement_factors(displacement_factors, masks);
299
301 subdiv_ccg, displacement_factors.as_span(), grids, layer_displacement_factor);
302
303 tls.translations.resize(positions.size());
304 const MutableSpan<float3> translations = tls.translations;
306 orig_data.normals,
307 positions,
308 displacement_factors,
309 tls.factors,
310 brush.height,
311 translations);
312
313 clip_and_lock_translations(sd, ss, positions, translations);
314 apply_translations(translations, grids, subdiv_ccg);
315 }
316}
317
318static void calc_bmesh(const Depsgraph &depsgraph,
319 const Sculpt &sd,
320 const Brush &brush,
321 Object &object,
323 LocalData &tls,
324 MutableSpan<float> layer_displacement_factor)
325{
326 SculptSession &ss = *object.sculpt;
327 const StrokeCache &cache = *ss.cache;
328
330
331 Array<float3> orig_positions(verts.size());
332 Array<float3> orig_normals(verts.size());
333 orig_position_data_gather_bmesh(*ss.bm_log, verts, orig_positions, orig_normals);
334
335 const MutableSpan positions = gather_bmesh_positions(verts, tls.positions);
336
337 tls.factors.resize(verts.size());
338 const MutableSpan<float> factors = tls.factors;
340 filter_region_clip_factors(ss, positions, factors);
341 if (brush.flag & BRUSH_FRONTFACE) {
342 calc_front_face(cache.view_normal_symm, verts, factors);
343 }
344
345 tls.distances.resize(verts.size());
346 const MutableSpan<float> distances = tls.distances;
347 calc_brush_distances(ss, orig_positions, eBrushFalloffShape(brush.falloff_shape), distances);
348 filter_distances_with_radius(cache.radius, distances, factors);
349 apply_hardness_to_distances(cache, distances);
350 calc_brush_strength_factors(cache, brush, distances, factors);
351
352 auto_mask::calc_vert_factors(depsgraph, object, cache.automasking.get(), node, verts, factors);
353
354 calc_brush_texture_factors(ss, brush, positions, factors);
355
356 const MutableSpan<float> displacement_factors = gather_data_bmesh(
357 layer_displacement_factor.as_span(), verts, tls.displacement_factors);
358
359 offset_displacement_factors(displacement_factors, tls.factors, cache.bstrength);
360
361 tls.masks.resize(verts.size());
362 const MutableSpan<float> masks = tls.masks;
363 mask::gather_mask_bmesh(*ss.bm, verts, masks);
364 clamp_displacement_factors(displacement_factors, masks);
365
366 scatter_data_bmesh(displacement_factors.as_span(), verts, layer_displacement_factor);
367
368 tls.translations.resize(verts.size());
369 const MutableSpan<float3> translations = tls.translations;
370 calc_translations(orig_positions,
371 orig_normals,
372 positions,
373 displacement_factors,
374 tls.factors,
375 brush.height,
376 translations);
377
378 clip_and_lock_translations(sd, ss, positions, translations);
379 apply_translations(translations, verts);
380}
381
382} // namespace layer_cc
383
384void do_layer_brush(const Depsgraph &depsgraph,
385 const Sculpt &sd,
386 Object &object,
387 const IndexMask &node_mask)
388{
389 SculptSession &ss = *object.sculpt;
390 bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
391 const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
392
394 switch (pbvh.type()) {
396 Mesh &mesh = *static_cast<Mesh *>(object.data);
397 const PositionDeformData position_data(depsgraph, object);
398 const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
399
400 const MeshAttributeData attribute_data(mesh);
401 bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
402 const VArraySpan persistent_position = *attributes.lookup<float3>(".sculpt_persistent_co",
404 const VArraySpan persistent_normal = *attributes.lookup<float3>(".sculpt_persistent_no",
406
407 bke::SpanAttributeWriter<float> persistent_disp_attr;
408 bool use_persistent_base = false;
409 MutableSpan<float> displacement;
410 if (brush.flag & BRUSH_PERSISTENT) {
411 if (!persistent_position.is_empty() && !persistent_normal.is_empty()) {
412 persistent_disp_attr = attributes.lookup_or_add_for_write_span<float>(
413 ".sculpt_persistent_disp", bke::AttrDomain::Point);
414 if (persistent_disp_attr) {
415 use_persistent_base = true;
416 displacement = persistent_disp_attr.span;
417 }
418 }
419 }
420
421 if (displacement.is_empty()) {
424 0.0f);
425 }
426 displacement = ss.cache->layer_displacement_factor;
427 }
428
430 node_mask.foreach_index(GrainSize(1), [&](const int i) {
431 LocalData &tls = all_tls.local();
433 sd,
434 brush,
435 attribute_data,
436 vert_normals,
437 use_persistent_base,
438 persistent_position,
439 persistent_normal,
440 object,
441 nodes[i],
442 tls,
443 displacement,
444 position_data);
445 bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
446 });
447 persistent_disp_attr.finish();
448 break;
449 }
451 SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
452 MutableSpan<float3> positions = subdiv_ccg.positions;
453
454 const std::optional<PersistentMultiresData> persistent_multires_data =
456
457 Span<float3> persistent_position;
458 Span<float3> persistent_normal;
459
460 bool use_persistent_base = false;
461 MutableSpan<float> displacement;
462 if (brush.flag & BRUSH_PERSISTENT) {
463 if (persistent_multires_data) {
464 use_persistent_base = true;
465 persistent_position = persistent_multires_data->positions;
466 persistent_normal = persistent_multires_data->normals;
467 displacement = persistent_multires_data->displacements;
468 }
469 }
470
471 if (displacement.is_empty()) {
473 ss.cache->layer_displacement_factor = Array<float>(positions.size(), 0.0f);
474 }
475 displacement = ss.cache->layer_displacement_factor;
476 }
477
479 node_mask.foreach_index(GrainSize(1), [&](const int i) {
480 LocalData &tls = all_tls.local();
482 sd,
483 brush,
484 object,
485 use_persistent_base,
486 persistent_position,
487 persistent_normal,
488 nodes[i],
489 tls,
490 displacement);
491 bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
492 });
493 break;
494 }
498 }
499 const MutableSpan<float> displacement = ss.cache->layer_displacement_factor;
501 node_mask.foreach_index(GrainSize(1), [&](const int i) {
502 LocalData &tls = all_tls.local();
503 calc_bmesh(depsgraph, sd, brush, object, nodes[i], tls, displacement);
505 });
506 break;
507 }
508 }
509 pbvh.tag_positions_changed(node_mask);
511}
512
513} // 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_NOINLINE
@ BRUSH_FRONTFACE
@ BRUSH_PERSISTENT
eBrushFalloffShape
Object is a sort of wrapper for general info.
BPy_StructRNA * depsgraph
Span< T > as_span() const
Definition BLI_array.hh:243
bool is_empty() const
Definition BLI_array.hh:264
constexpr bool is_empty() const
Definition BLI_span.hh:260
void resize(const int64_t new_size)
constexpr int64_t size() const
Definition BLI_span.hh:493
constexpr bool is_empty() const
Definition BLI_span.hh:509
constexpr Span< T > as_span() const
Definition BLI_span.hh:661
constexpr IndexRange index_range() const
Definition BLI_span.hh:670
constexpr IndexRange index_range() const
Definition BLI_span.hh:401
constexpr bool is_empty() const
Definition BLI_span.hh:260
GAttributeReader lookup(const StringRef attribute_id) const
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, AttrType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
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
void calc_vert_factors(const Depsgraph &depsgraph, const Object &object, const Cache &automasking, const bke::pbvh::MeshNode &node, Span< int > verts, MutableSpan< float > factors)
void calc_grids_factors(const Depsgraph &depsgraph, const Object &object, const Cache &automasking, const bke::pbvh::GridsNode &node, Span< int > grids, MutableSpan< float > factors)
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 BLI_NOINLINE void fill_factor_from_hide_and_mask(const Mesh &mesh, const Span< int > face_indices, const MutableSpan< float > r_factors)
static void calc_faces(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, const MeshAttributeData &attribute_data, const Span< float3 > vert_normals, const bool use_persistent_base, const Span< float3 > persistent_base_positions, const Span< float3 > persistent_base_normals, Object &object, bke::pbvh::MeshNode &node, LocalData &tls, MutableSpan< float > layer_displacement_factor, const PositionDeformData &position_data)
static BLI_NOINLINE void reset_displacement_factors(const MutableSpan< float > displacement_factors, const Span< float > factors, const float strength)
static BLI_NOINLINE void clamp_displacement_factors(const MutableSpan< float > displacement_factors, const Span< float > masks)
static void calc_bmesh(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, Object &object, bke::pbvh::BMeshNode &node, LocalData &tls, MutableSpan< float > layer_displacement_factor)
static void calc_grids(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, Object &object, const bool use_persistent_base, const Span< float3 > persistent_base_positions, const Span< float3 > persistent_base_normals, bke::pbvh::GridsNode &node, LocalData &tls, MutableSpan< float > layer_displacement_factor)
static BLI_NOINLINE void offset_displacement_factors(const MutableSpan< float > displacement_factors, const Span< float > factors, const float strength)
static BLI_NOINLINE void calc_translations(const Span< float3 > orig_positions, const Span< float3 > orig_normals, const Span< float3 > positions, const Span< float > displacement_factors, const Span< float > factors, const float height, const MutableSpan< float3 > r_translations)
static BLI_NOINLINE void clamp_mask(const MutableSpan< float > masks)
void do_layer_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
void gather_mask_bmesh(const BMesh &bm, const Set< BMVert *, 0 > &verts, const MutableSpan< float > r_mask)
MutableSpan< float3 > gather_grids_positions(const SubdivCCG &subdiv_ccg, const Span< int > grids, Vector< float3 > &positions)
void scatter_data_bmesh(Span< T > node_data, const Set< BMVert *, 0 > &verts, MutableSpan< T > dst)
Definition sculpt.cc:6461
void gather_bmesh_positions(const Set< BMVert *, 0 > &verts, MutableSpan< float3 > positions)
Definition sculpt.cc:6367
void calc_brush_strength_factors(const StrokeCache &cache, const Brush &brush, Span< float > distances, MutableSpan< float > factors)
Definition sculpt.cc:7183
void gather_data_grids(const SubdivCCG &subdiv_ccg, Span< T > src, Span< int > grids, MutableSpan< T > node_data)
Definition sculpt.cc:6405
void apply_hardness_to_distances(float radius, float hardness, MutableSpan< float > distances)
Definition sculpt.cc:7156
void filter_distances_with_radius(float radius, Span< float > distances, MutableSpan< float > factors)
Definition sculpt.cc:7105
void filter_region_clip_factors(const SculptSession &ss, Span< float3 > vert_positions, Span< int > verts, MutableSpan< float > factors)
Definition sculpt.cc:6972
void gather_data_bmesh(Span< T > src, const Set< BMVert *, 0 > &verts, MutableSpan< T > node_data)
Definition sculpt.cc:6421
void orig_position_data_gather_bmesh(const BMLog &bm_log, const Set< BMVert *, 0 > &verts, MutableSpan< float3 > positions, MutableSpan< float3 > normals)
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 scatter_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
Definition sculpt.cc:6435
void calc_brush_distances(const SculptSession &ss, Span< float3 > vert_positions, Span< int > vert, eBrushFalloffShape falloff_shape, MutableSpan< float > r_distances)
Definition sculpt.cc:7055
void apply_translations(Span< float3 > translations, Span< int > verts, MutableSpan< float3 > positions)
Definition sculpt.cc:7268
OrigPositionData orig_position_data_get_mesh(const Object &object, const bke::pbvh::MeshNode &node)
void gather_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
Definition sculpt.cc:6395
void calc_brush_texture_factors(const SculptSession &ss, const Brush &brush, Span< float3 > vert_positions, Span< int > vert, MutableSpan< float > factors)
Definition sculpt.cc:7195
OrigPositionData orig_position_data_get_grids(const Object &object, const bke::pbvh::GridsNode &node)
void calc_front_face(const float3 &view_normal, Span< float3 > normals, MutableSpan< float > factors)
Definition sculpt.cc:6914
void scatter_data_grids(const SubdivCCG &subdiv_ccg, Span< T > node_data, Span< int > grids, MutableSpan< T > dst)
Definition sculpt.cc:6445
VecBase< float, 3 > float3
int SCULPT_vertex_count_get(const Object &object)
Definition sculpt.cc:151
char falloff_shape
float height
blender::ed::sculpt_paint::StrokeCache * cache
Definition BKE_paint.hh:417
BMLog * bm_log
Definition BKE_paint.hh:392
SubdivCCG * subdiv_ccg
Definition BKE_paint.hh:395
std::optional< PersistentMultiresData > persistent_multires_data()
Definition paint.cc:2442
blender::Array< float > masks
blender::Array< blender::float3 > positions
std::unique_ptr< auto_mask::Cache > automasking
i
Definition text_draw.cc:230