Sculpt: Only re-upload face set data when changed
Similar to the previous commit, previously all GPU buffers were recreated when only face sets changed. Now only face sets are re-uploaded, using the same mechanism. Part of #118145.
This commit is contained in:
@@ -177,6 +177,7 @@ class DrawCache {
|
||||
public:
|
||||
virtual ~DrawCache() = default;
|
||||
virtual void tag_positions_changed(const IndexMask &node_mask) = 0;
|
||||
virtual void tag_face_sets_changed(const IndexMask &node_mask) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -233,6 +234,9 @@ class Tree {
|
||||
* \warning Must not be called from multiple threads in parallel.
|
||||
*/
|
||||
void tag_positions_changed(const IndexMask &node_mask);
|
||||
|
||||
/** Tag nodes where face sets have changed, causing refresh of derived data. */
|
||||
void tag_face_sets_changed(const IndexMask &node_mask);
|
||||
};
|
||||
|
||||
} // namespace blender::bke::pbvh
|
||||
@@ -397,7 +401,6 @@ bool bmesh_update_topology(BMesh &bm,
|
||||
void BKE_pbvh_node_mark_update(blender::bke::pbvh::Node &node);
|
||||
void BKE_pbvh_node_mark_update_mask(blender::bke::pbvh::Node &node);
|
||||
void BKE_pbvh_node_mark_update_color(blender::bke::pbvh::Node &node);
|
||||
void BKE_pbvh_node_mark_update_face_sets(blender::bke::pbvh::Node &node);
|
||||
void BKE_pbvh_node_mark_update_visibility(blender::bke::pbvh::Node &node);
|
||||
void BKE_pbvh_node_mark_rebuild_draw(blender::bke::pbvh::Node &node);
|
||||
void BKE_pbvh_node_mark_redraw(blender::bke::pbvh::Node &node);
|
||||
|
||||
@@ -560,6 +560,13 @@ void Tree::tag_positions_changed(const IndexMask &node_mask)
|
||||
}
|
||||
}
|
||||
|
||||
void Tree::tag_face_sets_changed(const IndexMask &node_mask)
|
||||
{
|
||||
if (this->draw_data) {
|
||||
this->draw_data->tag_face_sets_changed(node_mask);
|
||||
}
|
||||
}
|
||||
|
||||
static bool tree_is_empty(const Tree &pbvh)
|
||||
{
|
||||
return std::visit([](const auto &nodes) { return nodes.is_empty(); }, pbvh.nodes_);
|
||||
@@ -1540,11 +1547,6 @@ void BKE_pbvh_node_mark_update_color(blender::bke::pbvh::Node &node)
|
||||
node.flag_ |= PBVH_UpdateColor | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
|
||||
}
|
||||
|
||||
void BKE_pbvh_node_mark_update_face_sets(blender::bke::pbvh::Node &node)
|
||||
{
|
||||
node.flag_ |= PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
|
||||
}
|
||||
|
||||
void BKE_pbvh_mark_rebuild_pixels(blender::bke::pbvh::Tree &pbvh)
|
||||
{
|
||||
std::visit(
|
||||
|
||||
@@ -140,6 +140,7 @@ class DrawCacheImpl : public DrawCache {
|
||||
|
||||
void tag_all_attributes_dirty(const IndexMask &node_mask) override;
|
||||
void tag_positions_changed(const IndexMask &node_mask) override;
|
||||
void tag_face_sets_changed(const IndexMask &node_mask) override;
|
||||
|
||||
Span<gpu::Batch *> ensure_tris_batches(const Object &object,
|
||||
const ViewportRequest &request,
|
||||
@@ -203,6 +204,13 @@ void DrawCacheImpl::tag_positions_changed(const IndexMask &node_mask)
|
||||
}
|
||||
}
|
||||
|
||||
void DrawCacheImpl::tag_face_sets_changed(const IndexMask &node_mask)
|
||||
{
|
||||
if (DrawCacheImpl::AttributeData *data = attribute_vbos_.lookup_ptr(CustomRequest::FaceSet)) {
|
||||
data->tag_dirty(node_mask);
|
||||
}
|
||||
}
|
||||
|
||||
DrawCache &ensure_draw_data(std::unique_ptr<bke::pbvh::DrawCache> &ptr)
|
||||
{
|
||||
if (!ptr) {
|
||||
|
||||
@@ -195,10 +195,9 @@ static void do_draw_face_sets_brush_mesh(const Depsgraph &depsgraph,
|
||||
face_indices,
|
||||
tls,
|
||||
face_sets.span);
|
||||
BKE_pbvh_node_mark_update_face_sets(nodes[i]);
|
||||
});
|
||||
});
|
||||
|
||||
pbvh.tag_face_sets_changed(node_mask);
|
||||
face_sets.finish();
|
||||
}
|
||||
|
||||
|
||||
@@ -1313,6 +1313,8 @@ static void restore_face_set_from_undo_step(Object &object)
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask node_mask = bke::pbvh::all_leaf_nodes(pbvh, memory);
|
||||
|
||||
Array<bool> node_changed(node_mask.min_array_size(), false);
|
||||
|
||||
switch (pbvh.type()) {
|
||||
case bke::pbvh::Type::Mesh: {
|
||||
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
|
||||
@@ -1323,7 +1325,7 @@ static void restore_face_set_from_undo_step(Object &object)
|
||||
nodes[i]))
|
||||
{
|
||||
scatter_data_mesh(*orig_data, nodes[i].faces(), attribute.span);
|
||||
BKE_pbvh_node_mark_update_face_sets(nodes[i]);
|
||||
node_changed[i] = true;
|
||||
}
|
||||
});
|
||||
attribute.finish();
|
||||
@@ -1343,7 +1345,7 @@ static void restore_face_set_from_undo_step(Object &object)
|
||||
const Span<int> faces = bke::pbvh::node_face_indices_calc_grids(
|
||||
subdiv_ccg, nodes[i], tls);
|
||||
scatter_data_mesh(*orig_data, faces, attribute.span);
|
||||
BKE_pbvh_node_mark_update_face_sets(nodes[i]);
|
||||
node_changed[i] = true;
|
||||
}
|
||||
});
|
||||
attribute.finish();
|
||||
@@ -1352,6 +1354,8 @@ static void restore_face_set_from_undo_step(Object &object)
|
||||
case bke::pbvh::Type::BMesh:
|
||||
break;
|
||||
}
|
||||
|
||||
pbvh.tag_face_sets_changed(IndexMask::from_bools(node_changed, memory));
|
||||
}
|
||||
|
||||
void restore_position_from_undo_step(const Depsgraph &depsgraph, Object &object)
|
||||
|
||||
@@ -1422,22 +1422,7 @@ static void restore_face_set_data(Object &object, Cache &expand_cache)
|
||||
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask node_mask = bke::pbvh::all_leaf_nodes(pbvh, memory);
|
||||
switch (pbvh.type()) {
|
||||
case bke::pbvh::Type::Mesh: {
|
||||
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
|
||||
node_mask.foreach_index([&](const int i) { BKE_pbvh_node_mark_update_face_sets(nodes[i]); });
|
||||
break;
|
||||
}
|
||||
case bke::pbvh::Type::Grids: {
|
||||
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
|
||||
node_mask.foreach_index([&](const int i) { BKE_pbvh_node_mark_update_face_sets(nodes[i]); });
|
||||
break;
|
||||
}
|
||||
case bke::pbvh::Type::BMesh: {
|
||||
BLI_assert_unreachable();
|
||||
break;
|
||||
}
|
||||
}
|
||||
pbvh.tag_face_sets_changed(node_mask);
|
||||
}
|
||||
|
||||
static void restore_color_data(Object &ob, Cache &expand_cache)
|
||||
@@ -1708,9 +1693,7 @@ static void face_sets_update(Object &object, Cache &expand_cache)
|
||||
face_sets.finish();
|
||||
|
||||
bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
|
||||
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
|
||||
expand_cache.node_mask.foreach_index(
|
||||
[&](const int i) { BKE_pbvh_node_mark_update_face_sets(nodes[i]); });
|
||||
pbvh.tag_face_sets_changed(expand_cache.node_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -294,6 +294,8 @@ static void face_sets_update(const Depsgraph &depsgraph,
|
||||
Vector<int> new_face_sets;
|
||||
};
|
||||
|
||||
Array<bool> node_changed(pbvh.nodes_num(), false);
|
||||
|
||||
threading::EnumerableThreadSpecific<TLS> all_tls;
|
||||
if (pbvh.type() == bke::pbvh::Type::Mesh) {
|
||||
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
|
||||
@@ -312,7 +314,7 @@ static void face_sets_update(const Depsgraph &depsgraph,
|
||||
|
||||
undo::push_node(depsgraph, object, &nodes[i], undo::Type::FaceSet);
|
||||
array_utils::scatter(new_face_sets.as_span(), faces, face_sets.span);
|
||||
BKE_pbvh_node_mark_update_face_sets(nodes[i]);
|
||||
node_changed[i] = true;
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -334,11 +336,13 @@ static void face_sets_update(const Depsgraph &depsgraph,
|
||||
|
||||
undo::push_node(depsgraph, object, &nodes[i], undo::Type::FaceSet);
|
||||
array_utils::scatter(new_face_sets.as_span(), faces, face_sets.span);
|
||||
BKE_pbvh_node_mark_update_face_sets(nodes[i]);
|
||||
node_changed[i] = true;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
IndexMaskMemory memory;
|
||||
pbvh.tag_face_sets_changed(IndexMask::from_bools(node_changed, memory));
|
||||
face_sets.finish();
|
||||
}
|
||||
|
||||
@@ -358,6 +362,9 @@ static void clear_face_sets(const Depsgraph &depsgraph, Object &object, const In
|
||||
}
|
||||
SculptSession &ss = *object.sculpt;
|
||||
bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
|
||||
|
||||
Array<bool> node_changed(pbvh.nodes_num(), false);
|
||||
|
||||
const int default_face_set = mesh.face_sets_color_default;
|
||||
const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
|
||||
if (pbvh.type() == bke::pbvh::Type::Mesh) {
|
||||
@@ -369,7 +376,7 @@ static void clear_face_sets(const Depsgraph &depsgraph, Object &object, const In
|
||||
}))
|
||||
{
|
||||
undo::push_node(depsgraph, object, &nodes[i], undo::Type::FaceSet);
|
||||
BKE_pbvh_node_mark_update_face_sets(nodes[i]);
|
||||
node_changed[i] = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -386,11 +393,13 @@ static void clear_face_sets(const Depsgraph &depsgraph, Object &object, const In
|
||||
}))
|
||||
{
|
||||
undo::push_node(depsgraph, object, &nodes[i], undo::Type::FaceSet);
|
||||
BKE_pbvh_node_mark_update_face_sets(nodes[i]);
|
||||
node_changed[i] = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
IndexMaskMemory memory;
|
||||
pbvh.tag_face_sets_changed(IndexMask::from_bools(node_changed, memory));
|
||||
attributes.remove(".sculpt_face_set");
|
||||
}
|
||||
|
||||
@@ -774,14 +783,7 @@ static int init_op_exec(bContext *C, wmOperator *op)
|
||||
|
||||
undo::push_end(ob);
|
||||
|
||||
if (pbvh.type() == bke::pbvh::Type::Mesh) {
|
||||
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
|
||||
node_mask.foreach_index([&](const int i) { BKE_pbvh_node_mark_redraw(nodes[i]); });
|
||||
}
|
||||
else if (pbvh.type() == bke::pbvh::Type::Grids) {
|
||||
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
|
||||
node_mask.foreach_index([&](const int i) { BKE_pbvh_node_mark_redraw(nodes[i]); });
|
||||
}
|
||||
pbvh.tag_face_sets_changed(node_mask);
|
||||
|
||||
SCULPT_tag_update_overlays(C);
|
||||
|
||||
@@ -1136,14 +1138,7 @@ static int randomize_colors_exec(bContext *C, wmOperator * /*op*/)
|
||||
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask node_mask = bke::pbvh::all_leaf_nodes(pbvh, memory);
|
||||
if (pbvh.type() == bke::pbvh::Type::Mesh) {
|
||||
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
|
||||
node_mask.foreach_index([&](const int i) { BKE_pbvh_node_mark_redraw(nodes[i]); });
|
||||
}
|
||||
else if (pbvh.type() == bke::pbvh::Type::Grids) {
|
||||
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
|
||||
node_mask.foreach_index([&](const int i) { BKE_pbvh_node_mark_redraw(nodes[i]); });
|
||||
}
|
||||
pbvh.tag_face_sets_changed(node_mask);
|
||||
|
||||
SCULPT_tag_update_overlays(C);
|
||||
|
||||
@@ -1638,6 +1633,8 @@ static void gesture_apply_mesh(gesture::GestureData &gesture_data, const IndexMa
|
||||
Vector<int> face_indices;
|
||||
};
|
||||
|
||||
Array<bool> node_changed(pbvh.nodes_num(), false);
|
||||
|
||||
threading::EnumerableThreadSpecific<TLS> all_tls;
|
||||
if (pbvh.type() == bke::pbvh::Type::Mesh) {
|
||||
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
|
||||
@@ -1658,7 +1655,7 @@ static void gesture_apply_mesh(gesture::GestureData &gesture_data, const IndexMa
|
||||
any_updated = true;
|
||||
}
|
||||
if (any_updated) {
|
||||
BKE_pbvh_node_mark_update_face_sets(nodes[i]);
|
||||
node_changed[i] = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1686,12 +1683,14 @@ static void gesture_apply_mesh(gesture::GestureData &gesture_data, const IndexMa
|
||||
any_updated = true;
|
||||
}
|
||||
if (any_updated) {
|
||||
BKE_pbvh_node_mark_update_face_sets(nodes[i]);
|
||||
node_changed[i] = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
IndexMaskMemory memory;
|
||||
pbvh.tag_face_sets_changed(IndexMask::from_bools(node_changed, memory));
|
||||
face_sets.finish();
|
||||
}
|
||||
|
||||
|
||||
@@ -1174,24 +1174,22 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
|
||||
if (use_multires_undo(step_data, ss)) {
|
||||
MutableSpan<bke::pbvh::GridsNode> nodes = pbvh.nodes<bke::pbvh::GridsNode>();
|
||||
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
|
||||
Vector<int> faces_vector;
|
||||
node_mask.foreach_index([&](const int i) {
|
||||
faces_vector.clear();
|
||||
const Span<int> faces = bke::pbvh::node_face_indices_calc_grids(
|
||||
subdiv_ccg, nodes[i], faces_vector);
|
||||
if (indices_contain_true(modified_faces, faces)) {
|
||||
BKE_pbvh_node_mark_update_face_sets(nodes[i]);
|
||||
}
|
||||
});
|
||||
const IndexMask changed_nodes = IndexMask::from_predicate(
|
||||
node_mask, GrainSize(1), memory, [&](const int i) {
|
||||
Vector<int> faces_vector;
|
||||
const Span<int> faces = bke::pbvh::node_face_indices_calc_grids(
|
||||
subdiv_ccg, nodes[i], faces_vector);
|
||||
return indices_contain_true(modified_faces, faces);
|
||||
});
|
||||
pbvh.tag_face_sets_changed(changed_nodes);
|
||||
}
|
||||
else {
|
||||
MutableSpan<bke::pbvh::MeshNode> nodes = pbvh.nodes<bke::pbvh::MeshNode>();
|
||||
node_mask.foreach_index([&](const int i) {
|
||||
const Span<int> faces = nodes[i].faces();
|
||||
if (indices_contain_true(modified_faces, faces)) {
|
||||
BKE_pbvh_node_mark_update_face_sets(nodes[i]);
|
||||
}
|
||||
});
|
||||
const IndexMask changed_nodes = IndexMask::from_predicate(
|
||||
node_mask, GrainSize(1), memory, [&](const int i) {
|
||||
return indices_contain_true(modified_faces, nodes[i].all_verts());
|
||||
});
|
||||
pbvh.tag_face_sets_changed(changed_nodes);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user