Cleanup: Tidy up sculpt_paint tests

* Reduce duplication by using some test helpers
* Ensure file level docstring is at beginning of file
* Alphabetize imports

Pull Request: https://projects.blender.org/blender/blender/pulls/157658
This commit is contained in:
Sean Kim 2026-04-21 18:57:02 +02:00 • committed by Sean Kim
parent f94d9d4449
commit c985c2067b
13 changed files with 79 additions and 314 deletions

View file

@ -1,13 +1,15 @@
# SPDX-FileCopyrightText: 2025 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later */
"""
blender -b --factory-startup --python tests/python/sculpt_paint/automask_test.py -- --testdir tests/files/sculpting/
"""
__all__ = (
"main",
)
import os
import math
import unittest
import sys
import pathlib
@ -15,12 +17,8 @@ import numpy as np
import bpy
"""
blender -b --factory-startup --python tests/python/sculpt_paint/sculpt_brushes_test.py -- --testdir tests/files/mesh_paint/
"""
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from modules.test_helpers import AttributeType, BackendType, get_attribute_data, set_view3d_context_override, generate_stroke, generate_monkey
from modules.test_helpers import AttributeType, BackendType, get_attribute_data, set_view3d_context_override, generate_stroke
args = None

View file

@ -1,6 +1,9 @@
# SPDX-FileCopyrightText: 2025 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later
"""
blender -b --factory-startup --python tests/python/sculpt_paint/brush_asset_test.py
"""
import sys
import unittest

View file

