Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/python/CMakeLists.txt42
-rw-r--r--tests/python/bevel_operator.py366
-rw-r--r--tests/python/boolean_operator.py48
-rw-r--r--tests/python/deform_modifiers.py119
-rw-r--r--tests/python/modifiers.py352
-rw-r--r--tests/python/modules/mesh_test.py557
-rw-r--r--tests/python/operators.py181
-rw-r--r--tests/python/physics_cloth.py28
-rw-r--r--tests/python/physics_dynamic_paint.py58
-rw-r--r--tests/python/physics_ocean.py54
-rw-r--r--tests/python/physics_particle_instance.py56
-rw-r--r--tests/python/physics_particle_system.py55
-rw-r--r--tests/python/physics_softbody.py23
13 files changed, 1395 insertions, 544 deletions
diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt
index 97f5df3ec09..bf949d66286 100644
--- a/tests/python/CMakeLists.txt
+++ b/tests/python/CMakeLists.txt
@@ -205,6 +205,48 @@ add_blender_test(
)
add_blender_test(
+ physics_dynamic_paint
+ ${TEST_SRC_DIR}/physics/dynamic_paint_test.blend
+ --python ${TEST_PYTHON_DIR}/physics_dynamic_paint.py
+ --
+ --run-all-tests
+)
+
+add_blender_test(
+ deform_modifiers
+ ${TEST_SRC_DIR}/modeling/deform_modifiers.blend
+ --python ${TEST_PYTHON_DIR}/deform_modifiers.py
+ --
+ --run-all-tests
+)
+
+add_blender_test(
+ physics_ocean
+ ${TEST_SRC_DIR}/physics/ocean_test.blend
+ --python ${TEST_PYTHON_DIR}/physics_ocean.py
+ --
+ --run-all-tests
+)
+
+
+add_blender_test(
+ physics_particle_system
+ ${TEST_SRC_DIR}/physics/physics_particle_test.blend
+ --python ${TEST_PYTHON_DIR}/physics_particle_system.py
+ --
+ --run-all-tests
+)
+
+# Particle Instance disabling currently broken in master
+# add_blender_test(
+# physics_particle_instance
+# ${TEST_SRC_DIR}/physics/physics_particle_instance.blend
+# --python ${TEST_PYTHON_DIR}/physics_particle_instance.py
+# --
+# --run-all-tests
+# )
+
+add_blender_test(
constraints
--python ${CMAKE_CURRENT_LIST_DIR}/bl_constraints.py
--
diff --git a/tests/python/bevel_operator.py b/tests/python/bevel_operator.py
index 50f52b958f7..c732d437b57 100644
--- a/tests/python/bevel_operator.py
+++ b/tests/python/bevel_operator.py
@@ -27,151 +27,287 @@ import os
import sys
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
-from modules.mesh_test import OperatorTest
+from modules.mesh_test import MeshTest, OperatorSpecEditMode, RunTest
def main():
tests = [
# 0
- ['EDGE', {10}, 'Cube_test', 'Cube_result_1', 'bevel', {'offset': 0.2}],
- ['EDGE', {10, 7}, 'Cube_test', 'Cube_result_2', 'bevel', {'offset': 0.2, 'offset_type': 'WIDTH'}],
- ['EDGE', {8, 10, 7}, 'Cube_test', 'Cube_result_3', 'bevel', {'offset': 0.2, 'offset_type': 'DEPTH'}],
- ['EDGE', {10}, 'Cube_test', 'Cube_result_4', 'bevel', {'offset': 0.4, 'segments': 2}],
- ['EDGE', {10, 7}, 'Cube_test', 'Cube_result_5', 'bevel', {'offset': 0.4, 'segments': 3}],
+ MeshTest('Cube_test_1', 'Cube_test', 'Cube_result_1',
+
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2}, 'EDGE', {10})]),
+ MeshTest('Cube_test_2', 'Cube_test', 'Cube_result_2',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'offset_type': 'WIDTH'}, 'EDGE', {10, 7}, )]),
+ MeshTest('Cube_test_3', 'Cube_test', 'Cube_result_3',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'offset_type': 'DEPTH'}, 'EDGE', {8, 10, 7}, )]),
+ MeshTest('Cube_test_4', 'Cube_test', 'Cube_result_4',
+ [OperatorSpecEditMode('bevel', {'offset': 0.4, 'segments': 2}, 'EDGE', {10}, )]),
+ MeshTest('Cube_test_5', 'Cube_test', 'Cube_result_5',
+ [OperatorSpecEditMode('bevel', {'offset': 0.4, 'segments': 3}, 'EDGE', {10, 7}, )]),
# 5
- ['EDGE', {8, 10, 7}, 'Cube_test', 'Cube_result_6', 'bevel', {'offset': 0.4, 'segments': 4}],
- ['EDGE', {0, 10, 4, 7}, 'Cube_test', 'Cube_result_7', 'bevel', {'offset': 0.4, 'segments': 5, 'profile': 0.2}],
- ['EDGE', {8, 10, 7}, 'Cube_test', 'Cube_result_8', 'bevel', {'offset': 0.4, 'segments': 5, 'profile': 0.25}],
- ['EDGE', {8, 10, 7}, 'Cube_test', 'Cube_result_9', 'bevel', {'offset': 0.4, 'segments': 6, 'profile': 0.9}],
- ['EDGE', {10, 7}, 'Cube_test', 'Cube_result_10', 'bevel', {'offset': 0.4, 'segments': 4, 'profile': 1.0}],
+ MeshTest('Cube_test_6', 'Cube_test', 'Cube_result_6',
+ [OperatorSpecEditMode('bevel', {'offset': 0.4, 'segments': 4}, 'EDGE', {8, 10, 7}, )]),
+ MeshTest('Cube_test_7', 'Cube_test', 'Cube_result_7',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.4, 'segments': 5, 'profile': 0.2}, 'EDGE', {0, 10, 4, 7}, )]),
+ MeshTest('Cube_test_8', 'Cube_test', 'Cube_result_8',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.4, 'segments': 5, 'profile': 0.25}, 'EDGE', {8, 10, 7}, )]),
+ MeshTest('Cube_test_9', 'Cube_test', 'Cube_result_9',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.4, 'segments': 6, 'profile': 0.9}, 'EDGE', {8, 10, 7}, )]),
+ MeshTest('Cube_test_10', 'Cube_test', 'Cube_result_10',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.4, 'segments': 4, 'profile': 1.0}, 'EDGE', {10, 7}, )]),
# 10
- ['EDGE', {8, 10, 7}, 'Cube_test', 'Cube_result_11', 'bevel', {'offset': 0.4, 'segments': 5, 'profile': 1.0}],
- ['EDGE', {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 'Cube_test', 'Cube_result_12', 'bevel',
- {'offset': 0.4, 'segments': 8}],
- ['EDGE', {5}, 'Pyr4_test', 'Pyr4_result_1', 'bevel', {'offset': 0.2}],
- ['EDGE', {2, 5}, 'Pyr4_test', 'Pyr4_result_2', 'bevel', {'offset': 0.2}],
- ['EDGE', {2, 3, 5}, 'Pyr4_test', 'Pyr4_result_3', 'bevel', {'offset': 0.2}],
+ MeshTest('Cube_test_11', 'Cube_test', 'Cube_result_11',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.4, 'segments': 5, 'profile': 1.0}, 'EDGE', {8, 10, 7}, )]),
+ MeshTest("test 12", 'Cube_test', 'Cube_result_12',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.4, 'segments': 8}, 'EDGE',
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, )]),
+ MeshTest('Pyramid4_test_1', 'Pyr4_test', 'Pyr4_result_1',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2}, 'EDGE', {5}, )]),
+ MeshTest('Pyramid4_test_2', 'Pyr4_test', 'Pyr4_result_2',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2}, 'EDGE', {2, 5}, )]),
+ MeshTest('Pyramid4_test_3', 'Pyr4_test', 'Pyr4_result_3',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2}, 'EDGE', {2, 3, 5}, )]),
# 15
- ['EDGE', {1, 2, 3, 5}, 'Pyr4_test', 'Pyr4_result_4', 'bevel', {'offset': 0.2}],
- ['EDGE', {1, 2, 3, 5}, 'Pyr4_test', 'Pyr4_result_5', 'bevel', {'offset': 0.2, 'segments': 3}],
- ['EDGE', {2, 3}, 'Pyr4_test', 'Pyr4_result_6', 'bevel', {'offset': 0.2, 'segments': 2}],
- ['EDGE', {1, 2, 3, 5}, 'Pyr4_test', 'Pyr4_result_7', 'bevel', {'offset': 0.2, 'segments': 4, 'profile': 0.15}],
- ['VERT', {1}, 'Pyr4_test', 'Pyr4_result_8', 'bevel', {'offset': 0.75, 'segments': 4, 'affect': 'VERTICES'}],
+ MeshTest('Pyramid4_test_4', 'Pyr4_test', 'Pyr4_result_4',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2}, 'EDGE', {1, 2, 3, 5}, )]),
+ MeshTest('Pyramid4_test_5', 'Pyr4_test', 'Pyr4_result_5',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'segments': 3}, 'EDGE', {1, 2, 3, 5}, )]),
+ MeshTest('Pyramid4_test_6', 'Pyr4_test', 'Pyr4_result_6',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2, 'segments': 2}, 'EDGE', {2, 3}, )]),
+ MeshTest('Pyramid4_test_7', 'Pyr4_test', 'Pyr4_result_7',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'segments': 4, 'profile': 0.15}, 'EDGE', {1, 2, 3, 5}, )]),
+ MeshTest('Pyramid4_test_8', 'Pyr4_test', 'Pyr4_result_8',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.75, 'segments': 4, 'affect': 'VERTICES'}, 'VERT', {1}, )]),
# 20
- ['VERT', {1}, 'Pyr4_test', 'Pyr4_result_9', 'bevel',
- {'offset': 0.75, 'segments': 3, 'affect': 'VERTICES', 'profile': 0.25}],
- ['EDGE', {2, 3}, 'Pyr6_test', 'Pyr6_result_1', 'bevel', {'offset': 0.2}],
- ['EDGE', {8, 2, 3}, 'Pyr6_test', 'Pyr6_result_2', 'bevel', {'offset': 0.2, 'segments': 2}],
- ['EDGE', {0, 2, 3, 4, 6, 7, 9, 10, 11}, 'Pyr6_test', 'Pyr6_result_3', 'bevel',
- {'offset': 0.2, 'segments': 4, 'profile': 0.8}],
- ['EDGE', {8, 9, 3, 11}, 'Sept_test', 'Sept_result_1', 'bevel', {'offset': 0.1}],
+ MeshTest('Pyramid4_test_9', 'Pyr4_test', 'Pyr4_result_9',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.75, 'segments': 3, 'affect': 'VERTICES', 'profile': 0.25}, 'VERT',
+ {1}, )]),
+ MeshTest('Pyramid6_test_1', 'Pyr6_test', 'Pyr6_result_1',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2}, 'EDGE', {2, 3}, )]),
+ MeshTest('Pyramid6_test_2', 'Pyr6_test', 'Pyr6_result_2',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2, 'segments': 2}, 'EDGE', {8, 2, 3}, )]),
+ MeshTest('Pyramid6_test_3', 'Pyr6_test', 'Pyr6_result_3',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'segments': 4, 'profile': 0.8}, 'EDGE',
+ {0, 2, 3, 4, 6, 7, 9, 10, 11}, )]),
+ MeshTest('Sept_test_1', 'Sept_test', 'Sept_result_1',
+ [OperatorSpecEditMode('bevel', {'offset': 0.1}, 'EDGE', {8, 9, 3, 11}, )]),
# 25
- ['EDGE', {8, 9, 11}, 'Sept_test', 'Sept_result_2', 'bevel', {'offset': 0.1, 'offset_type': 'WIDTH'}],
- ['EDGE', {2, 8, 9, 12, 13, 14}, 'Saddle_test', 'Saddle_result_1', 'bevel', {'offset': 0.3, 'segments': 5}],
- ['VERT', {4}, 'Saddle_test', 'Saddle_result_2', 'bevel', {'offset': 0.6, 'segments': 6, 'affect': 'VERTICES'}],
- ['EDGE', {2, 5, 8, 11, 14, 18, 21, 24, 27, 30, 34, 37, 40, 43, 46, 50, 53, 56, 59, 62, 112, 113, 114, 115},
- 'Bent_test', 'Bent_result_1', 'bevel', {'offset': 0.2, 'segments': 3}],
- ['EDGE', {1, 8, 9, 10, 11}, 'Bentlines_test', 'Bentlines_result_1', 'bevel', {'offset': 0.2, 'segments': 3}],
+ MeshTest('Sept_test_2', 'Sept_test', 'Sept_result_2',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.1, 'offset_type': 'WIDTH'}, 'EDGE', {8, 9, 11}, )]),
+ MeshTest('Saddle_test_1', 'Saddle_test', 'Saddle_result_1',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.3, 'segments': 5}, 'EDGE', {2, 8, 9, 12, 13, 14}, )]),
+ MeshTest('Saddle_test_2', 'Saddle_test', 'Saddle_result_2',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.6, 'segments': 6, 'affect': 'VERTICES'}, 'VERT', {4}, )]),
+
+ MeshTest('Bent_test', 'Bent_test', 'Bent_result_1',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2, 'segments': 3},
+ 'EDGE',
+ {2, 5, 8, 11, 14, 18, 21, 24, 27, 30, 34, 37, 40, 43, 46, 50, 53, 56, 59, 62,
+ 112, 113, 114, 115}, )]),
+ MeshTest('Bentlines_test_1', 'Bentlines_test', 'Bentlines_result_1',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'segments': 3}, 'EDGE', {1, 8, 9, 10, 11}, )]),
# 30
- ['EDGE', {26, 12, 20}, 'Flaretop_test', 'Flaretop_result_1', 'bevel', {'offset': 0.4, 'segments': 2}],
- ['EDGE', {26, 12, 20}, 'Flaretop_test', 'Flaretop_result_2', 'bevel',
- {'offset': 0.4, 'segments': 2, 'profile': 1.0}],
- ['FACE', {1, 6, 7, 8, 9, 10, 11, 12}, 'Flaretop_test', 'Flaretop_result_3', 'bevel',
- {'offset': 0.4, 'segments': 4}],
- ['EDGE', {4, 8, 10, 18, 24}, 'BentL_test', 'BentL_result_1', 'bevel', {'offset': 0.2}],
- ['EDGE', {0, 1, 2, 10}, 'Wires_test', 'Wires_test_result_1', 'bevel', {'offset': 0.3}],
+ MeshTest('Flaretop_test_1', 'Flaretop_test', 'Flaretop_result_1',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.4, 'segments': 2}, 'EDGE', {26, 12, 20}, )]),
+ MeshTest('Flaretop_test_2', 'Flaretop_test', 'Flaretop_result_2',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.4, 'segments': 2, 'profile': 1.0}, 'EDGE', {26, 12, 20}, )]),
+ MeshTest('Flaretop_test_3', 'Flaretop_test', 'Flaretop_result_3',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.4, 'segments': 4}, 'FACE', {1, 6, 7, 8, 9, 10, 11, 12}, )]),
+ MeshTest('BentL_test', 'BentL_test', 'BentL_result_1',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2}, 'EDGE', {4, 8, 10, 18, 24}, )]),
+ MeshTest('Wires_test_1', 'Wires_test', 'Wires_test_result_1',
+ [OperatorSpecEditMode('bevel', {'offset': 0.3}, 'EDGE', {0, 1, 2, 10}, )]),
# 35
- ['VERT', {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, 'Wires_test', 'Wires_test_result_2', 'bevel',
- {'offset': 0.3, 'affect': 'VERTICES'}],
- ['EDGE', {3, 4, 5}, 'tri', 'tri_result_1', 'bevel', {'offset': 0.2}],
- ['EDGE', {3, 4, 5}, 'tri', 'tri_result_2', 'bevel', {'offset': 0.2, 'segments': 2}],
- ['EDGE', {3, 4, 5}, 'tri', 'tri_result_3', 'bevel', {'offset': 0.2, 'segments': 3}],
- ['EDGE', {3, 4}, 'tri', 'tri_result_4', 'bevel', {'offset': 0.2}],
+ MeshTest('Wires_test_2', 'Wires_test', 'Wires_test_result_2',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.3, 'affect': 'VERTICES'}, 'VERT',
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, )]),
+ MeshTest('tri_test_1', 'tri', 'tri_result_1',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2}, 'EDGE', {3, 4, 5}, )]),
+ MeshTest('tri_test_2', 'tri', 'tri_result_2',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2, 'segments': 2}, 'EDGE', {3, 4, 5}, )]),
+ MeshTest('tri_test_3', 'tri', 'tri_result_3',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2, 'segments': 3}, 'EDGE', {3, 4, 5}, )]),
+ MeshTest('tri_test_4', 'tri', 'tri_result_4',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2}, 'EDGE', {3, 4}, )]),
# 40
- ['EDGE', {3, 4}, 'tri', 'tri_result_5', 'bevel', {'offset': 0.2, 'segments': 2}],
- ['VERT', {3}, 'tri', 'tri_result_6', 'bevel', {'offset': 0.2, 'affect': 'VERTICES'}],
- ['VERT', {3}, 'tri', 'tri_result_7', 'bevel', {'offset': 0.2, 'segments': 2, 'affect': 'VERTICES'}],
- ['VERT', {3}, 'tri', 'tri_result_8', 'bevel', {'offset': 0.2, 'segments': 3, 'affect': 'VERTICES'}],
- ['VERT', {1}, 'tri', 'tri_result_9', 'bevel', {'offset': 0.2, 'affect': 'VERTICES'}],
+ MeshTest('tri_test_5', 'tri', 'tri_result_5',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2, 'segments': 2}, 'EDGE', {3, 4}, )]),
+ MeshTest('tri_test_6', 'tri', 'tri_result_6',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2, 'affect': 'VERTICES'}, 'VERT', {3}, )]),
+ MeshTest('tri_test_7', 'tri', 'tri_result_7',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'segments': 2, 'affect': 'VERTICES'}, 'VERT', {3}, )]),
+ MeshTest('tri_test_8', 'tri', 'tri_result_8',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'segments': 3, 'affect': 'VERTICES'}, 'VERT', {3}, )]),
+ MeshTest('tri_test_9', 'tri', 'tri_result_9',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2, 'affect': 'VERTICES'}, 'VERT', {1}, )]),
# 45
- ['EDGE', {3, 4, 5}, 'tri1gap', 'tri1gap_result_1', 'bevel', {'offset': 0.2}],
- ['EDGE', {3, 4, 5}, 'tri1gap', 'tri1gap_result_2', 'bevel', {'offset': 0.2, 'segments': 2}],
- ['EDGE', {3, 4, 5}, 'tri1gap', 'tri1gap_result_3', 'bevel', {'offset': 0.2, 'segments': 3}],
- ['EDGE', {3, 4}, 'tri1gap', 'tri1gap_result_4', 'bevel', {'offset': 0.2}],
- ['EDGE', {3, 4}, 'tri1gap', 'tri1gap_result_5', 'bevel', {'offset': 0.2, 'segments': 2}],
+ MeshTest('tri1gap_test_2', 'tri1gap', 'tri1gap_result_2',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2, 'segments': 2}, 'EDGE', {3, 4, 5}, )]),
+ MeshTest('tri1gap_test_3', 'tri1gap', 'tri1gap_result_3',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2, 'segments': 3}, 'EDGE', {3, 4, 5}, )]),
+ MeshTest('tri1gap_test_1', 'tri1gap', 'tri1gap_result_1',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2}, 'EDGE', {3, 4, 5}, )]),
+ MeshTest('tri1gap_test_4', 'tri1gap', 'tri1gap_result_4',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2}, 'EDGE', {3, 4}, )]),
+ MeshTest('tri1gap_test_5', 'tri1gap', 'tri1gap_result_5',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2, 'segments': 2}, 'EDGE', {3, 4}, )]),
# 50
- ['EDGE', {3, 4}, 'tri1gap', 'tri1gap_result_6', 'bevel', {'offset': 0.2, 'segments': 3}],
- ['EDGE', {3, 5}, 'tri1gap', 'tri1gap_result_7', 'bevel', {'offset': 0.2}],
- ['EDGE', {3, 5}, 'tri1gap', 'tri1gap_result_8', 'bevel', {'offset': 0.2, 'segments': 2}],
- ['EDGE', {3, 5}, 'tri1gap', 'tri1gap_result_9', 'bevel', {'offset': 0.2, 'segments': 3}],
- ['VERT', {3}, 'tri1gap', 'tri1gap_result_10', 'bevel', {'offset': 0.2, 'affect': 'VERTICES'}],
+ MeshTest('tri1gap_test_6', 'tri1gap', 'tri1gap_result_6',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2, 'segments': 3}, 'EDGE', {3, 4}, )]),
+ MeshTest('tri1gap_test_7', 'tri1gap', 'tri1gap_result_7',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2}, 'EDGE', {3, 5}, )]),
+ MeshTest('tri1gap_test_8', 'tri1gap', 'tri1gap_result_8',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2, 'segments': 2}, 'EDGE', {3, 5}, )]),
+ MeshTest('tri1gap_test_9', 'tri1gap', 'tri1gap_result_9',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2, 'segments': 3}, 'EDGE', {3, 5}, )]),
+ MeshTest('tri1gap_test_10', 'tri1gap', 'tri1gap_result_10',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'affect': 'VERTICES'}, 'VERT', {3}, )]),
# 55
- ['EDGE', {3, 4, 5}, 'tri2gaps', 'tri2gaps_result_1', 'bevel', {'offset': 0.2}],
- ['EDGE', {3, 4, 5}, 'tri2gaps', 'tri2gaps_result_2', 'bevel', {'offset': 0.2, 'segments': 2}],
- ['EDGE', {3, 4, 5}, 'tri2gaps', 'tri2gaps_result_3', 'bevel', {'offset': 0.2, 'segments': 3}],
- ['EDGE', {3, 4}, 'tri2gaps', 'tri2gaps_result_4', 'bevel', {'offset': 0.2}],
- ['EDGE', {3, 4}, 'tri2gaps', 'tri2gaps_result_5', 'bevel', {'offset': 0.2, 'segments': 2}],
+ MeshTest('tri2gaps_test_1', 'tri2gaps', 'tri2gaps_result_1',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2}, 'EDGE', {3, 4, 5}, )]),
+ MeshTest('tri2gaps_test_2', 'tri2gaps', 'tri2gaps_result_2',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'segments': 2}, 'EDGE', {3, 4, 5}, )]),
+ MeshTest('tri2gaps_test_3', 'tri2gaps', 'tri2gaps_result_3',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'segments': 3}, 'EDGE', {3, 4, 5}, )]),
+ MeshTest('tri2gaps_test_4', 'tri2gaps', 'tri2gaps_result_4',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2}, 'EDGE', {3, 4}, )]),
+ MeshTest('tri2gaps_test_5', 'tri2gaps', 'tri2gaps_result_5',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2, 'segments': 2}, 'EDGE', {3, 4}, )]),
# 60
- ['EDGE', {3, 4}, 'tri2gaps', 'tri2gaps_result_6', 'bevel', {'offset': 0.2, 'segments': 3}],
- ['EDGE', {3, 4, 5}, 'tri3gaps', 'tri3gaps_result_1', 'bevel', {'offset': 0.2}],
- ['EDGE', {3, 4, 5}, 'tri3gaps', 'tri3gaps_result_2', 'bevel', {'offset': 0.2, 'segments': 2}],
- ['EDGE', {3, 4, 5}, 'tri3gaps', 'tri3gaps_result_3', 'bevel', {'offset': 0.2, 'segments': 3}],
- ['EDGE', {32, 33, 34, 35, 24, 25, 26, 27, 28, 29, 30, 31}, 'cube3', 'cube3_result_1', 'bevel', {'offset': 0.2}],
+ MeshTest('tri2gaps_test_6', 'tri2gaps', 'tri2gaps_result_6',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2, 'segments': 3}, 'EDGE', {3, 4}, )]),
+ MeshTest('tri3gaps_test_1', 'tri3gaps', 'tri3gaps_result_1',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2}, 'EDGE', {3, 4, 5}, )]),
+ MeshTest('tri3gaps_test_2', 'tri3gaps', 'tri3gaps_result_2',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'segments': 2}, 'EDGE', {3, 4, 5}, )]),
+ MeshTest('tri3gaps_test_3', 'tri3gaps', 'tri3gaps_result_3',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'segments': 3}, 'EDGE', {3, 4, 5}, )]),
+ MeshTest('cube3_test_1', 'cube3', 'cube3_result_1',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2}, 'EDGE', {32, 33, 34, 35, 24, 25, 26, 27, 28, 29, 30, 31}, )]),
# 65
- ['EDGE', {32, 33, 34, 35, 24, 25, 26, 27, 28, 29, 30, 31}, 'cube3', 'cube3_result_2', 'bevel',
- {'offset': 0.2, 'segments': 2}],
- ['EDGE', {32, 35}, 'cube3', 'cube3_result_3', 'bevel', {'offset': 0.2}],
- ['EDGE', {24, 35}, 'cube3', 'cube3_result_4', 'bevel', {'offset': 0.2}],
- ['EDGE', {24, 32, 35}, 'cube3', 'cube3_result_5', 'bevel', {'offset': 0.2, 'segments': 2}],
- ['EDGE', {24, 32, 35}, 'cube3', 'cube3_result_6', 'bevel', {'offset': 0.2, 'segments': 3}],
+ MeshTest('cube3_test_2', 'cube3', 'cube3_result_2',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'segments': 2}, 'EDGE',
+ {32, 33, 34, 35, 24, 25, 26, 27, 28, 29, 30, 31}, )]),
+ MeshTest('cube3_test_3', 'cube3', 'cube3_result_3',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2}, 'EDGE', {32, 35}, )]),
+ MeshTest('cube3_test_4', 'cube3', 'cube3_result_4',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2}, 'EDGE', {24, 35}, )]),
+ MeshTest('cube3_test_5', 'cube3', 'cube3_result_5',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2, 'segments': 2}, 'EDGE', {24, 32, 35}, )]),
+ MeshTest('cube3_test_6', 'cube3', 'cube3_result_6',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2, 'segments': 3}, 'EDGE', {24, 32, 35}, )]),
# 70
- ['EDGE', {0, 1, 6, 7, 12, 14, 16, 17}, 'Tray', 'Tray_result_1', 'bevel', {'offset': 0.01, 'segments': 2}],
- ['EDGE', {33, 4, 38, 8, 41, 10, 42, 12, 14, 17, 24, 31}, 'Bumptop', 'Bumptop_result_1', 'bevel',
- {'offset': 0.1, 'segments': 4}],
- ['EDGE', {16, 14, 15}, 'Multisegment_test', 'Multisegment_result_1', 'bevel', {'offset': 0.2}],
- ['EDGE', {16, 14, 15}, 'Multisegment_test', 'Multisegment_result_1', 'bevel', {'offset': 0.2}],
- ['EDGE', {19, 20, 23, 15}, 'Window_test', 'Window_result_1', 'bevel', {'offset': 0.05, 'segments': 2}],
+ MeshTest('Tray', 'Tray', 'Tray_result_1',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.01, 'segments': 2}, 'EDGE', {0, 1, 6, 7, 12, 14, 16, 17}, )]),
+ MeshTest("test 73", 'Bumptop', 'Bumptop_result_1',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.1, 'segments': 4}, 'EDGE',
+ {33, 4, 38, 8, 41, 10, 42, 12, 14, 17, 24, 31}, )]),
+ MeshTest('Multisegment_test_1', 'Multisegment_test', 'Multisegment_result_1',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2}, 'EDGE', {16, 14, 15}, )]),
+ MeshTest('Window_test', 'Window_test', 'Window_result_1',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.05, 'segments': 2}, 'EDGE', {19, 20, 23, 15}, )]),
# 75
- ['EDGE', {8}, 'Cube_hn_test', 'Cube_hn_result_1', 'bevel', {'offset': 0.2, 'harden_normals': True}],
- ['EDGE', {4, 7, 39, 27, 30, 31}, 'Blocksteps_test', 'Blocksteps_result_1', 'bevel',
- {'offset': 0.2, 'miter_outer': 'PATCH'}],
- ['EDGE', {4, 7, 39, 27, 30, 31}, 'Blocksteps_test', 'Blocksteps_result_2', 'bevel',
- {'offset': 0.2, 'segments': 2, 'miter_outer': 'PATCH'}],
- ['EDGE', {4, 7, 39, 27, 30, 31}, 'Blocksteps_test', 'Blocksteps_result_3', 'bevel',
- {'offset': 0.2, 'segments': 3, 'miter_outer': 'PATCH'}],
- ['EDGE', {4, 7, 39, 27, 30, 31}, 'Blocksteps_test', 'Blocksteps_result_4', 'bevel',
- {'offset': 0.2, 'miter_outer': 'ARC'}],
+ MeshTest("test 77", 'Cube_hn_test', 'Cube_hn_result_1',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2, 'harden_normals': True}, 'EDGE', {8}, )]),
+ MeshTest('Blocksteps_test_1', 'Blocksteps_test', 'Blocksteps_result_1',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'miter_outer': 'PATCH'}, 'EDGE', {4, 7, 39, 27, 30, 31}, )]),
+ MeshTest('Blocksteps_test_2', 'Blocksteps_test', 'Blocksteps_result_2',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'segments': 2, 'miter_outer': 'PATCH'}, 'EDGE',
+ {4, 7, 39, 27, 30, 31}, )]),
+ MeshTest('Blocksteps_test_3', 'Blocksteps_test', 'Blocksteps_result_3',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'segments': 3, 'miter_outer': 'PATCH'}, 'EDGE',
+ {4, 7, 39, 27, 30, 31}, )]),
+ MeshTest('Blocksteps_test_4', 'Blocksteps_test', 'Blocksteps_result_4',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'miter_outer': 'ARC'}, 'EDGE', {4, 7, 39, 27, 30, 31}, )]),
# 80
- ['EDGE', {4, 7, 39, 27, 30, 31}, 'Blocksteps_test', 'Blocksteps_result_5', 'bevel',
- {'offset': 0.2, 'segments': 2, 'miter_outer': 'ARC'}],
- ['EDGE', {4, 7, 39, 27, 30, 31}, 'Blocksteps_test', 'Blocksteps_result_6', 'bevel',
- {'offset': 0.2, 'segments': 3, 'miter_outer': 'ARC'}],
- ['EDGE', {4, 7, 39, 27, 30, 31}, 'Blocksteps_test', 'Blocksteps_result_7', 'bevel',
- {'offset': 0.2, 'miter_outer': 'PATCH', 'miter_inner': 'ARC'}],
- ['EDGE', {4, 7, 39, 27, 30, 31}, 'Blocksteps_test', 'Blocksteps_result_8', 'bevel',
- {'offset': 0.2, 'segments': 2, 'miter_outer': 'PATCH', 'miter_inner': 'ARC'}],
- ['EDGE', {4, 7, 39, 27, 30, 31}, 'Blocksteps2_test', 'Blocksteps2_result_9', 'bevel',
- {'offset': 0.2, 'segments': 2, 'miter_outer': 'ARC'}],
+ MeshTest('Blocksteps_test_5', 'Blocksteps_test', 'Blocksteps_result_5',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'segments': 2, 'miter_outer': 'ARC'}, 'EDGE',
+ {4, 7, 39, 27, 30, 31}, )]),
+ MeshTest('Blocksteps_test_6', 'Blocksteps_test', 'Blocksteps_result_6',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'segments': 3, 'miter_outer': 'ARC'}, 'EDGE',
+ {4, 7, 39, 27, 30, 31}, )]),
+ MeshTest('Blocksteps_test_7', 'Blocksteps_test', 'Blocksteps_result_7',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'miter_outer': 'PATCH', 'miter_inner': 'ARC'}, 'EDGE',
+ {4, 7, 39, 27, 30, 31}, )]),
+ MeshTest("Blocksteps_test_8", 'Blocksteps_test', 'Blocksteps_result_8',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'segments': 2, 'miter_outer': 'PATCH', 'miter_inner': 'ARC'},
+ 'EDGE', {4, 7, 39, 27, 30, 31}, )]),
+ MeshTest('Blocksteps2_test', 'Blocksteps2_test', 'Blocksteps2_result_9',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'segments': 2, 'miter_outer': 'ARC'}, 'EDGE',
+ {4, 7, 39, 27, 30, 31}, )]),
# 85
- ['EDGE', {4, 7, 39, 27, 30, 31}, 'Blocksteps3_test', 'Blocksteps3_result_10', 'bevel',
- {'offset': 0.2, 'segments': 2, 'miter_outer': 'ARC'}],
- ['EDGE', {4, 7, 39, 27, 30, 31}, 'Blocksteps4_test', 'Blocksteps4_result_11', 'bevel',
- {'offset': 0.2, 'segments': 2, 'miter_outer': 'ARC'}],
- ['EDGE', {4, 7, 39, 27, 30, 31}, 'Blocksteps4_test', 'Blocksteps4_result_12', 'bevel',
- {'offset': 0.2, 'segments': 3, 'miter_outer': 'ARC'}],
- ['EDGE', {1, 7}, 'Spike_test', 'Spike_result_1', 'bevel', {'offset': 0.2, 'segments': 3}]
- ]
+ MeshTest('Blocksteps3_test', 'Blocksteps3_test', 'Blocksteps3_result_10',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'segments': 2, 'miter_outer': 'ARC'}, 'EDGE',
+ {4, 7, 39, 27, 30, 31}, )]),
+ MeshTest('Blocksteps4_test_1', 'Blocksteps4_test', 'Blocksteps4_result_11',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'segments': 2, 'miter_outer': 'ARC'}, 'EDGE',
+ {4, 7, 39, 27, 30, 31}, )]),
+ MeshTest('Blocksteps4_test_2', 'Blocksteps4_test', 'Blocksteps4_result_12',
+ [OperatorSpecEditMode('bevel',
+ {'offset': 0.2, 'segments': 3, 'miter_outer': 'ARC'}, 'EDGE',
+ {4, 7, 39, 27, 30, 31}, )]),
+ MeshTest('Spike_test', 'Spike_test', 'Spike_result_1',
+ [OperatorSpecEditMode('bevel', {'offset': 0.2, 'segments': 3}, 'EDGE', {1, 7})])
- operator_test = OperatorTest(tests)
+ ]
+ operator_test = RunTest(tests)
command = list(sys.argv)
for i, cmd in enumerate(command):
if cmd == "--run-all-tests":
+ operator_test.do_compare = True
operator_test.run_all_tests()
break
elif cmd == "--run-test":
- index = int(command[i + 1])
- operator_test.run_test(index)
+ name = command[i + 1]
+ operator_test.do_compare = False
+ operator_test.run_test(name)
break
diff --git a/tests/python/boolean_operator.py b/tests/python/boolean_operator.py
index b35c69b7ca5..0db6a074699 100644
--- a/tests/python/boolean_operator.py
+++ b/tests/python/boolean_operator.py
@@ -29,33 +29,53 @@ import os
import sys
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
-from modules.mesh_test import OperatorTest
+from modules.mesh_test import MeshTest, OperatorSpecEditMode, RunTest
def main():
tests = [
- ['FACE', {0, 1, 2, 3, 4, 5}, 'Cubecube', 'Cubecube_result_1', 'intersect_boolean', {'operation': 'UNION', 'solver' : 'FAST'}],
- ['FACE', {0, 1, 2, 3, 4, 5}, 'Cubecube', 'Cubecube_result_2', 'intersect_boolean', {'operation': 'INTERSECT', 'solver' : 'FAST'}],
- ['FACE', {0, 1, 2, 3, 4, 5}, 'Cubecube', 'Cubecube_result_3', 'intersect_boolean', {'operation': 'DIFFERENCE', 'solver' : 'FAST'}],
- ['FACE', {0, 1, 2, 3, 4, 5}, 'Cubecube', 'Cubecube_result_4', 'intersect', {'separate_mode': 'CUT', 'solver' : 'FAST'}],
- ['FACE', {0, 1, 2, 3, 4, 5}, 'Cubecube', 'Cubecube_result_5', 'intersect', {'separate_mode': 'ALL', 'solver' : 'FAST'}],
- ['FACE', {0, 1, 2, 3, 4, 5}, 'Cubecube', 'Cubecube_result_6', 'intersect', {'separate_mode': 'NONE', 'solver' : 'FAST'}],
- ['FACE', {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 'Cubecube', 'Cubecube_result_7', 'intersect',
- {'mode': 'SELECT', 'separate_mode': 'NONE', 'solver' : 'FAST'}],
- ['FACE', {6, 7, 8, 9, 10}, 'Cubecone', 'Cubecone_result_1', 'intersect_boolean', {'operation': 'UNION', 'solver' : 'FAST'}],
- ['FACE', {0, 1, 2, 3, 4, 5}, 'Cubecones', 'Cubecones_result_1', 'intersect_boolean', {'operation': 'UNION', 'solver' : 'FAST'}],
+
+ MeshTest('Cubecube_intersect_union', 'Cubecube', 'Cubecube_result_1',
+ [OperatorSpecEditMode('intersect_boolean',
+ {'operation': 'UNION', 'solver': 'FAST'}, 'FACE', {0, 1, 2, 3, 4, 5}, )]),
+ MeshTest('Cubecube_intersect_intersect', 'Cubecube', 'Cubecube_result_2',
+ [OperatorSpecEditMode('intersect_boolean', {'operation': 'INTERSECT', 'solver': 'FAST'}, 'FACE', {0, 1, 2, 3, 4, 5}, )]),
+ MeshTest('Cubecube_intersect_difference', 'Cubecube', 'Cubecube_result_3',
+ [OperatorSpecEditMode('intersect_boolean', {'operation': 'DIFFERENCE', 'solver': 'FAST'}, 'FACE',
+ {0, 1, 2, 3, 4, 5}, )]),
+ MeshTest('Cubecube_intersect_cut', 'Cubecube', 'Cubecube_result_4', [OperatorSpecEditMode('intersect',
+ {'separate_mode': 'CUT', 'solver': 'FAST'}, 'FACE', {0, 1, 2, 3, 4, 5}, )]),
+ MeshTest('Cubecube_intersect_all', 'Cubecube', 'Cubecube_result_5',
+ [OperatorSpecEditMode('intersect',
+ {'separate_mode': 'ALL', 'solver': 'FAST'}, 'FACE', {0, 1, 2, 3, 4, 5}, )]),
+ MeshTest('Cubecube_intersect_none', 'Cubecube', 'Cubecube_result_6',
+ [OperatorSpecEditMode('intersect',
+ {'separate_mode': 'NONE', 'solver': 'FAST'}, 'FACE', {0, 1, 2, 3, 4, 5}, )]),
+ MeshTest('Cubecube_intersect_select_none', 'Cubecube',
+ 'Cubecube_result_7',
+ [OperatorSpecEditMode('intersect',
+ {'mode': 'SELECT', 'separate_mode': 'NONE', 'solver': 'FAST'}, 'FACE',
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, )]),
+ MeshTest('Cubecone_intersect_union', 'Cubecone', 'Cubecone_result_1',
+ [OperatorSpecEditMode('intersect_boolean',
+ {'operation': 'UNION', 'solver': 'FAST'}, 'FACE', {6, 7, 8, 9, 10}, )]),
+ MeshTest('Cubecones_intersect_union', 'Cubecones', 'Cubecones_result_1',
+ [OperatorSpecEditMode('intersect_boolean', {'operation': 'UNION', 'solver': 'FAST'}, 'FACE', {0, 1, 2, 3, 4, 5}, )]),
+
]
- operator_test = OperatorTest(tests)
+ operator_test = RunTest(tests)
command = list(sys.argv)
for i, cmd in enumerate(command):
if cmd == "--run-all-tests":
+ operator_test.do_compare = True
operator_test.run_all_tests()
break
elif cmd == "--run-test":
- index = int(command[i + 1])
- operator_test.run_test(index)
+ name = command[i + 1]
+ operator_test.do_compare = False
+ operator_test.run_test(name)
break
diff --git a/tests/python/deform_modifiers.py b/tests/python/deform_modifiers.py
new file mode 100644
index 00000000000..7c4ea457e9d
--- /dev/null
+++ b/tests/python/deform_modifiers.py
@@ -0,0 +1,119 @@
+# ##### 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>
+
+# To run the test type: blender -b /path/to/the/blend/file --python path/to/this/py/file -- --run-all-tests -- --verbose
+# Type the above line in cmd/terminal, for example, look below
+# blender -b c:\blender-lib\deform_modifiers.blend --python c:\deform_modifiers.py -- --run-all-tests -- --verbose
+
+
+import os
+import sys
+import bpy
+
+sys.path.append(os.path.dirname(os.path.realpath(__file__)))
+from modules.mesh_test import MeshTest, ModifierSpec, OperatorSpecObjectMode, DeformModifierSpec, RunTest
+
+tests = [
+
+ # Surface Deform Test, finally can bind to the Target object.
+ # Actual deformation occurs by animating imitating user input.
+
+ MeshTest("SurfaceDeform", "testObjMonkeySurfaceDeform", "expObjMonkeySurfaceDeform",
+ [DeformModifierSpec(10, [
+ ModifierSpec('surface_deform', 'SURFACE_DEFORM', {'target': bpy.data.objects["Cube"]})],
+ OperatorSpecObjectMode('surfacedeform_bind', {'modifier': 'surface_deform'}))]),
+
+ # Mesh Deform Test, finally can bind to the Target object.
+ # Actual deformation occurs by animating imitating user input.
+
+ MeshTest("MeshDeform", "testObjMonkeyMeshDeform", "expObjMonkeyMeshDeform",
+ [DeformModifierSpec(10, [ModifierSpec('mesh_deform', 'MESH_DEFORM',
+ {'object': bpy.data.objects["MeshCube"], 'precision': 2})],
+ OperatorSpecObjectMode('meshdeform_bind', {'modifier': 'mesh_deform'}))]),
+
+ # Surface Deform Test, finally can bind to the Target object.
+ # Actual deformation occurs by animating imitating user input.
+
+ MeshTest("Hook", "testObjHookPlane", "expObjHookPlane",
+ [DeformModifierSpec(10, [ModifierSpec('hook', 'HOOK',
+ {'object': bpy.data.objects["Empty"], 'falloff_radius': 1,
+ 'vertex_group': 'Group'})])]),
+
+ # Laplacian Deform Test, first a hook is attached.
+
+ MeshTest("Laplace", "testObjCubeLaplacian", "expObjCubeLaplacian",
+ [DeformModifierSpec(10,
+ [ModifierSpec('hook2', 'HOOK', {'object': bpy.data.objects["Empty.001"],
+ 'vertex_group': 'hook_vg'}),
+ ModifierSpec('laplace', 'LAPLACIANDEFORM', {'vertex_group': 'laplace_vg'})],
+ OperatorSpecObjectMode('laplaciandeform_bind', {'modifier': 'laplace'}))]),
+
+ MeshTest("WarpPlane", "testObjPlaneWarp", "expObjPlaneWarp",
+ [DeformModifierSpec(10, [ModifierSpec('warp', 'WARP',
+ {'object_from': bpy.data.objects["From"],
+ 'object_to': bpy.data.objects["To"],
+ })])]),
+
+ #############################################
+ # Curves Deform Modifiers
+ #############################################
+ MeshTest("CurveArmature", "testObjBezierCurveArmature", "expObjBezierCurveArmature",
+ [DeformModifierSpec(10, [ModifierSpec('curve_armature', 'ARMATURE',
+ {'object': bpy.data.objects['testArmatureHelper'],
+ 'use_vertex_groups': False, 'use_bone_envelopes': True})])]),
+
+ MeshTest("CurveLattice", "testObjBezierCurveLattice", "expObjBezierCurveLattice",
+ [DeformModifierSpec(10, [ModifierSpec('curve_lattice', 'LATTICE',
+ {'object': bpy.data.objects['testLatticeCurve']})])]),
+
+ # HOOK for Curves can't be tested with current framework, as it requires going to Edit Mode to select vertices,
+ # here is no equivalent of a vertex group in Curves.
+ # Dummy test for Hook, can also be called corner case
+ MeshTest("CurveHook", "testObjBezierCurveHook", "expObjBezierCurveHook",
+ [DeformModifierSpec(10,
+ [ModifierSpec('curve_Hook', 'HOOK', {'object': bpy.data.objects['EmptyCurve']})])]),
+
+ MeshTest("MeshDeformCurve", "testObjCurveMeshDeform", "expObjCurveMeshDeform",
+ [DeformModifierSpec(10, [
+ ModifierSpec('mesh_deform_curve', 'MESH_DEFORM', {'object': bpy.data.objects["Cylinder"],
+ 'precision': 2})],
+ OperatorSpecObjectMode('meshdeform_bind', {'modifier': 'mesh_deform_curve'}))]),
+
+ MeshTest("WarpCurve", "testObjBezierCurveWarp", "expObjBezierCurveWarp",
+ [DeformModifierSpec(10, [ModifierSpec('warp_curve', 'WARP',
+ {'object_from': bpy.data.objects["From_curve"],
+ 'object_to': bpy.data.objects["To_curve"]})])]),
+
+]
+
+deform_tests = RunTest(tests)
+command = list(sys.argv)
+for i, cmd in enumerate(command):
+ if cmd == "--run-all-tests":
+ deform_tests.apply_modifiers = True
+ deform_tests.do_compare = True
+ deform_tests.run_all_tests()
+ break
+ elif cmd == "--run-test":
+ deform_tests.apply_modifiers = False
+ deform_tests.do_compare = False
+ name = command[i + 1]
+ deform_tests.run_test(name)
+ break
diff --git a/tests/python/modifiers.py b/tests/python/modifiers.py
index ba156cef8ea..24f71c4066d 100644
--- a/tests/python/modifiers.py
+++ b/tests/python/modifiers.py
@@ -26,7 +26,7 @@ from random import shuffle, seed
import bpy
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
-from modules.mesh_test import ModifierTest, ModifierSpec
+from modules.mesh_test import RunTest, ModifierSpec, MeshTest
seed(0)
@@ -47,7 +47,7 @@ def get_generate_modifiers_list(test_object_name, randomize=False):
ModifierSpec('array', 'ARRAY', {}),
ModifierSpec('bevel', 'BEVEL', {'width': 0.1}),
ModifierSpec('boolean', 'BOOLEAN', {'object': boolean_test_object, 'solver': 'FAST'}),
- ModifierSpec('build', 'BUILD', {'frame_start': 0, 'frame_duration': 1}),
+ ModifierSpec('build', 'BUILD', {'frame_start': 1, 'frame_duration': 1}, 2),
ModifierSpec('decimate', 'DECIMATE', {}),
ModifierSpec('edge split', 'EDGE_SPLIT', {}),
@@ -62,7 +62,6 @@ def get_generate_modifiers_list(test_object_name, randomize=False):
# ModifierSpec('remesh', 'REMESH', {}),
# ModifierSpec('screw', 'SCREW', {}), # screw can make the test very slow. Skipping for now.
- # ModifierSpec('skin', 'SKIN', {}), # skin is not reproducible .
ModifierSpec('solidify', 'SOLIDIFY', {}),
ModifierSpec('subsurf', 'SUBSURF', {}),
@@ -78,7 +77,6 @@ def get_generate_modifiers_list(test_object_name, randomize=False):
def main():
-
mask_first_list = get_generate_modifiers_list("testCubeMaskFirst", randomize=True)
mask_vertex_group = "testCubeMaskFirst" + "_mask"
mask_first_list.insert(0, ModifierSpec('mask', 'MASK', {'vertex_group': mask_vertex_group}))
@@ -88,169 +86,279 @@ def main():
# List of 'Generate' modifiers on a cube
###############################
# 0
- # ["testCube", "expectedCube", get_generate_modifiers_list("testCube")],
- ["testCubeRandom", "expectedCubeRandom", get_generate_modifiers_list("testCubeRandom", randomize=True)],
- ["testCubeMaskFirst", "expectedCubeMaskFirst", mask_first_list],
-
- ["testCollapseDecimate", "expectedCollapseDecimate",
- [ModifierSpec("subdivision", 'SUBSURF', {"levels": 2}),
- ModifierSpec('decimate', 'DECIMATE', {'decimate_type': 'COLLAPSE', 'ratio': 0.25, 'use_collapse_triangulate': True})]],
- ["testPlanarDecimate", "expectedPlanarDecimate",
- [ModifierSpec("subdivision", 'SUBSURF', {"levels": 2}),
- ModifierSpec('decimate', 'DECIMATE', {'decimate_type': 'DISSOLVE', 'angle_limit': math.radians(30)})]],
- ["testUnsubdivideDecimate", "expectedUnsubdivideDecimate",
- [ModifierSpec("subdivision", 'SUBSURF', {"levels": 2}),
- ModifierSpec('decimate', 'DECIMATE', {'decimate_type': 'UNSUBDIV', 'iterations': 2})]],
+ # MeshTest("testCube", "expectedCube", get_generate_modifiers_list("testCube")),
+ MeshTest("CubeRandom", "testCubeRandom", "expectedCubeRandom",
+ get_generate_modifiers_list("testCubeRandom", randomize=True)),
+ MeshTest("CubeMaskFirst", "testCubeMaskFirst", "expectedCubeMaskFirst", mask_first_list),
+
+ MeshTest("CollapseDecimate", "testCollapseDecimate", "expectedCollapseDecimate",
+ [ModifierSpec("subdivision", 'SUBSURF', {"levels": 2}),
+ ModifierSpec('decimate', 'DECIMATE',
+ {'decimate_type': 'COLLAPSE', 'ratio': 0.25, 'use_collapse_triangulate': True})]),
+ MeshTest("PlanarDecimate", "testPlanarDecimate", "expectedPlanarDecimate",
+ [ModifierSpec("subdivision", 'SUBSURF', {"levels": 2}),
+ ModifierSpec('decimate', 'DECIMATE',
+ {'decimate_type': 'DISSOLVE', 'angle_limit': math.radians(30)})]),
+ MeshTest("UnsubdivideDecimate", "testUnsubdivideDecimate", "expectedUnsubdivideDecimate",
+ [ModifierSpec("subdivision", 'SUBSURF', {"levels": 2}),
+ ModifierSpec('decimate', 'DECIMATE', {'decimate_type': 'UNSUBDIV', 'iterations': 2})]),
# 5
- ["testRadialBisectMirror", "expectedRadialBisectMirror",
- [ModifierSpec('mirror1', 'MIRROR', {'use_bisect_axis': (True, False, False)}),
- ModifierSpec('mirror2', 'MIRROR', {'use_bisect_axis': (True, False, False), 'mirror_object': bpy.data.objects["testRadialBisectMirrorHelper"]}),
- ModifierSpec('mirror3', 'MIRROR', {'use_axis': (False, True, False), 'use_bisect_axis': (False, True, False), 'use_bisect_flip_axis': (False, True, False), 'mirror_object': bpy.data.objects["testRadialBisectMirrorHelper"]})]],
- ["regressT58411Mirror", "expectedT58411Mirror",
- [ModifierSpec('mirror', 'MIRROR', {}),
- ModifierSpec('bevel', 'BEVEL', {'segments': 2, 'limit_method': 'WEIGHT'}),
- ModifierSpec('subd', 'SUBSURF', {'levels': 1})]],
-
- ["testBasicScrew", "expectedBasicScrew",
- [ModifierSpec('mirror', 'MIRROR', {'mirror_object': bpy.data.objects["testBasicScrewHelper"]}),
- ModifierSpec("screw", 'SCREW', {'angle': math.radians(400), 'steps': 20, 'iterations': 2, 'screw_offset': 2, 'use_normal_calculate': True})]],
- ["testObjectScrew", "expectedObjectScrew",
- [ModifierSpec('mirror', 'MIRROR', {'mirror_object': bpy.data.objects["testObjectScrewHelper2"]}),
- ModifierSpec("screw", 'SCREW', {"angle": math.radians(600), 'steps': 32, 'iterations': 1, 'use_object_screw_offset': True, 'use_normal_calculate': True, 'object': bpy.data.objects["testObjectScrewHelper1"]})]],
+ MeshTest("RadialBisectMirror", "testRadialBisectMirror", "expectedRadialBisectMirror",
+ [ModifierSpec('mirror1', 'MIRROR', {'use_bisect_axis': (True, False, False)}),
+ ModifierSpec('mirror2', 'MIRROR', {'use_bisect_axis': (True, False, False),
+ 'mirror_object': bpy.data.objects[
+ "testRadialBisectMirrorHelper"]}),
+ ModifierSpec('mirror3', 'MIRROR',
+ {'use_axis': (False, True, False), 'use_bisect_axis': (False, True, False),
+ 'use_bisect_flip_axis': (False, True, False),
+ 'mirror_object': bpy.data.objects["testRadialBisectMirrorHelper"]})]),
+ MeshTest("T58411Mirror", "regressT58411Mirror", "expectedT58411Mirror",
+ [ModifierSpec('mirror', 'MIRROR', {}),
+ ModifierSpec('bevel', 'BEVEL', {'segments': 2, 'limit_method': 'WEIGHT'}),
+ ModifierSpec('subd', 'SUBSURF', {'levels': 1})]),
+
+ MeshTest("BasicScrew", "testBasicScrew", "expectedBasicScrew",
+ [ModifierSpec('mirror', 'MIRROR', {'mirror_object': bpy.data.objects["testBasicScrewHelper"]}),
+ ModifierSpec("screw", 'SCREW',
+ {'angle': math.radians(400), 'steps': 20, 'iterations': 2, 'screw_offset': 2,
+ 'use_normal_calculate': True})]),
+ MeshTest("ObjectScrew", "testObjectScrew", "expectedObjectScrew",
+ [ModifierSpec('mirror', 'MIRROR', {'mirror_object': bpy.data.objects["testObjectScrewHelper2"]}),
+ ModifierSpec("screw", 'SCREW',
+ {"angle": math.radians(600), 'steps': 32, 'iterations': 1,
+ 'use_object_screw_offset': True,
+ 'use_normal_calculate': True, 'object': bpy.data.objects["testObjectScrewHelper1"]})]),
# 9
- ["testMergedScrewWeld", "expectedMergedScrewWeld",
- [ModifierSpec("screw", 'SCREW', {'angle': math.radians(360), 'steps': 12, 'iterations': 1, 'screw_offset': 1, 'use_normal_calculate': True, 'use_merge_vertices': True}),
- ModifierSpec("weld", 'WELD', {"merge_threshold": 0.001})]],
- ["regressT72380Weld", "expectedT72380Weld",
- [ModifierSpec('vedit', 'VERTEX_WEIGHT_EDIT', {'vertex_group': 'Group', 'use_remove': True, 'remove_threshold': 1}),
- ModifierSpec("weld", 'WELD', {"merge_threshold": 0.2, "vertex_group": "Group"})]],
- ["regressT72792Weld", "expectedT72792Weld",
- [ModifierSpec('array', 'ARRAY', {'fit_type': 'FIXED_COUNT', 'count': 2}),
- ModifierSpec("weld", 'WELD', {"merge_threshold": 0.1, "vertex_group": "Group"})]],
+ MeshTest("MergedScrewWeld", "testMergedScrewWeld", "expectedMergedScrewWeld",
+ [ModifierSpec("screw", 'SCREW',
+ {'angle': math.radians(360), 'steps': 12, 'iterations': 1, 'screw_offset': 1,
+ 'use_normal_calculate': True, 'use_merge_vertices': True}),
+ ModifierSpec("weld", 'WELD', {"merge_threshold": 0.001})]),
+ MeshTest("T72380Weld", "regressT72380Weld", "expectedT72380Weld",
+ [ModifierSpec('vedit', 'VERTEX_WEIGHT_EDIT',
+ {'vertex_group': 'Group', 'use_remove': True, 'remove_threshold': 1}),
+ ModifierSpec("weld", 'WELD', {"merge_threshold": 0.2, "vertex_group": "Group"})]),
+ MeshTest("T72792Weld", "regressT72792Weld", "expectedT72792Weld",
+ [ModifierSpec('array', 'ARRAY', {'fit_type': 'FIXED_COUNT', 'count': 2}),
+ ModifierSpec("weld", 'WELD', {"merge_threshold": 0.1, "vertex_group": "Group"})]),
############################################
# One 'Generate' modifier on primitive meshes
#############################################
# 12
- ["testCubeArray", "expectedCubeArray", [ModifierSpec('array', 'ARRAY', {})]],
- ["testCapArray", "expectedCapArray",
- [ModifierSpec('array', 'ARRAY', {'fit_type': 'FIT_LENGTH', 'fit_length': 2.0, 'start_cap': bpy.data.objects["testCapStart"], 'end_cap': bpy.data.objects["testCapEnd"]})]],
- ["testCurveArray", "expectedCurveArray",
- [ModifierSpec('array', 'ARRAY', {'fit_type': 'FIT_CURVE', 'curve': bpy.data.objects["testCurveArrayHelper"], 'use_relative_offset': False, 'use_constant_offset': True, 'constant_offset_displace': (0.5, 0, 0)})]],
- ["testRadialArray", "expectedRadialArray",
- [ModifierSpec('array', 'ARRAY', {'fit_type': 'FIXED_COUNT', 'count': 3, 'use_merge_vertices': True, 'use_merge_vertices_cap': True, 'use_relative_offset': False, 'use_object_offset': True, 'offset_object': bpy.data.objects["testRadialArrayHelper"]})]],
-
- ["testCylinderBuild", "expectedCylinderBuild", [ModifierSpec('build', 'BUILD', {'frame_start': 0, 'frame_duration': 1})]],
+ MeshTest("CubeArray", "testCubeArray", "expectedCubeArray",
+ [ModifierSpec('array', 'ARRAY', {})]),
+ MeshTest("CapArray", "testCapArray", "expectedCapArray",
+ [ModifierSpec('array', 'ARRAY',
+ {'fit_type': 'FIT_LENGTH', 'fit_length': 2.0,
+ 'start_cap': bpy.data.objects["testCapStart"],
+ 'end_cap': bpy.data.objects["testCapEnd"]})]),
+ MeshTest("CurveArray", "testCurveArray", "expectedCurveArray",
+ [ModifierSpec('array', 'ARRAY',
+ {'fit_type': 'FIT_CURVE', 'curve': bpy.data.objects["testCurveArrayHelper"],
+ 'use_relative_offset': False, 'use_constant_offset': True,
+ 'constant_offset_displace': (0.5, 0, 0)})]),
+ MeshTest("RadialArray", "testRadialArray", "expectedRadialArray",
+ [ModifierSpec('array', 'ARRAY', {'fit_type': 'FIXED_COUNT', 'count': 3, 'use_merge_vertices': True,
+ 'use_merge_vertices_cap': True, 'use_relative_offset': False,
+ 'use_object_offset': True,
+ 'offset_object': bpy.data.objects["testRadialArrayHelper"]})]),
+
+ MeshTest("CylinderBuild", "testCylinderBuild", "expectedCylinderBuild",
+ [ModifierSpec('build', 'BUILD', {'frame_start': 1, 'frame_duration': 1}, 2)]),
# 17
- ["testConeDecimate", "expectedConeDecimate", [ModifierSpec('decimate', 'DECIMATE', {'ratio': 0.5})]],
- ["testCubeEdgeSplit", "expectedCubeEdgeSplit", [ModifierSpec('edge split', 'EDGE_SPLIT', {})]],
-
- ["testSphereMirror", "expectedSphereMirror", [ModifierSpec('mirror', 'MIRROR', {})]],
- ["testLocalMirror", "expectedLocalMirror",
- [ModifierSpec('mirror', 'MIRROR', {'use_clip': True})]],
- ["testObjectOffsetMirror", "expectedObjectOffsetMirror",
- [ModifierSpec('mirror', 'MIRROR', {'mirror_object': bpy.data.objects["testObjectOffsetMirrorHelper"]})]],
-
- ["testCylinderMask", "expectedCylinderMask", [ModifierSpec('mask', 'MASK', {'vertex_group': "mask_vertex_group"})]],
- ["testConeMultiRes", "expectedConeMultiRes", [ModifierSpec('multires', 'MULTIRES', {})]],
+ MeshTest("ConeDecimate", "testConeDecimate", "expectedConeDecimate",
+ [ModifierSpec('decimate', 'DECIMATE', {'ratio': 0.5})]),
+ MeshTest("CubeEdgeSplit", "testCubeEdgeSplit", "expectedCubeEdgeSplit",
+ [ModifierSpec('edge split', 'EDGE_SPLIT', {})]),
+
+ MeshTest("SphereMirror", "testSphereMirror", "expectedSphereMirror",
+ [ModifierSpec('mirror', 'MIRROR', {})]),
+ MeshTest("LocalMirror", "testLocalMirror", "expectedLocalMirror",
+ [ModifierSpec('mirror', 'MIRROR', {'use_clip': True})]),
+ MeshTest("ObjectOffsetMirror", "testObjectOffsetMirror", "expectedObjectOffsetMirror",
+ [ModifierSpec('mirror', 'MIRROR',
+ {'mirror_object': bpy.data.objects["testObjectOffsetMirrorHelper"]})]),
+
+ MeshTest("CylinderMask", "testCylinderMask", "expectedCylinderMask",
+ [ModifierSpec('mask', 'MASK', {'vertex_group': "mask_vertex_group"})]),
+ MeshTest("ConeMultiRes", "testConeMultiRes", "expectedConeMultiRes",
+ [ModifierSpec('multires', 'MULTIRES', {})]),
# 24
- ["testCubeScrew", "expectedCubeScrew", [ModifierSpec('screw', 'SCREW', {})]],
-
- ["testCubeSolidify", "expectedCubeSolidify", [ModifierSpec('solidify', 'SOLIDIFY', {})]],
- ["testComplexSolidify", "expectedComplexSolidify",
- [ModifierSpec('solidify', 'SOLIDIFY', {'solidify_mode': 'NON_MANIFOLD', 'thickness': 0.05, 'offset': 0, 'nonmanifold_thickness_mode': 'CONSTRAINTS'})]],
- ["regressT63063Solidify", "expectedT63063Solidify",
- [ModifierSpec('solid', 'SOLIDIFY', {'thickness': 0.1, 'offset': 0.7})]],
- ["regressT61979Solidify", "expectedT61979Solidify",
- [ModifierSpec('solid', 'SOLIDIFY', {'thickness': -0.25, 'use_even_offset': True, 'use_quality_normals': True})]],
-
- ["testMonkeySubsurf", "expectedMonkeySubsurf", [ModifierSpec('subsurf', 'SUBSURF', {})]],
- ["testCatmullClarkSubdivisionSurface", "expectedCatmullClarkSubdivisionSurface",
- [ModifierSpec("subdivision", 'SUBSURF', {"levels": 2})]],
- ["testSimpleSubdivisionSurface", "expectedSimpleSubdivisionSurface",
- [ModifierSpec("subdivision", 'SUBSURF', {"levels": 2, 'subdivision_type': 'SIMPLE'})]],
- ["testCrease2dSubdivisionSurface", "expectedCrease2dSubdivisionSurface",
- [ModifierSpec("subdivision", 'SUBSURF', {"levels": 2})]],
- ["testCrease3dSubdivisionSurface", "expectedCrease3dSubdivisionSurface",
- [ModifierSpec("subdivision", 'SUBSURF', {"levels": 2})]],
+ MeshTest("CubeScrew", "testCubeScrew", "expectedCubeScrew",
+ [ModifierSpec('screw', 'SCREW', {})]),
+
+ MeshTest("CubeSolidify", "testCubeSolidify", "expectedCubeSolidify",
+ [ModifierSpec('solidify', 'SOLIDIFY', {})]),
+ MeshTest("ComplexSolidify", "testComplexSolidify", "expectedComplexSolidify",
+ [ModifierSpec('solidify', 'SOLIDIFY', {'solidify_mode': 'NON_MANIFOLD', 'thickness': 0.05, 'offset': 0,
+ 'nonmanifold_thickness_mode': 'CONSTRAINTS'})]),
+ MeshTest("T63063Solidify", "regressT63063Solidify", "expectedT63063Solidify",
+ [ModifierSpec('solid', 'SOLIDIFY', {'thickness': 0.1, 'offset': 0.7})]),
+ MeshTest("T61979Solidify", "regressT61979Solidify", "expectedT61979Solidify",
+ [ModifierSpec('solid', 'SOLIDIFY',
+ {'thickness': -0.25, 'use_even_offset': True, 'use_quality_normals': True})]),
+
+ MeshTest("MonkeySubsurf", "testMonkeySubsurf", "expectedMonkeySubsurf",
+ [ModifierSpec('subsurf', 'SUBSURF', {})]),
+ MeshTest("CatmullClarkSubdivisionSurface", "testCatmullClarkSubdivisionSurface",
+ "expectedCatmullClarkSubdivisionSurface",
+ [ModifierSpec("subdivision", 'SUBSURF', {"levels": 2})]),
+ MeshTest("SimpleSubdivisionSurface", "testSimpleSubdivisionSurface", "expectedSimpleSubdivisionSurface",
+ [ModifierSpec("subdivision", 'SUBSURF', {"levels": 2, 'subdivision_type': 'SIMPLE'})]),
+ MeshTest("Crease2dSubdivisionSurface", "testCrease2dSubdivisionSurface", "expectedCrease2dSubdivisionSurface",
+ [ModifierSpec("subdivision", 'SUBSURF', {"levels": 2})]),
+ MeshTest("Crease3dSubdivisionSurface", "testCrease3dSubdivisionSurface", "expectedCrease3dSubdivisionSurface",
+ [ModifierSpec("subdivision", 'SUBSURF', {"levels": 2})]),
# 34
- ["testSphereTriangulate", "expectedSphereTriangulate", [ModifierSpec('triangulate', 'TRIANGULATE', {})]],
- ["testMonkeyWireframe", "expectedMonkeyWireframe", [ModifierSpec('wireframe', 'WIREFRAME', {})]],
- #ModifierSpec('skin', 'SKIN', {}), # skin is not reproducible .
- ["testMergedWeld", "expectedMergedWeld",
- [ModifierSpec("weld", 'WELD', {"merge_threshold": 0.021})]],
- ["testMergedAllWeld", "expectedMergedAllWeld",
- [ModifierSpec("weld", 'WELD', {"merge_threshold": 1.8})]],
- ["testMergedNoneWeld", "expectedMergedNoneWeld",
- [ModifierSpec("weld", 'WELD', {"merge_threshold": 0.019})]],
+ MeshTest("SphereTriangulate", "testSphereTriangulate", "expectedSphereTriangulate",
+ [ModifierSpec('triangulate', 'TRIANGULATE', {})]),
+ MeshTest("MonkeyWireframe", "testMonkeyWireframe", "expectedMonkeyWireframe",
+ [ModifierSpec('wireframe', 'WIREFRAME', {})]),
+
+ # Duplicate the object, test object and expected object have same world coordinates.
+ MeshTest("Skin", "testObjPlaneSkin", "expObjPlaneSkin",
+ [ModifierSpec('skin', 'SKIN', {})]),
+
+ MeshTest("MergedWeld", "testMergedWeld", "expectedMergedWeld",
+ [ModifierSpec("weld", 'WELD', {"merge_threshold": 0.021})]),
+ MeshTest("MergedAllWeld", "testMergedAllWeld", "expectedMergedAllWeld",
+ [ModifierSpec("weld", 'WELD', {"merge_threshold": 1.8})]),
+ MeshTest("MergedNoneWeld", "testMergedNoneWeld", "expectedMergedNoneWeld",
+ [ModifierSpec("weld", 'WELD', {"merge_threshold": 0.019})]),
+
#############################################
# One 'Deform' modifier on primitive meshes
#############################################
# 39
- ["testMonkeyArmature", "expectedMonkeyArmature",
- [ModifierSpec('armature', 'ARMATURE', {'object': bpy.data.objects['testArmature'], 'use_vertex_groups': True})]],
- ["testTorusCast", "expectedTorusCast", [ModifierSpec('cast', 'CAST', {'factor': 2.64})]],
- ["testCubeCurve", "expectedCubeCurve",
- [ModifierSpec('curve', 'CURVE', {'object': bpy.data.objects['testBezierCurve']})]],
- ["testMonkeyDisplace", "expectedMonkeyDisplace", [ModifierSpec('displace', "DISPLACE", {})]],
-
- # Hook modifier requires moving the hook object to get a mesh change, so can't test it with the current framework
- # ["testMonkeyHook", "expectedMonkeyHook",
- # [ModifierSpec('hook', 'HOOK', {'object': bpy.data.objects["EmptyHook"], 'vertex_group': "HookVertexGroup"})]],
+ MeshTest("MonkeyArmature", "testMonkeyArmature", "expectedMonkeyArmature",
+ [ModifierSpec('armature', 'ARMATURE',
+ {'object': bpy.data.objects['testArmature'], 'use_vertex_groups': True})]),
+ MeshTest("TorusCast", "testTorusCast", "expectedTorusCast",
+ [ModifierSpec('cast', 'CAST', {'factor': 2.64})]),
+ MeshTest("CubeCurve", "testCubeCurve", "expectedCubeCurve",
+ [ModifierSpec('curve', 'CURVE', {'object': bpy.data.objects['testBezierCurve']})]),
+ MeshTest("MonkeyDisplace", "testMonkeyDisplace", "expectedMonkeyDisplace",
+ [ModifierSpec('displace', "DISPLACE", {})]),
+
+ # Hook modifier requires moving the hook object to get a mesh change
+ # so can't test it with the current framework
+ # MeshTest("MonkeyHook", "testMonkeyHook", "expectedMonkeyHook",
+ # [ModifierSpec('hook', 'HOOK', {'object': bpy.data.objects["EmptyHook"], 'vertex_group':
+ # "HookVertexGroup"})]),
# 43
- #ModifierSpec('laplacian_deform', 'LAPLACIANDEFORM', {}) Laplacian requires a more complex mesh
- ["testCubeLattice", "expectedCubeLattice",
- [ModifierSpec('lattice', 'LATTICE', {'object': bpy.data.objects["testLattice"]})]],
-
# ModifierSpec('laplacian_deform', 'LAPLACIANDEFORM', {}) Laplacian requires a more complex mesh
+ MeshTest("CubeLattice", "testCubeLattice", "expectedCubeLattice",
+ [ModifierSpec('lattice', 'LATTICE', {'object': bpy.data.objects["testLattice"]})]),
+
+ MeshTest("PlaneShrinkWrap", "testPlaneShrinkWrap", "expectedPlaneShrinkWrap",
+ [ModifierSpec('shrinkwrap', 'SHRINKWRAP',
+ {'target': bpy.data.objects["testCubeWrap"], 'offset': 0.5})]),
- # Mesh Deform Modifier requires user input, so skip.
+ MeshTest("CylinderSimpleDeform", "testCylinderSimpleDeform", "expectedCylinderSimpleDeform",
+ [ModifierSpec('simple_deform', 'SIMPLE_DEFORM', {'angle': math.radians(180), 'deform_axis': 'Z'})]),
- # mesh_test = MeshTest("testMonkeyDeform", "expectedMonkeyDeform",[
- # ModifierSpec('mesh_deform', 'MESH_DEFORM', {'object': bpy.data.objects["testDeformStructure"]}),
- # OperatorSpec('meshdeform_bind',{'modifier':'MeshDeform'},'FACE',{i for in range(500)})
- # ] ,True)
+ MeshTest("PlaneSmooth", "testPlaneSmooth", "expectedPlaneSmooth",
+ [ModifierSpec('smooth', 'SMOOTH', {'iterations': 11})]),
- ["testPlaneShrinkWrap", "expectedPlaneShrinkWrap",
- [ModifierSpec('shrinkwrap', 'SHRINKWRAP', {'target': bpy.data.objects["testCubeWrap"], 'offset': 0.5})]],
+ # Smooth corrective requires a complex mesh.
- ["testCylinderSimpleDeform", "expectedCylinderSimpleDeform",
- [ModifierSpec('simple_deform', 'SIMPLE_DEFORM', {'angle': math.radians(180), 'deform_axis': 'Z'})]],
+ MeshTest("BalloonLaplacianSmooth", "testBalloonLaplacianSmooth", "expectedBalloonLaplacianSmooth",
+ [ModifierSpec('laplaciansmooth', 'LAPLACIANSMOOTH', {'lambda_factor': 12, 'lambda_border': 12})]),
- ["testPlaneSmooth", "expectedPlaneSmooth",
- [ModifierSpec('smooth', 'SMOOTH', {'iterations': 11})]],
+ # Gets updated often
+ MeshTest("WavePlane", "testObjPlaneWave", "expObjPlaneWave",
+ [ModifierSpec('wave', 'WAVE', {})]),
- # Smooth corrective requires a complex mesh.
+ #############################################
+ # CURVES Generate Modifiers
+ #############################################
+ # Caution: Make sure test object has no modifier in "added" state, the test may fail.
+ MeshTest("BezCurveArray", "testObjBezierCurveArray", "expObjBezierCurveArray",
+ [ModifierSpec('array', 'ARRAY', {})]),
+
+ MeshTest("CurveBevel", "testObjBezierCurveBevel", "expObjBezierCurveBevel",
+ [ModifierSpec('bevel', 'BEVEL', {})]),
+
+ MeshTest("CurveBuild", "testObjBezierCurveBuild", "expObjBezierCurveBuild",
+ [ModifierSpec('build', 'BUILD', {'frame_start': 1, 'frame_duration': 1}, 2)]),
+
+ MeshTest("CurveDecimate", "testObjBezierCurveDecimate", "expObjBezierCurveDecimate",
+ [ModifierSpec('decimate', 'DECIMATE', {'ratio': 0.5})]),
+
+ MeshTest("CurveEdgeSplit", "testObjBezierCurveEdgeSplit", "expObjBezierCurveEdgeSplit",
+ [ModifierSpec('edgeSplit', 'EDGE_SPLIT', {})]),
+
+ MeshTest("CurveMirror", "testObjBezierCurveMirror", "expObjBezierCurveMirror",
+ [ModifierSpec('mirror', 'MIRROR', {'use_axis': (True, True, False)})]),
+
+ MeshTest("CurveScrew", "testObjBezierCurveScrew", "expObjBezierCurveScrew",
+ [ModifierSpec('screw', 'SCREW', {})]),
+
+ MeshTest("CurveSolidify", "testObjBezierCurveSolidify", "expObjBezierCurveSolidify",
+ [ModifierSpec('solidify', 'SOLIDIFY', {'thickness': 1})]),
+
+ MeshTest("CurveSubSurf", "testObjBezierCurveSubSurf", "expObjBezierCurveSubSurf",
+ [ModifierSpec('subSurf', 'SUBSURF', {})]),
+
+ MeshTest("CurveTriangulate", "testObjBezierCurveTriangulate", "expObjBezierCurveTriangulate",
+ [ModifierSpec('triangulate', 'TRIANGULATE', {})]),
+
+ # Test 60
+ # Caution Weld: if the distance is increased beyond a limit, the object disappears
+ MeshTest("CurveWeld", "testObjBezierCurveWeld", "expObjBezierCurveWeld",
+ [ModifierSpec('weld', 'WELD', {})]),
+
+ MeshTest("CurveWeld2", "testObjBezierCurveWeld2", "expObjBezierCurveWeld2",
+ [ModifierSpec('weld', 'WELD', {})]),
+
+ #############################################
+ # Curves Deform Modifiers
+ #############################################
+ # Test 62
+ MeshTest("CurveCast", "testObjBezierCurveCast", "expObjBezierCurveCast",
+ [ModifierSpec('Cast', 'CAST', {'cast_type': 'CYLINDER', 'factor': 10})]),
+
+ MeshTest("CurveShrinkWrap", "testObjBezierCurveShrinkWrap", "expObjBezierCurveShrinkWrap",
+ [ModifierSpec('ShrinkWrap', 'SHRINKWRAP',
+ {'target': bpy.data.objects['testShrinkWrapHelperSuzanne']})]),
+
+ MeshTest("CurveSimpleDeform", "testObjBezierCurveSimpleDeform", "expObjBezierCurveSimpleDeform",
+ [ModifierSpec('simple_deform', 'SIMPLE_DEFORM', {'angle': math.radians(90)})]),
- ["testBalloonLaplacianSmooth", "expectedBalloonLaplacianSmooth",
- [ModifierSpec('laplaciansmooth', 'LAPLACIANSMOOTH', {'lambda_factor': 12, 'lambda_border': 12})]],
+ MeshTest("CurveSmooth", "testObjBezierCurveSmooth", "expObjBezierCurveSmooth",
+ [ModifierSpec('smooth', 'SMOOTH', {'factor': 10})]),
- # Surface Deform and Warp requires user input, so skip.
+ MeshTest("CurveWave", "testObjBezierCurveWave", "expObjBezierCurveWave",
+ [ModifierSpec('curve_wave', 'WAVE', {'time_offset': -1.5})]),
- # Wave - requires complex mesh, so skip.
+ MeshTest("CurveCurve", "testObjBezierCurveCurve", "expObjBezierCurveCurve",
+ [ModifierSpec('curve_Curve', 'CURVE', {'object': bpy.data.objects['NurbsCurve']})]),
]
- modifiers_test = ModifierTest(tests)
+ modifiers_test = RunTest(tests)
command = list(sys.argv)
for i, cmd in enumerate(command):
if cmd == "--run-all-tests":
modifiers_test.apply_modifiers = True
+ modifiers_test.do_compare = True
modifiers_test.run_all_tests()
break
elif cmd == "--run-test":
modifiers_test.apply_modifiers = False
- index = int(command[i + 1])
- modifiers_test.run_test(index)
+ modifiers_test.do_compare = False
+ name = command[i + 1]
+ modifiers_test.run_test(name)
break
diff --git a/tests/python/modules/mesh_test.py b/tests/python/modules/mesh_test.py
index c85e7acf4e8..6671918a206 100644
--- a/tests/python/modules/mesh_test.py
+++ b/tests/python/modules/mesh_test.py
@@ -45,7 +45,6 @@ import functools
import inspect
import os
-
# Output from this module and from blender itself will occur during tests.
# We need to flush python so that the output is properly interleaved, otherwise
# blender's output for one test will end up showing in the middle of another test...
@@ -54,37 +53,39 @@ print = functools.partial(print, flush=True)
class ModifierSpec:
"""
- Holds one modifier and its parameters.
+ Holds a Generate or Deform or Physics modifier type and its parameters.
"""
- def __init__(self, modifier_name: str, modifier_type: str, modifier_parameters: dict):
+ def __init__(self, modifier_name: str, modifier_type: str, modifier_parameters: dict, frame_end=0):
"""
Constructs a modifier spec.
:param modifier_name: str - name of object modifier, e.g. "myFirstSubsurfModif"
:param modifier_type: str - type of object modifier, e.g. "SUBSURF"
:param modifier_parameters: dict - {name : val} dictionary giving modifier parameters, e.g. {"quality" : 4}
+ :param frame_end: int - frame at which simulation needs to be baked or modifier needs to be applied.
"""
self.modifier_name = modifier_name
self.modifier_type = modifier_type
self.modifier_parameters = modifier_parameters
+ self.frame_end = frame_end
def __str__(self):
return "Modifier: " + self.modifier_name + " of type " + self.modifier_type + \
" with parameters: " + str(self.modifier_parameters)
-class PhysicsSpec:
+class ParticleSystemSpec:
"""
- Holds one Physics modifier and its parameters.
+ Holds a Particle System modifier and its parameters.
"""
def __init__(self, modifier_name: str, modifier_type: str, modifier_parameters: dict, frame_end: int):
"""
- Constructs a physics spec.
- :param modifier_name: str - name of object modifier, e.g. "Cloth"
- :param modifier_type: str - type of object modifier, e.g. "CLOTH"
- :param modifier_parameters: dict - {name : val} dictionary giving modifier parameters, e.g. {"quality" : 4}
- :param frame_end:int - the last frame of the simulation at which it is baked
+ Constructs a particle system spec.
+ :param modifier_name: str - name of object modifier, e.g. "Particles"
+ :param modifier_type: str - type of object modifier, e.g. "PARTICLE_SYSTEM"
+ :param modifier_parameters: dict - {name : val} dictionary giving modifier parameters, e.g. {"seed" : 1}
+ :param frame_end: int - the last frame of the simulation at which the modifier is applied
"""
self.modifier_name = modifier_name
self.modifier_type = modifier_type
@@ -96,14 +97,14 @@ class PhysicsSpec:
" with parameters: " + str(self.modifier_parameters) + " with frame end: " + str(self.frame_end)
-class OperatorSpec:
+class OperatorSpecEditMode:
"""
Holds one operator and its parameters.
"""
def __init__(self, operator_name: str, operator_parameters: dict, select_mode: str, selection: set):
"""
- Constructs an operatorSpec. Raises ValueError if selec_mode is invalid.
+ Constructs an OperatorSpecEditMode. Raises ValueError if selec_mode is invalid.
:param operator_name: str - name of mesh operator from bpy.ops.mesh, e.g. "bevel" or "fill"
:param operator_parameters: dict - {name : val} dictionary containing operator parameters.
:param select_mode: str - mesh selection mode, must be either 'VERT', 'EDGE' or 'FACE'
@@ -121,6 +122,45 @@ class OperatorSpec:
" in selection mode: " + self.select_mode + ", selecting " + str(self.selection)
+class OperatorSpecObjectMode:
+ """
+ Holds an object operator and its parameters. Helper class for DeformModifierSpec.
+ Needed to support operations in Object Mode and not Edit Mode which is supported by OperatorSpecEditMode.
+ """
+
+ def __init__(self, operator_name: str, operator_parameters: dict):
+ """
+ :param operator_name: str - name of the object operator from bpy.ops.object, e.g. "shade_smooth" or "shape_keys"
+ :param operator_parameters: dict - contains operator parameters.
+ """
+ self.operator_name = operator_name
+ self.operator_parameters = operator_parameters
+
+ def __str__(self):
+ return "Operator: " + self.operator_name + " with parameters: " + str(self.operator_parameters)
+
+
+class DeformModifierSpec:
+ """
+ Holds a list of deform modifier and OperatorSpecObjectMode.
+ For deform modifiers which have an object operator
+ """
+
+ def __init__(self, frame_number: int, modifier_list: list, object_operator_spec: OperatorSpecObjectMode = None):
+ """
+ Constructs a Deform Modifier spec (for user input)
+ :param frame_number: int - the frame at which animated keyframe is inserted
+ :param modifier_list: ModifierSpec - contains modifiers
+ :param object_operator_spec: OperatorSpecObjectMode - contains object operators
+ """
+ self.frame_number = frame_number
+ self.modifier_list = modifier_list
+ self.object_operator_spec = object_operator_spec
+
+ def __str__(self):
+ return "Modifier: " + str(self.modifier_list) + " with object operator " + str(self.object_operator_spec)
+
+
class MeshTest:
"""
A mesh testing class targeted at testing modifiers and operators on a single object.
@@ -129,33 +169,45 @@ class MeshTest:
"""
def __init__(
- self,
- test_object_name: str,
- expected_object_name: str,
- operations_stack=None,
- apply_modifiers=False,
- threshold=None,
+ self,
+ test_name: str,
+ test_object_name: str,
+ expected_object_name: str,
+ operations_stack=None,
+ apply_modifiers=False,
+ do_compare=False,
+ threshold=None
):
"""
Constructs a MeshTest object. Raises a KeyError if objects with names expected_object_name
or test_object_name don't exist.
- :param test_object: str - Name of object of mesh type to run the operations on.
- :param expected_object: str - Name of object of mesh type that has the expected
+ :param test_name: str - unique test name identifier.
+ :param test_object_name: str - Name of object of mesh type to run the operations on.
+ :param expected_object_name: str - Name of object of mesh type that has the expected
geometry after running the operations.
:param operations_stack: list - stack holding operations to perform on the test_object.
- :param apply_modifier: bool - True if we want to apply the modifiers right after adding them to the object.
- This affects operations of type ModifierSpec only.
+ :param apply_modifiers: bool - True if we want to apply the modifiers right after adding them to the object.
+ - True if we want to apply the modifier to a list of modifiers, after some operation.
+ This affects operations of type ModifierSpec and DeformModifierSpec.
+ :param do_compare: bool - True if we want to compare the test and expected objects, False otherwise.
+ :param threshold : exponent: To allow variations and accept difference to a certain degree.
+
"""
if operations_stack is None:
operations_stack = []
for operation in operations_stack:
- if not (isinstance(operation, ModifierSpec) or isinstance(operation, OperatorSpec)):
- raise ValueError("Expected operation of type {} or {}. Got {}".
- format(type(ModifierSpec), type(OperatorSpec),
+ if not (isinstance(operation, ModifierSpec) or isinstance(operation, OperatorSpecEditMode)
+ or isinstance(operation, OperatorSpecObjectMode) or isinstance(operation, DeformModifierSpec)
+ or isinstance(operation, ParticleSystemSpec)):
+ raise ValueError("Expected operation of type {} or {} or {} or {}. Got {}".
+ format(type(ModifierSpec), type(OperatorSpecEditMode),
+ type(DeformModifierSpec), type(ParticleSystemSpec),
type(operation)))
self.operations_stack = operations_stack
self.apply_modifier = apply_modifiers
+ self.do_compare = do_compare
self.threshold = threshold
+ self.test_name = test_name
self.verbose = os.environ.get("BLENDER_VERBOSE") is not None
self.update = os.getenv('BLENDER_TEST_UPDATE') is not None
@@ -187,22 +239,6 @@ class MeshTest:
objects = bpy.data.objects
self.expected_object = objects[expected_object_name]
- def add_modifier(self, modifier_spec: ModifierSpec):
- """
- Add a modifier to the operations stack.
- :param modifier_spec: modifier to add to the operations stack
- """
- self.operations_stack.append(modifier_spec)
- if self.verbose:
- print("Added modififier {}".format(modifier_spec))
-
- def add_operator(self, operator_spec: OperatorSpec):
- """
- Adds an operator to the operations stack.
- :param operator_spec: OperatorSpec - operator to add to the operations stack.
- """
- self.operations_stack.append(operator_spec)
-
def _on_failed_test(self, compare_result, validation_success, evaluated_test_object):
if self.update and validation_success:
if self.verbose:
@@ -239,83 +275,164 @@ class MeshTest:
"""
return self._test_updated
- def _apply_modifier(self, test_object, modifier_spec: ModifierSpec):
+ def _set_parameters_impl(self, modifier, modifier_parameters, nested_settings_path, modifier_name):
"""
- Add modifier to object and apply (if modifier_spec.apply_modifier is True)
+ Doing a depth first traversal of the modifier parameters and setting their values.
+ :param: modifier: Of type modifier, its altered to become a setting in recursion.
+ :param: modifier_parameters : dict or sequence, a simple/nested dictionary of modifier parameters.
+ :param: nested_settings_path : list(stack): helps in tracing path to each node.
+ """
+ if not isinstance(modifier_parameters, dict):
+ param_setting = None
+ for i, setting in enumerate(nested_settings_path):
+
+ # We want to set the attribute only when we have reached the last setting.
+ # Applying of intermediate settings is meaningless.
+ if i == len(nested_settings_path) - 1:
+ setattr(modifier, setting, modifier_parameters)
+
+ elif hasattr(modifier, setting):
+ param_setting = getattr(modifier, setting)
+ # getattr doesn't accept canvas_surfaces["Surface"], but we need to pass it to setattr.
+ if setting == "canvas_surfaces":
+ modifier = param_setting.active
+ else:
+ modifier = param_setting
+ else:
+ # Clean up first
+ bpy.ops.object.delete()
+ raise Exception("Modifier '{}' has no parameter named '{}'".
+ format(modifier_name, setting))
+
+ # It pops the current node before moving on to its sibling.
+ nested_settings_path.pop()
+ return
+
+ for key in modifier_parameters:
+ nested_settings_path.append(key)
+ self._set_parameters_impl(modifier, modifier_parameters[key], nested_settings_path, modifier_name)
+
+ if nested_settings_path:
+ nested_settings_path.pop()
+
+ def set_parameters(self, modifier, modifier_parameters):
+ """
+ Wrapper for _set_parameters_util
+ """
+ settings = []
+ modifier_name = modifier.name
+ self._set_parameters_impl(modifier, modifier_parameters, settings, modifier_name)
+
+ def _add_modifier(self, test_object, modifier_spec: ModifierSpec):
+ """
+ Add modifier to object.
:param test_object: bpy.types.Object - Blender object to apply modifier on.
:param modifier_spec: ModifierSpec - ModifierSpec object with parameters
"""
+ bakers_list = ['CLOTH', 'SOFT_BODY', 'DYNAMIC_PAINT', 'FLUID']
+ scene = bpy.context.scene
+ scene.frame_set(1)
modifier = test_object.modifiers.new(modifier_spec.modifier_name,
modifier_spec.modifier_type)
+
+ if modifier is None:
+ raise Exception("This modifier type is already added on the Test Object, please remove it and try again.")
+
if self.verbose:
print("Created modifier '{}' of type '{}'.".
format(modifier_spec.modifier_name, modifier_spec.modifier_type))
- for param_name in modifier_spec.modifier_parameters:
- try:
- setattr(modifier, param_name, modifier_spec.modifier_parameters[param_name])
- if self.verbose:
- print("\t set parameter '{}' with value '{}'".
- format(param_name, modifier_spec.modifier_parameters[param_name]))
- except AttributeError:
- # Clean up first
- bpy.ops.object.delete()
- raise AttributeError("Modifier '{}' has no parameter named '{}'".
- format(modifier_spec.modifier_type, param_name))
+ # Special case for Dynamic Paint, need to toggle Canvas on.
+ if modifier.type == "DYNAMIC_PAINT":
+ bpy.ops.dpaint.type_toggle(type='CANVAS')
- if self.apply_modifier:
- bpy.ops.object.modifier_apply(modifier=modifier_spec.modifier_name)
+ self.set_parameters(modifier, modifier_spec.modifier_parameters)
+
+ if modifier.type in bakers_list:
+ self._bake_current_simulation(test_object, modifier.name, modifier_spec.frame_end)
+
+ scene.frame_set(modifier_spec.frame_end)
+
+ def _apply_modifier(self, test_object, modifier_name):
+ # Modifier automatically gets applied when converting from Curve to Mesh.
+ if test_object.type == 'CURVE':
+ bpy.ops.object.convert(target='MESH')
+ elif test_object.type == 'MESH':
+ bpy.ops.object.modifier_apply(modifier=modifier_name)
+ else:
+ raise Exception("This object type is not yet supported!")
+
+ def _bake_current_simulation(self, test_object, test_modifier_name, frame_end):
+ """
+ FLUID: Bakes the simulation
+ SOFT BODY, CLOTH, DYNAMIC PAINT: Overrides the point_cache context and then bakes.
+ """
- def _bake_current_simulation(self, obj, test_mod_type, test_mod_name, frame_end):
for scene in bpy.data.scenes:
- for modifier in obj.modifiers:
- if modifier.type == test_mod_type:
- obj.modifiers[test_mod_name].point_cache.frame_end = frame_end
- override = {'scene': scene, 'active_object': obj, 'point_cache': modifier.point_cache}
+ for modifier in test_object.modifiers:
+ if modifier.type == 'FLUID':
+ bpy.ops.fluid.bake_all()
+ break
+
+ elif modifier.type == 'CLOTH' or modifier.type == 'SOFT_BODY':
+ test_object.modifiers[test_modifier_name].point_cache.frame_end = frame_end
+ override_setting = modifier.point_cache
+ override = {'scene': scene, 'active_object': test_object, 'point_cache': override_setting}
+ bpy.ops.ptcache.bake(override, bake=True)
+ break
+
+ elif modifier.type == 'DYNAMIC_PAINT':
+ dynamic_paint_setting = modifier.canvas_settings.canvas_surfaces.active
+ override_setting = dynamic_paint_setting.point_cache
+ override = {'scene': scene, 'active_object': test_object, 'point_cache': override_setting}
bpy.ops.ptcache.bake(override, bake=True)
break
- def _apply_physics_settings(self, test_object, physics_spec: PhysicsSpec):
+ def _apply_particle_system(self, test_object, particle_sys_spec: ParticleSystemSpec):
"""
- Apply Physics settings to test objects.
+ Applies Particle System settings to test objects
"""
- scene = bpy.context.scene
- scene.frame_set(1)
- modifier = test_object.modifiers.new(physics_spec.modifier_name,
- physics_spec.modifier_type)
- physics_setting = modifier.settings
+ bpy.context.scene.frame_set(1)
+ bpy.ops.object.select_all(action='DESELECT')
+
+ test_object.modifiers.new(particle_sys_spec.modifier_name, particle_sys_spec.modifier_type)
+
+ settings_name = test_object.particle_systems.active.settings.name
+ particle_setting = bpy.data.particles[settings_name]
if self.verbose:
print("Created modifier '{}' of type '{}'.".
- format(physics_spec.modifier_name, physics_spec.modifier_type))
+ format(particle_sys_spec.modifier_name, particle_sys_spec.modifier_type))
- for param_name in physics_spec.modifier_parameters:
+ for param_name in particle_sys_spec.modifier_parameters:
try:
- setattr(physics_setting, param_name, physics_spec.modifier_parameters[param_name])
+ if param_name == "seed":
+ system_setting = test_object.particle_systems[particle_sys_spec.modifier_name]
+ setattr(system_setting, param_name, particle_sys_spec.modifier_parameters[param_name])
+ else:
+ setattr(particle_setting, param_name, particle_sys_spec.modifier_parameters[param_name])
+
if self.verbose:
print("\t set parameter '{}' with value '{}'".
- format(param_name, physics_spec.modifier_parameters[param_name]))
+ format(param_name, particle_sys_spec.modifier_parameters[param_name]))
except AttributeError:
# Clean up first
bpy.ops.object.delete()
raise AttributeError("Modifier '{}' has no parameter named '{}'".
- format(physics_spec.modifier_type, param_name))
-
- scene.frame_set(physics_spec.frame_end + 1)
+ format(particle_sys_spec.modifier_type, param_name))
- self._bake_current_simulation(
- test_object,
- physics_spec.modifier_type,
- physics_spec.modifier_name,
- physics_spec.frame_end,
- )
+ bpy.context.scene.frame_set(particle_sys_spec.frame_end)
+ test_object.select_set(True)
+ bpy.ops.object.duplicates_make_real()
+ test_object.select_set(True)
+ bpy.ops.object.join()
if self.apply_modifier:
- bpy.ops.object.modifier_apply(modifier=physics_spec.modifier_name)
+ self._apply_modifier(test_object, particle_sys_spec.modifier_name)
- def _apply_operator(self, test_object, operator: OperatorSpec):
+ 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: OperatorSpec - OperatorSpec object with parameters.
+ :param operator: OperatorSpecEditMode - OperatorSpecEditMode object with parameters.
"""
mesh = test_object.data
bpy.ops.object.mode_set(mode='EDIT')
@@ -340,15 +457,64 @@ class MeshTest:
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_mode(type=operator.select_mode)
mesh_operator = getattr(bpy.ops.mesh, operator.operator_name)
- if not mesh_operator:
- raise AttributeError("No mesh operator {}".format(operator.operator_name))
- retval = mesh_operator(**operator.operator_parameters)
+
+ try:
+ retval = mesh_operator(**operator.operator_parameters)
+ except AttributeError:
+ raise AttributeError("bpy.ops.mesh has no attribute {}".format(operator.operator_name))
+ except TypeError as ex:
+ raise TypeError("Incorrect operator parameters {!r} raised {!r}".format(operator.operator_parameters, ex))
+
+ if retval != {'FINISHED'}:
+ raise RuntimeError("Unexpected operator return value: {}".format(retval))
+ if self.verbose:
+ print("Applied {}".format(operator))
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ def _apply_operator_object_mode(self, operator: OperatorSpecObjectMode):
+ """
+ Applies the object operator.
+ """
+ bpy.ops.object.mode_set(mode='OBJECT')
+ object_operator = getattr(bpy.ops.object, operator.operator_name)
+
+ try:
+ retval = object_operator(**operator.operator_parameters)
+ except AttributeError:
+ raise AttributeError("bpy.ops.mesh has no attribute {}".format(operator.operator_name))
+ except TypeError as ex:
+ raise TypeError("Incorrect operator parameters {!r} raised {!r}".format(operator.operator_parameters, ex))
+
if retval != {'FINISHED'}:
raise RuntimeError("Unexpected operator return value: {}".format(retval))
if self.verbose:
print("Applied operator {}".format(operator))
+ def _apply_deform_modifier(self, test_object, operation: list):
+ """
+ param: operation: list: List of modifiers or combination of modifier and object operator.
+ """
+
+ scene = bpy.context.scene
+ scene.frame_set(1)
bpy.ops.object.mode_set(mode='OBJECT')
+ modifier_operations_list = operation.modifier_list
+ modifier_names = []
+ object_operations = operation.object_operator_spec
+ for modifier_operations in modifier_operations_list:
+ if isinstance(modifier_operations, ModifierSpec):
+ self._add_modifier(test_object, modifier_operations)
+ modifier_names.append(modifier_operations.modifier_name)
+
+ if isinstance(object_operations, OperatorSpecObjectMode):
+ self._apply_operator_object_mode(object_operations)
+
+ scene.frame_set(operation.frame_number)
+
+ if self.apply_modifier:
+ for mod_name in modifier_names:
+ self._apply_modifier(test_object, mod_name)
def run_test(self):
"""
@@ -369,24 +535,40 @@ class MeshTest:
evaluated_test_object = bpy.context.active_object
evaluated_test_object.name = "evaluated_object"
if self.verbose:
+ print()
print(evaluated_test_object.name, "is set to active")
# Add modifiers and operators.
for operation in self.operations_stack:
if isinstance(operation, ModifierSpec):
- self._apply_modifier(evaluated_test_object, operation)
+ self._add_modifier(evaluated_test_object, operation)
+ if self.apply_modifier:
+ self._apply_modifier(evaluated_test_object, operation.modifier_name)
+
+ elif isinstance(operation, OperatorSpecEditMode):
+ self._apply_operator_edit_mode(evaluated_test_object, operation)
+
+ elif isinstance(operation, OperatorSpecObjectMode):
+ self._apply_operator_object_mode(operation)
- elif isinstance(operation, OperatorSpec):
- self._apply_operator(evaluated_test_object, operation)
+ elif isinstance(operation, DeformModifierSpec):
+ self._apply_deform_modifier(evaluated_test_object, operation)
+
+ elif isinstance(operation, ParticleSystemSpec):
+ self._apply_particle_system(evaluated_test_object, operation)
- elif isinstance(operation, PhysicsSpec):
- self._apply_physics_settings(evaluated_test_object, operation)
else:
- raise ValueError("Expected operation of type {} or {} or {}. Got {}".
- format(type(ModifierSpec), type(OperatorSpec), type(PhysicsSpec),
- type(operation)))
+ raise ValueError("Expected operation of type {} or {} or {} or {}. Got {}".
+ format(type(ModifierSpec), type(OperatorSpecEditMode),
+ type(OperatorSpecObjectMode), type(ParticleSystemSpec), type(operation)))
# Compare resulting mesh with expected one.
+ # Compare only when self.do_compare is set to True, it is set to False for run-test and returns.
+ if not self.do_compare:
+ print("Meshes/objects are not compared, compare evaluated and expected object in Blender for "
+ "visualization only.")
+ return False
+
if self.verbose:
print("Comparing expected mesh with resulting mesh...")
evaluated_test_mesh = evaluated_test_object.data
@@ -415,75 +597,80 @@ class MeshTest:
return self._on_failed_test(compare_result, validation_success, evaluated_test_object)
-class OperatorTest:
+class RunTest:
"""
- Helper class that stores and executes operator tests.
+ Helper class that stores and executes modifier tests.
Example usage:
+ >>> modifier_list = [
+ >>> ModifierSpec("firstSUBSURF", "SUBSURF", {"quality": 5}),
+ >>> ModifierSpec("firstSOLIDIFY", "SOLIDIFY", {"thickness_clamp": 0.9, "thickness": 1})
+ >>> ]
+ >>> operator_list = [
+ >>> OperatorSpecEditMode("delete_edgeloop", {}, "EDGE", MONKEY_LOOP_EDGE),
+ >>> ]
>>> tests = [
- >>> ['FACE', {0, 1, 2, 3, 4, 5}, 'Cubecube', 'Cubecube_result_1', 'intersect_boolean', {'operation': 'UNION'}],
- >>> ['FACE', {0, 1, 2, 3, 4, 5}, 'Cubecube', 'Cubecube_result_2', 'intersect_boolean', {'operation': 'INTERSECT'}],
+ >>> MeshTest("Test1", "testCube", "expectedCube", modifier_list),
+ >>> MeshTest("Test2", "testCube_2", "expectedCube_2", modifier_list),
+ >>> MeshTest("MonkeyDeleteEdge", "testMonkey","expectedMonkey", operator_list)
>>> ]
- >>> operator_test = OperatorTest(tests)
- >>> operator_test.run_all_tests()
+ >>> modifiers_test = RunTest(tests)
+ >>> modifiers_test.run_all_tests()
"""
- def __init__(self, operator_tests):
+ def __init__(self, tests, apply_modifiers=False, do_compare=False):
"""
- Constructs an operator test.
- :param operator_tests: list - list of operator test cases. Each element in the list must contain the following
+ Construct a modifier test.
+ :param tests: list - list of modifier or operator test cases. Each element in the list must contain the
+ following
in the correct order:
- 1) select_mode: str - mesh selection mode, must be either 'VERT', 'EDGE' or 'FACE'
- 2) selection: set - set of vertices/edges/faces indices to select, e.g. [0, 9, 10].
- 3) test_object_name: bpy.Types.Object - test object
- 4) expected_object_name: bpy.Types.Object - expected object
- 5) operator_name: str - name of mesh operator from bpy.ops.mesh, e.g. "bevel" or "fill"
- 6) operator_parameters: dict - {name : val} dictionary containing operator parameters.
- """
- self.operator_tests = operator_tests
+ 0) test_name: str - unique test name
+ 1) test_object_name: bpy.Types.Object - test object
+ 2) expected_object_name: bpy.Types.Object - expected object
+ 3) modifiers or operators: list - list of mesh_test.ModifierSpec objects or
+ mesh_test.OperatorSpecEditMode objects
+ """
+ self.tests = tests
+ self._ensure_unique_test_name_or_raise_error()
+ self.apply_modifiers = apply_modifiers
+ self.do_compare = do_compare
self.verbose = os.environ.get("BLENDER_VERBOSE") is not None
self._failed_tests_list = []
- def run_test(self, index: int):
+ def _ensure_unique_test_name_or_raise_error(self):
"""
- Run a single test from operator_tests list
- :param index: int - index of test
- :return: bool - True if test is successful. False otherwise.
+ Check if the test name is unique else raise an error.
"""
- case = self.operator_tests[index]
- if len(case) != 6:
- raise ValueError("Expected exactly 6 parameters for each test case, got {}".format(len(case)))
- select_mode = case[0]
- selection = case[1]
- test_object_name = case[2]
- expected_object_name = case[3]
- operator_name = case[4]
- operator_parameters = case[5]
-
- operator_spec = OperatorSpec(operator_name, operator_parameters, select_mode, selection)
+ all_test_names = []
+ for each_test in self.tests:
+ test_name = each_test.test_name
+ all_test_names.append(test_name)
- test = MeshTest(test_object_name, expected_object_name)
- test.add_operator(operator_spec)
-
- success = test.run_test()
- if test.is_test_updated():
- # Run the test again if the blend file has been updated.
- success = test.run_test()
- return success
+ seen_name = set()
+ for ele in all_test_names:
+ if ele in seen_name:
+ raise ValueError("{} is a duplicate, write a new unique name.".format(ele))
+ else:
+ seen_name.add(ele)
def run_all_tests(self):
- for index, _ in enumerate(self.operator_tests):
+ """
+ Run all tests in self.tests list. Raises an exception if one the tests fails.
+ """
+ for test_number, each_test in enumerate(self.tests):
+ test_name = each_test.test_name
if self.verbose:
print()
- print("Running test {}...".format(index))
- success = self.run_test(index)
+ print("Running test {}...".format(test_number))
+ print("Test name {}\n".format(test_name))
+ success = self.run_test(test_name)
if not success:
- self._failed_tests_list.append(index)
+ self._failed_tests_list.append(test_name)
if len(self._failed_tests_list) != 0:
- print("Following tests failed: {}".format(self._failed_tests_list))
+ print("\nFollowing tests failed: {}".format(self._failed_tests_list))
blender_path = bpy.app.binary_path
blend_path = bpy.data.filepath
@@ -493,63 +680,31 @@ class OperatorTest:
print("Run following command to open Blender and run the failing test:")
print("{} {} --python {} -- {} {}"
- .format(blender_path, blend_path, python_path, "--run-test", "<test_index>"))
+ .format(blender_path, blend_path, python_path, "--run-test", "<test_name>"))
raise Exception("Tests {} failed".format(self._failed_tests_list))
-
-class ModifierTest:
- """
- Helper class that stores and executes modifier tests.
-
- Example usage:
-
- >>> modifier_list = [
- >>> ModifierSpec("firstSUBSURF", "SUBSURF", {"quality": 5}),
- >>> ModifierSpec("firstSOLIDIFY", "SOLIDIFY", {"thickness_clamp": 0.9, "thickness": 1})
- >>> ]
- >>> tests = [
- >>> ["testCube", "expectedCube", modifier_list],
- >>> ["testCube_2", "expectedCube_2", modifier_list]
- >>> ]
- >>> modifiers_test = ModifierTest(tests)
- >>> modifiers_test.run_all_tests()
- """
-
- def __init__(self, modifier_tests: list, apply_modifiers=False, threshold=None):
+ def run_test(self, test_name: str):
"""
- Construct a modifier test.
- :param modifier_tests: list - list of modifier test cases. Each element in the list must contain the following
- in the correct order:
- 1) test_object_name: bpy.Types.Object - test object
- 2) expected_object_name: bpy.Types.Object - expected object
- 3) modifiers: list - list of mesh_test.ModifierSpec objects.
- """
- self.modifier_tests = modifier_tests
- self.apply_modifiers = apply_modifiers
- self.threshold = threshold
- self.verbose = os.environ.get("BLENDER_VERBOSE") is not None
- self._failed_tests_list = []
-
- def run_test(self, index: int):
- """
- Run a single test from self.modifier_tests list
- :param index: int - index of test
+ Run a single test from self.tests list
+ :param test_name: int - name of test
:return: bool - True if test passed, False otherwise.
"""
- case = self.modifier_tests[index]
- if len(case) != 3:
- raise ValueError("Expected exactly 3 parameters for each test case, got {}".format(len(case)))
- test_object_name = case[0]
- expected_object_name = case[1]
- spec_list = case[2]
+ case = None
+ for index, each_test in enumerate(self.tests):
+ if test_name == each_test.test_name:
+ case = self.tests[index]
+ break
+
+ if case is None:
+ raise Exception('No test called {} found!'.format(test_name))
- test = MeshTest(test_object_name, expected_object_name, threshold=self.threshold)
+ test = case
if self.apply_modifiers:
test.apply_modifier = True
- for modifier_spec in spec_list:
- test.add_modifier(modifier_spec)
+ if self.do_compare:
+ test.do_compare = True
success = test.run_test()
if test.is_test_updated():
@@ -557,31 +712,3 @@ class ModifierTest:
success = test.run_test()
return success
-
- def run_all_tests(self):
- """
- Run all tests in self.modifiers_tests list. Raises an exception if one the tests fails.
- """
- for index, _ in enumerate(self.modifier_tests):
- if self.verbose:
- print()
- print("Running test {}...\n".format(index))
- success = self.run_test(index)
-
- if not success:
- self._failed_tests_list.append(index)
-
- if len(self._failed_tests_list) != 0:
- print("Following tests failed: {}".format(self._failed_tests_list))
-
- blender_path = bpy.app.binary_path
- blend_path = bpy.data.filepath
- frame = inspect.stack()[1]
- module = inspect.getmodule(frame[0])
- python_path = module.__file__
-
- print("Run following command to open Blender and run the failing test:")
- print("{} {} --python {} -- {} {}"
- .format(blender_path, blend_path, python_path, "--run-test", "<test_index>"))
-
- raise Exception("Tests {} failed".format(self._failed_tests_list))
diff --git a/tests/python/operators.py b/tests/python/operators.py
index 901820c7b2d..93cdfebab7b 100644
--- a/tests/python/operators.py
+++ b/tests/python/operators.py
@@ -26,7 +26,7 @@ from random import shuffle, seed
seed(0)
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
-from modules.mesh_test import OperatorTest, OperatorSpec
+from modules.mesh_test import MeshTest, OperatorSpecEditMode, RunTest
# Central vertical loop of Suzanne
MONKEY_LOOP_VERT = {68, 69, 71, 73, 74, 75, 76, 77, 90, 129, 136, 175, 188, 189, 198, 207,
@@ -39,126 +39,181 @@ def main():
tests = [
#### 0
# bisect
- ['FACE', {0, 1, 2, 3, 4, 5}, "testCubeBisect", "expectedCubeBisect", "bisect",
- {"plane_co": (0, 0, 0), "plane_no": (0, 1, 1), "clear_inner": True, "use_fill": True}],
+ MeshTest("CubeBisect", "testCubeBisect", "expectedCubeBisect",
+ [OperatorSpecEditMode("bisect",
+ {"plane_co": (0, 0, 0), "plane_no": (0, 1, 1), "clear_inner": True,
+ "use_fill": True}, 'FACE', {0, 1, 2, 3, 4, 5}, )]),
# blend from shape
- ['FACE', {0, 1, 2, 3, 4, 5}, "testCubeBlendFromShape", "expectedCubeBlendFromShape", "blend_from_shape",
- {"shape": "Key 1"}],
+ MeshTest("CubeBlendFromShape", "testCubeBlendFromShape", "expectedCubeBlendFromShape",
+ [OperatorSpecEditMode("blend_from_shape", {"shape": "Key 1"}, 'FACE', {0, 1, 2, 3, 4, 5})]),
# bridge edge loops
- ["FACE", {0, 1}, "testCubeBrigeEdgeLoop", "expectedCubeBridgeEdgeLoop", "bridge_edge_loops", {}],
+ MeshTest("CubeBridgeEdgeLoop", "testCubeBrigeEdgeLoop", "expectedCubeBridgeEdgeLoop",
+ [OperatorSpecEditMode("bridge_edge_loops", {}, "FACE", {0, 1})]),
# decimate
- ["FACE", {i for i in range(500)}, "testMonkeyDecimate", "expectedMonkeyDecimate", "decimate", {"ratio": 0.1}],
+ MeshTest("MonkeyDecimate", "testMonkeyDecimate", "expectedMonkeyDecimate",
+ [OperatorSpecEditMode("decimate",
+ {"ratio": 0.1}, "FACE", {i for i in range(500)})]),
### 4
# delete
- ["VERT", {3}, "testCubeDeleteVertices", "expectedCubeDeleteVertices", "delete", {}],
- ["FACE", {0}, "testCubeDeleteFaces", "expectedCubeDeleteFaces", "delete", {}],
- ["EDGE", {0, 1, 2, 3}, "testCubeDeleteEdges", "expectedCubeDeleteEdges", "delete", {}],
+ MeshTest("CubeDeleteVertices", "testCubeDeleteVertices", "expectedCubeDeleteVertices",
+ [OperatorSpecEditMode("delete", {}, "VERT", {3})]),
+ MeshTest("CubeDeleteFaces", "testCubeDeleteFaces", "expectedCubeDeleteFaces",
+ [OperatorSpecEditMode("delete", {}, "FACE", {0})]),
+ MeshTest("CubeDeleteEdges", "testCubeDeleteEdges", "expectedCubeDeleteEdges",
+ [OperatorSpecEditMode("delete", {}, "EDGE", {0, 1, 2, 3})]),
# delete edge loop
- ["VERT", MONKEY_LOOP_VERT, "testMokneyDeleteEdgeLoopVertices", "expectedMonkeyDeleteEdgeLoopVertices",
- "delete_edgeloop", {}],
- ["EDGE", MONKEY_LOOP_EDGE, "testMokneyDeleteEdgeLoopEdges", "expectedMonkeyDeleteEdgeLoopEdges",
- "delete_edgeloop", {}],
+ MeshTest("MonkeyDeleteEdgeLoopVertices", "testMokneyDeleteEdgeLoopVertices",
+ "expectedMonkeyDeleteEdgeLoopVertices",
+ [OperatorSpecEditMode("delete_edgeloop", {}, "VERT", MONKEY_LOOP_VERT)]),
+
+ MeshTest("MonkeyDeleteEdgeLoopEdges", "testMokneyDeleteEdgeLoopEdges",
+ "expectedMonkeyDeleteEdgeLoopEdges",
+ [OperatorSpecEditMode("delete_edgeloop", {}, "EDGE", MONKEY_LOOP_EDGE)]),
### 9
# delete loose
- ["VERT", {i for i in range(12)}, "testCubeDeleteLooseVertices", "expectedCubeDeleteLooseVertices",
- "delete_loose", {"use_verts": True, "use_edges": False, "use_faces": False}],
- ["EDGE", {i for i in range(14)}, "testCubeDeleteLooseEdges", "expectedCubeDeleteLooseEdges",
- "delete_loose", {"use_verts": False, "use_edges": True, "use_faces": False}],
- ["FACE", {i for i in range(7)}, "testCubeDeleteLooseFaces", "expectedCubeDeleteLooseFaces",
- "delete_loose", {"use_verts": False, "use_edges": False, "use_faces": True}],
+ MeshTest("CubeDeleteLooseVertices", "testCubeDeleteLooseVertices",
+ "expectedCubeDeleteLooseVertices",
+ [OperatorSpecEditMode("delete_loose", {"use_verts": True, "use_edges": False, "use_faces": False},
+ "VERT",
+ {i for i in range(12)})]),
+ MeshTest("CubeDeleteLooseEdges", "testCubeDeleteLooseEdges",
+ "expectedCubeDeleteLooseEdges",
+ [OperatorSpecEditMode("delete_loose", {"use_verts": False, "use_edges": True, "use_faces": False},
+ "EDGE",
+ {i for i in range(14)})]),
+ MeshTest("CubeDeleteLooseFaces", "testCubeDeleteLooseFaces",
+ "expectedCubeDeleteLooseFaces",
+ [OperatorSpecEditMode("delete_loose", {"use_verts": False, "use_edges": False, "use_faces": True},
+ "FACE",
+ {i for i in range(7)})]),
# dissolve degenerate
- ["VERT", {i for i in range(8)}, "testCubeDissolveDegenerate", "expectedCubeDissolveDegenerate",
- "dissolve_degenerate", {}],
+ MeshTest("CubeDissolveDegenerate", "testCubeDissolveDegenerate",
+ "expectedCubeDissolveDegenerate",
+ [OperatorSpecEditMode("dissolve_degenerate", {}, "VERT", {i for i in range(8)})]),
### 13
# dissolve edges
- ["EDGE", {0, 5, 6, 9}, "testCylinderDissolveEdges", "expectedCylinderDissolveEdges",
- "dissolve_edges", {}],
+ MeshTest("CylinderDissolveEdges", "testCylinderDissolveEdges", "expectedCylinderDissolveEdges",
+ [OperatorSpecEditMode("dissolve_edges", {}, "EDGE", {0, 5, 6, 9})]),
# dissolve faces
- ["VERT", {5, 34, 47, 49, 83, 91, 95}, "testCubeDissolveFaces", "expectedCubeDissolveFaces", "dissolve_faces",
- {}],
+ MeshTest("CubeDissolveFaces", "testCubeDissolveFaces", "expectedCubeDissolveFaces",
+ [OperatorSpecEditMode("dissolve_faces", {}, "VERT", {5, 34, 47, 49, 83, 91, 95})]),
### 15
# dissolve verts
- ["VERT", {16, 20, 22, 23, 25}, "testCubeDissolveVerts", "expectedCubeDissolveVerts", "dissolve_verts", {}],
+ MeshTest("CubeDissolveVerts", "testCubeDissolveVerts", "expectedCubeDissolveVerts",
+ [OperatorSpecEditMode("dissolve_verts", {}, "VERT", {16, 20, 22, 23, 25})]),
# duplicate
- ["VERT", {i for i in range(33)} - {23}, "testConeDuplicateVertices", "expectedConeDuplicateVertices",
- "duplicate", {}],
- ["VERT", {23}, "testConeDuplicateOneVertex", "expectedConeDuplicateOneVertex", "duplicate", {}],
- ["FACE", {6, 9}, "testConeDuplicateFaces", "expectedConeDuplicateFaces", "duplicate", {}],
- ["EDGE", {i for i in range(64)}, "testConeDuplicateEdges", "expectedConeDuplicateEdges", "duplicate", {}],
+ MeshTest("ConeDuplicateVertices", "testConeDuplicateVertices",
+ "expectedConeDuplicateVertices",
+ [OperatorSpecEditMode("duplicate", {}, "VERT", {i for i in range(33)} - {23})]),
+
+ MeshTest("ConeDuplicateOneVertex", "testConeDuplicateOneVertex", "expectedConeDuplicateOneVertex",
+ [OperatorSpecEditMode("duplicate", {}, "VERT", {23})]),
+ MeshTest("ConeDuplicateFaces", "testConeDuplicateFaces", "expectedConeDuplicateFaces",
+ [OperatorSpecEditMode("duplicate", {}, "FACE", {6, 9})]),
+ MeshTest("ConeDuplicateEdges", "testConeDuplicateEdges", "expectedConeDuplicateEdges",
+ [OperatorSpecEditMode("duplicate", {}, "EDGE", {i for i in range(64)})]),
### 20
# edge collapse
- ["EDGE", {1, 9, 4}, "testCylinderEdgeCollapse", "expectedCylinderEdgeCollapse", "edge_collapse", {}],
+ MeshTest("CylinderEdgeCollapse", "testCylinderEdgeCollapse", "expectedCylinderEdgeCollapse",
+ [OperatorSpecEditMode("edge_collapse", {}, "EDGE", {1, 9, 4})]),
# edge face add
- ["VERT", {1, 3, 4, 5, 7}, "testCubeEdgeFaceAddFace", "expectedCubeEdgeFaceAddFace", "edge_face_add", {}],
- ["VERT", {4, 5}, "testCubeEdgeFaceAddEdge", "expectedCubeEdgeFaceAddEdge", "edge_face_add", {}],
+ MeshTest("CubeEdgeFaceAddFace", "testCubeEdgeFaceAddFace", "expectedCubeEdgeFaceAddFace",
+ [OperatorSpecEditMode("edge_face_add", {}, "VERT", {1, 3, 4, 5, 7})]),
+ MeshTest("CubeEdgeFaceAddEdge", "testCubeEdgeFaceAddEdge", "expectedCubeEdgeFaceAddEdge",
+ [OperatorSpecEditMode("edge_face_add", {}, "VERT", {4, 5})]),
# edge rotate
- ["EDGE", {1}, "testCubeEdgeRotate", "expectedCubeEdgeRotate", "edge_rotate", {}],
+ MeshTest("CubeEdgeRotate", "testCubeEdgeRotate", "expectedCubeEdgeRotate",
+ [OperatorSpecEditMode("edge_rotate", {}, "EDGE", {1})]),
# edge split
- ["EDGE", {2, 5, 8, 11, 14, 17, 20, 23}, "testCubeEdgeSplit", "expectedCubeEdgeSplit", "edge_split", {}],
+ MeshTest("CubeEdgeSplit", "testCubeEdgeSplit", "expectedCubeEdgeSplit",
+ [OperatorSpecEditMode("edge_split", {}, "EDGE", {2, 5, 8, 11, 14, 17, 20, 23})]),
### 25
# face make planar
- ["FACE", {i for i in range(500)}, "testMonkeyFaceMakePlanar", "expectedMonkeyFaceMakePlanar",
- "face_make_planar", {}],
+ MeshTest("MonkeyFaceMakePlanar", "testMonkeyFaceMakePlanar",
+ "expectedMonkeyFaceMakePlanar",
+ [OperatorSpecEditMode("face_make_planar", {}, "FACE", {i for i in range(500)})]),
# face split by edges
- ["VERT", {i for i in range(6)}, "testPlaneFaceSplitByEdges", "expectedPlaneFaceSplitByEdges",
- "face_split_by_edges", {}],
+ MeshTest("PlaneFaceSplitByEdges", "testPlaneFaceSplitByEdges",
+ "expectedPlaneFaceSplitByEdges",
+ [OperatorSpecEditMode("face_split_by_edges", {}, "VERT", {i for i in range(6)})]),
# fill
- ["EDGE", {20, 21, 22, 23, 24, 45, 46, 47, 48, 49}, "testIcosphereFill", "expectedIcosphereFill",
- "fill", {}],
- ["EDGE", {20, 21, 22, 23, 24, 45, 46, 47, 48, 49}, "testIcosphereFillUseBeautyFalse",
- "expectedIcosphereFillUseBeautyFalse", "fill", {"use_beauty": False}],
+ MeshTest("IcosphereFill", "testIcosphereFill", "expectedIcosphereFill",
+ [OperatorSpecEditMode("fill", {}, "EDGE", {20, 21, 22, 23, 24, 45, 46, 47, 48, 49})]),
+ MeshTest("IcosphereFillUseBeautyFalse",
+ "testIcosphereFillUseBeautyFalse", "expectedIcosphereFillUseBeautyFalse",
+ [OperatorSpecEditMode("fill", {"use_beauty": False}, "EDGE",
+ {20, 21, 22, 23, 24, 45, 46, 47, 48, 49})]),
# fill grid
- ["EDGE", {1, 2, 3, 4, 5, 7, 9, 10, 11, 12, 13, 15}, "testPlaneFillGrid", "expectedPlaneFillGrid",
- "fill_grid", {}],
- ["EDGE", {1, 2, 3, 4, 5, 7, 9, 10, 11, 12, 13, 15}, "testPlaneFillGridSimpleBlending",
- "expectedPlaneFillGridSimpleBlending", "fill_grid", {"use_interp_simple": True}],
+ MeshTest("PlaneFillGrid", "testPlaneFillGrid",
+ "expectedPlaneFillGrid",
+ [OperatorSpecEditMode("fill_grid", {}, "EDGE", {1, 2, 3, 4, 5, 7, 9, 10, 11, 12, 13, 15})]),
+
+ MeshTest("PlaneFillGridSimpleBlending",
+ "testPlaneFillGridSimpleBlending",
+ "expectedPlaneFillGridSimpleBlending",
+ [OperatorSpecEditMode("fill_grid", {"use_interp_simple": True}, "EDGE",
+ {1, 2, 3, 4, 5, 7, 9, 10, 11, 12, 13, 15})]),
### 31
# fill holes
- ["VERT", {i for i in range(481)}, "testSphereFillHoles", "expectedSphereFillHoles", "fill_holes", {"sides": 9}],
+ MeshTest("SphereFillHoles", "testSphereFillHoles", "expectedSphereFillHoles",
+ [OperatorSpecEditMode("fill_holes", {"sides": 9}, "VERT", {i for i in range(481)})]),
# inset faces
- ["VERT", {5, 16, 17, 19, 20, 22, 23, 34, 47, 49, 50, 52, 59, 61, 62, 65, 83, 91, 95}, "testCubeInset",
- "expectedCubeInset", "inset", {"thickness": 0.2}],
- ["VERT", {5, 16, 17, 19, 20, 22, 23, 34, 47, 49, 50, 52, 59, 61, 62, 65, 83, 91, 95},
- "testCubeInsetEvenOffsetFalse", "expectedCubeInsetEvenOffsetFalse",
- "inset", {"thickness": 0.2, "use_even_offset": False}],
- ["VERT", {5, 16, 17, 19, 20, 22, 23, 34, 47, 49, 50, 52, 59, 61, 62, 65, 83, 91, 95}, "testCubeInsetDepth",
- "expectedCubeInsetDepth", "inset", {"thickness": 0.2, "depth": 0.2}],
- ["FACE", {35, 36, 37, 45, 46, 47, 55, 56, 57}, "testGridInsetRelativeOffset", "expectedGridInsetRelativeOffset",
- "inset", {"thickness": 0.4, "use_relative_offset": True}],
+ MeshTest("CubeInset",
+ "testCubeInset", "expectedCubeInset", [OperatorSpecEditMode("inset", {"thickness": 0.2}, "VERT",
+ {5, 16, 17, 19, 20, 22, 23, 34, 47, 49, 50,
+ 52,
+ 59, 61, 62, 65, 83, 91, 95})]),
+
+ MeshTest("CubeInsetEvenOffsetFalse",
+ "testCubeInsetEvenOffsetFalse", "expectedCubeInsetEvenOffsetFalse",
+ [OperatorSpecEditMode("inset", {"thickness": 0.2, "use_even_offset": False}, "VERT",
+ {5, 16, 17, 19, 20, 22, 23, 34, 47, 49, 50, 52, 59, 61, 62, 65, 83, 91, 95})]),
+ MeshTest("CubeInsetDepth",
+ "testCubeInsetDepth",
+ "expectedCubeInsetDepth", [OperatorSpecEditMode("inset", {"thickness": 0.2, "depth": 0.2}, "VERT",
+ {5, 16, 17, 19, 20, 22, 23, 34, 47, 49, 50, 52, 59, 61,
+ 62,
+ 65, 83, 91, 95})]),
+ MeshTest("GridInsetRelativeOffset", "testGridInsetRelativeOffset",
+ "expectedGridInsetRelativeOffset",
+ [OperatorSpecEditMode("inset", {"thickness": 0.4,
+ "use_relative_offset": True}, "FACE",
+ {35, 36, 37, 45, 46, 47, 55, 56, 57})]),
]
- operators_test = OperatorTest(tests)
+ operators_test = RunTest(tests)
command = list(sys.argv)
for i, cmd in enumerate(command):
if cmd == "--run-all-tests":
+ operators_test.do_compare = True
operators_test.run_all_tests()
break
elif cmd == "--run-test":
- operators_test.apply_modifiers = False
- index = int(command[i + 1])
- operators_test.run_test(index)
+ operators_test.do_compare = False
+ name = command[i + 1]
+ operators_test.run_test(name)
break
diff --git a/tests/python/physics_cloth.py b/tests/python/physics_cloth.py
index 5b9151ea089..b88b4d63f9d 100644
--- a/tests/python/physics_cloth.py
+++ b/tests/python/physics_cloth.py
@@ -24,26 +24,42 @@ import sys
import bpy
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
-from modules.mesh_test import ModifierTest, PhysicsSpec
+from modules.mesh_test import RunTest, ModifierSpec, MeshTest
def main():
test = [
- ["testCloth", "expectedCloth",
- [PhysicsSpec('Cloth', 'CLOTH', {'quality': 5}, 35)]],
+
+ MeshTest("ClothSimple", "testClothPlane", "expectedClothPlane",
+ [ModifierSpec('Cloth', 'CLOTH', {'settings': {'quality': 5}}, 15)], threshold=1e-3),
+
+ # Not reproducible
+ # MeshTest("ClothPressure", "testObjClothPressure", "expObjClothPressure",
+ # [ModifierSpec('Cloth2', 'CLOTH', {'settings': {'use_pressure': True,
+ # 'uniform_pressure_force': 1}}, 16)]),
+
+ # Not reproducible
+ # MeshTest("ClothSelfCollision", "testClothCollision", "expClothCollision",
+ # [ModifierSpec('Cloth', 'CLOTH', {'collision_settings': {'use_self_collision': True}}, 67)]),
+
+ MeshTest("ClothSpring", "testTorusClothSpring", "expTorusClothSpring",
+ [ModifierSpec('Cloth2', 'CLOTH', {'settings': {'use_internal_springs': True}}, 10)], threshold=1e-3),
+
]
- cloth_test = ModifierTest(test, threshold=1e-3)
+ cloth_test = RunTest(test)
command = list(sys.argv)
for i, cmd in enumerate(command):
if cmd == "--run-all-tests":
cloth_test.apply_modifiers = True
+ cloth_test.do_compare = True
cloth_test.run_all_tests()
break
elif cmd == "--run-test":
cloth_test.apply_modifiers = False
- index = int(command[i + 1])
- cloth_test.run_test(index)
+ cloth_test.do_compare = False
+ name = command[i + 1]
+ cloth_test.run_test(name)
break
diff --git a/tests/python/physics_dynamic_paint.py b/tests/python/physics_dynamic_paint.py
new file mode 100644
index 00000000000..b5d09c8cb3a
--- /dev/null
+++ b/tests/python/physics_dynamic_paint.py
@@ -0,0 +1,58 @@
+# ##### 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>
+
+import os
+import sys
+
+import bpy
+
+sys.path.append(os.path.dirname(os.path.realpath(__file__)))
+from modules.mesh_test import RunTest, ModifierSpec, MeshTest
+
+
+def main():
+ test = [
+
+ MeshTest("DynamicPaintSimple", "testObjDynamicPaintPlane", "expObjDynamicPaintPlane",
+ [ModifierSpec('dynamic_paint', 'DYNAMIC_PAINT',
+ {'ui_type': 'CANVAS',
+ 'canvas_settings': {'canvas_surfaces': {'surface_type': 'WAVE', 'frame_end': 15}}},
+ 15)]),
+
+ ]
+ dynamic_paint_test = RunTest(test)
+
+ command = list(sys.argv)
+ for i, cmd in enumerate(command):
+ if cmd == "--run-all-tests":
+ dynamic_paint_test.apply_modifiers = True
+ dynamic_paint_test.do_compare = True
+ dynamic_paint_test.run_all_tests()
+ break
+ elif cmd == "--run-test":
+ dynamic_paint_test.apply_modifiers = False
+ dynamic_paint_test.do_compare = False
+ name = command[i + 1]
+ dynamic_paint_test.run_test(name)
+ break
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tests/python/physics_ocean.py b/tests/python/physics_ocean.py
new file mode 100644
index 00000000000..40227d3d8d7
--- /dev/null
+++ b/tests/python/physics_ocean.py
@@ -0,0 +1,54 @@
+# ##### 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>
+
+import os
+import sys
+
+import bpy
+
+sys.path.append(os.path.dirname(os.path.realpath(__file__)))
+from modules.mesh_test import RunTest, ModifierSpec, MeshTest
+
+
+def main():
+ test = [
+ # World coordinates of test and expected object should be same.
+ MeshTest("PlaneOcean", "testObjPlaneOcean", "expObjPlaneOcean",
+ [ModifierSpec('Ocean', 'OCEAN', {})]),
+ ]
+ ocean_test = RunTest(test)
+
+ command = list(sys.argv)
+ for i, cmd in enumerate(command):
+ if cmd == "--run-all-tests":
+ ocean_test.apply_modifiers = True
+ ocean_test.do_compare = True
+ ocean_test.run_all_tests()
+ break
+ elif cmd == "--run-test":
+ ocean_test.apply_modifiers = False
+ ocean_test.do_compare = False
+ name = command[i + 1]
+ ocean_test.run_test(name)
+ break
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tests/python/physics_particle_instance.py b/tests/python/physics_particle_instance.py
new file mode 100644
index 00000000000..e12e357e4ce
--- /dev/null
+++ b/tests/python/physics_particle_instance.py
@@ -0,0 +1,56 @@
+# ##### 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>
+
+import os
+import sys
+
+import bpy
+
+sys.path.append(os.path.dirname(os.path.realpath(__file__)))
+from modules.mesh_test import RunTest, ModifierSpec, MeshTest
+
+
+def main():
+ test = [
+
+ MeshTest("ParticleInstanceSimple", "testParticleInstance", "expectedParticleInstance",
+ [ModifierSpec('ParticleInstance', 'PARTICLE_INSTANCE', {'object': bpy.data.objects['Cube']})],
+ threshold=1e-3),
+
+ ]
+ particle_instance_test = RunTest(test)
+
+ command = list(sys.argv)
+ for i, cmd in enumerate(command):
+ if cmd == "--run-all-tests":
+ particle_instance_test.apply_modifiers = True
+ particle_instance_test.do_compare = True
+ particle_instance_test.run_all_tests()
+ break
+ elif cmd == "--run-test":
+ particle_instance_test.apply_modifiers = False
+ particle_instance_test.do_compare = False
+ name = command[i + 1]
+ particle_instance_test.run_test(name)
+ break
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tests/python/physics_particle_system.py b/tests/python/physics_particle_system.py
new file mode 100644
index 00000000000..0adc5ab1c54
--- /dev/null
+++ b/tests/python/physics_particle_system.py
@@ -0,0 +1,55 @@
+# ##### 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>
+
+import os
+import sys
+
+import bpy
+
+sys.path.append(os.path.dirname(os.path.realpath(__file__)))
+from modules.mesh_test import RunTest, ParticleSystemSpec, MeshTest
+
+
+def main():
+ test = [
+ MeshTest("ParticleSystemTest", "testParticleSystem", "expParticleSystem",
+ [ParticleSystemSpec('Particles', 'PARTICLE_SYSTEM', {'render_type': "OBJECT",
+ 'instance_object': bpy.data.objects['Cube']}, 20)], threshold=1e-3),
+
+ ]
+ particle_test = RunTest(test)
+
+ command = list(sys.argv)
+ for i, cmd in enumerate(command):
+ if cmd == "--run-all-tests":
+ particle_test.apply_modifiers = True
+ particle_test.do_compare = True
+ particle_test.run_all_tests()
+ break
+ elif cmd == "--run-test":
+ particle_test.apply_modifiers = False
+ particle_test.do_compare = False
+ name = command[i + 1]
+ particle_test.run_test(name)
+ break
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tests/python/physics_softbody.py b/tests/python/physics_softbody.py
index 8d431be742c..985b3a29bb4 100644
--- a/tests/python/physics_softbody.py
+++ b/tests/python/physics_softbody.py
@@ -24,26 +24,31 @@ import sys
import bpy
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
-from modules.mesh_test import ModifierTest, PhysicsSpec
+from modules.mesh_test import RunTest, ModifierSpec, MeshTest
def main():
test = [
- ["testSoftBody", "expectedSoftBody",
- [PhysicsSpec('Softbody', 'SOFT_BODY', {'use_goal': False, 'bend': 8, 'pull': 0.8, 'push': 0.8}, 45)]],
+
+ MeshTest("SoftBodySimple", "testSoftBody", "expectedSoftBody",
+ [ModifierSpec('Softbody', 'SOFT_BODY',
+ {'settings': {'use_goal': False, 'bend': 8, 'pull': 0.8, 'push': 0.8}},
+ 45)]),
]
- softBody_test = ModifierTest(test)
+ soft_body_test = RunTest(test)
command = list(sys.argv)
for i, cmd in enumerate(command):
if cmd == "--run-all-tests":
- softBody_test.apply_modifiers = True
- softBody_test.run_all_tests()
+ soft_body_test.apply_modifiers = True
+ soft_body_test.do_compare = True
+ soft_body_test.run_all_tests()
break
elif cmd == "--run-test":
- softBody_test.apply_modifiers = False
- index = int(command[i + 1])
- softBody_test.run_test(index)
+ soft_body_test.apply_modifiers = False
+ soft_body_test.do_compare = False
+ name = command[i + 1]
+ soft_body_test.run_test(name)
break