Blender V4.5
sculpt_pose.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2020 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
10#include "BLI_math_geom.h"
11#include "BLI_math_matrix.h"
12#include "BLI_math_matrix.hh"
13#include "BLI_math_rotation.h"
14#include "BLI_math_vector.h"
15#include "BLI_math_vector.hh"
16
17#include "DNA_brush_types.h"
18#include "DNA_object_types.h"
19
20#include "BKE_brush.hh"
21#include "BKE_ccg.hh"
22#include "BKE_colortools.hh"
23#include "BKE_mesh.hh"
24#include "BKE_paint.hh"
25#include "BKE_paint_bvh.hh"
26
27#include "mesh_brush_common.hh"
28#include "paint_intern.hh"
29#include "sculpt_automask.hh"
30#include "sculpt_cloth.hh"
31#include "sculpt_face_set.hh"
32#include "sculpt_flood_fill.hh"
33#include "sculpt_hide.hh"
34#include "sculpt_intern.hh"
35#include "sculpt_pose.hh"
36#include "sculpt_smooth.hh"
37
38#include "bmesh.hh"
39
40#include <cmath>
41#include <cstdlib>
42
44
45static void solve_ik_chain(IKChain &ik_chain, const float3 &initial_target, const bool use_anchor)
46{
47 MutableSpan<IKChainSegment> segments = ik_chain.segments;
48
49 /* Set the initial target. */
50 float3 target = initial_target;
51
52 /* Solve the positions and rotations of all segments in the chain. */
53 for (const int i : segments.index_range()) {
54 /* Calculate the rotation to orientate the segment to the target from its initial state. */
55 float3 current_orientation = math::normalize(target - segments[i].orig);
56 float3 initial_orientation = math::normalize(segments[i].initial_head -
57 segments[i].initial_orig);
58 rotation_between_vecs_to_quat(segments[i].rot, initial_orientation, current_orientation);
59
60 /* Rotate the segment by calculating a new head position. */
61 float3 current_head_position = segments[i].orig + current_orientation * segments[i].len;
62
63 /* Move the origin of the segment towards the target. */
64 float3 current_origin_position = target - current_head_position;
65
66 /* Store the new head and origin positions to the segment. */
67 segments[i].head = current_head_position;
68 segments[i].orig += current_origin_position;
69
70 /* Use the origin of this segment as target for the next segment in the chain. */
71 target = segments[i].orig;
72 }
73
74 /* Move back the whole chain to preserve the anchor point. */
75 if (use_anchor) {
76 float3 anchor_diff = segments.last().initial_orig - segments.last().orig;
77 for (const int i : segments.index_range()) {
78 segments[i].orig += anchor_diff;
79 segments[i].head += anchor_diff;
80 }
81 }
82}
83
84static void solve_roll_chain(IKChain &ik_chain, const Brush &brush, const float roll)
85{
86 MutableSpan<IKChainSegment> segments = ik_chain.segments;
87
88 for (const int i : segments.index_range()) {
89 float3 initial_orientation = math::normalize(segments[i].initial_head -
90 segments[i].initial_orig);
91 float initial_rotation[4];
92 float current_rotation[4];
93
94 /* Calculate the current roll angle using the brush curve. */
95 float current_roll = roll * BKE_brush_curve_strength(&brush, i, segments.size());
96
97 axis_angle_normalized_to_quat(initial_rotation, initial_orientation, 0.0f);
98 axis_angle_normalized_to_quat(current_rotation, initial_orientation, current_roll);
99
100 /* Store the difference of the rotations in the segment rotation. */
101 rotation_between_quats_to_quat(segments[i].rot, current_rotation, initial_rotation);
102 }
103}
104
105static void solve_translate_chain(IKChain &ik_chain, const float delta[3])
106{
107 for (IKChainSegment &segment : ik_chain.segments) {
108 /* Move the origin and head of each segment by delta. */
109 add_v3_v3v3(segment.head, segment.initial_head, delta);
110 add_v3_v3v3(segment.orig, segment.initial_orig, delta);
111
112 /* Reset the segment rotation. */
113 unit_qt(segment.rot);
114 }
115}
116
117static void solve_scale_chain(IKChain &ik_chain, const float scale[3])
118{
119 for (IKChainSegment &segment : ik_chain.segments) {
120 /* Assign the scale to each segment. */
121 copy_v3_v3(segment.scale, scale);
122 }
123}
124
132
134 const IKChainSegment &segment,
135 const MutableSpan<float3> translations)
136{
137 BLI_assert(positions.size() == translations.size());
138 for (const int i : positions.index_range()) {
139 float3 position = positions[i];
140 const ePaintSymmetryAreas symm_area = SCULPT_get_vertex_symm_area(position);
141 position = math::transform_point(segment.pivot_mat_inv[int(symm_area)], position);
142 position = math::transform_point(segment.trans_mat[int(symm_area)], position);
143 position = math::transform_point(segment.pivot_mat[int(symm_area)], position);
144 translations[i] = position - positions[i];
145 }
146}
147
149{
150 BLI_assert(a.size() == b.size());
151 for (const int i : a.index_range()) {
152 a[i] += b[i];
153 }
154}
155
156static void calc_mesh(const Depsgraph &depsgraph,
157 const Sculpt &sd,
158 const Brush &brush,
159 const MeshAttributeData &attribute_data,
160 const bke::pbvh::MeshNode &node,
161 Object &object,
162 BrushLocalData &tls,
163 const PositionDeformData &position_data)
164{
165 SculptSession &ss = *object.sculpt;
166 const StrokeCache &cache = *ss.cache;
167
168 const Span<int> verts = node.verts();
169 const Span<float3> positions = gather_data_mesh(position_data.eval, verts, tls.positions);
170 const OrigPositionData orig_data = orig_position_data_get_mesh(object, node);
171
172 tls.factors.resize(verts.size());
173 const MutableSpan<float> factors = tls.factors;
174 fill_factor_from_hide_and_mask(attribute_data.hide_vert, attribute_data.mask, verts, factors);
175 auto_mask::calc_vert_factors(depsgraph, object, cache.automasking.get(), node, verts, factors);
176
177 tls.translations.resize(verts.size());
178 const MutableSpan<float3> translations = tls.translations;
179 translations.fill(float3(0));
180
181 tls.segment_weights.resize(verts.size());
182 tls.segment_translations.resize(verts.size());
183 const MutableSpan<float> segment_weights = tls.segment_weights;
184 const MutableSpan<float3> segment_translations = tls.segment_translations;
185
186 for (const IKChainSegment &segment : cache.pose_ik_chain->segments) {
187 calc_segment_translations(orig_data.positions, segment, segment_translations);
188 gather_data_mesh(segment.weights.as_span(), verts, segment_weights);
189 scale_translations(segment_translations, segment_weights);
190 add_arrays(translations, segment_translations);
191 }
192 scale_translations(translations, factors);
193
194 switch (eBrushDeformTarget(brush.deform_target)) {
196 reset_translations_to_original(translations, positions, orig_data.positions);
197 clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
198 position_data.deform(translations, verts);
199 break;
201 add_arrays(translations, orig_data.positions);
203 translations.as_span(), verts, cache.cloth_sim->deformation_pos.as_mutable_span());
204 break;
205 }
206}
207
208static void calc_grids(const Depsgraph &depsgraph,
209 const Sculpt &sd,
210 const Brush &brush,
211 const bke::pbvh::GridsNode &node,
212 Object &object,
213 BrushLocalData &tls)
214{
215 SculptSession &ss = *object.sculpt;
216 const StrokeCache &cache = *ss.cache;
217 SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
218
219 const Span<int> grids = node.grids();
220 const Span<float3> positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
221 const OrigPositionData orig_data = orig_position_data_get_grids(object, node);
222
223 tls.factors.resize(positions.size());
224 const MutableSpan<float> factors = tls.factors;
225 fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
226 auto_mask::calc_grids_factors(depsgraph, object, cache.automasking.get(), node, grids, factors);
227
228 tls.translations.resize(positions.size());
229 const MutableSpan<float3> translations = tls.translations;
230 translations.fill(float3(0));
231
232 tls.segment_weights.resize(positions.size());
233 tls.segment_translations.resize(positions.size());
234 const MutableSpan<float> segment_weights = tls.segment_weights;
235 const MutableSpan<float3> segment_translations = tls.segment_translations;
236
237 for (const IKChainSegment &segment : cache.pose_ik_chain->segments) {
238 calc_segment_translations(orig_data.positions, segment, segment_translations);
239 gather_data_grids(subdiv_ccg, segment.weights.as_span(), grids, segment_weights);
240 scale_translations(segment_translations, segment_weights);
241 add_arrays(translations, segment_translations);
242 }
243 scale_translations(translations, factors);
244
245 switch (eBrushDeformTarget(brush.deform_target)) {
247 reset_translations_to_original(translations, positions, orig_data.positions);
248 clip_and_lock_translations(sd, ss, orig_data.positions, translations);
249 apply_translations(translations, grids, subdiv_ccg);
250 break;
252 add_arrays(translations, orig_data.positions);
253 scatter_data_grids(subdiv_ccg,
254 translations.as_span(),
255 grids,
256 cache.cloth_sim->deformation_pos.as_mutable_span());
257 break;
258 }
259}
260
261static void calc_bmesh(const Depsgraph &depsgraph,
262 const Sculpt &sd,
263 const Brush &brush,
265 Object &object,
266 BrushLocalData &tls)
267{
268 SculptSession &ss = *object.sculpt;
269 const StrokeCache &cache = *ss.cache;
270
272 const Span<float3> positions = gather_bmesh_positions(verts, tls.positions);
273 Array<float3> orig_positions(verts.size());
274 Array<float3> orig_normals(verts.size());
275 orig_position_data_gather_bmesh(*ss.bm_log, verts, orig_positions, orig_normals);
276
277 tls.factors.resize(verts.size());
278 const MutableSpan<float> factors = tls.factors;
280 auto_mask::calc_vert_factors(depsgraph, object, cache.automasking.get(), node, verts, factors);
281
282 tls.translations.resize(verts.size());
283 const MutableSpan<float3> translations = tls.translations;
284 translations.fill(float3(0));
285
286 tls.segment_weights.resize(verts.size());
287 tls.segment_translations.resize(verts.size());
288 const MutableSpan<float> segment_weights = tls.segment_weights;
289 const MutableSpan<float3> segment_translations = tls.segment_translations;
290
291 for (const IKChainSegment &segment : cache.pose_ik_chain->segments) {
292 calc_segment_translations(orig_positions, segment, segment_translations);
293 gather_data_bmesh(segment.weights.as_span(), verts, segment_weights);
294 scale_translations(segment_translations, segment_weights);
295 add_arrays(translations, segment_translations);
296 }
297 scale_translations(translations, factors);
298
299 switch (eBrushDeformTarget(brush.deform_target)) {
301 reset_translations_to_original(translations, positions, orig_positions);
302 clip_and_lock_translations(sd, ss, orig_positions, translations);
303 apply_translations(translations, verts);
304 break;
306 add_arrays(translations, orig_positions);
308 translations.as_span(), verts, cache.cloth_sim->deformation_pos.as_mutable_span());
309 break;
310 }
311}
312
317 {
318 PoseGrowFactorData joined;
319 joined.pos_avg = a.pos_avg + b.pos_avg;
320 joined.pos_count = a.pos_count + b.pos_count;
321 return joined;
322 }
323};
324
331
332BLI_NOINLINE static void add_fake_neighbors(const Span<int> fake_neighbors,
333 const Span<int> verts,
334 const Span<int> orig_neighbor_data,
335 MutableSpan<int> neighbor_offsets,
336 Vector<int> &neighbor_data_with_fake)
337{
338 const OffsetIndices<int> offsets(neighbor_offsets);
339 for (const int i : verts.index_range()) {
340 const Span<int> orig_neighbors = orig_neighbor_data.slice(offsets[i]);
341
342 /* Modify the offsets in-place after using them to slice the current neighbor data. */
343 neighbor_offsets[i] = neighbor_data_with_fake.size();
344 neighbor_data_with_fake.extend(orig_neighbors);
345 const int neighbor = fake_neighbors[verts[i]];
346 if (neighbor != FAKE_NEIGHBOR_NONE) {
347 neighbor_data_with_fake.append(neighbor);
348 }
349 }
350 neighbor_offsets.last() = neighbor_data_with_fake.size();
351}
352
354 const float3 &pose_initial_position,
355 const Span<float3> vert_positions,
357 const Span<int> corner_verts,
358 const GroupedSpan<int> vert_to_face_map,
359 const Span<bool> hide_vert,
360 const Span<bool> hide_poly,
361 const Span<int> fake_neighbors,
362 const Span<float> prev_mask,
363 const bke::pbvh::MeshNode &node,
365 const MutableSpan<float> pose_factor,
366 PoseGrowFactorData &gftd)
367{
368 const Span<int> verts = hide::node_visible_verts(node, hide_vert, tls.vert_indices);
369
371 corner_verts,
372 vert_to_face_map,
373 hide_poly,
374 verts,
376 tls.neighbor_data);
377 if (!fake_neighbors.is_empty()) {
378 add_fake_neighbors(fake_neighbors,
379 verts,
380 tls.neighbor_data,
383 }
384 const GroupedSpan<int> neighbors(tls.neighbor_offsets.as_span(),
385 fake_neighbors.is_empty() ?
386 tls.neighbor_data.as_span() :
388
389 for (const int i : verts.index_range()) {
390 const int vert = verts[i];
391
392 float max = 0.0f;
393 for (const int neighbor : neighbors[i]) {
394 max = std::max(max, prev_mask[neighbor]);
395 }
396
397 if (max > prev_mask[vert]) {
398 const float3 &position = vert_positions[verts[i]];
399 pose_factor[vert] = max;
400 if (SCULPT_check_vertex_pivot_symmetry(position, pose_initial_position, symm)) {
401 gftd.pos_avg += position;
402 gftd.pos_count++;
403 }
404 }
405 }
406}
407
409 const float3 &pose_initial_position,
410 const SubdivCCG &subdiv_ccg,
411 const Span<int> fake_neighbors,
412 const Span<float> prev_mask,
413 const bke::pbvh::GridsNode &node,
414 const MutableSpan<float> pose_factor,
415 PoseGrowFactorData &gftd)
416{
417 const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
418 const Span<float3> positions = subdiv_ccg.positions;
419 const BitGroupVector<> &grid_hidden = subdiv_ccg.grid_hidden;
420 const Span<int> grids = node.grids();
421
422 for (const int i : grids.index_range()) {
423 const int grid = grids[i];
424 const IndexRange grid_range = bke::ccg::grid_range(key, grid);
425 for (const short y : IndexRange(key.grid_size)) {
426 for (const short x : IndexRange(key.grid_size)) {
427 const int offset = CCG_grid_xy_to_index(key.grid_size, x, y);
428 if (!grid_hidden.is_empty() && grid_hidden[grid][offset]) {
429 continue;
430 }
431 const int vert = grid_range[offset];
432
433 SubdivCCGNeighbors neighbors;
435 subdiv_ccg, SubdivCCGCoord{grid, x, y}, false, neighbors);
436
437 float max = 0.0f;
438 for (const SubdivCCGCoord neighbor : neighbors.coords) {
439 max = std::max(max, prev_mask[neighbor.to_index(key)]);
440 }
441 if (!fake_neighbors.is_empty()) {
442 if (fake_neighbors[vert] != FAKE_NEIGHBOR_NONE) {
443 max = std::max(max, prev_mask[fake_neighbors[vert]]);
444 }
445 }
446
447 if (max > prev_mask[vert]) {
448 const float3 &position = positions[vert];
449 pose_factor[vert] = max;
450 if (SCULPT_check_vertex_pivot_symmetry(position, pose_initial_position, symm)) {
451 gftd.pos_avg += position;
452 gftd.pos_count++;
453 }
454 }
455 }
456 }
457 }
458}
459
461 const float3 &pose_initial_position,
462 const Span<int> fake_neighbors,
463 const Span<float> prev_mask,
465 const MutableSpan<float> pose_factor,
466 PoseGrowFactorData &gftd)
467{
469
470 BMeshNeighborVerts neighbors;
471
472 for (BMVert *bm_vert : verts) {
473 const int vert = BM_elem_index_get(bm_vert);
474
475 float max = 0.0f;
476 for (const BMVert *neighbor : vert_neighbors_get_bmesh(*bm_vert, neighbors)) {
477 max = std::max(max, prev_mask[BM_elem_index_get(neighbor)]);
478 }
479 if (!fake_neighbors.is_empty()) {
480 if (fake_neighbors[vert] != FAKE_NEIGHBOR_NONE) {
481 max = std::max(max, prev_mask[fake_neighbors[vert]]);
482 }
483 }
484
485 if (max > prev_mask[vert]) {
486 const float3 position = bm_vert->co;
487 pose_factor[vert] = max;
488 if (SCULPT_check_vertex_pivot_symmetry(position, pose_initial_position, symm)) {
489 gftd.pos_avg += position;
490 gftd.pos_count++;
491 }
492 }
493 }
494}
495
496/* Grow the factor until its boundary is near to the offset pose origin or outside the target
497 * distance. */
498static void grow_pose_factor(const Depsgraph &depsgraph,
499 Object &ob,
500 SculptSession &ss,
501 float pose_origin[3],
502 float pose_target[3],
503 float max_len,
504 float *r_pose_origin,
505 MutableSpan<float> pose_factor)
506{
509
510 IndexMaskMemory memory;
511 const IndexMask node_mask = bke::pbvh::all_leaf_nodes(pbvh, memory);
512 const Span<int> fake_neighbors = ss.fake_neighbors.fake_neighbor_index;
513
514 bool grow_next_iteration = true;
515 float prev_len = FLT_MAX;
517 while (grow_next_iteration) {
518 prev_mask.as_mutable_span().copy_from(pose_factor);
519
522 switch (pbvh.type()) {
525 const Mesh &mesh = *static_cast<const Mesh *>(ob.data);
526 const Span<float3> vert_positions = bke::pbvh::vert_positions_eval(depsgraph, ob);
527 const OffsetIndices faces = mesh.faces();
528 const Span<int> corner_verts = mesh.corner_verts();
529 const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
530 const bke::AttributeAccessor attributes = mesh.attributes();
531 const VArraySpan<bool> hide_vert = *attributes.lookup<bool>(".hide_vert",
533 const VArraySpan<bool> hide_poly = *attributes.lookup<bool>(".hide_poly",
536 node_mask.index_range(),
537 1,
539 [&](const IndexRange range, PoseGrowFactorData gftd) {
540 GrowFactorLocalData &tls = all_tls.local();
541 node_mask.slice(range).foreach_index([&](const int i) {
542 grow_factors_mesh(symm,
543 pose_target,
544 vert_positions,
545 faces,
546 corner_verts,
547 vert_to_face_map,
548 hide_vert,
549 hide_poly,
550 fake_neighbors,
551 prev_mask,
552 nodes[i],
553 tls,
554 pose_factor,
555 gftd);
556 });
557 return gftd;
558 },
560 break;
561 }
564 const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
566 node_mask.index_range(),
567 1,
569 [&](const IndexRange range, PoseGrowFactorData gftd) {
570 node_mask.slice(range).foreach_index([&](const int i) {
571 grow_factors_grids(symm,
572 pose_target,
573 subdiv_ccg,
574 fake_neighbors,
575 prev_mask,
576 nodes[i],
577 pose_factor,
578 gftd);
579 });
580 return gftd;
581 },
583 break;
584 }
588 node_mask.index_range(),
589 1,
591 [&](const IndexRange range, PoseGrowFactorData gftd) {
592 node_mask.slice(range).foreach_index([&](const int i) {
593 grow_factors_bmesh(
594 symm, pose_target, fake_neighbors, prev_mask, nodes[i], pose_factor, gftd);
595 });
596 return gftd;
597 },
599 break;
600 }
601 }
602
603 if (gftd.pos_count != 0) {
604 gftd.pos_avg /= float(gftd.pos_count);
605 if (pose_origin) {
606 /* Test with pose origin. Used when growing the factors to compensate the Origin Offset. */
607 /* Stop when the factor's avg_pos starts moving away from the origin instead of getting
608 * closer to it. */
609 float len = math::distance(gftd.pos_avg, float3(pose_origin));
610 if (len < prev_len) {
611 prev_len = len;
612 grow_next_iteration = true;
613 }
614 else {
615 grow_next_iteration = false;
616 pose_factor.copy_from(prev_mask);
617 }
618 }
619 else {
620 /* Test with length. Used to calculate the origin positions of the IK chain. */
621 /* Stops when the factors have grown enough to generate a new segment origin. */
622 float len = math::distance(gftd.pos_avg, float3(pose_target));
623 if (len < max_len) {
624 prev_len = len;
625 grow_next_iteration = true;
626 }
627 else {
628 grow_next_iteration = false;
629 if (r_pose_origin) {
630 copy_v3_v3(r_pose_origin, gftd.pos_avg);
631 }
632 pose_factor.copy_from(prev_mask);
633 }
634 }
635 }
636 else {
637 if (r_pose_origin) {
638 copy_v3_v3(r_pose_origin, pose_target);
639 }
640 grow_next_iteration = false;
641 }
642 }
643}
644
645static bool vert_inside_brush_radius(const float3 &vertex,
646 const float3 &br_co,
647 float radius,
648 char symm)
649{
650 for (char i = 0; i <= symm; ++i) {
651 if (is_symmetry_iteration_valid(i, symm)) {
652 const float3 location = symmetry_flip(br_co, ePaintSymmetryFlags(i));
653 if (math::distance(location, vertex) < radius) {
654 return true;
655 }
656 }
657 }
658 return false;
659}
660
665static void calc_pose_origin_and_factor_mesh(const Depsgraph &depsgraph,
666 Object &object,
667 SculptSession &ss,
668 const float3 &initial_location,
669 float radius,
670 float3 &r_pose_origin,
671 MutableSpan<float> r_pose_factor)
672{
673 BLI_assert(!r_pose_factor.is_empty());
674
675 const Mesh &mesh = *static_cast<const Mesh *>(object.data);
676 const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
677 const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
678
679 /* Calculate the pose rotation point based on the boundaries of the brush factor. */
681 flood.add_initial(find_symm_verts_mesh(depsgraph, object, ss.active_vert_index(), radius));
682
683 const int symm = SCULPT_mesh_symmetry_xyz_get(object);
684
685 int tot_co = 0;
686 float3 pose_origin(0);
687 float3 fallback_floodfill_origin = initial_location;
688 flood.execute(object, vert_to_face_map, [&](int /*from_v*/, int to_v) {
689 r_pose_factor[to_v] = 1.0f;
690
691 const float3 co = positions_eval[to_v];
692 if (math::distance_squared(initial_location, fallback_floodfill_origin) <
693 math::distance_squared(initial_location, co))
694 {
695 fallback_floodfill_origin = co;
696 }
697
698 if (vert_inside_brush_radius(co, initial_location, radius, symm)) {
699 return true;
700 }
701
702 if (SCULPT_check_vertex_pivot_symmetry(co, initial_location, symm)) {
703 pose_origin += co;
704 tot_co++;
705 }
706
707 return false;
708 });
709
710 if (tot_co > 0) {
711 r_pose_origin = pose_origin / float(tot_co);
712 }
713 else {
714 r_pose_origin = fallback_floodfill_origin;
715 }
716}
717
719 SculptSession &ss,
720 const float3 &initial_location,
721 float radius,
722 float3 &r_pose_origin,
723 MutableSpan<float> r_pose_factor)
724{
725 BLI_assert(!r_pose_factor.is_empty());
726
727 const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
728
729 const Span<float3> positions = subdiv_ccg.positions;
730 const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
731 /* Calculate the pose rotation point based on the boundaries of the brush factor. */
733 flood.add_initial(key, find_symm_verts_grids(object, ss.active_vert_index(), radius));
734
735 const int symm = SCULPT_mesh_symmetry_xyz_get(object);
736
737 int tot_co = 0;
738 float3 pose_origin(0);
739 float3 fallback_floodfill_origin = initial_location;
740 flood.execute(
741 object, subdiv_ccg, [&](SubdivCCGCoord /*from_v*/, SubdivCCGCoord to_v, bool is_duplicate) {
742 const int to_v_i = to_v.to_index(key);
743
744 r_pose_factor[to_v_i] = 1.0f;
745
746 const float3 &co = positions[to_v_i];
747 if (math::distance_squared(initial_location, fallback_floodfill_origin) <
748 math::distance_squared(initial_location, co))
749 {
750 fallback_floodfill_origin = co;
751 }
752
753 if (vert_inside_brush_radius(co, initial_location, radius, symm)) {
754 return true;
755 }
756
757 if (SCULPT_check_vertex_pivot_symmetry(co, initial_location, symm)) {
758 if (!is_duplicate) {
759 pose_origin += co;
760 tot_co++;
761 }
762 }
763
764 return false;
765 });
766
767 if (tot_co > 0) {
768 r_pose_origin = pose_origin / float(tot_co);
769 }
770 else {
771 r_pose_origin = fallback_floodfill_origin;
772 }
773}
774
776 SculptSession &ss,
777 const float3 &initial_location,
778 float radius,
779 float3 &r_pose_origin,
780 MutableSpan<float> r_pose_factor)
781{
782 BLI_assert(!r_pose_factor.is_empty());
784
785 /* Calculate the pose rotation point based on the boundaries of the brush factor. */
788 flood.add_initial(*ss.bm, find_symm_verts_bmesh(object, ss.active_vert_index(), radius));
789
790 const int symm = SCULPT_mesh_symmetry_xyz_get(object);
791
792 int tot_co = 0;
793 float3 pose_origin(0);
794 float3 fallback_floodfill_origin = initial_location;
795 flood.execute(object, [&](BMVert * /*from_v*/, BMVert *to_v) {
796 const int to_v_i = BM_elem_index_get(to_v);
797 r_pose_factor[to_v_i] = 1.0f;
798
799 const float3 co = to_v->co;
800 if (math::distance_squared(initial_location, fallback_floodfill_origin) <
801 math::distance_squared(initial_location, co))
802 {
803 fallback_floodfill_origin = co;
804 }
805
806 if (vert_inside_brush_radius(co, initial_location, radius, symm)) {
807 return true;
808 }
809
810 if (SCULPT_check_vertex_pivot_symmetry(co, initial_location, symm)) {
811 pose_origin += co;
812 tot_co++;
813 }
814
815 return false;
816 });
817
818 if (tot_co > 0) {
819 r_pose_origin = pose_origin / float(tot_co);
820 }
821 else {
822 r_pose_origin = fallback_floodfill_origin;
823 }
824}
825
826static void calc_pose_data(const Depsgraph &depsgraph,
827 Object &object,
828 SculptSession &ss,
829 const float3 &initial_location,
830 float radius,
831 float pose_offset,
832 float3 &r_pose_origin,
833 MutableSpan<float> r_pose_factor)
834{
835 BLI_assert(!r_pose_factor.is_empty());
836
837 float3 pose_origin;
838 switch (bke::object::pbvh_get(object)->type()) {
841 depsgraph, object, ss, initial_location, radius, pose_origin, r_pose_factor);
842 break;
845 object, ss, initial_location, radius, pose_origin, r_pose_factor);
846 break;
849 object, ss, initial_location, radius, pose_origin, r_pose_factor);
850 break;
851 }
852
853 /* Offset the pose origin. */
854 const float3 pose_dir = math::normalize(pose_origin - initial_location);
855 pose_origin += pose_dir * radius * pose_offset;
856 r_pose_origin = pose_origin;
857
858 /* Do the initial grow of the factors to get the first segment of the chain with Origin Offset.
859 */
860 if (pose_offset != 0.0f) {
861 grow_pose_factor(depsgraph, object, ss, pose_origin, pose_origin, 0, nullptr, r_pose_factor);
862 }
863}
864
865/* Init the IK chain with empty weights. */
866static std::unique_ptr<IKChain> ik_chain_new(const int totsegments, const int totverts)
867{
868 std::unique_ptr<IKChain> ik_chain = std::make_unique<IKChain>();
869 ik_chain->segments.reinitialize(totsegments);
870 for (IKChainSegment &segment : ik_chain->segments) {
871 segment.weights = Array<float>(totverts, 0.0f);
872 }
873 return ik_chain;
874}
875
876/* Init the origin/head pairs of all the segments from the calculated origins. */
877static void ik_chain_origin_heads_init(IKChain &ik_chain, const float3 &initial_location)
878{
879 float3 origin;
880 float3 head;
881 for (const int i : ik_chain.segments.index_range()) {
882 if (i == 0) {
883 head = initial_location;
884 origin = ik_chain.segments[i].orig;
885 }
886 else {
887 head = ik_chain.segments[i - 1].orig;
888 origin = ik_chain.segments[i].orig;
889 }
890 ik_chain.segments[i].orig = origin;
891 ik_chain.segments[i].initial_orig = origin;
892 ik_chain.segments[i].head = head;
893 ik_chain.segments[i].initial_head = head;
894 ik_chain.segments[i].len = math::distance(head, origin);
895 ik_chain.segments[i].scale = float3(1.0f);
896 }
897}
898
899static int brush_num_effective_segments(const Brush &brush)
900{
901 /* Scaling multiple segments at the same time is not supported as the IK solver can't handle
902 * changes in the segment's length. It will also required a better weight distribution to avoid
903 * artifacts in the areas affected by multiple segments. */
904 if (ELEM(brush.pose_deform_type,
907 {
908 return 1;
909 }
910 return brush.pose_ik_segments;
911}
912
913static std::unique_ptr<IKChain> ik_chain_init_topology(const Depsgraph &depsgraph,
914 Object &object,
915 SculptSession &ss,
916 const Brush &brush,
917 const float3 &initial_location,
918 const float radius)
919{
920
921 const float chain_segment_len = radius * (1.0f + brush.pose_offset);
922
923 const int totvert = SCULPT_vertex_count_get(object);
924 const bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
925
926 int nearest_vertex_index = -1;
927 /* TODO: How should this function handle not being able to find the nearest vert? */
928 switch (pbvh.type()) {
930 const Mesh &mesh = *static_cast<const Mesh *>(object.data);
931 const Span<float3> vert_positions = bke::pbvh::vert_positions_eval(depsgraph, object);
932 const bke::AttributeAccessor attributes = mesh.attributes();
933 VArraySpan<bool> hide_vert = *attributes.lookup<bool>(".hide_vert", bke::AttrDomain::Point);
934 std::optional<int> nearest = nearest_vert_calc_mesh(pbvh,
935 vert_positions,
936 hide_vert,
937 initial_location,
938 std::numeric_limits<float>::max(),
939 true);
940 nearest_vertex_index = *nearest;
941 break;
942 }
944 const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
945 const std::optional<SubdivCCGCoord> nearest = nearest_vert_calc_grids(
946 pbvh, subdiv_ccg, initial_location, std::numeric_limits<float>::max(), true);
947 const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
948 nearest_vertex_index = nearest->to_index(key);
949 break;
950 }
952 const std::optional<BMVert *> nearest = nearest_vert_calc_bmesh(
953 pbvh, initial_location, std::numeric_limits<float>::max(), false);
954 nearest_vertex_index = BM_elem_index_get(*nearest);
955 break;
956 }
957 }
958
959 /* Init the buffers used to keep track of the changes in the pose factors as more segments are
960 * added to the IK chain. */
961
962 /* This stores the whole pose factors values as they grow through the mesh. */
963 Array<float> pose_factor_grow(totvert, 0.0f);
964
965 /* This stores the previous status of the factors when growing a new iteration. */
966 Array<float> pose_factor_grow_prev(totvert, 0.0f);
967
968 pose_factor_grow[nearest_vertex_index] = 1.0f;
969
970 const int tot_segments = brush_num_effective_segments(brush);
971 std::unique_ptr<IKChain> ik_chain = ik_chain_new(tot_segments, totvert);
972
973 /* Calculate the first segment in the chain using the brush radius and the pose origin offset. */
975 object,
976 ss,
977 initial_location,
978 radius,
979 brush.pose_offset,
980 ik_chain->segments[0].orig,
981 pose_factor_grow);
982
983 float3 next_chain_segment_target = ik_chain->segments[0].orig;
984
985 /* Init the weights of this segment and store the status of the pose factors to start calculating
986 * new segment origins. */
987 for (int j = 0; j < totvert; j++) {
988 ik_chain->segments[0].weights[j] = pose_factor_grow[j];
989 pose_factor_grow_prev[j] = pose_factor_grow[j];
990 }
991
992 /* Calculate the next segments in the chain growing the pose factors. */
993 for (const int i : ik_chain->segments.index_range().drop_front(1)) {
994
995 /* Grow the factors to get the new segment origin. */
997 object,
998 ss,
999 nullptr,
1000 next_chain_segment_target,
1001 chain_segment_len,
1002 ik_chain->segments[i].orig,
1003 pose_factor_grow);
1004 next_chain_segment_target = ik_chain->segments[i].orig;
1005
1006 /* Create the weights for this segment from the difference between the previous grow factor
1007 * iteration an the current iteration. */
1008 for (int j = 0; j < totvert; j++) {
1009 ik_chain->segments[i].weights[j] = pose_factor_grow[j] - pose_factor_grow_prev[j];
1010 /* Store the current grow factor status for the next iteration. */
1011 pose_factor_grow_prev[j] = pose_factor_grow[j];
1012 }
1013 }
1014
1015 ik_chain_origin_heads_init(*ik_chain, initial_location);
1016
1017 return ik_chain;
1018}
1019
1020static std::unique_ptr<IKChain> ik_chain_init_face_sets_mesh(const Depsgraph &depsgraph,
1021 Object &object,
1022 SculptSession &ss,
1023 const Brush &brush,
1024 const float radius)
1025{
1026 struct SegmentData {
1027 int vert;
1028 int face_set;
1029 };
1030
1031 Mesh &mesh = *static_cast<Mesh *>(object.data);
1032 Span<float3> vert_positions = bke::pbvh::vert_positions_eval(depsgraph, object);
1033 const OffsetIndices faces = mesh.faces();
1034 const Span<int> corner_verts = mesh.corner_verts();
1035 const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
1036 const bke::AttributeAccessor attributes = mesh.attributes();
1037 const VArraySpan<bool> hide_vert = *attributes.lookup<bool>(".hide_vert",
1039 const VArraySpan<bool> hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
1040 const VArraySpan face_sets = *attributes.lookup_or_default<int>(
1041 ".sculpt_face_set", bke::AttrDomain::Face, 0);
1042
1043 std::unique_ptr<IKChain> ik_chain = ik_chain_new(brush_num_effective_segments(brush),
1044 vert_positions.size());
1045
1046 /* Each vertex can only be assigned to one face set. */
1047 BitVector<> is_weighted(vert_positions.size());
1048 Set<int> visited_face_sets;
1049
1050 SegmentData current_data = {std::get<int>(ss.active_vert()), SCULPT_FACE_SET_NONE};
1051
1052 const int symm = SCULPT_mesh_symmetry_xyz_get(object);
1053 Vector<int> neighbors;
1054 int num_valid_segments = 0;
1055 for (const int i : ik_chain->segments.index_range()) {
1056 num_valid_segments++;
1057 const bool is_first_iteration = i == 0;
1058
1059 flood_fill::FillDataMesh flood_fill(vert_positions.size(),
1061 flood_fill.add_initial(find_symm_verts_mesh(depsgraph, object, current_data.vert, radius));
1062
1063 visited_face_sets.add(current_data.face_set);
1064
1065 MutableSpan<float> pose_factor = ik_chain->segments[i].weights;
1066 std::optional<SegmentData> next_segment_data;
1067
1068 float3 face_set_boundary_accum(0);
1069 int face_set_boundary_count = 0;
1070
1071 float3 fallback_accum(0);
1072 int fallback_count = 0;
1073
1074 const float3 &pose_initial_co = vert_positions[current_data.vert];
1075 flood_fill.execute(object, vert_to_face_map, [&](int /*from_v*/, int to_v) {
1076 const float3 &to_v_position = vert_positions[to_v];
1077 const bool symmetry_check = SCULPT_check_vertex_pivot_symmetry(
1078 to_v_position, pose_initial_co, symm);
1079
1080 /* First iteration. Continue expanding using topology until a vertex is outside the brush
1081 * radius to determine the first face set. */
1082 if (current_data.face_set == SCULPT_FACE_SET_NONE) {
1083
1084 pose_factor[to_v] = 1.0f;
1085 is_weighted[to_v].set();
1086
1087 if (vert_inside_brush_radius(to_v_position, pose_initial_co, radius, symm)) {
1088 const int visited_face_set = face_set::vert_face_set_get(
1089 vert_to_face_map, face_sets, to_v);
1090 visited_face_sets.add(visited_face_set);
1091 }
1092 else if (symmetry_check) {
1093 current_data.face_set = face_set::vert_face_set_get(vert_to_face_map, face_sets, to_v);
1094 visited_face_sets.add(current_data.face_set);
1095 }
1096 return true;
1097 }
1098
1099 /* We already have a current face set, so we can start checking the face sets of the
1100 * vertices. */
1101 /* In the first iteration we need to check all face sets we already visited as the flood
1102 * fill may still not be finished in some of them. */
1103 bool is_vertex_valid = false;
1104 if (is_first_iteration) {
1105 for (const int visited_face_set : visited_face_sets) {
1106 is_vertex_valid |= face_set::vert_has_face_set(
1107 vert_to_face_map, face_sets, to_v, visited_face_set);
1108 }
1109 }
1110 else {
1111 is_vertex_valid = face_set::vert_has_face_set(
1112 vert_to_face_map, face_sets, to_v, current_data.face_set);
1113 }
1114
1115 if (!is_vertex_valid) {
1116 return false;
1117 }
1118
1119 bool visit_next = false;
1120 if (!is_weighted[to_v]) {
1121 pose_factor[to_v] = 1.0f;
1122 is_weighted[to_v].set();
1123 visit_next = true;
1124 }
1125
1126 /* Fallback origin accumulation. */
1127 if (symmetry_check) {
1128 fallback_accum += to_v_position;
1129 fallback_count++;
1130 }
1131
1132 if (!symmetry_check || face_set::vert_has_unique_face_set(vert_to_face_map, face_sets, to_v))
1133 {
1134 return visit_next;
1135 }
1136
1137 /* We only add coordinates for calculating the origin when it is possible to go from this
1138 * vertex to another vertex in a valid face set for the next iteration. */
1139 bool count_as_boundary = false;
1140
1141 for (const int neighbor_idx : vert_neighbors_get_mesh(
1142 faces, corner_verts, vert_to_face_map, hide_poly, to_v, neighbors))
1143 {
1144 const int next_face_set_candidate = face_set::vert_face_set_get(
1145 vert_to_face_map, face_sets, neighbor_idx);
1146
1147 /* Check if we can get a valid face set for the next iteration from this neighbor. */
1148 if (face_set::vert_has_unique_face_set(vert_to_face_map, face_sets, neighbor_idx) &&
1149 !visited_face_sets.contains(next_face_set_candidate))
1150 {
1151 if (!next_segment_data) {
1152 next_segment_data = {neighbor_idx, next_face_set_candidate};
1153 }
1154 count_as_boundary = true;
1155 }
1156 }
1157
1158 /* Origin accumulation. */
1159 if (count_as_boundary) {
1160 face_set_boundary_accum += to_v_position;
1161 face_set_boundary_count++;
1162 }
1163 return visit_next;
1164 });
1165
1166 if (face_set_boundary_count > 0) {
1167 ik_chain->segments[i].orig = face_set_boundary_accum / float(face_set_boundary_count);
1168 }
1169 else if (fallback_count > 0) {
1170 ik_chain->segments[i].orig = fallback_accum / float(fallback_count);
1171 }
1172 else {
1173 ik_chain->segments[i].orig = float3(0);
1174 }
1175
1176 if (!next_segment_data) {
1177 /* It is possible that when traversing neighbors that we no longer have any vertices that
1178 * have not been assigned to a face set when trying to find the next segement's starting
1179 * point. All further segments are invalid in this case. */
1180 break;
1181 }
1182
1183 current_data = *next_segment_data;
1184 }
1185
1186 ik_chain->segments.resize(num_valid_segments);
1187 ik_chain_origin_heads_init(*ik_chain, vert_positions[std::get<int>(ss.active_vert())]);
1188
1189 return ik_chain;
1190}
1191
1192static std::unique_ptr<IKChain> ik_chain_init_face_sets_grids(Object &object,
1193 SculptSession &ss,
1194 const Brush &brush,
1195 const float radius)
1196{
1197 struct SegmentData {
1198 int vert;
1199 int face_set;
1200 };
1201
1202 const Mesh &mesh = *static_cast<const Mesh *>(object.data);
1203 const OffsetIndices<int> faces = mesh.faces();
1204 const Span<int> corner_verts = mesh.corner_verts();
1205 const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
1206 const bke::AttributeAccessor attributes = mesh.attributes();
1207 const VArraySpan face_sets = *attributes.lookup_or_default<int>(
1208 ".sculpt_face_set", bke::AttrDomain::Face, 0);
1209
1210 const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
1211 const Span<float3> positions = subdiv_ccg.positions;
1212 const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
1213 const int grids_num = ss.subdiv_ccg->grids_num * key.grid_area;
1214
1215 std::unique_ptr<IKChain> ik_chain = ik_chain_new(brush_num_effective_segments(brush), grids_num);
1216
1217 /* Each vertex can only be assigned to one face set. */
1218 BitVector<> is_weighted(grids_num);
1219 Set<int> visited_face_sets;
1220
1221 SegmentData current_data = {ss.active_vert_index(), SCULPT_FACE_SET_NONE};
1222
1223 const int symm = SCULPT_mesh_symmetry_xyz_get(object);
1224 SubdivCCGNeighbors neighbors;
1225 int num_valid_segments = 0;
1226 for (const int i : ik_chain->segments.index_range()) {
1227 num_valid_segments++;
1228 const bool is_first_iteration = i == 0;
1229
1231 flood_fill.add_initial(key, find_symm_verts_grids(object, current_data.vert, radius));
1232
1233 visited_face_sets.add(current_data.face_set);
1234
1235 MutableSpan<float> pose_factor = ik_chain->segments[i].weights;
1236 std::optional<SegmentData> next_segment_data;
1237
1238 float3 face_set_boundary_accum(0);
1239 int face_set_boundary_count = 0;
1240
1241 float3 fallback_accum(0);
1242 int fallback_count = 0;
1243
1244 const float3 &pose_initial_co = positions[current_data.vert];
1245 flood_fill.execute(
1246 object,
1247 subdiv_ccg,
1248 [&](SubdivCCGCoord /*from_v*/, SubdivCCGCoord to_v, bool is_duplicate) {
1249 const int to_v_i = to_v.to_index(key);
1250
1251 const float3 to_v_position = positions[to_v_i];
1252 const bool symmetry_check = SCULPT_check_vertex_pivot_symmetry(
1253 to_v_position, pose_initial_co, symm) &&
1254 !is_duplicate;
1255
1256 /* First iteration. Continue expanding using topology until a vertex is outside the brush
1257 * radius to determine the first face set. */
1258 if (current_data.face_set == SCULPT_FACE_SET_NONE) {
1259
1260 pose_factor[to_v_i] = 1.0f;
1261 is_weighted[to_v_i].set();
1262
1263 if (vert_inside_brush_radius(to_v_position, pose_initial_co, radius, symm)) {
1264 const int visited_face_set = face_set::vert_face_set_get(
1265 subdiv_ccg, face_sets, to_v.grid_index);
1266 visited_face_sets.add(visited_face_set);
1267 }
1268 else if (symmetry_check) {
1269 current_data.face_set = face_set::vert_face_set_get(
1270 subdiv_ccg, face_sets, to_v.grid_index);
1271 visited_face_sets.add(current_data.face_set);
1272 }
1273 return true;
1274 }
1275
1276 /* We already have a current face set, so we can start checking the face sets of the
1277 * vertices. */
1278 /* In the first iteration we need to check all face sets we already visited as the flood
1279 * fill may still not be finished in some of them. */
1280 bool is_vertex_valid = false;
1281 if (is_first_iteration) {
1282 for (const int visited_face_set : visited_face_sets) {
1283 is_vertex_valid |= face_set::vert_has_face_set(
1284 subdiv_ccg, face_sets, to_v.grid_index, visited_face_set);
1285 }
1286 }
1287 else {
1288 is_vertex_valid = face_set::vert_has_face_set(
1289 subdiv_ccg, face_sets, to_v.grid_index, current_data.face_set);
1290 }
1291
1292 if (!is_vertex_valid) {
1293 return false;
1294 }
1295
1296 bool visit_next = false;
1297 if (!is_weighted[to_v_i]) {
1298 pose_factor[to_v_i] = 1.0f;
1299 is_weighted[to_v_i].set();
1300 visit_next = true;
1301 }
1302
1303 /* Fallback origin accumulation. */
1304 if (symmetry_check) {
1305 fallback_accum += to_v_position;
1306 fallback_count++;
1307 }
1308
1309 if (!symmetry_check ||
1311 faces, corner_verts, vert_to_face_map, face_sets, subdiv_ccg, to_v))
1312 {
1313 return visit_next;
1314 }
1315
1316 /* We only add coordinates for calculating the origin when it is possible to go from this
1317 * vertex to another vertex in a valid face set for the next iteration. */
1318 bool count_as_boundary = false;
1319
1320 BKE_subdiv_ccg_neighbor_coords_get(subdiv_ccg, to_v, false, neighbors);
1321 for (const SubdivCCGCoord neighbor : neighbors.coords) {
1322 const int next_face_set_candidate = face_set::vert_face_set_get(
1323 subdiv_ccg, face_sets, neighbor.grid_index);
1324
1325 /* Check if we can get a valid face set for the next iteration from this neighbor. */
1327 faces, corner_verts, vert_to_face_map, face_sets, subdiv_ccg, neighbor) &&
1328 !visited_face_sets.contains(next_face_set_candidate))
1329 {
1330 if (!next_segment_data) {
1331 next_segment_data = {neighbor.to_index(key), next_face_set_candidate};
1332 }
1333 count_as_boundary = true;
1334 }
1335 }
1336
1337 /* Origin accumulation. */
1338 if (count_as_boundary) {
1339 face_set_boundary_accum += to_v_position;
1340 face_set_boundary_count++;
1341 }
1342 return visit_next;
1343 });
1344
1345 if (face_set_boundary_count > 0) {
1346 ik_chain->segments[i].orig = face_set_boundary_accum / float(face_set_boundary_count);
1347 }
1348 else if (fallback_count > 0) {
1349 ik_chain->segments[i].orig = fallback_accum / float(fallback_count);
1350 }
1351 else {
1352 ik_chain->segments[i].orig = float3(0);
1353 }
1354
1355 if (!next_segment_data) {
1356 /* It is possible that when traversing neighbors that we no longer have any vertices that
1357 * have not been assigned to a face set when trying to find the next segement's starting
1358 * point. All further segments are invalid in this case. */
1359 break;
1360 }
1361
1362 current_data = *next_segment_data;
1363 }
1364
1365 ik_chain->segments.resize(num_valid_segments);
1366 ik_chain_origin_heads_init(*ik_chain, positions[ss.active_vert_index()]);
1367
1368 return ik_chain;
1369}
1370
1371static std::unique_ptr<IKChain> ik_chain_init_face_sets_bmesh(Object &object,
1372 SculptSession &ss,
1373 const Brush &brush,
1374 const float radius)
1375{
1376 struct SegmentData {
1377 BMVert *vert;
1378 int face_set;
1379 };
1380
1381 const int verts_num = BM_mesh_elem_count(ss.bm, BM_VERT);
1382 const int face_set_offset = CustomData_get_offset_named(
1383 &ss.bm->pdata, CD_PROP_INT32, ".sculpt_face_set");
1384 std::unique_ptr<IKChain> ik_chain = ik_chain_new(brush_num_effective_segments(brush), verts_num);
1385
1386 /* Each vertex can only be assigned to one face set. */
1387 BitVector<> is_weighted(verts_num);
1388 Set<int> visited_face_sets;
1389
1390 SegmentData current_data = {std::get<BMVert *>(ss.active_vert()), SCULPT_FACE_SET_NONE};
1391
1392 const int symm = SCULPT_mesh_symmetry_xyz_get(object);
1393 BMeshNeighborVerts neighbors;
1394 int num_valid_segments = 0;
1395 for (const int i : ik_chain->segments.index_range()) {
1396 num_valid_segments++;
1397 const bool is_first_iteration = i == 0;
1398
1400 flood_fill.add_initial(
1401 *ss.bm, find_symm_verts_bmesh(object, BM_elem_index_get(current_data.vert), radius));
1402
1403 visited_face_sets.add(current_data.face_set);
1404
1405 MutableSpan<float> pose_factor = ik_chain->segments[i].weights;
1406 std::optional<SegmentData> next_segment_data;
1407
1408 float3 face_set_boundary_accum(0);
1409 int face_set_boundary_count = 0;
1410
1411 float3 fallback_accum(0);
1412 int fallback_count = 0;
1413
1414 const float3 pose_initial_co = current_data.vert->co;
1415 flood_fill.execute(object, [&](BMVert * /*from_v*/, BMVert *to_v) {
1416 const int to_v_i = BM_elem_index_get(to_v);
1417
1418 const float3 to_v_position = to_v->co;
1419 const bool symmetry_check = SCULPT_check_vertex_pivot_symmetry(
1420 to_v_position, pose_initial_co, symm);
1421
1422 /* First iteration. Continue expanding using topology until a vertex is outside the brush
1423 * radius to determine the first face set. */
1424 if (current_data.face_set == SCULPT_FACE_SET_NONE) {
1425
1426 pose_factor[to_v_i] = 1.0f;
1427 is_weighted[to_v_i].set();
1428
1429 if (vert_inside_brush_radius(to_v_position, pose_initial_co, radius, symm)) {
1430 const int visited_face_set = face_set::vert_face_set_get(face_set_offset, *to_v);
1431 visited_face_sets.add(visited_face_set);
1432 }
1433 else if (symmetry_check) {
1434 current_data.face_set = face_set::vert_face_set_get(face_set_offset, *to_v);
1435 visited_face_sets.add(current_data.face_set);
1436 }
1437 return true;
1438 }
1439
1440 /* We already have a current face set, so we can start checking the face sets of the
1441 * vertices. */
1442 /* In the first iteration we need to check all face sets we already visited as the flood
1443 * fill may still not be finished in some of them. */
1444 bool is_vertex_valid = false;
1445 if (is_first_iteration) {
1446 for (const int visited_face_set : visited_face_sets) {
1447 is_vertex_valid |= face_set::vert_has_face_set(face_set_offset, *to_v, visited_face_set);
1448 }
1449 }
1450 else {
1451 is_vertex_valid = face_set::vert_has_face_set(
1452 face_set_offset, *to_v, current_data.face_set);
1453 }
1454
1455 if (!is_vertex_valid) {
1456 return false;
1457 }
1458
1459 bool visit_next = false;
1460 if (!is_weighted[to_v_i]) {
1461 pose_factor[to_v_i] = 1.0f;
1462 is_weighted[to_v_i].set();
1463 visit_next = true;
1464 }
1465
1466 /* Fallback origin accumulation. */
1467 if (symmetry_check) {
1468 fallback_accum += to_v_position;
1469 fallback_count++;
1470 }
1471
1472 if (!symmetry_check || face_set::vert_has_unique_face_set(face_set_offset, *to_v)) {
1473 return visit_next;
1474 }
1475
1476 /* We only add coordinates for calculating the origin when it is possible to go from this
1477 * vertex to another vertex in a valid face set for the next iteration. */
1478 bool count_as_boundary = false;
1479
1480 for (BMVert *neighbor : vert_neighbors_get_bmesh(*to_v, neighbors)) {
1481 const int next_face_set_candidate = face_set::vert_face_set_get(face_set_offset,
1482 *neighbor);
1483
1484 /* Check if we can get a valid face set for the next iteration from this neighbor. */
1485 if (face_set::vert_has_unique_face_set(face_set_offset, *neighbor) &&
1486 !visited_face_sets.contains(next_face_set_candidate))
1487 {
1488 if (!next_segment_data) {
1489 next_segment_data = {neighbor, next_face_set_candidate};
1490 }
1491 count_as_boundary = true;
1492 }
1493 }
1494
1495 /* Origin accumulation. */
1496 if (count_as_boundary) {
1497 face_set_boundary_accum += to_v_position;
1498 face_set_boundary_count++;
1499 }
1500 return visit_next;
1501 });
1502
1503 if (face_set_boundary_count > 0) {
1504 ik_chain->segments[i].orig = face_set_boundary_accum / float(face_set_boundary_count);
1505 }
1506 else if (fallback_count > 0) {
1507 ik_chain->segments[i].orig = fallback_accum / float(fallback_count);
1508 }
1509 else {
1510 ik_chain->segments[i].orig = float3(0);
1511 }
1512
1513 if (!next_segment_data) {
1514 /* It is possible that when traversing neighbors that we no longer have any vertices that
1515 * have not been assigned to a face set when trying to find the next segement's starting
1516 * point. All further segments are invalid in this case. */
1517 break;
1518 }
1519
1520 current_data = *next_segment_data;
1521 }
1522
1523 ik_chain->segments.resize(num_valid_segments);
1524 ik_chain_origin_heads_init(*ik_chain, std::get<BMVert *>(ss.active_vert())->co);
1525
1526 return ik_chain;
1527}
1528
1529static std::unique_ptr<IKChain> ik_chain_init_face_sets(const Depsgraph &depsgraph,
1530 Object &object,
1531 SculptSession &ss,
1532 const Brush &brush,
1533 const float radius)
1534{
1535 switch (bke::object::pbvh_get(object)->type()) {
1537 return ik_chain_init_face_sets_mesh(depsgraph, object, ss, brush, radius);
1539 return ik_chain_init_face_sets_grids(object, ss, brush, radius);
1541 return ik_chain_init_face_sets_bmesh(object, ss, brush, radius);
1542 }
1543
1545 return nullptr;
1546}
1547
1548static std::optional<float3> calc_average_face_set_center(const Depsgraph &depsgraph,
1549 Object &object,
1550 const Span<int> floodfill_step,
1551 const int active_face_set,
1552 const int target_face_set)
1553{
1554 int count = 0;
1555 float3 sum(0.0f);
1556
1557 switch (bke::object::pbvh_get(object)->type()) {
1558 case bke::pbvh::Type::Mesh: {
1559 const Mesh &mesh = *static_cast<Mesh *>(object.data);
1560 const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
1561 const Span<float3> vert_positions = bke::pbvh::vert_positions_eval(depsgraph, object);
1562 const bke::AttributeAccessor attributes = mesh.attributes();
1563 const VArraySpan face_sets = *attributes.lookup_or_default<int>(
1564 ".sculpt_face_set", bke::AttrDomain::Face, 0);
1565
1566 for (const int vert : vert_positions.index_range()) {
1567 if (floodfill_step[vert] != 0 &&
1568 face_set::vert_has_face_set(vert_to_face_map, face_sets, vert, active_face_set) &&
1569 face_set::vert_has_face_set(vert_to_face_map, face_sets, vert, target_face_set))
1570 {
1571 sum += vert_positions[vert];
1572 count++;
1573 }
1574 }
1575 break;
1576 }
1578 const SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
1579 const Span<float3> positions = subdiv_ccg.positions;
1580
1581 const Mesh &mesh = *static_cast<Mesh *>(object.data);
1582 const bke::AttributeAccessor attributes = mesh.attributes();
1583 const VArraySpan face_sets = *attributes.lookup_or_default<int>(
1584 ".sculpt_face_set", bke::AttrDomain::Face, 0);
1585
1586 const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
1587 for (const int grid : IndexRange(subdiv_ccg.grids_num)) {
1588 for (const int index : bke::ccg::grid_range(key, grid)) {
1589 if (floodfill_step[index] != 0 &&
1590 face_set::vert_has_face_set(subdiv_ccg, face_sets, grid, active_face_set) &&
1591 face_set::vert_has_face_set(subdiv_ccg, face_sets, grid, target_face_set))
1592 {
1593 sum += positions[index];
1594 count++;
1595 }
1596 }
1597 }
1598 break;
1599 }
1602 BMesh &bm = *object.sculpt->bm;
1603 const int face_set_offset = CustomData_get_offset_named(
1604 &bm.pdata, CD_PROP_INT32, ".sculpt_face_set");
1605 for (const int vert : IndexRange(BM_mesh_elem_count(&bm, BM_VERT))) {
1606 const BMVert *bm_vert = BM_vert_at_index(&bm, vert);
1607 if (floodfill_step[vert] != 0 &&
1608 face_set::vert_has_face_set(face_set_offset, *bm_vert, active_face_set) &&
1609 face_set::vert_has_face_set(face_set_offset, *bm_vert, target_face_set))
1610 {
1611 sum += bm_vert->co;
1612 count++;
1613 }
1614 }
1615
1616 break;
1617 }
1618 }
1619
1620 if (count != 0) {
1621 return sum / float(count);
1622 }
1623
1624 return std::nullopt;
1625}
1626
1627static std::unique_ptr<IKChain> ik_chain_init_face_sets_fk_mesh(const Depsgraph &depsgraph,
1628 Object &object,
1629 SculptSession &ss,
1630 const float radius,
1631 const float3 &initial_location)
1632{
1633 const Mesh &mesh = *static_cast<Mesh *>(object.data);
1634 const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
1635 const bke::AttributeAccessor attributes = mesh.attributes();
1636 const VArraySpan face_sets = *attributes.lookup_or_default<int>(
1637 ".sculpt_face_set", bke::AttrDomain::Face, 0);
1638
1639 std::unique_ptr<IKChain> ik_chain = ik_chain_new(1, mesh.verts_num);
1640
1641 const int active_vert = std::get<int>(ss.active_vert());
1642
1643 const int active_face_set = face_set::active_face_set_get(object);
1644
1645 Set<int> visited_face_sets;
1646 Array<int> floodfill_step(mesh.verts_num);
1647 floodfill_step[active_vert] = 1;
1648
1649 int masked_face_set = SCULPT_FACE_SET_NONE;
1650 int target_face_set = SCULPT_FACE_SET_NONE;
1651 int masked_face_set_it = 0;
1653 step_floodfill.add_initial(active_vert);
1654 step_floodfill.execute(object, vert_to_face_map, [&](int from_v, int to_v) {
1655 floodfill_step[to_v] = floodfill_step[from_v] + 1;
1656
1657 const int to_face_set = face_set::vert_face_set_get(vert_to_face_map, face_sets, to_v);
1658 if (!visited_face_sets.contains(to_face_set)) {
1659 if (face_set::vert_has_unique_face_set(vert_to_face_map, face_sets, to_v) &&
1660 !face_set::vert_has_unique_face_set(vert_to_face_map, face_sets, from_v) &&
1661 face_set::vert_has_face_set(vert_to_face_map, face_sets, from_v, to_face_set))
1662 {
1663
1664 visited_face_sets.add(to_face_set);
1665
1666 if (floodfill_step[to_v] >= masked_face_set_it) {
1667 masked_face_set = to_face_set;
1668 masked_face_set_it = floodfill_step[to_v];
1669 }
1670
1671 if (target_face_set == SCULPT_FACE_SET_NONE) {
1672 target_face_set = to_face_set;
1673 }
1674 }
1675 }
1676
1677 return face_set::vert_has_face_set(vert_to_face_map, face_sets, to_v, active_face_set);
1678 });
1679
1680 const std::optional<float3> origin = calc_average_face_set_center(
1681 depsgraph, object, floodfill_step, active_face_set, masked_face_set);
1682 ik_chain->segments[0].orig = origin.value_or(float3(0));
1683
1684 std::optional<float3> head = std::nullopt;
1685 if (target_face_set != masked_face_set) {
1687 depsgraph, object, floodfill_step, active_face_set, target_face_set);
1688 }
1689
1690 ik_chain->segments[0].head = head.value_or(initial_location);
1691 ik_chain->grab_delta_offset = ik_chain->segments[0].head - initial_location;
1692
1693 flood_fill::FillDataMesh weight_floodfill(mesh.verts_num, ss.fake_neighbors.fake_neighbor_index);
1694 weight_floodfill.add_initial(find_symm_verts_mesh(depsgraph, object, active_vert, radius));
1695 MutableSpan<float> fk_weights = ik_chain->segments[0].weights;
1696 weight_floodfill.execute(object, vert_to_face_map, [&](int /*from_v*/, int to_v) {
1697 fk_weights[to_v] = 1.0f;
1698 return !face_set::vert_has_face_set(vert_to_face_map, face_sets, to_v, masked_face_set);
1699 });
1700
1701 ik_chain_origin_heads_init(*ik_chain, ik_chain->segments[0].head);
1702 return ik_chain;
1703}
1704
1705static std::unique_ptr<IKChain> ik_chain_init_face_sets_fk_grids(const Depsgraph &depsgraph,
1706 Object &object,
1707 SculptSession &ss,
1708 const float radius,
1709 const float3 &initial_location)
1710{
1711 const Mesh &mesh = *static_cast<const Mesh *>(object.data);
1712 const OffsetIndices<int> faces = mesh.faces();
1713 const Span<int> corner_verts = mesh.corner_verts();
1714 const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
1715 const bke::AttributeAccessor attributes = mesh.attributes();
1716 const VArraySpan face_sets = *attributes.lookup_or_default<int>(
1717 ".sculpt_face_set", bke::AttrDomain::Face, 0);
1718
1719 const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
1720 const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
1721 const Span<int> grid_to_face_map = subdiv_ccg.grid_to_face_map;
1722 const int grids_num = ss.subdiv_ccg->grids_num * key.grid_area;
1723
1724 std::unique_ptr<IKChain> ik_chain = ik_chain_new(1, grids_num);
1725
1726 const int active_vert_index = ss.active_vert_index();
1727
1728 const int active_face_set = face_set::active_face_set_get(object);
1729
1730 Set<int> visited_face_sets;
1731 Array<int> floodfill_step(grids_num);
1732 floodfill_step[active_vert_index] = 1;
1733
1734 int masked_face_set = SCULPT_FACE_SET_NONE;
1735 int target_face_set = SCULPT_FACE_SET_NONE;
1736 int masked_face_set_it = 0;
1737 flood_fill::FillDataGrids step_floodfill(grids_num, ss.fake_neighbors.fake_neighbor_index);
1738 step_floodfill.add_initial(SubdivCCGCoord::from_index(key, active_vert_index));
1739 step_floodfill.execute(
1740 object, subdiv_ccg, [&](SubdivCCGCoord from_v, SubdivCCGCoord to_v, bool is_duplicate) {
1741 const int from_v_i = from_v.to_index(key);
1742 const int to_v_i = to_v.to_index(key);
1743
1744 if (!is_duplicate) {
1745 floodfill_step[to_v_i] = floodfill_step[from_v_i] + 1;
1746 }
1747 else {
1748 floodfill_step[to_v_i] = floodfill_step[from_v_i];
1749 }
1750
1751 const int to_face_set = face_sets[grid_to_face_map[to_v.grid_index]];
1752 if (!visited_face_sets.contains(to_face_set)) {
1754 faces, corner_verts, vert_to_face_map, face_sets, subdiv_ccg, to_v) &&
1756 faces, corner_verts, vert_to_face_map, face_sets, subdiv_ccg, from_v) &&
1757 face_set::vert_has_face_set(subdiv_ccg, face_sets, from_v.grid_index, to_face_set))
1758 {
1759
1760 visited_face_sets.add(to_face_set);
1761
1762 if (floodfill_step[to_v_i] >= masked_face_set_it) {
1763 masked_face_set = to_face_set;
1764 masked_face_set_it = floodfill_step[to_v_i];
1765 }
1766
1767 if (target_face_set == SCULPT_FACE_SET_NONE) {
1768 target_face_set = to_face_set;
1769 }
1770 }
1771 }
1772
1774 subdiv_ccg, face_sets, to_v.grid_index, active_face_set);
1775 });
1776
1777 const std::optional<float3> origin = calc_average_face_set_center(
1778 depsgraph, object, floodfill_step, active_face_set, masked_face_set);
1779 ik_chain->segments[0].orig = origin.value_or(float3(0));
1780
1781 std::optional<float3> head = std::nullopt;
1782 if (target_face_set != masked_face_set) {
1784 depsgraph, object, floodfill_step, active_face_set, target_face_set);
1785 }
1786
1787 ik_chain->segments[0].head = head.value_or(initial_location);
1788 ik_chain->grab_delta_offset = ik_chain->segments[0].head - initial_location;
1789
1790 flood_fill::FillDataGrids weight_floodfill(grids_num, ss.fake_neighbors.fake_neighbor_index);
1791 weight_floodfill.add_initial(key, find_symm_verts_grids(object, active_vert_index, radius));
1792 MutableSpan<float> fk_weights = ik_chain->segments[0].weights;
1793 weight_floodfill.execute(
1794 object,
1795 subdiv_ccg,
1796 [&](SubdivCCGCoord /*from_v*/, SubdivCCGCoord to_v, bool /*is_duplicate*/) {
1797 int to_v_i = to_v.to_index(key);
1798
1799 fk_weights[to_v_i] = 1.0f;
1801 subdiv_ccg, face_sets, to_v.grid_index, masked_face_set);
1802 });
1803
1804 ik_chain_origin_heads_init(*ik_chain, ik_chain->segments[0].head);
1805 return ik_chain;
1806}
1807
1808static std::unique_ptr<IKChain> ik_chain_init_face_sets_fk_bmesh(const Depsgraph &depsgraph,
1809 Object &object,
1810 SculptSession &ss,
1811 const float radius,
1812 const float3 &initial_location)
1813{
1815
1816 BMesh &bm = *ss.bm;
1817 const int face_set_offset = CustomData_get_offset_named(
1818 &bm.pdata, CD_PROP_INT32, ".sculpt_face_set");
1819 const int verts_num = BM_mesh_elem_count(&bm, BM_VERT);
1820
1821 std::unique_ptr<IKChain> ik_chain = ik_chain_new(1, verts_num);
1822
1823 BMVert *active_vert = std::get<BMVert *>(ss.active_vert());
1824 const int active_vert_index = BM_elem_index_get(active_vert);
1825
1826 const int active_face_set = face_set::active_face_set_get(object);
1827
1828 Set<int> visited_face_sets;
1829 Array<int> floodfill_step(verts_num);
1830 floodfill_step[active_vert_index] = 1;
1831
1832 int masked_face_set = SCULPT_FACE_SET_NONE;
1833 int target_face_set = SCULPT_FACE_SET_NONE;
1834 int masked_face_set_it = 0;
1835 flood_fill::FillDataBMesh step_floodfill(verts_num, ss.fake_neighbors.fake_neighbor_index);
1836 step_floodfill.add_initial(active_vert);
1837 step_floodfill.execute(object, [&](BMVert *from_v, BMVert *to_v) {
1838 const int from_v_i = BM_elem_index_get(from_v);
1839 const int to_v_i = BM_elem_index_get(to_v);
1840
1841 floodfill_step[to_v_i] = floodfill_step[from_v_i] + 1;
1842
1843 const int to_face_set = face_set::vert_face_set_get(face_set_offset, *to_v);
1844 if (!visited_face_sets.contains(to_face_set)) {
1845 if (face_set::vert_has_unique_face_set(face_set_offset, *to_v) &&
1846 !face_set::vert_has_unique_face_set(face_set_offset, *from_v) &&
1847 face_set::vert_has_face_set(face_set_offset, *from_v, to_face_set))
1848 {
1849
1850 visited_face_sets.add(to_face_set);
1851
1852 if (floodfill_step[to_v_i] >= masked_face_set_it) {
1853 masked_face_set = to_face_set;
1854 masked_face_set_it = floodfill_step[to_v_i];
1855 }
1856
1857 if (target_face_set == SCULPT_FACE_SET_NONE) {
1858 target_face_set = to_face_set;
1859 }
1860 }
1861 }
1862
1863 return face_set::vert_has_face_set(face_set_offset, *to_v, active_face_set);
1864 });
1865
1866 const std::optional<float3> origin = calc_average_face_set_center(
1867 depsgraph, object, floodfill_step, active_face_set, masked_face_set);
1868 ik_chain->segments[0].orig = origin.value_or(float3(0));
1869
1870 std::optional<float3> head = std::nullopt;
1871 if (target_face_set != masked_face_set) {
1873 depsgraph, object, floodfill_step, active_face_set, target_face_set);
1874 }
1875
1876 ik_chain->segments[0].head = head.value_or(initial_location);
1877 ik_chain->grab_delta_offset = ik_chain->segments[0].head - initial_location;
1878
1879 flood_fill::FillDataBMesh weight_floodfill(verts_num, ss.fake_neighbors.fake_neighbor_index);
1880 weight_floodfill.add_initial(
1881 *ss.bm, find_symm_verts_bmesh(object, BM_elem_index_get(active_vert), radius));
1882 MutableSpan<float> fk_weights = ik_chain->segments[0].weights;
1883 weight_floodfill.execute(object, [&](BMVert * /*from_v*/, BMVert *to_v) {
1884 int to_v_i = BM_elem_index_get(to_v);
1885
1886 fk_weights[to_v_i] = 1.0f;
1887 return !face_set::vert_has_face_set(face_set_offset, *to_v, masked_face_set);
1888 });
1889
1890 ik_chain_origin_heads_init(*ik_chain, ik_chain->segments[0].head);
1891 return ik_chain;
1892}
1893
1894static std::unique_ptr<IKChain> ik_chain_init_face_sets_fk(const Depsgraph &depsgraph,
1895 Object &object,
1896 SculptSession &ss,
1897 const float radius,
1898 const float3 &initial_location)
1899{
1900 switch (bke::object::pbvh_get(object)->type()) {
1902 return ik_chain_init_face_sets_fk_mesh(depsgraph, object, ss, radius, initial_location);
1904 return ik_chain_init_face_sets_fk_grids(depsgraph, object, ss, radius, initial_location);
1906 return ik_chain_init_face_sets_fk_bmesh(depsgraph, object, ss, radius, initial_location);
1907 }
1909 return nullptr;
1910}
1911
1912static std::unique_ptr<IKChain> ik_chain_init(const Depsgraph &depsgraph,
1913 Object &ob,
1914 SculptSession &ss,
1915 const Brush &brush,
1916 const float3 &initial_location,
1917 const float radius)
1918{
1919 std::unique_ptr<IKChain> ik_chain;
1920
1921 const bool use_fake_neighbors = !(brush.flag2 & BRUSH_USE_CONNECTED_ONLY);
1922
1923 if (use_fake_neighbors) {
1925 }
1926 else {
1928 }
1929
1930 switch (brush.pose_origin_type) {
1932 ik_chain = ik_chain_init_topology(depsgraph, ob, ss, brush, initial_location, radius);
1933 break;
1935 ik_chain = ik_chain_init_face_sets(depsgraph, ob, ss, brush, radius);
1936 break;
1938 ik_chain = ik_chain_init_face_sets_fk(depsgraph, ob, ss, radius, initial_location);
1939 break;
1940 }
1941
1942 return ik_chain;
1943}
1944
1945static void pose_brush_init(const Depsgraph &depsgraph,
1946 Object &ob,
1947 SculptSession &ss,
1948 const Brush &brush)
1949{
1950 /* Init the IK chain that is going to be used to deform the vertices. */
1952 depsgraph, ob, ss, brush, ss.cache->location, ss.cache->radius);
1953
1954 /* Smooth the weights of each segment for cleaner deformation. */
1955 for (IKChainSegment &segment : ss.cache->pose_ik_chain->segments) {
1956 smooth::blur_geometry_data_array(ob, brush.pose_smooth_iterations, segment.weights);
1957 }
1958}
1959
1960std::unique_ptr<SculptPoseIKChainPreview> preview_ik_chain_init(const Depsgraph &depsgraph,
1961 Object &ob,
1962 SculptSession &ss,
1963 const Brush &brush,
1964 const float3 &initial_location,
1965 const float radius)
1966{
1967 const IKChain chain = *ik_chain_init(depsgraph, ob, ss, brush, initial_location, radius);
1968 std::unique_ptr<SculptPoseIKChainPreview> preview = std::make_unique<SculptPoseIKChainPreview>();
1969
1970 preview->initial_head_coords.reinitialize(chain.segments.size());
1971 preview->initial_orig_coords.reinitialize(chain.segments.size());
1972 for (const int i : chain.segments.index_range()) {
1973 preview->initial_head_coords[i] = chain.segments[i].initial_head;
1974 preview->initial_orig_coords[i] = chain.segments[i].initial_orig;
1975 }
1976
1977 return preview;
1978}
1979
1981{
1982 IKChain &ik_chain = *ss.cache->pose_ik_chain;
1984 solve_translate_chain(ik_chain, ss.cache->grab_delta);
1985}
1986
1987/* Calculate a scale factor based on the grab delta. */
1988static float calc_scale_from_grab_delta(SculptSession &ss, const float3 &ik_target)
1989{
1990 IKChain &ik_chain = *ss.cache->pose_ik_chain;
1991 const float3 segment_dir = math::normalize(ik_chain.segments[0].initial_head -
1992 ik_chain.segments[0].initial_orig);
1993 float4 plane;
1994 plane_from_point_normal_v3(plane, ik_chain.segments[0].initial_head, segment_dir);
1995 const float segment_len = ik_chain.segments[0].len;
1996 return segment_len / (segment_len - dist_signed_to_plane_v3(ik_target, plane));
1997}
1998
1999static void calc_scale_deform(SculptSession &ss, const Brush &brush)
2000{
2001 IKChain &ik_chain = *ss.cache->pose_ik_chain;
2002
2003 float3 ik_target = ss.cache->location + ss.cache->grab_delta;
2004
2005 /* Solve the IK for the first segment to include rotation as part of scale if enabled. */
2006 if (!(brush.flag2 & BRUSH_POSE_USE_LOCK_ROTATION)) {
2007 solve_ik_chain(ik_chain, ik_target, brush.flag2 & BRUSH_POSE_IK_ANCHORED);
2008 }
2009
2010 float3 scale(calc_scale_from_grab_delta(ss, ik_target));
2011
2012 /* Write the scale into the segments. */
2013 solve_scale_chain(ik_chain, scale);
2014}
2015
2016static void calc_twist_deform(SculptSession &ss, const Brush &brush)
2017{
2018 IKChain &ik_chain = *ss.cache->pose_ik_chain;
2019
2020 /* Calculate the maximum roll. 0.02 radians per pixel works fine. */
2021 float roll = (ss.cache->initial_mouse[0] - ss.cache->mouse[0]) * ss.cache->bstrength * 0.02f;
2023 solve_roll_chain(ik_chain, brush, roll);
2024}
2025
2026static void calc_rotate_deform(SculptSession &ss, const Brush &brush)
2027{
2028 IKChain &ik_chain = *ss.cache->pose_ik_chain;
2029
2030 /* Calculate the IK target. */
2031 float3 ik_target = ss.cache->location + ss.cache->grab_delta + ik_chain.grab_delta_offset;
2032
2033 /* Solve the IK positions. */
2034 solve_ik_chain(ik_chain, ik_target, brush.flag2 & BRUSH_POSE_IK_ANCHORED);
2035}
2036
2037static void calc_rotate_twist_deform(SculptSession &ss, const Brush &brush)
2038{
2039 if (ss.cache->invert) {
2040 calc_twist_deform(ss, brush);
2041 }
2042 else {
2043 calc_rotate_deform(ss, brush);
2044 }
2045}
2046
2048{
2049 if (ss.cache->invert) {
2051 }
2052 else {
2053 calc_scale_deform(ss, brush);
2054 }
2055}
2056
2057static void calc_squash_stretch_deform(SculptSession &ss, const Brush & /*brush*/)
2058{
2059 IKChain &ik_chain = *ss.cache->pose_ik_chain;
2060
2061 float3 ik_target = ss.cache->location + ss.cache->grab_delta;
2062
2063 float3 scale;
2064 scale.z = calc_scale_from_grab_delta(ss, ik_target);
2065 if (math::abs(scale.z) < 1e-5f) {
2066 scale = float3(0.0f);
2067 }
2068 else {
2069 const float signed_scale = math::sqrt(1.0f / math::abs(scale.z)) * math::sign(scale.z);
2070
2071 scale.x = signed_scale;
2072 scale.y = signed_scale;
2073 }
2074
2075 BLI_assert(std::isfinite(scale.x) && std::isfinite(scale.y) && std::isfinite(scale.z));
2076
2077 /* Write the scale into the segments. */
2078 solve_scale_chain(ik_chain, scale);
2079}
2080
2081static void align_pivot_local_space(float r_mat[4][4],
2083 ePaintSymmetryAreas symm_area,
2084 IKChainSegment *segment,
2085 const float3 &grab_location)
2086{
2087 const float3 symm_head = SCULPT_flip_v3_by_symm_area(
2088 segment->head, symm, symm_area, grab_location);
2089 const float3 symm_orig = SCULPT_flip_v3_by_symm_area(
2090 segment->orig, symm, symm_area, grab_location);
2091
2092 float3 segment_origin_head = math::normalize(symm_head - symm_orig);
2093
2094 copy_v3_v3(r_mat[2], segment_origin_head);
2095 ortho_basis_v3v3_v3(r_mat[0], r_mat[1], r_mat[2]);
2096}
2097
2098void do_pose_brush(const Depsgraph &depsgraph,
2099 const Sculpt &sd,
2100 Object &ob,
2101 const IndexMask &node_mask)
2102{
2103 SculptSession &ss = *ob.sculpt;
2105 const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
2107
2108 if (!ss.cache->pose_ik_chain) {
2109 pose_brush_init(depsgraph, ob, ss, brush);
2110 }
2111
2112 /* The pose brush applies all enabled symmetry axis in a single iteration, so the rest can be
2113 * ignored. */
2114 if (ss.cache->mirror_symmetry_pass != 0) {
2115 return;
2116 }
2117
2118 IKChain &ik_chain = *ss.cache->pose_ik_chain;
2119
2120 switch (brush.pose_deform_type) {
2122 calc_rotate_twist_deform(ss, brush);
2123 break;
2125 calc_scale_translate_deform(ss, brush);
2126 break;
2128 calc_squash_stretch_deform(ss, brush);
2129 break;
2130 }
2131
2132 /* Flip the segment chain in all symmetry axis and calculate the transform matrices for each
2133 * possible combination. */
2134 /* This can be optimized by skipping the calculation of matrices where the symmetry is not
2135 * enabled. */
2136 for (int symm_it = 0; symm_it < PAINT_SYMM_AREAS; symm_it++) {
2137 for (const int i : ik_chain.segments.index_range()) {
2138 ePaintSymmetryAreas symm_area = ePaintSymmetryAreas(symm_it);
2139
2140 float symm_rot[4];
2141 copy_qt_qt(symm_rot, ik_chain.segments[i].rot);
2142
2143 /* Flip the origins and rotation quats of each segment. */
2144 SCULPT_flip_quat_by_symm_area(symm_rot, symm, symm_area, ss.cache->orig_grab_location);
2146 ik_chain.segments[i].orig, symm, symm_area, ss.cache->orig_grab_location);
2147 float3 symm_initial_orig = SCULPT_flip_v3_by_symm_area(
2148 ik_chain.segments[i].initial_orig, symm, symm_area, ss.cache->orig_grab_location);
2149
2150 float pivot_local_space[4][4];
2151 unit_m4(pivot_local_space);
2152
2153 /* Align the segment pivot local space to the Z axis. */
2155 align_pivot_local_space(pivot_local_space,
2156 symm,
2157 symm_area,
2158 &ik_chain.segments[i],
2160 unit_m4(ik_chain.segments[i].trans_mat[symm_it].ptr());
2161 }
2162 else {
2163 quat_to_mat4(ik_chain.segments[i].trans_mat[symm_it].ptr(), symm_rot);
2164 }
2165
2166 /* Apply segment scale to the transform. */
2167 for (int scale_i = 0; scale_i < 3; scale_i++) {
2168 mul_v3_fl(ik_chain.segments[i].trans_mat[symm_it][scale_i],
2169 ik_chain.segments[i].scale[scale_i]);
2170 }
2171
2172 translate_m4(ik_chain.segments[i].trans_mat[symm_it].ptr(),
2173 symm_orig[0] - symm_initial_orig[0],
2174 symm_orig[1] - symm_initial_orig[1],
2175 symm_orig[2] - symm_initial_orig[2]);
2176
2177 unit_m4(ik_chain.segments[i].pivot_mat[symm_it].ptr());
2179 ik_chain.segments[i].pivot_mat[symm_it].ptr(), symm_orig[0], symm_orig[1], symm_orig[2]);
2180 mul_m4_m4_post(ik_chain.segments[i].pivot_mat[symm_it].ptr(), pivot_local_space);
2181
2182 invert_m4_m4(ik_chain.segments[i].pivot_mat_inv[symm_it].ptr(),
2183 ik_chain.segments[i].pivot_mat[symm_it].ptr());
2184 }
2185 }
2186
2188 switch (pbvh.type()) {
2189 case bke::pbvh::Type::Mesh: {
2190 Mesh &mesh = *static_cast<Mesh *>(ob.data);
2191 const MeshAttributeData attribute_data(mesh);
2193 const PositionDeformData position_data(depsgraph, ob);
2194 node_mask.foreach_index(GrainSize(1), [&](const int i) {
2195 BrushLocalData &tls = all_tls.local();
2196 calc_mesh(depsgraph, sd, brush, attribute_data, nodes[i], ob, tls, position_data);
2197 bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
2198 });
2199 break;
2200 }
2202 SubdivCCG &subdiv_ccg = *ob.sculpt->subdiv_ccg;
2203 MutableSpan<float3> positions = subdiv_ccg.positions;
2205 node_mask.foreach_index(GrainSize(1), [&](const int i) {
2206 BrushLocalData &tls = all_tls.local();
2207 calc_grids(depsgraph, sd, brush, nodes[i], ob, tls);
2208 bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
2209 });
2210 break;
2211 }
2214 node_mask.foreach_index(GrainSize(1), [&](const int i) {
2215 BrushLocalData &tls = all_tls.local();
2216 calc_bmesh(depsgraph, sd, brush, nodes[i], ob, tls);
2218 });
2219 break;
2220 }
2221 }
2222 pbvh.tag_positions_changed(node_mask);
2224}
2225
2226} // namespace blender::ed::sculpt_paint::pose
float BKE_brush_curve_strength(eBrushCurvePreset preset, const CurveMapping *cumap, float distance, float brush_radius)
Definition brush.cc:1510
int CCG_grid_xy_to_index(const int grid_size, const int x, const int y)
Definition BKE_ccg.hh:77
void BKE_curvemapping_init(CurveMapping *cumap)
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
#define PAINT_SYMM_AREAS
Definition BKE_paint.hh:143
ePaintSymmetryAreas
Definition BKE_paint.hh:136
#define SCULPT_FACE_SET_NONE
Definition BKE_paint.hh:344
const Brush * BKE_paint_brush_for_read(const Paint *paint)
Definition paint.cc:641
A BVH for high poly meshes.
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)
void BKE_subdiv_ccg_neighbor_coords_get(const SubdivCCG &subdiv_ccg, const SubdivCCGCoord &coord, bool include_duplicates, SubdivCCGNeighbors &r_neighbors)
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_NOINLINE
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
Definition math_geom.cc:217
float dist_signed_to_plane_v3(const float p[3], const float plane[4])
Definition math_geom.cc:495
void translate_m4(float mat[4][4], float Tx, float Ty, float Tz)
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void mul_m4_m4_post(float R[4][4], const float B[4][4])
void unit_m4(float m[4][4])
void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q2[4])
void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3])
void quat_to_mat4(float m[4][4], const float q[4])
void unit_qt(float q[4])
void axis_angle_normalized_to_quat(float r[4], const float axis[3], float angle)
void copy_qt_qt(float q[4], const float a[4])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3])
#define ELEM(...)
eBrushDeformTarget
@ BRUSH_DEFORM_TARGET_CLOTH_SIM
@ BRUSH_DEFORM_TARGET_GEOMETRY
@ BRUSH_POSE_DEFORM_SQUASH_STRETCH
@ BRUSH_POSE_DEFORM_ROTATE_TWIST
@ BRUSH_POSE_DEFORM_SCALE_TRASLATE
@ BRUSH_USE_CONNECTED_ONLY
@ BRUSH_POSE_USE_LOCK_ROTATION
@ BRUSH_POSE_IK_ANCHORED
@ BRUSH_POSE_ORIGIN_FACE_SETS_FK
@ BRUSH_POSE_ORIGIN_TOPOLOGY
@ BRUSH_POSE_ORIGIN_FACE_SETS
@ CD_PROP_INT32
Object is a sort of wrapper for general info.
ePaintSymmetryFlags
#define BM_elem_index_get(ele)
BMesh * bm
int BM_mesh_elem_count(BMesh *bm, const char htype)
BLI_INLINE BMVert * BM_vert_at_index(BMesh *bm, const int index)
#define BM_VERT
BPy_StructRNA * depsgraph
static T sum(const btAlignedObjectArray< T > &items)
void resize(const int64_t new_size)
MutableSpan< T > as_mutable_span()
Definition BLI_array.hh:237
constexpr int64_t size() const
Definition BLI_span.hh:493
constexpr bool is_empty() const
Definition BLI_span.hh:509
constexpr void fill(const T &value) const
Definition BLI_span.hh:517
constexpr Span< T > as_span() const
Definition BLI_span.hh:661
constexpr IndexRange index_range() const
Definition BLI_span.hh:670
constexpr T & last(const int64_t n=0) const
Definition BLI_span.hh:689
bool contains(const Key &key) const
Definition BLI_set.hh:310
bool add(const Key &key)
Definition BLI_set.hh:248
constexpr Span slice(int64_t start, int64_t size) const
Definition BLI_span.hh:137
constexpr int64_t size() const
Definition BLI_span.hh:252
constexpr IndexRange index_range() const
Definition BLI_span.hh:401
constexpr bool is_empty() const
Definition BLI_span.hh:260
int64_t size() const
void append(const T &value)
void resize(const int64_t new_size)
void extend(Span< T > array)
Span< T > as_span() const
GAttributeReader lookup(const StringRef attribute_id) const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const void *default_value=nullptr) const
void tag_positions_changed(const IndexMask &node_mask)
Definition pbvh.cc:559
Span< NodeT > nodes() const
void flush_bounds_to_parents()
Definition pbvh.cc:1122
void deform(MutableSpan< float3 > translations, Span< int > verts) const
Definition sculpt.cc:7445
void foreach_index(Fn &&fn) const
#define rot(x, k)
static float verts[][3]
VecBase< float, 3 > float3
int count
static char faces[256]
IndexRange grid_range(const int grid_area, const int grid)
pbvh::Tree * pbvh_get(Object &object)
Definition paint.cc:2912
IndexMask all_leaf_nodes(const Tree &pbvh, IndexMaskMemory &memory)
Definition pbvh.cc:2544
void update_node_bounds_bmesh(BMeshNode &node)
Definition pbvh.cc:1110
void update_node_bounds_mesh(Span< float3 > positions, MeshNode &node)
Definition pbvh.cc:1090
void update_node_bounds_grids(int grid_area, Span< float3 > positions, GridsNode &node)
Definition pbvh.cc:1099
Span< float3 > vert_positions_eval(const Depsgraph &depsgraph, const Object &object_orig)
Definition pbvh.cc:2416
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)
int vert_face_set_get(const GroupedSpan< int > vert_to_face_map, const Span< int > face_sets, const int vert)
Definition sculpt.cc:231
bool vert_has_unique_face_set(const GroupedSpan< int > vert_to_face_map, const Span< int > face_sets, int vert)
Definition sculpt.cc:293
bool vert_has_face_set(const GroupedSpan< int > vert_to_face_map, const Span< int > face_sets, const int vert, const int face_set)
Definition sculpt.cc:253
int active_face_set_get(const Object &object)
Definition sculpt.cc:197
Span< int > node_visible_verts(const bke::pbvh::MeshNode &node, const Span< bool > hide_vert, Vector< int > &indices)
void do_pose_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &ob, const IndexMask &node_mask)
static void grow_factors_bmesh(const ePaintSymmetryFlags symm, const float3 &pose_initial_position, const Span< int > fake_neighbors, const Span< float > prev_mask, bke::pbvh::BMeshNode &node, const MutableSpan< float > pose_factor, PoseGrowFactorData &gftd)
static std::unique_ptr< IKChain > ik_chain_init(const Depsgraph &depsgraph, Object &ob, SculptSession &ss, const Brush &brush, const float3 &initial_location, const float radius)
static BLI_NOINLINE void add_fake_neighbors(const Span< int > fake_neighbors, const Span< int > verts, const Span< int > orig_neighbor_data, MutableSpan< int > neighbor_offsets, Vector< int > &neighbor_data_with_fake)
static void solve_roll_chain(IKChain &ik_chain, const Brush &brush, const float roll)
static void calc_squash_stretch_deform(SculptSession &ss, const Brush &)
static std::unique_ptr< IKChain > ik_chain_init_face_sets(const Depsgraph &depsgraph, Object &object, SculptSession &ss, const Brush &brush, const float radius)
static void solve_translate_chain(IKChain &ik_chain, const float delta[3])
static void calc_mesh(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, const MeshAttributeData &attribute_data, const bke::pbvh::MeshNode &node, Object &object, BrushLocalData &tls, const PositionDeformData &position_data)
static void grow_factors_grids(const ePaintSymmetryFlags symm, const float3 &pose_initial_position, const SubdivCCG &subdiv_ccg, const Span< int > fake_neighbors, const Span< float > prev_mask, const bke::pbvh::GridsNode &node, const MutableSpan< float > pose_factor, PoseGrowFactorData &gftd)
static BLI_NOINLINE void calc_segment_translations(const Span< float3 > positions, const IKChainSegment &segment, const MutableSpan< float3 > translations)
static void calc_rotate_deform(SculptSession &ss, const Brush &brush)
static void calc_grids(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, const bke::pbvh::GridsNode &node, Object &object, BrushLocalData &tls)
static bool vert_inside_brush_radius(const float3 &vertex, const float3 &br_co, float radius, char symm)
static int brush_num_effective_segments(const Brush &brush)
static std::unique_ptr< IKChain > ik_chain_init_face_sets_grids(Object &object, SculptSession &ss, const Brush &brush, const float radius)
static std::unique_ptr< IKChain > ik_chain_init_face_sets_fk_bmesh(const Depsgraph &depsgraph, Object &object, SculptSession &ss, const float radius, const float3 &initial_location)
static std::unique_ptr< IKChain > ik_chain_init_face_sets_fk(const Depsgraph &depsgraph, Object &object, SculptSession &ss, const float radius, const float3 &initial_location)
static float calc_scale_from_grab_delta(SculptSession &ss, const float3 &ik_target)
static void sculpt_pose_do_translate_deform(SculptSession &ss, const Brush &brush)
static void calc_scale_translate_deform(SculptSession &ss, const Brush &brush)
static void ik_chain_origin_heads_init(IKChain &ik_chain, const float3 &initial_location)
static std::unique_ptr< IKChain > ik_chain_init_face_sets_fk_mesh(const Depsgraph &depsgraph, Object &object, SculptSession &ss, const float radius, const float3 &initial_location)
static void calc_pose_origin_and_factor_bmesh(Object &object, SculptSession &ss, const float3 &initial_location, float radius, float3 &r_pose_origin, MutableSpan< float > r_pose_factor)
static void calc_twist_deform(SculptSession &ss, const Brush &brush)
static void calc_scale_deform(SculptSession &ss, const Brush &brush)
static std::unique_ptr< IKChain > ik_chain_init_face_sets_fk_grids(const Depsgraph &depsgraph, Object &object, SculptSession &ss, const float radius, const float3 &initial_location)
static std::unique_ptr< IKChain > ik_chain_new(const int totsegments, const int totverts)
static void calc_pose_origin_and_factor_mesh(const Depsgraph &depsgraph, Object &object, SculptSession &ss, const float3 &initial_location, float radius, float3 &r_pose_origin, MutableSpan< float > r_pose_factor)
static std::optional< float3 > calc_average_face_set_center(const Depsgraph &depsgraph, Object &object, const Span< int > floodfill_step, const int active_face_set, const int target_face_set)
static std::unique_ptr< IKChain > ik_chain_init_face_sets_bmesh(Object &object, SculptSession &ss, const Brush &brush, const float radius)
static BLI_NOINLINE void add_arrays(const MutableSpan< float3 > a, const Span< float3 > b)
static void calc_rotate_twist_deform(SculptSession &ss, const Brush &brush)
static void solve_scale_chain(IKChain &ik_chain, const float scale[3])
static std::unique_ptr< IKChain > ik_chain_init_face_sets_mesh(const Depsgraph &depsgraph, Object &object, SculptSession &ss, const Brush &brush, const float radius)
static void align_pivot_local_space(float r_mat[4][4], ePaintSymmetryFlags symm, ePaintSymmetryAreas symm_area, IKChainSegment *segment, const float3 &grab_location)
static void grow_factors_mesh(const ePaintSymmetryFlags symm, const float3 &pose_initial_position, const Span< float3 > vert_positions, const OffsetIndices< int > faces, const Span< int > corner_verts, const GroupedSpan< int > vert_to_face_map, const Span< bool > hide_vert, const Span< bool > hide_poly, const Span< int > fake_neighbors, const Span< float > prev_mask, const bke::pbvh::MeshNode &node, GrowFactorLocalData &tls, const MutableSpan< float > pose_factor, PoseGrowFactorData &gftd)
static void solve_ik_chain(IKChain &ik_chain, const float3 &initial_target, const bool use_anchor)
static void grow_pose_factor(const Depsgraph &depsgraph, Object &ob, SculptSession &ss, float pose_origin[3], float pose_target[3], float max_len, float *r_pose_origin, MutableSpan< float > pose_factor)
static std::unique_ptr< IKChain > ik_chain_init_topology(const Depsgraph &depsgraph, Object &object, SculptSession &ss, const Brush &brush, const float3 &initial_location, const float radius)
static void calc_pose_origin_and_factor_grids(Object &object, SculptSession &ss, const float3 &initial_location, float radius, float3 &r_pose_origin, MutableSpan< float > r_pose_factor)
static void calc_bmesh(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, bke::pbvh::BMeshNode &node, Object &object, BrushLocalData &tls)
static void calc_pose_data(const Depsgraph &depsgraph, Object &object, SculptSession &ss, const float3 &initial_location, float radius, float pose_offset, float3 &r_pose_origin, MutableSpan< float > r_pose_factor)
std::unique_ptr< SculptPoseIKChainPreview > preview_ik_chain_init(const Depsgraph &depsgraph, Object &ob, SculptSession &ss, const Brush &brush, const float3 &initial_location, const float radius)
static void pose_brush_init(const Depsgraph &depsgraph, Object &ob, SculptSession &ss, const Brush &brush)
void blur_geometry_data_array(const Object &object, const int iterations, const MutableSpan< float > data)
void fill_factor_from_hide_and_mask(Span< bool > hide_vert, Span< float > mask, Span< int > verts, MutableSpan< float > r_factors)
Definition sculpt.cc:6809
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:6447
void gather_bmesh_positions(const Set< BMVert *, 0 > &verts, MutableSpan< float3 > positions)
Definition sculpt.cc:6353
void gather_data_grids(const SubdivCCG &subdiv_ccg, Span< T > src, Span< int > grids, MutableSpan< T > node_data)
Definition sculpt.cc:6391
void vert_random_access_ensure(Object &object)
Definition sculpt.cc:142
std::optional< int > nearest_vert_calc_mesh(const bke::pbvh::Tree &pbvh, const Span< float3 > vert_positions, const Span< bool > hide_vert, const float3 &location, const float max_distance, const bool use_original)
Definition sculpt.cc:593
Vector< int > find_symm_verts_grids(const Object &object, const int original_vert, const float max_distance)
GroupedSpan< int > calc_vert_neighbors(OffsetIndices< int > faces, Span< int > corner_verts, GroupedSpan< int > vert_to_face, Span< bool > hide_poly, Span< int > verts, Vector< int > &r_offset_data, Vector< int > &r_data)
Definition sculpt.cc:7607
Vector< BMVert *, 64 > BMeshNeighborVerts
void gather_data_bmesh(Span< T > src, const Set< BMVert *, 0 > &verts, MutableSpan< T > node_data)
Definition sculpt.cc:6407
void reset_translations_to_original(MutableSpan< float3 > translations, Span< float3 > positions, Span< float3 > orig_positions)
Definition sculpt.cc:7232
float3 symmetry_flip(const float3 &src, const ePaintSymmetryFlags symm)
void orig_position_data_gather_bmesh(const BMLog &bm_log, const Set< BMVert *, 0 > &verts, MutableSpan< float3 > positions, MutableSpan< float3 > normals)
void scale_translations(MutableSpan< float3 > translations, Span< float > factors)
Definition sculpt.cc:7487
Vector< int > find_symm_verts_mesh(const Depsgraph &depsgraph, const Object &object, const int original_vert, const float max_distance)
void clip_and_lock_translations(const Sculpt &sd, const SculptSession &ss, Span< float3 > positions, Span< int > verts, MutableSpan< float3 > translations)
Definition sculpt.cc:7318
void scatter_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
Definition sculpt.cc:6421
Span< BMVert * > vert_neighbors_get_bmesh(BMVert &vert, BMeshNeighborVerts &r_neighbors)
Definition sculpt.cc:388
void apply_translations(Span< float3 > translations, Span< int > verts, MutableSpan< float3 > positions)
Definition sculpt.cc:7251
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:6381
OrigPositionData orig_position_data_get_grids(const Object &object, const bke::pbvh::GridsNode &node)
std::optional< BMVert * > nearest_vert_calc_bmesh(const bke::pbvh::Tree &pbvh, const float3 &location, const float max_distance, const bool use_original)
Definition sculpt.cc:694
std::optional< SubdivCCGCoord > nearest_vert_calc_grids(const bke::pbvh::Tree &pbvh, const SubdivCCG &subdiv_ccg, const float3 &location, const float max_distance, const bool use_original)
Definition sculpt.cc:640
Span< int > vert_neighbors_get_mesh(const OffsetIndices< int > faces, const Span< int > corner_verts, const GroupedSpan< int > vert_to_face, const Span< bool > hide_poly, const int vert, Vector< int > &r_neighbors)
Definition sculpt.cc:430
void scatter_data_grids(const SubdivCCG &subdiv_ccg, Span< T > node_data, Span< int > grids, MutableSpan< T > dst)
Definition sculpt.cc:6431
Vector< int > find_symm_verts_bmesh(const Object &object, const int original_vert, const float max_distance)
bool is_symmetry_iteration_valid(const char i, const char symm)
T sqrt(const T &a)
T sign(const T &a)
T distance(const T &a, const T &b)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
T distance_squared(const VecBase< T, Size > &a, const VecBase< T, Size > &b)
T abs(const T &a)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
Value parallel_reduce(IndexRange range, int64_t grain_size, const Value &identity, const Function &function, const Reduction &reduction)
Definition BLI_task.hh:151
VecBase< float, 4 > float4
VecBase< float, 3 > float3
ePaintSymmetryFlags SCULPT_mesh_symmetry_xyz_get(const Object &object)
Definition sculpt.cc:185
Span< int > SCULPT_fake_neighbors_ensure(const Depsgraph &depsgraph, Object &ob, const float max_dist)
Definition sculpt.cc:6084
float3 SCULPT_flip_v3_by_symm_area(const float3 &vector, const ePaintSymmetryFlags symm, const ePaintSymmetryAreas symmarea, const float3 &pivot)
Definition sculpt.cc:2849
int SCULPT_vertex_count_get(const Object &object)
Definition sculpt.cc:152
void SCULPT_fake_neighbors_free(Object &ob)
Definition sculpt.cc:6106
bool SCULPT_check_vertex_pivot_symmetry(const float vco[3], const float pco[3], const char symm)
Definition sculpt.cc:549
ePaintSymmetryAreas SCULPT_get_vertex_symm_area(const float co[3])
Definition sculpt.cc:2806
void SCULPT_flip_quat_by_symm_area(float quat[4], const ePaintSymmetryFlags symm, const ePaintSymmetryAreas symmarea, const float pivot[3])
Definition sculpt.cc:2870
#define FAKE_NEIGHBOR_NONE
#define FLT_MAX
Definition stdcycles.h:14
float co[3]
CustomData pdata
int pose_deform_type
int pose_smooth_iterations
struct CurveMapping * curve
int pose_ik_segments
float disconnected_distance_max
int deform_target
float pose_offset
int pose_origin_type
int grid_size
Definition BKE_ccg.hh:33
int grid_area
Definition BKE_ccg.hh:35
struct SculptSession * sculpt
blender::Array< int > fake_neighbor_index
Definition BKE_paint.hh:369
blender::ed::sculpt_paint::StrokeCache * cache
Definition BKE_paint.hh:437
BMLog * bm_log
Definition BKE_paint.hh:412
SubdivCCG * subdiv_ccg
Definition BKE_paint.hh:415
ActiveVert active_vert() const
Definition paint.cc:2227
int active_vert_index() const
Definition paint.cc:2237
SculptFakeNeighbors fake_neighbors
Definition BKE_paint.hh:483
int to_index(const CCGKey &key) const
static SubdivCCGCoord from_index(const CCGKey &key, int index)
SubdivCCGNeighborCoords coords
blender::BitGroupVector grid_hidden
blender::Array< blender::float3 > positions
std::unique_ptr< pose::IKChain > pose_ik_chain
std::unique_ptr< auto_mask::Cache > automasking
std::unique_ptr< cloth::SimulationData > cloth_sim
void execute(Object &object, FunctionRef< bool(BMVert *from_v, BMVert *to_v)> func)
void execute(Object &object, const SubdivCCG &subdiv_ccg, FunctionRef< bool(SubdivCCGCoord from_v, SubdivCCGCoord to_v, bool is_duplicate)> func)
void execute(Object &object, GroupedSpan< int > vert_to_face_map, FunctionRef< bool(int from_v, int to_v)> func)
static PoseGrowFactorData join(const PoseGrowFactorData &a, const PoseGrowFactorData &b)
i
Definition text_draw.cc:230
max
Definition text_draw.cc:251
uint len