Sculpt: Extract bounds calculation from BVH build, parallelize

This applies the same change as the previous commit to the bounds
of every BVH node. The bounds calculation can be changed to use
the standard functions from the regular BVH deformation.

In a simple test this makes building the sculpt BVH 64% faster.
I observed a change from 762ms to 464ms for a 1.9m vertex mesh.
This commit is contained in:
Hans Goudey
2024-07-23 23:08:00 -04:00
parent 8ab2a139ca
commit f9c6fe30db

View File

@@ -238,22 +238,10 @@ static void build_mesh_leaf_node(const Span<int> corner_verts,
}
}
BKE_pbvh_node_mark_positions_update(node);
BKE_pbvh_node_mark_rebuild_draw(node);
}
static void update_vb(const Span<int> prim_indices,
Node *node,
const Span<Bounds<float3>> prim_bounds,
int offset,
int count)
{
node->bounds_ = prim_bounds[prim_indices[offset]];
for (const int i : IndexRange(offset, count).drop_front(1)) {
node->bounds_ = bounds::merge(node->bounds_, prim_bounds[prim_indices[i]]);
}
node->bounds_orig_ = node->bounds_;
}
int count_grid_quads(const BitGroupVector<> &grid_hidden,
const Span<int> grid_indices,
int gridsize,
@@ -293,7 +281,6 @@ static void build_leaf(Tree &pbvh,
const Span<int3> corner_tris,
MutableSpan<bool> vert_bitmap,
int node_index,
const Span<Bounds<float3>> prim_bounds,
int offset,
int count)
{
@@ -302,13 +289,11 @@ static void build_leaf(Tree &pbvh,
node.prim_indices_ = pbvh.prim_indices_.as_span().slice(offset, count);
/* Still need vb for searches */
update_vb(pbvh.prim_indices_, &node, prim_bounds, offset, count);
if (!corner_tris.is_empty()) {
build_mesh_leaf_node(corner_verts, corner_tris, vert_bitmap, &node);
}
else {
BKE_pbvh_node_mark_positions_update(&node);
BKE_pbvh_node_mark_rebuild_draw(&node);
}
}
@@ -411,8 +396,7 @@ static void build_sub(Tree &pbvh,
if (!leaf_needs_material_split(
pbvh, prim_to_face_map, material_indices, sharp_faces, offset, count))
{
build_leaf(
pbvh, corner_verts, corner_tris, vert_bitmap, node_index, prim_bounds, offset, count);
build_leaf(pbvh, corner_verts, corner_tris, vert_bitmap, node_index, offset, count);
return;
}
@@ -422,9 +406,6 @@ static void build_sub(Tree &pbvh,
pbvh.nodes_[node_index].children_offset_ = pbvh.nodes_.size();
pbvh.nodes_.resize(pbvh.nodes_.size() + 2);
/* Update parent node bounding box */
update_vb(pbvh.prim_indices_, &pbvh.nodes_[node_index], prim_bounds, offset, count);
Bounds<float3> cb_backing;
if (!below_leaf_limit) {
/* Find axis with widest range of primitive centroids */
@@ -669,6 +650,9 @@ std::unique_ptr<Tree> build_mesh(Mesh *mesh)
prim_bounds,
corner_tris.size());
update_bounds(*pbvh);
store_bounds_orig(*pbvh);
if (!hide_vert.is_empty()) {
MutableSpan<Node> nodes = pbvh->nodes_;
threading::parallel_for(nodes.index_range(), 8, [&](const IndexRange range) {
@@ -756,6 +740,9 @@ std::unique_ptr<Tree> build_grids(Mesh *mesh, SubdivCCG *subdiv_ccg)
prim_bounds,
grids.size());
update_bounds(*pbvh);
store_bounds_orig(*pbvh);
const BitGroupVector<> &grid_hidden = subdiv_ccg->grid_hidden;
if (!grid_hidden.is_empty()) {
MutableSpan<Node> nodes = pbvh->nodes_;