Fix #140556: Mask filter operations behave incorrectly on dense meshes

Mistake in 57c4e9dd2c

Pull Request: https://projects.blender.org/blender/blender/pulls/140570
This commit is contained in:
Sean Kim
2025-06-23 19:22:33 +02:00
committed by Sean Kim
parent 41d8066b1e
commit 7274fdb377
4 changed files with 96 additions and 1 deletions

View File

@@ -140,7 +140,7 @@ static void apply_new_mask_mesh(const Depsgraph &depsgraph,
node_mask.foreach_index(GrainSize(1), [&](const int i, const int pos) {
const Span<int> verts = nodes[i].verts();
const Span<float> new_node_mask = new_mask.slice(node_verts[pos]);
if (array_utils::indexed_data_equal<float>(mask, verts, new_mask)) {
if (array_utils::indexed_data_equal<float>(mask, verts, new_node_mask)) {
return;
}
undo::push_node(depsgraph, object, &nodes[i], undo::Type::Mask);

BIN
tests/files/sculpting/partially_masked_sphere.blend (Stored with Git LFS) Normal file

Binary file not shown.

View File

@@ -1263,6 +1263,13 @@ if(TEST_SRC_DIR_EXISTS)
--
--testdir "${TEST_SRC_DIR}/sculpting"
)
add_blender_test(
bl_sculpt_mask_filter
--python ${CMAKE_CURRENT_LIST_DIR}/sculpt_paint/mask_filter_test.py
--
--testdir "${TEST_SRC_DIR}/sculpting"
)
endif()
if(WITH_GPU_MESH_PAINT_TESTS AND TEST_SRC_DIR_EXISTS)

View File

@@ -0,0 +1,85 @@
# SPDX-FileCopyrightText: 2025 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later */
__all__ = (
"main",
)
import math
import unittest
import sys
import pathlib
import numpy as np
import bpy
"""
blender -b --factory-startup --python tests/python/sculpt_paint/mask_filter_test.py -- --testdir tests/files/sculpting/
"""
args = None
class GrowMaskTest(unittest.TestCase):
def setUp(self):
bpy.ops.wm.open_mainfile(filepath=str(args.testdir / "partially_masked_sphere.blend"), load_ui=False)
bpy.ops.ed.undo_push()
def test_grow_increases_number_of_masked_vertices(self):
mesh = bpy.context.object.data
mask_attr = mesh.attributes['.sculpt_mask']
num_vertices = mesh.attributes.domain_size('POINT')
old_mask_data = np.zeros(num_vertices, dtype=np.float32)
mask_attr.data.foreach_get('value', old_mask_data)
bpy.ops.sculpt.mask_filter(filter_type='GROW')
new_mask_data = np.zeros(num_vertices, dtype=np.float32)
mask_attr.data.foreach_get('value', new_mask_data)
self.assertGreater(np.count_nonzero(new_mask_data), np.count_nonzero(old_mask_data))
class ShrinkMaskTest(unittest.TestCase):
def setUp(self):
bpy.ops.wm.open_mainfile(filepath=str(args.testdir / "partially_masked_sphere.blend"), load_ui=False)
bpy.ops.ed.undo_push()
def test_shrink_decreases_number_of_masked_vertices(self):
mesh = bpy.context.object.data
mask_attr = mesh.attributes['.sculpt_mask']
num_vertices = mesh.attributes.domain_size('POINT')
old_mask_data = np.zeros(num_vertices, dtype=np.float32)
mask_attr.data.foreach_get('value', old_mask_data)
bpy.ops.sculpt.mask_filter(filter_type='SHRINK')
new_mask_data = np.zeros(num_vertices, dtype=np.float32)
mask_attr.data.foreach_get('value', new_mask_data)
self.assertLess(np.count_nonzero(new_mask_data), np.count_nonzero(old_mask_data))
def main():
global args
import argparse
argv = [sys.argv[0]]
if '--' in sys.argv:
argv += sys.argv[sys.argv.index('--') + 1:]
parser = argparse.ArgumentParser()
parser.add_argument('--testdir', required=True, type=pathlib.Path)
args, remaining = parser.parse_known_args(argv)
unittest.main(argv=remaining)
if __name__ == "__main__":
main()