159 return static_cast<const Mesh *
>(
object.data)->verts_num;
180 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
181 return mesh.vert_positions();
188 const Mesh *mesh =
static_cast<const Mesh *
>(
object.data);
203 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
212 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
220 return face_sets[face_index];
237 for (
const int face : vert_to_face_map[vert]) {
238 face_set = std::max(face_sets[face], face_set);
246 return face_sets[face];
262 const Span<int> faces = vert_to_face_map[vert];
264 faces.begin(), faces.end(), [&](
const int face) { return face_sets[face] == face_set; });
276 return face_sets[face] == face_set;
281 if (face_set_offset == -1) {
303 for (
const int face_index : vert_to_face_map[vert]) {
304 if (face_set == -1) {
305 face_set = face_sets[face_index];
308 if (face_sets[face_index] != face_set) {
328 const Span<int> vert_map = vert_to_face_map[v1];
329 int p1 = -1, p2 = -1;
330 for (
int i = 0; i < vert_map.
size(); i++) {
331 const int face_i = vert_map[i];
332 for (
const int corner : faces[face_i]) {
333 if (corner_verts[corner] ==
v2) {
347 if (p1 != -1 && p2 != -1) {
348 return face_sets[p1] == face_sets[p2];
366 subdiv_ccg, coord, corner_verts, faces, v1,
v2);
372 vert_to_face_map, face_sets, corner_verts, faces, v1,
v2);
396 if (other_vert != &vert) {
397 r_neighbors.
append(other_vert);
411 if (other_vert != &vert) {
412 r_neighbors.
append(other_vert);
418 if (r_neighbors.
size() == 2) {
440 for (
const int face : vert_to_face[vert]) {
441 if (!hide_poly.
is_empty() && hide_poly[face]) {
462 return boundary[vert].test();
475 subdiv_ccg, vert, corner_verts, faces, v1,
v2);
478 return boundary[v1].test();
480 return boundary[v1].test() && boundary[
v2].test();
521 bool is_in_symmetry_area =
true;
522 for (
int i = 0; i < 3; i++) {
523 char symm_it = 1 << i;
524 if (symm & symm_it) {
525 if (pco[i] == 0.0f) {
527 is_in_symmetry_area =
false;
530 if (vco[i] * pco[i] < 0.0f) {
531 is_in_symmetry_area =
false;
535 return is_in_symmetry_area;
539 const float normal_weight,
547 float len_view_scale;
549 float view_aligned_normal[3];
553 len_view_scale = (len_view_scale > FLT_EPSILON) ? 1.0f / len_view_scale : 1.0f;
556 mul_v3_fl(grab_delta, 1.0f - normal_weight);
567 const float max_distance,
568 const bool use_original)
570 const float max_distance_sq = max_distance * max_distance;
574 return node_in_sphere(node, location, max_distance_sq, use_original);
582 float distance_sq = std::numeric_limits<float>::max();
590 [&](
const IndexRange range, NearestData nearest) {
591 nodes_in_sphere.
slice(range).foreach_index([&](
const int i) {
592 for (
const int vert : nodes[i].verts()) {
593 if (!hide_vert.
is_empty() && hide_vert[vert]) {
597 if (distance_sq < nearest.distance_sq) {
598 nearest = {vert, distance_sq};
604 [](
const NearestData a,
const NearestData
b) {
605 return a.distance_sq <
b.distance_sq ? a :
b;
613 const float max_distance,
614 const bool use_original)
616 const float max_distance_sq = max_distance * max_distance;
620 return node_in_sphere(node, location, max_distance_sq, use_original);
628 float distance_sq = std::numeric_limits<float>::max();
640 [&](
const IndexRange range, NearestData nearest) {
641 nodes_in_sphere.
slice(range).foreach_index([&](
const int i) {
642 for (
const int grid : nodes[i].grids()) {
646 if (distance_sq < nearest.distance_sq) {
651 nearest = {coord, distance_sq};
658 [](
const NearestData a,
const NearestData
b) {
659 return a.distance_sq <
b.distance_sq ? a :
b;
661 return nearest.coord;
666 const float max_distance,
667 const bool use_original)
669 const float max_distance_sq = max_distance * max_distance;
673 return node_in_sphere(node, location, max_distance_sq, use_original);
681 float distance_sq = std::numeric_limits<float>::max();
689 [&](
const IndexRange range, NearestData nearest) {
690 nodes_in_sphere.
slice(range).foreach_index([&](
const int i) {
698 if (distance_sq < nearest.distance_sq) {
699 nearest = {vert, distance_sq};
705 [](
const NearestData a,
const NearestData
b) {
706 return a.distance_sq <
b.distance_sq ? a :
b;
715 return i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || !
ELEM(i, 3, 5)));
719 const float br_co[3],
723 for (
char i = 0; i <= symm; ++i) {
764 return ELEM(sculpt_brush_type,
863 switch (pbvh.
type()) {
866 Mesh &mesh = *
static_cast<Mesh *
>(
object.data);
877 node_changed[i] =
true;
892 node_changed[i] =
true;
910 for (
const int grid : nodes[i].grids()) {
913 if (grid_hidden.
is_empty() || !grid_hidden[grid][i]) {
914 masks[grid_range[i]] = (*orig_data)[index];
920 node_changed[i] =
true;
935 nodes.index_range(),
GrainSize(64), memory, [&](
const int i) {
940 Mesh &mesh = *
static_cast<Mesh *
>(
object.data);
942 const Span<int> corner_verts = mesh.corner_verts();
948 for (
const int i :
verts.index_range()) {
955 color_attribute.
span);
971 switch (pbvh.
type()) {
975 *
static_cast<Mesh *
>(
object.data));
981 node_changed[i] =
true;
991 *
static_cast<Mesh *
>(
object.data));
999 subdiv_ccg, nodes[i], tls);
1001 node_changed[i] =
true;
1020 switch (pbvh.
type()) {
1023 Mesh &mesh = *
static_cast<Mesh *
>(
object.data);
1025 MutableSpan positions_orig = mesh.vert_positions_for_write();
1028 nodes.index_range(),
GrainSize(64), memory, [&](
const int i) {
1037 const bool need_translations = !ss.
deform_imats.is_empty() || active_key;
1047 if (need_translations) {
1055 if (positions_eval.
data() != positions_orig.
data()) {
1065 if (
ELEM(active_key,
nullptr, mesh.key->refkey)) {
1102 nodes.index_range(),
GrainSize(64), memory, [&](
const int i) {
1110 node_mask.foreach_index(
GrainSize(1), [&](
const int i) {
1113 for (
const int grid : nodes[i].grids()) {
1116 if (grid_hidden.
is_empty() || !grid_hidden[grid][i]) {
1117 positions[grid_range[i]] = orig_data.
positions[index];
1251 float overlap = 0.0f;
1253 for (
int i = 1; i < sd.
radial_symm[axis -
'X']; i++) {
1271 for (
int i = 0; i <= symm; i++) {
1282 return 1.0f / overlap;
1346 float p = 1.0f - (distance * radius_inv);
1347 return std::clamp(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
1352 const float distance,
1353 const float radius_inv,
1357 float p = 1.0f - (distance * radius_inv);
1358 const float afactor = std::clamp(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
1360 const float3 disp = (co - test_location) * (1.0f - afactor);
1361 return test_location + disp;
1366 const float distance,
1367 const float radius_inv,
1368 const int flip_index,
1372 test_location, distance, radius_inv, position);
1377 const float distance,
1378 const float radius_inv,
1379 const int flip_index,
1396 const bool use_area_nos,
1397 const bool use_area_cos,
1406 const float position_radius_sq = position_radius * position_radius;
1407 const float position_radius_inv =
math::rcp(position_radius);
1409 const float normal_radius_sq = normal_radius * normal_radius;
1410 const float normal_radius_inv =
math::rcp(normal_radius);
1418 const Span<float3> orig_positions = orig_data->positions;
1426 for (
const int i :
verts.index_range()) {
1427 const int vert =
verts[i];
1428 if (!hide_vert.
is_empty() && hide_vert[vert]) {
1431 const bool normal_test_r = use_area_nos && distances_sq[i] <= normal_radius_sq;
1432 const bool area_test_r = use_area_cos && distances_sq[i] <= position_radius_sq;
1433 if (!normal_test_r && !area_test_r) {
1436 const float3 &normal = orig_normals[i];
1437 const float distance = std::sqrt(distances_sq[i]);
1438 const int flip_index =
math::dot(view_normal, normal) <= 0.0f;
1441 location, orig_positions[i], distance, position_radius_inv, flip_index, anctd);
1443 if (normal_test_r) {
1456 for (
const int i :
verts.index_range()) {
1457 const int vert =
verts[i];
1458 if (!hide_vert.
is_empty() && hide_vert[vert]) {
1461 const bool normal_test_r = distances_sq[i] <= normal_radius_sq;
1462 const bool area_test_r = distances_sq[i] <= position_radius_sq;
1463 if (!normal_test_r && !area_test_r) {
1466 const float3 &normal = vert_normals[vert];
1467 const float distance = std::sqrt(distances_sq[i]);
1468 const int flip_index =
math::dot(view_normal, normal) <= 0.0f;
1471 location, vert_positions[vert], distance, position_radius_inv, flip_index, anctd);
1473 if (normal_test_r) {
1481 const bool use_area_nos,
1482 const bool use_area_cos,
1491 const float position_radius_sq = position_radius * position_radius;
1492 const float position_radius_inv =
math::rcp(position_radius);
1494 const float normal_radius_sq = normal_radius * normal_radius;
1495 const float normal_radius_inv =
math::rcp(normal_radius);
1507 const Span<float3> orig_positions = orig_data->positions;
1517 const int grid = grids[i];
1519 if (!grid_hidden.
is_empty() && grid_hidden[grid][offset]) {
1522 const int node_vert = grid_range_node[offset];
1524 const bool normal_test_r = use_area_nos && distances_sq[node_vert] <= normal_radius_sq;
1525 const bool area_test_r = use_area_cos && distances_sq[node_vert] <= position_radius_sq;
1526 if (!normal_test_r && !area_test_r) {
1529 const float3 &normal = orig_normals[node_vert];
1530 const float distance = std::sqrt(distances_sq[node_vert]);
1531 const int flip_index =
math::dot(view_normal, normal) <= 0.0f;
1534 orig_positions[node_vert],
1536 position_radius_inv,
1540 if (normal_test_r) {
1557 const int grid = grids[i];
1560 if (!grid_hidden.
is_empty() && grid_hidden[grid][offset]) {
1563 const int node_vert = grid_range_node[offset];
1564 const int vert = grid_range[offset];
1566 const bool normal_test_r = use_area_nos && distances_sq[node_vert] <= normal_radius_sq;
1567 const bool area_test_r = use_area_cos && distances_sq[node_vert] <= position_radius_sq;
1568 if (!normal_test_r && !area_test_r) {
1571 const float3 &normal = normals[vert];
1572 const float distance = std::sqrt(distances_sq[node_vert]);
1573 const int flip_index =
math::dot(view_normal, normal) <= 0.0f;
1576 location, positions[node_vert], distance, position_radius_inv, flip_index, anctd);
1578 if (normal_test_r) {
1587 const bool use_area_nos,
1588 const bool use_area_cos,
1589 const bool has_bm_orco,
1598 const float position_radius_sq = position_radius * position_radius;
1599 const float position_radius_inv =
math::rcp(position_radius);
1601 const float normal_radius_sq = normal_radius * normal_radius;
1602 const float normal_radius_inv =
math::rcp(normal_radius);
1604 bool use_original =
false;
1611 if (use_original && has_bm_orco) {
1619 const float *co_tri[3] = {
1620 orig_positions[orig_tris[i][0]],
1621 orig_positions[orig_tris[i][1]],
1622 orig_positions[orig_tris[i][2]],
1633 const bool normal_test_r = use_area_nos && distances_sq[i] <= normal_radius_sq;
1634 const bool area_test_r = use_area_cos && distances_sq[i] <= position_radius_sq;
1635 if (!normal_test_r && !area_test_r) {
1639 float3(orig_positions[orig_tris[i][1]]),
1640 float3(orig_positions[orig_tris[i][2]]));
1642 const float distance = std::sqrt(distances_sq[i]);
1643 const int flip_index =
math::dot(view_normal, normal) <= 0.0f;
1646 location, positions[i], distance, position_radius_inv, flip_index, anctd);
1648 if (normal_test_r) {
1674 const bool normal_test_r = use_area_nos && distances_sq[i] <= normal_radius_sq;
1675 const bool area_test_r = use_area_cos && distances_sq[i] <= position_radius_sq;
1676 if (!normal_test_r && !area_test_r) {
1680 const float3 &normal = normals[i];
1681 const float distance = std::sqrt(distances_sq[i]);
1682 const int flip_index =
math::dot(view_normal, normal) <= 0.0f;
1685 location, positions[i], distance, position_radius_inv, flip_index, anctd);
1687 if (normal_test_r) {
1708 const bool normal_test_r = use_area_nos && distances_sq[i] <= normal_radius_sq;
1709 const bool area_test_r = use_area_cos && distances_sq[i] <= position_radius_sq;
1710 if (!normal_test_r && !area_test_r) {
1714 const float3 &normal = vert->no;
1715 const float distance = std::sqrt(distances_sq[i]);
1716 const int flip_index =
math::dot(view_normal, normal) <= 0.0f;
1719 location, positions[i], distance, position_radius_inv, flip_index, anctd);
1721 if (normal_test_r) {
1733 joined.
area_cos[0] = a.area_cos[0] +
b.area_cos[0];
1734 joined.area_cos[1] = a.area_cos[1] +
b.area_cos[1];
1735 joined.count_co[0] = a.count_co[0] +
b.count_co[0];
1736 joined.count_co[1] = a.count_co[1] +
b.count_co[1];
1738 joined.area_nos[0] = a.area_nos[0] +
b.area_nos[0];
1739 joined.area_nos[1] = a.area_nos[1] +
b.area_nos[1];
1740 joined.count_no[0] = a.count_no[0] +
b.count_no[0];
1741 joined.count_no[1] = a.count_no[1] +
b.count_no[1];
1758 switch (pbvh.
type()) {
1760 const Mesh &mesh = *
static_cast<const Mesh *
>(ob.
data);
1772 SampleLocalData &tls = all_tls.local();
1773 node_mask.slice(range).foreach_index([&](const int i) {
1774 calc_area_normal_and_center_node_mesh(ob,
1799 SampleLocalData &tls = all_tls.local();
1800 node_mask.slice(range).foreach_index([&](const int i) {
1801 calc_area_normal_and_center_node_bmesh(
1802 ob, brush, false, true, has_bm_orco, nodes[i], tls, anctd);
1812 node_mask.index_range(),
1816 SampleLocalData &tls = all_tls.local();
1817 node_mask.slice(range).foreach_index([&](const int i) {
1818 calc_area_normal_and_center_node_grids(ob, brush, false, true, nodes[i], tls, anctd);
1828 for (n = 0; n < anctd.area_cos.size(); n++) {
1829 if (anctd.count_co[n] == 0) {
1833 mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.count_co[n]);
1841 if (anctd.count_co[0] == 0 && anctd.count_co[1] == 0) {
1843 copy_v3_v3(r_area_co, ss.cache->location_symm);
1858 switch (pbvh.
type()) {
1859 case bke::pbvh::Type::Mesh: {
1860 const Mesh &mesh = *
static_cast<const Mesh *
>(ob.
data);
1864 const VArraySpan hide_vert = *attributes.lookup<
bool>(
".hide_vert", bke::AttrDomain::Point);
1867 anctd = threading::parallel_reduce(
1872 SampleLocalData &tls = all_tls.local();
1873 node_mask.slice(range).foreach_index([&](const int i) {
1874 calc_area_normal_and_center_node_mesh(ob,
1890 case bke::pbvh::Type::BMesh: {
1891 const bool has_bm_orco = ss.
bm && dyntopo::stroke_is_dyntopo(ob, brush);
1894 anctd = threading::parallel_reduce(
1899 SampleLocalData &tls = all_tls.local();
1900 node_mask.slice(range).foreach_index([&](const int i) {
1901 calc_area_normal_and_center_node_bmesh(
1907 static_cast<const blender::bke::pbvh::BMeshNode &>(nodes[i]),
1916 case bke::pbvh::Type::Grids: {
1918 anctd = threading::parallel_reduce(
1919 node_mask.index_range(),
1923 SampleLocalData &tls = all_tls.local();
1924 node_mask.slice(range).foreach_index([&](const int i) {
1925 calc_area_normal_and_center_node_grids(ob, brush, true, false, nodes[i], tls, anctd);
1929 calc_area_normal_and_center_reduce);
1934 for (
const int i : {0, 1}) {
1935 if (anctd.count_no[i] != 0) {
1941 return std::nullopt;
1957 switch (pbvh.
type()) {
1958 case bke::pbvh::Type::Mesh: {
1959 const Mesh &mesh = *
static_cast<const Mesh *
>(ob.
data);
1963 const VArraySpan hide_vert = *attributes.lookup<
bool>(
".hide_vert", bke::AttrDomain::Point);
1966 anctd = threading::parallel_reduce(
1971 SampleLocalData &tls = all_tls.local();
1972 node_mask.slice(range).foreach_index([&](const int i) {
1973 calc_area_normal_and_center_node_mesh(ob,
1989 case bke::pbvh::Type::BMesh: {
1990 const bool has_bm_orco = ss.
bm && dyntopo::stroke_is_dyntopo(ob, brush);
1993 anctd = threading::parallel_reduce(
1998 SampleLocalData &tls = all_tls.local();
1999 node_mask.slice(range).foreach_index([&](const int i) {
2000 calc_area_normal_and_center_node_bmesh(
2001 ob, brush, true, true, has_bm_orco, nodes[i], tls, anctd);
2008 case bke::pbvh::Type::Grids: {
2010 anctd = threading::parallel_reduce(
2011 node_mask.index_range(),
2015 SampleLocalData &tls = all_tls.local();
2016 node_mask.slice(range).foreach_index([&](const int i) {
2017 calc_area_normal_and_center_node_grids(ob, brush, true, true, nodes[i], tls, anctd);
2021 calc_area_normal_and_center_reduce);
2027 for (n = 0; n < anctd.area_cos.size(); n++) {
2028 if (anctd.count_co[n] == 0) {
2032 mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.count_co[n]);
2040 if (anctd.count_co[0] == 0 && anctd.count_co[1] == 0) {
2042 copy_v3_v3(r_area_co, ss.cache->location_symm);
2047 for (n = 0; n < anctd.area_nos.size(); n++) {
2069 const float feather,
2078 const float alpha = root_alpha * root_alpha;
2081 const float pen_flip = cache.
pen_flip ? -1.0f : 1.0f;
2087 float flip = dir *
invert * pen_flip;
2093 float final_pressure;
2097 final_pressure =
pow4f(pressure);
2098 overlap = (1.0f + overlap) / 2.0f;
2099 return 0.25f * alpha * flip * final_pressure * overlap * feather;
2103 return alpha * flip * pressure * overlap * feather;
2105 return alpha * pressure * overlap * feather;
2109 return root_alpha * feather;
2112 return root_alpha * feather * pressure * overlap;
2117 return 0.1f * alpha * flip * pressure * overlap * feather;
2122 return 10.0f * alpha * flip * pressure * overlap * feather;
2125 return alpha * pressure * overlap * feather;
2127 return alpha * pressure * overlap * feather * 2.0f;
2129 final_pressure = pressure * pressure;
2130 return final_pressure * overlap * feather;
2133 return alpha * pressure * overlap * feather;
2136 final_pressure =
powf(pressure, 1.5f);
2137 return alpha * flip * final_pressure * overlap * feather * 0.3f;
2139 final_pressure = pressure * pressure;
2140 return alpha * flip * final_pressure * overlap * feather * 1.3f;
2143 overlap = (1.0f + overlap) / 2.0f;
2146 return alpha * flip * pressure * overlap * feather;
2148 return alpha * pressure * feather;
2153 return alpha * flip * pressure * overlap * feather;
2157 return 0.250f * alpha * flip * pressure * overlap * feather;
2160 return 0.125f * alpha * flip * pressure * overlap * feather;
2164 overlap = (1.0f + overlap) / 2.0f;
2165 return alpha * flip * pressure * overlap * feather;
2171 overlap = (1.0f + overlap) / 2.0f;
2172 return alpha * flip * pressure * overlap * feather;
2176 return 0.5f * alpha * flip * pressure * overlap * feather;
2180 return flip * alpha * pressure * feather;
2184 return alpha * flip * pressure * overlap * feather;
2187 return 0.25f * alpha * flip * pressure * overlap * feather;
2191 overlap = (1.0f + overlap) / 2.0f;
2192 return alpha * pressure * overlap * feather;
2195 return alpha * pressure * feather;
2198 return root_alpha * feather;
2201 return root_alpha * feather;
2204 return alpha * pressure * feather;
2209 return root_alpha * feather;
2221 const float brush_point[3],
2222 const int thread_id,
2262 float x = symm_point[0];
2263 float y = symm_point[1];
2279 const float point_3d[3] = {point_2d[0], point_2d[1], 0.0f};
2298 for (
int i = 0; i < 3; ++i) {
2328 const float radius_sq,
2329 const bool original)
2339 const float radius_sq,
2340 const bool original)
2345 float dummy_co[3], dummy_depth;
2347 &ray_dist_precalc, bounds.
min, bounds.
max, dummy_co, &dummy_depth);
2350 return dist_sq < radius_sq ||
true;
2400 const bool use_original,
2401 const float radius_scale,
2464 const float center[3],
2465 const float screen_dir[2],
2466 float r_local_dir[3])
2471 mul_v3_m4v3(loc, ob.object_to_world().ptr(), center);
2478 mul_m4_v3(ob.world_to_object().ptr(), r_local_dir);
2483 float local_mat[4][4],
2484 float local_mat_inv[4][4])
2506 float motion_normal_screen[2];
2507 motion_normal_screen[0] =
cosf(angle);
2508 motion_normal_screen[1] =
sinf(angle);
2511 float motion_normal_local[3];
2513 *cache->
vc, cache->
location_symm, motion_normal_screen, motion_normal_local);
2535 float radius = cache->
radius;
2549#define SCULPT_TILT_SENSITIVITY 0.7f
2552 const float tilt_strength)
2554 if (!
U.experimental.use_sculpt_tools_tilt) {
2559 float normal_tilt_y[3];
2561 float normal_tilt_xy[3];
2563 normal_tilt_xy, normal_tilt_y, cache->
vc->
rv3d->
viewinv[1], cache->
tilt.x * rot_max);
2582 calc_brush_local_mat(
2598 U.experimental.use_sculpt_texture_paint)
2621 bke::pbvh::build_pixels(
depsgraph, ob, *image, *image_user);
2688 float axis[3],
angle;
2720 for (
int i = 0; i < 3; i++) {
2722 if (!(symm & symm_it)) {
2725 if (symmarea & symm_it) {
2728 if (pivot[i] < 0.0f) {
2738 const float pivot[3])
2740 for (
int i = 0; i < 3; i++) {
2742 if (!(symm & symm_it)) {
2745 if (symmarea & symm_it) {
2748 if (pivot[i] < 0.0f) {
2918 const float radius_scale = 1.25f;
2987 mul_m4_v3(ob.object_to_world().ptr(), location);
3059 float radius_scale = 1.0f;
3069 radius_scale = 2.0f;
3137 depsgraph, ob, 1.0f, 0.0f, 0.0f,
false,
true);
3145 std::numeric_limits<float>::max());
3158 if (use_vector_displacement) {
3295 scene,
depsgraph, paint_mode_settings, sd, ob, node_mask, texnode_mask);
3336 mul_m4_v3(ob.object_to_world().ptr(), location);
3364 float frac = 1.0f / max_overlap_count(sd);
3365 float reduce = (feather -
frac) / (1.0f -
frac);
3367 printf(
"feather: %f frac: %f reduce: %f\n", feather,
frac, reduce);
3370 mul_v3_fl(cache.grab_delta_symmetry, reduce);
3425 const float radius = cache->
radius;
3427 const float *bbMin = bb.
min;
3428 const float *bbMax = bb.
max;
3439 float original_initial_location[3];
3443 for (
int dim = 0; dim < 3; dim++) {
3445 start[dim] = (bbMin[dim] - orgLoc[dim] - radius) / step[dim];
3446 end[dim] = (bbMax[dim] - orgLoc[dim] + radius) / step[dim];
3449 start[dim] = end[dim] = 0;
3455 action(
depsgraph, scene, sd, ob, brush, ups, paint_mode_settings);
3459 for (cur[0] = start[0]; cur[0] <= end[0]; cur[0]++) {
3460 for (cur[1] = start[1]; cur[1] <= end[1]; cur[1]++) {
3461 for (cur[2] = start[2]; cur[2] <= end[2]; cur[2]++) {
3462 if (!cur[0] && !cur[1] && !cur[2]) {
3469 for (
int dim = 0; dim < 3; dim++) {
3470 cache->
location_symm[dim] = cur[dim] * step[dim] + orgLoc[dim];
3473 original_initial_location[dim];
3475 action(
depsgraph, scene, sd, ob, brush, ups, paint_mode_settings);
3495 for (
int i = 1; i < sd.
radial_symm[axis -
'X']; i++) {
3538 for (
int i = 0; i <= symm; i++) {
3550 depsgraph, scene, sd, ob, brush, ups, paint_mode_settings, action, symm,
'X', feather);
3552 depsgraph, scene, sd, ob, brush, ups, paint_mode_settings, action, symm,
'Y', feather);
3554 depsgraph, scene, sd, ob, brush, ups, paint_mode_settings, action, symm,
'Z', feather);
3598 std::array<wmOperatorType *, 7> trim_operators = {
3608 return std::any_of(trim_operators.begin(), trim_operators.end(), [tref](
wmOperatorType *
ot) {
3610 return WM_toolsystem_ref_properties_get_from_operator(tref, ot, &ptr);
3629 return "Draw Brush";
3631 return "Smooth Brush";
3633 return "Crease Brush";
3635 return "Blob Brush";
3637 return "Pinch Brush";
3639 return "Inflate Brush";
3641 return "Grab Brush";
3643 return "Nudge Brush";
3645 return "Thumb Brush";
3647 return "Layer Brush";
3649 return "Flatten Brush";
3651 return "Clay Brush";
3653 return "Clay Strips Brush";
3655 return "Clay Thumb Brush";
3657 return "Fill Brush";
3659 return "Scrape Brush";
3661 return "Snake Hook Brush";
3663 return "Rotate Brush";
3665 return "Mask Brush";
3667 return "Simplify Brush";
3669 return "Draw Sharp Brush";
3671 return "Elastic Deform Brush";
3673 return "Pose Brush";
3675 return "Multi-plane Scrape Brush";
3677 return "Slide/Relax Brush";
3679 return "Boundary Brush";
3681 return "Cloth Brush";
3683 return "Draw Face Sets";
3685 return "Multires Displacement Eraser";
3687 return "Multires Displacement Smear";
3689 return "Paint Brush";
3691 return "Smear Brush";
3729 for (
int i = 0; i < 3; i++) {
3744 mirror_ob_inv.
ptr(),
3745 ob.object_to_world().ptr());
3778 if (!smooth_brush) {
3780 CLOG_WARN(&
LOG,
"Switching to the smooth brush not possible, corresponding brush not");
3827 StrokeCache *cache = MEM_new<StrokeCache>(__func__);
3834 float viewDir[3] = {0.0f, 0.0f, 1.0f};
3842 for (
int i = 0; i < 3; i++) {
3893 smooth_brush_toggle_on(C, &sd.
paint, cache);
3904 cache->
brush = brush;
3940 cache->
accum =
true;
3944 cache->
accum =
false;
3950 cache->
accum =
false;
3955 cache->
accum =
false;
3957 cache->
accum =
true;
3967 cache->
accum =
true;
3972#define PIXEL_INPUT_THRESHHOLD 5
3977#undef PIXEL_INPUT_THRESHHOLD
3991 return initial_size * clay_stabilized_pressure;
3994 return initial_size * cache.
pressure;
4047 const float mval[2] = {
4053 if (!
ELEM(brush_type,
4072 float grab_location[3], imat[4][4], delta[3], loc[3];
4076 if (pbvh.
type() == bke::pbvh::Type::Mesh) {
4159 const float eps = 0.00001f;
4243 cloth::is_cloth_deform_brush(brush)))
4338 if (pbvh && auto_mask::is_enabled(sd,
object, &brush)) {
4365 bool need_pmap = sculpt_needs_connectivity_info(sd, brush, ob, 0);
4384 bool use_origco =
false;
4387 switch (pbvh.
type()) {
4389 if (
const std::optional<OrigPositionData> orig_data =
4390 orig_position_data_lookup_mesh_all_verts(
4394 origco = orig_data->positions;
4398 if (
const std::optional<OrigPositionData> orig_data = orig_position_data_lookup_grids(
4402 origco = orig_data->positions;
4416 switch (pbvh.
type()) {
4418 int mesh_active_vert;
4456 BMVert *bmesh_active_vert;
4488 bool use_origco =
false;
4491 switch (pbvh.
type()) {
4493 if (
const std::optional<OrigPositionData> orig_data =
4494 orig_position_data_lookup_mesh_all_verts(
4498 origco = orig_data->positions;
4502 if (
const std::optional<OrigPositionData> orig_data = orig_position_data_lookup_grids(
4506 origco = orig_data->positions;
4537 const float mval[2],
4540 float ray_normal[3],
4574 dist =
len_v3v3(ray_start, ray_end);
4582 const float mval[2],
4583 bool use_sampled_normal)
4590 float ray_start[3], ray_end[3], ray_normal[3], depth, mat[3][3];
4591 float viewDir[3] = {0.0f, 0.0f, 1.0f};
4592 bool original =
false;
4607 zero_v3(out->active_vertex_co);
4622 const Mesh &mesh = *
static_cast<const Mesh *
>(ob.
data);
4624 srd.faces = mesh.faces();
4625 srd.corner_verts = mesh.corner_verts();
4626 srd.corner_tris = mesh.corner_tris();
4634 srd.ray_start = ray_start;
4635 srd.ray_normal = ray_normal;
4650 zero_v3(out->active_vertex_co);
4659 switch (pbvh->
type()) {
4679 if (!use_sampled_normal) {
4707 IndexMaskMemory memory;
4708 const IndexMask node_mask = pbvh_gather_cursor_update(ob, original, memory);
4711 if (node_mask.is_empty()) {
4719 if (
const std::optional<float3> sampled_normal = calc_area_normal(
4734 const float mval[2],
4735 bool force_original)
4745 const float mval[2],
4746 bool force_original,
4748 bool limit_closest_radius)
4753 float ray_start[3], ray_end[3], ray_normal[3], depth;
4761 bool original = force_original || ((cache) ? !cache->
accum :
false);
4784 const Mesh &mesh = *
static_cast<const Mesh *
>(ob.
data);
4786 srd.
faces = mesh.faces();
4814 if (hit || !check_closest) {
4824 const Mesh &mesh = *
static_cast<const Mesh *
>(ob.
data);
4826 srd.faces = mesh.faces();
4827 srd.corner_verts = mesh.corner_verts();
4828 srd.corner_tris = mesh.corner_tris();
4835 srd.ray_start = ray_start;
4836 srd.ray_normal = ray_normal;
4837 srd.depth = std::numeric_limits<float>::max();
4838 srd.dist_sq_to_ray = std::numeric_limits<float>::max();
4846 if (srd.hit && srd.dist_sq_to_ray) {
4853 float closest_radius_sq = std::numeric_limits<float>::max();
4854 if (limit_closest_radius) {
4855 closest_radius_sq = sculpt_calc_radius(vc, brush, *
CTX_data_scene(C), out);
4856 closest_radius_sq *= closest_radius_sq;
4859 return hit && srd.dist_sq_to_ray < closest_radius_sq;
4886 if (!
G.background) {
4929 undo::restore_from_undo_step(
depsgraph, sd, ob);
4946 undo::restore_from_undo_step(
depsgraph, sd, ob);
4979 if (mmd !=
nullptr) {
4983 if ((update_type == UpdateType::Image) != 0) {
4985 if (update_type == UpdateType::Image) {
4996 if (!use_pbvh_draw) {
5017 r.
xmin += region.winrct.xmin - 2;
5018 r.
xmax += region.winrct.xmin + 2;
5019 r.
ymin += region.winrct.ymin - 2;
5020 r.
ymax += region.winrct.ymin + 2;
5026 if (pbvh.
type() == bke::pbvh::Type::Mesh) {
5030 if (use_pbvh_draw) {
5036 mesh->tag_positions_changed_no_normals();
5038 mesh->runtime->corner_normals_cache.tag_dirty();
5044 mesh->tag_positions_changed();
5047 mesh->bounds_set_eager(bke::pbvh::bounds_get(pbvh));
5048 if (ob.
runtime->bounds_eval) {
5049 ob.
runtime->bounds_eval = mesh->bounds_min_max();
5068 current_rv3d->
rflag &= ~RV3D_PAINTING;
5085 if (rv3d != current_rv3d) {
5094 if (update_type == UpdateType::Image) {
5107 if (update_type == UpdateType::Position) {
5108 bke::pbvh::store_bounds_orig(pbvh);
5114 if (update_type == UpdateType::Position) {
5115 if (pbvh.
type() == bke::pbvh::Type::BMesh) {
5253 if (dyntopo::stroke_is_dyntopo(ob, brush)) {
5315 smooth_brush_toggle_off(C, &sd.
paint, ss.
cache);
5320 MEM_delete(ss.
cache);
5347 int ignore_background_click;
5385 if (!pbvh || pbvh->
type() != bke::pbvh::Type::Grids) {
5405 if (ignore_background_click && !
over_mesh(C, op, mval)) {
5454 if (ss.
cache && !dyntopo::stroke_is_dyntopo(ob, brush)) {
5455 undo::restore_from_undo_step(
depsgraph, sd, ob);
5460 MEM_delete(ss.
cache);
5477 ot->
idname =
"SCULPT_OT_brush_stroke";
5496 "ignore_background_click",
5498 "Ignore Background Click",
5499 "Clicks on the background do not start the stroke");
5519 float distance_sq = std::numeric_limits<float>::max();
5524 if (joined.
vert == -1) {
5525 joined.
vert =
b.vert;
5529 joined.
vert =
b.vert;
5540 const float max_distance_sq,
5541 const int island_id,
5545 for (
const int vert : node.verts()) {
5546 if (!hide_vert.
is_empty() && hide_vert[vert]) {
5552 if (islands::vert_id_get(ss, vert) == island_id) {
5556 if (distance_sq < max_distance_sq && distance_sq < nvtd.
distance_sq) {
5568 const float max_distance_sq,
5569 const int island_id,
5573 for (
const int grid : node.grids()) {
5574 const IndexRange grid_range = bke::ccg::grid_range(key, grid);
5576 const int vert = grid_range[offset];
5580 if (islands::vert_id_get(ss, vert) == island_id) {
5584 if (distance_sq < max_distance_sq && distance_sq < nvtd.
distance_sq) {
5594 const float max_distance_sq,
5595 const int island_id,
5599 for (
const BMVert *bm_vert :
5609 if (islands::vert_id_get(ss, vert) == island_id) {
5613 if (distance_sq < max_distance_sq && distance_sq < nvtd.
distance_sq) {
5622 const float max_distance_sq,
5630 switch (pbvh.
type()) {
5631 case bke::pbvh::Type::Mesh: {
5632 const Mesh &mesh = *
static_cast<const Mesh *
>(ob.
data);
5636 bke::AttrDomain::Point);
5637 for (
const int vert : vert_positions.
index_range()) {
5641 const int island_id = islands::vert_id_get(ss, vert);
5642 const float3 &location = vert_positions[vert];
5645 const IndexMask nodes_in_sphere = bke::pbvh::search_nodes(
5658 nodes_in_sphere.
slice(range).foreach_index([&](
const int i) {
5670 NearestVertData::join);
5671 if (nvtd.vert == -1) {
5674 fake_neighbors[vert] = nvtd.vert;
5675 fake_neighbors[nvtd.vert] = vert;
5679 case bke::pbvh::Type::Grids: {
5684 for (
const int vert : positions.index_range()) {
5688 const int island_id = islands::vert_id_get(ss, vert);
5689 const float3 &location = positions[vert];
5691 const IndexMask nodes_in_sphere = bke::pbvh::search_nodes(
5704 nodes_in_sphere.
slice(range).foreach_index([&](
const int i) {
5717 NearestVertData::join);
5718 if (nvtd.vert == -1) {
5721 fake_neighbors[vert] = nvtd.vert;
5722 fake_neighbors[nvtd.vert] = vert;
5726 case bke::pbvh::Type::BMesh: {
5732 const int island_id = islands::vert_id_get(ss, vert);
5735 const IndexMask nodes_in_sphere = bke::pbvh::search_nodes(
5748 nodes_in_sphere.
slice(range).foreach_index([&](
const int i) {
5750 ss, location, max_distance_sq, island_id, nodes[i], nvtd);
5754 NearestVertData::join);
5755 if (nvtd.vert == -1) {
5758 fake_neighbors[vert] = nvtd.vert;
5759 fake_neighbors[nvtd.vert] = vert;
5781 array_utils::count_indices(base_mesh->corner_edges(), adjacent_faces_edge_count);
5784 for (
const int e : edges.index_range()) {
5785 if (adjacent_faces_edge_count[
e] < 2) {
5786 const int2 &edge = edges[
e];
5797 const float max_dist)
5810 islands::ensure_cache(ob);
5811 fake_neighbor_init(ob, max_dist);
5821 pose_fake_neighbors_free(ss);
5831 float ray_start[3], ray_end[3], ray_normal[3];
5856 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
5858 srd.
faces = mesh.faces();
5901 const int verts_num)
5905 if (islands_num == 1) {
5911 for (const int i : range) {
5912 island_ids[i] = uint8_t(island_indices[i]);
5924 const Span<int> corner_verts = mesh.corner_verts();
5931 faces.index_range(), hide_poly, memory);
5937 disjoint_set.
join(face_verts.
first(), face_verts[i]);
5953 for (const int grid : range) {
5954 SubdivCCGNeighbors neighbors;
5955 for (const short y : IndexRange(key.grid_size)) {
5956 for (const short x : IndexRange(key.grid_size)) {
5957 const SubdivCCGCoord coord{grid, x, y};
5958 SubdivCCGNeighbors neighbors;
5959 BKE_subdiv_ccg_neighbor_coords_get(subdiv_ccg, coord, true, neighbors);
5960 for (const SubdivCCGCoord neighbor : neighbors.coords) {
5961 disjoint_set.join(coord.to_index(key), neighbor.to_index(key));
5968 return vert_disjoint_set_to_islands(disjoint_set, subdiv_ccg.positions.size());
5983 for (
const BMFace *face :
6036 calc_brush_local_mat(0.0, ob, unused, mat);
6060 positions[i] = vert->co;
6076 normals[i] = vert->no;
6086 for (
const int i : indices.index_range()) {
6087 dst[i] = src[indices[i]];
6101 const IndexRange grids_range = bke::ccg::grid_range(key, grids[i]);
6102 const IndexRange node_range = bke::ccg::grid_range(key, i);
6126 for (
const int i : indices.index_range()) {
6127 dst[indices[i]] = src[i];
6141 const IndexRange grids_range = bke::ccg::grid_range(key, grids[i]);
6142 const IndexRange node_range = bke::ccg::grid_range(key, i);
6284 r_factors.
resize(positions.size());
6292 r_distances.
resize(positions.size());
6299 auto_mask::calc_grids_factors(
depsgraph,
object, cache.
automasking.get(), node, grids, factors);
6388 r_factors.
resize(positions.size());
6396 r_distances.
resize(positions.size());
6403 auto_mask::calc_grids_factors(
depsgraph,
object, cache.
automasking.get(), node, grids, factors);
6449 for (
const int i :
verts.index_range()) {
6450 r_factors[i] = hide_vert[
verts[i]] ? 0.0f : 1.0f;
6454 r_factors.
fill(1.0f);
6467 r_factors.
fill(1.0f);
6471 const BitSpan hidden = grid_hidden[grids[i]];
6474 r_factors[start + offset] = hidden[offset] ? 0.0f : 1.0f;
6497 if (!mask.is_empty()) {
6498 for (
const int i :
verts.index_range()) {
6499 r_factors[i] = 1.0f - mask[
verts[i]];
6503 r_factors.
fill(1.0f);
6507 for (
const int i :
verts.index_range()) {
6508 if (hide_vert[
verts[i]]) {
6509 r_factors[i] = 0.0f;
6527 r_factors[i] = 0.0f;
6543 const Span src = masks.
slice(bke::ccg::grid_range(key, grids[i]));
6546 dst[offset] = 1.0f - src[offset];
6551 r_factors.
fill(1.0f);
6557 const BitSpan hidden = grid_hidden[grids[i]];
6560 if (hidden[offset]) {
6561 r_factors[start + offset] = 0.0f;
6575 for (
const int i :
verts.index_range()) {
6577 factors[i] *= std::max(
dot, 0.0f);
6587 for (
const int i : normals.index_range()) {
6589 factors[i] *= std::max(
dot, 0.0f);
6602 const Span<float3> grid_normals = normals.
slice(bke::ccg::grid_range(key, grids[i]));
6604 for (
const int offset : grid_factors.
index_range()) {
6605 const float dot =
math::dot(view_normal, grid_normals[offset]);
6606 grid_factors[offset] *= std::max(
dot, 0.0f);
6620 factors[i] *= std::max(
dot, 0.0f);
6634 factors[i] *= std::max(
dot, 0.0f);
6656 for (
const int i :
verts.index_range()) {
6658 if (radial_symmetry_pass) {
6683 for (
const int i : positions.index_range()) {
6685 if (radial_symmetry_pass) {
6709 for (
const int i :
verts.index_range()) {
6716 for (
const int i :
verts.index_range()) {
6729 for (
float &value : r_distances) {
6730 value = std::sqrt(value);
6748 for (
const int i : positions.index_range()) {
6755 for (
const int i : positions.index_range()) {
6767 for (
float &value : r_distances) {
6768 value = std::sqrt(value);
6777 if (distances[i] >= radius) {
6794 const float hardness = 1.0f - roundness;
6795 for (
const int i :
verts.index_range()) {
6796 if (factors[i] == 0.0f) {
6797 r_distances[i] = std::numeric_limits<float>::max();
6802 if (!(local.x <= 1.0f && local.y <= 1.0f && local.z <= 1.0f)) {
6804 r_distances[i] = std::numeric_limits<float>::max();
6807 if (std::min(local.x, local.y) > hardness) {
6812 if (std::max(local.x, local.y) > hardness) {
6814 r_distances[i] = (std::max(local.x, local.y) - hardness) / roundness;
6819 r_distances[i] = 0.0f;
6833 const float hardness = 1.0f - roundness;
6834 for (
const int i : positions.index_range()) {
6835 if (factors[i] == 0.0f) {
6836 r_distances[i] = std::numeric_limits<float>::max();
6841 if (!(local.x <= 1.0f && local.y <= 1.0f && local.z <= 1.0f)) {
6843 r_distances[i] = std::numeric_limits<float>::max();
6846 if (std::min(local.x, local.y) > hardness) {
6851 if (std::max(local.x, local.y) > hardness) {
6853 r_distances[i] = (std::max(local.x, local.y) - hardness) / roundness;
6858 r_distances[i] = 0.0f;
6863 const float hardness,
6866 if (hardness == 0.0f) {
6869 const float threshold = hardness * radius;
6870 if (hardness == 1.0f) {
6872 distances[i] = distances[i] < threshold ? 0.0f : radius;
6876 const float radius_inv =
math::rcp(radius);
6877 const float hardness_inv_rcp =
math::rcp(1.0f - hardness);
6879 if (distances[i] < threshold) {
6880 distances[i] = 0.0f;
6883 const float radius_factor = (distances[i] * radius_inv - hardness) * hardness_inv_rcp;
6884 distances[i] = radius_factor * radius;
6912 for (
const int i :
verts.index_range()) {
6913 float texture_value;
6917 ss, brush, vert_positions[
verts[i]], thread_id, &texture_value, texture_rgba);
6919 factors[i] *= texture_value;
6936 for (
const int i : positions.index_range()) {
6937 float texture_value;
6942 factors[i] *= texture_value;
6953 const float3 prev_translation = positions[i] - orig_positions[i];
6954 translations[i] -= prev_translation;
6964 for (
const int i :
verts.index_range()) {
6965 const int vert =
verts[i];
6966 positions[vert] += translations[i];
6979 const Span<float3> grid_translations = translations.
slice(bke::ccg::grid_range(key, i));
6981 for (
const int offset : grid_positions.
index_range()) {
6982 grid_positions[offset] += grid_translations[offset];
7002 if (len_sq < std::numeric_limits<float>::epsilon()) {
7005 const float dot_factor = -
math::rcp(len_sq);
7007 translations[i] += plane *
math::dot(translations[i], plane) * dot_factor;
7017 for (
const int i :
verts.index_range()) {
7036 for (
float3 &translation : translations) {
7037 translation[axis] = 0.0f;
7048 for (
const int i :
verts.index_range()) {
7049 const int vert =
verts[i];
7057 co_mirror[axis] = 0.0f;
7059 translations[i][axis] = co_local[axis] - positions[vert][axis];
7077 for (
float3 &translation : translations) {
7078 translation[axis] = 0.0f;
7089 for (
const int i : positions.index_range()) {
7096 co_mirror[axis] = 0.0f;
7098 translations[i][axis] = co_local[axis] - positions[i][axis];
7106 this->eval = bke::pbvh::vert_positions_eval(
depsgraph, object_orig);
7111 orig_ = mesh.vert_positions_for_write();
7114 if (eval_mut.
data() != orig_.data()) {
7115 eval_mut_ = eval_mut;
7118 if (
Key *keys = mesh.key) {
7120 const int active_index = object_orig.
shapenr - 1;
7122 basis_active_ = active_key_ == keys->refkey;
7127 active_key_ =
nullptr;
7128 basis_active_ =
false;
7148 if (deform_imats_) {
7155 const MutableSpan active_key_data(
static_cast<float3 *
>(key->data), key->totelem);
7156 if (basis_active_) {
7165 if (dependent_keys_) {
7168 if ((other_key != key) && (*dependent_keys_)[i]) {
7188 if (&active_key == mesh.key->refkey) {
7189 for (
const int vert :
verts) {
7190 active_key_data[vert] = positions_orig[vert];
7198 object.shapenr - 1))
7202 if ((other_key != &active_key) && (*dependent)[i]) {
7213 translations[i] *= factors[i];
7219 if (factor == 1.0f) {
7223 translations[i] *= factor;
7229 if (strength == 1.0f) {
7232 for (
float &factor : factors) {
7242 factors[i] *= strengths[i];
7253 r_translations[i] = offset * factors[i];
7263 for (
const int i :
verts.index_range()) {
7264 translations[i] = new_positions[i] - old_positions[
verts[i]];
7274 translations[i] = new_positions[i] - old_positions[i];
7291 for (
const int i : positions.index_range()) {
7302 [&](
const int i,
const int pos) { node_data[
pos] = nodes[i].verts().
size(); });
7303 return offset_indices::accumulate_counts_to_offsets(node_data);
7315 return offset_indices::accumulate_counts_to_offsets(node_data);
7327 return offset_indices::accumulate_counts_to_offsets(node_data);
7339 for (
const int i :
verts.index_range()) {
7352 const int grid = grids[i];
7353 const int node_verts_start = i * key.
grid_area;
7358 const int node_vert_index = node_verts_start + offset;
7396 for (
const int i :
verts.index_range()) {
7397 const int vert =
verts[i];
7401 if (boundary_verts[vert]) {
7402 if (neighbors.
size() == 2) {
7408 neighbors.
remove_if([&](
const int vert) {
return !boundary_verts[vert]; });
7426 const int grid = grids[i];
7427 const int node_verts_start = i * key.
grid_area;
7434 const int node_vert_index = node_verts_start + offset;
7445 faces, corner_verts, boundary_verts, subdiv_ccg, coord))
7455 faces, corner_verts, boundary_verts, subdiv_ccg, coord);
7459 result[node_vert_index] = neighbors.
coords;
7474 result[i] = neighbor_data;
7484 for (
const int i :
verts.index_range()) {
7485 const float3 &position = vert_positions[
verts[i]];
7488 translations[i] = closest - position;
7496 for (
const int i : positions.index_range()) {
7497 const float3 &position = positions[i];
7500 translations[i] = closest - position;
7511 for (
const int i : positions.index_range()) {
7539 for (
const int i :
verts.index_range()) {
7550 for (
const int i : positions.index_range()) {
7562 for (
const int i :
verts.index_range()) {
7573 for (
const int i : positions.index_range()) {
const MTex * BKE_brush_mask_texture_get(const Brush *brush, const eObjectMode object_mode)
bool BKE_brush_use_alpha_pressure(const Brush *brush)
float BKE_brush_unprojected_radius_get(const Scene *scene, const Brush *brush)
int BKE_brush_size_get(const Scene *scene, const Brush *brush)
void BKE_brush_unprojected_radius_set(Scene *scene, Brush *brush, float unprojected_radius)
void BKE_brush_size_set(Scene *scene, Brush *brush, int size)
float BKE_brush_sample_tex_3d(const Scene *scene, const Brush *br, const MTex *mtex, const float point[3], float rgba[4], int thread, ImagePool *pool)
bool BKE_brush_use_size_pressure(const Brush *brush)
bool BKE_brush_has_cube_tip(const Brush *brush, PaintMode paint_mode)
float BKE_brush_alpha_get(const Scene *scene, const Brush *brush)
bool BKE_brush_use_locked_size(const Scene *scene, const Brush *brush)
void BKE_brush_calc_curve_factors(eBrushCurvePreset preset, const CurveMapping *cumap, blender::Span< float > distances, float brush_radius, blender::MutableSpan< float > factors)
int CCG_grid_xy_to_index(const int grid_size, const int x, const int y)
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Base * CTX_data_active_base(const bContext *C)
Main * CTX_data_main(const bContext *C)
ToolSettings * CTX_data_tool_settings(const bContext *C)
RegionView3D * CTX_wm_region_view3d(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
ImagePool * BKE_image_pool_new(void)
KeyBlock * BKE_keyblock_from_object(Object *ob)
KeyBlock * BKE_keyblock_find_by_index(Key *key, int index)
std::optional< blender::Array< bool > > BKE_keyblock_get_dependent_keys(const Key *key, int index)
bool BKE_base_is_visible(const View3D *v3d, const Base *base)
Mesh * BKE_mesh_from_object(Object *ob)
void multires_stitch_grids(Object *)
void multires_mark_as_modified(Depsgraph *depsgraph, Object *object, MultiresModifiedFlags flags)
General operations, lookup, etc. for blender objects.
std::optional< blender::Bounds< blender::float3 > > BKE_object_boundbox_get(const Object *ob)
bool BKE_paint_brush_set_essentials(Main *bmain, Paint *paint, const char *name)
#define PAINT_SYMM_AREA_DEFAULT
bool BKE_paint_brush_set(Paint *paint, Brush *brush)
bool BKE_sculptsession_use_pbvh_draw(const Object *ob, const RegionView3D *rv3d)
std::variant< std::monostate, int, SubdivCCGCoord, BMVert * > ActiveVert
#define SCULPT_FACE_SET_NONE
const Brush * BKE_paint_brush_for_read(const Paint *paint)
MultiresModifierData * BKE_sculpt_multires_active(const Scene *scene, Object *ob)
void BKE_sculpt_update_object_for_edit(Depsgraph *depsgraph, Object *ob_orig, bool is_paint_tool)
void BKE_sculpt_color_layer_create_if_needed(Object *object)
Paint * BKE_paint_get_active_from_context(const bContext *C)
Brush * BKE_paint_brush(Paint *paint)
void BKE_sculpt_mask_layers_ensure(Depsgraph *depsgraph, Main *bmain, Object *ob, MultiresModifierData *mmd)
A BVH for high poly meshes.
bool BKE_pbvh_node_fully_hidden_get(const blender::bke::pbvh::Node &node)
blender::Bounds< blender::float3 > BKE_pbvh_redraw_BB(const blender::bke::pbvh::Tree &pbvh)
blender::Bounds< blender::float3 > BKE_pbvh_node_get_original_BB(const blender::bke::pbvh::Node *node)
void BKE_pbvh_node_mark_topology_update(blender::bke::pbvh::Node &node)
int BKE_pbvh_get_grid_num_verts(const Object &object)
float BKE_pbvh_node_get_tmin(const blender::bke::pbvh::Node *node)
bool BKE_pbvh_node_fully_masked_get(const blender::bke::pbvh::Node &node)
void BKE_pbvh_bmesh_after_stroke(BMesh &bm, blender::bke::pbvh::Tree &pbvh)
const blender::Set< BMFace *, 0 > & BKE_pbvh_bmesh_node_faces(blender::bke::pbvh::BMeshNode *node)
const blender::Set< BMVert *, 0 > & BKE_pbvh_bmesh_node_unique_verts(blender::bke::pbvh::BMeshNode *node)
void BKE_pbvh_bmesh_node_save_orig(BMesh *bm, BMLog *log, blender::bke::pbvh::BMeshNode *node, bool use_original)
void BKE_pbvh_node_get_bm_orco_data(const blender::bke::pbvh::BMeshNode &node, blender::Span< blender::float3 > &r_orig_positions, blender::Span< blender::int3 > &r_orig_tris)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
bool BKE_subdiv_ccg_coord_is_mesh_boundary(blender::OffsetIndices< int > faces, blender::Span< int > corner_verts, blender::BitSpan boundary_verts, const SubdivCCG &subdiv_ccg, SubdivCCGCoord coord)
int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG &subdiv_ccg, const int grid_index)
CCGKey BKE_subdiv_ccg_key_top_level(const SubdivCCG &subdiv_ccg)
@ SUBDIV_CCG_ADJACENT_EDGE
@ SUBDIV_CCG_ADJACENT_VERTEX
@ SUBDIV_CCG_ADJACENT_NONE
void BKE_subdiv_ccg_foreach_visible_grid_vert(const CCGKey &key, const blender::BitGroupVector<> &grid_hidden, const int grid, const Fn &fn)
SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(const SubdivCCG &subdiv_ccg, const SubdivCCGCoord &coord, blender::Span< int > corner_verts, blender::OffsetIndices< int > faces, int &r_v1, int &r_v2)
void BKE_subdiv_ccg_neighbor_coords_get(const SubdivCCG &subdiv_ccg, const SubdivCCGCoord &coord, bool include_duplicates, SubdivCCGNeighbors &r_neighbors)
@ MULTIRES_COORDS_MODIFIED
#define BLI_assert_unreachable()
Dial * BLI_dial_init(const float start_position[2], float threshold)
float BLI_dial_angle(Dial *dial, const float current_position[2])
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
MINLINE float max_ff(float a, float b)
MINLINE float pow2f(float x)
MINLINE float square_f(float a)
MINLINE float pow3f(float x)
MINLINE float pow4f(float x)
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
void isect_ray_tri_watertight_v3_precalc(struct IsectRayPrecalc *isect_precalc, const float ray_direction[3])
struct DistRayAABB_Precalc dist_squared_ray_to_aabb_v3_precalc(const float ray_origin[3], const float ray_direction[3])
MINLINE float plane_point_side_v3(const float plane[4], const float co[3])
void closest_to_plane_normalized_v3(float r_close[3], const float plane[4], const float pt[3])
void closest_on_tri_to_point_v3(float r[3], const float p[3], const float v1[3], const float v2[3], const float v3[3])
float dist_squared_ray_to_aabb_v3(const struct DistRayAABB_Precalc *data, const float bb_min[3], const float bb_max[3], float r_point[3], float *r_depth)
void mul_m3_v3(const float M[3][3], float r[3])
void zero_m4(float m[4][4])
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void copy_m3_m4(float m1[3][3], const float m2[4][4])
void mul_m4_v3(const float M[4][4], float r[3])
void scale_m4_fl(float R[4][4], float scale)
void copy_m4_m4(float m1[4][4], const float m2[4][4])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void rotate_m4(float mat[4][4], char axis, float angle)
void mul_v3_mat3_m4v3(float r[3], const float mat[4][4], const float vec[3])
void mul_mat3_m4_v3(const float mat[4][4], float r[3])
void normalize_m4(float R[4][4]) ATTR_NONNULL()
void axis_angle_to_mat3_single(float R[3][3], char axis, float angle)
void axis_angle_normalized_to_quat(float r[4], const float axis[3], float angle)
void quat_to_axis_angle(float axis[3], float *angle, const float q[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
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_fl(float r[3], float f)
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_v3_int(int r[3], const int a[3])
void project_plane_v3_v3v3(float out[3], const float p[3], const float v_plane[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void negate_v3(float r[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE bool is_zero_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void zero_v2(float r[2])
MINLINE void zero_v3(float r[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE void copy_v4_fl(float r[4], float f)
MINLINE float normalize_v3(float n[3])
void BLI_rcti_union(struct rcti *rct_a, const struct rcti *rct_b)
bool BLI_rcti_is_empty(const struct rcti *rect)
int BLI_task_parallel_thread_id(const TaskParallelTLS *tls)
#define ARRAY_SET_ITEMS(...)
#define CLOG_WARN(clg_ref,...)
void DEG_id_tag_update(ID *id, unsigned int flags)
#define ID_REAL_USERS(id)
@ BRUSH_DEFORM_TARGET_CLOTH_SIM
#define SCULPT_BRUSH_TYPE_HAS_DYNTOPO(t)
@ SCULPT_BRUSH_TYPE_DRAW_SHARP
@ SCULPT_BRUSH_TYPE_THUMB
@ SCULPT_BRUSH_TYPE_BOUNDARY
@ SCULPT_BRUSH_TYPE_DISPLACEMENT_SMEAR
@ SCULPT_BRUSH_TYPE_DRAW_FACE_SETS
@ SCULPT_BRUSH_TYPE_NUDGE
@ SCULPT_BRUSH_TYPE_CLOTH
@ SCULPT_BRUSH_TYPE_PINCH
@ SCULPT_BRUSH_TYPE_SMEAR
@ SCULPT_BRUSH_TYPE_CLAY_THUMB
@ SCULPT_BRUSH_TYPE_MULTIPLANE_SCRAPE
@ SCULPT_BRUSH_TYPE_SIMPLIFY
@ SCULPT_BRUSH_TYPE_SNAKE_HOOK
@ SCULPT_BRUSH_TYPE_CREASE
@ SCULPT_BRUSH_TYPE_LAYER
@ SCULPT_BRUSH_TYPE_SLIDE_RELAX
@ SCULPT_BRUSH_TYPE_ELASTIC_DEFORM
@ SCULPT_BRUSH_TYPE_FLATTEN
@ SCULPT_BRUSH_TYPE_SMOOTH
@ SCULPT_BRUSH_TYPE_PAINT
@ SCULPT_BRUSH_TYPE_DISPLACEMENT_ERASER
@ SCULPT_BRUSH_TYPE_SCRAPE
@ SCULPT_BRUSH_TYPE_INFLATE
@ SCULPT_BRUSH_TYPE_ROTATE
@ SCULPT_BRUSH_TYPE_CLAY_STRIPS
@ BRUSH_GRAB_ACTIVE_VERTEX
@ BRUSH_INVERSE_SMOOTH_PRESSURE
@ BRUSH_INVERT_TO_SCRAPE_FILL
@ BRUSH_CLOTH_DEFORM_EXPAND
@ BRUSH_CLOTH_DEFORM_GRAB
@ BRUSH_CLOTH_DEFORM_SNAKE_HOOK
#define SCULPT_BRUSH_TYPE_HAS_ACCUMULATE(t)
#define SCULPT_BRUSH_TYPE_HAS_RAKE(t)
@ BRUSH_SNAKE_HOOK_DEFORM_ELASTIC
@ PAINT_FALLOFF_SHAPE_SPHERE
@ PAINT_FALLOFF_SHAPE_TUBE
@ BRUSH_SMOOTH_DEFORM_SURFACE
@ BRUSH_SMOOTH_DEFORM_LAPLACIAN
@ BRUSH_PAINT_WET_MIX_PRESSURE
@ BRUSH_PAINT_HARDNESS_PRESSURE
@ BRUSH_PAINT_FLOW_PRESSURE
@ BRUSH_PAINT_DENSITY_PRESSURE
@ BRUSH_PAINT_WET_PERSISTENCE_PRESSURE
@ BRUSH_PAINT_WET_MIX_PRESSURE_INVERT
@ BRUSH_PAINT_HARDNESS_PRESSURE_INVERT
@ BRUSH_PAINT_FLOW_PRESSURE_INVERT
@ BRUSH_PAINT_DENSITY_PRESSURE_INVERT
@ BRUSH_PAINT_WET_PERSISTENCE_PRESSURE_INVERT
@ BRUSH_USE_COLOR_AS_DISPLACEMENT
@ BRUSH_AREA_RADIUS_PRESSURE
#define SCULPT_BRUSH_TYPE_HAS_NORMAL_WEIGHT(t)
#define SCULPT_BRUSH_TYPE_HAS_TOPOLOGY_RAKE(t)
Object is a sort of wrapper for general info.
@ SCULPT_DYNTOPO_SUBDIVIDE
@ SCULPT_DYNTOPO_DETAIL_MANUAL
@ SCULPT_DYNTOPO_DETAIL_CONSTANT
@ SCULPT_DYNTOPO_COLLAPSE
@ SCULPT_DYNTOPO_DETAIL_BRUSH
@ V3D_SHADING_VERTEX_COLOR
#define RV3D_CLIPPING_ENABLED(v3d, rv3d)
#define OPERATOR_RETVAL_CHECK(ret)
void ED_image_undo_push_begin(const char *name, PaintMode paint_mode)
void ED_image_undo_push_end()
void ED_image_paint_brush_type_update_sticky_shading_color(bContext *C, Object *ob)
void ED_area_tag_redraw_regiontype(ScrArea *area, int regiontype)
void ED_region_tag_redraw_partial(ARegion *region, const rcti *rct, bool rebuild)
void ED_region_tag_redraw(ARegion *region)
blender::float2 ED_view3d_project_float_v2_m4(const ARegion *region, const float co[3], const blender::float4x4 &mat)
void ED_view3d_win_to_3d(const View3D *v3d, const ARegion *region, const float depth_pt[3], const float mval[2], float r_out[3])
void ED_view3d_init_mats_rv3d(const Object *ob, RegionView3D *rv3d)
ViewContext ED_view3d_viewcontext_init(bContext *C, Depsgraph *depsgraph)
void ED_view3d_win_to_delta(const ARegion *region, const float xy_delta[2], float zfac, float r_out[3])
blender::float4x4 ED_view3d_ob_project_mat_get(const RegionView3D *rv3d, const Object *ob)
bool ED_view3d_win_to_segment_clipped(const Depsgraph *depsgraph, const ARegion *region, const View3D *v3d, const float mval[2], float r_ray_start[3], float r_ray_end[3], bool do_clip_planes)
void view3d_operator_needs_opengl(const bContext *C)
void ED_view3d_win_to_origin(const ARegion *region, const float mval[2], float r_out[3])
float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3])
bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], bool is_local)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Read Guarded memory(de)allocation.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a vector
void ntreeTexEndExecTree(struct bNodeTreeExec *exec)
struct bNodeTreeExec * ntreeTexBeginExecTree(struct bNodeTree *ntree)
#define BM_ELEM_CD_SET_FLOAT(ele, offset, f)
#define BM_ELEM_CD_GET_FLOAT(ele, offset)
#define BM_ELEM_CD_GET_INT(ele, offset)
#define BM_elem_index_get(ele)
#define BM_elem_flag_test(ele, hflag)
#define BM_elem_flag_test_bool(ele, hflag)
#define BM_ITER_ELEM(ele, iter, data, itype)
ATTR_WARN_UNUSED_RESULT BMesh * bm
const float * BM_log_find_original_vert_mask(BMLog *log, BMVert *v)
const float * BM_log_find_original_vert_co(BMLog *log, BMVert *v)
int BM_mesh_elem_count(BMesh *bm, const char htype)
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
BLI_INLINE BMVert * BM_vert_at_index(BMesh *bm, const int index)
bool BM_vert_is_boundary(const BMVert *v)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE void invalidate()
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
bool closest(btVector3 &v)
IndexRange index_range() const
void reinitialize(const int64_t new_size)
int calc_reduced_ids(MutableSpan< int > result) const
constexpr IndexRange drop_front(int64_t n) const
constexpr int64_t size() const
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr T * data() const
constexpr void fill(const T &value) const
constexpr IndexRange index_range() const
constexpr void copy_from(Span< T > values) const
constexpr Span slice(int64_t start, int64_t size) const
constexpr const T & first() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
int64_t remove_if(Predicate &&predicate)
void append(const T &value)
void resize(const int64_t new_size)
void reinitialize(const int64_t new_size)
void append_non_duplicates(const T &value)
Span< T > as_span() const
void resize(const int64_t new_size_in_bits, const bool value=false)
GAttributeReader lookup(const StringRef attribute_id) const
void tag_attribute_changed(const IndexMask &node_mask, StringRef attribute_name)
void tag_positions_changed(const IndexMask &node_mask)
Span< NodeT > nodes() const
void tag_face_sets_changed(const IndexMask &node_mask)
void tag_masks_changed(const IndexMask &node_mask)
void tag_topology_changed(const IndexMask &node_mask)
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
static IndexMask from_bools_inverse(const IndexMask &universe, Span< bool > bools, IndexMaskMemory &memory)
IndexMask slice(IndexRange range) const
int64_t min_array_size() const
IndexRange index_range() const
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
void foreach_index(Fn &&fn) const
input_tx image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "preview_img") .compute_source("compositor_compute_preview.glsl") .do_static_compilation(true)
local_group_size(16, 16) .push_constant(Type b
CCL_NAMESPACE_BEGIN ccl_device_inline float frac(float x, ccl_private int *ix)
const Depsgraph * depsgraph
draw_view in_light_buf[] float
static float normals[][3]
int ED_gpencil_session_active()
static void transform_positions(const Span< blender::float3 > src, const blender::float4x4 &transform, blender::MutableSpan< blender::float3 > dst)
CCL_NAMESPACE_BEGIN ccl_device float invert(float color, float factor)
IndexRange grid_range(const int grid_area, const int grid)
int2 face_find_adjacent_verts(const IndexRange face, const Span< int > corner_verts, const int vert)
pbvh::Tree * pbvh_get(Object &object)
IndexMask search_nodes(const Tree &pbvh, IndexMaskMemory &memory, FunctionRef< bool(const Node &)> filter_fn)
void update_normals(const Depsgraph &depsgraph, Object &object_orig, Tree &pbvh)
IndexMask all_leaf_nodes(const Tree &pbvh, IndexMaskMemory &memory)
void clip_ray_ortho(Tree &pbvh, bool original, float ray_start[3], float ray_end[3], float ray_normal[3])
bool node_raycast_bmesh(BMeshNode &node, const float3 &ray_start, const float3 &ray_normal, IsectRayPrecalc *isect_precalc, float *depth, bool use_original, BMVert **r_active_vertex, float3 &r_face_normal)
bool node_raycast_mesh(const MeshNode &node, Span< float3 > node_positions, Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, Span< int3 > corner_tris, Span< bool > hide_poly, const float3 &ray_start, const float3 &ray_normal, IsectRayPrecalc *isect_precalc, float *depth, int &r_active_vertex, int &r_active_face_index, float3 &r_face_normal)
void node_update_mask_bmesh(int mask_offset, BMeshNode &node)
void node_update_mask_mesh(Span< float > mask, MeshNode &node)
void node_update_mask_grids(const CCGKey &key, Span< float > masks, GridsNode &node)
bool node_raycast_grids(const SubdivCCG &subdiv_ccg, GridsNode &node, Span< float3 > node_positions, const float3 &ray_start, const float3 &ray_normal, const IsectRayPrecalc *isect_precalc, float *depth, SubdivCCGCoord &r_active_vertex, int &r_active_grid_index, float3 &r_face_normal)
Span< float3 > vert_normals_eval(const Depsgraph &depsgraph, const Object &object_orig)
MutableSpan< float3 > vert_positions_eval_for_write(const Depsgraph &depsgraph, Object &object_orig)
Bounds< float3 > node_bounds(const Node &node)
bool bmesh_update_topology(BMesh &bm, Tree &pbvh, BMLog &bm_log, PBVHTopologyUpdateMode mode, float min_edge_len, float max_edge_len, const float center[3], const float view_normal[3], float radius, bool use_frontface, bool use_projected)
bool find_nearest_to_ray_node(Tree &pbvh, Node &node, Span< float3 > node_positions, bool use_origco, Span< float3 > vert_positions, const OffsetIndices< int > faces, Span< int > corner_verts, Span< int3 > corner_tris, Span< bool > hide_poly, const SubdivCCG *subdiv_ccg, const float ray_start[3], const float ray_normal[3], float *depth, float *dist_sq)
Span< int > node_face_indices_calc_grids(const SubdivCCG &subdiv_ccg, const GridsNode &node, Vector< int > &faces)
Span< float3 > vert_positions_eval(const Depsgraph &depsgraph, const Object &object_orig)
void find_nearest_to_ray(Tree &pbvh, const FunctionRef< void(Node &node, float *tmin)> fn, const float3 &ray_start, const float3 &ray_normal, bool original)
void raycast(Tree &pbvh, FunctionRef< void(Node &node, float *tmin)> cb, const float3 &ray_start, const float3 &ray_normal, bool original)
bool needs_normal(const SculptSession &ss, const Sculpt &sd, const Brush *brush)
std::unique_ptr< Cache > cache_init(const Depsgraph &depsgraph, const Sculpt &sd, Object &ob)
bool is_enabled(const Sculpt &sd, const Object &object, const Brush *br)
void do_boundary_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
bool vert_is_boundary(const GroupedSpan< int > vert_to_face_map, const Span< bool > hide_poly, const BitSpan boundary, const int vert)
void ensure_boundary_info(Object &object)
void brush_store_simulation_state(const Depsgraph &depsgraph, const Object &object, SimulationData &cloth_sim)
void ensure_nodes_constraints(const Sculpt &sd, Object &object, const IndexMask &node_mask, SimulationData &cloth_sim, const float3 &initial_location, const float radius)
void sim_activate_nodes(Object &object, SimulationData &cloth_sim, const IndexMask &node_mask)
IndexMask brush_affected_nodes_gather(const Object &object, const Brush &brush, IndexMaskMemory &memory)
void do_cloth_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
void do_simulation_step(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, SimulationData &cloth_sim, const IndexMask &node_mask)
std::unique_ptr< SimulationData > brush_simulation_create(const Depsgraph &depsgraph, Object &ob, const float cloth_mass, const float cloth_damping, const float cloth_softbody_strength, const bool use_collisions, const bool needs_deform_coords)
bke::GSpanAttributeWriter active_color_attribute_for_write(Mesh &mesh)
void do_smear_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &ob, const IndexMask &node_mask)
void color_vert_set(OffsetIndices< int > faces, Span< int > corner_verts, GroupedSpan< int > vert_to_face_map, bke::AttrDomain color_domain, int vert, const float4 &color, GMutableSpan color_attribute)
void do_paint_brush(const Scene &scene, const Depsgraph &depsgraph, PaintModeSettings &paint_mode_settings, const Sculpt &sd, Object &ob, const IndexMask &node_mask, const IndexMask &texnode_mask)
float relative_to_detail_size(const float relative_detail, const float brush_radius, const float pixel_radius, const float pixel_size)
float constant_to_detail_size(const float constant_detail, const Object &ob)
float brush_to_detail_size(const float brush_percent, const float brush_radius)
constexpr float EDGE_LENGTH_MIN_FACTOR
bool stroke_is_dyntopo(const Object &object, const Brush &brush)
int vert_face_set_get(const GroupedSpan< int > vert_to_face_map, const Span< int > face_sets, const int vert)
int find_next_available_id(Object &object)
bool vert_has_unique_face_set(const GroupedSpan< int > vert_to_face_map, const Span< int > face_sets, int vert)
bool vert_has_face_set(const GroupedSpan< int > vert_to_face_map, const Span< int > face_sets, const int vert, const int face_set)
bke::SpanAttributeWriter< int > ensure_face_sets_mesh(Mesh &mesh)
int active_face_set_get(const Object &object)
static bool sculpt_check_unique_face_set_for_edge_in_base_mesh(const GroupedSpan< int > vert_to_face_map, const Span< int > face_sets, const Span< int > corner_verts, const OffsetIndices< int > faces, int v1, int v2)
bool vert_all_faces_visible_get(const Span< bool > hide_poly, const GroupedSpan< int > vert_to_face_map, const int vert)
void ensure_cache(Object &object)
static SculptTopologyIslandCache calc_topology_islands_grids(const Object &object)
static SculptTopologyIslandCache vert_disjoint_set_to_islands(const AtomicDisjointSet &vert_sets, const int verts_num)
static SculptTopologyIslandCache calc_topology_islands_mesh(const Mesh &mesh)
static SculptTopologyIslandCache calculate_cache(const Object &object)
static SculptTopologyIslandCache calc_topology_islands_bmesh(const Object &object)
int vert_id_get(const SculptSession &ss, const int vert)
void do_pose_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &ob, const IndexMask &node_mask)
void pose_brush_init(const Depsgraph &depsgraph, Object &ob, SculptSession &ss, const Brush &brush)
void push_nodes(const Depsgraph &depsgraph, Object &object, const IndexMask &node_mask, const Type type)
static void restore_from_undo_step(const Depsgraph &depsgraph, const Sculpt &sd, Object &object)
static void restore_color_from_undo_step(Object &object)
static void restore_face_set_from_undo_step(Object &object)
void restore_position_from_undo_step(const Depsgraph &depsgraph, Object &object)
static void restore_mask_from_undo_step(Object &object)
BMLogEntry * get_bmesh_log_entry()
void fill_factor_from_hide_and_mask(Span< bool > hide_vert, Span< float > mask, Span< int > verts, MutableSpan< float > r_factors)
static void calc_local_from_screen(const ViewContext &vc, const float center[3], const float screen_dir[2], float r_local_dir[3])
std::optional< Span< float > > orig_mask_data_lookup_grids(const Object &object, const bke::pbvh::GridsNode &node)
void do_clay_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
int paint_stroke_exec(bContext *C, wmOperator *op, PaintStroke *stroke)
void do_bmesh_topology_rake_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask, const float input_strength)
void do_blob_brush(const Depsgraph &depsgraph, const Scene &scene, const Sculpt &sd, Object &object, const IndexMask &node_mask)
void do_snake_hook_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
void update_shape_keys(Object &object, const Mesh &mesh, const KeyBlock &active_key, Span< int > verts, Span< float3 > translations, Span< float3 > positions_orig)
static bool brush_needs_rake_rotation(const Brush &brush)
MutableSpan< float3 > gather_grids_positions(const SubdivCCG &subdiv_ccg, const Span< int > grids, Vector< float3 > &positions)
static float brush_dynamic_size_get(const Brush &brush, const StrokeCache &cache, float initial_size)
static void fake_neighbor_search_mesh(const SculptSession &ss, const Span< float3 > vert_positions, const Span< bool > hide_vert, const float3 &location, const float max_distance_sq, const int island_id, const bke::pbvh::MeshNode &node, NearestVertData &nvtd)
bool node_in_sphere(const bke::pbvh::Node &node, const float3 &location, const float radius_sq, const bool original)
void scatter_data_bmesh(Span< T > node_data, const Set< BMVert *, 0 > &verts, MutableSpan< T > dst)
bool node_in_cylinder(const DistRayAABB_Precalc &ray_dist_precalc, const bke::pbvh::Node &node, const float radius_sq, const bool original)
static int sculpt_brush_needs_normal(const SculptSession &ss, const Sculpt &sd, const Brush &brush)
void calc_factors_common_from_orig_data_grids(const Depsgraph &depsgraph, const Brush &brush, const Object &object, Span< float3 > positions, Span< float3 > normals, const bke::pbvh::GridsNode &node, Vector< float > &r_factors, Vector< float > &r_distances)
static void do_radial_symmetry(const Depsgraph &depsgraph, const Scene &scene, const Sculpt &sd, Object &ob, const Brush &brush, UnifiedPaintSettings &ups, PaintModeSettings &paint_mode_settings, const BrushActionFunc action, const ePaintSymmetryFlags symm, const int axis, const float)
static int brush_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
void gather_bmesh_positions(const Set< BMVert *, 0 > &verts, MutableSpan< float3 > positions)
void do_nudge_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
void do_displacement_eraser_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
void do_relax_face_sets_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
void do_displacement_smear_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &ob, const IndexMask &node_mask)
static void stroke_update_step(bContext *C, wmOperator *, PaintStroke *stroke, PointerRNA *itemptr)
void calc_brush_strength_factors(const StrokeCache &cache, const Brush &brush, Span< float > distances, MutableSpan< float > factors)
static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent *event)
std::optional< Span< int > > orig_face_set_data_lookup_mesh(const Object &object, const bke::pbvh::MeshNode &node)
void gather_data_grids(const SubdivCCG &subdiv_ccg, Span< T > src, Span< int > grids, MutableSpan< T > node_data)
static void redo_empty_ui(bContext *, wmOperator *)
void calc_vert_neighbors_interior(OffsetIndices< int > faces, Span< int > corner_verts, GroupedSpan< int > vert_to_face, BitSpan boundary_verts, Span< bool > hide_poly, Span< int > verts, MutableSpan< Vector< int > > result)
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 do_rotate_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
void filter_below_plane_factors(Span< float3 > vert_positions, Span< int > verts, const float4 &plane, MutableSpan< float > factors)
void apply_hardness_to_distances(float radius, float hardness, MutableSpan< float > distances)
void calc_factors_common_grids(const Depsgraph &depsgraph, const Brush &brush, const Object &object, Span< float3 > positions, const bke::pbvh::GridsNode &node, Vector< float > &r_factors, Vector< float > &r_distances)
void gather_bmesh_normals(const Set< BMVert *, 0 > &verts, MutableSpan< float3 > normals)
static void pose_fake_neighbors_free(SculptSession &ss)
bool node_fully_masked_or_hidden(const bke::pbvh::Node &node)
void calc_factors_common_mesh_indexed(const Depsgraph &depsgraph, const Brush &brush, const Object &object, const MeshAttributeData &attribute_data, Span< float3 > vert_positions, Span< float3 > vert_normals, const bke::pbvh::MeshNode &node, Vector< float > &r_factors, Vector< float > &r_distances)
void filter_distances_with_radius(float radius, Span< float > distances, MutableSpan< float > factors)
void do_multiplane_scrape_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
static void copy_indices(const Span< float3 > src, const Span< int > indices, MutableSpan< float3 > dst)
void do_surface_smooth_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
std::optional< OrigPositionData > orig_position_data_lookup_grids(const Object &object, const bke::pbvh::GridsNode &node)
static void cache_paint_invariants_update(StrokeCache &cache, const Brush &brush)
OffsetIndices< int > create_node_vert_offsets_bmesh(const Span< bke::pbvh::BMeshNode > nodes, const IndexMask &nodes_mask, Array< int > &node_data)
void filter_region_clip_factors(const SculptSession &ss, Span< float3 > vert_positions, Span< int > verts, MutableSpan< float > factors)
void gather_data_bmesh(Span< T > src, const Set< BMVert *, 0 > &verts, MutableSpan< T > node_data)
void flush_update_done(const bContext *C, Object &ob, UpdateType update_type)
static void fake_neighbor_init(Object &object, const float max_dist)
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 calc_brush_distances(const SculptSession &ss, Span< float3 > vert_positions, Span< int > vert_indices, eBrushFalloffShape falloff_shape, MutableSpan< float > r_distances)
void orig_position_data_gather_bmesh(const BMLog &bm_log, const Set< BMVert *, 0 > &verts, MutableSpan< float3 > positions, MutableSpan< float3 > normals)
static float area_normal_calc_weight(const float distance, const float radius_inv)
void scale_translations(MutableSpan< float3 > translations, Span< float > factors)
void paint_stroke_cancel(bContext *C, wmOperator *op, PaintStroke *stroke)
void flush_update_step(bContext *C, UpdateType update_type)
static IndexMask pbvh_gather_generic(Object &ob, const Brush &brush, bool use_original, float radius_scale, IndexMaskMemory &memory)
void do_elastic_deform_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
void do_draw_sharp_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
float clay_thumb_get_stabilized_pressure(const StrokeCache &cache)
void do_grab_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
static bool brush_type_needs_original(const char sculpt_brush_type)
bool paint_supports_dynamic_size(const Brush &br, PaintMode mode)
static void sculpt_update_cache_invariants(bContext *C, Sculpt &sd, SculptSession &ss, wmOperator *op, const float mval[2])
static void sculpt_init_mirror_clipping(const Object &ob, const SculptSession &ss)
static IndexMask pbvh_gather_texpaint(Object &ob, const Brush &brush, const bool use_original, const float radius_scale, IndexMaskMemory &memory)
static void brush_exit_tex(Sculpt &sd)
void do_topology_relax_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
static bool need_delta_from_anchored_origin(const Brush &brush)
static bool sculpt_needs_connectivity_info(const Sculpt &sd, const Brush &brush, const Object &object, int stroke_mode)
bool report_if_shape_key_is_locked(const Object &ob, ReportList *reports)
static void calc_area_normal_and_center_node_bmesh(const Object &object, const Brush &brush, const bool use_area_nos, const bool use_area_cos, const bool has_bm_orco, const bke::pbvh::BMeshNode &node, SampleLocalData &tls, AreaNormalCenterData &anctd)
void filter_verts_outside_symmetry_area(Span< float3 > positions, const float3 &pivot, ePaintSymmetryFlags symm, MutableSpan< float > factors)
static int sculpt_brush_stroke_exec(bContext *C, wmOperator *op)
static void accumulate_area_center(const float3 &test_location, const float3 &position, const float distance, const float radius_inv, const int flip_index, AreaNormalCenterData &anctd)
static void rake_data_update(SculptRakeData *srd, const float co[3])
void calc_translations_to_plane(Span< float3 > vert_positions, Span< int > verts, const float4 &plane, MutableSpan< float3 > translations)
void scale_factors(MutableSpan< float > factors, float strength)
void calc_factors_common_from_orig_data_mesh(const Depsgraph &depsgraph, const Brush &brush, const Object &object, const MeshAttributeData &attribute_data, Span< float3 > positions, Span< float3 > normals, const bke::pbvh::MeshNode &node, Vector< float > &r_factors, Vector< float > &r_distances)
static float3 calc_sculpt_normal(const Depsgraph &depsgraph, const Sculpt &sd, Object &ob, const IndexMask &node_mask)
void translations_from_new_positions(Span< float3 > new_positions, Span< int > verts, Span< float3 > old_positions, MutableSpan< float3 > translations)
static bool need_delta_for_tip_orientation(const Brush &brush)
void clip_and_lock_translations(const Sculpt &sd, const SculptSession &ss, Span< float3 > positions, Span< int > verts, MutableSpan< float3 > translations)
static void sculpt_brush_stroke_cancel(bContext *C, wmOperator *op)
static void do_brush_action(const Depsgraph &depsgraph, const Scene &scene, const Sculpt &sd, Object &ob, const Brush &brush, UnifiedPaintSettings &ups, PaintModeSettings &paint_mode_settings)
static void push_undo_nodes(const Depsgraph &depsgraph, Object &ob, const Brush &brush, const IndexMask &node_mask)
static void stroke_done(const bContext *C, PaintStroke *)
std::optional< Span< float4 > > orig_color_data_lookup_mesh(const Object &object, const bke::pbvh::MeshNode &node)
void scatter_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
void do_draw_face_sets_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
void SCULPT_OT_brush_stroke(wmOperatorType *ot)
void project_translations(MutableSpan< float3 > translations, const float3 &plane)
static void dynamic_topology_update(const Depsgraph &depsgraph, const Scene &, const Sculpt &sd, Object &ob, const Brush &brush, UnifiedPaintSettings &, PaintModeSettings &)
void calc_brush_plane(const Depsgraph &depsgraph, const Brush &brush, Object &ob, const IndexMask &node_mask, float3 &r_area_no, float3 &r_area_co)
static void calc_brush_local_mat(const float rotation, const Object &ob, float local_mat[4][4], float local_mat_inv[4][4])
void do_draw_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
std::optional< float3 > calc_area_normal(const Depsgraph &depsgraph, const Brush &brush, const Object &ob, const IndexMask &node_mask)
void filter_plane_trim_limit_factors(const Brush &brush, const StrokeCache &cache, Span< float3 > translations, MutableSpan< float > factors)
void apply_translations(Span< float3 > translations, Span< int > verts, MutableSpan< float3 > positions)
void do_smooth_mask_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask, float brush_strength)
void calc_factors_common_mesh(const Depsgraph &depsgraph, const Brush &brush, const Object &object, const MeshAttributeData &attribute_data, Span< float3 > positions, Span< float3 > vert_normals, const bke::pbvh::MeshNode &node, Vector< float > &r_factors, Vector< float > &r_distances)
Span< BMVert * > vert_neighbors_get_bmesh(BMVert &vert, Vector< BMVert *, 64 > &r_neighbors)
ViewContext * paint_stroke_view_context(PaintStroke *stroke)
void do_draw_vector_displacement_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
void do_layer_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
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)
static void fake_neighbor_search_bmesh(const SculptSession &ss, const float3 &location, const float max_distance_sq, const int island_id, const bke::pbvh::BMeshNode &node, NearestVertData &nvtd)
static void sculpt_fix_noise_tear(const Sculpt &sd, Object &ob)
static AreaNormalCenterData calc_area_normal_and_center_reduce(const AreaNormalCenterData &a, const AreaNormalCenterData &b)
void filter_above_plane_factors(Span< float3 > vert_positions, Span< int > verts, const float4 &plane, MutableSpan< float > factors)
void calc_area_center(const Depsgraph &depsgraph, const Brush &brush, const Object &ob, const IndexMask &node_mask, float r_area_co[3])
void do_fill_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
static void sculpt_update_cache_variants(bContext *C, Sculpt &sd, Object &ob, PointerRNA *ptr)
void calc_brush_cube_distances(const Brush &brush, const float4x4 &mat, Span< float3 > positions, Span< int > verts, MutableSpan< float > r_distances, MutableSpan< float > factors)
int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event, PaintStroke **stroke_p)
void do_topology_slide_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
void apply_crazyspace_to_translations(Span< float3x3 > deform_imats, Span< int > verts, MutableSpan< float3 > translations)
void do_thumb_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
static void brush_delta_update(const Depsgraph &depsgraph, UnifiedPaintSettings &ups, const Object &ob, const Brush &brush)
std::optional< BMVert * > nearest_vert_calc_bmesh(const bke::pbvh::Tree &pbvh, const float3 &location, const float max_distance, const bool use_original)
void do_smooth_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask, const float brush_strength)
static void fake_neighbor_search(const Depsgraph &depsgraph, const Object &ob, const float max_distance_sq, MutableSpan< int > fake_neighbors)
void calc_front_face(const float3 &view_normal, Span< float3 > normals, MutableSpan< float > factors)
static void calc_area_normal_and_center_node_grids(const Object &object, const Brush &brush, const bool use_area_nos, const bool use_area_cos, const bke::pbvh::GridsNode &node, SampleLocalData &tls, AreaNormalCenterData &anctd)
static void do_symmetrical_brush_actions(const Depsgraph &depsgraph, const Scene &scene, const Sculpt &sd, Object &ob, const BrushActionFunc action, UnifiedPaintSettings &ups, PaintModeSettings &paint_mode_settings)
void(*)(const Depsgraph &depsgraph, const Scene &scene, const Sculpt &sd, Object &ob, const Brush &brush, UnifiedPaintSettings &ups, PaintModeSettings &paint_mode_settings) BrushActionFunc
float paint_stroke_distance_get(PaintStroke *stroke)
static bool stroke_test_start(bContext *C, wmOperator *op, const float mval[2])
static float3 area_center_calc_weighted(const float3 &test_location, const float distance, const float radius_inv, const float3 &co)
static void fake_neighbor_search_grids(const SculptSession &ss, const CCGKey &key, const Span< float3 > positions, const BitGroupVector<> &grid_hidden, const float3 &location, const float max_distance_sq, const int island_id, const bke::pbvh::GridsNode &node, NearestVertData &nvtd)
static void update_sculpt_normal(const Depsgraph &depsgraph, const Sculpt &sd, Object &ob, const IndexMask &node_mask)
float sculpt_calc_radius(const ViewContext &vc, const Brush &brush, const Scene &scene, const float3 location)
std::optional< Span< float > > orig_mask_data_lookup_mesh(const Object &object, const bke::pbvh::MeshNode &node)
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)
void do_flatten_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
Span< BMVert * > vert_neighbors_get_interior_bmesh(BMVert &vert, Vector< BMVert *, 64 > &r_neighbors)
static IndexMask pbvh_gather_cursor_update(Object &ob, bool use_original, IndexMaskMemory &memory)
static bool brush_uses_topology_rake(const SculptSession &ss, const Brush &brush)
OffsetIndices< int > create_node_vert_offsets(const Span< bke::pbvh::MeshNode > nodes, const IndexMask &nodes_mask, Array< int > &node_data)
static void calc_area_normal_and_center_node_mesh(const Object &object, const Span< float3 > vert_positions, const Span< float3 > vert_normals, const Span< bool > hide_vert, const Brush &brush, const bool use_area_nos, const bool use_area_cos, const bke::pbvh::MeshNode &node, SampleLocalData &tls, AreaNormalCenterData &anctd)
void gather_grids_normals(const SubdivCCG &subdiv_ccg, Span< int > grids, MutableSpan< float3 > normals)
void do_inflate_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
void calc_area_normal_and_center(const Depsgraph &depsgraph, const Brush &brush, const Object &ob, const IndexMask &node_mask, float r_area_no[3], float r_area_co[3])
void paint_stroke_free(bContext *C, wmOperator *op, PaintStroke *stroke)
PaintStroke * paint_stroke_new(bContext *C, wmOperator *op, StrokeGetLocation get_location, StrokeTestStart test_start, StrokeUpdateStep update_step, StrokeRedraw redraw, StrokeDone done, int event_type)
void translations_from_offset_and_factors(const float3 &offset, Span< float > factors, MutableSpan< float3 > r_translations)
static float area_normal_and_center_get_normal_radius(const SculptSession &ss, const Brush &brush)
void do_clay_strips_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
static void do_tiled(const Depsgraph &depsgraph, const Scene &scene, const Sculpt &sd, Object &ob, const Brush &brush, UnifiedPaintSettings &ups, PaintModeSettings &paint_mode_settings, const BrushActionFunc action)
std::optional< OrigPositionData > orig_position_data_lookup_mesh(const Object &object, const bke::pbvh::MeshNode &node)
std::optional< Span< int > > orig_face_set_data_lookup_grids(const Object &object, const bke::pbvh::GridsNode &node)
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 calc_brush_texture_factors(const SculptSession &ss, const Brush &brush, Span< float3 > vert_positions, Span< int > vert_indices, MutableSpan< float > factors)
void fill_factor_from_hide(Span< bool > hide_vert, Span< int > verts, MutableSpan< float > r_factors)
void scatter_data_grids(const SubdivCCG &subdiv_ccg, Span< T > node_data, Span< int > grids, MutableSpan< T > dst)
void do_crease_brush(const Depsgraph &depsgraph, const Scene &scene, const Sculpt &sd, Object &object, const IndexMask &node_mask)
void do_pinch_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
void do_gravity_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
void calc_factors_common_bmesh(const Depsgraph &depsgraph, const Brush &brush, const Object &object, Span< float3 > positions, bke::pbvh::BMeshNode &node, Vector< float > &r_factors, Vector< float > &r_distances)
void do_scrape_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
void do_mask_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
void do_enhance_details_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
static void accumulate_area_normal(const float3 &normal, const float distance, const float radius_inv, const int flip_index, AreaNormalCenterData &anctd)
bool paint_brush_tool_poll(bContext *C)
void calc_factors_common_from_orig_data_bmesh(const Depsgraph &depsgraph, const Brush &brush, const Object &object, Span< float3 > positions, Span< float3 > normals, bke::pbvh::BMeshNode &node, Vector< float > &r_factors, Vector< float > &r_distances)
Span< float3 > vert_positions_for_grab_active_get(const Depsgraph &depsgraph, const Object &object)
static float area_normal_and_center_get_position_radius(const SculptSession &ss, const Brush &brush)
void calc_brush_distances_squared(const SculptSession &ss, Span< float3 > vert_positions, Span< int > vert_indices, eBrushFalloffShape falloff_shape, MutableSpan< float > r_distances)
void do_clay_thumb_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
QuaternionBase< float > Quaternion
T length_squared(const VecBase< T, Size > &a)
VecBase< T, 3 > normal_tri(const VecBase< T, 3 > &v1, const VecBase< T, 3 > &v2, const VecBase< T, 3 > &v3)
T clamp(const T &a, const T &min, const T &max)
QuaternionBase< T > to_quaternion(const AxisAngleBase< T, AngleT > &axis_angle)
T safe_divide(const T &a, const T &b)
T distance(const T &a, const T &b)
T dot(const QuaternionBase< T > &a, const QuaternionBase< T > &b)
CartesianBasis invert(const CartesianBasis &basis)
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)
void isolate_task(const Function &function)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Value parallel_reduce(IndexRange range, int64_t grain_size, const Value &identity, const Function &function, const Reduction &reduction)
VecBase< float, 3 > float3
bool paint_convert_bb_to_rect(rcti *rect, const float bb_min[3], const float bb_max[3], const ARegion ®ion, const RegionView3D &rv3d, const Object &ob)
float paint_calc_object_space_radius(const ViewContext &vc, const blender::float3 ¢er, float pixel_radius)
bool paint_get_tex_pixel(const MTex *mtex, float u, float v, ImagePool *pool, int thread, float *r_intensity, float r_rgba[4])
void paint_stroke_operator_properties(wmOperatorType *ot)
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
float RNA_float_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
static void stroke_undo_end(const bContext *C, Brush *brush)
bool SCULPT_stroke_is_first_brush_step_of_symmetry_pass(const blender::ed::sculpt_paint::StrokeCache &cache)
bool SCULPT_get_redraw_rect(const ARegion ®ion, const RegionView3D &rv3d, const Object &ob, rcti &rect)
bool SCULPT_brush_cursor_poll(bContext *C)
ePaintSymmetryFlags SCULPT_mesh_symmetry_xyz_get(const Object &object)
void SCULPT_calc_vertex_displacement(const SculptSession &ss, const Brush &brush, float rgba[3], float r_offset[3])
static void restore_from_undo_step_if_necessary(const Depsgraph &depsgraph, const Sculpt &sd, Object &ob)
bool SCULPT_cursor_geometry_info_update(bContext *C, SculptCursorGeometryInfo *out, const float mval[2], bool use_sampled_normal)
bool SCULPT_stroke_get_location(bContext *C, float out[3], const float mval[2], bool force_original)
static float calc_symmetry_feather(const Sculpt &sd, const blender::ed::sculpt_paint::StrokeCache &cache)
static void sculpt_raycast_cb(blender::bke::pbvh::Node &node, SculptRaycastData &srd, float *tmin)
static void brush_stroke_init(bContext *C)
const float * SCULPT_brush_frontface_normal_from_falloff_shape(const SculptSession &ss, char falloff_shape)
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)
bool SCULPT_brush_type_needs_all_pbvh_nodes(const Brush &brush)
void SCULPT_vertex_random_access_ensure(Object &object)
static void brush_init_tex(const Sculpt &sd, SculptSession &ss)
static bool sculpt_needs_pbvh_pixels(PaintModeSettings &paint_mode_settings, const Brush &brush, Object &ob)
static bool over_mesh(bContext *C, wmOperator *, const float mval[2])
void SCULPT_stroke_modifiers_check(const bContext *C, Object &ob, const Brush &brush)
void sculpt_apply_texture(const SculptSession &ss, const Brush &brush, const float brush_point[3], const int thread_id, float *r_value, float r_rgba[4])
static void sculpt_pbvh_update_pixels(const Depsgraph &depsgraph, PaintModeSettings &paint_mode_settings, Object &ob)
bool SCULPT_vertex_is_occluded(const Depsgraph &depsgraph, const Object &object, const float3 &position, bool original)
static const char * sculpt_brush_type_name(const Sculpt &sd)
float SCULPT_raycast_init(ViewContext *vc, const float mval[2], float ray_start[3], float ray_end[3], float ray_normal[3], bool original)
void SCULPT_cache_calc_brushdata_symm(blender::ed::sculpt_paint::StrokeCache &cache, const ePaintSymmetryFlags symm, const char axis, const float angle)
bool SCULPT_stroke_get_location_ex(bContext *C, float out[3], const float mval[2], bool force_original, bool check_closest, bool limit_closest_radius)
static void sculpt_find_nearest_to_ray_cb(blender::bke::pbvh::Node &node, SculptFindNearestToRayData &srd, float *tmin)
bool SCULPT_mode_poll_view3d(bContext *C)
float3 SCULPT_flip_v3_by_symm_area(const float3 &vector, const ePaintSymmetryFlags symm, const ePaintSymmetryAreas symmarea, const float3 &pivot)
bool SCULPT_mode_poll(bContext *C)
static void stroke_undo_begin(const bContext *C, wmOperator *op)
static bool is_brush_related_tool(bContext *C)
bool SCULPT_stroke_is_main_symmetry_pass(const blender::ed::sculpt_paint::StrokeCache &cache)
#define SCULPT_TILT_SENSITIVITY
static void extend_redraw_rect_previous(Object &ob, rcti &rect)
static void flip_qt(float quat[4], const ePaintSymmetryFlags symm)
static void flip_qt_qt(float out[4], const float in[4], const ePaintSymmetryFlags symm)
int SCULPT_vertex_count_get(const Object &object)
void sculpt_project_v3_normal_align(const SculptSession &ss, const float normal_weight, float grab_delta[3])
static void update_brush_local_mat(const Sculpt &sd, Object &ob)
void SCULPT_cube_tip_init(const Sculpt &, const Object &ob, const Brush &brush, float mat[4][4])
void SCULPT_fake_neighbors_free(Object &ob)
bool SCULPT_is_vertex_inside_brush_radius_symm(const float vertex[3], const float br_co[3], float radius, char symm)
bool SCULPT_check_vertex_pivot_symmetry(const float vco[3], const float pco[3], const char symm)
bool SCULPT_handles_colors_report(const Object &object, ReportList *reports)
void SCULPT_tilt_apply_to_normal(float r_normal[3], blender::ed::sculpt_paint::StrokeCache *cache, const float tilt_strength)
bool SCULPT_poll(bContext *C)
ePaintSymmetryAreas SCULPT_get_vertex_symm_area(const float co[3])
static float calc_overlap(const blender::ed::sculpt_paint::StrokeCache &cache, const ePaintSymmetryFlags symm, const char axis, const float angle)
float SCULPT_brush_plane_offset_get(const Sculpt &sd, const SculptSession &ss)
static float brush_strength(const Sculpt &sd, const blender::ed::sculpt_paint::StrokeCache &cache, const float feather, const UnifiedPaintSettings &ups, const PaintModeSettings &)
void SCULPT_tilt_effective_normal_get(const SculptSession &ss, const Brush &brush, float r_no[3])
void SCULPT_flip_quat_by_symm_area(float quat[4], const ePaintSymmetryFlags symm, const ePaintSymmetryAreas symmarea, const float pivot[3])
bool SCULPT_stroke_is_first_brush_step(const blender::ed::sculpt_paint::StrokeCache &cache)
static float calc_radial_symmetry_feather(const Sculpt &sd, const blender::ed::sculpt_paint::StrokeCache &cache, const ePaintSymmetryFlags symm, const char axis)
#define PIXEL_INPUT_THRESHHOLD
void SCULPT_tag_update_overlays(bContext *C)
#define SCULPT_RAKE_BRUSH_FACTOR
#define FAKE_NEIGHBOR_NONE
bool SCULPT_brush_type_is_mask(int tool)
BLI_INLINE bool SCULPT_brush_type_is_attribute_only(int tool)
bool SCULPT_brush_type_is_paint(int tool)
bool SCULPT_use_image_paint_brush(PaintModeSettings &settings, Object &ob)
bool SCULPT_paint_image_canvas_get(PaintModeSettings &paint_mode_settings, Object &ob, Image **r_image, ImageUser **r_image_user) ATTR_NONNULL()
Get the image canvas for painting on the given object.
float topology_rake_factor
int snake_hook_deform_type
float normal_radius_factor
struct CurveMapping * curve
float texture_sample_bias
float tilt_strength_factor
struct Object * mirror_ob
ObjectRuntimeHandle * runtime
struct SculptSession * sculpt
blender::Array< int > fake_neighbor_index
float current_max_distance
Span< blender::int3 > corner_tris
const SubdivCCG * subdiv_ccg
blender::VArraySpan< bool > hide_poly
blender::OffsetIndices< int > faces
Span< float3 > vert_positions
blender::float3 follow_co
blender::OffsetIndices< int > faces
int active_face_grid_index
blender::VArraySpan< bool > hide_poly
const SubdivCCG * subdiv_ccg
IsectRayPrecalc isect_precalc
Span< blender::float3 > vert_positions
Span< blender::int3 > corner_tris
blender::ed::sculpt_paint::StrokeCache * cache
std::optional< int > active_grid_index
void clear_active_vert(bool persist_last_active)
blender::ed::sculpt_paint::filter::Cache * filter_cache
std::optional< int > active_face_index
KeyBlock * shapekey_active
blender::float3 cursor_normal
SculptVertexInfo vertex_info
blender::float3 cursor_view_normal
ActiveVert active_vert() const
blender::float3 cursor_location
blender::float3 active_vert_position(const Depsgraph &depsgraph, const Object &object) const
std::unique_ptr< SculptTopologyIslandCache > topology_island_cache
blender::Array< blender::float3x3, 0 > deform_imats
struct SculptSession::@48 multires
MultiresModifierData * modifier
blender::float3 cursor_sampled_normal
SculptFakeNeighbors fake_neighbors
bool deform_modifiers_active
void set_active_vert(ActiveVert vert)
blender::Array< uint8_t > vert_island_ids
blender::BitVector boundary
struct Object * gravity_object
blender::Vector< SubdivCCGCoord, 256 > coords
blender::Array< blender::float3 > normals
blender::BitGroupVector grid_hidden
blender::Array< float > masks
blender::Array< blender::float3 > positions
struct bNodeTree * nodetree
float average_stroke_accum[3]
float anchored_initial_mouse[2]
float initial_pixel_radius
int average_stroke_counter
bNodeTreeRuntimeHandle * runtime
const c_style_mat & ptr() const
std::array< float3, 2 > area_cos
std::array< int, 2 > count_no
std::array< int, 2 > count_co
std::array< float3, 2 > area_nos
Vector< float3 > translations
VArraySpan< bool > hide_vert
static NearestVertData join(const NearestVertData &a, const NearestVertData &b)
Vector< float3 > positions
Vector< float > distances
struct blender::ed::sculpt_paint::StrokeCache::@481 clay_thumb_brush
std::optional< math::Quaternion > rake_rotation
struct blender::ed::sculpt_paint::StrokeCache::@480 paint_brush
float3 initial_normal_symm
Array< float > layer_displacement_factor
struct blender::ed::sculpt_paint::StrokeCache::@478 mirror_modifier_clip
float3 gravity_direction_symm
float4x4 brush_local_mat_inv
float3 sculpt_normal_symm
std::unique_ptr< auto_mask::Cache > automasking
float dyntopo_pixel_radius
float3 initial_location_symm
float4x4 symm_rot_mat_inv
std::optional< math::Quaternion > rake_rotation_symm
float3 last_location_symm
char saved_mask_brush_tool
ePaintSymmetryFlags mirror_symmetry_pass
Array< float4 > mix_colors
Array< float3 > surface_smooth_laplacian_disp
std::unique_ptr< cloth::SimulationData > cloth_sim
std::array< float, 10 > pressure_stabilizer
float3 orig_grab_location
Brush * saved_active_brush
const AngleT & angle() const
const vec3_type & axis() const
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
int(* modal)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
void(* ui)(bContext *C, wmOperator *op)
void(* cancel)(bContext *C, wmOperator *op)
struct ReportList * reports
struct wmOperatorType * type
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
bScreen * WM_window_get_active_screen(const wmWindow *win)