From d64f62e4fa92ceeff1d945c9c51d4bc94cf4a0ee Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 12 Sep 2024 23:45:52 +0200 Subject: [PATCH] Sculpt: Update BVH node bounds in deformation loops Updating the node bounds just after deforming the vertices in the node is faster because the position data is still fresh in CPU caches. Updating it later on means all the other nodes have been processed in the meantime which will evict that position data from the caches. This results in a 1.11x improvement in the brush benchmark timing, from 0.495s to 0.438s on a Ryzen 7950x (best of 5 runs). As part of the change, the update tagging has completely moved to each brush implementation. This continues the process of making each brush more independent. Part of #118145. Pull Request: https://projects.blender.org/blender/blender/pulls/127536 --- source/blender/blenkernel/BKE_pbvh_api.hh | 9 ++- source/blender/blenkernel/intern/pbvh.cc | 11 +-- .../brushes/bmesh_topology_rake.cc | 3 + .../editors/sculpt_paint/brushes/clay.cc | 8 ++ .../sculpt_paint/brushes/clay_strips.cc | 8 ++ .../sculpt_paint/brushes/clay_thumb.cc | 8 ++ .../editors/sculpt_paint/brushes/crease.cc | 8 ++ .../editors/sculpt_paint/brushes/draw.cc | 18 ++++- .../sculpt_paint/brushes/draw_face_sets.cc | 2 +- .../sculpt_paint/brushes/draw_sharp.cc | 18 ++++- .../brushes/draw_vector_displacement.cc | 18 ++++- .../sculpt_paint/brushes/elastic_deform.cc | 8 ++ .../sculpt_paint/brushes/enhance_details.cc | 8 ++ .../editors/sculpt_paint/brushes/fill.cc | 8 ++ .../editors/sculpt_paint/brushes/flatten.cc | 7 ++ .../editors/sculpt_paint/brushes/grab.cc | 8 ++ .../editors/sculpt_paint/brushes/inflate.cc | 18 ++++- .../editors/sculpt_paint/brushes/layer.cc | 11 ++- .../editors/sculpt_paint/brushes/mask.cc | 13 ++- .../sculpt_paint/brushes/multiplane_scrape.cc | 8 ++ .../brushes/multires_displacement_eraser.cc | 10 ++- .../brushes/multires_displacement_smear.cc | 8 +- .../editors/sculpt_paint/brushes/pinch.cc | 8 ++ .../editors/sculpt_paint/brushes/relax.cc | 12 ++- .../editors/sculpt_paint/brushes/rotate.cc | 18 ++++- .../editors/sculpt_paint/brushes/scrape.cc | 8 ++ .../editors/sculpt_paint/brushes/smooth.cc | 1 + .../sculpt_paint/brushes/smooth_mask.cc | 8 +- .../sculpt_paint/brushes/snake_hook.cc | 8 ++ .../sculpt_paint/brushes/surface_smooth.cc | 4 +- .../editors/sculpt_paint/brushes/thumb.cc | 18 ++++- .../sculpt_paint/brushes/topology_slide.cc | 18 ++++- source/blender/editors/sculpt_paint/sculpt.cc | 79 ------------------- .../editors/sculpt_paint/sculpt_boundary.cc | 54 +++++++++++-- .../editors/sculpt_paint/sculpt_cloth.cc | 13 +++ .../editors/sculpt_paint/sculpt_face_set.cc | 1 + .../sculpt_paint/sculpt_filter_mesh.cc | 1 + .../sculpt_paint/sculpt_paint_color.cc | 4 + .../editors/sculpt_paint/sculpt_pose.cc | 18 ++++- .../editors/sculpt_paint/sculpt_project.cc | 6 ++ .../editors/sculpt_paint/sculpt_transform.cc | 6 ++ 41 files changed, 366 insertions(+), 137 deletions(-) diff --git a/source/blender/blenkernel/BKE_pbvh_api.hh b/source/blender/blenkernel/BKE_pbvh_api.hh index bc8bab90c5a..b6a31d5639d 100644 --- a/source/blender/blenkernel/BKE_pbvh_api.hh +++ b/source/blender/blenkernel/BKE_pbvh_api.hh @@ -536,9 +536,16 @@ void node_update_visibility_grids(const BitGroupVector<> &grid_hidden, GridsNode void node_update_visibility_bmesh(BMeshNode &node); void update_node_bounds_mesh(Span positions, MeshNode &node); -void update_node_bounds_grids(const CCGKey &key, Span positions, GridsNode &node); +void update_node_bounds_grids(int grid_area, Span 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 MeshNode::faces() const { return this->face_indices_; diff --git a/source/blender/blenkernel/intern/pbvh.cc b/source/blender/blenkernel/intern/pbvh.cc index 736efb08d71..b83deeeccf0 100644 --- a/source/blender/blenkernel/intern/pbvh.cc +++ b/source/blender/blenkernel/intern/pbvh.cc @@ -1038,11 +1038,11 @@ void update_node_bounds_mesh(const Span positions, MeshNode &node) node.bounds_ = bounds; } -void update_node_bounds_grids(const CCGKey &key, const Span positions, GridsNode &node) +void update_node_bounds_grids(const int grid_area, const Span positions, GridsNode &node) { Bounds bounds = negative_bounds(); for (const int grid : node.grids()) { - for (const float3 &position : positions.slice(bke::ccg::grid_range(key, grid))) { + for (const float3 &position : positions.slice(bke::ccg::grid_range(grid_area, grid))) { math::min_max(position, bounds.min, bounds.max); } } @@ -1086,7 +1086,7 @@ static BoundsMergeInfo merge_child_bounds(MutableSpan nodes, const int no return {node.bounds_, update}; } -static void flush_bounds_to_parents(Tree &pbvh) +void flush_bounds_to_parents(Tree &pbvh) { std::visit( [](auto &nodes) { @@ -1116,8 +1116,9 @@ void update_bounds_grids(const CCGKey &key, const Span positions, Tree & pbvh, memory, [&](const Node &node) { return update_search(node, PBVH_UpdateBB); }); MutableSpan nodes = pbvh.nodes(); - nodes_to_update.foreach_index( - GrainSize(1), [&](const int i) { update_node_bounds_grids(key, positions, nodes[i]); }); + nodes_to_update.foreach_index(GrainSize(1), [&](const int i) { + update_node_bounds_grids(key.grid_area, positions, nodes[i]); + }); if (!nodes.is_empty()) { flush_bounds_to_parents(pbvh); } diff --git a/source/blender/editors/sculpt_paint/brushes/bmesh_topology_rake.cc b/source/blender/editors/sculpt_paint/brushes/bmesh_topology_rake.cc index 37cd07d53c7..d4429017f3e 100644 --- a/source/blender/editors/sculpt_paint/brushes/bmesh_topology_rake.cc +++ b/source/blender/editors/sculpt_paint/brushes/bmesh_topology_rake.cc @@ -127,9 +127,12 @@ void do_bmesh_topology_rake_brush(const Depsgraph &depsgraph, node_mask.slice(range).foreach_index([&](const int i) { calc_bmesh( depsgraph, sd, object, brush, direction, factor * ss.cache->pressure, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); } + bke::pbvh::flush_bounds_to_parents(pbvh); } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/brushes/clay.cc b/source/blender/editors/sculpt_paint/brushes/clay.cc index 110da772c2c..fa7fb32b7f2 100644 --- a/source/blender/editors/sculpt_paint/brushes/clay.cc +++ b/source/blender/editors/sculpt_paint/brushes/clay.cc @@ -245,16 +245,21 @@ void do_clay_brush(const Depsgraph &depsgraph, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_grids(depsgraph, sd, object, brush, test_plane, bstrength, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -265,11 +270,14 @@ void do_clay_brush(const Depsgraph &depsgraph, LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_bmesh(depsgraph, sd, object, brush, test_plane, bstrength, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/brushes/clay_strips.cc b/source/blender/editors/sculpt_paint/brushes/clay_strips.cc index e339ecf8840..3525cb52151 100644 --- a/source/blender/editors/sculpt_paint/brushes/clay_strips.cc +++ b/source/blender/editors/sculpt_paint/brushes/clay_strips.cc @@ -299,16 +299,21 @@ void do_clay_strips_brush(const Depsgraph &depsgraph, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_grids(depsgraph, sd, object, brush, mat, plane, strength, flip, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -319,11 +324,14 @@ void do_clay_strips_brush(const Depsgraph &depsgraph, LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_bmesh(depsgraph, sd, object, brush, mat, plane, strength, flip, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/brushes/clay_thumb.cc b/source/blender/editors/sculpt_paint/brushes/clay_thumb.cc index 98a80ce3a1f..d12d2a2fa14 100644 --- a/source/blender/editors/sculpt_paint/brushes/clay_thumb.cc +++ b/source/blender/editors/sculpt_paint/brushes/clay_thumb.cc @@ -278,16 +278,21 @@ void do_clay_thumb_brush(const Depsgraph &depsgraph, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_grids(depsgraph, sd, brush, plane_tilt, clay_strength, nodes[i], object, tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -298,11 +303,14 @@ void do_clay_thumb_brush(const Depsgraph &depsgraph, LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_bmesh(depsgraph, sd, brush, plane_tilt, clay_strength, object, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } float clay_thumb_get_stabilized_pressure(const StrokeCache &cache) diff --git a/source/blender/editors/sculpt_paint/brushes/crease.cc b/source/blender/editors/sculpt_paint/brushes/crease.cc index 0995480b0e1..56ba033a275 100644 --- a/source/blender/editors/sculpt_paint/brushes/crease.cc +++ b/source/blender/editors/sculpt_paint/brushes/crease.cc @@ -281,16 +281,21 @@ static void do_crease_or_blob_brush(const Depsgraph &depsgraph, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_grids(depsgraph, sd, object, brush, offset, strength, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -301,11 +306,14 @@ static void do_crease_or_blob_brush(const Depsgraph &depsgraph, LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_bmesh(depsgraph, sd, object, brush, offset, strength, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } } // namespace crease_cc diff --git a/source/blender/editors/sculpt_paint/brushes/draw.cc b/source/blender/editors/sculpt_paint/brushes/draw.cc index c9f473a4075..673e6910a7a 100644 --- a/source/blender/editors/sculpt_paint/brushes/draw.cc +++ b/source/blender/editors/sculpt_paint/brushes/draw.cc @@ -196,16 +196,22 @@ static void offset_positions(const Depsgraph &depsgraph, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); - node_mask.slice(range).foreach_index( - [&](const int i) { calc_grids(depsgraph, sd, object, brush, offset, nodes[i], tls); }); + node_mask.slice(range).foreach_index([&](const int i) { + calc_grids(depsgraph, sd, object, brush, offset, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); + }); }); break; } @@ -213,12 +219,16 @@ static void offset_positions(const Depsgraph &depsgraph, MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); - node_mask.slice(range).foreach_index( - [&](const int i) { calc_bmesh(depsgraph, sd, object, brush, offset, nodes[i], tls); }); + node_mask.slice(range).foreach_index([&](const int i) { + calc_bmesh(depsgraph, sd, object, brush, offset, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); + }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } void do_draw_brush(const Depsgraph &depsgraph, diff --git a/source/blender/editors/sculpt_paint/brushes/draw_face_sets.cc b/source/blender/editors/sculpt_paint/brushes/draw_face_sets.cc index f5231da39ff..58853e425ba 100644 --- a/source/blender/editors/sculpt_paint/brushes/draw_face_sets.cc +++ b/source/blender/editors/sculpt_paint/brushes/draw_face_sets.cc @@ -184,7 +184,6 @@ static void do_draw_face_sets_brush_mesh(const Depsgraph &depsgraph, MeshLocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { const Span face_indices = nodes[i].faces(); - calc_faces(depsgraph, object, brush, @@ -195,6 +194,7 @@ 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]); }); }); diff --git a/source/blender/editors/sculpt_paint/brushes/draw_sharp.cc b/source/blender/editors/sculpt_paint/brushes/draw_sharp.cc index dd54050b5a6..53ab6cddace 100644 --- a/source/blender/editors/sculpt_paint/brushes/draw_sharp.cc +++ b/source/blender/editors/sculpt_paint/brushes/draw_sharp.cc @@ -192,16 +192,22 @@ static void offset_positions(const Depsgraph &depsgraph, calc_faces( depsgraph, sd, brush, offset, positions_eval, nodes[i], object, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); - node_mask.slice(range).foreach_index( - [&](const int i) { calc_grids(depsgraph, sd, object, brush, offset, nodes[i], tls); }); + node_mask.slice(range).foreach_index([&](const int i) { + calc_grids(depsgraph, sd, object, brush, offset, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); + }); }); break; } @@ -209,12 +215,16 @@ static void offset_positions(const Depsgraph &depsgraph, MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); - node_mask.slice(range).foreach_index( - [&](const int i) { calc_bmesh(depsgraph, sd, object, brush, offset, nodes[i], tls); }); + node_mask.slice(range).foreach_index([&](const int i) { + calc_bmesh(depsgraph, sd, object, brush, offset, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); + }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } void do_draw_sharp_brush(const Depsgraph &depsgraph, diff --git a/source/blender/editors/sculpt_paint/brushes/draw_vector_displacement.cc b/source/blender/editors/sculpt_paint/brushes/draw_vector_displacement.cc index f5ab472d8ee..3eb65c5ecbf 100644 --- a/source/blender/editors/sculpt_paint/brushes/draw_vector_displacement.cc +++ b/source/blender/editors/sculpt_paint/brushes/draw_vector_displacement.cc @@ -245,16 +245,22 @@ void do_draw_vector_displacement_brush(const Depsgraph &depsgraph, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); - node_mask.slice(range).foreach_index( - [&](const int i) { calc_grids(depsgraph, sd, object, brush, nodes[i], tls); }); + node_mask.slice(range).foreach_index([&](const int i) { + calc_grids(depsgraph, sd, object, brush, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); + }); }); break; } @@ -262,12 +268,16 @@ void do_draw_vector_displacement_brush(const Depsgraph &depsgraph, MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); - node_mask.slice(range).foreach_index( - [&](const int i) { calc_bmesh(depsgraph, sd, object, brush, nodes[i], tls); }); + node_mask.slice(range).foreach_index([&](const int i) { + calc_bmesh(depsgraph, sd, object, brush, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); + }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/brushes/elastic_deform.cc b/source/blender/editors/sculpt_paint/brushes/elastic_deform.cc index fb0616b5cf2..ef30abf67cc 100644 --- a/source/blender/editors/sculpt_paint/brushes/elastic_deform.cc +++ b/source/blender/editors/sculpt_paint/brushes/elastic_deform.cc @@ -259,16 +259,21 @@ void do_elastic_deform_brush(const Depsgraph &depsgraph, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_grids(depsgraph, sd, object, brush, params, grab_delta, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -279,10 +284,13 @@ void do_elastic_deform_brush(const Depsgraph &depsgraph, LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_bmesh(depsgraph, sd, object, brush, params, grab_delta, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); } break; } + bke::pbvh::flush_bounds_to_parents(pbvh); } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/brushes/enhance_details.cc b/source/blender/editors/sculpt_paint/brushes/enhance_details.cc index d41b245ef98..23f8a598029 100644 --- a/source/blender/editors/sculpt_paint/brushes/enhance_details.cc +++ b/source/blender/editors/sculpt_paint/brushes/enhance_details.cc @@ -334,16 +334,21 @@ void do_enhance_details_brush(const Depsgraph &depsgraph, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_grids(depsgraph, sd, object, brush, translations, strength, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -354,11 +359,14 @@ void do_enhance_details_brush(const Depsgraph &depsgraph, LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_bmesh(depsgraph, sd, object, brush, translations, strength, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/brushes/fill.cc b/source/blender/editors/sculpt_paint/brushes/fill.cc index 2a9fc391710..3d047107975 100644 --- a/source/blender/editors/sculpt_paint/brushes/fill.cc +++ b/source/blender/editors/sculpt_paint/brushes/fill.cc @@ -231,16 +231,21 @@ void do_fill_brush(const Depsgraph &depsgraph, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_grids(depsgraph, sd, object, brush, plane, ss.cache->bstrength, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -251,11 +256,14 @@ void do_fill_brush(const Depsgraph &depsgraph, LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_bmesh(depsgraph, sd, object, brush, plane, ss.cache->bstrength, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/brushes/flatten.cc b/source/blender/editors/sculpt_paint/brushes/flatten.cc index a2036b55ff6..7ed3da77053 100644 --- a/source/blender/editors/sculpt_paint/brushes/flatten.cc +++ b/source/blender/editors/sculpt_paint/brushes/flatten.cc @@ -224,16 +224,21 @@ void do_flatten_brush(const Depsgraph &depsgraph, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_grids(depsgraph, sd, object, brush, plane, ss.cache->bstrength, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -244,6 +249,8 @@ void do_flatten_brush(const Depsgraph &depsgraph, LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_bmesh(depsgraph, sd, object, brush, plane, ss.cache->bstrength, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; diff --git a/source/blender/editors/sculpt_paint/brushes/grab.cc b/source/blender/editors/sculpt_paint/brushes/grab.cc index edad97ee358..83fe63b1c15 100644 --- a/source/blender/editors/sculpt_paint/brushes/grab.cc +++ b/source/blender/editors/sculpt_paint/brushes/grab.cc @@ -233,16 +233,21 @@ void do_grab_brush(const Depsgraph &depsgraph, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_grids(depsgraph, sd, object, brush, grab_delta, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -253,11 +258,14 @@ void do_grab_brush(const Depsgraph &depsgraph, LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_bmesh(depsgraph, sd, object, brush, grab_delta, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/brushes/inflate.cc b/source/blender/editors/sculpt_paint/brushes/inflate.cc index da4a29c85be..2c399acf926 100644 --- a/source/blender/editors/sculpt_paint/brushes/inflate.cc +++ b/source/blender/editors/sculpt_paint/brushes/inflate.cc @@ -209,16 +209,22 @@ void do_inflate_brush(const Depsgraph &depsgraph, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); - node_mask.slice(range).foreach_index( - [&](const int i) { calc_grids(depsgraph, sd, object, brush, scale, nodes[i], tls); }); + node_mask.slice(range).foreach_index([&](const int i) { + calc_grids(depsgraph, sd, object, brush, scale, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); + }); }); break; } @@ -226,12 +232,16 @@ void do_inflate_brush(const Depsgraph &depsgraph, MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); - node_mask.slice(range).foreach_index( - [&](const int i) { calc_bmesh(depsgraph, sd, object, brush, scale, nodes[i], tls); }); + node_mask.slice(range).foreach_index([&](const int i) { + calc_bmesh(depsgraph, sd, object, brush, scale, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); + }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/brushes/layer.cc b/source/blender/editors/sculpt_paint/brushes/layer.cc index 6fbc038cfed..0757ce372fa 100644 --- a/source/blender/editors/sculpt_paint/brushes/layer.cc +++ b/source/blender/editors/sculpt_paint/brushes/layer.cc @@ -410,14 +410,18 @@ void do_layer_brush(const Depsgraph &depsgraph, tls, displacement, positions_orig); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); persistent_disp_attr.finish(); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; if (ss.cache->layer_displacement_factor.is_empty()) { - ss.cache->layer_displacement_factor = Array(SCULPT_vertex_count_get(object), 0.0f); + ss.cache->layer_displacement_factor = Array(positions.size(), 0.0f); } const MutableSpan displacement = ss.cache->layer_displacement_factor; MutableSpan nodes = pbvh.nodes(); @@ -425,6 +429,8 @@ void do_layer_brush(const Depsgraph &depsgraph, LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_grids(depsgraph, sd, brush, object, nodes[i], tls, displacement); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -439,11 +445,14 @@ void do_layer_brush(const Depsgraph &depsgraph, LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_bmesh(depsgraph, sd, brush, object, nodes[i], tls, displacement); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/brushes/mask.cc b/source/blender/editors/sculpt_paint/brushes/mask.cc index 19febb543e4..1d03c04f546 100644 --- a/source/blender/editors/sculpt_paint/brushes/mask.cc +++ b/source/blender/editors/sculpt_paint/brushes/mask.cc @@ -244,6 +244,7 @@ void do_mask_brush(const Depsgraph &depsgraph, mesh, tls, mask.span); + BKE_pbvh_node_mark_update_mask(nodes[i]); }); }); mask.finish(); @@ -253,8 +254,10 @@ void do_mask_brush(const Depsgraph &depsgraph, MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); - node_mask.slice(range).foreach_index( - [&](const int i) { calc_grids(depsgraph, object, brush, bstrength, nodes[i], tls); }); + node_mask.slice(range).foreach_index([&](const int i) { + calc_grids(depsgraph, object, brush, bstrength, nodes[i], tls); + BKE_pbvh_node_mark_update_mask(nodes[i]); + }); }); break; } @@ -262,8 +265,10 @@ void do_mask_brush(const Depsgraph &depsgraph, MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); - node_mask.slice(range).foreach_index( - [&](const int i) { calc_bmesh(depsgraph, object, brush, bstrength, nodes[i], tls); }); + node_mask.slice(range).foreach_index([&](const int i) { + calc_bmesh(depsgraph, object, brush, bstrength, nodes[i], tls); + BKE_pbvh_node_mark_update_mask(nodes[i]); + }); }); break; } diff --git a/source/blender/editors/sculpt_paint/brushes/multiplane_scrape.cc b/source/blender/editors/sculpt_paint/brushes/multiplane_scrape.cc index e1143aad98c..0051e2e9dbf 100644 --- a/source/blender/editors/sculpt_paint/brushes/multiplane_scrape.cc +++ b/source/blender/editors/sculpt_paint/brushes/multiplane_scrape.cc @@ -663,11 +663,14 @@ void do_multiplane_scrape_brush(const Depsgraph &depsgraph, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); } }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); @@ -682,6 +685,8 @@ void do_multiplane_scrape_brush(const Depsgraph &depsgraph, nodes[i], object, tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -701,11 +706,14 @@ void do_multiplane_scrape_brush(const Depsgraph &depsgraph, nodes[i], object, tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } void multiplane_scrape_preview_draw(const uint gpuattr, diff --git a/source/blender/editors/sculpt_paint/brushes/multires_displacement_eraser.cc b/source/blender/editors/sculpt_paint/brushes/multires_displacement_eraser.cc index 4e746cea616..64047fb29f6 100644 --- a/source/blender/editors/sculpt_paint/brushes/multires_displacement_eraser.cc +++ b/source/blender/editors/sculpt_paint/brushes/multires_displacement_eraser.cc @@ -100,6 +100,8 @@ void do_displacement_eraser_brush(const Depsgraph &depsgraph, const IndexMask &node_mask) { SculptSession &ss = *object.sculpt; + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; const Brush &brush = *BKE_paint_brush_for_read(&sd.paint); const float strength = std::min(ss.cache->bstrength, 1.0f); @@ -108,9 +110,13 @@ void do_displacement_eraser_brush(const Depsgraph &depsgraph, MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); - node_mask.slice(range).foreach_index( - [&](const int i) { calc_node(depsgraph, sd, object, brush, strength, nodes[i], tls); }); + node_mask.slice(range).foreach_index([&](const int i) { + calc_node(depsgraph, sd, object, brush, strength, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); + }); }); + bke::pbvh::flush_bounds_to_parents(pbvh); } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/brushes/multires_displacement_smear.cc b/source/blender/editors/sculpt_paint/brushes/multires_displacement_smear.cc index 282f750c148..da835533d2c 100644 --- a/source/blender/editors/sculpt_paint/brushes/multires_displacement_smear.cc +++ b/source/blender/editors/sculpt_paint/brushes/multires_displacement_smear.cc @@ -204,9 +204,13 @@ void do_displacement_smear_brush(const Depsgraph &depsgraph, threading::EnumerableThreadSpecific all_tls; threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); - node_mask.slice(range).foreach_index( - [&](const int i) { calc_node(depsgraph, ob, brush, strength, nodes[i], tls); }); + node_mask.slice(range).foreach_index([&](const int i) { + calc_node(depsgraph, ob, brush, strength, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); + }); }); + bke::pbvh::flush_bounds_to_parents(pbvh); } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/brushes/pinch.cc b/source/blender/editors/sculpt_paint/brushes/pinch.cc index 486ab471d2b..d51295cc7cc 100644 --- a/source/blender/editors/sculpt_paint/brushes/pinch.cc +++ b/source/blender/editors/sculpt_paint/brushes/pinch.cc @@ -270,16 +270,21 @@ void do_pinch_brush(const Depsgraph &depsgraph, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_grids(depsgraph, sd, object, brush, stroke_xz, ss.cache->bstrength, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -290,11 +295,14 @@ void do_pinch_brush(const Depsgraph &depsgraph, LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_bmesh(depsgraph, sd, object, brush, stroke_xz, ss.cache->bstrength, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/brushes/relax.cc b/source/blender/editors/sculpt_paint/brushes/relax.cc index 1e9725cade3..ac046d27bf7 100644 --- a/source/blender/editors/sculpt_paint/brushes/relax.cc +++ b/source/blender/editors/sculpt_paint/brushes/relax.cc @@ -535,7 +535,10 @@ static void do_topology_relax_brush_mesh(const Depsgraph &depsgraph, object, translations.as_mutable_span().slice(node_vert_offsets[pos]), positions_orig); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); + bke::pbvh::flush_bounds_to_parents(pbvh); } BLI_NOINLINE static void calc_topology_relax_factors_grids(const Depsgraph &depsgraph, @@ -589,7 +592,8 @@ static void do_topology_relax_brush_grids(const Depsgraph &depsgraph, const SculptSession &ss = *object.sculpt; bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object); MutableSpan nodes = pbvh.nodes(); - SubdivCCG &subdiv_ccg = *ss.subdiv_ccg; + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg); Mesh &mesh = *static_cast(object.data); @@ -643,7 +647,10 @@ static void do_topology_relax_brush_grids(const Depsgraph &depsgraph, object, current_positions.as_mutable_span().slice(node_vert_offsets[pos]), translations.as_mutable_span().slice(node_vert_offsets[pos])); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); + bke::pbvh::flush_bounds_to_parents(pbvh); } static void calc_topology_relax_factors_bmesh(const Depsgraph &depsgraph, @@ -735,7 +742,10 @@ static void do_topology_relax_brush_bmesh(const Depsgraph &depsgraph, object, translations.as_mutable_span().slice(node_vert_offsets[pos]), current_positions.as_span().slice(node_vert_offsets[pos])); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); + bke::pbvh::flush_bounds_to_parents(pbvh); } /** \} */ diff --git a/source/blender/editors/sculpt_paint/brushes/rotate.cc b/source/blender/editors/sculpt_paint/brushes/rotate.cc index cd8f08a66c6..ed0d57cdc19 100644 --- a/source/blender/editors/sculpt_paint/brushes/rotate.cc +++ b/source/blender/editors/sculpt_paint/brushes/rotate.cc @@ -223,16 +223,22 @@ void do_rotate_brush(const Depsgraph &depsgraph, calc_faces( depsgraph, sd, brush, angle, positions_eval, nodes[i], object, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); - node_mask.slice(range).foreach_index( - [&](const int i) { calc_grids(depsgraph, sd, object, brush, angle, nodes[i], tls); }); + node_mask.slice(range).foreach_index([&](const int i) { + calc_grids(depsgraph, sd, object, brush, angle, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); + }); }); break; } @@ -240,12 +246,16 @@ void do_rotate_brush(const Depsgraph &depsgraph, MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); - node_mask.slice(range).foreach_index( - [&](const int i) { calc_bmesh(depsgraph, sd, object, brush, angle, nodes[i], tls); }); + node_mask.slice(range).foreach_index([&](const int i) { + calc_bmesh(depsgraph, sd, object, brush, angle, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); + }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/brushes/scrape.cc b/source/blender/editors/sculpt_paint/brushes/scrape.cc index 1e8003f86a2..fdf87b9ce2c 100644 --- a/source/blender/editors/sculpt_paint/brushes/scrape.cc +++ b/source/blender/editors/sculpt_paint/brushes/scrape.cc @@ -232,16 +232,21 @@ void do_scrape_brush(const Depsgraph &depsgraph, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_grids(depsgraph, sd, object, brush, plane, ss.cache->bstrength, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -252,11 +257,14 @@ void do_scrape_brush(const Depsgraph &depsgraph, LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_bmesh(depsgraph, sd, object, brush, plane, ss.cache->bstrength, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/brushes/smooth.cc b/source/blender/editors/sculpt_paint/brushes/smooth.cc index df865abdd7c..08fd8621b70 100644 --- a/source/blender/editors/sculpt_paint/brushes/smooth.cc +++ b/source/blender/editors/sculpt_paint/brushes/smooth.cc @@ -330,6 +330,7 @@ void do_smooth_brush(const Depsgraph &depsgraph, break; } } + bke::pbvh::update_bounds(depsgraph, object, pbvh); } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/brushes/smooth_mask.cc b/source/blender/editors/sculpt_paint/brushes/smooth_mask.cc index 2824fed23a3..15e815b95a8 100644 --- a/source/blender/editors/sculpt_paint/brushes/smooth_mask.cc +++ b/source/blender/editors/sculpt_paint/brushes/smooth_mask.cc @@ -172,6 +172,7 @@ static void do_smooth_brush_mesh(const Depsgraph &depsgraph, tls, new_masks.as_span().slice(node_vert_offsets[pos]), mask.span); + BKE_pbvh_node_mark_update_mask(nodes[i]); }); } mask.finish(); @@ -304,8 +305,10 @@ void do_smooth_mask_brush(const Depsgraph &depsgraph, MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); - node_mask.slice(range).foreach_index( - [&](const int i) { calc_grids(depsgraph, object, brush, strength, nodes[i], tls); }); + node_mask.slice(range).foreach_index([&](const int i) { + calc_grids(depsgraph, object, brush, strength, nodes[i], tls); + BKE_pbvh_node_mark_update_mask(nodes[i]); + }); }); } break; @@ -322,6 +325,7 @@ void do_smooth_mask_brush(const Depsgraph &depsgraph, LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_bmesh(depsgraph, object, mask_offset, brush, strength, nodes[i], tls); + BKE_pbvh_node_mark_update_mask(nodes[i]); }); }); } diff --git a/source/blender/editors/sculpt_paint/brushes/snake_hook.cc b/source/blender/editors/sculpt_paint/brushes/snake_hook.cc index c35f3e7ee37..d55b4a6fdd3 100644 --- a/source/blender/editors/sculpt_paint/brushes/snake_hook.cc +++ b/source/blender/editors/sculpt_paint/brushes/snake_hook.cc @@ -396,16 +396,21 @@ void do_snake_hook_brush(const Depsgraph &depsgraph, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_grids(depsgraph, sd, object, brush, &spvc, grab_delta, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -416,11 +421,14 @@ void do_snake_hook_brush(const Depsgraph &depsgraph, LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { calc_bmesh(depsgraph, sd, object, brush, &spvc, grab_delta, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/brushes/surface_smooth.cc b/source/blender/editors/sculpt_paint/brushes/surface_smooth.cc index 9d0df2bd66a..70bb409ff82 100644 --- a/source/blender/editors/sculpt_paint/brushes/surface_smooth.cc +++ b/source/blender/editors/sculpt_paint/brushes/surface_smooth.cc @@ -376,9 +376,10 @@ void do_surface_smooth_brush(const Depsgraph &depsgraph, const IndexMask &node_mask) { SculptSession &ss = *object.sculpt; + bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object); const Brush &brush = *BKE_paint_brush_for_read(&sd.paint); - switch (bke::object::pbvh_get(object)->type()) { + switch (pbvh.type()) { case bke::pbvh::Type::Mesh: do_surface_smooth_brush_mesh( depsgraph, sd, brush, node_mask, object, ss.cache->surface_smooth_laplacian_disp); @@ -395,6 +396,7 @@ void do_surface_smooth_brush(const Depsgraph &depsgraph, break; } } + bke::pbvh::update_bounds(depsgraph, object, pbvh); } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/brushes/thumb.cc b/source/blender/editors/sculpt_paint/brushes/thumb.cc index 7f9df4aef35..4ac6d767be8 100644 --- a/source/blender/editors/sculpt_paint/brushes/thumb.cc +++ b/source/blender/editors/sculpt_paint/brushes/thumb.cc @@ -199,16 +199,22 @@ void do_thumb_brush(const Depsgraph &depsgraph, calc_faces( depsgraph, sd, brush, offset, positions_eval, nodes[i], object, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); - node_mask.slice(range).foreach_index( - [&](const int i) { calc_grids(depsgraph, sd, object, brush, offset, nodes[i], tls); }); + node_mask.slice(range).foreach_index([&](const int i) { + calc_grids(depsgraph, sd, object, brush, offset, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); + }); }); break; } @@ -216,12 +222,16 @@ void do_thumb_brush(const Depsgraph &depsgraph, MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); - node_mask.slice(range).foreach_index( - [&](const int i) { calc_bmesh(depsgraph, sd, object, brush, offset, nodes[i], tls); }); + node_mask.slice(range).foreach_index([&](const int i) { + calc_bmesh(depsgraph, sd, object, brush, offset, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); + }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/brushes/topology_slide.cc b/source/blender/editors/sculpt_paint/brushes/topology_slide.cc index e0cab13af29..eb1f7edc6f1 100644 --- a/source/blender/editors/sculpt_paint/brushes/topology_slide.cc +++ b/source/blender/editors/sculpt_paint/brushes/topology_slide.cc @@ -343,16 +343,22 @@ void do_topology_slide_brush(const Depsgraph &depsgraph, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); - node_mask.slice(range).foreach_index( - [&](const int i) { calc_grids(depsgraph, sd, object, brush, nodes[i], tls); }); + node_mask.slice(range).foreach_index([&](const int i) { + calc_grids(depsgraph, sd, object, brush, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); + }); }); break; } @@ -360,12 +366,16 @@ void do_topology_slide_brush(const Depsgraph &depsgraph, MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); - node_mask.slice(range).foreach_index( - [&](const int i) { calc_bmesh(depsgraph, sd, object, brush, nodes[i], tls); }); + node_mask.slice(range).foreach_index([&](const int i) { + calc_bmesh(depsgraph, sd, object, brush, nodes[i], tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); + }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 9fa8bbe0160..0db5552269e 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -3347,27 +3347,6 @@ static void push_undo_nodes(const Depsgraph &depsgraph, bool need_coords = ss.cache->supports_gravity; if (brush.sculpt_brush_type == SCULPT_BRUSH_TYPE_DRAW_FACE_SETS) { - switch (pbvh.type()) { - case bke::pbvh::Type::Mesh: { - MutableSpan nodes = pbvh.nodes(); - node_mask.foreach_index( - [&](const int i) { BKE_pbvh_node_mark_update_face_sets(nodes[i]); }); - break; - } - case bke::pbvh::Type::Grids: { - MutableSpan nodes = pbvh.nodes(); - node_mask.foreach_index( - [&](const int i) { BKE_pbvh_node_mark_update_face_sets(nodes[i]); }); - break; - } - case bke::pbvh::Type::BMesh: { - MutableSpan nodes = pbvh.nodes(); - node_mask.foreach_index( - [&](const int i) { BKE_pbvh_node_mark_update_face_sets(nodes[i]); }); - break; - } - } - /* Draw face sets in smooth mode moves the vertices. */ if (ss.cache->alt_smooth) { need_coords = true; @@ -3378,43 +3357,9 @@ static void push_undo_nodes(const Depsgraph &depsgraph, } else if (brush.sculpt_brush_type == SCULPT_BRUSH_TYPE_MASK) { undo::push_nodes(depsgraph, ob, node_mask, undo::Type::Mask); - switch (pbvh.type()) { - case bke::pbvh::Type::Mesh: { - MutableSpan nodes = pbvh.nodes(); - node_mask.foreach_index([&](const int i) { BKE_pbvh_node_mark_update_mask(nodes[i]); }); - break; - } - case bke::pbvh::Type::Grids: { - MutableSpan nodes = pbvh.nodes(); - node_mask.foreach_index([&](const int i) { BKE_pbvh_node_mark_update_mask(nodes[i]); }); - break; - } - case bke::pbvh::Type::BMesh: { - MutableSpan nodes = pbvh.nodes(); - node_mask.foreach_index([&](const int i) { BKE_pbvh_node_mark_update_mask(nodes[i]); }); - break; - } - } } else if (SCULPT_brush_type_is_paint(brush.sculpt_brush_type)) { undo::push_nodes(depsgraph, ob, node_mask, undo::Type::Color); - switch (pbvh.type()) { - case bke::pbvh::Type::Mesh: { - MutableSpan nodes = pbvh.nodes(); - node_mask.foreach_index([&](const int i) { BKE_pbvh_node_mark_update_color(nodes[i]); }); - break; - } - case bke::pbvh::Type::Grids: { - MutableSpan nodes = pbvh.nodes(); - node_mask.foreach_index([&](const int i) { BKE_pbvh_node_mark_update_color(nodes[i]); }); - break; - } - case bke::pbvh::Type::BMesh: { - MutableSpan nodes = pbvh.nodes(); - node_mask.foreach_index([&](const int i) { BKE_pbvh_node_mark_update_color(nodes[i]); }); - break; - } - } } else { need_coords = true; @@ -3422,26 +3367,6 @@ static void push_undo_nodes(const Depsgraph &depsgraph, if (need_coords) { undo::push_nodes(depsgraph, ob, node_mask, undo::Type::Position); - switch (pbvh.type()) { - case bke::pbvh::Type::Mesh: { - MutableSpan nodes = pbvh.nodes(); - node_mask.foreach_index( - [&](const int i) { BKE_pbvh_node_mark_positions_update(nodes[i]); }); - break; - } - case bke::pbvh::Type::Grids: { - MutableSpan nodes = pbvh.nodes(); - node_mask.foreach_index( - [&](const int i) { BKE_pbvh_node_mark_positions_update(nodes[i]); }); - break; - } - case bke::pbvh::Type::BMesh: { - MutableSpan nodes = pbvh.nodes(); - node_mask.foreach_index( - [&](const int i) { BKE_pbvh_node_mark_positions_update(nodes[i]); }); - break; - } - } } } @@ -5395,10 +5320,6 @@ void flush_update_step(bContext *C, UpdateType update_type) * only the part of the 3D viewport where changes happened. */ rcti r; - if (update_type == UpdateType::Position) { - bke::pbvh::update_bounds(depsgraph, ob, pbvh); - } - RegionView3D *rv3d = CTX_wm_region_view3d(C); if (rv3d && SCULPT_get_redraw_rect(region, *rv3d, ob, r)) { if (ss.cache) { diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.cc b/source/blender/editors/sculpt_paint/sculpt_boundary.cc index c281f808cfe..5b46a60e7c8 100644 --- a/source/blender/editors/sculpt_paint/sculpt_boundary.cc +++ b/source/blender/editors/sculpt_paint/sculpt_boundary.cc @@ -1312,12 +1312,14 @@ static void do_bend_brush(const Depsgraph &depsgraph, deform_target, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { - SubdivCCG &subdiv_ccg = *ss.subdiv_ccg; + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; threading::EnumerableThreadSpecific all_tls; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { @@ -1336,6 +1338,8 @@ static void do_bend_brush(const Depsgraph &depsgraph, boundary.initial_vert_position, strength, deform_target); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -1358,11 +1362,14 @@ static void do_bend_brush(const Depsgraph &depsgraph, boundary.initial_vert_position, strength, deform_target); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } /** \} */ @@ -1603,12 +1610,14 @@ static void do_slide_brush(const Depsgraph &depsgraph, deform_target, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { - SubdivCCG &subdiv_ccg = *ss.subdiv_ccg; + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; threading::EnumerableThreadSpecific all_tls; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { @@ -1626,6 +1635,8 @@ static void do_slide_brush(const Depsgraph &depsgraph, boundary.initial_vert_position, strength, deform_target); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -1647,11 +1658,14 @@ static void do_slide_brush(const Depsgraph &depsgraph, boundary.initial_vert_position, strength, deform_target); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } /** \} */ @@ -1877,12 +1891,14 @@ static void do_inflate_brush(const Depsgraph &depsgraph, deform_target, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { - SubdivCCG &subdiv_ccg = *ss.subdiv_ccg; + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; threading::EnumerableThreadSpecific all_tls; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { @@ -1899,6 +1915,8 @@ static void do_inflate_brush(const Depsgraph &depsgraph, boundary.initial_vert_position, strength, deform_target); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -1919,11 +1937,14 @@ static void do_inflate_brush(const Depsgraph &depsgraph, boundary.initial_vert_position, strength, deform_target); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } /** \} */ @@ -2152,12 +2173,14 @@ static void do_grab_brush(const Depsgraph &depsgraph, deform_target, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { - SubdivCCG &subdiv_ccg = *ss.subdiv_ccg; + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; threading::EnumerableThreadSpecific all_tls; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { @@ -2175,6 +2198,8 @@ static void do_grab_brush(const Depsgraph &depsgraph, boundary.initial_vert_position, strength, deform_target); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -2196,11 +2221,14 @@ static void do_grab_brush(const Depsgraph &depsgraph, boundary.initial_vert_position, strength, deform_target); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } /** \} */ @@ -2436,12 +2464,14 @@ static void do_twist_brush(const Depsgraph &depsgraph, deform_target, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { - SubdivCCG &subdiv_ccg = *ss.subdiv_ccg; + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; threading::EnumerableThreadSpecific all_tls; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { @@ -2460,6 +2490,8 @@ static void do_twist_brush(const Depsgraph &depsgraph, boundary.initial_vert_position, strength, deform_target); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -2482,11 +2514,14 @@ static void do_twist_brush(const Depsgraph &depsgraph, boundary.initial_vert_position, strength, deform_target); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } /** \} */ @@ -2841,12 +2876,14 @@ static void do_smooth_brush(const Depsgraph &depsgraph, deform_target, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { - SubdivCCG &subdiv_ccg = *ss.subdiv_ccg; + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; threading::EnumerableThreadSpecific all_tls; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { @@ -2862,6 +2899,8 @@ static void do_smooth_brush(const Depsgraph &depsgraph, boundary.initial_vert_position, strength, deform_target); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -2881,11 +2920,14 @@ static void do_smooth_brush(const Depsgraph &depsgraph, boundary.initial_vert_position, strength, deform_target); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } /* -------------------------------------------------------------------- */ diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.cc b/source/blender/editors/sculpt_paint/sculpt_cloth.cc index b29ccc1c6ac..6e7fabb9c94 100644 --- a/source/blender/editors/sculpt_paint/sculpt_cloth.cc +++ b/source/blender/editors/sculpt_paint/sculpt_cloth.cc @@ -1431,6 +1431,8 @@ void do_simulation_step(const Depsgraph &depsgraph, cloth_sim.node_state[cloth_sim.node_state_index.lookup(&nodes[i])] = SCULPT_CLOTH_NODE_INACTIVE; + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; @@ -1468,6 +1470,8 @@ void do_simulation_step(const Depsgraph &depsgraph, cloth_sim.node_state[cloth_sim.node_state_index.lookup(&nodes[i])] = SCULPT_CLOTH_NODE_INACTIVE; + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -1501,11 +1505,14 @@ void do_simulation_step(const Depsgraph &depsgraph, cloth_sim.node_state[cloth_sim.node_state_index.lookup(&nodes[i])] = SCULPT_CLOTH_NODE_INACTIVE; + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } static void cloth_brush_apply_brush_foces(const Depsgraph &depsgraph, @@ -2342,11 +2349,14 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent object, tls); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { FilterLocalData &tls = all_tls.local(); @@ -2354,6 +2364,7 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent apply_filter_forces_grids( *depsgraph, filter_type, filter_strength, gravity, nodes[i], object, tls); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -2366,11 +2377,13 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent apply_filter_forces_bmesh( *depsgraph, filter_type, filter_strength, gravity, nodes[i], object, tls); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); /* Activate all nodes. */ sim_activate_nodes(object, *ss.filter_cache->cloth_sim, node_mask); diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.cc b/source/blender/editors/sculpt_paint/sculpt_face_set.cc index 1c59dddb8f4..afe408f2c45 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.cc +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.cc @@ -1470,6 +1470,7 @@ static void edit_modify_coordinates( BLI_assert_unreachable(); } + bke::pbvh::update_bounds(depsgraph, ob, pbvh); flush_update_step(C, UpdateType::Position); flush_update_done(C, ob, UpdateType::Position); undo::push_end(ob); diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.cc b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.cc index e0c1ed19ff0..830165a9a84 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.cc +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.cc @@ -2297,6 +2297,7 @@ static void sculpt_mesh_filter_apply(bContext *C, wmOperator *op) ss.filter_cache->iteration_count++; + bke::pbvh::update_bounds(depsgraph, ob, *bke::object::pbvh_get(ob)); flush_update_step(C, UpdateType::Position); } diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.cc b/source/blender/editors/sculpt_paint/sculpt_paint_color.cc index 04bae8bd93a..9133b367c50 100644 --- a/source/blender/editors/sculpt_paint/sculpt_paint_color.cc +++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.cc @@ -591,6 +591,7 @@ void do_paint_brush(const Depsgraph &depsgraph, nodes[i], tls, color_attribute); + BKE_pbvh_node_mark_update_color(nodes[i]); }); }); color_attribute.finish(); @@ -667,6 +668,7 @@ void do_paint_brush(const Depsgraph &depsgraph, tls, ss.cache->paint_brush.mix_colors, color_attribute); + BKE_pbvh_node_mark_update_color(nodes[i]); }); }); color_attribute.finish(); @@ -890,6 +892,7 @@ void do_smear_brush(const Depsgraph &depsgraph, nodes[i], tls, color_attribute); + BKE_pbvh_node_mark_update_color(nodes[i]); }); }); } @@ -921,6 +924,7 @@ void do_smear_brush(const Depsgraph &depsgraph, nodes[i], tls, color_attribute); + BKE_pbvh_node_mark_update_color(nodes[i]); }); }); } diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.cc b/source/blender/editors/sculpt_paint/sculpt_pose.cc index adbfbd8920d..9de10bd5436 100644 --- a/source/blender/editors/sculpt_paint/sculpt_pose.cc +++ b/source/blender/editors/sculpt_paint/sculpt_pose.cc @@ -1595,16 +1595,22 @@ void do_pose_brush(const Depsgraph &depsgraph, node_mask.slice(range).foreach_index([&](const int i) { calc_mesh(depsgraph, sd, brush, positions_eval, nodes[i], ob, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *ob.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { BrushLocalData &tls = all_tls.local(); - node_mask.slice(range).foreach_index( - [&](const int i) { calc_grids(depsgraph, sd, brush, nodes[i], ob, tls); }); + node_mask.slice(range).foreach_index([&](const int i) { + calc_grids(depsgraph, sd, brush, nodes[i], ob, tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); + }); }); break; } @@ -1612,12 +1618,16 @@ void do_pose_brush(const Depsgraph &depsgraph, MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { BrushLocalData &tls = all_tls.local(); - node_mask.slice(range).foreach_index( - [&](const int i) { calc_bmesh(depsgraph, sd, brush, nodes[i], ob, tls); }); + node_mask.slice(range).foreach_index([&](const int i) { + calc_bmesh(depsgraph, sd, brush, nodes[i], ob, tls); + BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); + }); }); break; } } + bke::pbvh::flush_bounds_to_parents(pbvh); } } // namespace blender::ed::sculpt_paint::pose diff --git a/source/blender/editors/sculpt_paint/sculpt_project.cc b/source/blender/editors/sculpt_paint/sculpt_project.cc index b304cf875e2..88f35f1e62f 100644 --- a/source/blender/editors/sculpt_paint/sculpt_project.cc +++ b/source/blender/editors/sculpt_paint/sculpt_project.cc @@ -167,11 +167,14 @@ static void gesture_apply_for_symmetry_pass(bContext &C, gesture::GestureData &g tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); undo::push_nodes(depsgraph, object, node_mask, undo::Type::Position); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { @@ -179,6 +182,7 @@ static void gesture_apply_for_symmetry_pass(bContext &C, gesture::GestureData &g node_mask.slice(range).foreach_index([&](const int i) { apply_projection_grids(sd, gesture_data, nodes[i], object, tls); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -191,6 +195,7 @@ static void gesture_apply_for_symmetry_pass(bContext &C, gesture::GestureData &g node_mask.slice(range).foreach_index([&](const int i) { apply_projection_bmesh(sd, gesture_data, nodes[i], object, tls); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; @@ -203,6 +208,7 @@ static void gesture_apply_for_symmetry_pass(bContext &C, gesture::GestureData &g BLI_assert_unreachable(); break; } + bke::pbvh::flush_bounds_to_parents(pbvh); } static void gesture_end(bContext &C, gesture::GestureData &gesture_data) diff --git a/source/blender/editors/sculpt_paint/sculpt_transform.cc b/source/blender/editors/sculpt_paint/sculpt_transform.cc index 084147756d6..14a189bdaa9 100644 --- a/source/blender/editors/sculpt_paint/sculpt_transform.cc +++ b/source/blender/editors/sculpt_paint/sculpt_transform.cc @@ -506,11 +506,14 @@ static void transform_radius_elastic(const Depsgraph &depsgraph, tls, positions_orig); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_mesh(positions_eval, nodes[i]); }); }); break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *ob.sculpt->subdiv_ccg; + MutableSpan positions = subdiv_ccg.positions; MutableSpan nodes = pbvh.nodes(); threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { TransformLocalData &tls = all_tls.local(); @@ -518,6 +521,7 @@ static void transform_radius_elastic(const Depsgraph &depsgraph, elastic_transform_node_grids( sd, params, elastic_transform_mat, elastic_transform_pivot, nodes[i], ob, tls); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]); }); }); break; @@ -530,12 +534,14 @@ static void transform_radius_elastic(const Depsgraph &depsgraph, elastic_transform_node_bmesh( sd, params, elastic_transform_mat, elastic_transform_pivot, nodes[i], ob, tls); BKE_pbvh_node_mark_positions_update(nodes[i]); + bke::pbvh::update_node_bounds_bmesh(nodes[i]); }); }); break; } } } + bke::pbvh::flush_bounds_to_parents(pbvh); } void update_modal_transform(bContext *C, Object &ob)