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();
123 owned_verts.append(vert);
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; });
144 const int leaf_limit,
145 const int node_index,
146 const int parent_index,
156 node.parent_ = parent_index;
160 if (below_leaf_limit) {
162 node.flag_ |= Node::Leaf;
169 nodes[node_index].children_offset_ = nodes.
size();
173 if (!below_leaf_limit) {
175 if (bounds_precalc) {
179 bounds = threading::parallel_reduce(
205 nodes[node_index].children_offset_,
214 nodes[node_index].children_offset_ + 1,
227 for (
const int vert : face_verts.
slice(1, face_verts.
size() - 1)) {
235#ifdef DEBUG_BUILD_TIME
238 Tree pbvh(Type::Mesh);
242 if (
faces.is_empty()) {
247 static_assert(leaf_limit < std::numeric_limits<MeshNode::LocalVertMapIndexT>::max());
256 for (
const int face :
range) {
259 face_centers[face] =
bounds.center();
260 current = bounds::merge(current,
bounds);
267 const VArraySpan hide_vert = *attributes.lookup<
bool>(
".hide_vert", AttrDomain::Point);
268 const VArraySpan material_index = *attributes.lookup<
int>(
"material_index", AttrDomain::Face);
271 array_utils::fill_index_range<int>(pbvh.prim_indices_);
276#ifdef DEBUG_BUILD_TIME
280 material_index,
leaf_limit, 0, -1,
bounds, face_centers, 0, pbvh.prim_indices_, nodes);
292 for (const int i : range) {
293 node_update_visibility_mesh(hide_vert, nodes[i]);
304 const int leaf_limit,
305 const int node_index,
306 const int parent_index,
316 node.parent_ = parent_index;
320 if (below_leaf_limit) {
322 node.flag_ |= Node::Leaf;
329 nodes[node_index].children_offset_ = nodes.
size();
333 if (!below_leaf_limit) {
335 if (bounds_precalc) {
339 bounds = threading::parallel_reduce(
365 nodes[node_index].children_offset_,
374 nodes[node_index].children_offset_ + 1,
397#ifdef DEBUG_BUILD_TIME
400 Tree pbvh(Type::Grids);
402 if (
faces.is_empty()) {
415 constexpr int base_limit = 800;
416 const int leaf_limit = std::max(base_limit /
key.grid_area, 1);
425 for (
const int face :
range) {
427 face_centers[face] =
bounds.center();
428 current = bounds::merge(current,
bounds);
435 const VArraySpan material_index = *attributes.lookup<
int>(
"material_index", AttrDomain::Face);
438 array_utils::fill_index_range<int>(face_indices);
443#ifdef DEBUG_BUILD_TIME
447 material_index,
leaf_limit, 0, -1,
bounds, face_centers, 0, face_indices, nodes);
455 for (
const int face : nodes[i].prim_indices_) {
456 for (
const int corner :
faces[face]) {
457 pbvh.prim_indices_[offset] = corner;
467 for (const int i : range) {
468 node_grids_num[i] = offset_indices::sum_group_sizes(faces, nodes[i].prim_indices_);
471 const OffsetIndices<int> node_grid_offsets = offset_indices::accumulate_counts_to_offsets(
474 threading::parallel_for(nodes.index_range(), 512, [&](
const IndexRange range) {
475 for (const int i : range) {
476 nodes[i].prim_indices_ = pbvh.prim_indices_.as_span().slice(node_grid_offsets[i]);
480 pbvh.tag_positions_changed(nodes.index_range());
482 pbvh.update_bounds_grids(positions,
key.grid_area);
483 store_bounds_orig(pbvh);
487 threading::parallel_for(nodes.index_range(), 8, [&](
const IndexRange range) {
488 for (const int i : range) {
489 node_update_visibility_grids(grid_hidden, nodes[i]);
494 update_mask_grids(subdiv_ccg, nodes.index_range(), pbvh);
499Tree::Tree(
const Type type) : type_(type)
516 return std::visit([](
const auto &
nodes) {
return nodes.size(); }, this->
nodes_);
521 return std::get<Vector<MeshNode>>(this->
nodes_);
525 return std::get<Vector<GridsNode>>(this->
nodes_);
529 return std::get<Vector<BMeshNode>>(this->
nodes_);
533 return std::get<Vector<MeshNode>>(this->
nodes_);
537 return std::get<Vector<GridsNode>>(this->
nodes_);
541 return std::get<Vector<BMeshNode>>(this->
nodes_);
566 this->
draw_data->tag_positions_changed(node_mask);
573 node_mask.
set_bits(visibility_dirty_);
575 this->
draw_data->tag_visibility_changed(node_mask);
582 this->
draw_data->tag_topology_changed(node_mask);
589 this->
draw_data->tag_face_sets_changed(node_mask);
596 this->
draw_data->tag_masks_changed(node_mask);
603 this->
draw_data->tag_attribute_changed(node_mask, attribute_name);
609 return std::visit([](
const auto &nodes) {
return nodes.is_empty(); }, pbvh.
nodes_);
615 return std::visit([](
auto &nodes) ->
Node & {
return nodes.first(); }, pbvh.
nodes_);
642 while (!iter->
stack.is_empty()) {
649 if (
node ==
nullptr) {
662 if (
node->flag_ & leaf_flag) {
673 iter->
stack.push({&nodes[
node->children_offset_ + 1],
false});
674 iter->
stack.push({&nodes[
node->children_offset_],
false});
684 while (!iter->
stack.is_empty()) {
690 if (
node ==
nullptr) {
705 iter->
stack.push({&nodes[
node->children_offset_ + 1],
false});
706 iter->
stack.push({&nodes[
node->children_offset_],
false});
728 tree->left = new_node;
736 tree->right = new_node;
749 hit_fn(*
tree->data, tmin);
760 tree->left =
nullptr;
765 tree->right =
nullptr;
799 new_node->
left =
nullptr;
800 new_node->
right =
nullptr;
830 const Object &object_eval)
833 const Mesh &mesh_orig = *
static_cast<const Mesh *
>(object_orig.
data);
838 return mesh_eval->runtime->vert_normals_true_cache;
846 return mesh_eval->runtime->vert_normals_true_cache;
855 return mesh_orig.
runtime->vert_normals_true_cache;
865 const Object &object_eval)
868 const Mesh &mesh_orig = *
static_cast<const Mesh *
>(object_orig.
data);
873 return mesh_eval->runtime->face_normals_true_cache;
881 return mesh_eval->runtime->face_normals_true_cache;
890 return mesh_orig.
runtime->face_normals_true_cache;
905 for (
const int i : face_indices) {
917 normals_calc_faces(positions, faces, corner_verts, face_indices.slice(range), face_normals);
938 for (
const int vert :
verts) {
940 for (
const int face : vert_to_face_map[vert]) {
941 normal += face_normals[face];
953 normals_calc_verts_simple(vert_to_face_map, face_normals, verts.slice(range), vert_normals);
999 for (
const int vert :
node.vert_indices_.as_span().drop_front(
node.unique_verts_num_)) {
1008 if (face_normals_cache.
is_dirty()) {
1009 face_normals_cache.ensure([&](Vector<float3> &r_data) {
1010 r_data.resize(faces.size());
1011 bke::mesh::normals_calc_faces(positions, faces, corner_verts, r_data);
1023 boundary_verts.reserve(boundary_faces.size());
1024 for (
const int face : boundary_faces) {
1025 boundary_verts.add_multiple(corner_verts.slice(
faces[face]));
1028 const Span<float3> face_normals = face_normals_cache.data();
1030 if (vert_normals_cache.is_dirty()) {
1032 r_data.resize(positions.size());
1034 positions,
faces, corner_verts, vert_to_face_map, face_normals, r_data);
1050 switch (this->
type()) {
1061 subdiv_ccg,
nodes, nodes_to_update, memory);
1093 for (
const int vert :
node.all_verts()) {
1096 node.bounds_ = bounds;
1102 for (
const int grid :
node.grids()) {
1107 node.bounds_ = bounds;
1113 for (
const BMVert *vert :
node.bm_unique_verts_) {
1116 for (
const BMVert *vert :
node.bm_other_verts_) {
1119 node.bounds_ = bounds;
1133 if (std::optional<int> parent =
nodes[i].parent()) {
1134 nodes_to_update.
add(*parent);
1138 while (!nodes_to_update.
is_empty()) {
1139 const int node_index = *nodes_to_update.
begin();
1140 nodes_to_update.
remove(node_index);
1149 const std::optional<int> parent =
node.parent();
1150 const bool bounds_changed =
node.bounds_.min != old_bounds.
min ||
1151 node.bounds_.max != old_bounds.
max;
1153 if (bounds_changed && parent) {
1154 nodes_to_update.
add(*parent);
1204 switch (this->
type()) {
1229 for (const int i : range) {
1230 nodes[i].bounds_orig_ = nodes[i].bounds_;
1240 const bool fully_masked = std::all_of(
1241 verts.begin(),
verts.end(), [&](
const int vert) { return mask[vert] == 1.0f; });
1242 const bool fully_unmasked = std::all_of(
1243 verts.begin(),
verts.end(), [&](
const int vert) { return mask[vert] <= 0.0f; });
1253 if (
mask.is_empty()) {
1255 nodes[i].flag_ &=
~Node::FullyMasked;
1267 bool fully_masked =
true;
1268 bool fully_unmasked =
true;
1269 for (
const int grid :
node.grids()) {
1271 fully_masked &=
mask == 1.0f;
1272 fully_unmasked &=
mask <= 0.0f;
1285 nodes[i].flag_ &=
~Node::FullyMasked;
1298 bool fully_masked =
true;
1299 bool fully_unmasked =
true;
1300 for (
const BMVert *vert :
node.bm_unique_verts_) {
1304 for (
const BMVert *vert :
node.bm_other_verts_) {
1318 nodes[i].flag_ &=
~Node::FullyMasked;
1332 const bool fully_hidden = std::all_of(
1333 verts.begin(),
verts.end(), [&](
const int vert) { return hide_vert[vert]; });
1355 const bool fully_hidden = std::none_of(
1356 node.prim_indices_.begin(),
node.prim_indices_.end(), [&](
const int grid) {
1357 return bits::any_bit_unset(grid_hidden[grid]);
1378 const bool unique_hidden = std::all_of(
1379 node.bm_unique_verts_.begin(),
node.bm_unique_verts_.end(), [&](
const BMVert *vert) {
1380 return BM_elem_flag_test(vert, BM_ELEM_HIDDEN);
1382 const bool other_hidden = std::all_of(
1383 node.bm_other_verts_.begin(),
node.bm_other_verts_.end(), [&](
const BMVert *vert) {
1384 return BM_elem_flag_test(vert, BM_ELEM_HIDDEN);
1403 switch (this->
type()) {
1405 const Mesh &
mesh = *
static_cast<const Mesh *
>(
object.data);
1424 int display_gridsize)
1426 const int gridarea = (gridsize - 1) * (gridsize - 1);
1428 return gridarea * grid_indices.
size();
1434 int depth1 = int(
log2(
double(gridsize) - 1.0) + DBL_EPSILON);
1435 int depth2 = int(
log2(
double(display_gridsize) - 1.0) + DBL_EPSILON);
1437 int skip = depth2 < depth1 ? 1 << (depth1 - depth2 - 1) : 1;
1440 for (
const int grid : grid_indices) {
1443 for (
int y = 0;
y < gridsize - skip;
y += skip) {
1444 for (
int x = 0;
x < gridsize - skip;
x += skip) {
1470 for (
const int grid : nodes[i].grids()) {
1471 faces_to_update[grid_to_face_map[grid]] =
true;
1481 if (nodes.is_empty()) {
1484 return nodes.first().bounds_;
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 r_orig_positions =
node.orig_positions_;
1607 r_orig_tris =
node.orig_tris_;
1630 const float3 &ray_normal,
1653 (depth_test < *depth)) ||
1655 (depth_test < *depth)))
1657 *depth = depth_test;
1673 (depth_test < *depth))
1675 *depth = depth_test;
1685 const float3 &ray_direction,
1692 const float *tri[3] = {v0, v1,
v2};
1694 for (
int i = 0, j = 2; i < 3; j = i++) {
1698 ray_origin, ray_direction, tri[i], tri[j], point_test, &depth_test);
1699 if (dist_sq_test < dist_sq_best || i == 0) {
1701 *r_depth = depth_test;
1702 dist_sq_best = dist_sq_test;
1705 return dist_sq_best;
1709 const float3 &ray_normal,
1722 ray_start, ray_normal, t0, t1, t2, co, &depth_test)) < *dist_sq)
1724 *dist_sq = dist_sq_test;
1725 *r_depth = depth_test;
1727 ray_start, ray_normal, t0, t2, t3, co, &depth_test)) < *dist_sq)
1729 *dist_sq = dist_sq_test;
1730 *r_depth = depth_test;
1739 const float3 &ray_normal,
1751 ray_start, ray_normal, t0, t1, t2, co, &depth_test)) < *dist_sq)
1753 *dist_sq = dist_sq_test;
1754 *r_depth = depth_test;
1764 const float3 &ray_normal,
1765 const int face_index,
1766 const int tri_index,
1767 const std::array<const float *, 3> co,
1769 int &r_active_vertex,
1770 int &r_active_face_index,
1774 float3 nearest_vertex_co(0.0f);
1777 const float3 location = ray_start + ray_normal * depth;
1778 for (
int i = 0; i < co.size(); i++) {
1785 nearest_vertex_co = co[i];
1786 r_active_vertex = corner_verts[corner_tris[tri_index][i]];
1787 r_active_face_index = face_index;
1800 const float3 &ray_normal,
1803 int &r_active_vertex,
1804 int &r_active_face_index,
1812 const int face_i = face_indices[i];
1813 if (!hide_poly.
is_empty() && hide_poly[face_i]) {
1818 const int3 &tri = corner_tris[tri_i];
1819 const std::array<const float *, 3> co{{vert_positions[corner_verts[tri[0]]],
1820 vert_positions[corner_verts[tri[1]]],
1821 vert_positions[corner_verts[tri[2]]]}};
1833 r_active_face_index,
1842 const int face_i = face_indices[i];
1843 if (!hide_poly.
is_empty() && hide_poly[face_i]) {
1848 const int3 &tri = corner_tris[tri_i];
1849 const std::array<const float *, 3> co{
1850 {node_positions[vert_map.
index_of(corner_verts[tri[0]])],
1851 node_positions[vert_map.
index_of(corner_verts[tri[1]])],
1852 node_positions[vert_map.
index_of(corner_verts[tri[2]])]}};
1864 r_active_face_index,
1875 const float3 &ray_normal,
1879 const std::array<const float *, 4> co,
1882 int &r_active_grid_index,
1886 float3 nearest_vertex_co;
1889 const float3 location = ray_start + ray_normal * depth;
1891 constexpr short x_it[4] = {0, 1, 1, 0};
1892 constexpr short y_it[4] = {1, 1, 0, 0};
1894 for (
int i = 0; i < co.size(); i++) {
1902 r_active_vertex =
SubdivCCGCoord{grid, short(
x + x_it[i]), short(
y + y_it[i])};
1905 r_active_grid_index = grid;
1912 const float3 &ray_normal,
1916 int &r_active_grid_index,
1921 const int grid_size =
key.grid_size;
1927 for (
const int grid : grids) {
1936 const std::array<const float *, 4> co{
1942 ray_start, isect_precalc, co[0], co[1], co[2], co[3], depth))
1953 r_active_grid_index,
1962 const int grid = grids[i];
1971 const std::array<const float *, 4> co{grid_positions[(
y + 1) * grid_size +
x],
1972 grid_positions[(
y + 1) * grid_size +
x + 1],
1973 grid_positions[
y * grid_size +
x + 1],
1974 grid_positions[
y * grid_size +
x]};
1976 ray_start, isect_precalc, co[0], co[1], co[2], co[3], depth))
1987 r_active_grid_index,
1999 Tree &pbvh,
bool original,
float ray_start[3],
float ray_end[3],
float ray_normal[3])
2004 float rootmin_start, rootmin_end;
2006 float bb_center[3], bb_diff[3];
2008 float ray_normal_inv[3];
2009 float offset = 1.0f + 1e-3f;
2010 const float offset_vec[3] = {1e-3f, 1e-3f, 1e-3f};
2040 float dist =
max[2] -
min[2];
2073 float epsilon = (std::nextafter(rootmin_start, rootmin_start + 1000.0f) - rootmin_start) *
2076 if (rootmin_start == rootmin_end) {
2077 rootmin_start -= epsilon;
2078 rootmin_end += epsilon;
2089 const bool original)
2091 const float *bb_min, *bb_max;
2095 bb_min =
node->bounds_orig_.min;
2096 bb_max =
node->bounds_orig_.max;
2099 bb_min =
node->bounds_.min;
2100 bb_max =
node->bounds_.max;
2103 float co_dummy[3], depth;
2105 &dist_ray_to_aabb_precalc, bb_min, bb_max, co_dummy, &depth);
2107 return depth > 0.0f;
2113 const float3 &ray_normal,
2114 const bool original)
2133 const float3 &ray_normal,
2142 const int face_i = face_indices[i];
2143 if (!hide_poly.
is_empty() && hide_poly[face_i]) {
2148 const int3 &corner_tri = corner_tris[tri_i];
2151 vert_positions[corner_verts[corner_tri[0]]],
2152 vert_positions[corner_verts[corner_tri[1]]],
2153 vert_positions[corner_verts[corner_tri[2]]],
2162 const int face_i = face_indices[i];
2163 if (!hide_poly.
is_empty() && hide_poly[face_i]) {
2168 const int3 &corner_tri = corner_tris[tri_i];
2171 node_positions[vert_map.
index_of(corner_verts[corner_tri[0]])],
2172 node_positions[vert_map.
index_of(corner_verts[corner_tri[1]])],
2173 node_positions[vert_map.
index_of(corner_verts[corner_tri[2]])],
2186 const float ray_start[3],
2187 const float ray_normal[3],
2193 const int grid_size =
key.grid_size;
2199 for (
const int grid : grids) {
2223 const int grid = grids[i];
2234 grid_positions[
y * grid_size +
x],
2235 grid_positions[
y * grid_size +
x + 1],
2236 grid_positions[(
y + 1) * grid_size +
x + 1],
2237 grid_positions[(
y + 1) * grid_size +
x],
2258 const float ray_start[3],
2259 const float ray_normal[3],
2266 switch (pbvh.
type()) {
2289 static_cast<BMeshNode &
>(
node), ray_start, ray_normal, depth, dist_sq, use_origco);
2311 for (
const int i : frustum_planes.
index_range()) {
2312 float vmin[3], vmax[3];
2314 for (
int axis = 0; axis < 3; axis++) {
2315 if (frustum_planes[i][axis] < 0) {
2316 vmin[axis] = bounds.
min[axis];
2317 vmax[axis] = bounds.
max[axis];
2320 vmin[axis] = bounds.
max[axis];
2321 vmax[axis] = bounds.
min[axis];
2325 if (
dot_v3v3(frustum_planes[i], vmin) + frustum_planes[i][3] < 0) {
2328 if (
dot_v3v3(frustum_planes[i], vmax) + frustum_planes[i][3] <= 0) {
2362 const Mesh &mesh_orig = *
static_cast<const Mesh *
>(object_orig.
data);
2367 return mesh_eval->vert_positions();
2375 return mesh_eval->vert_positions();
2384 return mesh_orig.vert_positions();
2389 Mesh &mesh_orig = *
static_cast<Mesh *
>(object_orig.
data);
2394 Mesh *mesh_eval_mut =
const_cast<Mesh *
>(mesh_eval);
2395 return mesh_eval_mut->vert_positions_for_write();
2403 Mesh *mesh_eval_mut =
const_cast<Mesh *
>(mesh_eval);
2404 return mesh_eval_mut->vert_positions_for_write();
2413 return mesh_orig.vert_positions_for_write();
2459 return node.debug_draw_gen_;
2507 const OffsetIndices
faces =
mesh.faces();
2509 IndexMaskMemory memory;
2510 const IndexMask hidden_faces =
2518 face.
begin(), face.
end(), [&](
const int corner) {
2519 return grid_hidden[corner][key.grid_area - 1];
2525 if (hidden_faces.is_empty()) {
2526 attributes.
remove(
".hide_poly");
2531 hide_poly.
span.fill(
false);
2547 [&](
const auto &nodes) {
2549 nodes.index_range(),
GrainSize(1024), memory, [&](
const int i) {
2571 if (
node->flag_ & leaf_flag) {
2587 [&](
const auto &pbvh_nodes) {
2588 using VectorT = std::decay_t<
decltype(pbvh_nodes)>;
2590 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 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
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
void reinitialize(const int64_t new_size)
constexpr Iterator end() const
constexpr Iterator begin() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
void reserve(const int64_t n)
bool remove(const Key &key)
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
void add_multiple(Span< Key > keys)
int64_t index_of(const Key &key) const
void append(const T &value)
IndexRange index_range() const
void resize(const int64_t new_size)
void resize(const int64_t new_size_in_bits, const bool value=false)
GAttributeReader lookup(const StringRef attribute_id) const
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
bool remove(const StringRef attribute_id)
const Bounds< float3 > & bounds() const
const Bounds< float3 > & bounds_orig() const
void update_normals(Object &object_orig, Object &object_eval)
void tag_attribute_changed(const IndexMask &node_mask, StringRef attribute_name)
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)
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()
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
const Depsgraph * depsgraph
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
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)
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 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)
static void free_tree(node_tree *tree)
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)
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)
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)
static bool ray_aabb_intersect(Node &node, const RaycastData &rcd)
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 traverse_tree(node_tree *tree, const FunctionRef< void(Node &node, float *tmin)> hit_fn, float *tmin)
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)
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)
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 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)
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)
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)
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)
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)
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
#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