55#define STACK_FIXED_DEPTH 100
60 return {
float3(std::numeric_limits<float>::max()),
float3(std::numeric_limits<float>::lowest())};
73 const int *split = std::partition(faces.begin(), faces.end(), [&](
const int face) {
74 return face_centers[face][axis] >= middle;
76 return split - faces.begin();
81 const int first = material_indices[faces.first()];
82 const int *split = std::partition(
83 faces.begin(), faces.end(), [&](
const int face) { return material_indices[face] == first; });
84 return split - faces.begin();
92#ifdef DEBUG_BUILD_TIME
98 for (const int i : range) {
99 MeshNode &node = nodes[i];
102 int corners_count = 0;
103 for (const int face_index : node.face_indices_) {
104 const IndexRange face = faces[face_index];
105 verts.add_multiple(corner_verts.slice(face));
106 corners_count += face.size();
108 nodes[i].corners_num_ = corners_count;
110 new (&verts_per_node[i]) Array<int>(verts.size());
111 std::copy(verts.begin(), verts.end(), verts_per_node[i].begin());
112 std::sort(verts_per_node[i].begin(), verts_per_node[i].end());
119 for (
const int i : nodes.index_range()) {
120 MeshNode &node = nodes[i];
123 shared_verts.
clear();
124 for (
const int vert : verts_per_node[i]) {
125 if (vert_used[vert]) {
126 shared_verts.
append(vert);
129 vert_used[vert].set();
130 owned_verts.append(vert);
133 node.unique_verts_num_ = owned_verts.size();
134 node.vert_indices_.reserve(owned_verts.size() + shared_verts.
size());
135 node.vert_indices_.add_multiple(owned_verts);
136 node.vert_indices_.add_multiple(shared_verts);
145 const int first = material_indices[faces.first()];
147 faces.begin(), faces.end(), [&](
const int face) { return material_indices[face] != first; });
152 const int leaf_limit,
153 const int node_index,
162 if (below_leaf_limit) {
166 node.face_indices_ =
faces;
172 nodes[node_index].children_offset_ = nodes.size();
173 nodes.resize(nodes.size() + 2);
176 if (!below_leaf_limit) {
178 if (bounds_precalc) {
182 bounds = threading::parallel_reduce(
187 for (
const int face : faces.slice(range)) {
208 nodes[node_index].children_offset_,
216 nodes[node_index].children_offset_ + 1,
228 for (
const int vert : face_verts.
slice(1, face_verts.
size() - 1)) {
236#ifdef DEBUG_BUILD_TIME
239 Tree pbvh(Type::Mesh);
240 const Span<float3> vert_positions = mesh.vert_positions();
242 const Span<int> corner_verts = mesh.corner_verts();
243 if (faces.is_empty()) {
248 static_assert(leaf_limit < std::numeric_limits<MeshNode::LocalVertMapIndexT>::max());
257 for (
const int face :
range) {
259 corner_verts.
slice(faces[face]));
260 face_centers[face] =
bounds.center();
261 current = bounds::merge(current,
bounds);
268 const VArraySpan hide_vert = *attributes.lookup<
bool>(
".hide_vert", AttrDomain::Point);
269 const VArraySpan material_index = *attributes.lookup<
int>(
"material_index", AttrDomain::Face);
272 array_utils::fill_index_range<int>(pbvh.prim_indices_);
277#ifdef DEBUG_BUILD_TIME
281 material_index,
leaf_limit, 0,
bounds, face_centers, 0, pbvh.prim_indices_, nodes);
292 threading::parallel_for(nodes.index_range(), 8, [&](
const IndexRange range) {
293 for (const int i : range) {
294 node_update_visibility_mesh(hide_vert, nodes[i]);
305 const int leaf_limit,
306 const int node_index,
315 if (below_leaf_limit) {
319 node.prim_indices_ =
faces;
325 nodes[node_index].children_offset_ = nodes.size();
326 nodes.resize(nodes.size() + 2);
329 if (!below_leaf_limit) {
331 if (bounds_precalc) {
335 bounds = threading::parallel_reduce(
340 for (
const int face : faces.slice(range)) {
361 nodes[node_index].children_offset_,
369 nodes[node_index].children_offset_ + 1,
383 for (
const float3 &position : positions.slice(ccg::face_range(faces, key, face))) {
391#ifdef DEBUG_BUILD_TIME
394 Tree pbvh(Type::Grids);
396 if (faces.is_empty()) {
402 if (positions.is_empty()) {
415 for (
const int face :
range) {
417 face_centers[face] =
bounds.center();
418 current = bounds::merge(current,
bounds);
425 const VArraySpan material_index = *attributes.lookup<
int>(
"material_index", AttrDomain::Face);
428 array_utils::fill_index_range<int>(face_indices);
433#ifdef DEBUG_BUILD_TIME
437 material_index,
leaf_limit, 0,
bounds, face_centers, 0, face_indices, nodes);
444 for (
const int i : nodes.index_range()) {
445 for (
const int face : nodes[i].prim_indices_) {
446 for (
const int corner : faces[face]) {
447 pbvh.prim_indices_[offset] = corner;
456 threading::parallel_for(nodes.index_range(), 16, [&](
const IndexRange range) {
457 for (const int i : range) {
458 node_grids_num[i] = offset_indices::sum_group_sizes(faces, nodes[i].prim_indices_);
461 const OffsetIndices<int> node_grid_offsets = offset_indices::accumulate_counts_to_offsets(
464 threading::parallel_for(nodes.index_range(), 512, [&](
const IndexRange range) {
465 for (const int i : range) {
466 nodes[i].prim_indices_ = pbvh.prim_indices_.as_span().slice(node_grid_offsets[i]);
470 pbvh.tag_positions_changed(nodes.index_range());
472 update_bounds_grids(key, positions, pbvh);
473 store_bounds_orig(pbvh);
477 threading::parallel_for(nodes.index_range(), 8, [&](
const IndexRange range) {
478 for (const int i : range) {
479 node_update_visibility_grids(grid_hidden, nodes[i]);
484 update_mask_grids(subdiv_ccg, nodes.index_range(), pbvh);
489Tree::Tree(
const Type type) : type_(type)
506 return std::visit([](
const auto &nodes) {
return nodes.size(); }, this->
nodes_);
511 return std::get<Vector<MeshNode>>(this->
nodes_);
515 return std::get<Vector<GridsNode>>(this->
nodes_);
519 return std::get<Vector<BMeshNode>>(this->
nodes_);
523 return std::get<Vector<MeshNode>>(this->
nodes_);
527 return std::get<Vector<GridsNode>>(this->
nodes_);
531 return std::get<Vector<BMeshNode>>(this->
nodes_);
558 this->
draw_data->tag_positions_changed(node_mask);
568 this->
draw_data->tag_visibility_changed(node_mask);
575 this->
draw_data->tag_topology_changed(node_mask);
582 this->
draw_data->tag_face_sets_changed(node_mask);
589 this->
draw_data->tag_masks_changed(node_mask);
596 this->
draw_data->tag_attribute_changed(node_mask, attribute_name);
602 return std::visit([](
const auto &nodes) {
return nodes.is_empty(); }, pbvh.
nodes_);
608 return std::visit([](
auto &nodes) ->
Node & {
return nodes.first(); }, pbvh.
nodes_);
635 while (!iter->
stack.is_empty()) {
642 if (node ==
nullptr) {
651 if (iter->
scb && !iter->
scb(*node)) {
655 if (node->flag_ & leaf_flag) {
666 iter->
stack.push({&nodes[node->children_offset_ + 1],
false});
667 iter->
stack.push({&nodes[node->children_offset_],
false});
677 while (!iter->
stack.is_empty()) {
683 if (node ==
nullptr) {
687 if (iter->
scb && !iter->
scb(*node)) {
698 iter->
stack.push({&nodes[node->children_offset_ + 1],
false});
699 iter->
stack.push({&nodes[node->children_offset_],
false});
721 tree->left = new_node;
729 tree->right = new_node;
742 hit_fn(*
tree->data, tmin);
753 tree->left =
nullptr;
758 tree->right =
nullptr;
792 new_node->
left =
nullptr;
793 new_node->
right =
nullptr;
818 return a.faces_num ==
b.faces_num && a.corners_num ==
b.corners_num &&
819 a.verts_num ==
b.verts_num;
823 const Object &object_eval)
826 const Mesh &mesh_orig = *
static_cast<const Mesh *
>(object_orig.
data);
831 return mesh_eval->runtime->vert_normals_cache;
835 return mesh_eval->runtime->vert_normals_cache;
844 return mesh_orig.
runtime->vert_normals_cache;
854 const Object &object_eval)
857 const Mesh &mesh_orig = *
static_cast<const Mesh *
>(object_orig.
data);
862 return mesh_eval->runtime->face_normals_cache;
866 return mesh_eval->runtime->face_normals_cache;
875 return mesh_orig.
runtime->face_normals_cache;
890 for (
const int i : face_indices) {
902 normals_calc_faces(positions, faces, corner_verts, face_indices.slice(range), face_normals);
923 for (
const int vert :
verts) {
925 for (
const int face : vert_to_face_map[vert]) {
926 normal += face_normals[face];
938 normals_calc_verts_simple(vert_to_face_map, face_normals, verts.slice(range), vert_normals);
973 const Span<int> corner_verts = mesh.corner_verts();
984 for (
const int vert : node.vert_indices_.as_span().drop_front(node.unique_verts_num_)) {
993 if (face_normals_cache.
is_dirty()) {
994 face_normals_cache.ensure([&](Vector<float3> &r_data) {
995 r_data.resize(faces.size());
996 bke::mesh::normals_calc_faces(positions, faces, corner_verts, r_data);
1008 boundary_verts.reserve(boundary_faces.size());
1009 for (
const int face : boundary_faces) {
1010 boundary_verts.add_multiple(corner_verts.slice(faces[face]));
1013 const Span<float3> face_normals = face_normals_cache.data();
1015 if (vert_normals_cache.is_dirty()) {
1016 vert_normals_cache.ensure([&](Vector<float3> &r_data) {
1017 r_data.resize(positions.size());
1019 positions, faces, corner_verts, vert_to_face_map, face_normals, r_data);
1023 vert_normals_cache.update([&](Vector<float3> &r_data) {
1035 switch (pbvh.
type()) {
1046 subdiv_ccg, nodes, nodes_to_update, memory);
1078 for (
const int vert : node.all_verts()) {
1081 node.bounds_ = bounds;
1087 for (
const int grid : node.grids()) {
1092 node.bounds_ = bounds;
1098 for (
const BMVert *vert : node.bm_unique_verts_) {
1101 for (
const BMVert *vert : node.bm_other_verts_) {
1104 node.bounds_ = bounds;
1112template<
typename NodeT>
1115 const int node_index)
1117 NodeT &node = nodes[node_index];
1119 const bool update = node_index < dirty.
size() && dirty[node_index];
1120 return {node.bounds_,
update};
1129 return {node.bounds_,
update};
1136 nodes.first().bounds_ =
1185 switch (pbvh.
type()) {
1211 for (const int i : range) {
1212 nodes[i].bounds_orig_ = nodes[i].bounds_;
1222 const bool fully_masked = std::all_of(
1223 verts.begin(),
verts.end(), [&](
const int vert) { return mask[vert] == 1.0f; });
1224 const bool fully_unmasked = std::all_of(
1225 verts.begin(),
verts.end(), [&](
const int vert) { return mask[vert] <= 0.0f; });
1235 if (mask.is_empty()) {
1237 nodes[i].flag_ &= ~PBVH_FullyMasked;
1249 bool fully_masked =
true;
1250 bool fully_unmasked =
true;
1251 for (
const int grid : node.grids()) {
1253 fully_masked &= mask == 1.0f;
1254 fully_unmasked &= mask <= 0.0f;
1267 nodes[i].flag_ &= ~PBVH_FullyMasked;
1280 bool fully_masked =
true;
1281 bool fully_unmasked =
true;
1282 for (
const BMVert *vert : node.bm_unique_verts_) {
1286 for (
const BMVert *vert : node.bm_other_verts_) {
1300 nodes[i].flag_ &= ~PBVH_FullyMasked;
1314 const bool fully_hidden = std::all_of(
1315 verts.begin(),
verts.end(), [&](
const int vert) { return hide_vert[vert]; });
1326 node_mask.
foreach_index([&](
const int i) { nodes[i].flag_ &= ~PBVH_FullyHidden; });
1337 const bool fully_hidden = std::none_of(
1338 node.prim_indices_.begin(), node.prim_indices_.end(), [&](
const int grid) {
1339 return bits::any_bit_unset(grid_hidden[grid]);
1350 node_mask.
foreach_index([&](
const int i) { nodes[i].flag_ &= ~PBVH_FullyHidden; });
1360 const bool unique_hidden = std::all_of(
1361 node.bm_unique_verts_.begin(), node.bm_unique_verts_.end(), [&](
const BMVert *vert) {
1362 return BM_elem_flag_test(vert, BM_ELEM_HIDDEN);
1364 const bool other_hidden = std::all_of(
1365 node.bm_other_verts_.begin(), node.bm_other_verts_.end(), [&](
const BMVert *vert) {
1366 return BM_elem_flag_test(vert, BM_ELEM_HIDDEN);
1385 switch (pbvh.
type()) {
1387 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
1406 int display_gridsize)
1408 const int gridarea = (gridsize - 1) * (gridsize - 1);
1410 return gridarea * grid_indices.
size();
1416 int depth1 =
int(log2(
double(gridsize) - 1.0) + DBL_EPSILON);
1417 int depth2 =
int(log2(
double(display_gridsize) - 1.0) + DBL_EPSILON);
1419 int skip = depth2 < depth1 ? 1 << (depth1 - depth2 - 1) : 1;
1422 for (
const int grid : grid_indices) {
1425 for (
int y = 0; y < gridsize - skip; y += skip) {
1426 for (
int x = 0; x < gridsize - skip; x += skip) {
1473 for (
const int grid : nodes[i].grids()) {
1474 faces_to_update[grid_to_face_map[grid]] =
true;
1484 if (nodes.is_empty()) {
1487 return nodes.first().bounds_;
1538 node.flag_ &= ~PBVH_FullyHidden;
1555 node.flag_ &= ~PBVH_FullyMasked;
1572 node.flag_ &= ~PBVH_FullyUnmasked;
1590 for (
const int grid : node.grids()) {
1591 const int face = grid_to_face_map[grid];
1592 if (face != prev_face) {
1597 return faces.as_span();
1606 return node.bounds_;
1614 return node->bounds_orig_;
1621 r_orig_positions = node.orig_positions_;
1622 r_orig_tris = node.orig_tris_;
1645 const float3 &ray_normal,
1668 (depth_test < *depth)) ||
1670 (depth_test < *depth)))
1672 *depth = depth_test;
1688 (depth_test < *depth))
1690 *depth = depth_test;
1700 const float3 &ray_direction,
1707 const float *tri[3] = {v0, v1,
v2};
1709 for (
int i = 0, j = 2; i < 3; j = i++) {
1713 ray_origin, ray_direction, tri[i], tri[j], point_test, &depth_test);
1714 if (dist_sq_test < dist_sq_best || i == 0) {
1716 *r_depth = depth_test;
1717 dist_sq_best = dist_sq_test;
1720 return dist_sq_best;
1724 const float3 &ray_normal,
1737 ray_start, ray_normal, t0, t1, t2, co, &depth_test)) < *dist_sq)
1739 *dist_sq = dist_sq_test;
1740 *r_depth = depth_test;
1742 ray_start, ray_normal, t0, t2, t3, co, &depth_test)) < *dist_sq)
1744 *dist_sq = dist_sq_test;
1745 *r_depth = depth_test;
1754 const float3 &ray_normal,
1766 ray_start, ray_normal, t0, t1, t2, co, &depth_test)) < *dist_sq)
1768 *dist_sq = dist_sq_test;
1769 *r_depth = depth_test;
1779 const float3 &ray_normal,
1780 const int face_index,
1781 const int tri_index,
1782 const std::array<const float *, 3> co,
1784 int &r_active_vertex,
1785 int &r_active_face_index,
1789 float3 nearest_vertex_co(0.0f);
1792 const float3 location = ray_start + ray_normal * *depth;
1793 for (
int i = 0; i < co.size(); i++) {
1800 nearest_vertex_co = co[i];
1801 r_active_vertex = corner_verts[corner_tris[tri_index][i]];
1802 r_active_face_index = face_index;
1815 const float3 &ray_normal,
1818 int &r_active_vertex,
1819 int &r_active_face_index,
1822 const Span<int> face_indices = node.faces();
1827 const int face_i = face_indices[i];
1828 if (!hide_poly.
is_empty() && hide_poly[face_i]) {
1833 const int3 &tri = corner_tris[tri_i];
1834 const std::array<const float *, 3> co{{vert_positions[corner_verts[tri[0]]],
1835 vert_positions[corner_verts[tri[1]]],
1836 vert_positions[corner_verts[tri[2]]]}};
1848 r_active_face_index,
1857 const int face_i = face_indices[i];
1858 if (!hide_poly.
is_empty() && hide_poly[face_i]) {
1863 const int3 &tri = corner_tris[tri_i];
1864 const std::array<const float *, 3> co{
1865 {node_positions[vert_map.
index_of(corner_verts[tri[0]])],
1866 node_positions[vert_map.
index_of(corner_verts[tri[1]])],
1867 node_positions[vert_map.
index_of(corner_verts[tri[2]])]}};
1879 r_active_face_index,
1890 const float3 &ray_normal,
1894 const std::array<const float *, 4> co,
1897 int &r_active_grid_index,
1901 float3 nearest_vertex_co;
1904 const float3 location = ray_start + ray_normal * *depth;
1906 constexpr short x_it[4] = {0, 1, 1, 0};
1907 constexpr short y_it[4] = {1, 1, 0, 0};
1909 for (
int i = 0; i < co.size(); i++) {
1917 r_active_vertex =
SubdivCCGCoord{grid, short(x + x_it[i]), short(y + y_it[i])};
1920 r_active_grid_index = grid;
1927 const float3 &ray_normal,
1931 int &r_active_grid_index,
1942 for (
const int grid : grids) {
1944 for (
const short y :
IndexRange(grid_size - 1)) {
1945 for (
const short x :
IndexRange(grid_size - 1)) {
1951 const std::array<const float *, 4> co{
1957 ray_start, isect_precalc, co[0], co[1], co[2], co[3], depth))
1968 r_active_grid_index,
1977 const int grid = grids[i];
1979 for (
const short y :
IndexRange(grid_size - 1)) {
1980 for (
const short x :
IndexRange(grid_size - 1)) {
1986 const std::array<const float *, 4> co{grid_positions[(y + 1) * grid_size + x],
1987 grid_positions[(y + 1) * grid_size + x + 1],
1988 grid_positions[y * grid_size + x + 1],
1989 grid_positions[y * grid_size +
x]};
1991 ray_start, isect_precalc, co[0], co[1], co[2], co[3], depth))
2002 r_active_grid_index,
2014 Tree &pbvh,
bool original,
float ray_start[3],
float ray_end[3],
float ray_normal[3])
2019 float rootmin_start, rootmin_end;
2021 float bb_center[3], bb_diff[3];
2023 float ray_normal_inv[3];
2024 float offset = 1.0f + 1e-3f;
2025 const float offset_vec[3] = {1e-3f, 1e-3f, 1e-3f};
2055 float dist = max[2] -
min[2];
2088 float epsilon = (std::nextafter(rootmin_start, rootmin_start + 1000.0f) - rootmin_start) *
2091 if (rootmin_start == rootmin_end) {
2092 rootmin_start -= epsilon;
2093 rootmin_end += epsilon;
2104 const bool original)
2106 const float *bb_min, *bb_max;
2110 bb_min = node->bounds_orig_.min;
2111 bb_max = node->bounds_orig_.max;
2114 bb_min = node->bounds_.min;
2115 bb_max = node->bounds_.max;
2118 float co_dummy[3], depth;
2120 &dist_ray_to_aabb_precalc, bb_min, bb_max, co_dummy, &depth);
2122 return depth > 0.0f;
2128 const float3 &ray_normal,
2129 const bool original)
2148 const float3 &ray_normal,
2152 const Span<int> face_indices = node.faces();
2157 const int face_i = face_indices[i];
2158 if (!hide_poly.
is_empty() && hide_poly[face_i]) {
2163 const int3 &corner_tri = corner_tris[tri_i];
2166 vert_positions[corner_verts[corner_tri[0]]],
2167 vert_positions[corner_verts[corner_tri[1]]],
2168 vert_positions[corner_verts[corner_tri[2]]],
2177 const int face_i = face_indices[i];
2178 if (!hide_poly.
is_empty() && hide_poly[face_i]) {
2183 const int3 &corner_tri = corner_tris[tri_i];
2186 node_positions[vert_map.
index_of(corner_verts[corner_tri[0]])],
2187 node_positions[vert_map.
index_of(corner_verts[corner_tri[1]])],
2188 node_positions[vert_map.
index_of(corner_verts[corner_tri[2]])],
2201 const float ray_start[3],
2202 const float ray_normal[3],
2214 for (
const int grid : grids) {
2216 for (
const short y :
IndexRange(grid_size - 1)) {
2217 for (
const short x :
IndexRange(grid_size - 1)) {
2238 const int grid = grids[i];
2240 for (
const short y :
IndexRange(grid_size - 1)) {
2241 for (
const short x :
IndexRange(grid_size - 1)) {
2249 grid_positions[y * grid_size + x],
2250 grid_positions[y * grid_size + x + 1],
2251 grid_positions[(y + 1) * grid_size + x + 1],
2252 grid_positions[(y + 1) * grid_size + x],
2273 const float ray_start[3],
2274 const float ray_normal[3],
2281 switch (pbvh.
type()) {
2304 static_cast<BMeshNode &
>(node), ray_start, ray_normal, depth, dist_sq, use_origco);
2327 for (
int i = 0; i < frustum->
num_planes; i++) {
2328 float vmin[3], vmax[3];
2330 for (
int axis = 0; axis < 3; axis++) {
2331 if (planes[i][axis] < 0) {
2332 vmin[axis] = bounds.
min[axis];
2333 vmax[axis] = bounds.
max[axis];
2336 vmin[axis] = bounds.
max[axis];
2337 vmax[axis] = bounds.
min[axis];
2341 if (
dot_v3v3(planes[i], vmin) + planes[i][3] < 0) {
2344 if (
dot_v3v3(planes[i], vmax) + planes[i][3] <= 0) {
2371 const float bmin[3],
2372 const float bmax[3],
2388 if (!(node.flag_ &
flag)) {
2392 draw_fn(&node, user_data, node.bounds_.min, node.bounds_.max, node.flag_);
2420 for (
int i = 0; i < planes->num_planes; i++) {
2428 const Mesh &mesh_orig = *
static_cast<const Mesh *
>(object_orig.
data);
2433 return mesh_eval->vert_positions();
2441 return mesh_eval->vert_positions();
2450 return mesh_orig.vert_positions();
2455 Mesh &mesh_orig = *
static_cast<Mesh *
>(object_orig.
data);
2460 Mesh *mesh_eval_mut =
const_cast<Mesh *
>(mesh_eval);
2461 return mesh_eval_mut->vert_positions_for_write();
2469 Mesh *mesh_eval_mut =
const_cast<Mesh *
>(mesh_eval);
2470 return mesh_eval_mut->vert_positions_for_write();
2479 return mesh_orig.vert_positions_for_write();
2485 &
const_cast<Object &
>(object_orig));
2505 &
const_cast<Object &
>(object_orig));
2527 return node.debug_draw_gen_;
2537 Mesh &mesh = *
static_cast<Mesh *
>(
object.data);
2571 Mesh &mesh = *
static_cast<Mesh *
>(
object.data);
2575 const OffsetIndices faces = mesh.faces();
2577 IndexMaskMemory memory;
2578 const IndexMask hidden_faces =
2586 face.begin(), face.end(), [&](
const int corner) {
2587 return grid_hidden[corner][key.grid_area - 1];
2593 if (hidden_faces.is_empty()) {
2594 attributes.
remove(
".hide_poly");
2599 hide_poly.
span.fill(
false);
2615 [&](
const auto &nodes) {
2617 nodes.index_range(),
GrainSize(1024), memory, [&](
const int i) {
2618 return (nodes[i].flag_ &
PBVH_Leaf) != 0;
2639 if (node->flag_ & leaf_flag) {
2652 const_cast<Tree &
>(pbvh), [&](
Node &node) {
return filter_fn(node); },
PBVH_Leaf);
2655 [&](
const auto &pbvh_nodes) {
2656 using VectorT = std::decay_t<
decltype(pbvh_nodes)>;
2657 for (
const int i : nodes.index_range()) {
2658 indices[i] =
static_cast<typename VectorT::value_type *
>(nodes[i]) - pbvh_nodes.data();
2662 std::sort(indices.begin(), indices.end());
int CCG_grid_xy_to_index(const int grid_size, const int x, const int y)
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
General operations, lookup, etc. for blender objects.
Mesh * BKE_object_get_evaluated_mesh_no_subsurf(const Object *object_eval)
const Mesh * BKE_object_get_mesh_deform_eval(const Object *object)
bool paint_is_grid_face_hidden(blender::BoundedBitSpan grid_hidden, int gridsize, int x, int y)
void BKE_pbvh_draw_debug_cb(blender::bke::pbvh::Tree &pbvh, void(*draw_fn)(blender::bke::pbvh::Node *node, void *user_data, const float bmin[3], const float bmax[3], PBVHNodeFlags flag), void *user_data)
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_mark_rebuild_pixels(blender::bke::pbvh::Tree &pbvh)
bool BKE_pbvh_node_frustum_exclude_AABB(const blender::bke::pbvh::Node *node, const PBVHFrustumPlanes *frustum)
void BKE_pbvh_node_fully_unmasked_set(blender::bke::pbvh::Node &node, int fully_masked)
int BKE_pbvh_debug_draw_gen_get(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)
void BKE_pbvh_node_mark_update(blender::bke::pbvh::Node &node)
bool BKE_pbvh_node_frustum_contain_AABB(const blender::bke::pbvh::Node *node, const PBVHFrustumPlanes *frustum)
bool BKE_pbvh_node_fully_masked_get(const blender::bke::pbvh::Node &node)
void BKE_pbvh_node_fully_hidden_set(blender::bke::pbvh::Node &node, int fully_hidden)
int BKE_pbvh_get_grid_num_faces(const Object &object)
void BKE_pbvh_node_fully_masked_set(blender::bke::pbvh::Node &node, int fully_masked)
bool BKE_pbvh_node_fully_unmasked_get(const blender::bke::pbvh::Node &node)
void BKE_pbvh_vert_coords_apply(blender::bke::pbvh::Tree &pbvh, blender::Span< blender::float3 > vert_positions)
void BKE_pbvh_sync_visibility_from_verts(Object &object)
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)
CCGKey BKE_subdiv_ccg_key_top_level(const SubdivCCG &subdiv_ccg)
void BKE_subdiv_ccg_update_normals(SubdivCCG &subdiv_ccg, const blender::IndexMask &face_mask)
#define BLI_assert_unreachable()
void BLI_kdtree_nd_ free(KDTree *tree)
MINLINE int square_i(int a)
bool isect_ray_aabb_v3(const struct IsectRayAABB_Precalc *data, const float bb_min[3], const float bb_max[3], float *r_tmin)
struct DistRayAABB_Precalc dist_squared_ray_to_aabb_v3_precalc(const float ray_origin[3], const float ray_direction[3])
float normal_quad_v3(float n[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
void isect_ray_aabb_v3_precalc(struct IsectRayAABB_Precalc *data, const float ray_origin[3], const float ray_direction[3])
bool isect_ray_tri_watertight_v3(const float ray_origin[3], const struct IsectRayPrecalc *isect_precalc, const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float r_uv[2])
void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3])
Normal to x,y matrix.
float dist_squared_ray_to_seg_v3(const float ray_origin[3], const float ray_direction[3], const float v0[3], const float v1[3], float r_point[3], float *r_depth)
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)
float line_point_factor_v3(const float p[3], const float l1[3], const float l2[3])
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
void mul_m3_v3(const float M[3][3], float r[3])
MINLINE void copy_v4_v4(float r[4], const float a[4])
void minmax_v3v3_v3(float min[3], float max[3], const float vec[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_v3_v3(float r[3], const float a[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)
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
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])
Platform independent time functions.
#define SCOPED_TIMER_AVERAGED(name)
#define SET_FLAG_FROM_TEST(value, test, flag)
bool DEG_is_original_object(const Object *object)
Object * DEG_get_original_object(Object *object)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
Object is a sort of wrapper for general info.
static void split(const char *text, const char *seps, char ***str, int *count)
Read Guarded memory(de)allocation.
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
#define BM_ELEM_CD_GET_FLOAT(ele, offset)
#define BM_elem_flag_disable(ele, hflag)
#define BM_elem_flag_test(ele, hflag)
#define BM_elem_flag_enable(ele, hflag)
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
ATTR_WARN_UNUSED_RESULT BMesh * bm
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
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
void reinitialize(const int64_t new_size)
void update(FunctionRef< void(T &data)> compute_cache)
constexpr Span drop_front(int64_t n) 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 Span take_front(int64_t n) const
constexpr bool is_empty() const
int64_t index_of(const Key &key) const
void add_multiple(Span< Key > keys)
void append(const T &value)
void resize(const int64_t new_size)
void resize(const int64_t new_size_in_bits, const bool value=false)
bool remove(const StringRef attribute_id)
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)
std::unique_ptr< DrawCache > draw_data
void tag_visibility_changed(const IndexMask &node_mask)
void tag_topology_changed(const IndexMask &node_mask)
BitVector visibility_dirty_
std::variant< Vector< MeshNode >, Vector< GridsNode >, Vector< BMeshNode > > nodes_
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
static IndexMask from_bits(BitSpan bits, IndexMaskMemory &memory)
static IndexMask from_indices(Span< T > indices, IndexMaskMemory &memory)
int64_t min_array_size() const
void set_bits(MutableBitSpan r_bits, int64_t offset=0) const
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
void foreach_index(Fn &&fn) const
local_group_size(16, 16) .push_constant(Type b
const Depsgraph * depsgraph
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
IndexRange grid_range(const int grid_area, const int grid)
float3 face_normal_calc(Span< float3 > vert_positions, Span< int > face_verts)
IndexRange face_triangles_range(OffsetIndices< int > faces, int face_i)
void normals_calc_verts(Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, GroupedSpan< int > vert_to_face_map, Span< float3 > face_normals, MutableSpan< float3 > vert_normals)
pbvh::Tree * pbvh_get(Object &object)
static void update_visibility_grids(const SubdivCCG &subdiv_ccg, const MutableSpan< GridsNode > nodes, const IndexMask &node_mask)
IndexMask search_nodes(const Tree &pbvh, IndexMaskMemory &memory, FunctionRef< bool(const Node &)> filter_fn)
static bool nearest_to_ray_aabb_dist_sq(Node *node, const DistRayAABB_Precalc &dist_ray_to_aabb_precalc, const bool original)
static void normals_calc_faces(const Span< float3 > positions, const OffsetIndices< int > faces, const Span< int > corner_verts, const Span< int > face_indices, MutableSpan< float3 > face_normals)
static const SharedCache< Vector< float3 > > & vert_normals_cache_eval(const Object &object_orig, const Object &object_eval)
Bounds< float3 > calc_face_bounds(const Span< float3 > vert_positions, const Span< int > face_verts)
void node_pixels_free(blender::bke::pbvh::Node *node)
void update_mask_bmesh(const BMesh &bm, const IndexMask &node_mask, Tree &pbvh)
void update_normals(const Depsgraph &depsgraph, Object &object_orig, Tree &pbvh)
static void node_tree_insert(node_tree *tree, node_tree *new_node)
static BLI_NOINLINE void build_mesh_leaf_nodes(const int verts_num, const OffsetIndices< int > faces, const Span< int > corner_verts, MutableSpan< MeshNode > nodes)
void update_bounds_grids(const CCGKey &key, Span< float3 > positions, Tree &pbvh)
void set_frustum_planes(Tree &pbvh, PBVHFrustumPlanes *planes)
static void free_tree(node_tree *tree)
void update_bounds(const Depsgraph &depsgraph, const Object &object, Tree &pbvh)
static Bounds< float3 > calc_face_grid_bounds(const OffsetIndices< int > faces, const Span< float3 > positions, const CCGKey &key, const int face)
void update_mask_mesh(const Mesh &mesh, const IndexMask &node_mask, Tree &pbvh)
Span< float3 > vert_normals_eval_from_eval(const Object &object_eval)
static void calc_grids_intersect_data(const float3 &ray_start, const float3 &ray_normal, const int grid, const short x, const short y, const std::array< const float *, 4 > co, float *depth, SubdivCCGCoord &r_active_vertex, int &r_active_grid_index, float3 &r_face_normal)
IndexMask all_leaf_nodes(const Tree &pbvh, IndexMaskMemory &memory)
static void calc_node_vert_normals(const GroupedSpan< int > vert_to_face_map, const Span< float3 > face_normals, const Span< MeshNode > nodes, const IndexMask &nodes_to_update, MutableSpan< float3 > vert_normals)
void clip_ray_ortho(Tree &pbvh, bool original, float ray_start[3], float ray_end[3], float ray_normal[3])
static BoundsMergeInfo merge_child_bounds(MutableSpan< NodeT > nodes, const BitSpan dirty, const int node_index)
static bool pbvh_grids_node_nearest_to_ray(const SubdivCCG &subdiv_ccg, GridsNode &node, const Span< float3 > node_positions, const float ray_start[3], const float ray_normal[3], float *r_depth, float *dist_sq)
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 update_node_bounds_bmesh(BMeshNode &node)
static void calc_boundary_vert_normals(const GroupedSpan< int > vert_to_face_map, const Span< float3 > face_normals, const Span< int > verts, MutableSpan< float3 > vert_normals)
static void update_visibility_faces(const Mesh &mesh, const MutableSpan< MeshNode > nodes, const IndexMask &node_mask)
static void pbvh_iter_begin(PBVHIter *iter, Tree &pbvh, FunctionRef< bool(Node &)> scb)
static float dist_squared_ray_to_tri_v3_fast(const float3 &ray_origin, const float3 &ray_direction, const float3 &v0, const float3 &v1, const float3 &v2, float3 &r_point, float *r_depth)
static bool leaf_needs_material_split(const Span< int > faces, const Span< int > material_indices)
bool ray_face_nearest_tri(const float3 &ray_start, const float3 &ray_normal, const float3 &t0, const float3 &t1, const float3 &t2, float *r_depth, float *dist_sq)
static void normals_calc_verts_simple(const GroupedSpan< int > vert_to_face_map, const Span< float3 > face_normals, const Span< int > verts, MutableSpan< float3 > vert_normals)
Span< float3 > vert_positions_eval_from_eval(const Object &object_eval)
static bool tree_is_empty(const Tree &pbvh)
void node_update_mask_bmesh(int mask_offset, BMeshNode &node)
void node_update_mask_mesh(Span< float > mask, MeshNode &node)
void node_update_visibility_grids(const BitGroupVector<> &grid_hidden, GridsNode &node)
void update_bounds_mesh(Span< float3 > vert_positions, Tree &pbvh)
static bool ray_aabb_intersect(Node &node, const RaycastData &rcd)
void bmesh_normals_update(Tree &pbvh, const IndexMask &nodes_to_update)
bool ray_face_nearest_quad(const float3 &ray_start, const float3 &ray_normal, const float3 &t0, const float3 &t1, const float3 &t2, const float3 &t3, float *r_depth, float *dist_sq)
static void traverse_tree(node_tree *tree, const FunctionRef< void(Node &node, float *tmin)> hit_fn, float *tmin)
static void calc_mesh_intersect_data(const Span< int > corner_verts, const Span< int3 > corner_tris, const float3 &ray_start, const float3 &ray_normal, const int face_index, const int tri_index, const std::array< const float *, 3 > co, const float *depth, int &r_active_vertex, int &r_active_face_index, float3 &r_face_normal)
static Node & first_node(Tree &pbvh)
void update_visibility(const Object &object, Tree &pbvh)
void node_update_mask_grids(const CCGKey &key, Span< float > masks, GridsNode &node)
static int partition_along_axis(const Span< float3 > face_centers, MutableSpan< int > faces, const int axis, const float middle)
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)
static Node * pbvh_iter_next_occluded(PBVHIter *iter)
static Bounds< float3 > negative_bounds()
void update_node_bounds_mesh(Span< float3 > positions, MeshNode &node)
void node_update_visibility_bmesh(BMeshNode &node)
static SharedCache< Vector< float3 > > & vert_normals_cache_eval_for_write(Object &object_orig, Object &object_eval)
Bounds< float3 > bounds_get(const Tree &pbvh)
void update_normals_from_eval(Object &object_eval, Tree &pbvh)
Span< float3 > vert_normals_eval(const Depsgraph &depsgraph, const Object &object_orig)
bool bmesh_node_nearest_to_ray(BMeshNode &node, const float3 &ray_start, const float3 &ray_normal, float *r_depth, float *dist_sq, bool use_original)
IndexMask nodes_to_face_selection_grids(const SubdivCCG &subdiv_ccg, Span< GridsNode > nodes, const IndexMask &nodes_mask, IndexMaskMemory &memory)
int count_grid_quads(const BitGroupVector<> &grid_visibility, Span< int > grid_indices, int gridsize, int display_gridsize)
static SharedCache< Vector< float3 > > & face_normals_cache_eval_for_write(Object &object_orig, Object &object_eval)
void update_mask_grids(const SubdivCCG &subdiv_ccg, const IndexMask &node_mask, Tree &pbvh)
MutableSpan< float3 > vert_positions_eval_for_write(const Depsgraph &depsgraph, Object &object_orig)
static bool pbvh_faces_node_nearest_to_ray(const MeshNode &node, const Span< float3 > node_positions, const Span< float3 > vert_positions, const OffsetIndices< int > faces, const Span< int > corner_verts, const Span< int3 > corner_tris, const Span< bool > hide_poly, const float3 &ray_start, const float3 &ray_normal, float *r_depth, float *dist_sq)
bool ray_face_intersection_quad(const float3 &ray_start, const IsectRayPrecalc *isect_precalc, const float3 &t0, const float3 &t1, const float3 &t2, const float3 &t3, float *depth)
static Bounds< float3 > merge_bounds(const Bounds< float3 > &a, const Bounds< float3 > &b)
void pixels_free(blender::bke::pbvh::Tree *pbvh)
static PlaneAABBIsect test_frustum_aabb(const Bounds< float3 > &bounds, const PBVHFrustumPlanes *frustum)
static const SharedCache< Vector< float3 > > & face_normals_cache_eval(const Object &object_orig, const Object &object_eval)
static void build_nodes_recursive_grids(const Span< int > material_indices, const int leaf_limit, const int node_index, const std::optional< Bounds< float3 > > &bounds_precalc, const Span< float3 > face_centers, const int depth, MutableSpan< int > faces, Vector< GridsNode > &nodes)
static Vector< Node * > search_gather(Tree &pbvh, const FunctionRef< bool(Node &)> scb, PBVHNodeFlags leaf_flag)
Bounds< float3 > node_bounds(const Node &node)
void get_frustum_planes(const Tree &pbvh, PBVHFrustumPlanes *planes)
static int partition_material_indices(const Span< int > material_indices, MutableSpan< int > faces)
Span< float3 > face_normals_eval_from_eval(const Object &object_eval)
static void update_visibility_bmesh(const MutableSpan< BMeshNode > nodes, const IndexMask &node_mask)
void update_bounds_bmesh(const BMesh &bm, Tree &pbvh)
bool ray_face_intersection_tri(const float3 &ray_start, const IsectRayPrecalc *isect_precalc, const float3 &t0, const float3 &t1, const float3 &t2, float *depth)
void update_node_bounds_grids(int grid_area, Span< float3 > positions, GridsNode &node)
static void update_normals_mesh(Object &object_orig, Object &object_eval, const Span< MeshNode > nodes, const IndexMask &nodes_to_update)
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)
void store_bounds_orig(Tree &pbvh)
static bool mesh_topology_count_matches(const Mesh &a, const Mesh &b)
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)
static Node * pbvh_iter_next(PBVHIter *iter, PBVHNodeFlags leaf_flag)
static void search_callback_occluded(Tree &pbvh, const FunctionRef< bool(Node &)> scb, const FunctionRef< void(Node &node, float *tmin)> hit_fn)
void node_update_visibility_mesh(Span< bool > hide_vert, MeshNode &node)
static void build_nodes_recursive_mesh(const Span< int > material_indices, const int leaf_limit, const int node_index, const std::optional< Bounds< float3 > > &bounds_precalc, const Span< float3 > face_centers, const int depth, MutableSpan< int > faces, Vector< MeshNode > &nodes)
static void calc_boundary_face_normals(const Span< float3 > positions, const OffsetIndices< int > faces, const Span< int > corner_verts, const Span< int > face_indices, MutableSpan< float3 > face_normals)
void flush_bounds_to_parents(Tree &pbvh)
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)
static void calc_node_face_normals(const Span< float3 > positions, const OffsetIndices< int > faces, const Span< int > corner_verts, const Span< MeshNode > nodes, const IndexMask &nodes_to_update, MutableSpan< float3 > face_normals)
void raycast(Tree &pbvh, FunctionRef< void(Node &node, float *tmin)> cb, const float3 &ray_start, const float3 &ray_normal, bool original)
void mesh_hide_vert_flush(Mesh &mesh)
void mesh_hide_face_flush(Mesh &mesh)
Bounds< T > merge(const Bounds< T > &a, const Bounds< T > &b)
void masked_fill(MutableSpan< T > data, const T &value, const IndexMask &mask)
T midpoint(const T &a, const T &b)
void min_max(const T &value, T &min, T &max)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
int dominant_axis(const VecBase< T, 3 > &a)
void parallel_invoke(Functions &&...functions)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
VecBase< float, 3 > float3
static void update(bNodeTree *ntree)
#define STACK_FIXED_DEPTH
MeshRuntimeHandle * runtime
struct SculptSession * sculpt
blender::SharedCache< blender::Vector< blender::float3 > > face_normals_deform
blender::Array< blender::float3, 0 > deform_cos
blender::SharedCache< blender::Vector< blender::float3 > > vert_normals_deform
blender::BitGroupVector grid_hidden
blender::Array< float > masks
blender::OffsetIndices< int > faces
blender::Span< int > grid_to_face_map
blender::Array< blender::float3 > positions
MutableVArraySpan< T > span
blender::FunctionRef< bool(Node &)> scb
Stack< StackItem, 100 > stack