Mesh automated testing: compare selection
MeshTest now compares selection between evaluated mesh and expected mesh. This way, we can test more operators such as `faces_select_linked_flat` Note: selection comparison intentionally does not happen in BKE_mesh_cmp() on C side but rather on Python side, because selection is independent of mesh generation. Reviewed By: calra, mont29 Differential Revision: https://developer.blender.org/D10279
This commit is contained in:
parent
847da6176e
commit
b6d7aa9e13
|
@ -247,9 +247,11 @@ class MeshTest:
|
|||
# Replace expected object with object we ran operations on, i.e. evaluated_test_object.
|
||||
evaluated_test_object.location = self.expected_object.location
|
||||
expected_object_name = self.expected_object.name
|
||||
evaluated_selection = {v.index for v in evaluated_test_object.data.vertices if v.select}
|
||||
|
||||
bpy.data.objects.remove(self.expected_object, do_unlink=True)
|
||||
evaluated_test_object.name = expected_object_name
|
||||
self._do_selection(evaluated_test_object.data, "VERT", evaluated_selection)
|
||||
|
||||
# Save file.
|
||||
bpy.ops.wm.save_as_mainfile(filepath=bpy.data.filepath)
|
||||
|
@ -428,30 +430,40 @@ class MeshTest:
|
|||
if self.apply_modifier:
|
||||
self._apply_modifier(test_object, particle_sys_spec.modifier_name)
|
||||
|
||||
def _do_selection(self, mesh: bpy.types.Mesh, select_mode: str, selection: set):
|
||||
"""
|
||||
Do selection on a mesh
|
||||
:param mesh: bpy.types.Mesh - input mesh
|
||||
:param: select_mode: str - selection mode. Must be 'VERT', 'EDGE' or 'FACE'
|
||||
:param: selection: set - indices of selection.
|
||||
|
||||
Example: select_mode='VERT' and selection={1,2,3} selects veritces 1, 2 and 3 of input mesh
|
||||
"""
|
||||
# deselect all
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
bpy.ops.mesh.select_all(action='DESELECT')
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
bpy.context.tool_settings.mesh_select_mode = (select_mode == 'VERT',
|
||||
select_mode == 'EDGE',
|
||||
select_mode == 'FACE')
|
||||
|
||||
items = (mesh.vertices if select_mode == 'VERT'
|
||||
else mesh.edges if select_mode == 'EDGE'
|
||||
else mesh.polygons if select_mode == 'FACE'
|
||||
else None)
|
||||
if items is None:
|
||||
raise ValueError("Invalid selection mode")
|
||||
for index in selection:
|
||||
items[index].select = True
|
||||
|
||||
def _apply_operator_edit_mode(self, test_object, operator: OperatorSpecEditMode):
|
||||
"""
|
||||
Apply operator on test object.
|
||||
:param test_object: bpy.types.Object - Blender object to apply operator on.
|
||||
:param operator: OperatorSpecEditMode - OperatorSpecEditMode object with parameters.
|
||||
"""
|
||||
mesh = test_object.data
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
bpy.ops.mesh.select_all(action='DESELECT')
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
# Do selection.
|
||||
bpy.context.tool_settings.mesh_select_mode = (operator.select_mode == 'VERT',
|
||||
operator.select_mode == 'EDGE',
|
||||
operator.select_mode == 'FACE')
|
||||
for index in operator.selection:
|
||||
if operator.select_mode == 'VERT':
|
||||
mesh.vertices[index].select = True
|
||||
elif operator.select_mode == 'EDGE':
|
||||
mesh.edges[index].select = True
|
||||
elif operator.select_mode == 'FACE':
|
||||
mesh.polygons[index].select = True
|
||||
else:
|
||||
raise ValueError("Invalid selection mode")
|
||||
self._do_selection(test_object.data, operator.select_mode, operator.selection)
|
||||
|
||||
# Apply operator in edit mode.
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
|
@ -579,6 +591,12 @@ class MeshTest:
|
|||
compare_result = evaluated_test_mesh.unit_test_compare(mesh=expected_mesh)
|
||||
compare_success = (compare_result == 'Same')
|
||||
|
||||
selected_evaluatated_verts = [v.index for v in evaluated_test_mesh.vertices if v.select]
|
||||
selected_expected_verts = [v.index for v in expected_mesh.vertices if v.select]
|
||||
if selected_evaluatated_verts != selected_expected_verts:
|
||||
compare_result = "Selection doesn't match"
|
||||
compare_success = False
|
||||
|
||||
# Also check if invalid geometry (which is never expected) had to be corrected...
|
||||
validation_success = not evaluated_test_mesh.validate(verbose=True)
|
||||
|
||||
|
|
|
@ -137,6 +137,15 @@ def main():
|
|||
MeshTest("CubeEdgeSplit", "testCubeEdgeSplit", "expectedCubeEdgeSplit",
|
||||
[OperatorSpecEditMode("edge_split", {}, "EDGE", {2, 5, 8, 11, 14, 17, 20, 23})]),
|
||||
|
||||
### 25
|
||||
# edge ring select - Cannot be tested. Need user input.
|
||||
# MeshTest("CubeEdgeRingSelect", "testCubeEdgeRingSelect", "expectedCubeEdgeRingSelect",
|
||||
# [OperatorSpecEditMode("edgering_select", {}, "EDGE", {5, 20, 25, 26})]),
|
||||
# MeshTest("EmptyMeshEdgeRingSelect", "testGridEdgeRingSelect", "expectedGridEdgeRingSelect",
|
||||
# [OperatorSpecEditMode("edgering_select", {}, "VERT", {65, 66, 67})]),
|
||||
# MeshTest("EmptyMeshEdgeRingSelect", "testEmptyMeshdgeRingSelect", "expectedEmptyMeshEdgeRingSelect",
|
||||
# [OperatorSpecEditMode("edgering_select", {}, "VERT", {})]),
|
||||
|
||||
# face make planar
|
||||
MeshTest("MonkeyFaceMakePlanar", "testMonkeyFaceMakePlanar",
|
||||
"expectedMonkeyFaceMakePlanar",
|
||||
|
@ -147,6 +156,15 @@ def main():
|
|||
"expectedPlaneFaceSplitByEdges",
|
||||
[OperatorSpecEditMode("face_split_by_edges", {}, "VERT", {i for i in range(6)})]),
|
||||
|
||||
# faces select linked flat
|
||||
MeshTest("CubeFacesSelectLinkedFlat", "testCubeFaceSelectLinkedFlat", "expectedCubeFaceSelectLinkedFlat",
|
||||
[OperatorSpecEditMode("faces_select_linked_flat", {}, "FACE", {7})]),
|
||||
MeshTest("PlaneFacesSelectLinkedFlat", "testPlaneFaceSelectLinkedFlat", "expectedPlaneFaceSelectLinkedFlat",
|
||||
[OperatorSpecEditMode("faces_select_linked_flat", {}, "VERT", {1})]),
|
||||
MeshTest("EmptyMeshFacesSelectLinkedFlat", "testEmptyMeshFaceSelectLinkedFlat",
|
||||
"expectedEmptyMeshFaceSelectLinkedFlat",
|
||||
[OperatorSpecEditMode("faces_select_linked_flat", {}, "VERT", {})]),
|
||||
|
||||
# fill
|
||||
MeshTest("IcosphereFill", "testIcosphereFill", "expectedIcosphereFill",
|
||||
[OperatorSpecEditMode("fill", {}, "EDGE", {20, 21, 22, 23, 24, 45, 46, 47, 48, 49})]),
|
||||
|
|
Loading…
Reference in New Issue