Blender V4.3
relax.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
10#include "BKE_subdiv_ccg.hh"
11
13#include "BLI_math_vector.hh"
14#include "BLI_task.hh"
15
22
24
25inline namespace relax_cc {
26
27/* -------------------------------------------------------------------- */
36
42
48
49static void apply_positions_faces(const Sculpt &sd,
50 const Span<int> verts,
51 Object &object,
52 const MutableSpan<float3> translations,
53 const PositionDeformData &position_data)
54{
55 SculptSession &ss = *object.sculpt;
56 clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
57 position_data.deform(translations, verts);
58}
59
60static void apply_positions_grids(const Sculpt &sd,
61 const Span<int> grids,
62 Object &object,
63 const Span<float3> positions,
64 const MutableSpan<float3> translations)
65{
66 SculptSession &ss = *object.sculpt;
67 SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
68
69 clip_and_lock_translations(sd, ss, positions, translations);
70 apply_translations(translations, grids, subdiv_ccg);
71}
72
73static void apply_positions_bmesh(const Sculpt &sd,
75 Object &object,
76 const MutableSpan<float3> translations,
77 const Span<float3> positions)
78
79{
80 SculptSession &ss = *object.sculpt;
81
82 clip_and_lock_translations(sd, ss, positions, translations);
83 apply_translations(translations, verts);
84}
85
88/* -------------------------------------------------------------------- */
92static std::array<float, 4> iteration_strengths(const float strength, const int stroke_iteration)
93{
94 if (stroke_iteration % 3 == 0) {
95 return {strength, strength, strength, strength};
96 }
97
98 /* This operations needs a strength tweak as the relax deformation is too weak by default. */
99 const float modified_strength = strength * 1.5f;
100 return {modified_strength, modified_strength, strength, strength};
101}
102
103BLI_NOINLINE static void calc_factors_faces(const Depsgraph &depsgraph,
104 const Brush &brush,
105 const Span<float3> positions_eval,
106 const Span<float3> vert_normals,
107 const GroupedSpan<int> vert_to_face_map,
108 const MeshAttributeData &attribute_data,
109 const float strength,
110 const bool relax_face_sets,
111 const Object &object,
112 const bke::pbvh::MeshNode &node,
113 MeshLocalData &tls,
114 const MutableSpan<float> factors)
115{
116 const SculptSession &ss = *object.sculpt;
117 const StrokeCache &cache = *ss.cache;
118
119 const Span<int> verts = node.verts();
120
121 fill_factor_from_hide_and_mask(attribute_data.hide_vert, attribute_data.mask, verts, factors);
122 filter_region_clip_factors(ss, positions_eval, verts, factors);
123 if (brush.flag & BRUSH_FRONTFACE) {
124 calc_front_face(cache.view_normal_symm, vert_normals, verts, factors);
125 }
126
127 tls.distances.resize(verts.size());
128 const MutableSpan<float> distances = tls.distances;
130 ss, positions_eval, verts, eBrushFalloffShape(brush.falloff_shape), distances);
131 filter_distances_with_radius(cache.radius, distances, factors);
132 apply_hardness_to_distances(cache, distances);
133 calc_brush_strength_factors(cache, brush, distances, factors);
134
135 auto_mask::calc_vert_factors(depsgraph, object, cache.automasking.get(), node, verts, factors);
136
137 scale_factors(factors, strength);
138
139 calc_brush_texture_factors(ss, brush, positions_eval, verts, factors);
140
142 vert_to_face_map, attribute_data.face_sets, relax_face_sets, verts, factors);
143}
144
145static void do_relax_face_sets_brush_mesh(const Depsgraph &depsgraph,
146 const Sculpt &sd,
147 const Brush &brush,
148 Object &object,
149 const IndexMask &node_mask,
150 const float strength,
151 const bool relax_face_sets)
152{
153 const SculptSession &ss = *object.sculpt;
154 bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
156 Mesh &mesh = *static_cast<Mesh *>(object.data);
157 const OffsetIndices faces = mesh.faces();
158 const Span<int> corner_verts = mesh.corner_verts();
159 const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
160 const MeshAttributeData attribute_data(mesh.attributes());
161
162 const PositionDeformData position_data(depsgraph, object);
163 const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
164
165 Array<int> node_offset_data;
166 const OffsetIndices<int> node_vert_offsets = create_node_vert_offsets(
167 nodes, node_mask, node_offset_data);
168
169 Array<float3> translations(node_vert_offsets.total_size());
170 Array<float> factors(node_vert_offsets.total_size());
171
173 node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) {
174 MeshLocalData &tls = all_tls.local();
176 brush,
177 position_data.eval,
178 vert_normals,
179 vert_to_face_map,
180 attribute_data,
181 strength,
182 relax_face_sets,
183 object,
184 nodes[i],
185 tls,
186 factors.as_mutable_span().slice(node_vert_offsets[pos]));
187 });
188
189 node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) {
190 MeshLocalData &tls = all_tls.local();
192 position_data.eval,
193 vert_normals,
194 faces,
195 corner_verts,
196 vert_to_face_map,
198 attribute_data.face_sets,
199 attribute_data.hide_poly,
200 relax_face_sets,
201 nodes[i].verts(),
202 factors.as_span().slice(node_vert_offsets[pos]),
203 tls.vert_neighbors,
204 translations.as_mutable_span().slice(node_vert_offsets[pos]));
205 });
206
207 node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) {
209 nodes[i].verts(),
210 object,
211 translations.as_mutable_span().slice(node_vert_offsets[pos]),
212 position_data);
213 bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
214 });
215 pbvh.tag_positions_changed(node_mask);
217}
218
219BLI_NOINLINE static void calc_factors_grids(const Depsgraph &depsgraph,
220 const Brush &brush,
221 const OffsetIndices<int> faces,
222 const Span<int> corner_verts,
223 const GroupedSpan<int> vert_to_face_map,
224 const Span<int> face_sets,
225 const bke::pbvh::GridsNode &node,
226 const float strength,
227 const bool relax_face_sets,
228 Object &object,
229 GridLocalData &tls,
230 const MutableSpan<float3> positions,
231 const MutableSpan<float> factors)
232{
233 SculptSession &ss = *object.sculpt;
234 const StrokeCache &cache = *ss.cache;
235 const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
236 const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
237
238 const Span<int> grids = node.grids();
239 const int grid_verts_num = grids.size() * key.grid_area;
240
241 gather_data_grids(subdiv_ccg, subdiv_ccg.positions.as_span(), grids, positions);
242
243 fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
244 filter_region_clip_factors(ss, positions, factors);
245 if (brush.flag & BRUSH_FRONTFACE) {
246 calc_front_face(cache.view_normal_symm, subdiv_ccg, grids, factors);
247 }
248
249 tls.distances.resize(grid_verts_num);
250 const MutableSpan<float> distances = tls.distances;
251 calc_brush_distances(ss, positions, eBrushFalloffShape(brush.falloff_shape), distances);
252 filter_distances_with_radius(cache.radius, distances, factors);
253 apply_hardness_to_distances(cache, distances);
254 calc_brush_strength_factors(cache, brush, distances, factors);
255
256 auto_mask::calc_grids_factors(depsgraph, object, cache.automasking.get(), node, grids, factors);
257
258 scale_factors(factors, strength);
259
260 calc_brush_texture_factors(ss, brush, positions, factors);
261
263 corner_verts,
264 vert_to_face_map,
265 face_sets,
266 subdiv_ccg,
267 relax_face_sets,
268 grids,
269 factors);
270}
271
272static void do_relax_face_sets_brush_grids(const Depsgraph &depsgraph,
273 const Sculpt &sd,
274 const Brush &brush,
275 Object &object,
276 const IndexMask &node_mask,
277 const float strength,
278 const bool relax_face_sets)
279{
280 const SculptSession &ss = *object.sculpt;
281 bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
283 SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
284 MutableSpan<float3> positions = subdiv_ccg.positions;
285 const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
286
287 Mesh &mesh = *static_cast<Mesh *>(object.data);
288 const OffsetIndices faces = mesh.faces();
289 const Span<int> corner_verts = mesh.corner_verts();
290 const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
291 const bke::AttributeAccessor attributes = mesh.attributes();
292 const VArraySpan hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
293 const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
294
295 Array<int> node_offset_data;
296 const OffsetIndices<int> node_vert_offsets = create_node_vert_offsets(
297 key, nodes, node_mask, node_offset_data);
298
299 Array<float3> current_positions(node_vert_offsets.total_size());
300 Array<float3> translations(node_vert_offsets.total_size());
301 Array<float> factors(node_vert_offsets.total_size());
302
304 node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) {
305 GridLocalData &tls = all_tls.local();
307 brush,
308 faces,
309 corner_verts,
310 vert_to_face_map,
311 face_sets,
312 nodes[i],
313 strength,
314 relax_face_sets,
315 object,
316 tls,
317 current_positions.as_mutable_span().slice(node_vert_offsets[pos]),
318 factors.as_mutable_span().slice(node_vert_offsets[pos]));
319 });
320
321 node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) {
322 GridLocalData &tls = all_tls.local();
324 subdiv_ccg,
325 faces,
326 corner_verts,
327 face_sets,
328 vert_to_face_map,
330 nodes[i].grids(),
331 relax_face_sets,
332 factors.as_span().slice(node_vert_offsets[pos]),
333 tls.vert_neighbors,
334 translations.as_mutable_span().slice(node_vert_offsets[pos]));
335 });
336
337 node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) {
339 nodes[i].grids(),
340 object,
341 current_positions.as_mutable_span().slice(node_vert_offsets[pos]),
342 translations.as_mutable_span().slice(node_vert_offsets[pos]));
343 bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
344 });
345 pbvh.tag_positions_changed(node_mask);
347}
348
349static void calc_factors_bmesh(const Depsgraph &depsgraph,
350 Object &object,
351 const Brush &brush,
352 const int face_set_offset,
354 const float strength,
355 const bool relax_face_sets,
356 BMeshLocalData &tls,
357 MutableSpan<float3> positions,
358 MutableSpan<float> factors)
359{
360 SculptSession &ss = *object.sculpt;
361 const StrokeCache &cache = *ss.cache;
362
364
365 gather_bmesh_positions(verts, positions);
366
368 filter_region_clip_factors(ss, positions, factors);
369 if (brush.flag & BRUSH_FRONTFACE) {
370 calc_front_face(cache.view_normal_symm, verts, factors);
371 }
372
373 tls.distances.resize(verts.size());
374 const MutableSpan<float> distances = tls.distances;
375 calc_brush_distances(ss, positions, eBrushFalloffShape(brush.falloff_shape), distances);
376 filter_distances_with_radius(cache.radius, distances, factors);
377 apply_hardness_to_distances(cache, distances);
378 calc_brush_strength_factors(cache, brush, distances, factors);
379
380 auto_mask::calc_vert_factors(depsgraph, object, cache.automasking.get(), node, verts, factors);
381
382 scale_factors(factors, strength);
383
384 calc_brush_texture_factors(ss, brush, positions, factors);
386 face_set_offset, relax_face_sets, verts, factors);
387}
388
389static void do_relax_face_sets_brush_bmesh(const Depsgraph &depsgraph,
390 const Sculpt &sd,
391 const Brush &brush,
392 Object &object,
393 const IndexMask &node_mask,
394 const float strength,
395 const bool relax_face_sets)
396{
397 bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
399 Array<int> node_offset_data;
400 const OffsetIndices<int> node_vert_offsets = create_node_vert_offsets_bmesh(
401 nodes, node_mask, node_offset_data);
402
403 const int face_set_offset = CustomData_get_offset_named(
404 &object.sculpt->bm->pdata, CD_PROP_INT32, ".sculpt_face_set");
405
406 Array<float3> current_positions(node_vert_offsets.total_size());
407 Array<float3> translations(node_vert_offsets.total_size());
408 Array<float> factors(node_vert_offsets.total_size());
409
411 node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) {
412 BMeshLocalData &tls = all_tls.local();
414 object,
415 brush,
416 face_set_offset,
417 nodes[i],
418 strength,
419 relax_face_sets,
420 tls,
421 current_positions.as_mutable_span().slice(node_vert_offsets[pos]),
422 factors.as_mutable_span().slice(node_vert_offsets[pos]));
423 });
424
425 node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) {
426 BMeshLocalData &tls = all_tls.local();
429 current_positions.as_mutable_span().slice(node_vert_offsets[pos]),
430 face_set_offset,
431 relax_face_sets,
432 factors.as_span().slice(node_vert_offsets[pos]),
433 tls.vert_neighbors,
434 translations.as_mutable_span().slice(node_vert_offsets[pos]));
435 });
436
437 node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) {
440 object,
441 translations.as_mutable_span().slice(node_vert_offsets[pos]),
442 current_positions.as_span().slice(node_vert_offsets[pos]));
444 });
445 pbvh.tag_positions_changed(node_mask);
447}
448
451/* -------------------------------------------------------------------- */
455 const Brush &brush,
456 const float strength,
457 const Object &object,
458 const MeshAttributeData &attribute_data,
459 const bke::pbvh::MeshNode &node,
460 MeshLocalData &tls,
461 const MutableSpan<float> factors)
462{
463 SculptSession &ss = *object.sculpt;
464 const StrokeCache &cache = *ss.cache;
465
466 const OrigPositionData orig_data = orig_position_data_get_mesh(object, node);
467 const Span<int> verts = node.verts();
468
469 fill_factor_from_hide_and_mask(attribute_data.hide_vert, attribute_data.mask, verts, factors);
470 filter_region_clip_factors(ss, orig_data.positions, factors);
471 if (brush.flag & BRUSH_FRONTFACE) {
472 calc_front_face(cache.view_normal_symm, orig_data.normals, factors);
473 }
474
475 tls.distances.resize(verts.size());
476 const MutableSpan<float> distances = tls.distances;
478 ss, orig_data.positions, eBrushFalloffShape(brush.falloff_shape), distances);
479 filter_distances_with_radius(cache.radius, distances, factors);
480 apply_hardness_to_distances(cache, distances);
481 calc_brush_strength_factors(cache, brush, distances, factors);
482
483 auto_mask::calc_vert_factors(depsgraph, object, cache.automasking.get(), node, verts, factors);
484
485 scale_factors(factors, strength);
486
487 calc_brush_texture_factors(ss, brush, orig_data.positions, factors);
488}
489
490static void do_topology_relax_brush_mesh(const Depsgraph &depsgraph,
491 const Sculpt &sd,
492 const Brush &brush,
493 Object &object,
494 const IndexMask &node_mask,
495 const float strength)
496{
497 const SculptSession &ss = *object.sculpt;
498 bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
500 Mesh &mesh = *static_cast<Mesh *>(object.data);
501 const OffsetIndices faces = mesh.faces();
502 const Span<int> corner_verts = mesh.corner_verts();
503 const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
504 const MeshAttributeData attribute_data(mesh.attributes());
505 const PositionDeformData position_data(depsgraph, object);
506 const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
507
508 Array<int> node_offset_data;
509 const OffsetIndices<int> node_vert_offsets = create_node_vert_offsets(
510 nodes, node_mask, node_offset_data);
511
512 Array<float3> translations(node_vert_offsets.total_size());
513 Array<float> factors(node_vert_offsets.total_size());
514
516 node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) {
517 MeshLocalData &tls = all_tls.local();
519 brush,
520 strength,
521 object,
522 attribute_data,
523 nodes[i],
524 tls,
525 factors.as_mutable_span().slice(node_vert_offsets[pos]));
526 });
527
528 node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) {
529 MeshLocalData &tls = all_tls.local();
531 position_data.eval,
532 vert_normals,
533 faces,
534 corner_verts,
535 vert_to_face_map,
537 attribute_data.face_sets,
538 attribute_data.hide_poly,
539 false,
540 nodes[i].verts(),
541 factors.as_span().slice(node_vert_offsets[pos]),
542 tls.vert_neighbors,
543 translations.as_mutable_span().slice(node_vert_offsets[pos]));
544 });
545
546 node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) {
548 nodes[i].verts(),
549 object,
550 translations.as_mutable_span().slice(node_vert_offsets[pos]),
551 position_data);
552 bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
553 });
554 pbvh.tag_positions_changed(node_mask);
556}
557
559 const Brush &brush,
560 const float strength,
561 const Object &object,
562 const bke::pbvh::GridsNode &node,
563 GridLocalData &tls,
564 const MutableSpan<float3> positions,
565 const MutableSpan<float> factors)
566{
567 const SculptSession &ss = *object.sculpt;
568 const StrokeCache &cache = *ss.cache;
569 const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
570 const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
571
572 const Span<int> grids = node.grids();
573 const int grid_verts_num = grids.size() * key.grid_area;
574
575 gather_data_grids(subdiv_ccg, subdiv_ccg.positions.as_span(), grids, positions);
576 const OrigPositionData orig_data = orig_position_data_get_grids(object, node);
577
578 fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
579 filter_region_clip_factors(ss, orig_data.positions, factors);
580 if (brush.flag & BRUSH_FRONTFACE) {
581 calc_front_face(cache.view_normal_symm, orig_data.normals, factors);
582 }
583
584 tls.distances.resize(grid_verts_num);
585 const MutableSpan<float> distances = tls.distances;
587 ss, orig_data.positions, eBrushFalloffShape(brush.falloff_shape), distances);
588 filter_distances_with_radius(cache.radius, distances, factors);
589 apply_hardness_to_distances(cache, distances);
590 calc_brush_strength_factors(cache, brush, distances, factors);
591
592 auto_mask::calc_grids_factors(depsgraph, object, cache.automasking.get(), node, grids, factors);
593
594 scale_factors(factors, strength);
595
596 calc_brush_texture_factors(ss, brush, orig_data.positions, factors);
597}
598
599static void do_topology_relax_brush_grids(const Depsgraph &depsgraph,
600 const Sculpt &sd,
601 const Brush &brush,
602 Object &object,
603 const IndexMask &node_mask,
604 const float strength)
605{
606 const SculptSession &ss = *object.sculpt;
607 bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
609 SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
610 MutableSpan<float3> positions = subdiv_ccg.positions;
611 const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
612
613 Mesh &mesh = *static_cast<Mesh *>(object.data);
614 const OffsetIndices faces = mesh.faces();
615 const Span<int> corner_verts = mesh.corner_verts();
616 const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
617 const bke::AttributeAccessor attributes = mesh.attributes();
618 const VArraySpan hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
619 const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
620
621 Array<int> node_offset_data;
622 const OffsetIndices<int> node_vert_offsets = create_node_vert_offsets(
623 key, nodes, node_mask, node_offset_data);
624
625 Array<float3> current_positions(node_vert_offsets.total_size());
626 Array<float3> translations(node_vert_offsets.total_size());
627 Array<float> factors(node_vert_offsets.total_size());
628
630 node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) {
631 GridLocalData &tls = all_tls.local();
633 depsgraph,
634 brush,
635 strength,
636 object,
637 nodes[i],
638 tls,
639 current_positions.as_mutable_span().slice(node_vert_offsets[pos]),
640 factors.as_mutable_span().slice(node_vert_offsets[pos]));
641 });
642
643 node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) {
644 GridLocalData &tls = all_tls.local();
646 subdiv_ccg,
647 faces,
648 corner_verts,
649 face_sets,
650 vert_to_face_map,
652 nodes[i].grids(),
653 false,
654 factors.as_span().slice(node_vert_offsets[pos]),
655 tls.vert_neighbors,
656 translations.as_mutable_span().slice(node_vert_offsets[pos]));
657 });
658
659 node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) {
661 nodes[i].grids(),
662 object,
663 current_positions.as_mutable_span().slice(node_vert_offsets[pos]),
664 translations.as_mutable_span().slice(node_vert_offsets[pos]));
665 bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
666 });
667 pbvh.tag_positions_changed(node_mask);
669}
670
671static void calc_topology_relax_factors_bmesh(const Depsgraph &depsgraph,
672 Object &object,
673 const Brush &brush,
675 const float strength,
676 BMeshLocalData &tls,
677 MutableSpan<float3> positions,
678 MutableSpan<float> factors)
679{
680 SculptSession &ss = *object.sculpt;
681 const StrokeCache &cache = *ss.cache;
682
684
685 Array<float3> orig_positions(verts.size());
686 Array<float3> orig_normals(verts.size());
687 orig_position_data_gather_bmesh(*ss.bm_log, verts, orig_positions, orig_normals);
688
689 gather_bmesh_positions(verts, positions);
690
692 filter_region_clip_factors(ss, orig_positions, factors);
693 if (brush.flag & BRUSH_FRONTFACE) {
694 calc_front_face(cache.view_normal_symm, orig_normals, factors);
695 }
696
697 tls.distances.resize(verts.size());
698 const MutableSpan<float> distances = tls.distances;
699 calc_brush_distances(ss, orig_positions, eBrushFalloffShape(brush.falloff_shape), distances);
700 filter_distances_with_radius(cache.radius, distances, factors);
701 apply_hardness_to_distances(cache, distances);
702 calc_brush_strength_factors(cache, brush, distances, factors);
703
704 auto_mask::calc_vert_factors(depsgraph, object, cache.automasking.get(), node, verts, factors);
705
706 scale_factors(factors, strength);
707
708 calc_brush_texture_factors(ss, brush, orig_positions, factors);
709}
710
711static void do_topology_relax_brush_bmesh(const Depsgraph &depsgraph,
712 const Sculpt &sd,
713 const Brush &brush,
714 Object &object,
715 const IndexMask &node_mask,
716 const float strength)
717{
718 bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
720 const int face_set_offset = CustomData_get_offset_named(
721 &object.sculpt->bm->pdata, CD_PROP_INT32, ".sculpt_face_set");
722
723 Array<int> node_offset_data;
724 const OffsetIndices<int> node_vert_offsets = create_node_vert_offsets_bmesh(
725 nodes, node_mask, node_offset_data);
726
727 Array<float3> current_positions(node_vert_offsets.total_size());
728 Array<float3> translations(node_vert_offsets.total_size());
729 Array<float> factors(node_vert_offsets.total_size());
730
732 node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) {
733 BMeshLocalData &tls = all_tls.local();
735 depsgraph,
736 object,
737 brush,
738 nodes[i],
739 strength,
740 tls,
741 current_positions.as_mutable_span().slice(node_vert_offsets[pos]),
742 factors.as_mutable_span().slice(node_vert_offsets[pos]));
743 });
744
745 node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) {
746 BMeshLocalData &tls = all_tls.local();
749 current_positions.as_mutable_span().slice(node_vert_offsets[pos]),
750 face_set_offset,
751 false,
752 factors.as_span().slice(node_vert_offsets[pos]),
753 tls.vert_neighbors,
754 translations.as_mutable_span().slice(node_vert_offsets[pos]));
755 });
756
757 node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) {
760 object,
761 translations.as_mutable_span().slice(node_vert_offsets[pos]),
762 current_positions.as_span().slice(node_vert_offsets[pos]));
764 });
765 pbvh.tag_positions_changed(node_mask);
767}
770} // namespace relax_cc
771
773 const Sculpt &sd,
774 Object &object,
775 const IndexMask &node_mask)
776{
777 const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
778
780
781 const SculptSession &ss = *object.sculpt;
782 const std::array<float, 4> strengths = iteration_strengths(ss.cache->bstrength,
784
785 /* On every third step of the stroke, behave more similarly to the Topology Relax brush */
786 const bool relax_face_sets = !(ss.cache->iteration_count % 3 == 0);
787
788 for (const float strength : strengths) {
789 switch (bke::object::pbvh_get(object)->type()) {
792 depsgraph, sd, brush, object, node_mask, strength * strength, relax_face_sets);
793 break;
796 depsgraph, sd, brush, object, node_mask, strength * strength, relax_face_sets);
797 break;
800 depsgraph, sd, brush, object, node_mask, strength * strength, relax_face_sets);
801 break;
802 }
803 }
804}
805
806void do_topology_relax_brush(const Depsgraph &depsgraph,
807 const Sculpt &sd,
808 Object &object,
809 const IndexMask &node_mask)
810{
811 const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
812 const SculptSession &ss = *object.sculpt;
813
815 return;
816 }
817
818 const float strength = ss.cache->bstrength;
819
821
822 for (int i = 0; i < 4; i++) {
823 switch (bke::object::pbvh_get(object)->type()) {
825 do_topology_relax_brush_mesh(depsgraph, sd, brush, object, node_mask, strength);
826 break;
828 do_topology_relax_brush_grids(depsgraph, sd, brush, object, node_mask, strength);
829 break;
831 do_topology_relax_brush_bmesh(depsgraph, sd, brush, object, node_mask, strength);
832 break;
833 }
834 }
835}
836} // namespace blender::ed::sculpt_paint
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
const Brush * BKE_paint_brush_for_read(const Paint *paint)
Definition paint.cc:654
const blender::Set< BMVert *, 0 > & BKE_pbvh_bmesh_node_unique_verts(blender::bke::pbvh::BMeshNode *node)
CCGKey BKE_subdiv_ccg_key_top_level(const SubdivCCG &subdiv_ccg)
#define BLI_NOINLINE
@ BRUSH_FRONTFACE
eBrushFalloffShape
@ CD_PROP_INT32
Span< T > as_span() const
Definition BLI_array.hh:232
MutableSpan< T > as_mutable_span()
Definition BLI_array.hh:237
constexpr int64_t size() const
Definition BLI_span.hh:253
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
void calc_grids_factors(const Depsgraph &depsgraph, const Object &object, const Cache &cache, const bke::pbvh::GridsNode &node, Span< int > grids, MutableSpan< float > factors)
void calc_vert_factors(const Depsgraph &depsgraph, const Object &object, const Cache &cache, const bke::pbvh::MeshNode &node, Span< int > verts, MutableSpan< float > factors)
void ensure_boundary_info(Object &object)
Definition sculpt.cc:5770
static BLI_NOINLINE void fill_factor_from_hide_and_mask(const Mesh &mesh, const Span< int > face_indices, const MutableSpan< float > r_factors)
void filter_verts_with_unique_face_sets_mesh(const GroupedSpan< int > vert_to_face_map, const Span< int > face_sets, const bool unique, const Span< int > verts, const MutableSpan< float > factors)
void filter_verts_with_unique_face_sets_bmesh(int face_set_offset, const bool unique, const Set< BMVert *, 0 > &verts, const MutableSpan< float > factors)
void filter_verts_with_unique_face_sets_grids(const OffsetIndices< int > faces, const Span< int > corner_verts, const GroupedSpan< int > vert_to_face_map, const Span< int > face_sets, const SubdivCCG &subdiv_ccg, const bool unique, const Span< int > grids, const MutableSpan< float > factors)
static std::array< float, 4 > iteration_strengths(const float strength, const int stroke_iteration)
Definition relax.cc:92
static void do_topology_relax_brush_grids(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, Object &object, const IndexMask &node_mask, const float strength)
Definition relax.cc:599
static BLI_NOINLINE void calc_factors_faces(const Depsgraph &depsgraph, const Brush &brush, const Span< float3 > positions_eval, const Span< float3 > vert_normals, const GroupedSpan< int > vert_to_face_map, const MeshAttributeData &attribute_data, const float strength, const bool relax_face_sets, const Object &object, const bke::pbvh::MeshNode &node, MeshLocalData &tls, const MutableSpan< float > factors)
Definition relax.cc:103
static void calc_factors_bmesh(const Depsgraph &depsgraph, Object &object, const Brush &brush, const int face_set_offset, bke::pbvh::BMeshNode &node, const float strength, const bool relax_face_sets, BMeshLocalData &tls, MutableSpan< float3 > positions, MutableSpan< float > factors)
Definition relax.cc:349
static void do_relax_face_sets_brush_grids(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, Object &object, const IndexMask &node_mask, const float strength, const bool relax_face_sets)
Definition relax.cc:272
static BLI_NOINLINE void calc_topology_relax_factors_faces(const Depsgraph &depsgraph, const Brush &brush, const float strength, const Object &object, const MeshAttributeData &attribute_data, const bke::pbvh::MeshNode &node, MeshLocalData &tls, const MutableSpan< float > factors)
Definition relax.cc:454
static void do_relax_face_sets_brush_bmesh(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, Object &object, const IndexMask &node_mask, const float strength, const bool relax_face_sets)
Definition relax.cc:389
static void apply_positions_grids(const Sculpt &sd, const Span< int > grids, Object &object, const Span< float3 > positions, const MutableSpan< float3 > translations)
Definition relax.cc:60
static void apply_positions_bmesh(const Sculpt &sd, const Set< BMVert *, 0 > verts, Object &object, const MutableSpan< float3 > translations, const Span< float3 > positions)
Definition relax.cc:73
static void do_topology_relax_brush_bmesh(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, Object &object, const IndexMask &node_mask, const float strength)
Definition relax.cc:711
static void calc_topology_relax_factors_bmesh(const Depsgraph &depsgraph, Object &object, const Brush &brush, bke::pbvh::BMeshNode &node, const float strength, BMeshLocalData &tls, MutableSpan< float3 > positions, MutableSpan< float > factors)
Definition relax.cc:671
static void do_relax_face_sets_brush_mesh(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, Object &object, const IndexMask &node_mask, const float strength, const bool relax_face_sets)
Definition relax.cc:145
static BLI_NOINLINE void calc_factors_grids(const Depsgraph &depsgraph, const Brush &brush, const OffsetIndices< int > faces, const Span< int > corner_verts, const GroupedSpan< int > vert_to_face_map, const Span< int > face_sets, const bke::pbvh::GridsNode &node, const float strength, const bool relax_face_sets, Object &object, GridLocalData &tls, const MutableSpan< float3 > positions, const MutableSpan< float > factors)
Definition relax.cc:219
static void apply_positions_faces(const Sculpt &sd, const Span< int > verts, Object &object, const MutableSpan< float3 > translations, const PositionDeformData &position_data)
Definition relax.cc:49
static void do_topology_relax_brush_mesh(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, Object &object, const IndexMask &node_mask, const float strength)
Definition relax.cc:490
static BLI_NOINLINE void calc_topology_relax_factors_grids(const Depsgraph &depsgraph, const Brush &brush, const float strength, const Object &object, const bke::pbvh::GridsNode &node, GridLocalData &tls, const MutableSpan< float3 > positions, const MutableSpan< float > factors)
Definition relax.cc:558
void calc_relaxed_translations_grids(const SubdivCCG &subdiv_ccg, const OffsetIndices< int > faces, const Span< int > corner_verts, const Span< int > face_sets, const GroupedSpan< int > vert_to_face_map, const BitSpan boundary_verts, const Span< int > grids, const bool filter_boundary_face_sets, const Span< float > factors, Vector< Vector< SubdivCCGCoord > > &neighbors, const MutableSpan< float3 > translations)
void calc_relaxed_translations_faces(const Span< float3 > vert_positions, const Span< float3 > vert_normals, const OffsetIndices< int > faces, const Span< int > corner_verts, const GroupedSpan< int > vert_to_face_map, const BitSpan boundary_verts, const Span< int > face_sets, const Span< bool > hide_poly, const bool filter_boundary_face_sets, const Span< int > verts, const Span< float > factors, Vector< Vector< int > > &neighbors, const MutableSpan< float3 > translations)
void calc_relaxed_translations_bmesh(const Set< BMVert *, 0 > &verts, const Span< float3 > positions, const int face_set_offset, const bool filter_boundary_face_sets, const Span< float > factors, Vector< Vector< BMVert * > > &neighbors, const MutableSpan< float3 > translations)
void gather_bmesh_positions(const Set< BMVert *, 0 > &verts, MutableSpan< float3 > positions)
Definition sculpt.cc:6054
void do_relax_face_sets_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
Definition relax.cc:772
void calc_brush_strength_factors(const StrokeCache &cache, const Brush &brush, Span< float > distances, MutableSpan< float > factors)
Definition sculpt.cc:6889
void gather_data_grids(const SubdivCCG &subdiv_ccg, Span< T > src, Span< int > grids, MutableSpan< T > node_data)
Definition sculpt.cc:6092
void apply_hardness_to_distances(float radius, float hardness, MutableSpan< float > distances)
Definition sculpt.cc:6862
void filter_distances_with_radius(float radius, Span< float > distances, MutableSpan< float > factors)
Definition sculpt.cc:6772
OffsetIndices< int > create_node_vert_offsets_bmesh(const Span< bke::pbvh::BMeshNode > nodes, const IndexMask &nodes_mask, Array< int > &node_data)
Definition sculpt.cc:7318
void filter_region_clip_factors(const SculptSession &ss, Span< float3 > vert_positions, Span< int > verts, MutableSpan< float > factors)
Definition sculpt.cc:6639
void calc_brush_distances(const SculptSession &ss, Span< float3 > vert_positions, Span< int > vert_indices, eBrushFalloffShape falloff_shape, MutableSpan< float > r_distances)
Definition sculpt.cc:6722
void orig_position_data_gather_bmesh(const BMLog &bm_log, const Set< BMVert *, 0 > &verts, MutableSpan< float3 > positions, MutableSpan< float3 > normals)
void do_topology_relax_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
Definition relax.cc:806
void scale_factors(MutableSpan< float > factors, float strength)
Definition sculpt.cc:7227
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
OrigPositionData orig_position_data_get_mesh(const Object &object, const bke::pbvh::MeshNode &node)
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:6581
OffsetIndices< int > create_node_vert_offsets(const Span< bke::pbvh::MeshNode > nodes, const IndexMask &nodes_mask, Array< int > &node_data)
Definition sculpt.cc:7296
void calc_brush_texture_factors(const SculptSession &ss, const Brush &brush, Span< float3 > vert_positions, Span< int > vert_indices, MutableSpan< float > factors)
Definition sculpt.cc:6898
bool SCULPT_stroke_is_first_brush_step_of_symmetry_pass(const blender::ed::sculpt_paint::StrokeCache &cache)
Definition sculpt.cc:513
char falloff_shape
int grid_area
Definition BKE_ccg.hh:35
blender::ed::sculpt_paint::StrokeCache * cache
Definition BKE_paint.hh:427
BMLog * bm_log
Definition BKE_paint.hh:402
SculptVertexInfo vertex_info
Definition BKE_paint.hh:458
SubdivCCG * subdiv_ccg
Definition BKE_paint.hh:405
blender::BitVector boundary
Definition BKE_paint.hh:351
blender::Array< blender::float3 > positions
std::unique_ptr< auto_mask::Cache > automasking
Vector< Vector< BMVert * > > vert_neighbors
Definition relax.cc:46
Vector< Vector< SubdivCCGCoord > > vert_neighbors
Definition relax.cc:40