Changeset View
Changeset View
Standalone View
Standalone View
tests/python/modules/mesh_test.py
| Show First 20 Lines • Show All 241 Lines • ▼ Show 20 Lines | class MeshTest: | ||||
| def _on_failed_test(self, compare_result, validation_success, evaluated_test_object): | def _on_failed_test(self, compare_result, validation_success, evaluated_test_object): | ||||
| if self.update and validation_success: | if self.update and validation_success: | ||||
| if self.verbose: | if self.verbose: | ||||
| print("Test failed expectantly. Updating expected mesh...") | print("Test failed expectantly. Updating expected mesh...") | ||||
| # Replace expected object with object we ran operations on, i.e. evaluated_test_object. | # Replace expected object with object we ran operations on, i.e. evaluated_test_object. | ||||
| evaluated_test_object.location = self.expected_object.location | evaluated_test_object.location = self.expected_object.location | ||||
| expected_object_name = self.expected_object.name | 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) | bpy.data.objects.remove(self.expected_object, do_unlink=True) | ||||
| evaluated_test_object.name = expected_object_name | evaluated_test_object.name = expected_object_name | ||||
| self._do_selection(evaluated_test_object.data, "VERT", evaluated_selection) | |||||
| # Save file. | # Save file. | ||||
| bpy.ops.wm.save_as_mainfile(filepath=bpy.data.filepath) | bpy.ops.wm.save_as_mainfile(filepath=bpy.data.filepath) | ||||
| self._test_updated = True | self._test_updated = True | ||||
| # Set new expected object. | # Set new expected object. | ||||
| self.expected_object = evaluated_test_object | self.expected_object = evaluated_test_object | ||||
| ▲ Show 20 Lines • Show All 162 Lines • ▼ Show 20 Lines | def _apply_particle_system(self, test_object, particle_sys_spec: ParticleSystemSpec): | ||||
| bpy.context.scene.frame_set(particle_sys_spec.frame_end) | bpy.context.scene.frame_set(particle_sys_spec.frame_end) | ||||
| test_object.select_set(True) | test_object.select_set(True) | ||||
| bpy.ops.object.duplicates_make_real() | bpy.ops.object.duplicates_make_real() | ||||
| test_object.select_set(True) | test_object.select_set(True) | ||||
| bpy.ops.object.join() | bpy.ops.object.join() | ||||
| if self.apply_modifier: | if self.apply_modifier: | ||||
| self._apply_modifier(test_object, particle_sys_spec.modifier_name) | self._apply_modifier(test_object, particle_sys_spec.modifier_name) | ||||
| def _apply_operator_edit_mode(self, test_object, operator: OperatorSpecEditMode): | def _do_selection(self, mesh: bpy.types.Mesh, select_mode: str, selection: set): | ||||
| """ | """ | ||||
| Apply operator on test object. | Do selection on a mesh | ||||
| :param test_object: bpy.types.Object - Blender object to apply operator on. | :param mesh: bpy.types.Mesh - input mesh | ||||
| :param operator: OperatorSpecEditMode - OperatorSpecEditMode object with parameters. | :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 | |||||
| """ | """ | ||||
| mesh = test_object.data | # deselect all | ||||
| bpy.ops.object.mode_set(mode='EDIT') | bpy.ops.object.mode_set(mode='EDIT') | ||||
| bpy.ops.mesh.select_all(action='DESELECT') | bpy.ops.mesh.select_all(action='DESELECT') | ||||
| bpy.ops.object.mode_set(mode='OBJECT') | bpy.ops.object.mode_set(mode='OBJECT') | ||||
| # Do selection. | bpy.context.tool_settings.mesh_select_mode = (select_mode == 'VERT', | ||||
| bpy.context.tool_settings.mesh_select_mode = (operator.select_mode == 'VERT', | select_mode == 'EDGE', | ||||
| operator.select_mode == 'EDGE', | select_mode == 'FACE') | ||||
| operator.select_mode == 'FACE') | |||||
| for index in operator.selection: | items = (mesh.vertices if select_mode == 'VERT' | ||||
| if operator.select_mode == 'VERT': | else mesh.edges if select_mode == 'EDGE' | ||||
| mesh.vertices[index].select = True | else mesh.polygons if select_mode == 'FACE' | ||||
| elif operator.select_mode == 'EDGE': | else None) | ||||
| mesh.edges[index].select = True | if items is None: | ||||
| elif operator.select_mode == 'FACE': | |||||
| mesh.polygons[index].select = True | |||||
| else: | |||||
| raise ValueError("Invalid selection mode") | 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. | |||||
| """ | |||||
| self._do_selection(test_object.data, operator.select_mode, operator.selection) | |||||
| # Apply operator in edit mode. | # Apply operator in edit mode. | ||||
| bpy.ops.object.mode_set(mode='EDIT') | bpy.ops.object.mode_set(mode='EDIT') | ||||
| bpy.ops.mesh.select_mode(type=operator.select_mode) | bpy.ops.mesh.select_mode(type=operator.select_mode) | ||||
| mesh_operator = getattr(bpy.ops.mesh, operator.operator_name) | mesh_operator = getattr(bpy.ops.mesh, operator.operator_name) | ||||
| try: | try: | ||||
| retval = mesh_operator(**operator.operator_parameters) | retval = mesh_operator(**operator.operator_parameters) | ||||
| ▲ Show 20 Lines • Show All 111 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
| evaluated_test_mesh = evaluated_test_object.data | evaluated_test_mesh = evaluated_test_object.data | ||||
| expected_mesh = self.expected_object.data | expected_mesh = self.expected_object.data | ||||
| if self.threshold: | if self.threshold: | ||||
| compare_result = evaluated_test_mesh.unit_test_compare(mesh=expected_mesh, threshold=self.threshold) | compare_result = evaluated_test_mesh.unit_test_compare(mesh=expected_mesh, threshold=self.threshold) | ||||
| else: | else: | ||||
| compare_result = evaluated_test_mesh.unit_test_compare(mesh=expected_mesh) | compare_result = evaluated_test_mesh.unit_test_compare(mesh=expected_mesh) | ||||
| compare_success = (compare_result == 'Same') | 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... | # Also check if invalid geometry (which is never expected) had to be corrected... | ||||
| validation_success = evaluated_test_mesh.validate(verbose=True) == False | validation_success = not evaluated_test_mesh.validate(verbose=True) | ||||
| if compare_success and validation_success: | if compare_success and validation_success: | ||||
| if self.verbose: | if self.verbose: | ||||
| print("Success!") | print("Success!") | ||||
| # Clean up. | # Clean up. | ||||
| if self.verbose: | if self.verbose: | ||||
| print("Cleaning up...") | print("Cleaning up...") | ||||
| ▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | class RunTest: | ||||
| def run_all_tests(self): | def run_all_tests(self): | ||||
| """ | """ | ||||
| Run all tests in self.tests list. Raises an exception if one the tests fails. | Run all tests in self.tests list. Raises an exception if one the tests fails. | ||||
| """ | """ | ||||
| for test_number, each_test in enumerate(self.tests): | for test_number, each_test in enumerate(self.tests): | ||||
| test_name = each_test.test_name | test_name = each_test.test_name | ||||
| if self.verbose: | if self.verbose: | ||||
| print() | print() | ||||
| print("Running test {}...".format(test_number)) | print("Running test {}/{}: {}...".format(test_number+1, len(self.tests), test_name)) | ||||
| print("Test name {}\n".format(test_name)) | |||||
| success = self.run_test(test_name) | success = self.run_test(test_name) | ||||
| if not success: | if not success: | ||||
| self._failed_tests_list.append(test_name) | self._failed_tests_list.append(test_name) | ||||
| if len(self._failed_tests_list) != 0: | if len(self._failed_tests_list) != 0: | ||||
| print("\nFollowing tests failed: {}".format(self._failed_tests_list)) | print("\nFollowing tests failed: {}".format(self._failed_tests_list)) | ||||
| Show All 40 Lines | |||||