[Bf-blender-cvs] [2edc2136a1d] soc-2021-geometry-nodes-regression-test: WIP: Saving work, Mesh Test Abstract class implementattion complete, updating to Win 11
Himanshi Kalra
noreply at git.blender.org
Sat Jul 3 10:48:07 CEST 2021
Commit: 2edc2136a1d89e4fdeafa7df127a1e4df18fb9db
Author: Himanshi Kalra
Date: Sat Jul 3 14:17:38 2021 +0530
Branches: soc-2021-geometry-nodes-regression-test
https://developer.blender.org/rB2edc2136a1d89e4fdeafa7df127a1e4df18fb9db
WIP: Saving work, Mesh Test Abstract class implementattion complete, updating to Win 11
===================================================================
M tests/python/modules/base_mesh_test.py
A tests/python/modules/spec_classes.py
A tests/python/test_classes.py
===================================================================
diff --git a/tests/python/modules/base_mesh_test.py b/tests/python/modules/base_mesh_test.py
index d07f5485041..1e8f48b74fc 100644
--- a/tests/python/modules/base_mesh_test.py
+++ b/tests/python/modules/base_mesh_test.py
@@ -3,6 +3,8 @@ import bpy
import os
import sys
+from modules.spec_classes import ModifierSpec, DeformModifierSpec, OperatorSpecEditMode, OperatorSpecObjectMode
+
class MeshTest(ABC):
def __init__(self, test_object_name, exp_object_name, threshold=None):
@@ -10,37 +12,123 @@ class MeshTest(ABC):
self.exp_object_name = exp_object_name
self.threshold = threshold
self.update = os.getenv("BLENDER_TEST_UPDATE") is not None
- self.eval_object_name = "evaluated_object"
+ # self.eval_object_name = "evaluated_object"
+
+ # Private flag to indicate whether the blend file was updated after the test.
+ self._test_updated = False
+ objects = bpy.data.objects
+ self.test_object = objects[self.test_object_name]
+
+ # TODO - create exp object, in case doesn't exist.
+ self.expected_object = objects[self.exp_object_name]
def create_evaluated_object(self):
+ bpy.context.view_layer.objects.active = self.test_object
+
+ # Duplicate test object.
+ bpy.ops.object.mode_set(mode="OBJECT")
+ bpy.ops.object.select_all(action="DESELECT")
+ bpy.context.view_layer.objects.active = self.test_object
+
+ self.test_object.select_set(True)
+ bpy.ops.object.duplicate()
+ evaluated_test_object = bpy.context.active_object
+ evaluated_test_object.name = "evaluated_object"
# Real implementation.
- pass
+ return evaluated_test_object
+
+ @staticmethod
+ def _print_result(result):
+ comparison_result, selection_result, validation_result = result
+ print("Mesh Compariosn: {}".format(comparison_result))
+ print("Selection Result: {}".format(selection_result))
+ print("Mesh Validation: {}".format(validation_result))
def run_test(self):
+ evaluated_test_object = self.create_evaluated_object()
+ self.apply_operations(evaluated_test_object)
+ result = self.compare_meshes(evaluated_test_object)
+
+ comparison_result, selection_result, validation_result = result
+
+ if comparison_result == "Same" and selection_result == "Same" and validation_result == "Valid":
+ self.passed_test(result)
+
+ elif self.update:
+ self.failed_test(result)
+ self.update_failed_test(evaluated_test_object)
+
+ else:
+ self.failed_test(result)
+
# Real implementation.
pass
- def failed_test(self):
+ def failed_test(self, result):
+ print("The test failed with the following: ")
+ self._print_result(result)
# Real implementation.
pass
- def passed_test(self):
+ def passed_test(self, result):
+ print("The tests passed successfully.")
+ self._print_result(result)
# Real implementation
pass
- def update_failed_test(self):
- if self.failed_test() and self.update:
- self.create_evaluated_object()
- # Real implementation
- pass
+ 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 update_failed_test(self, evaluated_test_object):
+ # Update expected 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)
+ self._test_updated = True
+ self.expected_object = evaluated_test_object
+
+ # Real implementation.
- def compare_meshes(self, evaluated_object, with_selection=True):
+ def compare_meshes(self, evaluated_object):
objects = bpy.data.objects
evaluated_test_mesh = objects[evaluated_object.name].data
expected_mesh = objects[self.exp_object_name].data
result_codes = []
- # Mesh Comparison
+ # Mesh Comparison.
if self.threshold:
result_mesh = expected_mesh.unit_test_compare(
mesh=evaluated_test_mesh, threshold=self.threshold)
@@ -50,37 +138,40 @@ class MeshTest(ABC):
result_codes.append(result_mesh)
# Selection comparison.
- if with_selection:
- 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:
- result_selection = "Same"
- else:
- result_selection = "Selection doesn't match."
- else:
- result_selection = "NA"
+ 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:
+ result_selection = "Same"
+ else:
+ result_selection = "Selection doesn't match."
result_codes.append(result_selection)
# Validation check.
- # TODO
+ result_validation = evaluated_test_mesh.validate(verbose=True)
+ if result_validation:
+ result_validation = "Invalid Mesh"
+ else:
+ result_validation = "Valid"
+ result_codes.append(result_validation)
return result_codes
@abstractmethod
- def apply_operations(self):
+ def apply_operations(self, evaluated_test_object):
pass
def __repr__(self):
return "MeshTest({}, {} )".format(self.test_object_name, self.exp_object_name)
-class SpecTest(MeshTest):
- def __init__(self, test_object_name, exp_object_name, threshold=None, operation_stack=None):
- super.__init__(test_object_name, exp_object_name, threshold=None)
+class SpecMeshTest(MeshTest):
+ def __init__(self, test_name, test_object_name, exp_object_name, operation_stack=None, threshold=None):
+ self.test_name = test_name
+ super().__init__(test_object_name, exp_object_name, threshold)
pass
def apply_operations(self):
@@ -88,12 +179,21 @@ class SpecTest(MeshTest):
class BlendFileTest(MeshTest):
- def apply_operations(self):
- pass
+ def apply_operations(self, evaluated_test_object):
+ """
+ Apply all modifiers (Geometry Nodes for now) added to the current object [Discuss]
+ """
+ # select_only_object(evaluated_test_object)
+
+ modifiers_list = evaluated_test_object.modifiers
+
+ for modifier in modifiers_list:
+ bpy.ops.object.modifier_apply(modifier=modifier.name)
geometry_nodes_test = BlendFileTest("test_object", "expected_object")
geometry_nodes_test.run_test()
-modifier_test = SpecTest("test_array", "exp_array", operation_stack=[])
+modifier_test = SpecMeshTest("test_name", "test_array",
+ "exp_array", operation_stack=[])
modifier_test.run_test()
diff --git a/tests/python/modules/spec_classes.py b/tests/python/modules/spec_classes.py
new file mode 100644
index 00000000000..8416bc60aa0
--- /dev/null
+++ b/tests/python/modules/spec_classes.py
@@ -0,0 +1,168 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+# A framework to run regression tests on mesh modifiers and operators based on howardt's mesh_ops_test.py
+#
+# General idea:
+# A test is:
+# Object mode
+# Select <test_object>
+# Duplicate the object
+# Select the object
+# Apply operation for each operation in <operations_stack> with given parameters
+# (an operation is either a modifier or an operator)
+# tes
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list