diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mask.cc b/source/blender/editors/sculpt_paint/sculpt_filter_mask.cc index adb8c38b6c8..3759c369973 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mask.cc +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mask.cc @@ -46,6 +46,23 @@ enum class FilterType { ContrastDecrease = 6, }; +BLI_NOINLINE static void copy_old_hidden_mask_mesh(const Span verts, + const Span hide_vert, + const Span mask, + const MutableSpan new_mask) +{ + BLI_assert(verts.size() == new_mask.size()); + if (hide_vert.is_empty()) { + return; + } + + for (const int i : verts.index_range()) { + if (hide_vert[verts[i]]) { + new_mask[i] = mask[verts[i]]; + } + } +} + BLI_NOINLINE static void multiply_add(const Span src, const float factor, const float offset, @@ -109,7 +126,6 @@ struct FilterLocalData { static void apply_new_mask_mesh(const Depsgraph &depsgraph, Object &object, - const Span hide_vert, const IndexMask &node_mask, const OffsetIndices node_verts, const Span new_mask, @@ -117,15 +133,13 @@ static void apply_new_mask_mesh(const Depsgraph &depsgraph, { bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object); MutableSpan nodes = pbvh.nodes(); - threading::EnumerableThreadSpecific> all_tls; Array node_changed(node_mask.min_array_size(), false); node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) { - Vector &tls = all_tls.local(); - const Span verts = hide::node_visible_verts(nodes[i], hide_vert, tls); + const Span verts = nodes[i].verts(); const Span new_node_mask = new_mask.slice(node_verts[pos]); - if (array_utils::indexed_data_equal(mask, verts, new_node_mask)) { + if (array_utils::indexed_data_equal(mask, verts, new_mask)) { return; } undo::push_node(depsgraph, object, &nodes[i], undo::Type::Mask); @@ -142,6 +156,7 @@ static void smooth_mask_mesh(const OffsetIndices faces, const Span corner_verts, const GroupedSpan vert_to_face_map, const Span hide_poly, + const Span hide_vert, const Span mask, const bke::pbvh::MeshNode &node, FilterLocalData &tls, @@ -154,12 +169,14 @@ static void smooth_mask_mesh(const OffsetIndices faces, calc_vert_neighbors(faces, corner_verts, vert_to_face_map, hide_poly, verts, neighbors); smooth::neighbor_data_average_mesh(mask, neighbors, new_mask); + copy_old_hidden_mask_mesh(verts, hide_vert, mask, new_mask); } static void sharpen_mask_mesh(const OffsetIndices faces, const Span corner_verts, const GroupedSpan vert_to_face_map, const Span hide_poly, + const Span hide_vert, const Span mask, const bke::pbvh::MeshNode &node, FilterLocalData &tls, @@ -178,12 +195,14 @@ static void sharpen_mask_mesh(const OffsetIndices faces, smooth::neighbor_data_average_mesh(mask, neighbors, new_mask); sharpen_masks(node_mask, new_mask); + copy_old_hidden_mask_mesh(verts, hide_vert, mask, new_mask); } static void grow_mask_mesh(const OffsetIndices faces, const Span corner_verts, const GroupedSpan vert_to_face_map, const Span hide_poly, + const Span hide_vert, const Span mask, const bke::pbvh::MeshNode &node, FilterLocalData &tls, @@ -201,12 +220,14 @@ static void grow_mask_mesh(const OffsetIndices faces, new_mask[i] = std::max(mask[neighbor], new_mask[i]); } } + copy_old_hidden_mask_mesh(verts, hide_vert, mask, new_mask); } static void shrink_mask_mesh(const OffsetIndices faces, const Span corner_verts, const GroupedSpan vert_to_face_map, const Span hide_poly, + const Span hide_vert, const Span mask, const bke::pbvh::MeshNode &node, FilterLocalData &tls, @@ -224,6 +245,7 @@ static void shrink_mask_mesh(const OffsetIndices faces, new_mask[i] = std::min(mask[neighbor], new_mask[i]); } } + copy_old_hidden_mask_mesh(verts, hide_vert, mask, new_mask); } static bool increase_contrast_mask_mesh(const Depsgraph &depsgraph, @@ -240,6 +262,7 @@ static bool increase_contrast_mask_mesh(const Depsgraph &depsgraph, tls.new_mask.resize(verts.size()); const MutableSpan new_mask = tls.new_mask; mask_increase_contrast(node_mask, new_mask); + copy_old_hidden_mask_mesh(verts, hide_vert, mask, new_mask); if (node_mask == new_mask.as_span()) { return false; @@ -265,6 +288,7 @@ static bool decrease_contrast_mask_mesh(const Depsgraph &depsgraph, tls.new_mask.resize(verts.size()); const MutableSpan new_mask = tls.new_mask; mask_decrease_contrast(node_mask, new_mask); + copy_old_hidden_mask_mesh(verts, hide_vert, mask, new_mask); if (node_mask == new_mask.as_span()) { return false; @@ -721,13 +745,13 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op) corner_verts, vert_to_face_map, hide_poly, + hide_vert, mask.span, nodes[i], tls, new_masks.as_mutable_span().slice(node_offsets[pos])); }); - apply_new_mask_mesh( - *depsgraph, ob, hide_vert, node_mask, node_offsets, new_masks, mask.span); + apply_new_mask_mesh(*depsgraph, ob, node_mask, node_offsets, new_masks, mask.span); break; } case FilterType::Sharpen: { @@ -737,13 +761,13 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op) corner_verts, vert_to_face_map, hide_poly, + hide_vert, mask.span, nodes[i], tls, new_masks.as_mutable_span().slice(node_offsets[pos])); }); - apply_new_mask_mesh( - *depsgraph, ob, hide_vert, node_mask, node_offsets, new_masks, mask.span); + apply_new_mask_mesh(*depsgraph, ob, node_mask, node_offsets, new_masks, mask.span); break; } case FilterType::Grow: { @@ -753,13 +777,13 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op) corner_verts, vert_to_face_map, hide_poly, + hide_vert, mask.span, nodes[i], tls, new_masks.as_mutable_span().slice(node_offsets[pos])); }); - apply_new_mask_mesh( - *depsgraph, ob, hide_vert, node_mask, node_offsets, new_masks, mask.span); + apply_new_mask_mesh(*depsgraph, ob, node_mask, node_offsets, new_masks, mask.span); break; } case FilterType::Shrink: { @@ -769,13 +793,13 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op) corner_verts, vert_to_face_map, hide_poly, + hide_vert, mask.span, nodes[i], tls, new_masks.as_mutable_span().slice(node_offsets[pos])); }); - apply_new_mask_mesh( - *depsgraph, ob, hide_vert, node_mask, node_offsets, new_masks, mask.span); + apply_new_mask_mesh(*depsgraph, ob, node_mask, node_offsets, new_masks, mask.span); break; } case FilterType::ContrastIncrease: {