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
path: root/tests
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2021-07-29 03:52:11 +0300
committerCampbell Barton <ideasman42@gmail.com>2021-07-29 04:09:21 +0300
commitbc0a7d3fae5cfbe76ff84b76cb0ce48fe46adea5 (patch)
tree32a3a121b4c87b20daacfd95f2e00a1102a3a3de /tests
parent2453dc1b0ecad21a84b45e8c900a16cc42fa12f1 (diff)
PyAPI: support multi-dimensional arrays for bpy.props vector types
- Multi-dimensional boolean, int and float vector types are supported. - A sequence of int's for the "size" is used to declare dimensions. - Nested sequences are required for default arguments. Now it's possible to define matrix properties, for e.g: bpy.props.FloatVectorProperty(size=(4, 4), subtype='MATRIX')
Diffstat (limited to 'tests')
-rw-r--r--tests/python/bl_pyapi_prop_array.py120
1 files changed, 118 insertions, 2 deletions
diff --git a/tests/python/bl_pyapi_prop_array.py b/tests/python/bl_pyapi_prop_array.py
index ac1082c009e..2f38b67d7a1 100644
--- a/tests/python/bl_pyapi_prop_array.py
+++ b/tests/python/bl_pyapi_prop_array.py
@@ -2,18 +2,61 @@
# ./blender.bin --background -noaudio --python tests/python/bl_pyapi_prop_array.py -- --verbose
import bpy
+from bpy.props import (
+ BoolVectorProperty,
+ FloatVectorProperty,
+ IntVectorProperty,
+)
import unittest
import numpy as np
+id_inst = bpy.context.scene
+id_type = bpy.types.Scene
+
+
+# -----------------------------------------------------------------------------
+# Utility Functions
+
+def seq_items_xform(data, xform_fn):
+ """
+ Recursively expand items using `xform_fn`.
+ """
+ if hasattr(data, "__len__"):
+ return tuple(seq_items_xform(v, xform_fn) for v in data)
+ return xform_fn(data)
+
+
+def seq_items_as_tuple(data):
+ """
+ Return nested sequences as a nested tuple.
+ Useful when comparing different kinds of nested sequences.
+ """
+ return seq_items_xform(data, lambda v: v)
+
+
+def seq_items_as_dims(data):
+ """
+ Nested length calculation, extracting the length from each sequence.
+ Where a 4x4 matrix returns ``(4, 4)`` for example.
+ """
+ return ((len(data),) + seq_items_as_dims(data[0])) if hasattr(data, "__len__") else ()
+
+
+# -----------------------------------------------------------------------------
+# Tests
class TestPropArray(unittest.TestCase):
def setUp(self):
- bpy.types.Scene.test_array_f = bpy.props.FloatVectorProperty(size=10)
- bpy.types.Scene.test_array_i = bpy.props.IntVectorProperty(size=10)
+ id_type.test_array_f = FloatVectorProperty(size=10)
+ id_type.test_array_i = IntVectorProperty(size=10)
scene = bpy.context.scene
self.array_f = scene.test_array_f
self.array_i = scene.test_array_i
+ def tearDown(self):
+ del id_type.test_array_f
+ del id_type.test_array_i
+
def test_foreach_getset_i(self):
with self.assertRaises(TypeError):
self.array_i.foreach_set(range(5))
@@ -79,6 +122,79 @@ class TestPropArray(unittest.TestCase):
self.assertEqual(v1, v2)
+class TestPropArrayMultiDimensional(unittest.TestCase):
+
+ def setUp(self):
+ self._initial_dir = set(dir(id_type))
+
+ def tearDown(self):
+ for member in (set(dir(id_type)) - self._initial_dir):
+ delattr(id_type, member)
+
+ def test_defaults(self):
+ # The data is in int format, converted into float & bool to avoid duplication.
+ default_data = (
+ # 1D.
+ (1,),
+ (1, 2),
+ (1, 2, 3),
+ (1, 2, 3, 4),
+ # 2D.
+ ((1,),),
+ ((1,), (11,)),
+ ((1, 2), (11, 22)),
+ ((1, 2, 3), (11, 22, 33)),
+ ((1, 2, 3, 4), (11, 22, 33, 44)),
+ # 3D.
+ (((1,),),),
+ ((1,), (11,), (111,)),
+ ((1, 2), (11, 22), (111, 222),),
+ ((1, 2, 3), (11, 22, 33), (111, 222, 333)),
+ ((1, 2, 3, 4), (11, 22, 33, 44), (111, 222, 333, 444)),
+ )
+ for data in default_data:
+ for (vector_prop_fn, xform_fn) in (
+ (BoolVectorProperty, lambda v: bool(v % 2)),
+ (FloatVectorProperty, lambda v: float(v)),
+ (IntVectorProperty, lambda v: v),
+ ):
+ data_native = seq_items_xform(data, xform_fn)
+ size = seq_items_as_dims(data)
+ id_type.temp = vector_prop_fn(size=size, default=data_native)
+ data_as_tuple = seq_items_as_tuple(id_inst.temp)
+ self.assertEqual(data_as_tuple, data_native)
+ del id_type.temp
+
+ def test_matrix(self):
+ data = ((1, 2, 3, 4), (11, 22, 33, 44), (111, 222, 333, 444), (1111, 2222, 3333, 4444),)
+ data_native = seq_items_xform(data, lambda v: float(v))
+ id_type.temp = FloatVectorProperty(size=(4, 4), subtype='MATRIX', default=data_native)
+ data_as_tuple = seq_items_as_tuple(id_inst.temp)
+ self.assertEqual(data_as_tuple, data_native)
+ del id_type.temp
+
+ def test_matrix_with_callbacks(self):
+ # """
+ # Internally matrices have rows/columns swapped,
+ # This test ensures this is being done properly.
+ # """
+ data = ((1, 2, 3, 4), (11, 22, 33, 44), (111, 222, 333, 444), (1111, 2222, 3333, 4444),)
+ data_native = seq_items_xform(data, lambda v: float(v))
+ local_data = {"array": data}
+
+ def get_fn(id_arg):
+ return local_data["array"]
+
+ def set_fn(id_arg, value):
+ local_data["array"] = value
+
+ id_type.temp = FloatVectorProperty(size=(4, 4), subtype='MATRIX', get=get_fn, set=set_fn)
+ id_inst.temp = data_native
+ data_as_tuple = seq_items_as_tuple(id_inst.temp)
+ self.assertEqual(data_as_tuple, data_native)
+ del id_type.temp
+
+
if __name__ == '__main__':
import sys
sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else [])