Fix: Paint: Mimic modal execution when calling PaintStroke::exec

Currently, when using `sculpt.brush_stroke`, the raycast that updates
active attributes and certain properties on the `SculptSession` is not
executed, preventing certain brush features from working.

There were a few  problems that prevented this from working correctly:
* When `test_start` was called, all non-`invoke` calls were considered
  valid.
* We need to call `test_start` on each stroke step until we find the
  actual starting point
* The wrong "mouse" event was passed to `test_start`

Additionally, this allows a handful of tests that formerly had to be
skipped to be ran as part of the sculpt brush test suite.

Pull Request: https://projects.blender.org/blender/blender/pulls/154341
This commit is contained in:
Sean Kim 2026-02-16 19:28:15 +01:00 • committed by Sean Kim
parent 701bd71b9d
commit ff0161c348
3 changed files with 37 additions and 49 deletions

View file

@ -210,7 +210,7 @@ class MeshBrushTests(unittest.TestCase):
self._activate_brush("Trim")
self._check_stroke(backend, AttributeType.POSITION)
@unittest.skip("Needs raycast")
@unittest.skip("Asserts in blender")
def test_boundary_brush_creates_valid_data(self):
for backend in BackendType:
with self.subTest(backend):
@ -246,7 +246,7 @@ class MeshBrushTests(unittest.TestCase):
self._activate_brush("Grab 2D")
self._check_stroke(backend, AttributeType.POSITION)
@unittest.skip("Requires raycast")
@unittest.skip("Test currently fails")
def test_grab_silhouette_brush_creates_valid_data(self):
for backend in BackendType:
with self.subTest(backend):
@ -268,7 +268,6 @@ class MeshBrushTests(unittest.TestCase):
self._activate_brush("Pinch/Magnify")
self._check_stroke(backend, AttributeType.POSITION)
@unittest.skip("Brush requires raycast")
def test_pose_brush_creates_valid_data(self):
for backend in BackendType:
with self.subTest(backend):
@ -457,7 +456,7 @@ class MeshBrushTests(unittest.TestCase):
self._activate_brush("Blur")
self._check_stroke(backend, AttributeType.COLOR)
@unittest.skip("Brush requires raycast")
@unittest.skip("Asserts in blender")
def test_bend_boundary_cloth_brush_creates_valid_data(self):
for backend in BackendType:
with self.subTest(backend):
@ -465,7 +464,6 @@ class MeshBrushTests(unittest.TestCase):
self._activate_brush("Bend Boundary Cloth")
self._check_stroke(backend, AttributeType.POSITION)
@unittest.skip("Brush requires raycast")
def test_bend_twist_cloth_brush_creates_valid_data(self):
for backend in BackendType:
with self.subTest(backend):
@ -487,13 +485,13 @@ class MeshBrushTests(unittest.TestCase):
self._activate_brush("Expand/Contract Cloth")
self._check_stroke(backend, AttributeType.POSITION)
@unittest.skip("Brush requires raycast")
@unittest.skip("Test currently fails")
def test_grab_cloth_brush_creates_valid_data(self):
for backend in BackendType:
with self.subTest(backend):
self._initialize(backend)
self._activate_brush("Grab Cloth")
self._check_stroke(backend, AttributeType.POSITION)
self._check_stroke(backend, AttributeType.POSITION, start_over_mesh=True)
@unittest.skip("Brush has a typo currently in the name, 'Grab Planar Cloth '")
def test_grab_planar_cloth_brush_creates_valid_data(self):
@ -503,7 +501,7 @@ class MeshBrushTests(unittest.TestCase):
self._activate_brush("Grab Planar Cloth")
self._check_stroke(backend, AttributeType.POSITION, start_over_mesh=True)
@unittest.skip("Brush requires raycast")
@unittest.skip("Test currently fails")
def test_grab_random_cloth_brush_creates_valid_data(self):
for backend in BackendType:
with self.subTest(backend):
@ -539,7 +537,6 @@ class MeshBrushTests(unittest.TestCase):
self._activate_brush("Push Cloth")
self._check_stroke(backend, AttributeType.POSITION, start_over_mesh=True)
@unittest.skip("Brush requires raycast")
def test_stretch_move_cloth_brush_creates_valid_data(self):
for backend in BackendType:
with self.subTest(backend):
@ -547,7 +544,7 @@ class MeshBrushTests(unittest.TestCase):
self._activate_brush("Stretch/Move Cloth")
self._check_stroke(backend, AttributeType.POSITION, start_over_mesh=True)
@unittest.skip("Brush requires raycast")
@unittest.skip("Asserts in blender")
def test_twist_boundary_cloth_brush_creates_valid_data(self):
for backend in BackendType:
with self.subTest(backend):