From 30c1475dfd12d3723cf5100bd427a2e6954ebddb Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 13 Sep 2024 17:29:25 -0400 Subject: [PATCH] Sculpt: Update node mask status eagerly Similar to 7b69c8249471ac4f575440750a334d3ca27a4065. We didn't make any good use of the time in between changing mask values and recalculating whether nodes were fully masked or not masked at all. There was no point in the lazy calculation. Eager calculation should be faster too, for the same reason as the above commit. Part of #118145. --- source/blender/blenkernel/BKE_pbvh.hh | 1 - source/blender/blenkernel/BKE_pbvh_api.hh | 6 +- source/blender/blenkernel/intern/pbvh.cc | 70 +++++-------------- .../blender/blenkernel/intern/pbvh_bmesh.cc | 3 + .../editors/sculpt_paint/brushes/mask.cc | 8 +++ .../sculpt_paint/brushes/smooth_mask.cc | 3 + .../editors/sculpt_paint/paint_mask.cc | 9 +-- source/blender/editors/sculpt_paint/sculpt.cc | 7 +- .../editors/sculpt_paint/sculpt_expand.cc | 5 ++ .../sculpt_paint/sculpt_filter_mask.cc | 9 +++ .../editors/sculpt_paint/sculpt_mask_init.cc | 4 +- .../editors/sculpt_paint/sculpt_ops.cc | 10 ++- .../editors/sculpt_paint/sculpt_undo.cc | 22 +++--- 13 files changed, 77 insertions(+), 80 deletions(-) diff --git a/source/blender/blenkernel/BKE_pbvh.hh b/source/blender/blenkernel/BKE_pbvh.hh index 5086701c27f..2631042de5e 100644 --- a/source/blender/blenkernel/BKE_pbvh.hh +++ b/source/blender/blenkernel/BKE_pbvh.hh @@ -31,7 +31,6 @@ enum PBVHNodeFlags { PBVH_UpdateDrawBuffers = 1 << 4, PBVH_UpdateRedraw = 1 << 5, - PBVH_UpdateMask = 1 << 6, PBVH_UpdateVisibility = 1 << 8, PBVH_RebuildDrawBuffers = 1 << 9, diff --git a/source/blender/blenkernel/BKE_pbvh_api.hh b/source/blender/blenkernel/BKE_pbvh_api.hh index 23d96b3d0ff..b48e10a1ff8 100644 --- a/source/blender/blenkernel/BKE_pbvh_api.hh +++ b/source/blender/blenkernel/BKE_pbvh_api.hh @@ -489,7 +489,11 @@ void update_bounds_bmesh(const BMesh &bm, Tree &pbvh); */ void store_bounds_orig(Tree &pbvh); -void update_mask(const Object &object, Tree &pbvh); +/** Update node "fully masked" and "fully unmasked" values after mask values have been changed. */ +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). */ diff --git a/source/blender/blenkernel/intern/pbvh.cc b/source/blender/blenkernel/intern/pbvh.cc index 3582c411df3..50bb7cc847c 100644 --- a/source/blender/blenkernel/intern/pbvh.cc +++ b/source/blender/blenkernel/intern/pbvh.cc @@ -295,6 +295,8 @@ std::unique_ptr build_mesh(const Mesh &mesh) }); } + update_mask_mesh(mesh, nodes.index_range(), *pbvh); + return pbvh; } @@ -483,6 +485,8 @@ std::unique_ptr build_grids(const Mesh &base_mesh, const SubdivCCG &subdiv }); } + update_mask_grids(subdiv_ccg, nodes.index_range(), *pbvh); + return pbvh; } @@ -1211,26 +1215,23 @@ void node_update_mask_mesh(const Span mask, MeshNode &node) verts.begin(), verts.end(), [&](const int vert) { return mask[vert] <= 0.0f; }); SET_FLAG_FROM_TEST(node.flag_, fully_masked, PBVH_FullyMasked); SET_FLAG_FROM_TEST(node.flag_, fully_unmasked, PBVH_FullyUnmasked); - node.flag_ &= ~PBVH_UpdateMask; } -static void update_mask_mesh(const Mesh &mesh, - const MutableSpan nodes, - const IndexMask &nodes_to_update) +void update_mask_mesh(const Mesh &mesh, const IndexMask &node_mask, Tree &pbvh) { + const MutableSpan nodes = pbvh.nodes(); const AttributeAccessor attributes = mesh.attributes(); const VArraySpan mask = *attributes.lookup(".sculpt_mask", AttrDomain::Point); if (mask.is_empty()) { - nodes_to_update.foreach_index([&](const int i) { + node_mask.foreach_index([&](const int i) { nodes[i].flag_ &= ~PBVH_FullyMasked; nodes[i].flag_ |= PBVH_FullyUnmasked; - nodes[i].flag_ &= ~PBVH_UpdateMask; }); return; } - nodes_to_update.foreach_index(GrainSize(1), - [&](const int i) { node_update_mask_mesh(mask, nodes[i]); }); + node_mask.foreach_index(GrainSize(1), + [&](const int i) { node_update_mask_mesh(mask, nodes[i]); }); } void node_update_mask_grids(const CCGKey &key, const Span masks, GridsNode &node) @@ -1245,24 +1246,21 @@ void node_update_mask_grids(const CCGKey &key, const Span masks, GridsNod } SET_FLAG_FROM_TEST(node.flag_, fully_masked, PBVH_FullyMasked); SET_FLAG_FROM_TEST(node.flag_, fully_unmasked, PBVH_FullyUnmasked); - node.flag_ &= ~PBVH_UpdateMask; } -static void update_mask_grids(const SubdivCCG &subdiv_ccg, - const MutableSpan nodes, - const IndexMask &nodes_to_update) +void update_mask_grids(const SubdivCCG &subdiv_ccg, const IndexMask &node_mask, Tree &pbvh) { + const MutableSpan nodes = pbvh.nodes(); const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg); if (subdiv_ccg.masks.is_empty()) { - nodes_to_update.foreach_index([&](const int i) { + node_mask.foreach_index([&](const int i) { nodes[i].flag_ &= ~PBVH_FullyMasked; nodes[i].flag_ |= PBVH_FullyUnmasked; - nodes[i].flag_ &= ~PBVH_UpdateMask; }); return; } - nodes_to_update.foreach_index( + node_mask.foreach_index( GrainSize(1), [&](const int i) { node_update_mask_grids(key, subdiv_ccg.masks, nodes[i]); }); } @@ -1281,52 +1279,22 @@ void node_update_mask_bmesh(const int mask_offset, BMeshNode &node) } SET_FLAG_FROM_TEST(node.flag_, fully_masked, PBVH_FullyMasked); SET_FLAG_FROM_TEST(node.flag_, fully_unmasked, PBVH_FullyUnmasked); - node.flag_ &= ~PBVH_UpdateMask; } -static void update_mask_bmesh(const BMesh &bm, - const MutableSpan nodes, - const IndexMask &nodes_to_update) +void update_mask_bmesh(const BMesh &bm, const IndexMask &node_mask, Tree &pbvh) { + const MutableSpan nodes = pbvh.nodes(); const int offset = CustomData_get_offset_named(&bm.vdata, CD_PROP_FLOAT, ".sculpt_mask"); if (offset == -1) { - nodes_to_update.foreach_index([&](const int i) { + node_mask.foreach_index([&](const int i) { nodes[i].flag_ &= ~PBVH_FullyMasked; nodes[i].flag_ |= PBVH_FullyUnmasked; - nodes[i].flag_ &= ~PBVH_UpdateMask; }); return; } - nodes_to_update.foreach_index(GrainSize(1), - [&](const int i) { node_update_mask_bmesh(offset, nodes[i]); }); -} - -void update_mask(const Object &object, Tree &pbvh) -{ - IndexMaskMemory memory; - const IndexMask nodes_to_update = search_nodes( - pbvh, memory, [&](const Node &node) { return update_search(node, PBVH_UpdateMask); }); - - switch (pbvh.type()) { - case Type::Mesh: { - const Mesh &mesh = *static_cast(object.data); - update_mask_mesh(mesh, pbvh.nodes(), nodes_to_update); - break; - } - case Type::Grids: { - const SculptSession &ss = *object.sculpt; - const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg; - update_mask_grids(subdiv_ccg, pbvh.nodes(), nodes_to_update); - break; - } - case Type::BMesh: { - const SculptSession &ss = *object.sculpt; - const BMesh &bm = *ss.bm; - update_mask_bmesh(bm, pbvh.nodes(), nodes_to_update); - break; - } - } + node_mask.foreach_index(GrainSize(1), + [&](const int i) { node_update_mask_bmesh(offset, nodes[i]); }); } void node_update_visibility_mesh(const Span hide_vert, MeshNode &node) @@ -1546,7 +1514,7 @@ void BKE_pbvh_node_mark_update(blender::bke::pbvh::Node &node) void BKE_pbvh_node_mark_update_mask(blender::bke::pbvh::Node &node) { - node.flag_ |= PBVH_UpdateMask | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw; + node.flag_ |= PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw; } void BKE_pbvh_mark_rebuild_pixels(blender::bke::pbvh::Tree &pbvh) diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.cc b/source/blender/blenkernel/intern/pbvh_bmesh.cc index cfa8b4d8c80..3851db36813 100644 --- a/source/blender/blenkernel/intern/pbvh_bmesh.cc +++ b/source/blender/blenkernel/intern/pbvh_bmesh.cc @@ -2289,6 +2289,8 @@ std::unique_ptr build_bmesh(BMesh *bm) } }); + update_mask_bmesh(*bm, nodes.index_range(), *pbvh); + BLI_memarena_free(arena); return pbvh; } @@ -2499,6 +2501,7 @@ void BKE_pbvh_bmesh_after_stroke(BMesh &bm, blender::bke::pbvh::Tree &pbvh) IndexMaskMemory memory; const IndexMask node_mask = IndexMask::from_bools(node_changed, memory); pbvh.tag_positions_changed(node_mask); + update_mask_bmesh(bm, node_mask, pbvh); } void BKE_pbvh_node_mark_topology_update(blender::bke::pbvh::Node &node) diff --git a/source/blender/editors/sculpt_paint/brushes/mask.cc b/source/blender/editors/sculpt_paint/brushes/mask.cc index 1d03c04f546..cbbc608e6b5 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_update_mask_mesh(mask.span, nodes[i]); BKE_pbvh_node_mark_update_mask(nodes[i]); }); }); @@ -251,22 +252,29 @@ void do_mask_brush(const Depsgraph &depsgraph, break; } case blender::bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *ss.subdiv_ccg; + const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg); + MutableSpan masks = subdiv_ccg.masks; 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); + bke::pbvh::node_update_mask_grids(key, masks, nodes[i]); BKE_pbvh_node_mark_update_mask(nodes[i]); }); }); break; } case blender::bke::pbvh::Type::BMesh: { + const int mask_offset = CustomData_get_offset_named( + &ss.bm->vdata, CD_PROP_FLOAT, ".sculpt_mask"); 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); + bke::pbvh::node_update_mask_bmesh(mask_offset, nodes[i]); BKE_pbvh_node_mark_update_mask(nodes[i]); }); }); diff --git a/source/blender/editors/sculpt_paint/brushes/smooth_mask.cc b/source/blender/editors/sculpt_paint/brushes/smooth_mask.cc index 15e815b95a8..7a5a799ee0b 100644 --- a/source/blender/editors/sculpt_paint/brushes/smooth_mask.cc +++ b/source/blender/editors/sculpt_paint/brushes/smooth_mask.cc @@ -175,6 +175,7 @@ static void do_smooth_brush_mesh(const Depsgraph &depsgraph, BKE_pbvh_node_mark_update_mask(nodes[i]); }); } + bke::pbvh::update_mask_mesh(mesh, node_mask, pbvh); mask.finish(); } @@ -311,6 +312,7 @@ void do_smooth_mask_brush(const Depsgraph &depsgraph, }); }); } + bke::pbvh::update_mask_grids(*ss.subdiv_ccg, node_mask, pbvh); break; } case bke::pbvh::Type::BMesh: { @@ -329,6 +331,7 @@ void do_smooth_mask_brush(const Depsgraph &depsgraph, }); }); } + bke::pbvh::update_mask_bmesh(*ss.bm, node_mask, pbvh); break; } } diff --git a/source/blender/editors/sculpt_paint/paint_mask.cc b/source/blender/editors/sculpt_paint/paint_mask.cc index 53e640556b5..8f5e318813f 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.cc +++ b/source/blender/editors/sculpt_paint/paint_mask.cc @@ -214,7 +214,7 @@ void update_mask_mesh(const Depsgraph &depsgraph, } undo::push_node(depsgraph, object, &nodes[i], undo::Type::Mask); scatter_data_mesh(tls.mask.as_span(), verts, mask.span); - bke::pbvh::node_update_mask_mesh(mask.span, static_cast(nodes[i])); + bke::pbvh::node_update_mask_mesh(mask.span, nodes[i]); BKE_pbvh_node_mark_redraw(nodes[i]); }); }); @@ -361,7 +361,6 @@ static bool try_remove_mask_mesh(const Depsgraph &depsgraph, }); attributes.remove(".sculpt_mask"); - /* Avoid calling #BKE_pbvh_node_mark_update_mask by doing that update here. */ node_mask.foreach_index([&](const int i) { BKE_pbvh_node_fully_masked_set(nodes[i], false); BKE_pbvh_node_fully_unmasked_set(nodes[i], true); @@ -404,7 +403,6 @@ static void fill_mask_mesh(const Depsgraph &depsgraph, }); mask.finish(); - /* Avoid calling #BKE_pbvh_node_mark_update_mask by doing that update here. */ node_mask.foreach_index([&](const int i) { BKE_pbvh_node_fully_masked_set(nodes[i], value == 1.0f); BKE_pbvh_node_fully_unmasked_set(nodes[i], value == 0.0f); @@ -468,7 +466,6 @@ static void fill_mask_grids(Main &bmain, if (any_changed) { multires_mark_as_modified(&depsgraph, &object, MULTIRES_COORDS_MODIFIED); } - /* Avoid calling #BKE_pbvh_node_mark_update_mask by doing that update here. */ node_mask.foreach_index([&](const int i) { BKE_pbvh_node_fully_masked_set(nodes[i], value == 1.0f); BKE_pbvh_node_fully_unmasked_set(nodes[i], value == 0.0f); @@ -510,7 +507,6 @@ static void fill_mask_bmesh(const Depsgraph &depsgraph, BKE_pbvh_node_mark_redraw(nodes[i]); } }); - /* Avoid calling #BKE_pbvh_node_mark_update_mask by doing that update here. */ node_mask.foreach_index([&](const int i) { BKE_pbvh_node_fully_masked_set(nodes[i], value == 1.0f); BKE_pbvh_node_fully_unmasked_set(nodes[i], value == 0.0f); @@ -767,6 +763,7 @@ static void gesture_apply_for_symmetry_pass(bContext & /*C*/, gesture::GestureDa mask = mask_gesture_get_new_value(mask, op.mode, op.value); } }); + bke::pbvh::node_update_mask_grids(key, masks, nodes[i]); BKE_pbvh_node_mark_update_mask(nodes[i]); } }); @@ -792,6 +789,7 @@ static void gesture_apply_for_symmetry_pass(bContext & /*C*/, gesture::GestureDa BM_ELEM_CD_SET_FLOAT(vert, offset, new_mask); } } + bke::pbvh::node_update_mask_bmesh(offset, nodes[i]); BKE_pbvh_node_mark_update_mask(nodes[i]); }); }); @@ -807,7 +805,6 @@ static void gesture_end(bContext &C, gesture::GestureData &gesture_data) if (bke::object::pbvh_get(object)->type() == bke::pbvh::Type::Grids) { multires_mark_as_modified(depsgraph, &object, MULTIRES_COORDS_MODIFIED); } - bke::pbvh::update_mask(object, *bke::object::pbvh_get(object)); undo::push_end(object); } diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 121bf1abffb..35ccf8a1a1e 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -1225,6 +1225,7 @@ static void restore_mask_from_undo_step(Object &object) { const Span verts = nodes[i].verts(); array_utils::scatter(*orig_data, verts, mask.span); + bke::pbvh::node_update_mask_mesh(mask.span, nodes[i]); BKE_pbvh_node_mark_update_mask(nodes[i]); } }); @@ -1239,6 +1240,7 @@ static void restore_mask_from_undo_step(Object &object) for (BMVert *vert : BKE_pbvh_bmesh_node_unique_verts(&nodes[i])) { if (const float *orig_mask = BM_log_find_original_vert_mask(ss.bm_log, vert)) { BM_ELEM_CD_SET_FLOAT(vert, offset, *orig_mask); + bke::pbvh::node_update_mask_bmesh(offset, nodes[i]); BKE_pbvh_node_mark_update_mask(nodes[i]); } } @@ -1266,6 +1268,7 @@ static void restore_mask_from_undo_step(Object &object) index++; } } + bke::pbvh::node_update_mask_grids(key, masks, nodes[i]); BKE_pbvh_node_mark_update_mask(nodes[i]); } }); @@ -5450,10 +5453,6 @@ void flush_update_done(const bContext *C, Object &ob, UpdateType update_type) SCULPT_fake_neighbors_free(ob); } - if (update_type == UpdateType::Mask) { - bke::pbvh::update_mask(ob, pbvh); - } - if (update_type == UpdateType::Position) { if (pbvh.type() == bke::pbvh::Type::BMesh) { BKE_pbvh_bmesh_after_stroke(*ss.bm, pbvh); diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.cc b/source/blender/editors/sculpt_paint/sculpt_expand.cc index 3bb71b211ae..e75cf1b76b6 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.cc +++ b/source/blender/editors/sculpt_paint/sculpt_expand.cc @@ -1466,6 +1466,7 @@ static void write_mask_data(Object &object, const Span mask) attributes.add(".sculpt_mask", bke::AttrDomain::Point, bke::AttributeInitVArray(VArray::ForSpan(mask))); + bke::pbvh::update_mask_mesh(mesh, node_mask, pbvh); MutableSpan nodes = pbvh.nodes(); node_mask.foreach_index([&](const int i) { BKE_pbvh_node_mark_update_mask(nodes[i]); }); break; @@ -1478,6 +1479,7 @@ static void write_mask_data(Object &object, const Span mask) for (const int i : mask.index_range()) { BM_ELEM_CD_SET_FLOAT(BM_vert_at_index(&bm, i), offset, mask[i]); } + bke::pbvh::update_mask_bmesh(bm, node_mask, pbvh); MutableSpan nodes = pbvh.nodes(); node_mask.foreach_index([&](const int i) { BKE_pbvh_node_mark_update_mask(nodes[i]); }); break; @@ -1485,6 +1487,7 @@ static void write_mask_data(Object &object, const Span mask) case bke::pbvh::Type::Grids: { SubdivCCG &subdiv_ccg = *ss.subdiv_ccg; subdiv_ccg.masks.as_mutable_span().copy_from(mask); + bke::pbvh::update_mask_grids(subdiv_ccg, node_mask, pbvh); MutableSpan nodes = pbvh.nodes(); node_mask.foreach_index([&](const int i) { BKE_pbvh_node_mark_update_mask(nodes[i]); }); break; @@ -1616,6 +1619,7 @@ static void update_mask_grids(const SculptSession &ss, } if (any_changed) { BKE_pbvh_node_mark_update_mask(node); + bke::pbvh::node_update_mask_grids(key, masks, node); } } @@ -1662,6 +1666,7 @@ static void update_mask_bmesh(SculptSession &ss, } if (any_changed) { BKE_pbvh_node_mark_update_mask(*node); + bke::pbvh::node_update_mask_bmesh(mask_offset, *node); } } diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mask.cc b/source/blender/editors/sculpt_paint/sculpt_filter_mask.cc index 65282566f09..e56fb01aa32 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mask.cc +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mask.cc @@ -126,6 +126,7 @@ static void apply_new_mask_mesh(const Depsgraph &depsgraph, } undo::push_node(depsgraph, object, &nodes[i], undo::Type::Mask); scatter_data_mesh(new_node_mask, verts, mask); + bke::pbvh::node_update_mask_mesh(mask, nodes[i]); BKE_pbvh_node_mark_update_mask(nodes[i]); }); } @@ -239,6 +240,7 @@ static void increase_contrast_mask_mesh(const Depsgraph &depsgraph, undo::push_node(depsgraph, object, &node, undo::Type::Mask); scatter_data_mesh(new_mask.as_span(), verts, mask); + bke::pbvh::node_update_mask_mesh(mask, node); BKE_pbvh_node_mark_update_mask(node); } @@ -263,6 +265,7 @@ static void decrease_contrast_mask_mesh(const Depsgraph &depsgraph, undo::push_node(depsgraph, object, &node, undo::Type::Mask); scatter_data_mesh(new_mask.as_span(), verts, mask); + bke::pbvh::node_update_mask_mesh(mask, node); BKE_pbvh_node_mark_update_mask(node); } @@ -305,6 +308,7 @@ static void apply_new_mask_grids(const Depsgraph &depsgraph, } undo::push_node(depsgraph, object, &nodes[i], undo::Type::Mask); scatter_data_grids(subdiv_ccg, new_node_mask, grids, masks); + bke::pbvh::node_update_mask_grids(key, masks, nodes[i]); BKE_pbvh_node_mark_update_mask(nodes[i]); }); @@ -436,6 +440,7 @@ static void increase_contrast_mask_grids(const Depsgraph &depsgraph, undo::push_node(depsgraph, object, &node, undo::Type::Mask); scatter_data_grids(subdiv_ccg, new_mask.as_span(), grids, subdiv_ccg.masks.as_mutable_span()); + bke::pbvh::node_update_mask_grids(key, subdiv_ccg.masks, node); BKE_pbvh_node_mark_update_mask(node); } @@ -467,6 +472,7 @@ static void decrease_contrast_mask_grids(const Depsgraph &depsgraph, undo::push_node(depsgraph, object, &node, undo::Type::Mask); scatter_data_grids(subdiv_ccg, new_mask.as_span(), grids, subdiv_ccg.masks.as_mutable_span()); + bke::pbvh::node_update_mask_grids(key, subdiv_ccg.masks, node); BKE_pbvh_node_mark_update_mask(node); } @@ -503,6 +509,7 @@ static void apply_new_mask_bmesh(const Depsgraph &depsgraph, } undo::push_node(depsgraph, object, &nodes[i], undo::Type::Mask); scatter_mask_bmesh(new_node_mask, bm, verts); + bke::pbvh::node_update_mask_bmesh(mask_offset, nodes[i]); BKE_pbvh_node_mark_update_mask(nodes[i]); }); } @@ -600,6 +607,7 @@ static void increase_contrast_mask_bmesh(const Depsgraph &depsgraph, undo::push_node(depsgraph, object, &node, undo::Type::Mask); scatter_mask_bmesh(new_mask.as_span(), bm, verts); + bke::pbvh::node_update_mask_bmesh(mask_offset, node); BKE_pbvh_node_mark_update_mask(node); } @@ -630,6 +638,7 @@ static void decrease_contrast_mask_bmesh(const Depsgraph &depsgraph, undo::push_node(depsgraph, object, &node, undo::Type::Mask); scatter_mask_bmesh(new_mask.as_span(), bm, verts); + bke::pbvh::node_update_mask_bmesh(mask_offset, node); BKE_pbvh_node_mark_update_mask(node); } diff --git a/source/blender/editors/sculpt_paint/sculpt_mask_init.cc b/source/blender/editors/sculpt_paint/sculpt_mask_init.cc index d5fe8c4e4c6..ce253832e68 100644 --- a/source/blender/editors/sculpt_paint/sculpt_mask_init.cc +++ b/source/blender/editors/sculpt_paint/sculpt_mask_init.cc @@ -103,10 +103,10 @@ static void init_mask_grids( for (const int grid : nodes[i].grids()) { write_fn(grid_hidden, grid, masks.slice(bke::ccg::grid_range(key, grid))); } + bke::pbvh::node_update_mask_grids(key, masks, nodes[i]); BKE_pbvh_node_mark_update_mask(nodes[i]); }); BKE_subdiv_ccg_average_grids(subdiv_ccg); - bke::pbvh::update_mask(object, pbvh); } static int sculpt_mask_init_exec(bContext *C, wmOperator *op) @@ -255,9 +255,9 @@ static int sculpt_mask_init_exec(bContext *C, wmOperator *op) break; } } + bke::pbvh::node_update_mask_bmesh(offset, nodes[i]); BKE_pbvh_node_mark_update_mask(nodes[i]); }); - bke::pbvh::update_mask(ob, pbvh); break; } } diff --git a/source/blender/editors/sculpt_paint/sculpt_ops.cc b/source/blender/editors/sculpt_paint/sculpt_ops.cc index 650fc000998..9cbce71aa80 100644 --- a/source/blender/editors/sculpt_paint/sculpt_ops.cc +++ b/source/blender/editors/sculpt_paint/sculpt_ops.cc @@ -880,7 +880,6 @@ static int sculpt_mask_by_color_invoke(bContext *C, wmOperator *op, const wmEven sculpt_mask_by_color_full_mesh(*depsgraph, ob, active_vert, threshold, invert, preserve_mask); } - bke::pbvh::update_mask(ob, *bke::object::pbvh_get(ob)); undo::push_end(ob); flush_update_done(C, ob, UpdateType::Mask); @@ -1187,27 +1186,32 @@ static int sculpt_bake_cavity_exec(bContext *C, wmOperator *op) break; } case bke::pbvh::Type::Grids: { + SubdivCCG &subdiv_ccg = *ob.sculpt->subdiv_ccg; + const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg); + MutableSpan masks = subdiv_ccg.masks; 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) { bake_mask_grids(*depsgraph, ob, *automasking, mode, factor, nodes[i], tls); + bke::pbvh::node_update_mask_grids(key, masks, nodes[i]); BKE_pbvh_node_mark_update_mask(nodes[i]); }); }); - bke::pbvh::update_mask(ob, pbvh); break; } case bke::pbvh::Type::BMesh: { + const int mask_offset = CustomData_get_offset_named( + &ob.sculpt->bm->vdata, CD_PROP_FLOAT, ".sculpt_mask"); 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) { bake_mask_bmesh(*depsgraph, ob, *automasking, mode, factor, nodes[i], tls); + bke::pbvh::node_update_mask_bmesh(mask_offset, nodes[i]); BKE_pbvh_node_mark_update_mask(nodes[i]); }); }); - bke::pbvh::update_mask(ob, pbvh); break; } } diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.cc b/source/blender/editors/sculpt_paint/sculpt_undo.cc index 7a973a7f672..28da6016ad2 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.cc +++ b/source/blender/editors/sculpt_paint/sculpt_undo.cc @@ -1134,11 +1134,11 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data) for (std::unique_ptr &unode : step_data.nodes) { restore_mask_grids(object, *unode, modified_grids); } - node_mask.foreach_index([&](const int i) { - if (indices_contain_true(modified_grids, nodes[i].grids())) { - BKE_pbvh_node_mark_update_mask(nodes[i]); - } - }); + const IndexMask changed_nodes = IndexMask::from_predicate( + node_mask, GrainSize(1), memory, [&](const int i) { + return indices_contain_true(modified_grids, nodes[i].grids()); + }); + bke::pbvh::update_mask_grids(*ss.subdiv_ccg, changed_nodes, pbvh); } else { MutableSpan nodes = pbvh.nodes(); @@ -1147,14 +1147,12 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data) for (std::unique_ptr &unode : step_data.nodes) { restore_mask_mesh(object, *unode, modified_verts); } - node_mask.foreach_index([&](const int i) { - if (indices_contain_true(modified_verts, nodes[i].all_verts())) { - BKE_pbvh_node_mark_update_mask(nodes[i]); - } - }); + const IndexMask changed_nodes = IndexMask::from_predicate( + node_mask, GrainSize(1), memory, [&](const int i) { + return indices_contain_true(modified_verts, nodes[i].all_verts()); + }); + bke::pbvh::update_mask_mesh(mesh, changed_nodes, pbvh); } - - bke::pbvh::update_mask(object, pbvh); break; } case Type::FaceSet: {