41static bool check_counts(
const int neighbor_count,
const int boundary_vertex_count)
45 if (neighbor_count <= 2) {
51 if (boundary_vertex_count > 2) {
68 const int initial_vert)
70 if (!hide_vert.
is_empty() && hide_vert[initial_vert]) {
74 int neighbor_count = 0;
75 int boundary_vertex_count = 0;
79 faces, corner_verts, vert_to_face, hide_poly, initial_vert, neighbors))
81 if (hide_vert.
is_empty() || !hide_vert[neighbor]) {
84 boundary_vertex_count++;
89 return check_counts(neighbor_count, boundary_vertex_count);
108 int neighbor_count = 0;
109 int boundary_vertex_count = 0;
111 if (grid_hidden.
is_empty() || !grid_hidden[neighbor.grid_index][neighbor.to_index(key)]) {
114 boundary_vertex_count++;
119 return check_counts(neighbor_count, boundary_vertex_count);
128 int neighbor_count = 0;
129 int boundary_vertex_count = 0;
136 boundary_vertex_count++;
141 return check_counts(neighbor_count, boundary_vertex_count);
157 const int initial_vert,
165 flood_fill.add_initial(initial_vert);
167 const float3 initial_vert_position = vert_positions[initial_vert];
168 const float radius_sq = radius * radius;
170 std::optional<int> boundary_initial_vert;
171 int boundary_initial_vert_steps = std::numeric_limits<int>::max();
174 flood_fill.execute(
object, vert_to_face, [&](
int from_v,
int to_v) {
175 if (!hide_vert.
is_empty() && hide_vert[from_v]) {
179 floodfill_steps[to_v] = floodfill_steps[from_v] + 1;
182 if (floodfill_steps[to_v] < boundary_initial_vert_steps) {
183 boundary_initial_vert_steps = floodfill_steps[to_v];
184 boundary_initial_vert = to_v;
189 return len_sq < radius_sq;
192 return boundary_initial_vert;
212 flood_fill.add_initial(initial_vert);
214 const float3 initial_vert_position = positions[initial_vert.
to_index(key)];
215 const float radius_sq = radius * radius;
217 int boundary_initial_vert_steps = std::numeric_limits<int>::max();
218 Array<int> floodfill_steps(positions.size(), 0);
219 std::optional<SubdivCCGCoord> boundary_initial_vert;
223 const int to_v_index = to_v.
to_index(key);
224 const int from_v_index = from_v.
to_index(key);
231 floodfill_steps[to_v_index] = floodfill_steps[from_v_index];
234 floodfill_steps[to_v_index] = floodfill_steps[from_v_index] + 1;
238 if (floodfill_steps[to_v_index] < boundary_initial_vert_steps) {
239 boundary_initial_vert_steps = floodfill_steps[to_v_index];
240 boundary_initial_vert = to_v;
246 return len_sq < radius_sq;
249 return boundary_initial_vert;
258 return &initial_vert;
263 flood_fill.add_initial(&initial_vert);
265 const float3 initial_vert_position = initial_vert.
co;
266 const float radius_sq = radius * radius;
268 int boundary_initial_vert_steps = std::numeric_limits<int>::max();
270 std::optional<BMVert *> boundary_initial_vert;
272 flood_fill.execute(
object, [&](
BMVert *from_v,
BMVert *to_v) {
280 floodfill_steps[to_v_i] = floodfill_steps[from_v_i] + 1;
283 if (floodfill_steps[to_v_i] < boundary_initial_vert_steps) {
284 boundary_initial_vert_steps = floodfill_steps[to_v_i];
285 boundary_initial_vert = to_v;
290 return len_sq < radius_sq;
293 return boundary_initial_vert;
309 const float distance,
312 boundary.verts.append(new_index);
314 boundary.distance.add(new_index, distance);
315 included_verts.
add(new_index);
329 const int initial_boundary_vert,
335 add_index(boundary, initial_boundary_vert, 0.0f, included_verts);
336 flood_fill.add_initial(initial_boundary_vert);
338 flood_fill.execute(
object, vert_to_face, [&](
const int from_v,
const int to_v) {
339 const float3 from_v_co = vert_positions[from_v];
340 const float3 to_v_co = vert_positions[to_v];
345 const float edge_len =
len_v3v3(from_v_co, to_v_co);
346 const float distance_boundary_to_dst = boundary.distance.lookup_default(from_v, 0.0f) +
348 add_index(boundary, to_v, distance_boundary_to_dst, included_verts);
349 boundary.edges.append({from_v_co, to_v_co});
351 faces, corner_verts, vert_to_face, hide_vert, hide_poly, boundary_verts, to_v);
367 const int initial_boundary_index = initial_vert.
to_index(key);
369 add_index(boundary, initial_boundary_index, 0.0f, included_verts);
370 flood_fill.add_initial(initial_vert);
376 const int from_v_i = from_v.
to_index(key);
377 const int to_v_i = to_v.
to_index(key);
379 const float3 &from_v_co = positions[from_v_i];
380 const float3 &to_v_co = positions[to_v_i];
385 const float edge_len =
len_v3v3(from_v_co, to_v_co);
386 const float distance_boundary_to_dst = boundary.distance.lookup_default(from_v_i, 0.0f) +
388 add_index(boundary, to_v_i, distance_boundary_to_dst, included_verts);
390 boundary.edges.append({from_v_co, to_v_co});
393 faces, corner_verts, subdiv_ccg, boundary_verts, to_v);
399 BMVert &initial_boundary_vert,
407 add_index(boundary, initial_boundary_index, 0.0f, included_verts);
408 flood_fill.add_initial(&initial_boundary_vert);
410 flood_fill.execute(
object, [&](
BMVert *from_v,
BMVert *to_v) {
414 const float3 from_v_co = from_v->
co;
420 const float edge_len =
len_v3v3(from_v_co, to_v_co);
421 const float distance_boundary_to_dst = boundary.distance.lookup_default(from_v_i, 0.0f) +
423 add_index(boundary, to_v_i, distance_boundary_to_dst, included_verts);
424 boundary.edges.append({from_v_co, to_v_co});
435#define BOUNDARY_VERTEX_NONE -1
436#define BOUNDARY_STEPS_NONE -1
450 const int initial_vert_i,
455 boundary.edit_info.propagation_steps_num =
Array<int>(vert_positions.
size(),
457 boundary.edit_info.strength_factor =
Array<float>(vert_positions.
size(), 0.0f);
459 std::queue<int> current_iteration;
461 for (
const int i : boundary.verts.index_range()) {
462 const int vert = boundary.verts[i];
463 const int index = boundary.verts[i];
465 boundary.edit_info.original_vertex_i[index] = index;
466 boundary.edit_info.propagation_steps_num[index] = 0;
468 current_iteration.push(vert);
471 int propagation_steps_num = 0;
472 float accum_distance = 0.0f;
474 std::queue<int> next_iteration;
479 if (accum_distance > radius || current_iteration.empty()) {
480 boundary.max_propagation_steps = propagation_steps_num;
484 while (!current_iteration.empty()) {
485 const int from_v = current_iteration.front();
486 current_iteration.pop();
490 faces, corner_verts, vert_to_face, hide_poly, from_v, neighbors))
492 if ((!hide_vert.
is_empty() && hide_vert[from_v]) ||
498 boundary.edit_info.original_vertex_i[neighbor] =
499 boundary.edit_info.original_vertex_i[from_v];
501 boundary.edit_info.propagation_steps_num[neighbor] =
502 boundary.edit_info.propagation_steps_num[from_v] + 1;
504 next_iteration.push(neighbor);
508 if (boundary.edit_info.original_vertex_i[from_v] == initial_vert_i) {
509 boundary.pivot_position = vert_positions[neighbor];
510 accum_distance +=
math::distance(vert_positions[from_v], boundary.pivot_position);
516 while (!next_iteration.empty()) {
517 const int next_v = next_iteration.front();
518 next_iteration.pop();
519 current_iteration.push(next_v);
522 propagation_steps_num++;
527 const int initial_vert_i,
536 boundary.edit_info.strength_factor =
Array<float>(positions.size(), 0.0f);
538 std::queue<SubdivCCGCoord> current_iteration;
540 for (
const int i : boundary.verts.index_range()) {
543 const int index = boundary.verts[i];
545 boundary.edit_info.original_vertex_i[index] = index;
546 boundary.edit_info.propagation_steps_num[index] = 0;
551 boundary.edit_info.original_vertex_i[neighbor.to_index(key)] = index;
554 current_iteration.push(vert);
557 int propagation_steps_num = 0;
558 float accum_distance = 0.0f;
560 std::queue<SubdivCCGCoord> next_iteration;
565 if (accum_distance > radius || current_iteration.empty()) {
566 boundary.max_propagation_steps = propagation_steps_num;
570 while (!current_iteration.empty()) {
572 current_iteration.pop();
574 const int from_v_i = from_v.
to_index(key);
580 const int neighbor_idx = neighbor.to_index(key);
584 subdiv_ccg.
grid_hidden[neighbor.grid_index][index_in_grid];
590 boundary.edit_info.original_vertex_i[neighbor_idx] =
591 boundary.edit_info.original_vertex_i[from_v_i];
593 boundary.edit_info.propagation_steps_num[neighbor_idx] =
594 boundary.edit_info.propagation_steps_num[from_v_i];
598 const int neighbor_idx = neighbor.to_index(key);
602 subdiv_ccg.
grid_hidden[neighbor.grid_index][index_in_grid];
608 boundary.edit_info.original_vertex_i[neighbor_idx] =
609 boundary.edit_info.original_vertex_i[from_v_i];
611 boundary.edit_info.propagation_steps_num[neighbor_idx] =
612 boundary.edit_info.propagation_steps_num[from_v_i] + 1;
614 next_iteration.push(neighbor);
625 const int neighbor_duplicate_index = coord.to_index(key);
626 boundary.edit_info.original_vertex_i[neighbor_duplicate_index] =
627 boundary.edit_info.original_vertex_i[from_v_i];
628 boundary.edit_info.propagation_steps_num[neighbor_duplicate_index] =
629 boundary.edit_info.propagation_steps_num[from_v_i] + 1;
634 if (boundary.edit_info.original_vertex_i[from_v_i] == initial_vert_i) {
635 boundary.pivot_position = positions[neighbor_idx];
636 accum_distance +=
math::distance(positions[from_v_i], boundary.pivot_position);
642 while (!next_iteration.empty()) {
644 next_iteration.pop();
645 current_iteration.push(next_v);
648 propagation_steps_num++;
653 const int initial_vert_i,
661 boundary.edit_info.strength_factor =
Array<float>(num_verts, 0.0f);
663 std::queue<BMVert *> current_iteration;
665 for (
const int i : boundary.verts.index_range()) {
666 const int index = boundary.verts[i];
669 boundary.edit_info.original_vertex_i[index] = index;
670 boundary.edit_info.propagation_steps_num[index] = 0;
674 current_iteration.push(vert);
677 int propagation_steps_num = 0;
678 float accum_distance = 0.0f;
680 std::queue<BMVert *> next_iteration;
685 if (accum_distance > radius || current_iteration.empty()) {
686 boundary.max_propagation_steps = propagation_steps_num;
690 while (!current_iteration.empty()) {
691 BMVert *from_v = current_iteration.front();
692 current_iteration.pop();
704 boundary.edit_info.original_vertex_i[neighbor_idx] =
705 boundary.edit_info.original_vertex_i[from_v_i];
707 boundary.edit_info.propagation_steps_num[neighbor_idx] =
708 boundary.edit_info.propagation_steps_num[from_v_i] + 1;
710 next_iteration.push(neighbor);
714 if (boundary.edit_info.original_vertex_i[from_v_i] == initial_vert_i) {
715 boundary.pivot_position = neighbor->co;
722 while (!next_iteration.empty()) {
723 BMVert *next_v = next_iteration.front();
724 next_iteration.pop();
725 current_iteration.push(next_v);
728 propagation_steps_num++;
748 BLI_assert(boundary.edit_info.original_vertex_i.size() ==
749 boundary.edit_info.propagation_steps_num.size());
750 BLI_assert(boundary.edit_info.original_vertex_i.size() ==
751 boundary.edit_info.strength_factor.size());
753 const int num_elements = boundary.edit_info.strength_factor.size();
758 for (
const int i :
IndexRange(num_elements)) {
759 if (boundary.edit_info.propagation_steps_num[i] != boundary.max_propagation_steps) {
763 const int orig_vert_i = boundary.edit_info.original_vertex_i[i];
765 const float3 normal = vert_normals[i];
766 const float3 dir = vert_positions[orig_vert_i] - vert_positions[i];
768 boundary.bend.pivot_positions[orig_vert_i] = vert_positions[i];
771 for (
const int i :
IndexRange(num_elements)) {
775 const int orig_vert_i = boundary.edit_info.original_vertex_i[i];
777 boundary.bend.pivot_positions[i] = boundary.bend.pivot_positions[orig_vert_i];
778 boundary.bend.pivot_rotation_axis[i] = boundary.bend.pivot_rotation_axis[orig_vert_i];
784 BLI_assert(boundary.edit_info.original_vertex_i.size() ==
785 boundary.edit_info.propagation_steps_num.size());
786 BLI_assert(boundary.edit_info.original_vertex_i.size() ==
787 boundary.edit_info.strength_factor.size());
789 const int num_elements = boundary.edit_info.strength_factor.size();
797 for (
const int i :
IndexRange(num_elements)) {
798 if (boundary.edit_info.propagation_steps_num[i] != boundary.max_propagation_steps) {
802 const int orig_vert_i = boundary.edit_info.original_vertex_i[i];
804 const float3 normal = normals[i];
805 const float3 dir = positions[orig_vert_i] - positions[i];
807 boundary.bend.pivot_positions[orig_vert_i] = positions[i];
810 for (
const int i :
IndexRange(num_elements)) {
814 const int orig_vert_i = boundary.edit_info.original_vertex_i[i];
816 boundary.bend.pivot_positions[i] = boundary.bend.pivot_positions[orig_vert_i];
817 boundary.bend.pivot_rotation_axis[i] = boundary.bend.pivot_rotation_axis[orig_vert_i];
823 BLI_assert(boundary.edit_info.original_vertex_i.size() ==
824 boundary.edit_info.propagation_steps_num.size());
825 BLI_assert(boundary.edit_info.original_vertex_i.size() ==
826 boundary.edit_info.strength_factor.size());
828 const int num_elements = boundary.edit_info.strength_factor.size();
833 for (
const int i :
IndexRange(num_elements)) {
834 if (boundary.edit_info.propagation_steps_num[i] != boundary.max_propagation_steps) {
839 const int orig_vert_i = boundary.edit_info.original_vertex_i[i];
845 boundary.bend.pivot_positions[boundary.edit_info.original_vertex_i[i]] = vert->
co;
848 for (
const int i :
IndexRange(num_elements)) {
852 const int orig_vert_i = boundary.edit_info.original_vertex_i[i];
853 boundary.bend.pivot_positions[i] = boundary.bend.pivot_positions[orig_vert_i];
854 boundary.bend.pivot_rotation_axis[i] = boundary.bend.pivot_rotation_axis[orig_vert_i];
860 BLI_assert(boundary.edit_info.original_vertex_i.size() ==
861 boundary.edit_info.propagation_steps_num.size());
862 BLI_assert(boundary.edit_info.original_vertex_i.size() ==
863 boundary.edit_info.strength_factor.size());
865 const int num_elements = boundary.edit_info.strength_factor.size();
868 for (
const int i :
IndexRange(num_elements)) {
869 if (boundary.edit_info.propagation_steps_num[i] != boundary.max_propagation_steps) {
872 const int orig_vert_i = boundary.edit_info.original_vertex_i[i];
873 boundary.slide.directions[orig_vert_i] =
math::normalize(vert_positions[orig_vert_i] -
877 for (
const int i :
IndexRange(num_elements)) {
881 boundary.slide.directions[i] =
882 boundary.slide.directions[boundary.edit_info.original_vertex_i[i]];
888 BLI_assert(boundary.edit_info.original_vertex_i.size() ==
889 boundary.edit_info.propagation_steps_num.size());
890 BLI_assert(boundary.edit_info.original_vertex_i.size() ==
891 boundary.edit_info.strength_factor.size());
893 const int num_elements = boundary.edit_info.strength_factor.size();
898 for (
const int i :
IndexRange(num_elements)) {
899 if (boundary.edit_info.propagation_steps_num[i] != boundary.max_propagation_steps) {
902 const int orig_vert_i = boundary.edit_info.original_vertex_i[i];
904 boundary.slide.directions[orig_vert_i] =
math::normalize(positions[orig_vert_i] -
908 for (
const int i :
IndexRange(num_elements)) {
912 boundary.slide.directions[i] =
913 boundary.slide.directions[boundary.edit_info.original_vertex_i[i]];
919 BLI_assert(boundary.edit_info.original_vertex_i.size() ==
920 boundary.edit_info.propagation_steps_num.size());
921 BLI_assert(boundary.edit_info.original_vertex_i.size() ==
922 boundary.edit_info.strength_factor.size());
924 const int num_elements = boundary.edit_info.strength_factor.size();
927 for (
const int i :
IndexRange(num_elements)) {
928 if (boundary.edit_info.propagation_steps_num[i] != boundary.max_propagation_steps) {
932 const int orig_vert_i = boundary.edit_info.original_vertex_i[i];
938 for (
const int i :
IndexRange(num_elements)) {
942 boundary.slide.directions[i] =
943 boundary.slide.directions[boundary.edit_info.original_vertex_i[i]];
949 boundary.twist.pivot_position =
float3(0);
950 for (
const float3 &position : positions) {
951 boundary.twist.pivot_position += position;
953 boundary.twist.pivot_position *= 1.0f / boundary.verts.size();
954 boundary.twist.rotation_axis =
math::normalize(boundary.pivot_position -
955 boundary.initial_vert_position);
961 array_utils::gather(vert_positions, boundary.verts.as_span(), positions.as_mutable_span());
969 array_utils::gather(vert_positions, boundary.verts.as_span(), positions.as_mutable_span());
976 for (
const int i : positions.index_range()) {
978 positions[i] = vert->
co;
1084 for (
const int i : positions.index_range()) {
1085 float3 from_pivot_to_pos = positions[i] - pivot_positions[i];
1088 new_positions[i] = rotated + pivot_positions[i];
1101 const float3 symmetry_pivot,
1102 const float strength,
1160 const float3 symmetry_pivot,
1161 const float strength,
1175 subdiv_ccg, vert_factors, grids, tls.
factors);
1190 subdiv_ccg, vert_pivot_axes, grids, tls.
pivot_axes);
1211 cache.
cloth_sim->deformation_pos.as_mutable_span());
1225 const float3 symmetry_pivot,
1226 const float strength,
1258 calc_bend_position(orig_positions, pivot_positions, pivot_axes, factors, new_positions);
1283 const float strength,
1287 switch (pbvh.
type()) {
1298 boundary.edit_info.propagation_steps_num,
1299 boundary.edit_info.strength_factor,
1300 boundary.bend.pivot_positions,
1301 boundary.bend.pivot_rotation_axis,
1304 boundary.initial_vert_position,
1313 SubdivCCG &subdiv_ccg = *
object.sculpt->subdiv_ccg;
1323 boundary.edit_info.propagation_steps_num,
1324 boundary.edit_info.strength_factor,
1325 boundary.bend.pivot_positions,
1326 boundary.bend.pivot_rotation_axis,
1329 boundary.initial_vert_position,
1344 boundary.edit_info.propagation_steps_num,
1345 boundary.edit_info.strength_factor,
1346 boundary.bend.pivot_positions,
1347 boundary.bend.pivot_rotation_axis,
1350 boundary.initial_vert_position,
1377 for (
const int i : positions.index_range()) {
1378 new_positions[i] = positions[i] + (directions[i] * factors[i]);
1390 const float3 symmetry_pivot,
1391 const float strength,
1448 const float3 symmetry_pivot,
1449 const float strength,
1463 subdiv_ccg, vert_factors, grids, tls.
factors);
1498 cache.
cloth_sim->deformation_pos.as_mutable_span());
1511 const float3 symmetry_pivot,
1512 const float strength,
1568 const float strength,
1572 switch (pbvh.
type()) {
1583 boundary.edit_info.propagation_steps_num,
1584 boundary.edit_info.strength_factor,
1585 boundary.slide.directions,
1588 boundary.initial_vert_position,
1597 SubdivCCG &subdiv_ccg = *
object.sculpt->subdiv_ccg;
1607 boundary.edit_info.propagation_steps_num,
1608 boundary.edit_info.strength_factor,
1609 boundary.slide.directions,
1612 boundary.initial_vert_position,
1627 boundary.edit_info.propagation_steps_num,
1628 boundary.edit_info.strength_factor,
1629 boundary.slide.directions,
1632 boundary.initial_vert_position,
1655 BLI_assert(positions.size() == normals.size());
1659 for (
const int i : positions.index_range()) {
1660 new_positions[i] = positions[i] + (normals[i] * factors[i]);
1671 const float3 symmetry_pivot,
1672 const float strength,
1724 const float3 symmetry_pivot,
1725 const float strength,
1739 subdiv_ccg, vert_factors, grids, tls.
factors);
1770 cache.
cloth_sim->deformation_pos.as_mutable_span());
1782 const float3 symmetry_pivot,
1783 const float strength,
1836 const float strength,
1840 switch (pbvh.
type()) {
1851 boundary.edit_info.propagation_steps_num,
1852 boundary.edit_info.strength_factor,
1855 boundary.initial_vert_position,
1864 SubdivCCG &subdiv_ccg = *
object.sculpt->subdiv_ccg;
1874 boundary.edit_info.propagation_steps_num,
1875 boundary.edit_info.strength_factor,
1878 boundary.initial_vert_position,
1893 boundary.edit_info.propagation_steps_num,
1894 boundary.edit_info.strength_factor,
1897 boundary.initial_vert_position,
1923 for (
const int i : positions.index_range()) {
1924 new_positions[i] = positions[i] + (grab_delta * factors[i]);
1935 const float3 grab_delta_symmetry,
1936 const float3 symmetry_pivot,
1937 const float strength,
1989 const float3 grab_delta_symmetry,
1990 const float3 symmetry_pivot,
1991 const float strength,
2005 subdiv_ccg, vert_factors, grids, tls.
factors);
2036 cache.
cloth_sim->deformation_pos.as_mutable_span());
2048 const float3 grab_delta_symmetry,
2049 const float3 symmetry_pivot,
2050 const float strength,
2103 const float strength,
2108 switch (pbvh.
type()) {
2119 boundary.edit_info.propagation_steps_num,
2120 boundary.edit_info.strength_factor,
2124 boundary.initial_vert_position,
2133 SubdivCCG &subdiv_ccg = *
object.sculpt->subdiv_ccg;
2143 boundary.edit_info.propagation_steps_num,
2144 boundary.edit_info.strength_factor,
2148 boundary.initial_vert_position,
2163 boundary.edit_info.propagation_steps_num,
2164 boundary.edit_info.strength_factor,
2168 boundary.initial_vert_position,
2187 const float3 pivot_point,
2195 for (
const int i : positions.index_range()) {
2207 const float3 twist_pivot_position,
2209 const float3 symmetry_pivot,
2210 const float strength,
2237 orig_data.
positions, twist_pivot_position, twist_axis, factors, new_positions);
2261 const float3 twist_pivot_position,
2265 const float3 symmetry_pivot,
2266 const float strength,
2280 subdiv_ccg, vert_factors, grids, tls.
factors);
2295 orig_data.
positions, twist_pivot_position, twist_axis, factors, new_positions);
2312 cache.
cloth_sim->deformation_pos.as_mutable_span());
2322 const float3 twist_pivot_position,
2326 const float3 symmetry_pivot,
2327 const float strength,
2355 calc_twist_position(orig_positions, twist_pivot_position, twist_axis, factors, new_positions);
2380 const float strength,
2384 switch (pbvh.
type()) {
2395 boundary.edit_info.propagation_steps_num,
2396 boundary.edit_info.strength_factor,
2399 boundary.twist.pivot_position,
2400 boundary.twist.rotation_axis,
2401 boundary.initial_vert_position,
2410 SubdivCCG &subdiv_ccg = *
object.sculpt->subdiv_ccg;
2420 boundary.edit_info.propagation_steps_num,
2421 boundary.edit_info.strength_factor,
2422 boundary.twist.pivot_position,
2423 boundary.twist.rotation_axis,
2426 boundary.initial_vert_position,
2441 boundary.edit_info.propagation_steps_num,
2442 boundary.edit_info.strength_factor,
2443 boundary.twist.pivot_position,
2444 boundary.twist.rotation_axis,
2447 boundary.initial_vert_position,
2474 for (
const int i : positions.index_range()) {
2475 const float3 to_smooth = average_position[i] - positions[i];
2476 new_positions[i] = positions[i] + (to_smooth * factors[i]);
2492 for (
const int i : neighbors.index_range()) {
2493 average_positions[i] =
float3(0.0f);
2494 int valid_neighbors = 0;
2495 for (
const int neighbor : neighbors[i]) {
2496 if (propagation_steps[i] == vert_propagation_steps[neighbor]) {
2497 average_positions[i] += vert_positions[neighbor];
2502 if (valid_neighbors == 0) {
2522 for (
const int i : neighbors.index_range()) {
2523 average_positions[i] =
float3(0.0f);
2524 int valid_neighbors = 0;
2526 if (propagation_steps[i] == vert_propagation_steps[neighbor.to_index(key)]) {
2527 average_positions[i] += positions[neighbor.to_index(key)];
2532 if (valid_neighbors == 0) {
2548 for (
const int i : neighbors.index_range()) {
2549 average_positions[i] =
float3(0.0f);
2550 int valid_neighbors = 0;
2551 for (
BMVert *neighbor : neighbors[i]) {
2553 if (propagation_steps[i] == vert_propagation_steps[neighbor_idx]) {
2554 average_positions[i] += neighbor->co;
2559 if (valid_neighbors == 0) {
2575 const float3 symmetry_pivot,
2576 const float strength,
2607 vert_propagation_steps,
2640 const float3 symmetry_pivot,
2641 const float strength,
2655 subdiv_ccg, vert_factors, grids, tls.
factors);
2672 vert_propagation_steps,
2698 cache.
cloth_sim->deformation_pos.as_mutable_span());
2709 const float3 symmetry_pivot,
2710 const float strength,
2741 vert_propagation_steps, neighbors, propagation_steps, factors, average_positions);
2770 const float strength,
2774 switch (pbvh.
type()) {
2776 Mesh &mesh = *
static_cast<Mesh *
>(
object.data);
2779 const Span<int> corner_verts = mesh.corner_verts();
2794 boundary.edit_info.propagation_steps_num,
2795 boundary.edit_info.strength_factor,
2798 boundary.initial_vert_position,
2807 SubdivCCG &subdiv_ccg = *
object.sculpt->subdiv_ccg;
2816 boundary.edit_info.propagation_steps_num,
2817 boundary.edit_info.strength_factor,
2820 boundary.initial_vert_position,
2834 boundary.edit_info.propagation_steps_num,
2835 boundary.edit_info.strength_factor,
2838 boundary.initial_vert_position,
2870 const float boundary_distance = boundary.distance.lookup_default(index, 0.0f);
2871 float falloff_distance = 0.0f;
2872 float direction = 1.0f;
2876 falloff_distance = boundary_distance;
2879 const int div = boundary_distance / radius;
2880 const float mod =
fmodf(boundary_distance, radius);
2881 falloff_distance = div % 2 == 0 ?
mod : radius -
mod;
2885 const int div = boundary_distance / radius;
2886 const float mod =
fmodf(boundary_distance, radius);
2887 falloff_distance = div % 2 == 0 ?
mod : radius -
mod;
2889 if (((div - 1) & 2) == 0) {
2900 return {falloff_distance, direction};
2912 BLI_assert(boundary.edit_info.original_vertex_i.size() ==
2913 boundary.edit_info.propagation_steps_num.size());
2914 BLI_assert(boundary.edit_info.original_vertex_i.size() ==
2915 boundary.edit_info.strength_factor.size());
2917 const int num_elements = boundary.edit_info.strength_factor.size();
2920 for (
const int i :
IndexRange(num_elements)) {
2922 const float mask_factor = mask.is_empty() ? 1.0f : 1.0f - mask[i];
2923 boundary.edit_info.strength_factor[i] = mask_factor *
2926 boundary.edit_info.propagation_steps_num[i],
2927 boundary.max_propagation_steps);
2930 if (boundary.edit_info.original_vertex_i[i] == boundary.initial_vert_i) {
2939 if (!use_boundary_distances) {
2946 boundary, brush, radius, boundary.edit_info.original_vertex_i[i]);
2948 &brush, falloff_distance, radius);
2957 BLI_assert(boundary.edit_info.original_vertex_i.size() ==
2958 boundary.edit_info.propagation_steps_num.size());
2959 BLI_assert(boundary.edit_info.original_vertex_i.size() ==
2960 boundary.edit_info.strength_factor.size());
2969 const float mask_factor = subdiv_ccg.
masks.
is_empty() ? 1.0f :
2970 1.0f - subdiv_ccg.
masks[index];
2971 boundary.edit_info.strength_factor[index] =
2973 boundary.edit_info.propagation_steps_num[index],
2974 boundary.max_propagation_steps);
2977 if (boundary.edit_info.original_vertex_i[index] == boundary.initial_vert_i) {
2986 if (!use_boundary_distances) {
2993 boundary, brush, radius, boundary.edit_info.original_vertex_i[index]);
2994 boundary.edit_info.strength_factor[index] *= direction *
2996 &brush, falloff_distance, radius);
3006 BLI_assert(boundary.edit_info.original_vertex_i.size() ==
3007 boundary.edit_info.propagation_steps_num.size());
3008 BLI_assert(boundary.edit_info.original_vertex_i.size() ==
3009 boundary.edit_info.strength_factor.size());
3011 const int num_elements = boundary.edit_info.strength_factor.size();
3015 for (
const int i :
IndexRange(num_elements)) {
3020 const float mask_factor = mask_offset == -1 ? 1.0f :
3023 boundary.edit_info.strength_factor[i] = mask_factor *
3026 boundary.edit_info.propagation_steps_num[i],
3027 boundary.max_propagation_steps);
3030 if (boundary.edit_info.original_vertex_i[i] == boundary.initial_vert_i) {
3039 if (!use_boundary_distances) {
3046 boundary, brush, radius, boundary.edit_info.original_vertex_i[i]);
3048 &brush, falloff_distance, radius);
3060 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
3069 if (std::holds_alternative<std::monostate>(initial_vert_ref)) {
3073 std::optional<int> initial_vert;
3075 initial_vert = std::get<int>(initial_vert_ref);
3078 float3 location =
symmetry_flip(positions_eval[std::get<int>(initial_vert_ref)], symm_area);
3083 if (!initial_vert) {
3124 if (std::holds_alternative<std::monostate>(initial_vert_ref)) {
3128 std::optional<SubdivCCGCoord> initial_vert;
3130 initial_vert = std::get<SubdivCCGCoord>(initial_vert_ref);
3133 const SubdivCCGCoord active_vert = std::get<SubdivCCGCoord>(initial_vert_ref);
3139 if (!initial_vert) {
3179 if (std::holds_alternative<std::monostate>(initial_vert_ref)) {
3183 std::optional<BMVert *> initial_vert;
3185 initial_vert = std::get<BMVert *>(initial_vert_ref);
3188 BMVert *active_vert = std::get<BMVert *>(initial_vert_ref);
3193 if (!initial_vert) {
3235 angle_factor =
floorf(angle_factor * 10) / 10.0f;
3237 return angle_factor *
M_PI;
3252 angle_factor =
floorf(angle_factor * 10) / 10.0f;
3254 return angle_factor *
M_PI;
3275 switch (pbvh.
type()) {
3362 const int initial_vert,
3370 switch (pbvh.
type()) {
3392 const int initial_vert,
3399 Mesh &mesh = *
static_cast<Mesh *
>(
object.data);
3401 const Span<int> corner_verts = mesh.corner_verts();
3419 if (!boundary_initial_vert) {
3439 std::unique_ptr<SculptBoundary> boundary = std::make_unique<SculptBoundary>();
3442 const int boundary_initial_vert_index = *boundary_initial_vert;
3443 boundary->initial_vert_i = boundary_initial_vert_index;
3444 boundary->initial_vert_position = positions_eval[boundary_initial_vert_index];
3454 *boundary_initial_vert,
3457 const float boundary_radius = brush ? radius * (1.0f + brush->
boundary_offset) : radius;
3464 boundary_initial_vert_index,
3480 Mesh &mesh = *
static_cast<Mesh *
>(
object.data);
3482 const Span<int> corner_verts = mesh.corner_verts();
3490 if (!boundary_initial_vert) {
3502 std::unique_ptr<SculptBoundary> boundary = std::make_unique<SculptBoundary>();
3506 const int boundary_initial_vert_index = boundary_vert.
to_index(key);
3507 boundary->initial_vert_i = boundary_initial_vert_index;
3508 boundary->initial_vert_position = positions[boundary_initial_vert_index];
3511 object, faces, corner_verts, subdiv_ccg, ss.
vertex_info.
boundary, boundary_vert, *boundary);
3513 const float boundary_radius = brush ? radius * (1.0f + brush->
boundary_offset) : radius;
3530 object, ss.
bm, *initial_vert, radius);
3532 if (!boundary_initial_vert) {
3542 std::unique_ptr<SculptBoundary> boundary = std::make_unique<SculptBoundary>();
3545 const int boundary_initial_vert_index =
BM_elem_index_get(*boundary_initial_vert);
3546 boundary->initial_vert_i = boundary_initial_vert_index;
3547 boundary->initial_vert_position = (*boundary_initial_vert)->co;
3551 const float boundary_radius = brush ? radius * (1.0f + brush->
boundary_offset) : radius;
3573 if (std::holds_alternative<std::monostate>(initial_vert)) {
3579 std::unique_ptr<SculptBoundary> boundary =
nullptr;
3580 switch (pbvh.
type()) {
3585 boundary =
data_init_grids(
object, brush, std::get<SubdivCCGCoord>(initial_vert), radius);
3588 boundary =
data_init_bmesh(
object, brush, std::get<BMVert *>(initial_vert), radius);
3592 if (boundary ==
nullptr) {
3595 std::unique_ptr<SculptBoundaryPreview> preview = std::make_unique<SculptBoundaryPreview>();
3596 preview->edges = boundary->edges;
3597 preview->pivot_position = boundary->pivot_position;
3598 preview->initial_vert_position = boundary->initial_vert_position;
3605 const float outline_col[3],
3606 const float outline_alpha)
float BKE_brush_curve_strength(eBrushCurvePreset preset, const CurveMapping *cumap, float distance, float brush_radius)
int CCG_grid_xy_to_index(const int grid_size, const int x, const int y)
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
std::variant< std::monostate, int, SubdivCCGCoord, BMVert * > ActiveVert
const Brush * BKE_paint_brush_for_read(const Paint *paint)
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()
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
float dist_signed_to_plane_v3(const float p[3], const float plane[4])
void rotate_v3_v3v3fl(float r[3], const float p[3], const float axis[3], float angle)
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
@ BRUSH_DEFORM_TARGET_CLOTH_SIM
@ BRUSH_DEFORM_TARGET_GEOMETRY
@ BRUSH_BOUNDARY_DEFORM_GRAB
@ BRUSH_BOUNDARY_DEFORM_TWIST
@ BRUSH_BOUNDARY_DEFORM_BEND
@ BRUSH_BOUNDARY_DEFORM_EXPAND
@ BRUSH_BOUNDARY_DEFORM_INFLATE
@ BRUSH_BOUNDARY_DEFORM_SMOOTH
@ BRUSH_BOUNDARY_FALLOFF_CONSTANT
@ BRUSH_BOUNDARY_FALLOFF_LOOP
@ BRUSH_BOUNDARY_FALLOFF_LOOP_INVERT
@ BRUSH_BOUNDARY_FALLOFF_RADIUS
Object is a sort of wrapper for general info.
void GPU_line_width(float width)
#define BM_ELEM_CD_GET_FLOAT(ele, offset)
#define BM_elem_index_get(ele)
#define BM_elem_flag_test(ele, hflag)
ATTR_WARN_UNUSED_RESULT BMesh * bm
int BM_mesh_elem_count(BMesh *bm, const char htype)
BLI_INLINE BMVert * BM_vert_at_index(BMesh *bm, const int index)
constexpr int64_t size() const
constexpr Span< T > as_span() const
constexpr IndexRange index_range() const
constexpr int64_t size() const
constexpr bool is_empty() const
void tag_positions_changed(const IndexMask &node_mask)
Span< NodeT > nodes() const
void foreach_index(Fn &&fn) const
const Depsgraph * depsgraph
void gather(const GVArray &src, const IndexMask &indices, GMutableSpan dst, int64_t grain_size=4096)
IndexRange grid_range(const int grid_area, const int grid)
pbvh::Tree * pbvh_get(Object &object)
void update_node_bounds_bmesh(BMeshNode &node)
void update_node_bounds_mesh(Span< float3 > positions, MeshNode &node)
Span< float3 > vert_normals_eval(const Depsgraph &depsgraph, const Object &object_orig)
void update_node_bounds_grids(int grid_area, Span< float3 > positions, GridsNode &node)
Span< float3 > vert_positions_eval(const Depsgraph &depsgraph, const Object &object_orig)
void flush_bounds_to_parents(Tree &pbvh)
void calc_grids_factors(const Depsgraph &depsgraph, const Object &object, const Cache &cache, const bke::pbvh::GridsNode &node, Span< int > grids, MutableSpan< float > factors)
void calc_vert_factors(const Depsgraph &depsgraph, const Object &object, const Cache &cache, const bke::pbvh::MeshNode &node, Span< int > verts, MutableSpan< float > factors)
static void slide_data_init_bmesh(BMesh *bm, SculptBoundary &boundary)
static BLI_NOINLINE void calc_inflate_position(const Span< float3 > positions, const Span< float3 > normals, const Span< float > factors, const MutableSpan< float3 > new_positions)
static void slide_data_init_grids(const SubdivCCG &subdiv_ccg, SculptBoundary &boundary)
static void twist_data_init_grids(const SubdivCCG &subdiv_ccg, SculptBoundary &boundary)
static void calc_slide_bmesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Span< int > vert_propagation_steps, const Span< float > vert_factors, const Span< float3 > vert_slide_directions, bke::pbvh::BMeshNode &node, LocalDataBMesh &tls, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target)
static BLI_NOINLINE void calc_slide_position(const Span< float3 > positions, const Span< float3 > directions, const Span< float > factors, const MutableSpan< float3 > new_positions)
static void calc_twist_bmesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Span< int > vert_propagation_steps, const Span< float > vert_factors, const float3 twist_pivot_position, const float3 twist_axis, bke::pbvh::BMeshNode &node, LocalDataBMesh &tls, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target)
static std::optional< SubdivCCGCoord > get_closest_boundary_vert_grids(Object &object, const OffsetIndices< int > faces, const Span< int > corner_verts, const SubdivCCG &subdiv_ccg, const BitSpan boundary, const SubdivCCGCoord initial_vert, const float radius)
void pivot_line_preview_draw(const uint gpuattr, SculptSession &ss)
static void indices_init_bmesh(Object &object, BMesh *bm, BMVert &initial_boundary_vert, SculptBoundary &boundary)
static void init_boundary_grids(Object &object, const Brush &brush, const ePaintSymmetryFlags symm_area)
static void edit_data_init_grids(const SubdivCCG &subdiv_ccg, const int initial_vert_i, const float radius, SculptBoundary &boundary)
static void calc_twist_mesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Span< int > vert_propagation_steps, const Span< float > vert_factors, const bke::pbvh::MeshNode &node, LocalDataMesh &tls, const float3 twist_pivot_position, const float3 twist_axis, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target, const PositionDeformData &position_data)
static void calc_inflate_mesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Span< int > vert_propagation_steps, const Span< float > vert_factors, const bke::pbvh::MeshNode &node, LocalDataMesh &tls, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target, const PositionDeformData &position_data)
static bool is_vert_in_editable_boundary_mesh(const OffsetIndices< int > faces, const Span< int > corner_verts, const GroupedSpan< int > vert_to_face, const Span< bool > hide_vert, const Span< bool > hide_poly, const BitSpan boundary, const int initial_vert)
std::unique_ptr< SculptBoundary > data_init_bmesh(Object &object, const Brush *brush, BMVert *initial_vert, const float radius)
static void init_falloff_bmesh(BMesh *bm, const Brush &brush, const float radius, SculptBoundary &boundary)
static bool check_counts(const int neighbor_count, const int boundary_vertex_count)
std::unique_ptr< SculptBoundaryPreview > preview_data_init(const Depsgraph &depsgraph, Object &object, const Brush *brush, const float radius)
static void calc_bend_mesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Span< int > vert_propagation_steps, const Span< float > vert_factors, const Span< float3 > vert_pivot_positions, const Span< float3 > vert_pivot_axes, const bke::pbvh::MeshNode &node, LocalDataMesh &tls, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target, const PositionDeformData &position_data)
static void indices_init_mesh(Object &object, const OffsetIndices< int > faces, const Span< int > corner_verts, const GroupedSpan< int > vert_to_face, const Span< bool > hide_vert, const Span< bool > hide_poly, const BitSpan boundary_verts, const Span< float3 > vert_positions, const int initial_boundary_vert, SculptBoundary &boundary)
static void calc_smooth_bmesh(const Sculpt &sd, Object &object, const Span< int > vert_propagation_steps, const Span< float > vert_factors, bke::pbvh::BMeshNode &node, LocalDataBMesh &tls, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target)
static void twist_data_init_bmesh(BMesh *bm, SculptBoundary &boundary)
static BLI_NOINLINE void calc_smooth_position(const Span< float3 > positions, const Span< float3 > average_position, const Span< float > factors, const MutableSpan< float3 > new_positions)
void do_boundary_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
static float get_mesh_strength(const SculptSession &ss, const Brush &brush)
static void calc_smooth_grids(const Sculpt &sd, Object &object, SubdivCCG &subdiv_ccg, const Span< int > vert_propagation_steps, const Span< float > vert_factors, const bke::pbvh::GridsNode &node, LocalDataGrids &tls, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target)
static void calc_slide_mesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Span< int > vert_propagation_steps, const Span< float > vert_factors, const Span< float3 > vert_slide_directions, const bke::pbvh::MeshNode &node, LocalDataMesh &tls, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target, const PositionDeformData &position_data)
static void do_slide_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask, const SculptBoundary &boundary, const float strength, const eBrushDeformTarget deform_target)
static void init_boundary_mesh(const Depsgraph &depsgraph, Object &object, const Brush &brush, const ePaintSymmetryFlags symm_area)
static BLI_NOINLINE void calc_twist_position(const Span< float3 > positions, const float3 pivot_point, const float3 pivot_axis, const Span< float > factors, const MutableSpan< float3 > new_positions)
static void bend_data_init_grids(const SubdivCCG &subdiv_ccg, SculptBoundary &boundary)
static void calc_bend_grids(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, SubdivCCG &subdiv_ccg, const Span< int > vert_propagation_steps, const Span< float > vert_factors, const Span< float3 > vert_pivot_positions, const Span< float3 > vert_pivot_axes, const bke::pbvh::GridsNode &node, LocalDataGrids &tls, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target)
static bool is_vert_in_editable_boundary_bmesh(BMVert &initial_vert)
static void init_boundary_bmesh(Object &object, const Brush &brush, const ePaintSymmetryFlags symm_area)
static BLI_NOINLINE void calc_bend_position(const Span< float3 > positions, const Span< float3 > pivot_positions, const Span< float3 > pivot_axes, const Span< float > factors, const MutableSpan< float3 > new_positions)
static BLI_NOINLINE void filter_uninitialized_verts(const Span< int > propagation_steps, const MutableSpan< float > factors)
static void bend_data_init_mesh(const Span< float3 > vert_positions, const Span< float3 > vert_normals, SculptBoundary &boundary)
static void edit_data_init_bmesh(BMesh *bm, const int initial_vert_i, const float radius, SculptBoundary &boundary)
static void calc_inflate_grids(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, SubdivCCG &subdiv_ccg, const Span< int > vert_propagation_steps, const Span< float > vert_factors, const bke::pbvh::GridsNode &node, LocalDataGrids &tls, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target)
static void populate_twist_data(const Span< float3 > positions, SculptBoundary &boundary)
static std::pair< float, float > calc_boundary_falloff(const SculptBoundary &boundary, const Brush &brush, const float radius, const int index)
static void twist_data_init_mesh(const Span< float3 > vert_positions, SculptBoundary &boundary)
static void calc_grab_bmesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Span< int > vert_propagation_steps, const Span< float > vert_factors, bke::pbvh::BMeshNode &node, LocalDataBMesh &tls, const float3 grab_delta_symmetry, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target)
std::unique_ptr< SculptBoundary > data_init(const Depsgraph &depsgraph, Object &object, const Brush *brush, const int initial_vert, const float radius)
bool vert_is_boundary(const GroupedSpan< int > vert_to_face_map, const Span< bool > hide_poly, const BitSpan boundary, const int vert)
static void do_grab_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask, const SculptBoundary &boundary, const float strength, const eBrushDeformTarget deform_target)
static void do_bend_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask, const SculptBoundary &boundary, const float strength, const eBrushDeformTarget deform_target)
static void calc_grab_mesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Span< int > vert_propagation_steps, const Span< float > vert_factors, const bke::pbvh::MeshNode &node, LocalDataMesh &tls, const float3 grab_delta_symmetry, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target, const PositionDeformData &position_data)
void edges_preview_draw(const uint gpuattr, SculptSession &ss, const float outline_col[3], const float outline_alpha)
static bool is_vert_in_editable_boundary_grids(const OffsetIndices< int > faces, const Span< int > corner_verts, const SubdivCCG &subdiv_ccg, const BitSpan boundary, const SubdivCCGCoord initial_vert)
static float displacement_from_grab_delta_get(const SculptSession &ss, const SculptBoundary &boundary)
static void calc_twist_grids(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, SubdivCCG &subdiv_ccg, const Span< int > vert_propagation_steps, const Span< float > vert_factors, const float3 twist_pivot_position, const float3 twist_axis, const bke::pbvh::GridsNode &node, LocalDataGrids &tls, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target)
static std::optional< BMVert * > get_closest_boundary_vert_bmesh(Object &object, BMesh *bm, BMVert &initial_vert, const float radius)
std::unique_ptr< SculptBoundary > data_init_mesh(const Depsgraph &depsgraph, Object &object, const Brush *brush, const int initial_vert, const float radius)
static void bend_data_init_bmesh(BMesh *bm, SculptBoundary &boundary)
static void calc_inflate_bmesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Span< int > vert_propagation_steps, const Span< float > vert_factors, bke::pbvh::BMeshNode &node, LocalDataBMesh &tls, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target)
static void calc_bend_bmesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Span< int > vert_propagation_steps, const Span< float > vert_factors, const Span< float3 > vert_pivot_positions, const Span< float3 > vert_pivot_axes, bke::pbvh::BMeshNode &node, LocalDataBMesh &tls, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target)
static void calc_grab_grids(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, SubdivCCG &subdiv_ccg, const Span< int > vert_propagation_steps, const Span< float > vert_factors, const bke::pbvh::GridsNode &node, LocalDataGrids &tls, const float3 grab_delta_symmetry, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target)
static void calc_smooth_mesh(const Sculpt &sd, Object &object, const OffsetIndices< int > faces, const Span< int > corner_verts, const GroupedSpan< int > vert_to_face, const Span< bool > hide_poly, const Span< int > vert_propagation_steps, const Span< float > vert_factors, const bke::pbvh::MeshNode &node, LocalDataMesh &tls, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target, const PositionDeformData &position_data)
static void edit_data_init_mesh(OffsetIndices< int > faces, Span< int > corner_verts, GroupedSpan< int > vert_to_face, Span< float3 > vert_positions, Span< bool > hide_vert, Span< bool > hide_poly, const int initial_vert_i, const float radius, SculptBoundary &boundary)
static BLI_NOINLINE void calc_average_position(const Span< float3 > vert_positions, const Span< int > vert_propagation_steps, const Span< Vector< int > > neighbors, const Span< int > propagation_steps, const MutableSpan< float > factors, const MutableSpan< float3 > average_positions)
constexpr int BOUNDARY_INDICES_BLOCK_SIZE
static void do_inflate_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask, const SculptBoundary &boundary, const float strength, const eBrushDeformTarget deform_target)
static void calc_slide_grids(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, SubdivCCG &subdiv_ccg, const Span< int > vert_propagation_steps, const Span< float > vert_factors, const Span< float3 > vert_slide_directions, const bke::pbvh::GridsNode &node, LocalDataGrids &tls, const float3 symmetry_pivot, const float strength, const eBrushDeformTarget deform_target)
static void do_twist_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask, const SculptBoundary &boundary, const float strength, const eBrushDeformTarget deform_target)
void ensure_boundary_info(Object &object)
static void init_falloff_mesh(const Span< float > mask, const Brush &brush, const float radius, SculptBoundary &boundary)
static void init_falloff_grids(const SubdivCCG &subdiv_ccg, const Brush &brush, const float radius, SculptBoundary &boundary)
static void do_smooth_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask, const SculptBoundary &boundary, const float strength, const eBrushDeformTarget deform_target)
static void add_index(SculptBoundary &boundary, const int new_index, const float distance, Set< int, BOUNDARY_INDICES_BLOCK_SIZE > &included_verts)
static void indices_init_grids(Object &object, const OffsetIndices< int > faces, const Span< int > corner_verts, const SubdivCCG &subdiv_ccg, const BitSpan boundary_verts, const SubdivCCGCoord initial_vert, SculptBoundary &boundary)
static std::optional< int > get_closest_boundary_vert_mesh(Object &object, const GroupedSpan< int > vert_to_face, const Span< float3 > vert_positions, const Span< bool > hide_vert, const Span< bool > hide_poly, const BitSpan boundary, const int initial_vert, const float radius)
static BLI_NOINLINE void calc_grab_position(const Span< float3 > positions, const float3 grab_delta, const Span< float > factors, const MutableSpan< float3 > new_positions)
std::unique_ptr< SculptBoundary > data_init_grids(Object &object, const Brush *brush, const SubdivCCGCoord initial_vert, const float radius)
static void slide_data_init_mesh(const Span< float3 > vert_positions, SculptBoundary &boundary)
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)
void gather_bmesh_positions(const Set< BMVert *, 0 > &verts, MutableSpan< float3 > positions)
void gather_data_grids(const SubdivCCG &subdiv_ccg, Span< T > src, Span< int > grids, MutableSpan< T > node_data)
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)
void gather_data_bmesh(Span< T > src, const Set< BMVert *, 0 > &verts, MutableSpan< T > node_data)
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 filter_verts_outside_symmetry_area(Span< float3 > positions, const float3 &pivot, ePaintSymmetryFlags symm, MutableSpan< float > factors)
void scale_factors(MutableSpan< float > factors, float strength)
void translations_from_new_positions(Span< float3 > new_positions, Span< int > verts, Span< float3 > old_positions, MutableSpan< float3 > translations)
void clip_and_lock_translations(const Sculpt &sd, const SculptSession &ss, Span< float3 > positions, Span< int > verts, MutableSpan< float3 > translations)
void scatter_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
void apply_translations(Span< float3 > translations, Span< int > verts, MutableSpan< float3 > positions)
OrigPositionData orig_position_data_get_mesh(const Object &object, const bke::pbvh::MeshNode &node)
Span< BMVert * > vert_neighbors_get_bmesh(BMVert &vert, Vector< BMVert *, 64 > &r_neighbors)
void gather_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
void calc_vert_neighbors(OffsetIndices< int > faces, Span< int > corner_verts, GroupedSpan< int > vert_to_face, Span< bool > hide_poly, Span< int > verts, MutableSpan< Vector< int > > result)
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)
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)
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)
void scatter_data_grids(const SubdivCCG &subdiv_ccg, Span< T > node_data, Span< int > grids, MutableSpan< T > dst)
T distance(const T &a, const T &b)
AxisSigned cross(const AxisSigned a, const AxisSigned 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)
float3 rotate_around_axis(const float3 &vector, const float3 ¢er, const float3 &axis, float angle)
VecBase< float, 3 > float3
bool SCULPT_stroke_is_first_brush_step_of_symmetry_pass(const blender::ed::sculpt_paint::StrokeCache &cache)
ePaintSymmetryFlags SCULPT_mesh_symmetry_xyz_get(const Object &object)
void SCULPT_vertex_random_access_ensure(Object &object)
#define BOUNDARY_STEPS_NONE
#define BOUNDARY_VERTEX_NONE
struct CurveMapping * curve
int boundary_falloff_type
struct SculptSession * sculpt
blender::ed::sculpt_paint::StrokeCache * cache
SculptVertexInfo vertex_info
std::unique_ptr< SculptBoundaryPreview > boundary_preview
ActiveVert active_vert() const
blender::BitVector boundary
int to_index(const CCGKey &key) const
static SubdivCCGCoord from_index(const CCGKey &key, int index)
blender::Span< SubdivCCGCoord > duplicates() const
blender::Vector< SubdivCCGCoord, 256 > coords
blender::Span< SubdivCCGCoord > unique() const
blender::Array< blender::float3 > normals
blender::BitGroupVector grid_hidden
blender::Array< float > masks
blender::Array< blender::float3 > positions
std::unique_ptr< auto_mask::Cache > automasking
float3 initial_location_symm
ePaintSymmetryFlags mirror_symmetry_pass
std::unique_ptr< cloth::SimulationData > cloth_sim
std::array< std::unique_ptr< boundary::SculptBoundary >, PAINT_SYMM_AREAS > boundaries
Vector< float3 > translations
Vector< float3 > average_positions
Vector< float3 > pivot_positions
Vector< float3 > new_positions
Vector< float3 > pivot_axes
Vector< Vector< BMVert * > > neighbors
Vector< float3 > positions
Vector< float3 > slide_directions
Vector< int > propagation_steps
Vector< float3 > average_positions
Vector< float3 > slide_directions
Vector< float3 > positions
Vector< int > propagation_steps
Vector< float3 > pivot_axes
Vector< float3 > translations
Vector< float3 > new_positions
Vector< Vector< SubdivCCGCoord > > neighbors
Vector< float3 > pivot_positions
Vector< float3 > new_positions
Vector< float3 > translations
Vector< float3 > positions
Vector< float3 > average_positions
Vector< float3 > pivot_positions
Vector< int > propagation_steps
Vector< Vector< int > > neighbors
Vector< float3 > slide_directions
Vector< float3 > pivot_axes
ccl_device_inline int mod(int x, int m)