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,
227 for (
const int vert : face_verts.
slice(1, face_verts.
size() - 1)) {
235#ifdef DEBUG_BUILD_TIME
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();
270 pbvh.prim_indices_.reinitialize(
faces.size());
276#ifdef DEBUG_BUILD_TIME
285 pbvh.tag_positions_changed(
nodes.index_range());
287 pbvh.update_bounds_mesh(vert_positions);
292 for (const int i : range) {
293 node_update_visibility_mesh(hide_vert, nodes[i]);
305 const int node_index,
306 const int parent_index,
320 if (below_leaf_limit) {
329 nodes[node_index].children_offset_ =
nodes.size();
333 if (!below_leaf_limit) {
335 if (bounds_precalc) {
344 for (
const int face :
faces.slice(range)) {
365 nodes[node_index].children_offset_,
374 nodes[node_index].children_offset_ + 1,
397#ifdef DEBUG_BUILD_TIME
402 if (
faces.is_empty()) {
415 constexpr int base_limit = 800;
425 for (
const int face : range) {
427 face_centers[face] =
bounds.center();
443#ifdef DEBUG_BUILD_TIME
451 pbvh.prim_indices_.reinitialize(
faces.total_size());
454 for (
const int i :
nodes.index_range()) {
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_);
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);
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_);
548 for (Node &node :
nodes) {
561 bounds_dirty_.resize(std::max(bounds_dirty_.size(), node_mask.
min_array_size()),
false);
562 normals_dirty_.resize(std::max(normals_dirty_.size(), node_mask.
min_array_size()),
false);
566 this->
draw_data->tag_positions_changed(node_mask);
572 visibility_dirty_.resize(std::max(visibility_dirty_.size(), node_mask.
min_array_size()),
false);
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_);
642 while (!iter->
stack.is_empty()) {
649 if (node ==
nullptr) {
658 if (iter->
scb && !iter->
scb(*node)) {
662 if (node->
flag_ & leaf_flag) {
668 iter->
stack.push({node,
true});
684 while (!iter->
stack.is_empty()) {
690 if (node ==
nullptr) {
694 if (iter->
scb && !iter->
scb(*node)) {
728 tree->left = new_node;
736 tree->right = new_node;
749 hit_fn(*
tree->data, tmin);
760 tree->left =
nullptr;
765 tree->right =
nullptr;
778namespace blender::bke::pbvh {
797 new_node->
data = node;
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);
1008 if (face_normals_cache.
is_dirty()) {
1024 for (
const int face : boundary_faces) {
1030 if (vert_normals_cache.
is_dirty()) {
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);
1070 normals_dirty_.clear_and_shrink();
1077 pbvh.update_normals(object_orig, object_eval);
1087 pbvh.update_normals(object_orig, object_eval);
1093 for (
const int vert : node.
all_verts()) {
1102 for (
const int grid : node.
grids()) {
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);
1142 auto &node =
nodes[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);
1159 bounds_dirty_.clear_and_shrink();
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()) {
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;
1298 bool fully_masked =
true;
1299 bool fully_unmasked =
true;
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(
1357 return bits::any_bit_unset(grid_hidden[grid]);
1378 const bool unique_hidden = std::all_of(
1380 return BM_elem_flag_test(vert, BM_ELEM_HIDDEN);
1382 const bool other_hidden = std::all_of(
1384 return BM_elem_flag_test(vert, BM_ELEM_HIDDEN);
1402 visibility_dirty_.clear_and_shrink();
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_;
1581namespace blender::bke::pbvh {
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();
1612namespace blender::bke::pbvh {
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++) {
1905 r_active_grid_index = grid;
1912 const float3 &ray_normal,
1916 int &r_active_grid_index,
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;
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],
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);
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) {
2353 pbvh.update_bounds_mesh(vert_positions);
2357namespace blender::bke::pbvh {
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();
2518 face.
begin(), face.
end(), [&](
const int corner) {
2519 return grid_hidden[corner][key.grid_area - 1];
2526 attributes.
remove(
".hide_poly");
2531 hide_poly.
span.fill(
false);
2542namespace blender::bke::pbvh {
2547 [&](
const auto &
nodes) {
2571 if (node->
flag_ & leaf_flag) {
2587 [&](
const auto &pbvh_nodes) {
2588 using VectorT = std::decay_t<
decltype(pbvh_nodes)>;
2589 for (
const int i :
nodes.index_range()) {
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
BPy_StructRNA * depsgraph
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 const T & first() 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)
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, eCustomDataType 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
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 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)
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)
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)
#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
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