42#ifdef DEBUG_BUILD_TIME
48#define STACK_FIXED_DEPTH 100
53 return {
float3(std::numeric_limits<float>::max()),
float3(std::numeric_limits<float>::lowest())};
66 const int *
split = std::partition(
faces.begin(),
faces.end(), [&](
const int face) {
67 return face_centers[face][axis] >= middle;
74 const int first = material_indices[
faces.first()];
75 const int *
split = std::partition(
76 faces.begin(),
faces.end(), [&](
const int face) { return material_indices[face] == first; });
85#ifdef DEBUG_BUILD_TIME
91 for (const int i : range) {
92 MeshNode &node = nodes[i];
95 int corners_count = 0;
96 for (const int face_index : node.face_indices_) {
97 const IndexRange face = faces[face_index];
98 verts.add_multiple(corner_verts.slice(face));
99 corners_count += face.size();
101 nodes[i].corners_num_ = corners_count;
103 new (&verts_per_node[i]) Array<int>(verts.size());
104 std::copy(verts.begin(), verts.end(), verts_per_node[i].begin());
105 std::sort(verts_per_node[i].begin(), verts_per_node[i].end());
112 for (
const int i :
nodes.index_range()) {
113 MeshNode &node =
nodes[
i];
116 shared_verts.
clear();
117 for (
const int vert : verts_per_node[
i]) {
118 if (vert_used[vert]) {
119 shared_verts.
append(vert);
122 vert_used[vert].set();
126 node.unique_verts_num_ = owned_verts.
size();
127 node.vert_indices_.reserve(owned_verts.
size() + shared_verts.
size());
128 node.vert_indices_.add_multiple(owned_verts);
129 node.vert_indices_.add_multiple(shared_verts);
138 const int first = material_indices[
faces.first()];
140 faces.begin(),
faces.end(), [&](
const int face) { return material_indices[face] != first; });
145 const int node_index,
146 const int parent_index,
160 if (below_leaf_limit) {
169 nodes[node_index].children_offset_ =
nodes.size();
173 if (!below_leaf_limit) {
175 if (bounds_precalc) {
184 for (
const int face :
faces.slice(range)) {
205 nodes[node_index].children_offset_,
214 nodes[node_index].children_offset_ + 1,
223Tree Tree::from_spatially_organized_mesh(
const Mesh &
mesh)
225#ifdef DEBUG_BUILD_TIME
229 Tree
pbvh(Type::Mesh);
241 pbvh.prim_indices_.reinitialize(mesh.
faces_num);
245 for (const int node_idx : range) {
246 MeshNode &pbvh_node = nodes[node_idx];
247 pbvh_node.parent_ = spatial_groups[node_idx].parent;
249 if (spatial_groups[node_idx].children_offset != 0) {
250 pbvh_node.children_offset_ = spatial_groups[node_idx].children_offset;
253 pbvh_node.children_offset_ = 0;
254 pbvh_node.flag_ = Node::Leaf;
256 const IndexRange face_range = spatial_groups[node_idx].faces;
257 const int face_count = face_range.size();
259 if (face_count > 0) {
260 pbvh_node.face_indices_ = Span<int>(&pbvh.prim_indices_[face_range.start()], face_count);
262 pbvh_node.corners_num_ = spatial_groups[node_idx].corners_count;
264 pbvh_node.unique_verts_num_ = spatial_groups[node_idx].unique_verts.size();
266 pbvh_node.vert_indices_.reserve(spatial_groups[node_idx].unique_verts.size() +
267 spatial_groups[node_idx].shared_verts.size());
269 for (const int i : spatial_groups[node_idx].unique_verts.index_range()) {
270 const int vert_idx = spatial_groups[node_idx].unique_verts.start() + i;
271 pbvh_node.vert_indices_.add(vert_idx);
274 for (const int vert_idx : spatial_groups[node_idx].shared_verts) {
275 pbvh_node.vert_indices_.add(vert_idx);
279 pbvh_node.unique_verts_num_ = 0;
280 pbvh_node.corners_num_ = 0;
287 pbvh.update_bounds_mesh(vert_positions);
288 store_bounds_orig(pbvh);
290 const AttributeAccessor attributes = mesh.
attributes();
291 const VArraySpan hide_vert = *attributes.lookup<
bool>(
".hide_vert", AttrDomain::Point);
293 if (!hide_vert.is_empty()) {
295 for (const int i : range) {
296 node_update_visibility_mesh(hide_vert, nodes[i]);
308#ifdef DEBUG_BUILD_TIME
311 if (
mesh.runtime->spatial_groups) {
312 return from_spatially_organized_mesh(
mesh);
318 if (
faces.is_empty()) {
323 static_assert(leaf_limit < std::numeric_limits<MeshNode::LocalVertMapIndexT>::max());
332 for (
const int face : range) {
335 face_centers[face] =
bounds.center();
346 pbvh.prim_indices_.reinitialize(
faces.size());
352#ifdef DEBUG_BUILD_TIME
361 pbvh.tag_positions_changed(
nodes.index_range());
363 pbvh.update_bounds_mesh(vert_positions);
368 for (const int i : range) {
369 node_update_visibility_mesh(hide_vert, nodes[i]);
381 const int node_index,
382 const int parent_index,
396 if (below_leaf_limit) {
405 nodes[node_index].children_offset_ =
nodes.size();
409 if (!below_leaf_limit) {
411 if (bounds_precalc) {
420 for (
const int face :
faces.slice(range)) {
441 nodes[node_index].children_offset_,
450 nodes[node_index].children_offset_ + 1,
473#ifdef DEBUG_BUILD_TIME
478 if (
faces.is_empty()) {
491 constexpr int base_limit = 800;
501 for (
const int face : range) {
503 face_centers[face] =
bounds.center();
519#ifdef DEBUG_BUILD_TIME
527 pbvh.prim_indices_.reinitialize(
faces.total_size());
530 for (
const int i :
nodes.index_range()) {
531 for (
const int face :
nodes[
i].prim_indices_) {
532 for (
const int corner :
faces[face]) {
533 pbvh.prim_indices_[offset] = corner;
543 for (const int i : range) {
544 node_grids_num[i] = offset_indices::sum_group_sizes(faces, nodes[i].prim_indices_);
551 for (const int i : range) {
552 nodes[i].prim_indices_ = pbvh.prim_indices_.as_span().slice(node_grid_offsets[i]);
556 pbvh.tag_positions_changed(
nodes.index_range());
558 pbvh.update_bounds_grids(positions, key.grid_area);
559 store_bounds_orig(
pbvh);
564 for (const int i : range) {
565 node_update_visibility_grids(grid_hidden, nodes[i]);
570 update_mask_grids(subdiv_ccg, nodes.
index_range(), pbvh);
575Tree::Tree(
const Type type) : type_(type)
592 return std::visit([](
const auto &
nodes) {
return nodes.size(); }, this->
nodes_);
597 return std::get<Vector<MeshNode>>(this->
nodes_);
601 return std::get<Vector<GridsNode>>(this->
nodes_);
605 return std::get<Vector<BMeshNode>>(this->
nodes_);
609 return std::get<Vector<MeshNode>>(this->
nodes_);
613 return std::get<Vector<GridsNode>>(this->
nodes_);
617 return std::get<Vector<BMeshNode>>(this->
nodes_);
624 for (Node &node :
nodes) {
637 bounds_dirty_.resize(std::max(bounds_dirty_.size(), node_mask.
min_array_size()),
false);
638 normals_dirty_.resize(std::max(normals_dirty_.size(), node_mask.
min_array_size()),
false);
642 this->
draw_data->tag_positions_changed(node_mask);
648 visibility_dirty_.resize(std::max(visibility_dirty_.size(), node_mask.
min_array_size()),
false);
649 node_mask.
set_bits(visibility_dirty_);
651 this->
draw_data->tag_visibility_changed(node_mask);
658 this->
draw_data->tag_topology_changed(node_mask);
665 this->
draw_data->tag_face_sets_changed(node_mask);
672 this->
draw_data->tag_masks_changed(node_mask);
679 this->
draw_data->tag_attribute_changed(node_mask, attribute_name);
685 return std::visit([](
const auto &
nodes) {
return nodes.is_empty(); },
pbvh.nodes_);
718 while (!iter->
stack.is_empty()) {
725 if (node ==
nullptr) {
734 if (iter->
scb && !iter->
scb(*node)) {
738 if (node->
flag_ & leaf_flag) {
744 iter->
stack.push({node,
true});
760 while (!iter->
stack.is_empty()) {
766 if (node ==
nullptr) {
770 if (iter->
scb && !iter->
scb(*node)) {
804 tree->left = new_node;
812 tree->right = new_node;
825 hit_fn(*
tree->data, tmin);
836 tree->left =
nullptr;
841 tree->right =
nullptr;
854namespace blender::bke::pbvh {
873 new_node->
data = node;
875 new_node->
left =
nullptr;
876 new_node->
right =
nullptr;
920 const Mesh &mesh_orig = *
static_cast<const Mesh *
>(object_orig.
data);
946 const Object &object_eval)
949 const Mesh &mesh_orig = *
static_cast<const Mesh *
>(object_orig.
data);
953 switch (
result.cache_source) {
955 return result.mesh_eval->runtime->vert_normals_true_cache;
957 return result.mesh_eval->runtime->vert_normals_true_cache;
961 return mesh_orig.
runtime->vert_normals_true_cache;
964 return mesh_orig.
runtime->vert_normals_true_cache;
974 const Object &object_eval)
977 const Mesh &mesh_orig = *
static_cast<const Mesh *
>(object_orig.
data);
980 switch (
result.cache_source) {
982 return result.mesh_eval->runtime->face_normals_true_cache;
984 return result.mesh_eval->runtime->face_normals_true_cache;
988 return mesh_orig.
runtime->face_normals_true_cache;
991 return mesh_orig.
runtime->face_normals_true_cache;
1003 const Mesh &mesh_orig = *
static_cast<const Mesh *
>(object_orig.
data);
1006 switch (
result.cache_source) {
1008 return result.mesh_eval->vert_positions();
1010 return result.mesh_eval->vert_positions();
1014 return mesh_orig.vert_positions();
1017 return mesh_orig.vert_positions();
1023 Mesh &mesh_orig = *
static_cast<Mesh *
>(object_orig.
data);
1026 switch (
result.cache_source) {
1028 return const_cast<Mesh *
>(
result.mesh_eval)->vert_positions_for_write();
1030 return const_cast<Mesh *
>(
result.mesh_eval)->vert_positions_for_write();
1034 return mesh_orig.vert_positions_for_write();
1037 return mesh_orig.vert_positions_for_write();
1085 for (
const int i : face_indices) {
1097 normals_calc_faces(positions, faces, corner_verts, face_indices.slice(range), face_normals);
1118 for (
const int vert :
verts) {
1120 for (
const int face : vert_to_face_map[vert]) {
1121 normal += face_normals[face];
1126 vert_normals[vert] =
float3(0, 0, 1);
1137 normals_calc_verts_simple(vert_to_face_map, face_normals, verts.slice(range), vert_normals);
1192 if (face_normals_cache.
is_dirty()) {
1208 for (
const int face : boundary_faces) {
1214 if (vert_normals_cache.
is_dirty()) {
1218 positions,
faces, corner_verts, vert_to_face_map, face_normals, r_data);
1234 switch (this->
type()) {
1245 subdiv_ccg,
nodes, nodes_to_update, memory);
1254 normals_dirty_.clear_and_shrink();
1261 pbvh.update_normals(object_orig, object_eval);
1271 pbvh.update_normals(object_orig, object_eval);
1277 for (
const int vert : node.
all_verts()) {
1286 for (
const int grid : node.
grids()) {
1317 if (std::optional<int> parent =
nodes[
i].parent()) {
1318 nodes_to_update.
add(*parent);
1322 while (!nodes_to_update.
is_empty()) {
1323 const int node_index = *nodes_to_update.
begin();
1324 nodes_to_update.
remove(node_index);
1326 auto &node =
nodes[node_index];
1333 const std::optional<int> parent = node.parent();
1334 const bool bounds_changed = node.bounds_.min != old_bounds.
min ||
1335 node.bounds_.max != old_bounds.
max;
1337 if (bounds_changed && parent) {
1338 nodes_to_update.
add(*parent);
1343 bounds_dirty_.clear_and_shrink();
1388 switch (this->
type()) {
1413 for (const int i : range) {
1414 nodes[i].bounds_orig_ = nodes[i].bounds_;
1424 const bool fully_masked = std::all_of(
1425 verts.begin(),
verts.end(), [&](
const int vert) { return mask[vert] == 1.0f; });
1426 const bool fully_unmasked = std::all_of(
1427 verts.begin(),
verts.end(), [&](
const int vert) { return mask[vert] <= 0.0f; });
1437 if (
mask.is_empty()) {
1451 bool fully_masked =
true;
1452 bool fully_unmasked =
true;
1453 for (
const int grid : node.
grids()) {
1455 fully_masked &=
mask == 1.0f;
1456 fully_unmasked &=
mask <= 0.0f;
1482 bool fully_masked =
true;
1483 bool fully_unmasked =
true;
1516 const bool fully_hidden = std::all_of(
1517 verts.begin(),
verts.end(), [&](
const int vert) { return hide_vert[vert]; });
1539 const bool fully_hidden = std::none_of(
1541 return bits::any_bit_unset(grid_hidden[grid]);
1562 const bool unique_hidden = std::all_of(
1564 return BM_elem_flag_test(vert, BM_ELEM_HIDDEN);
1566 const bool other_hidden = std::all_of(
1568 return BM_elem_flag_test(vert, BM_ELEM_HIDDEN);
1586 visibility_dirty_.clear_and_shrink();
1587 switch (this->type()) {
1589 const Mesh &
mesh = *
static_cast<const Mesh *
>(
object.data);
1608 int display_gridsize)
1610 const int gridarea = (gridsize - 1) * (gridsize - 1);
1612 return gridarea * grid_indices.
size();
1618 int depth1 = int(
log2(
double(gridsize) - 1.0) + DBL_EPSILON);
1619 int depth2 = int(
log2(
double(display_gridsize) - 1.0) + DBL_EPSILON);
1621 int skip = depth2 < depth1 ? 1 << (depth1 - depth2 - 1) : 1;
1624 for (
const int grid : grid_indices) {
1627 for (
int y = 0;
y < gridsize - skip;
y += skip) {
1628 for (
int x = 0;
x < gridsize - skip;
x += skip) {
1654 for (
const int grid :
nodes[
i].grids()) {
1655 faces_to_update[grid_to_face_map[grid]] =
true;
1665 if (
nodes.is_empty()) {
1668 return nodes.first().bounds_;
1765namespace blender::bke::pbvh {
1774 for (
const int grid : node.
grids()) {
1775 const int face = grid_to_face_map[grid];
1776 if (face != prev_face) {
1781 return faces.as_span();
1796namespace blender::bke::pbvh {
1814 const float3 &ray_normal,
1837 (depth_test < *depth)) ||
1839 (depth_test < *depth)))
1841 *depth = depth_test;
1857 (depth_test < *depth))
1859 *depth = depth_test;
1869 const float3 &ray_direction,
1876 const float *tri[3] = {v0, v1,
v2};
1878 for (
int i = 0, j = 2;
i < 3; j =
i++) {
1882 ray_origin, ray_direction, tri[
i], tri[j], point_test, &depth_test);
1883 if (dist_sq_test < dist_sq_best ||
i == 0) {
1885 *r_depth = depth_test;
1886 dist_sq_best = dist_sq_test;
1889 return dist_sq_best;
1893 const float3 &ray_normal,
1906 ray_start, ray_normal, t0, t1, t2, co, &depth_test)) < *dist_sq)
1908 *dist_sq = dist_sq_test;
1909 *r_depth = depth_test;
1911 ray_start, ray_normal, t0, t2, t3, co, &depth_test)) < *dist_sq)
1913 *dist_sq = dist_sq_test;
1914 *r_depth = depth_test;
1923 const float3 &ray_normal,
1935 ray_start, ray_normal, t0, t1, t2, co, &depth_test)) < *dist_sq)
1937 *dist_sq = dist_sq_test;
1938 *r_depth = depth_test;
1948 const float3 &ray_normal,
1949 const int face_index,
1950 const int tri_index,
1951 const std::array<const float *, 3> co,
1953 int &r_active_vertex,
1954 int &r_active_face_index,
1958 float3 nearest_vertex_co(0.0f);
1961 const float3 location = ray_start + ray_normal * depth;
1962 for (
int i = 0;
i < co.size();
i++) {
1969 nearest_vertex_co = co[
i];
1970 r_active_vertex = corner_verts[corner_tris[tri_index][
i]];
1971 r_active_face_index = face_index;
1984 const float3 &ray_normal,
1987 int &r_active_vertex,
1988 int &r_active_face_index,
1996 const int face_i = face_indices[
i];
1997 if (!hide_poly.
is_empty() && hide_poly[face_i]) {
2002 const int3 &tri = corner_tris[tri_i];
2003 const std::array<const float *, 3> co{{vert_positions[corner_verts[tri[0]]],
2004 vert_positions[corner_verts[tri[1]]],
2005 vert_positions[corner_verts[tri[2]]]}};
2017 r_active_face_index,
2026 const int face_i = face_indices[
i];
2027 if (!hide_poly.
is_empty() && hide_poly[face_i]) {
2032 const int3 &tri = corner_tris[tri_i];
2033 const std::array<const float *, 3> co{
2034 {node_positions[vert_map.
index_of(corner_verts[tri[0]])],
2035 node_positions[vert_map.
index_of(corner_verts[tri[1]])],
2036 node_positions[vert_map.
index_of(corner_verts[tri[2]])]}};
2048 r_active_face_index,
2059 const float3 &ray_normal,
2063 const std::array<const float *, 4> co,
2066 int &r_active_grid_index,
2070 float3 nearest_vertex_co;
2073 const float3 location = ray_start + ray_normal * depth;
2075 constexpr short x_it[4] = {0, 1, 1, 0};
2076 constexpr short y_it[4] = {1, 1, 0, 0};
2078 for (
int i = 0;
i < co.size();
i++) {
2089 r_active_grid_index = grid;
2096 const float3 &ray_normal,
2100 int &r_active_grid_index,
2111 for (
const int grid : grids) {
2120 const std::array<const float *, 4> co{
2126 ray_start, isect_precalc, co[0], co[1], co[2], co[3], depth))
2137 r_active_grid_index,
2146 const int grid = grids[
i];
2155 const std::array<const float *, 4> co{grid_positions[(
y + 1) * grid_size +
x],
2156 grid_positions[(
y + 1) * grid_size +
x + 1],
2157 grid_positions[
y * grid_size +
x + 1],
2158 grid_positions[
y * grid_size +
x]};
2160 ray_start, isect_precalc, co[0], co[1], co[2], co[3], depth))
2171 r_active_grid_index,
2183 Tree &
pbvh,
bool original,
float ray_start[3],
float ray_end[3],
float ray_normal[3])
2188 float rootmin_start, rootmin_end;
2190 float bb_center[3], bb_diff[3];
2192 float ray_normal_inv[3];
2193 float offset = 1.0f + 1e-3f;
2194 const float offset_vec[3] = {1e-3f, 1e-3f, 1e-3f};
2224 float dist =
max[2] -
min[2];
2257 float epsilon = (std::nextafter(rootmin_start, rootmin_start + 1000.0f) - rootmin_start) *
2260 if (rootmin_start == rootmin_end) {
2261 rootmin_start -= epsilon;
2262 rootmin_end += epsilon;
2273 const bool original)
2275 const float *bb_min, *bb_max;
2287 float co_dummy[3], depth;
2289 &dist_ray_to_aabb_precalc, bb_min, bb_max, co_dummy, &depth);
2291 return depth > 0.0f;
2297 const float3 &ray_normal,
2298 const bool original)
2317 const float3 &ray_normal,
2326 const int face_i = face_indices[
i];
2327 if (!hide_poly.
is_empty() && hide_poly[face_i]) {
2332 const int3 &corner_tri = corner_tris[tri_i];
2335 vert_positions[corner_verts[corner_tri[0]]],
2336 vert_positions[corner_verts[corner_tri[1]]],
2337 vert_positions[corner_verts[corner_tri[2]]],
2346 const int face_i = face_indices[
i];
2347 if (!hide_poly.
is_empty() && hide_poly[face_i]) {
2352 const int3 &corner_tri = corner_tris[tri_i];
2355 node_positions[vert_map.
index_of(corner_verts[corner_tri[0]])],
2356 node_positions[vert_map.
index_of(corner_verts[corner_tri[1]])],
2357 node_positions[vert_map.
index_of(corner_verts[corner_tri[2]])],
2370 const float ray_start[3],
2371 const float ray_normal[3],
2383 for (
const int grid : grids) {
2407 const int grid = grids[
i];
2418 grid_positions[
y * grid_size +
x],
2419 grid_positions[
y * grid_size +
x + 1],
2420 grid_positions[(
y + 1) * grid_size +
x + 1],
2421 grid_positions[(
y + 1) * grid_size +
x],
2442 const float ray_start[3],
2443 const float ray_normal[3],
2450 switch (
pbvh.type()) {
2473 static_cast<BMeshNode &
>(node), ray_start, ray_normal, depth, dist_sq, use_origco);
2496 float vmin[3], vmax[3];
2498 for (
int axis = 0; axis < 3; axis++) {
2499 if (frustum_planes[
i][axis] < 0) {
2500 vmin[axis] =
bounds.min[axis];
2501 vmax[axis] =
bounds.max[axis];
2504 vmin[axis] =
bounds.max[axis];
2505 vmax[axis] =
bounds.min[axis];
2509 if (
dot_v3v3(frustum_planes[
i], vmin) + frustum_planes[
i][3] < 0) {
2512 if (
dot_v3v3(frustum_planes[
i], vmax) + frustum_planes[
i][3] <= 0) {
2537 pbvh.update_bounds_mesh(vert_positions);
2602 face.
begin(), face.
end(), [&](
const int corner) {
2603 return grid_hidden[corner][key.grid_area - 1];
2610 attributes.
remove(
".hide_poly");
2615 hide_poly.
span.fill(
false);
2626namespace blender::bke::pbvh {
2631 [&](
const auto &
nodes) {
2655 if (node->
flag_ & leaf_flag) {
2671 [&](
const auto &pbvh_nodes) {
2672 using VectorT = std::decay_t<
decltype(pbvh_nodes)>;
2673 for (
const int i :
nodes.index_range()) {
2674 indices[
i] =
static_cast<typename VectorT::value_type *
>(
nodes[
i]) - pbvh_nodes.data();
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)
A BVH for high poly meshes.
bool BKE_pbvh_node_fully_hidden_get(const blender::bke::pbvh::Node &node)
void BKE_pbvh_mark_rebuild_pixels(blender::bke::pbvh::Tree &pbvh)
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_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])
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])
#define SCOPED_TIMER_AVERAGED(name)
#define SET_FLAG_FROM_TEST(value, test, flag)
bool DEG_is_original(const T *id)
T * DEG_get_original(T *id)
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
Object is a sort of wrapper for general info.
static void split(const char *text, const char *seps, char ***str, int *count)
#define STACK_FIXED_DEPTH
#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 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
BPy_StructRNA * depsgraph
DBVT_INLINE bool Intersect(const btDbvtAabbMm &a, const btDbvtAabbMm &b)
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
static IndexMask from_indices(Span< T > indices, IndexMaskMemory &memory)
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
constexpr Iterator end() const
constexpr Iterator begin() const
constexpr Span drop_front(int64_t n) const
constexpr const T * end() const
constexpr const T * begin() const
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
static IndexMask from_bits(BitSpan bits, IndexMaskMemory &memory)
void reserve(const int64_t n)
bool remove(const Key &key)
void update(FunctionRef< void(T &data)> compute_cache)
void ensure(FunctionRef< void(T &data)> compute_cache)
constexpr Span slice(int64_t start, int64_t size) const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
void reserve(const int64_t n)
void add_multiple(Span< Key > keys)
int64_t index_of(const Key &key) const
Span< Key > as_span() const
void append(const T &value)
IndexRange index_range() const
void resize(const int64_t new_size)
GAttributeReader lookup(const StringRef attribute_id) const
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, AttrType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
bool remove(const StringRef attribute_id)
Bounds< float3 > bounds_orig_
void update_normals(Object &object_orig, Object &object_eval)
void tag_attribute_changed(const IndexMask &node_mask, StringRef attribute_name)
Tree(const Tree &other)=delete
void tag_positions_changed(const IndexMask &node_mask)
Span< NodeT > nodes() const
void update_bounds(const Depsgraph &depsgraph, const Object &object)
void update_bounds_grids(Span< float3 > positions, int grid_area)
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 update_visibility(const Object &object)
static Tree from_grids(const Mesh &base_mesh, const SubdivCCG &subdiv_ccg)
static Tree from_mesh(const Mesh &mesh)
void tag_topology_changed(const IndexMask &node_mask)
void update_bounds_mesh(Span< float3 > vert_positions)
void update_bounds_bmesh(const BMesh &bm)
std::variant< Vector< MeshNode >, Vector< GridsNode >, Vector< BMeshNode > > nodes_
void flush_bounds_to_parents()
int64_t min_array_size() const
void set_bits(MutableBitSpan r_bits, int64_t offset=0) const
void foreach_index(Fn &&fn) const
float length(VecOp< float, D >) RET
VecBase< float, 3 > float3
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
ccl_device bool ray_aabb_intersect(const float3 bbox_min, const float3 bbox_max, const float3 ray_P, const float3 ray_D, ccl_private Interval< float > *t_range)
void fill_index_range(MutableSpan< T > span, const T start=0)
IndexRange face_range(const OffsetIndices< int > faces, const int grid_area, const int face)
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)
void normals_calc_faces(Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, MutableSpan< float3 > face_normals)
pbvh::Tree * pbvh_get(Object &object)
void raycast(Tree &pbvh, FunctionRef< void(Node &node, float *tmin)> hit_fn, const float3 &ray_start, const float3 &ray_normal, bool original)
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 PlaneAABBIsect test_frustum_aabb(const Bounds< float3 > &bounds, const Span< float4 > frustum_planes)
static bool nearest_to_ray_aabb_dist_sq(Node *node, const DistRayAABB_Precalc &dist_ray_to_aabb_precalc, const bool original)
bool bmesh_node_nearest_to_ray(BMeshNode &node, const float3 &ray_start, const float3 &ray_normal, float *r_depth, float *dist_sq, const bool use_original)
static Vector< Node * > search_gather(Tree &pbvh, const FunctionRef< bool(Node &)> scb, Node::Flags leaf_flag)
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)
static void build_nodes_recursive_grids(const Span< int > material_indices, const int leaf_limit, const int node_index, const int parent_index, const std::optional< Bounds< float3 > > &bounds_precalc, const Span< float3 > face_centers, const int depth, MutableSpan< int > faces, Vector< GridsNode > &nodes)
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 BLI_NOINLINE void build_mesh_leaf_nodes(const int verts_num, const OffsetIndices< int > faces, const Span< int > corner_verts, MutableSpan< MeshNode > nodes)
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)
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 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)
int count_grid_quads(const BitGroupVector<> &grid_hidden, Span< int > grid_indices, int gridsize, int display_gridsize)
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)
int partition_along_axis(const Span< float3 > face_centers, MutableSpan< int > faces, const int axis, const float middle)
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)
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)
bool node_frustum_exclude_aabb(const Node &node, Span< float4 > frustum_planes)
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 bmesh_normals_update(Tree &pbvh, const IndexMask &nodes_to_update)
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)
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 free_tree(NodeTree *tree)
static Node * pbvh_iter_next(PBVHIter *iter, Node::Flags leaf_flag)
static Node & first_node(Tree &pbvh)
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)
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)
IndexMask nodes_to_face_selection_grids(const SubdivCCG &subdiv_ccg, Span< GridsNode > nodes, const IndexMask &nodes_mask, IndexMaskMemory &memory)
static void build_nodes_recursive_mesh(const Span< int > material_indices, const int leaf_limit, const int node_index, const int parent_index, const std::optional< Bounds< float3 > > &bounds_precalc, const Span< float3 > face_centers, const int depth, MutableSpan< int > faces, Vector< MeshNode > &nodes)
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 const SharedCache< Vector< float3 > > & face_normals_cache_eval(const Object &object_orig, const Object &object_eval)
static void node_tree_insert(NodeTree *tree, NodeTree *new_node)
bool leaf_needs_material_split(const Span< int > faces, const Span< int > material_indices)
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, const float depth, SubdivCCGCoord &r_active_vertex, int &r_active_grid_index, float3 &r_face_normal)
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)
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)
bool node_frustum_contain_aabb(const Node &node, Span< float4 > frustum_planes)
static void update_normals_mesh(Object &object_orig, Object &object_eval, const Span< MeshNode > nodes, const IndexMask &nodes_to_update)
static void traverse_tree(NodeTree *tree, const FunctionRef< void(Node &node, float *tmin)> hit_fn, float *tmin)
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 void search_callback_occluded(Tree &pbvh, const FunctionRef< bool(Node &)> scb, const FunctionRef< void(Node &node, float *tmin)> hit_fn)
static PositionSourceResult cache_source_get(const Object &object_orig, const Object &object_eval)
void node_update_visibility_mesh(Span< bool > hide_vert, MeshNode &node)
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 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 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)
QuaternionBase< T > normalize_and_get_length(const QuaternionBase< T > &q, T &out_length)
T midpoint(const T &a, const T &b)
void min_max(const T &value, T &min, T &max)
int dominant_axis(const VecBase< T, 3 > &a)
OffsetIndices< int > accumulate_counts_to_offsets(MutableSpan< int > counts_to_offsets, int start_offset=0)
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))
Value parallel_reduce(IndexRange range, int64_t grain_size, const Value &identity, const Function &function, const Reduction &reduction)
VecBase< int32_t, 3 > int3
VecBase< float, 3 > float3
static void init(bNodeTree *, bNode *node)
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
Array< int3, 0 > orig_tris_
Array< float3, 0 > orig_positions_
Set< BMVert *, 0 > bm_unique_verts_
Set< BMVert *, 0 > bm_other_verts_
Span< int > prim_indices_
Span< int > grids() const
Span< int > faces() const
Span< int > face_indices_
Span< int > all_verts() const
VectorSet< int, 0, DefaultProbingStrategy, DefaultHash< int >, DefaultEquality< int >, SimpleVectorSetSlot< int, LocalVertMapIndexT >, GuardedAllocator > LocalVertMap
LocalVertMap vert_indices_
blender::FunctionRef< bool(Node &)> scb
Stack< StackItem, 100 > stack
PositionSource cache_source