Cleanup: Make paint BVH update tags proper private members
Move some functions to be methods of pbvh::Tree instead. Pull Request: https://projects.blender.org/blender/blender/pulls/133989
This commit is contained in:
@@ -226,9 +226,6 @@ class Tree {
|
||||
/** Memory backing for #Node::prim_indices. Without an inline buffer to make #Tree movable. */
|
||||
Array<int, 0> prim_indices_;
|
||||
|
||||
public:
|
||||
std::variant<Vector<MeshNode>, Vector<GridsNode>, Vector<BMeshNode>> nodes_;
|
||||
|
||||
/**
|
||||
* If true, the bounds for the corresponding node index is out of date.
|
||||
* \note Values are only meaningful for leaf nodes.
|
||||
@@ -250,6 +247,9 @@ class Tree {
|
||||
*/
|
||||
BitVector<> visibility_dirty_;
|
||||
|
||||
public:
|
||||
std::variant<Vector<MeshNode>, Vector<GridsNode>, Vector<BMeshNode>> nodes_;
|
||||
|
||||
pixels::PBVHData *pixels_ = nullptr;
|
||||
|
||||
std::unique_ptr<DrawCache> draw_data;
|
||||
@@ -273,7 +273,7 @@ class Tree {
|
||||
|
||||
Type type() const
|
||||
{
|
||||
return this->type_;
|
||||
return type_;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -302,6 +302,26 @@ class Tree {
|
||||
*/
|
||||
void tag_attribute_changed(const IndexMask &node_mask, StringRef attribute_name);
|
||||
|
||||
/**
|
||||
* Run the last step of the BVH bounds recalculation process, propagating updated leaf node
|
||||
* bounds to their parent/ancestor inner nodes. This is meant to be used after leaf node bounds
|
||||
* have been computed separately.
|
||||
*/
|
||||
void flush_bounds_to_parents();
|
||||
|
||||
/**
|
||||
* Recalculate node bounding boxes based on the current coordinates. Calculation is only done for
|
||||
* affected nodes that have been tagged by #PBVH::tag_positions_changed().
|
||||
*/
|
||||
void update_bounds(const Depsgraph &depsgraph, const Object &object);
|
||||
void update_bounds_mesh(Span<float3> vert_positions);
|
||||
void update_bounds_grids(Span<float3> positions, int grid_area);
|
||||
void update_bounds_bmesh(const BMesh &bm);
|
||||
|
||||
void update_normals(Object &object_orig, Object &object_eval);
|
||||
|
||||
void update_visibility(const Object &object);
|
||||
|
||||
private:
|
||||
explicit Tree(Type type);
|
||||
};
|
||||
@@ -505,15 +525,6 @@ void BKE_pbvh_bmesh_after_stroke(BMesh &bm, blender::bke::pbvh::Tree &pbvh);
|
||||
|
||||
namespace blender::bke::pbvh {
|
||||
|
||||
/**
|
||||
* Recalculate node bounding boxes based on the current coordinates. Calculation is only done for
|
||||
* affected nodes that have been tagged by #PBVH::tag_positions_changed().
|
||||
*/
|
||||
void update_bounds(const Depsgraph &depsgraph, const Object &object, Tree &pbvh);
|
||||
void update_bounds_mesh(Span<float3> vert_positions, Tree &pbvh);
|
||||
void update_bounds_grids(const CCGKey &key, Span<float3> positions, Tree &pbvh);
|
||||
void update_bounds_bmesh(const BMesh &bm, Tree &pbvh);
|
||||
|
||||
/**
|
||||
* Copy all current node bounds to the original bounds. "Original" bounds are typically from before
|
||||
* a brush stroke started (while the "regular" bounds update on every change of positions). These
|
||||
@@ -527,7 +538,6 @@ void update_mask_mesh(const Mesh &mesh, const IndexMask &node_mask, Tree &pbvh);
|
||||
void update_mask_grids(const SubdivCCG &subdiv_ccg, const IndexMask &node_mask, Tree &pbvh);
|
||||
void update_mask_bmesh(const BMesh &bm, const IndexMask &node_mask, Tree &pbvh);
|
||||
|
||||
void update_visibility(const Object &object, Tree &pbvh);
|
||||
void update_normals(const Depsgraph &depsgraph, Object &object_orig, Tree &pbvh);
|
||||
/** Update geometry normals (potentially on the original object geometry). */
|
||||
void update_normals_from_eval(Object &object_eval, Tree &pbvh);
|
||||
@@ -602,13 +612,6 @@ void update_node_bounds_mesh(Span<float3> positions, MeshNode &node);
|
||||
void update_node_bounds_grids(int grid_area, Span<float3> positions, GridsNode &node);
|
||||
void update_node_bounds_bmesh(BMeshNode &node);
|
||||
|
||||
/**
|
||||
* Run the last step of the BVH bounds recalculation process, propagating updated leaf node bounds
|
||||
* to their parent/ancestor inner nodes. This is meant to be used after leaf node bounds have been
|
||||
* computed separately.
|
||||
*/
|
||||
void flush_bounds_to_parents(Tree &pbvh);
|
||||
|
||||
inline Span<int> MeshNode::faces() const
|
||||
{
|
||||
return this->face_indices_;
|
||||
|
||||
@@ -273,7 +273,7 @@ Tree Tree::from_mesh(const Mesh &mesh)
|
||||
|
||||
pbvh.tag_positions_changed(nodes.index_range());
|
||||
|
||||
update_bounds_mesh(vert_positions, pbvh);
|
||||
pbvh.update_bounds_mesh(vert_positions);
|
||||
store_bounds_orig(pbvh);
|
||||
|
||||
if (!hide_vert.is_empty()) {
|
||||
@@ -457,7 +457,7 @@ Tree Tree::from_grids(const Mesh &base_mesh, const SubdivCCG &subdiv_ccg)
|
||||
|
||||
pbvh.tag_positions_changed(nodes.index_range());
|
||||
|
||||
update_bounds_grids(key, positions, pbvh);
|
||||
pbvh.update_bounds_grids(positions, key.grid_area);
|
||||
store_bounds_orig(pbvh);
|
||||
|
||||
const BitGroupVector<> &grid_hidden = subdiv_ccg.grid_hidden;
|
||||
@@ -536,12 +536,10 @@ Tree::~Tree()
|
||||
|
||||
void Tree::tag_positions_changed(const IndexMask &node_mask)
|
||||
{
|
||||
this->bounds_dirty_.resize(std::max(this->bounds_dirty_.size(), node_mask.min_array_size()),
|
||||
false);
|
||||
this->normals_dirty_.resize(std::max(this->normals_dirty_.size(), node_mask.min_array_size()),
|
||||
false);
|
||||
node_mask.set_bits(this->bounds_dirty_);
|
||||
node_mask.set_bits(this->normals_dirty_);
|
||||
bounds_dirty_.resize(std::max(bounds_dirty_.size(), node_mask.min_array_size()), false);
|
||||
normals_dirty_.resize(std::max(normals_dirty_.size(), node_mask.min_array_size()), false);
|
||||
node_mask.set_bits(bounds_dirty_);
|
||||
node_mask.set_bits(normals_dirty_);
|
||||
if (this->draw_data) {
|
||||
this->draw_data->tag_positions_changed(node_mask);
|
||||
}
|
||||
@@ -549,9 +547,8 @@ void Tree::tag_positions_changed(const IndexMask &node_mask)
|
||||
|
||||
void Tree::tag_visibility_changed(const IndexMask &node_mask)
|
||||
{
|
||||
this->visibility_dirty_.resize(std::max(this->bounds_dirty_.size(), node_mask.min_array_size()),
|
||||
false);
|
||||
node_mask.set_bits(this->visibility_dirty_);
|
||||
visibility_dirty_.resize(std::max(visibility_dirty_.size(), node_mask.min_array_size()), false);
|
||||
node_mask.set_bits(visibility_dirty_);
|
||||
if (this->draw_data) {
|
||||
this->draw_data->tag_visibility_changed(node_mask);
|
||||
}
|
||||
@@ -1015,20 +1012,20 @@ static void update_normals_mesh(Object &object_orig,
|
||||
}
|
||||
}
|
||||
|
||||
static void update_normals(Object &object_orig, Object &object_eval, Tree &pbvh)
|
||||
void Tree::update_normals(Object &object_orig, Object &object_eval)
|
||||
{
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask nodes_to_update = IndexMask::from_bits(pbvh.normals_dirty_, memory);
|
||||
const IndexMask nodes_to_update = IndexMask::from_bits(normals_dirty_, memory);
|
||||
|
||||
switch (pbvh.type()) {
|
||||
switch (this->type()) {
|
||||
case Type::Mesh: {
|
||||
update_normals_mesh(object_orig, object_eval, pbvh.nodes<MeshNode>(), nodes_to_update);
|
||||
update_normals_mesh(object_orig, object_eval, this->nodes<MeshNode>(), nodes_to_update);
|
||||
break;
|
||||
}
|
||||
case Type::Grids: {
|
||||
SculptSession &ss = *object_orig.sculpt;
|
||||
SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
|
||||
MutableSpan<GridsNode> nodes = pbvh.nodes<GridsNode>();
|
||||
MutableSpan<GridsNode> nodes = this->nodes<GridsNode>();
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask faces_to_update = nodes_to_face_selection_grids(
|
||||
subdiv_ccg, nodes, nodes_to_update, memory);
|
||||
@@ -1036,18 +1033,18 @@ static void update_normals(Object &object_orig, Object &object_eval, Tree &pbvh)
|
||||
break;
|
||||
}
|
||||
case Type::BMesh: {
|
||||
bmesh_normals_update(pbvh, nodes_to_update);
|
||||
bmesh_normals_update(*this, nodes_to_update);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pbvh.normals_dirty_.clear_and_shrink();
|
||||
normals_dirty_.clear_and_shrink();
|
||||
}
|
||||
|
||||
void update_normals(const Depsgraph &depsgraph, Object &object_orig, Tree &pbvh)
|
||||
{
|
||||
BLI_assert(DEG_is_original_object(&object_orig));
|
||||
Object &object_eval = *DEG_get_evaluated_object(&depsgraph, &object_orig);
|
||||
update_normals(object_orig, object_eval, pbvh);
|
||||
pbvh.update_normals(object_orig, object_eval);
|
||||
}
|
||||
|
||||
void update_normals_from_eval(Object &object_eval, Tree &pbvh)
|
||||
@@ -1057,7 +1054,7 @@ void update_normals_from_eval(Object &object_eval, Tree &pbvh)
|
||||
* their result), and also because (currently) sculpt deformations skip tagging the mesh normals
|
||||
* caches dirty. */
|
||||
Object &object_orig = *DEG_get_original_object(&object_eval);
|
||||
update_normals(object_orig, object_eval, pbvh);
|
||||
pbvh.update_normals(object_orig, object_eval);
|
||||
}
|
||||
|
||||
void update_node_bounds_mesh(const Span<float3> positions, MeshNode &node)
|
||||
@@ -1117,75 +1114,74 @@ static BoundsMergeInfo merge_child_bounds(MutableSpan<NodeT> nodes,
|
||||
return {node.bounds_, update};
|
||||
}
|
||||
|
||||
void flush_bounds_to_parents(Tree &pbvh)
|
||||
void Tree::flush_bounds_to_parents()
|
||||
{
|
||||
std::visit(
|
||||
[&](auto &nodes) {
|
||||
nodes.first().bounds_ =
|
||||
merge_child_bounds(nodes.as_mutable_span(), pbvh.bounds_dirty_, 0).bounds;
|
||||
merge_child_bounds(nodes.as_mutable_span(), bounds_dirty_, 0).bounds;
|
||||
},
|
||||
pbvh.nodes_);
|
||||
pbvh.bounds_dirty_.clear_and_shrink();
|
||||
this->nodes_);
|
||||
bounds_dirty_.clear_and_shrink();
|
||||
}
|
||||
|
||||
void update_bounds_mesh(const Span<float3> vert_positions, Tree &pbvh)
|
||||
void Tree::update_bounds_mesh(const Span<float3> vert_positions)
|
||||
{
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask nodes_to_update = IndexMask::from_bits(pbvh.bounds_dirty_, memory);
|
||||
const IndexMask nodes_to_update = IndexMask::from_bits(bounds_dirty_, memory);
|
||||
if (nodes_to_update.is_empty()) {
|
||||
return;
|
||||
}
|
||||
MutableSpan<MeshNode> nodes = pbvh.nodes<MeshNode>();
|
||||
MutableSpan<MeshNode> nodes = this->nodes<MeshNode>();
|
||||
nodes_to_update.foreach_index(
|
||||
GrainSize(1), [&](const int i) { update_node_bounds_mesh(vert_positions, nodes[i]); });
|
||||
flush_bounds_to_parents(pbvh);
|
||||
this->flush_bounds_to_parents();
|
||||
}
|
||||
|
||||
void update_bounds_grids(const CCGKey &key, const Span<float3> positions, Tree &pbvh)
|
||||
void Tree::update_bounds_grids(const Span<float3> positions, const int grid_area)
|
||||
{
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask nodes_to_update = IndexMask::from_bits(pbvh.bounds_dirty_, memory);
|
||||
const IndexMask nodes_to_update = IndexMask::from_bits(bounds_dirty_, memory);
|
||||
if (nodes_to_update.is_empty()) {
|
||||
return;
|
||||
}
|
||||
MutableSpan<GridsNode> nodes = pbvh.nodes<GridsNode>();
|
||||
MutableSpan<GridsNode> nodes = this->nodes<GridsNode>();
|
||||
nodes_to_update.foreach_index(GrainSize(1), [&](const int i) {
|
||||
update_node_bounds_grids(key.grid_area, positions, nodes[i]);
|
||||
update_node_bounds_grids(grid_area, positions, nodes[i]);
|
||||
});
|
||||
flush_bounds_to_parents(pbvh);
|
||||
this->flush_bounds_to_parents();
|
||||
}
|
||||
|
||||
void update_bounds_bmesh(const BMesh & /*bm*/, Tree &pbvh)
|
||||
void Tree::update_bounds_bmesh(const BMesh & /*bm*/)
|
||||
{
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask nodes_to_update = IndexMask::from_bits(pbvh.bounds_dirty_, memory);
|
||||
const IndexMask nodes_to_update = IndexMask::from_bits(bounds_dirty_, memory);
|
||||
if (nodes_to_update.is_empty()) {
|
||||
return;
|
||||
}
|
||||
MutableSpan<BMeshNode> nodes = pbvh.nodes<BMeshNode>();
|
||||
MutableSpan<BMeshNode> nodes = this->nodes<BMeshNode>();
|
||||
nodes_to_update.foreach_index(GrainSize(1),
|
||||
[&](const int i) { update_node_bounds_bmesh(nodes[i]); });
|
||||
flush_bounds_to_parents(pbvh);
|
||||
this->flush_bounds_to_parents();
|
||||
}
|
||||
|
||||
void update_bounds(const Depsgraph &depsgraph, const Object &object, Tree &pbvh)
|
||||
void Tree::update_bounds(const Depsgraph &depsgraph, const Object &object)
|
||||
{
|
||||
switch (pbvh.type()) {
|
||||
switch (this->type()) {
|
||||
case Type::Mesh: {
|
||||
const Span<float3> positions = bke::pbvh::vert_positions_eval(depsgraph, object);
|
||||
update_bounds_mesh(positions, pbvh);
|
||||
this->update_bounds_mesh(positions);
|
||||
break;
|
||||
}
|
||||
case Type::Grids: {
|
||||
const SculptSession &ss = *object.sculpt;
|
||||
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
|
||||
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
|
||||
update_bounds_grids(key, subdiv_ccg.positions, pbvh);
|
||||
this->update_bounds_grids(subdiv_ccg.positions, subdiv_ccg.grid_area);
|
||||
break;
|
||||
}
|
||||
case Type::BMesh: {
|
||||
const SculptSession &ss = *object.sculpt;
|
||||
update_bounds_bmesh(*ss.bm, pbvh);
|
||||
this->update_bounds_bmesh(*ss.bm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1362,27 +1358,27 @@ static void update_visibility_bmesh(const MutableSpan<BMeshNode> nodes, const In
|
||||
[&](const int i) { node_update_visibility_bmesh(nodes[i]); });
|
||||
}
|
||||
|
||||
void update_visibility(const Object &object, Tree &pbvh)
|
||||
void Tree::update_visibility(const Object &object)
|
||||
{
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask node_mask = IndexMask::from_bits(pbvh.visibility_dirty_, memory);
|
||||
const IndexMask node_mask = IndexMask::from_bits(visibility_dirty_, memory);
|
||||
if (node_mask.is_empty()) {
|
||||
return;
|
||||
}
|
||||
pbvh.visibility_dirty_.clear_and_shrink();
|
||||
switch (pbvh.type()) {
|
||||
visibility_dirty_.clear_and_shrink();
|
||||
switch (this->type()) {
|
||||
case Type::Mesh: {
|
||||
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
|
||||
update_visibility_faces(mesh, pbvh.nodes<MeshNode>(), node_mask);
|
||||
update_visibility_faces(mesh, this->nodes<MeshNode>(), node_mask);
|
||||
break;
|
||||
}
|
||||
case Type::Grids: {
|
||||
const SculptSession &ss = *object.sculpt;
|
||||
update_visibility_grids(*ss.subdiv_ccg, pbvh.nodes<GridsNode>(), node_mask);
|
||||
update_visibility_grids(*ss.subdiv_ccg, this->nodes<GridsNode>(), node_mask);
|
||||
break;
|
||||
}
|
||||
case Type::BMesh: {
|
||||
update_visibility_bmesh(pbvh.nodes<BMeshNode>(), node_mask);
|
||||
update_visibility_bmesh(this->nodes<BMeshNode>(), node_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2356,7 +2352,7 @@ void BKE_pbvh_vert_coords_apply(blender::bke::pbvh::Tree &pbvh,
|
||||
{
|
||||
using namespace blender::bke::pbvh;
|
||||
pbvh.tag_positions_changed(blender::IndexRange(pbvh.nodes_num()));
|
||||
update_bounds_mesh(vert_positions, pbvh);
|
||||
pbvh.update_bounds_mesh(vert_positions);
|
||||
store_bounds_orig(pbvh);
|
||||
}
|
||||
|
||||
|
||||
@@ -2262,7 +2262,7 @@ Tree Tree::from_bmesh(BMesh &bm)
|
||||
nodes, cd_vert_node_offset, cd_face_node_offset, nodeinfo, face_bounds, &rootnode, 0);
|
||||
|
||||
pbvh.tag_positions_changed(nodes.index_range());
|
||||
update_bounds_bmesh(bm, pbvh);
|
||||
pbvh.update_bounds_bmesh(bm);
|
||||
store_bounds_orig(pbvh);
|
||||
|
||||
threading::parallel_for(nodes.index_range(), 8, [&](const IndexRange range) {
|
||||
|
||||
Reference in New Issue
Block a user