52 float3 target = initial_target;
59 segments[i].initial_orig);
63 float3 current_head_position = segments[i].orig + current_orientation * segments[i].len;
66 float3 current_origin_position = target - current_head_position;
69 segments[i].head = current_head_position;
70 segments[i].orig += current_origin_position;
73 target = segments[i].orig;
78 float3 anchor_diff = segments.
last().initial_orig - segments.
last().orig;
80 segments[i].orig += anchor_diff;
81 segments[i].head += anchor_diff;
92 segments[i].initial_orig);
93 float initial_rotation[4];
94 float current_rotation[4];
111 add_v3_v3v3(segment.head, segment.initial_head, delta);
112 add_v3_v3v3(segment.orig, segment.initial_orig, delta);
140 for (
const int i : positions.index_range()) {
141 float3 position = positions[i];
146 translations[i] = position - positions[i];
153 for (
const int i : a.index_range()) {
192 add_arrays(translations, segment_translations);
241 gather_data_grids(subdiv_ccg, segment.weights.as_span(), grids, segment_weights);
243 add_arrays(translations, segment_translations);
258 cache.
cloth_sim->deformation_pos.as_mutable_span());
297 add_arrays(translations, segment_translations);
321 joined.
pos_avg = a.pos_avg +
b.pos_avg;
336 for (
const int i :
verts.index_range()) {
337 const int neighbor = fake_neighbors[
verts[i]];
339 neighbors[i].append(neighbor);
345 const float3 &pose_initial_position,
369 for (
const int i :
verts.index_range()) {
370 const int vert =
verts[i];
373 for (
const int neighbor : neighbors[i]) {
374 max = std::max(max, prev_mask[neighbor]);
377 if (max > prev_mask[vert]) {
379 pose_factor[vert] =
max;
389 const float3 &pose_initial_position,
403 const int grid = grids[i];
408 if (!grid_hidden.
is_empty() && grid_hidden[grid][offset]) {
411 const int vert = grid_range[offset];
419 max = std::max(max, prev_mask[neighbor.to_index(key)]);
423 max = std::max(max, prev_mask[fake_neighbors[vert]]);
427 if (max > prev_mask[vert]) {
428 const float3 &position = positions[vert];
429 pose_factor[vert] =
max;
441 const float3 &pose_initial_position,
461 max = std::max(max, prev_mask[fake_neighbors[vert]]);
465 if (max > prev_mask[vert]) {
466 const float3 &position = bm_vert->co;
467 pose_factor[vert] =
max;
481 float pose_origin[3],
482 float pose_target[3],
484 float *r_pose_origin,
494 bool grow_next_iteration =
true;
497 while (grow_next_iteration) {
502 switch (pbvh.
type()) {
508 const Span<int> corner_verts = mesh.corner_verts();
520 GrowFactorLocalData &tls = all_tls.local();
521 node_mask.slice(range).foreach_index([&](const int i) {
522 grow_factors_mesh(symm,
550 node_mask.slice(range).foreach_index([&](const int i) {
551 grow_factors_grids(symm,
572 node_mask.slice(range).foreach_index([&](const int i) {
574 symm, pose_target, fake_neighbors, prev_mask, nodes[i], pose_factor, gftd);
583 if (gftd.pos_count != 0) {
590 if (
len < prev_len) {
592 grow_next_iteration =
true;
595 grow_next_iteration =
false;
596 pose_factor.copy_from(prev_mask);
605 grow_next_iteration =
true;
608 grow_next_iteration =
false;
612 pose_factor.copy_from(prev_mask);
620 grow_next_iteration =
false;
630 for (
char i = 0; i <= symm; ++i) {
648 const float3 &initial_location,
655 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
667 float3 fallback_floodfill_origin = initial_location;
668 flood.
execute(
object, vert_to_face_map, [&](
int ,
int to_v) {
669 r_pose_factor[to_v] = 1.0f;
671 const float3 co = positions_eval[to_v];
675 fallback_floodfill_origin = co;
691 r_pose_origin = pose_origin /
float(tot_co);
694 r_pose_origin = fallback_floodfill_origin;
700 const float3 &initial_location,
719 float3 fallback_floodfill_origin = initial_location;
722 const int to_v_i = to_v.
to_index(key);
724 r_pose_factor[to_v_i] = 1.0f;
726 const float3 &co = positions[to_v_i];
730 fallback_floodfill_origin = co;
748 r_pose_origin = pose_origin /
float(tot_co);
751 r_pose_origin = fallback_floodfill_origin;
757 const float3 &initial_location,
773 float3 fallback_floodfill_origin = initial_location;
776 r_pose_factor[to_v_i] = 1.0f;
782 fallback_floodfill_origin = co;
798 r_pose_origin = pose_origin /
float(tot_co);
801 r_pose_origin = fallback_floodfill_origin;
808 const float3 &initial_location,
817 switch (bke::object::pbvh_get(
object)->type()) {
818 case bke::pbvh::Type::Mesh:
820 depsgraph,
object, ss, initial_location, radius, pose_origin, r_pose_factor);
822 case bke::pbvh::Type::Grids:
824 object, ss, initial_location, radius, pose_origin, r_pose_factor);
826 case bke::pbvh::Type::BMesh:
828 object, ss, initial_location, radius, pose_origin, r_pose_factor);
834 pose_origin += pose_dir * radius * pose_offset;
835 r_pose_origin = pose_origin;
839 if (pose_offset != 0.0f) {
845static std::unique_ptr<IKChain>
ik_chain_new(
const int totsegments,
const int totverts)
847 std::unique_ptr<IKChain> ik_chain = std::make_unique<IKChain>();
848 ik_chain->segments.reinitialize(totsegments);
860 for (
const int i : ik_chain.
segments.index_range()) {
862 head = initial_location;
866 head = ik_chain.
segments[i - 1].orig;
870 ik_chain.
segments[i].initial_orig = origin;
872 ik_chain.
segments[i].initial_head = head;
896 const float3 &initial_location,
900 const float chain_segment_len = radius * (1.0f + brush.
pose_offset);
905 int nearest_vertex_index = -1;
907 switch (pbvh.
type()) {
908 case bke::pbvh::Type::Mesh: {
909 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
912 VArraySpan<bool> hide_vert = *attributes.lookup<
bool>(
".hide_vert", bke::AttrDomain::Point);
917 std::numeric_limits<float>::max(),
919 nearest_vertex_index = *nearest;
922 case bke::pbvh::Type::Grids: {
925 pbvh, subdiv_ccg, initial_location, std::numeric_limits<float>::max(),
true);
927 nearest_vertex_index = nearest->to_index(key);
930 case bke::pbvh::Type::BMesh: {
932 pbvh, initial_location, std::numeric_limits<float>::max(),
false);
947 pose_factor_grow[nearest_vertex_index] = 1.0f;
950 std::unique_ptr<IKChain> ik_chain =
ik_chain_new(tot_segments, totvert);
959 ik_chain->segments[0].orig,
962 float3 next_chain_segment_target = ik_chain->segments[0].orig;
966 for (
int j = 0; j < totvert; j++) {
967 ik_chain->segments[0].weights[j] = pose_factor_grow[j];
968 pose_factor_grow_prev[j] = pose_factor_grow[j];
972 for (
const int i : ik_chain->segments.index_range().drop_front(1)) {
979 next_chain_segment_target,
981 ik_chain->segments[i].orig,
983 next_chain_segment_target = ik_chain->segments[i].orig;
987 for (
int j = 0; j < totvert; j++) {
988 ik_chain->segments[i].weights[j] = pose_factor_grow[j] - pose_factor_grow_prev[j];
990 pose_factor_grow_prev[j] = pose_factor_grow[j];
1005 struct SegmentData {
1010 Mesh &mesh = *
static_cast<Mesh *
>(
object.data);
1013 const Span<int> corner_verts = mesh.corner_verts();
1017 bke::AttrDomain::Point);
1018 const VArraySpan<bool> hide_poly = *attributes.lookup<
bool>(
".hide_poly", bke::AttrDomain::Face);
1019 const VArraySpan face_sets = *attributes.lookup_or_default<
int>(
1020 ".sculpt_face_set", bke::AttrDomain::Face, 0);
1023 vert_positions.
size());
1033 for (
const int i : ik_chain->segments.index_range()) {
1034 const bool is_first_iteration = i == 0;
1039 visited_face_sets.
add(current_data.face_set);
1042 std::optional<SegmentData> next_segment_data;
1044 float3 face_set_boundary_accum(0);
1045 int face_set_boundary_count = 0;
1047 float3 fallback_accum(0);
1048 int fallback_count = 0;
1050 const float3 &pose_initial_co = vert_positions[current_data.vert];
1051 flood_fill.execute(
object, vert_to_face_map, [&](
int ,
int to_v) {
1052 const float3 &to_v_position = vert_positions[to_v];
1054 to_v_position, pose_initial_co, symm);
1060 pose_factor[to_v] = 1.0f;
1061 is_weighted[to_v].set();
1064 const int visited_face_set = face_set::vert_face_set_get(
1065 vert_to_face_map, face_sets, to_v);
1066 visited_face_sets.
add(visited_face_set);
1068 else if (symmetry_check) {
1069 current_data.face_set = face_set::vert_face_set_get(vert_to_face_map, face_sets, to_v);
1070 visited_face_sets.
add(current_data.face_set);
1079 bool is_vertex_valid =
false;
1080 if (is_first_iteration) {
1081 for (
const int visited_face_set : visited_face_sets) {
1082 is_vertex_valid |= face_set::vert_has_face_set(
1083 vert_to_face_map, face_sets, to_v, visited_face_set);
1087 is_vertex_valid = face_set::vert_has_face_set(
1088 vert_to_face_map, face_sets, to_v, current_data.face_set);
1091 if (!is_vertex_valid) {
1095 bool visit_next =
false;
1096 if (!is_weighted[to_v]) {
1097 pose_factor[to_v] = 1.0f;
1098 is_weighted[to_v].set();
1103 if (symmetry_check) {
1104 fallback_accum += to_v_position;
1108 if (!symmetry_check || face_set::vert_has_unique_face_set(vert_to_face_map, face_sets, to_v))
1115 bool count_as_boundary =
false;
1118 faces, corner_verts, vert_to_face_map, hide_poly, to_v, neighbors))
1120 const int next_face_set_candidate = face_set::vert_face_set_get(
1121 vert_to_face_map, face_sets, neighbor_idx);
1124 if (face_set::vert_has_unique_face_set(vert_to_face_map, face_sets, neighbor_idx) &&
1125 !visited_face_sets.
contains(next_face_set_candidate))
1127 if (!next_segment_data) {
1128 next_segment_data = {neighbor_idx, next_face_set_candidate};
1130 count_as_boundary =
true;
1135 if (count_as_boundary) {
1136 face_set_boundary_accum += to_v_position;
1137 face_set_boundary_count++;
1142 if (face_set_boundary_count > 0) {
1143 ik_chain->segments[i].orig = face_set_boundary_accum /
float(face_set_boundary_count);
1145 else if (fallback_count > 0) {
1146 ik_chain->segments[i].orig = fallback_accum /
float(fallback_count);
1149 ik_chain->segments[i].orig =
float3(0);
1152 current_data = *next_segment_data;
1165 struct SegmentData {
1170 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
1172 const Span<int> corner_verts = mesh.corner_verts();
1175 const VArraySpan face_sets = *attributes.lookup_or_default<
int>(
1176 ".sculpt_face_set", bke::AttrDomain::Face, 0);
1193 for (
const int i : ik_chain->segments.index_range()) {
1194 const bool is_first_iteration = i == 0;
1197 flood_fill.add_initial(key,
1200 visited_face_sets.
add(current_data.face_set);
1203 std::optional<SegmentData> next_segment_data;
1205 float3 face_set_boundary_accum(0);
1206 int face_set_boundary_count = 0;
1208 float3 fallback_accum(0);
1209 int fallback_count = 0;
1211 const float3 &pose_initial_co = positions[current_data.vert.to_index(key)];
1216 const int to_v_i = to_v.
to_index(key);
1218 const float3 to_v_position = positions[to_v_i];
1220 to_v_position, pose_initial_co, symm) &&
1227 pose_factor[to_v_i] = 1.0f;
1228 is_weighted[to_v_i].set();
1231 const int visited_face_set = face_set::vert_face_set_get(
1233 visited_face_sets.
add(visited_face_set);
1235 else if (symmetry_check) {
1236 current_data.face_set = face_set::vert_face_set_get(
1238 visited_face_sets.
add(current_data.face_set);
1247 bool is_vertex_valid =
false;
1248 if (is_first_iteration) {
1249 for (
const int visited_face_set : visited_face_sets) {
1250 is_vertex_valid |= face_set::vert_has_face_set(
1251 subdiv_ccg, face_sets, to_v.
grid_index, visited_face_set);
1255 is_vertex_valid = face_set::vert_has_face_set(
1256 subdiv_ccg, face_sets, to_v.
grid_index, current_data.face_set);
1259 if (!is_vertex_valid) {
1263 bool visit_next =
false;
1264 if (!is_weighted[to_v_i]) {
1265 pose_factor[to_v_i] = 1.0f;
1266 is_weighted[to_v_i].set();
1271 if (symmetry_check) {
1272 fallback_accum += to_v_position;
1276 if (!symmetry_check ||
1277 face_set::vert_has_unique_face_set(
1278 faces, corner_verts, vert_to_face_map, face_sets, subdiv_ccg, to_v))
1285 bool count_as_boundary =
false;
1289 const int next_face_set_candidate = face_set::vert_face_set_get(
1290 subdiv_ccg, face_sets, neighbor.grid_index);
1293 if (face_set::vert_has_unique_face_set(
1294 faces, corner_verts, vert_to_face_map, face_sets, subdiv_ccg, neighbor) &&
1295 !visited_face_sets.
contains(next_face_set_candidate))
1297 if (!next_segment_data) {
1298 next_segment_data = {neighbor, next_face_set_candidate};
1300 count_as_boundary =
true;
1305 if (count_as_boundary) {
1306 face_set_boundary_accum += to_v_position;
1307 face_set_boundary_count++;
1312 if (face_set_boundary_count > 0) {
1313 ik_chain->segments[i].orig = face_set_boundary_accum /
float(face_set_boundary_count);
1315 else if (fallback_count > 0) {
1316 ik_chain->segments[i].orig = fallback_accum /
float(fallback_count);
1319 ik_chain->segments[i].orig =
float3(0);
1322 current_data = *next_segment_data;
1326 positions[std::get<SubdivCCGCoord>(ss.
active_vert()).to_index(key)]);
1336 struct SegmentData {
1354 for (
const int i : ik_chain->segments.index_range()) {
1355 const bool is_first_iteration = i == 0;
1358 flood_fill.add_initial(
1361 visited_face_sets.
add(current_data.face_set);
1364 std::optional<SegmentData> next_segment_data;
1366 float3 face_set_boundary_accum(0);
1367 int face_set_boundary_count = 0;
1369 float3 fallback_accum(0);
1370 int fallback_count = 0;
1372 const float3 pose_initial_co = current_data.vert->co;
1373 flood_fill.execute(
object, [&](
BMVert * ,
BMVert *to_v) {
1376 const float3 to_v_position = to_v->
co;
1378 to_v_position, pose_initial_co, symm);
1384 pose_factor[to_v_i] = 1.0f;
1385 is_weighted[to_v_i].set();
1388 const int visited_face_set = face_set::vert_face_set_get(face_set_offset, *to_v);
1389 visited_face_sets.
add(visited_face_set);
1391 else if (symmetry_check) {
1392 current_data.face_set = face_set::vert_face_set_get(face_set_offset, *to_v);
1393 visited_face_sets.
add(current_data.face_set);
1402 bool is_vertex_valid =
false;
1403 if (is_first_iteration) {
1404 for (
const int visited_face_set : visited_face_sets) {
1405 is_vertex_valid |= face_set::vert_has_face_set(face_set_offset, *to_v, visited_face_set);
1409 is_vertex_valid = face_set::vert_has_face_set(
1410 face_set_offset, *to_v, current_data.face_set);
1413 if (!is_vertex_valid) {
1417 bool visit_next =
false;
1418 if (!is_weighted[to_v_i]) {
1419 pose_factor[to_v_i] = 1.0f;
1420 is_weighted[to_v_i].set();
1425 if (symmetry_check) {
1426 fallback_accum += to_v_position;
1430 if (!symmetry_check || face_set::vert_has_unique_face_set(face_set_offset, *to_v)) {
1436 bool count_as_boundary =
false;
1439 const int next_face_set_candidate = face_set::vert_face_set_get(face_set_offset,
1443 if (face_set::vert_has_unique_face_set(face_set_offset, *neighbor) &&
1444 !visited_face_sets.
contains(next_face_set_candidate))
1446 if (!next_segment_data) {
1447 next_segment_data = {neighbor, next_face_set_candidate};
1449 count_as_boundary =
true;
1454 if (count_as_boundary) {
1455 face_set_boundary_accum += to_v_position;
1456 face_set_boundary_count++;
1461 if (face_set_boundary_count > 0) {
1462 ik_chain->segments[i].orig = face_set_boundary_accum /
float(face_set_boundary_count);
1464 else if (fallback_count > 0) {
1465 ik_chain->segments[i].orig = fallback_accum /
float(fallback_count);
1468 ik_chain->segments[i].orig =
float3(0);
1471 current_data = *next_segment_data;
1485 switch (bke::object::pbvh_get(
object)->type()) {
1486 case bke::pbvh::Type::Mesh:
1488 case bke::pbvh::Type::Grids:
1490 case bke::pbvh::Type::BMesh:
1501 const int active_face_set,
1502 const int target_face_set)
1507 switch (bke::object::pbvh_get(
object)->type()) {
1508 case bke::pbvh::Type::Mesh: {
1509 const Mesh &mesh = *
static_cast<Mesh *
>(
object.data);
1513 const VArraySpan face_sets = *attributes.lookup_or_default<
int>(
1514 ".sculpt_face_set", bke::AttrDomain::Face, 0);
1516 for (
const int vert : vert_positions.
index_range()) {
1517 if (floodfill_step[vert] != 0 &&
1518 face_set::vert_has_face_set(vert_to_face_map, face_sets, vert, active_face_set) &&
1519 face_set::vert_has_face_set(vert_to_face_map, face_sets, vert, target_face_set))
1521 sum += vert_positions[vert];
1527 case bke::pbvh::Type::Grids: {
1528 const SubdivCCG &subdiv_ccg = *
object.sculpt->subdiv_ccg;
1531 const Mesh &mesh = *
static_cast<Mesh *
>(
object.data);
1533 const VArraySpan face_sets = *attributes.lookup_or_default<
int>(
1534 ".sculpt_face_set", bke::AttrDomain::Face, 0);
1538 for (
const int index : bke::ccg::grid_range(key, grid)) {
1539 if (floodfill_step[index] != 0 &&
1540 face_set::vert_has_face_set(subdiv_ccg, face_sets, grid, active_face_set) &&
1541 face_set::vert_has_face_set(subdiv_ccg, face_sets, grid, target_face_set))
1543 sum += positions[index];
1550 case bke::pbvh::Type::BMesh: {
1552 BMesh &
bm = *
object.sculpt->bm;
1557 if (floodfill_step[vert] != 0 &&
1558 face_set::vert_has_face_set(face_set_offset, *bm_vert, active_face_set) &&
1559 face_set::vert_has_face_set(face_set_offset, *bm_vert, target_face_set))
1574 return std::nullopt;
1581 const float3 &initial_location)
1583 const Mesh &mesh = *
static_cast<Mesh *
>(
object.data);
1586 const VArraySpan face_sets = *attributes.lookup_or_default<
int>(
1587 ".sculpt_face_set", bke::AttrDomain::Face, 0);
1589 std::unique_ptr<IKChain> ik_chain =
ik_chain_new(1, mesh.verts_num);
1591 const int active_vert = std::get<int>(ss.
active_vert());
1593 const int active_face_set = face_set::active_face_set_get(
object);
1597 floodfill_step[active_vert] = 1;
1601 int masked_face_set_it = 0;
1604 step_floodfill.
execute(
object, vert_to_face_map, [&](
int from_v,
int to_v) {
1605 floodfill_step[to_v] = floodfill_step[from_v] + 1;
1607 const int to_face_set = face_set::vert_face_set_get(vert_to_face_map, face_sets, to_v);
1608 if (!visited_face_sets.
contains(to_face_set)) {
1609 if (face_set::vert_has_unique_face_set(vert_to_face_map, face_sets, to_v) &&
1610 !face_set::vert_has_unique_face_set(vert_to_face_map, face_sets, from_v) &&
1611 face_set::vert_has_face_set(vert_to_face_map, face_sets, from_v, to_face_set))
1614 visited_face_sets.
add(to_face_set);
1616 if (floodfill_step[to_v] >= masked_face_set_it) {
1617 masked_face_set = to_face_set;
1618 masked_face_set_it = floodfill_step[to_v];
1622 target_face_set = to_face_set;
1627 return face_set::vert_has_face_set(vert_to_face_map, face_sets, to_v, active_face_set);
1631 depsgraph,
object, floodfill_step, active_face_set, masked_face_set);
1632 ik_chain->segments[0].orig = origin.value_or(
float3(0));
1634 std::optional<float3> head = std::nullopt;
1635 if (target_face_set != masked_face_set) {
1637 depsgraph,
object, floodfill_step, active_face_set, target_face_set);
1640 ik_chain->segments[0].head = head.value_or(initial_location);
1641 ik_chain->grab_delta_offset = ik_chain->segments[0].head - initial_location;
1646 weight_floodfill.
execute(
object, vert_to_face_map, [&](
int ,
int to_v) {
1647 fk_weights[to_v] = 1.0f;
1648 return !face_set::vert_has_face_set(vert_to_face_map, face_sets, to_v, masked_face_set);
1659 const float3 &initial_location)
1661 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
1663 const Span<int> corner_verts = mesh.corner_verts();
1666 const VArraySpan face_sets = *attributes.lookup_or_default<
int>(
1667 ".sculpt_face_set", bke::AttrDomain::Face, 0);
1671 const Span<int> grid_to_face_map = subdiv_ccg.grid_to_face_map;
1674 std::unique_ptr<IKChain> ik_chain =
ik_chain_new(1, grids_num);
1679 const int active_face_set = face_set::active_face_set_get(
object);
1683 floodfill_step[active_vert_index] = 1;
1687 int masked_face_set_it = 0;
1692 const int from_v_i = from_v.
to_index(key);
1693 const int to_v_i = to_v.
to_index(key);
1695 if (!is_duplicate) {
1696 floodfill_step[to_v_i] = floodfill_step[from_v_i] + 1;
1699 floodfill_step[to_v_i] = floodfill_step[from_v_i];
1702 const int to_face_set = face_sets[grid_to_face_map[to_v.
grid_index]];
1703 if (!visited_face_sets.
contains(to_face_set)) {
1704 if (face_set::vert_has_unique_face_set(
1705 faces, corner_verts, vert_to_face_map, face_sets, subdiv_ccg, to_v) &&
1706 !face_set::vert_has_unique_face_set(
1707 faces, corner_verts, vert_to_face_map, face_sets, subdiv_ccg, from_v) &&
1708 face_set::vert_has_face_set(subdiv_ccg, face_sets, from_v.grid_index, to_face_set))
1711 visited_face_sets.add(to_face_set);
1713 if (floodfill_step[to_v_i] >= masked_face_set_it) {
1714 masked_face_set = to_face_set;
1715 masked_face_set_it = floodfill_step[to_v_i];
1718 if (target_face_set == SCULPT_FACE_SET_NONE) {
1719 target_face_set = to_face_set;
1724 return face_set::vert_has_face_set(
1725 subdiv_ccg, face_sets, to_v.
grid_index, active_face_set);
1728 const std::optional<float3> origin = calc_average_face_set_center(
1729 depsgraph,
object, floodfill_step, active_face_set, masked_face_set);
1730 ik_chain->segments[0].orig = origin.value_or(
float3(0));
1732 std::optional<float3> head = std::nullopt;
1733 if (target_face_set != masked_face_set) {
1734 head = calc_average_face_set_center(
1735 depsgraph,
object, floodfill_step, active_face_set, target_face_set);
1738 ik_chain->segments[0].head = head.value_or(initial_location);
1739 ik_chain->grab_delta_offset = ik_chain->segments[0].head - initial_location;
1741 flood_fill::FillDataGrids weight_floodfill(grids_num);
1742 weight_floodfill.add_initial(key,
1743 find_symm_verts_grids(
object, active_vert.to_index(key), radius));
1745 weight_floodfill.execute(
1751 fk_weights[to_v_i] = 1.0f;
1752 return !face_set::vert_has_face_set(
1753 subdiv_ccg, face_sets, to_v.
grid_index, masked_face_set);
1756 ik_chain_origin_heads_init(*ik_chain, ik_chain->segments[0].head);
1764 const float3 &initial_location)
1773 std::unique_ptr<IKChain> ik_chain =
ik_chain_new(1, verts_num);
1778 const int active_face_set = face_set::active_face_set_get(
object);
1782 floodfill_step[active_vert_index] = 1;
1786 int masked_face_set_it = 0;
1793 floodfill_step[to_v_i] = floodfill_step[from_v_i] + 1;
1795 const int to_face_set = face_set::vert_face_set_get(face_set_offset, *to_v);
1796 if (!visited_face_sets.
contains(to_face_set)) {
1797 if (face_set::vert_has_unique_face_set(face_set_offset, *to_v) &&
1798 !face_set::vert_has_unique_face_set(face_set_offset, *from_v) &&
1799 face_set::vert_has_face_set(face_set_offset, *from_v, to_face_set))
1802 visited_face_sets.
add(to_face_set);
1804 if (floodfill_step[to_v_i] >= masked_face_set_it) {
1805 masked_face_set = to_face_set;
1806 masked_face_set_it = floodfill_step[to_v_i];
1810 target_face_set = to_face_set;
1815 return face_set::vert_has_face_set(face_set_offset, *to_v, active_face_set);
1819 depsgraph,
object, floodfill_step, active_face_set, masked_face_set);
1820 ik_chain->segments[0].orig = origin.value_or(
float3(0));
1822 std::optional<float3> head = std::nullopt;
1823 if (target_face_set != masked_face_set) {
1825 depsgraph,
object, floodfill_step, active_face_set, target_face_set);
1828 ik_chain->segments[0].head = head.value_or(initial_location);
1829 ik_chain->grab_delta_offset = ik_chain->segments[0].head - initial_location;
1838 fk_weights[to_v_i] = 1.0f;
1839 return !face_set::vert_has_face_set(face_set_offset, *to_v, masked_face_set);
1850 const float3 &initial_location)
1852 switch (bke::object::pbvh_get(
object)->type()) {
1853 case bke::pbvh::Type::Mesh:
1855 case bke::pbvh::Type::Grids:
1857 case bke::pbvh::Type::BMesh:
1868 const float3 &initial_location,
1871 std::unique_ptr<IKChain> ik_chain;
1875 if (use_fake_neighbors) {
1913 const float3 &initial_location,
1917 std::unique_ptr<SculptPoseIKChainPreview> preview = std::make_unique<SculptPoseIKChainPreview>();
1919 preview->initial_head_coords.reinitialize(chain.
segments.size());
1920 preview->initial_orig_coords.reinitialize(chain.
segments.size());
1921 for (
const int i : chain.
segments.index_range()) {
1922 preview->initial_head_coords[i] = chain.
segments[i].initial_head;
1923 preview->initial_orig_coords[i] = chain.
segments[i].initial_orig;
1941 ik_chain.
segments[0].initial_orig);
1944 const float segment_len = ik_chain.
segments[0].len;
2014 scale[0] = scale[1] =
sqrtf(1.0f / scale[2]);
2024 const float3 &grab_location)
2027 segment->head, symm, symm_area, grab_location);
2029 segment->orig, symm, symm_area, grab_location);
2072 for (
const int i : ik_chain.
segments.index_range()) {
2085 float pivot_local_space[4][4];
2102 for (
int scale_i = 0; scale_i < 3; scale_i++) {
2104 ik_chain.
segments[i].scale[scale_i]);
2108 symm_orig[0] - symm_initial_orig[0],
2109 symm_orig[1] - symm_initial_orig[1],
2110 symm_orig[2] - symm_initial_orig[2]);
2114 ik_chain.
segments[i].pivot_mat[symm_it].ptr(), symm_orig[0], symm_orig[1], symm_orig[2]);
2118 ik_chain.
segments[i].pivot_mat[symm_it].ptr());
2123 switch (pbvh.
type()) {
2124 case bke::pbvh::Type::Mesh: {
2132 bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
2136 case bke::pbvh::Type::Grids: {
2143 bke::pbvh::update_node_bounds_grids(subdiv_ccg.
grid_area, positions, nodes[i]);
2147 case bke::pbvh::Type::BMesh: {
2152 bke::pbvh::update_node_bounds_bmesh(nodes[i]);
2158 bke::pbvh::flush_bounds_to_parents(pbvh);
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)
#define SCULPT_FACE_SET_NONE
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 unit_m4(float m[4][4])
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 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 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])
@ 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_ORIGIN_FACE_SETS_FK
@ BRUSH_POSE_ORIGIN_TOPOLOGY
@ BRUSH_POSE_ORIGIN_FACE_SETS
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
#define BM_elem_index_get(ele)
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)
static T sum(const btAlignedObjectArray< T > &items)
MutableSpan< T > as_mutable_span()
constexpr int64_t size() const
constexpr bool is_empty() const
constexpr void fill(const T &value) const
constexpr Span< T > as_span() const
constexpr IndexRange index_range() const
constexpr T & last(const int64_t n=0) const
bool contains(const Key &key) const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
void resize(const int64_t new_size)
void tag_positions_changed(const IndexMask &node_mask)
Span< NodeT > nodes() const
IndexRange index_range() const
void foreach_index(Fn &&fn) const
local_group_size(16, 16) .push_constant(Type b
const Depsgraph * depsgraph
draw_view in_light_buf[] float
IndexRange grid_range(const int grid_area, const int grid)
pbvh::Tree * pbvh_get(Object &object)
IndexMask all_leaf_nodes(const Tree &pbvh, IndexMaskMemory &memory)
Span< float3 > vert_positions_eval(const Depsgraph &depsgraph, const Object &object_orig)
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 BLI_NOINLINE void fill_factor_from_hide_and_mask(const Mesh &mesh, const Span< int > face_indices, const MutableSpan< float > r_factors)
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 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 BLI_NOINLINE void add_fake_neighbors(const Span< int > fake_neighbors, const Span< int > verts, const MutableSpan< Vector< int > > neighbors)
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)
void pose_brush_init(const Depsgraph &depsgraph, Object &ob, 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)
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)
Vector< int > find_symm_verts_grids(const Object &object, const int original_vert, const float max_distance)
void gather_data_bmesh(Span< T > src, const Set< BMVert *, 0 > &verts, MutableSpan< T > node_data)
void reset_translations_to_original(MutableSpan< float3 > translations, Span< float3 > positions, Span< float3 > orig_positions)
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)
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)
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)
Vector< int > find_symm_verts_bmesh(const Object &object, const int original_vert, const float max_distance)
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)
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)
VecBase< float, 3 > float3
ePaintSymmetryFlags SCULPT_mesh_symmetry_xyz_get(const Object &object)
Span< int > SCULPT_fake_neighbors_ensure(const Depsgraph &depsgraph, Object &ob, const float max_dist)
bool SCULPT_is_symmetry_iteration_valid(char i, char symm)
void SCULPT_vertex_random_access_ensure(Object &object)
float3 SCULPT_flip_v3_by_symm_area(const float3 &vector, const ePaintSymmetryFlags symm, const ePaintSymmetryAreas symmarea, const float3 &pivot)
int SCULPT_vertex_count_get(const Object &object)
void SCULPT_fake_neighbors_free(Object &ob)
bool SCULPT_check_vertex_pivot_symmetry(const float vco[3], const float pco[3], const char symm)
ePaintSymmetryAreas SCULPT_get_vertex_symm_area(const float co[3])
void SCULPT_flip_quat_by_symm_area(float quat[4], const ePaintSymmetryFlags symm, const ePaintSymmetryAreas symmarea, const float pivot[3])
#define FAKE_NEIGHBOR_NONE
int pose_smooth_iterations
struct CurveMapping * curve
float disconnected_distance_max
struct SculptSession * sculpt
blender::Array< int > fake_neighbor_index
blender::ed::sculpt_paint::StrokeCache * cache
ActiveVert active_vert() const
int active_vert_index() const
SculptFakeNeighbors fake_neighbors
int to_index(const CCGKey &key) const
blender::Vector< SubdivCCGCoord, 256 > coords
blender::BitGroupVector grid_hidden
blender::Array< blender::float3 > positions
VArraySpan< bool > hide_vert
std::unique_ptr< pose::IKChain > pose_ik_chain
std::unique_ptr< auto_mask::Cache > automasking
ePaintSymmetryFlags mirror_symmetry_pass
std::unique_ptr< cloth::SimulationData > cloth_sim
float3 orig_grab_location
void add_initial(BMVert *vertex)
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 add_initial(SubdivCCGCoord vertex)
void execute(Object &object, GroupedSpan< int > vert_to_face_map, FunctionRef< bool(int from_v, int to_v)> func)
void add_initial(int vertex)
Vector< float3 > segment_translations
Vector< float > segment_weights
Vector< float3 > translations
Vector< float3 > positions
Vector< Vector< int > > vert_neighbors
Vector< int > vert_indices
Array< IKChainSegment > segments
static PoseGrowFactorData join(const PoseGrowFactorData &a, const PoseGrowFactorData &b)