@ -1,83 +1,29 @@
# SPDX-FileCopyrightText: 2025 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later */
"""
blender -b --factory-startup --python tests/python/sculpt_paint/brush_strength_curves_test.py -- --testdir tests/files/sculpting/
"""
__all__ = (
"main",
)
import math
import unittest
import sys
import os
import pathlib
import numpy as np
import sys
import unittest
import bpy
"""
blender -b --factory-startup --python tests/python/sculpt_paint/brush_strength_curves_test.py -- --testdir tests/files/sculpting/
"""
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from modules.test_helpers import set_view3d_context_override, generate_stroke
args = None
def set_view3d_context_override(context_override):
"""
Set context override to become the first viewport in the active workspace
The ``context_override`` is expected to be a copy of an actual current context
obtained by `context.copy()`
"""
for area in context_override["screen"].areas:
if area.type != 'VIEW_3D':
continue
for space in area.spaces:
if space.type != 'VIEW_3D':
continue
for region in area.regions:
if region.type != 'WINDOW':
continue
context_override["area"] = area
context_override["region"] = region
def generate_stroke(context):
"""
Generate stroke for the bpy.ops.sculpt.brush_stroke operator
The generated stroke coves the full plane diagonal.
"""
import bpy
from mathutils import Vector
template = {
"name": "stroke",
"mouse": (0.0, 0.0),
"mouse_event": (0, 0),
"is_start": True,
"location": (0, 0, 0),
"pressure": 1.0,
"time": 1.0,
"size": 1.0,
"x_tilt": 0,
"y_tilt": 0
}
num_steps = 100
start = Vector((context['area'].width, context['area'].height))
end = Vector((0, 0))
delta = (end - start) / (num_steps - 1)
stroke = []
for i in range(num_steps):
step = template.copy()
step["mouse_event"] = start + delta * i
stroke.append(step)
return stroke
class BrushCurvesTest(unittest.TestCase):
"""
Test that using a basic "Draw" brush stroke with each of the given brush curve presets doesn't produce invalid

View file

@ -1,22 +1,19 @@
# SPDX-FileCopyrightText: 2026 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later */
"""
blender -b --factory-startup --python tests/python/dyntopo_test.py -- --testdir tests/files/sculpting/
"""
__all__ = (
"main",
)
import unittest
import sys
import pathlib
import numpy as np
import sys
import unittest
import bpy
"""
blender -b --factory-startup --python tests/python/dyntopo_test.py -- --testdir tests/files/sculpting/
"""
args = None

View file

@ -1,47 +1,25 @@
# SPDX-FileCopyrightText: 2026 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later */
"""
blender -b --factory-startup --python tests/python/sculpt_paint/face_set_test.py -- --testdir tests/files/sculpting
"""
__all__ = (
"main",
)
import math
import unittest
import sys
import pathlib
import numpy as np
import os
import pathlib
import sys
import unittest
import bpy
"""
blender -b --factory-startup --python tests/python/sculpt_paint/face_set_test.py -- --testdir tests/files/sculpting
"""
args = None
def set_view3d_context_override(context_override):
"""
Set context override to become the first viewport in the active workspace
The ``context_override`` is expected to be a copy of an actual current context
obtained by `context.copy()`
"""
for area in context_override["screen"].areas:
if area.type != 'VIEW_3D':
continue
for space in area.spaces:
if space.type != 'VIEW_3D':
continue
for region in area.regions:
if region.type != 'WINDOW':
continue
context_override["area"] = area
context_override["region"] = region
def get_attribute_data(
attribute_name='position',
attribute_domain='POINT',

View file

@ -1,46 +1,28 @@
# SPDX-FileCopyrightText: 2025 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later */
"""
blender -b --factory-startup --python tests/python/mask_test.py -- --testdir tests/files/sculpting/
"""
__all__ = (
"main",
)
import unittest
import sys
import os
import pathlib
import numpy as np
import sys
import unittest
import bpy
"""
blender -b --factory-startup --python tests/python/mask_test.py -- --testdir tests/files/sculpting/
"""
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from modules.test_helpers import set_view3d_context_override
args = None
def set_view3d_context_override(context_override):
"""
Set context override to become the first viewport in the active workspace
The ``context_override`` is expected to be a copy of an actual current context
obtained by `context.copy()`
"""
for area in context_override["screen"].areas:
if area.type != 'VIEW_3D':
continue
for space in area.spaces:
if space.type != 'VIEW_3D':
continue
for region in area.regions:
if region.type != 'WINDOW':
continue
context_override["area"] = area
context_override["region"] = region
class GrowMaskTest(unittest.TestCase):
def setUp(self):
bpy.ops.wm.open_mainfile(filepath=str(args.testdir / "partially_masked_sphere.blend"), load_ui=False)

View file

@ -1,47 +1,29 @@
# SPDX-FileCopyrightText: 2026 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later */
"""
blender -b --factory-startup --python tests/python/sculpt_paint/mesh_filter_test.py -- --testdir tests/files/
"""
__all__ = (
"main",
)
import math
import unittest
import sys
import pathlib
import numpy as np
import os
import pathlib
import sys
import unittest
import bpy
"""
blender -b --factory-startup --python tests/python/sculpt_paint/mesh_filter_test.py -- --testdir tests/files/
"""
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from modules.test_helpers import set_view3d_context_override
args = None
def set_view3d_context_override(context_override):
"""
Set context override to become the first viewport in the active workspace
The ``context_override`` is expected to be a copy of an actual current context
obtained by `context.copy()`
"""
for area in context_override["screen"].areas:
if area.type != 'VIEW_3D':
continue
for space in area.spaces:
if space.type != 'VIEW_3D':
continue
for region in area.regions:
if region.type != 'WINDOW':
continue
context_override["area"] = area
context_override["region"] = region
def get_attribute_data(
attribute_name='position',
attribute_domain='POINT',

View file

@ -1,22 +1,21 @@
# SPDX-FileCopyrightText: 2025 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later */
"""
blender -b --factory-startup --python tests/python/bl_object_modifier_multires.py -- --testdir tests/files/sculpting/
"""
__all__ = (
"main",
)
import unittest
import sys
import pathlib
import sys
import unittest
import bpy
from mathutils import Vector
"""
blender -b --factory-startup --python tests/python/bl_object_modifier_multires.py -- --testdir tests/files/sculpting/
"""
args = None

View file

@ -1,24 +1,22 @@
# SPDX-FileCopyrightText: 2025 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later */
"""
blender -b --factory-startup --python tests/python/sculpt_paint/sculpt_brushes_test.py -- --testdir tests/files/mesh_paint/
"""
__all__ = (
"main",
)
import os
import math
import unittest
import sys
import os
import pathlib
import numpy as np
import sys
import unittest
import bpy
"""
blender -b --factory-startup --python tests/python/sculpt_paint/sculpt_brushes_test.py -- --testdir tests/files/mesh_paint/
"""
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from modules.test_helpers import AttributeType, BackendType, COLOR_BACKEND_TYPES, MASK_BACKEND_TYPES, get_attribute_data, set_view3d_context_override, generate_stroke, generate_monkey

View file

@ -1,87 +1,29 @@
# SPDX-FileCopyrightText: 2025 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later */
"""
blender -b --factory-startup --python tests/python/sculpt_paint/vertex_paint_brushes_test.py -- --testdir tests/files/mesh_paint/
"""
__all__ = (
"main",
)
import numpy as np
import math
import os
import pathlib
import unittest
import sys
import pathlib
import numpy as np
import bpy
"""
blender -b --factory-startup --python tests/python/sculpt_paint/vertex_paint_brushes_test.py -- --testdir tests/files/mesh_paint/
"""
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from modules.test_helpers import set_view3d_context_override, generate_stroke
args = None
def set_view3d_context_override(context_override):
"""
Set context override to become the first viewport in the active workspace
The ``context_override`` is expected to be a copy of an actual current context
obtained by `context.copy()`
"""
for area in context_override["screen"].areas:
if area.type != 'VIEW_3D':
continue
for space in area.spaces:
if space.type != 'VIEW_3D':
continue
for region in area.regions:
if region.type != 'WINDOW':
continue
context_override["area"] = area
context_override["region"] = region
def generate_stroke(context, start_over_mesh=False):
"""
Generate stroke for the bpy.ops.sculpt.brush_stroke operator
The generated stroke coves the full plane diagonal.
"""
import bpy
from mathutils import Vector
template = {
"name": "stroke",
"mouse": (0.0, 0.0),
"mouse_event": (0, 0),
"is_start": True,
"location": (0, 0, 0),
"pressure": 1.0,
"time": 1.0,
"size": 1.0,
"x_tilt": 0,
"y_tilt": 0
}
num_steps = 100
if start_over_mesh:
start = Vector((context['area'].width // 2, context['area'].height // 2))
else:
start = Vector((context['area'].width, context['area'].height))
end = Vector((0, 0))
delta = (end - start) / (num_steps - 1)
stroke = []
for i in range(num_steps):
step = template.copy()
step["mouse_event"] = start + delta * i
stroke.append(step)
return stroke
def get_attribute_data(
attribute_name='Attribute',
attribute_domain='CORNER',

View file

@ -1,6 +1,9 @@
# SPDX-FileCopyrightText: 2026 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later
"""
blender -b --factory-startup tests/files/sculpting/voxel_remesh_compare --python tests/python/sculpt_paint/voxel_remesh_compare_test.py
"""
__all__ = (
"main",
@ -11,10 +14,6 @@ import sys
import bpy
"""
blender -b --factory-startup tests/files/sculpting/voxel_remesh_compare --python tests/python/sculpt_paint/voxel_remesh_compare_test.py
"""
BASE_DIR = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(BASE_DIR, ".."))
from modules.mesh_test import RunTest, SpecMeshTest, OperatorSpec

View file

@ -1,21 +1,20 @@
# SPDX-FileCopyrightText: 2025 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later */
"""
blender -b --factory-startup --python tests/python/sculpt_paint/voxel_remesh_test.py
"""
__all__ = (
"main",
)
import os
import unittest
import sys
import unittest
import bpy
"""
blender -b --factory-startup --python tests/python/sculpt_paint/voxel_remesh_test.py
"""
sys.path.append(os.path.dirname(os.path.realpath(__file__)))

View file

@ -1,87 +1,29 @@
# SPDX-FileCopyrightText: 2025 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later */
"""
blender -b --factory-startup --python tests/python/sculpt_paint/weight_paint_brushes_test.py -- --testdir tests/files/mesh_paint/
"""
__all__ = (
"main",
)
import math
import unittest
import sys
import pathlib
import numpy as np
import os
import pathlib
import sys
import unittest
import bpy
"""
blender -b --factory-startup --python tests/python/sculpt_paint/weight_paint_brushes_test.py -- --testdir tests/files/mesh_paint/
"""
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from modules.test_helpers import set_view3d_context_override, generate_stroke
args = None
def set_view3d_context_override(context_override):
"""
Set context override to become the first viewport in the active workspace
The ``context_override`` is expected to be a copy of an actual current context
obtained by `context.copy()`
"""
for area in context_override["screen"].areas:
if area.type != 'VIEW_3D':
continue
for space in area.spaces:
if space.type != 'VIEW_3D':
continue
for region in area.regions:
if region.type != 'WINDOW':
continue
context_override["area"] = area
context_override["region"] = region
def generate_stroke(context, start_over_mesh=False):
"""
Generate stroke for the bpy.ops.sculpt.brush_stroke operator
The generated stroke coves the full plane diagonal.
"""
import bpy
from mathutils import Vector
template = {
"name": "stroke",
"mouse": (0.0, 0.0),
"mouse_event": (0, 0),
"is_start": True,
"location": (0, 0, 0),
"pressure": 1.0,
"time": 1.0,
"size": 1.0,
"x_tilt": 0,
"y_tilt": 0
}
num_steps = 100
if start_over_mesh:
start = Vector((context['area'].width // 2, context['area'].height // 2))
else:
start = Vector((context['area'].width, context['area'].height))
end = Vector((0, 0))
delta = (end - start) / (num_steps - 1)
stroke = []
for i in range(num_steps):
step = template.copy()
step["mouse_event"] = start + delta * i
stroke.append(step)
return stroke
def get_weights(ob, vgroup):
group_index = vgroup.index
for i, v in enumerate(ob.data.vertices):