BPY: Implement get_transform and set_transform for runtime-defined RNA properties.
Improve handling of runtime defined python RNA properties. Mainly:
* Add `get_transform` and `set_transform` new callbacks.
These allow to edit the value, while still using the default
(IDProperty-based) storage system.
* Read-only properties should now be defined using a new `options` flag,
`READ_ONLY`.
* `get`/`set` should only be used when storing data outside of the
default system now.
* Having a `get` without a `set` defined forces property to be
read-only (same behavior as before).
* Having a `set` without a `get` is now an error.
* Just like with existing `get/set` callbacks, `get_/set_transform`
callbacks must always generate values matching the constraints defined
by their `bpy.props` property definition (same type, within required
range, same dimensions/sizes for the `Vector` properties, etc.).
* To simplify handling of non-statically sized strings, the relevant
RNA API has been modified, to use `std::string` instead of
(allocated) char arrays.
Relevant unittests and benchmarking have been added or updated as part
of this project.
Note: From initial benchmarking, 'transform' versions of get/set are
several times faster than 'real' get/set.
Implements #141042.
Pull Request: https://projects.blender.org/blender/blender/pulls/141303
This commit is contained in:
committed by
Bastien Montagne
parent
75c66158aa
commit
469f54f484
@@ -7,6 +7,8 @@ import bpy
|
||||
import rna_prop_ui
|
||||
import idprop
|
||||
|
||||
import io
|
||||
import sys
|
||||
import unittest
|
||||
from array import array
|
||||
|
||||
@@ -266,6 +268,12 @@ class TestIdPropertyDynamicRNA(TestHelper, unittest.TestCase):
|
||||
string_prop: bpy.props.StringProperty()
|
||||
int_prop: bpy.props.IntProperty()
|
||||
float_array_prop: bpy.props.FloatVectorProperty(size=[3])
|
||||
# Basic get/set transform.
|
||||
string_prop_transform: bpy.props.StringProperty(
|
||||
default="test",
|
||||
maxlen=10,
|
||||
get_transform=lambda self, storage_val, is_set: storage_val + "!!",
|
||||
set_transform=lambda self, new_val, storage_val, is_set: storage_val + "!!" + new_val)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@@ -348,6 +356,40 @@ class TestIdPropertyDynamicRNA(TestHelper, unittest.TestCase):
|
||||
with self.assertRaises(TypeError):
|
||||
self.id.bl_system_properties_get()['dynrna_prop']['float_array_prop'] = [1.0, 10.0, 100.0, 0.1]
|
||||
|
||||
def test_get_set_transform(self):
|
||||
self.assertEqual(len(self.id.dynrna_prop.string_prop_transform), 6)
|
||||
self.assertEqual(self.id.dynrna_prop.string_prop_transform, "test!!")
|
||||
# Default value only, was not yet set.
|
||||
self.assertFalse('string_prop_transform' in self.id.bl_system_properties_get()['dynrna_prop'])
|
||||
|
||||
self.id.dynrna_prop.string_prop_transform = "-"
|
||||
self.assertEqual(self.id.dynrna_prop.string_prop_transform, "test!!-!!")
|
||||
self.assertEqual(self.id.bl_system_properties_get()['dynrna_prop']['string_prop_transform'], "test!!-")
|
||||
|
||||
# Raw-set exactly maxlen - 1 char.
|
||||
self.id.bl_system_properties_get()['dynrna_prop']['string_prop_transform'] = "test!!tes"
|
||||
# get_transform will produce an 11-char results, which should trigger an error.
|
||||
# These asserts are not raised currently, but only print in `stderr`...
|
||||
# But the returned string is the 'storage' one, not the result from get_transform.
|
||||
stderr, sys.stderr = sys.stderr, io.StringIO()
|
||||
self.assertEqual(self.id.dynrna_prop.string_prop_transform, "test!!tes")
|
||||
self.assertTrue("ValueError" in sys.stderr.getvalue() and
|
||||
"10" in sys.stderr.getvalue() and "11" in sys.stderr.getvalue())
|
||||
sys.stderr.close()
|
||||
sys.stderr = stderr
|
||||
|
||||
# Raw-set back to default value.
|
||||
self.id.bl_system_properties_get()['dynrna_prop']['string_prop_transform'] = "test"
|
||||
# Now set_transform will return 12-char string, wich is also invalid and discarded.
|
||||
stderr, sys.stderr = sys.stderr, io.StringIO()
|
||||
self.id.dynrna_prop.string_prop_transform = "test!!"
|
||||
self.assertTrue("ValueError" in sys.stderr.getvalue() and
|
||||
"10" in sys.stderr.getvalue() and "12" in sys.stderr.getvalue())
|
||||
sys.stderr.close()
|
||||
sys.stderr = stderr
|
||||
self.assertEqual(self.id.bl_system_properties_get()['dynrna_prop']['string_prop_transform'], "test")
|
||||
self.assertEqual(self.id.dynrna_prop.string_prop_transform, "test!!")
|
||||
|
||||
|
||||
class TestIdPropertyGroupView(TestHelper, unittest.TestCase):
|
||||
|
||||
|
||||
@@ -45,33 +45,70 @@ class TestPropNumerical(unittest.TestCase):
|
||||
id_type.test_float = FloatProperty(default=float(self.default_value))
|
||||
|
||||
self.test_bool_storage = bool(self.custom_value)
|
||||
self.test_int_storage = int(self.custom_value)
|
||||
self.test_float_storage = float(self.custom_value)
|
||||
|
||||
def set_(s, v):
|
||||
def bool_set_(s, v):
|
||||
self.test_bool_storage = v
|
||||
|
||||
def int_set_(s, v):
|
||||
self.test_int_storage = v
|
||||
|
||||
def float_set_(s, v):
|
||||
self.test_float_storage = v
|
||||
|
||||
id_type.test_bool_getset = BoolProperty(
|
||||
default=bool(self.default_value),
|
||||
get=lambda s: self.test_bool_storage,
|
||||
set=set_,
|
||||
set=bool_set_,
|
||||
)
|
||||
|
||||
self.test_int_storage = int(self.custom_value)
|
||||
|
||||
def set_(s, v):
|
||||
self.test_int_storage = v
|
||||
id_type.test_int_getset = IntProperty(
|
||||
default=int(self.default_value),
|
||||
get=lambda s: self.test_int_storage,
|
||||
set=set_,
|
||||
set=int_set_,
|
||||
)
|
||||
|
||||
self.test_float_storage = float(self.custom_value)
|
||||
|
||||
def set_(s, v):
|
||||
self.test_float_storage = v
|
||||
id_type.test_float_getset = FloatProperty(
|
||||
default=float(self.default_value),
|
||||
get=lambda s: self.test_float_storage,
|
||||
set=set_,
|
||||
set=float_set_,
|
||||
)
|
||||
|
||||
id_type.test_bool_transform = BoolProperty(
|
||||
default=bool(self.default_value),
|
||||
get_transform=lambda s, c_v, isset: c_v,
|
||||
set_transform=lambda s, n_v, c_v, isset: n_v,
|
||||
)
|
||||
id_type.test_int_transform = IntProperty(
|
||||
default=int(self.default_value),
|
||||
get_transform=lambda s, c_v, isset: c_v,
|
||||
set_transform=lambda s, n_v, c_v, isset: n_v,
|
||||
)
|
||||
id_type.test_float_transform = FloatProperty(
|
||||
default=float(self.default_value),
|
||||
get_transform=lambda s, c_v, isset: c_v,
|
||||
set_transform=lambda s, n_v, c_v, isset: n_v,
|
||||
)
|
||||
|
||||
id_type.test_bool_getset_transform = BoolProperty(
|
||||
default=bool(self.default_value),
|
||||
get=lambda s: self.test_bool_storage,
|
||||
set=bool_set_,
|
||||
get_transform=lambda s, c_v, isset: c_v,
|
||||
set_transform=lambda s, n_v, c_v, isset: n_v,
|
||||
)
|
||||
id_type.test_int_getset_transform = IntProperty(
|
||||
default=int(self.default_value),
|
||||
get=lambda s: self.test_int_storage,
|
||||
set=int_set_,
|
||||
get_transform=lambda s, c_v, isset: c_v,
|
||||
set_transform=lambda s, n_v, c_v, isset: n_v,
|
||||
)
|
||||
id_type.test_float_getset_transform = FloatProperty(
|
||||
default=float(self.default_value),
|
||||
get=lambda s: self.test_float_storage,
|
||||
set=float_set_,
|
||||
get_transform=lambda s, c_v, isset: c_v,
|
||||
set_transform=lambda s, n_v, c_v, isset: n_v,
|
||||
)
|
||||
|
||||
def tearDown(self):
|
||||
@@ -83,6 +120,14 @@ class TestPropNumerical(unittest.TestCase):
|
||||
del id_type.test_int_getset
|
||||
del id_type.test_bool_getset
|
||||
|
||||
del id_type.test_float_transform
|
||||
del id_type.test_int_transform
|
||||
del id_type.test_bool_transform
|
||||
|
||||
del id_type.test_float_getset_transform
|
||||
del id_type.test_int_getset_transform
|
||||
del id_type.test_bool_getset_transform
|
||||
|
||||
def do_test_access(self, prop_name, py_type, expected_value):
|
||||
v = getattr(id_inst, prop_name)
|
||||
self.assertIsInstance(v, py_type)
|
||||
@@ -110,6 +155,24 @@ class TestPropNumerical(unittest.TestCase):
|
||||
def test_access_float_getset(self):
|
||||
self.do_test_access("test_float_getset", float, float(self.custom_value))
|
||||
|
||||
def test_access_bool_transform(self):
|
||||
self.do_test_access("test_bool_transform", bool, bool(self.default_value))
|
||||
|
||||
def test_access_int_transform(self):
|
||||
self.do_test_access("test_int_transform", int, int(self.default_value))
|
||||
|
||||
def test_access_float_transform(self):
|
||||
self.do_test_access("test_float_transform", float, float(self.default_value))
|
||||
|
||||
def test_access_bool_getset_transform(self):
|
||||
self.do_test_access("test_bool_getset_transform", bool, bool(self.custom_value))
|
||||
|
||||
def test_access_int_getset_transform(self):
|
||||
self.do_test_access("test_int_getset_transform", int, int(self.custom_value))
|
||||
|
||||
def test_access_float_getset_transform(self):
|
||||
self.do_test_access("test_float_getset_transform", float, float(self.custom_value))
|
||||
|
||||
# TODO: Add expected failure cases (e.g. handling of out-of range values).
|
||||
|
||||
|
||||
@@ -171,28 +234,63 @@ class TestPropEnum(unittest.TestCase):
|
||||
)
|
||||
|
||||
self.test_enum_storage = self.enum_expected_values[self.custom_value]
|
||||
|
||||
def set_(s, v):
|
||||
self.test_enum_storage = v
|
||||
id_type.test_enum_getset = EnumProperty(
|
||||
items=self.enum_items,
|
||||
default=self.default_value,
|
||||
get=lambda s: self.test_enum_storage,
|
||||
set=set_,
|
||||
)
|
||||
|
||||
self.test_enum_bitflag_storage = functools.reduce(
|
||||
lambda a, b: a | b,
|
||||
(self.enum_expected_bitflag_values[bf] for bf in self.custom_bitflag_value))
|
||||
|
||||
def set_(s, v):
|
||||
def enum_set_(s, v):
|
||||
self.test_enum_storage = v
|
||||
|
||||
def bitflag_set_(s, v):
|
||||
self.test_enum_bitflag_storage = v
|
||||
|
||||
id_type.test_enum_getset = EnumProperty(
|
||||
items=self.enum_items,
|
||||
default=self.default_value,
|
||||
get=lambda s: self.test_enum_storage,
|
||||
set=enum_set_,
|
||||
)
|
||||
|
||||
id_type.test_enum_bitflag_getset = EnumProperty(
|
||||
items=self.enum_items,
|
||||
default=self.default_bitflag_value,
|
||||
options={"ENUM_FLAG"},
|
||||
get=lambda s: self.test_enum_bitflag_storage,
|
||||
set=set_,
|
||||
set=bitflag_set_,
|
||||
)
|
||||
|
||||
id_type.test_enum_transform = EnumProperty(
|
||||
items=self.enum_items,
|
||||
default=self.default_value,
|
||||
get_transform=lambda s, c_v, isset: c_v,
|
||||
set_transform=lambda s, n_v, c_v, isset: n_v,
|
||||
)
|
||||
|
||||
id_type.test_enum_bitflag_transform = EnumProperty(
|
||||
items=self.enum_items,
|
||||
default=self.default_bitflag_value,
|
||||
options={"ENUM_FLAG"},
|
||||
get_transform=lambda s, c_v, isset: c_v,
|
||||
set_transform=lambda s, n_v, c_v, isset: n_v,
|
||||
)
|
||||
|
||||
id_type.test_enum_getset_transform = EnumProperty(
|
||||
items=self.enum_items,
|
||||
default=self.default_value,
|
||||
get=lambda s: self.test_enum_storage,
|
||||
set=enum_set_,
|
||||
get_transform=lambda s, c_v, isset: c_v,
|
||||
set_transform=lambda s, n_v, c_v, isset: n_v,
|
||||
)
|
||||
|
||||
id_type.test_enum_bitflag_getset_transform = EnumProperty(
|
||||
items=self.enum_items,
|
||||
default=self.default_bitflag_value,
|
||||
options={"ENUM_FLAG"},
|
||||
get_transform=lambda s, c_v, isset: c_v,
|
||||
set_transform=lambda s, n_v, c_v, isset: n_v,
|
||||
get=lambda s: self.test_enum_bitflag_storage,
|
||||
set=bitflag_set_,
|
||||
)
|
||||
|
||||
def tearDown(self):
|
||||
@@ -200,6 +298,10 @@ class TestPropEnum(unittest.TestCase):
|
||||
del id_type.test_enum_bitflag
|
||||
del id_type.test_enum_getset
|
||||
del id_type.test_enum_bitflag_getset
|
||||
del id_type.test_enum_transform
|
||||
del id_type.test_enum_bitflag_transform
|
||||
del id_type.test_enum_getset_transform
|
||||
del id_type.test_enum_bitflag_getset_transform
|
||||
|
||||
# Test expected generated values for enum items.
|
||||
def do_test_enum_values(self, prop_name, expected_item_values):
|
||||
@@ -215,6 +317,24 @@ class TestPropEnum(unittest.TestCase):
|
||||
def test_enum_bitflag_item_values(self):
|
||||
self.do_test_enum_values("test_enum_bitflag", self.enum_expected_bitflag_values)
|
||||
|
||||
def test_enum_getset_item_values(self):
|
||||
self.do_test_enum_values("test_enum_getset", self.enum_expected_values)
|
||||
|
||||
def test_enum_bitflag_getset_item_values(self):
|
||||
self.do_test_enum_values("test_enum_bitflag_getset", self.enum_expected_bitflag_values)
|
||||
|
||||
def test_enum_transform_item_values(self):
|
||||
self.do_test_enum_values("test_enum_transform", self.enum_expected_values)
|
||||
|
||||
def test_enum_bitflag_transform_item_values(self):
|
||||
self.do_test_enum_values("test_enum_bitflag_transform", self.enum_expected_bitflag_values)
|
||||
|
||||
def test_enum_getset_transform_item_values(self):
|
||||
self.do_test_enum_values("test_enum_getset_transform", self.enum_expected_values)
|
||||
|
||||
def test_enum_bitflag_getset_transform_item_values(self):
|
||||
self.do_test_enum_values("test_enum_bitflag_getset_transform", self.enum_expected_bitflag_values)
|
||||
|
||||
# Test basic access to enum values.
|
||||
def do_test_access(self, prop_name, py_type, expected_value):
|
||||
v = getattr(id_inst, prop_name)
|
||||
@@ -234,6 +354,18 @@ class TestPropEnum(unittest.TestCase):
|
||||
def test_access_enum_bitflag_getset(self):
|
||||
self.do_test_access("test_enum_bitflag_getset", set, self.custom_bitflag_value)
|
||||
|
||||
def test_access_enum_transform(self):
|
||||
self.do_test_access("test_enum_transform", str, self.default_value)
|
||||
|
||||
def test_access_enum_bitflag_transform(self):
|
||||
self.do_test_access("test_enum_bitflag_transform", set, self.default_bitflag_value)
|
||||
|
||||
def test_access_enum_getset_transform(self):
|
||||
self.do_test_access("test_enum_getset_transform", str, self.custom_value)
|
||||
|
||||
def test_access_enum_bitflag_getset_transform(self):
|
||||
self.do_test_access("test_enum_bitflag_getset_transform", set, self.custom_bitflag_value)
|
||||
|
||||
# TODO: Add expected failure cases (e.g. handling of invalid items identifiers).
|
||||
|
||||
|
||||
|
||||
@@ -147,32 +147,71 @@ class TestPropArrayIndex(unittest.TestCase):
|
||||
|
||||
self.test_array_b_2d_storage = [[bool(v) for v in range(self.size_2d[1])] for i in range(self.size_2d[0])]
|
||||
|
||||
def set_(s, v):
|
||||
def bool_set_(s, v):
|
||||
self.test_array_b_2d_storage = v
|
||||
id_type.test_array_b_2d_getset = BoolVectorProperty(
|
||||
size=self.size_2d,
|
||||
get=lambda s: self.test_array_b_2d_storage,
|
||||
set=set_,
|
||||
)
|
||||
|
||||
self.test_array_i_2d_storage = [[int(v) for v in range(self.size_2d[1])] for i in range(self.size_2d[0])]
|
||||
|
||||
def set_(s, v):
|
||||
def int_set_(s, v):
|
||||
self.test_array_i_2d_storage = v
|
||||
id_type.test_array_i_2d_getset = IntVectorProperty(
|
||||
size=self.size_2d,
|
||||
get=lambda s: self.test_array_i_2d_storage,
|
||||
set=set_,
|
||||
)
|
||||
|
||||
self.test_array_f_2d_storage = [[float(v) for v in range(self.size_2d[1])] for i in range(self.size_2d[0])]
|
||||
|
||||
def set_(s, v):
|
||||
def float_set_(s, v):
|
||||
self.test_array_f_2d_storage = v
|
||||
|
||||
id_type.test_array_b_2d_getset = BoolVectorProperty(
|
||||
size=self.size_2d,
|
||||
get=lambda s: self.test_array_b_2d_storage,
|
||||
set=bool_set_,
|
||||
)
|
||||
id_type.test_array_i_2d_getset = IntVectorProperty(
|
||||
size=self.size_2d,
|
||||
get=lambda s: self.test_array_i_2d_storage,
|
||||
set=int_set_,
|
||||
)
|
||||
id_type.test_array_f_2d_getset = FloatVectorProperty(
|
||||
size=self.size_2d,
|
||||
get=lambda s: self.test_array_f_2d_storage,
|
||||
set=set_,
|
||||
set=float_set_,
|
||||
)
|
||||
|
||||
id_type.test_array_b_3d_transform = BoolVectorProperty(
|
||||
size=self.size_3d,
|
||||
get_transform=lambda s, c_v, isset: seq_items_xform(c_v, lambda v: not v),
|
||||
set_transform=lambda s, n_v, c_v, isset: seq_items_xform(n_v, lambda v: not v),
|
||||
)
|
||||
id_type.test_array_i_3d_transform = IntVectorProperty(
|
||||
size=self.size_3d,
|
||||
get_transform=lambda s, c_v, isset: seq_items_xform(c_v, lambda v: v + 1),
|
||||
set_transform=lambda s, n_v, c_v, isset: seq_items_xform(n_v, lambda v: v - 1),
|
||||
)
|
||||
id_type.test_array_f_3d_transform = FloatVectorProperty(
|
||||
size=self.size_3d,
|
||||
get_transform=lambda s, c_v, isset: seq_items_xform(c_v, lambda v: v * 2.0),
|
||||
set_transform=lambda s, n_v, c_v, isset: seq_items_xform(n_v, lambda v: v / 2.0),
|
||||
)
|
||||
|
||||
id_type.test_array_b_2d_getset_transform = BoolVectorProperty(
|
||||
size=self.size_2d,
|
||||
get=lambda s: self.test_array_b_2d_storage,
|
||||
set=bool_set_,
|
||||
get_transform=lambda s, c_v, isset: seq_items_xform(c_v, lambda v: not v),
|
||||
set_transform=lambda s, n_v, c_v, isset: seq_items_xform(n_v, lambda v: not v),
|
||||
)
|
||||
id_type.test_array_i_2d_getset_transform = IntVectorProperty(
|
||||
size=self.size_2d,
|
||||
get=lambda s: self.test_array_i_2d_storage,
|
||||
set=int_set_,
|
||||
get_transform=lambda s, c_v, isset: seq_items_xform(c_v, lambda v: v + 1),
|
||||
set_transform=lambda s, n_v, c_v, isset: seq_items_xform(n_v, lambda v: v - 1),
|
||||
)
|
||||
id_type.test_array_f_2d_getset_transform = FloatVectorProperty(
|
||||
size=self.size_2d,
|
||||
get=lambda s: self.test_array_f_2d_storage,
|
||||
set=float_set_,
|
||||
get_transform=lambda s, c_v, isset: seq_items_xform(c_v, lambda v: v * 2.0),
|
||||
set_transform=lambda s, n_v, c_v, isset: seq_items_xform(n_v, lambda v: v / 2.0),
|
||||
)
|
||||
|
||||
def tearDown(self):
|
||||
@@ -190,6 +229,14 @@ class TestPropArrayIndex(unittest.TestCase):
|
||||
del id_type.test_array_i_2d_getset
|
||||
del id_type.test_array_b_2d_getset
|
||||
|
||||
del id_type.test_array_f_3d_transform
|
||||
del id_type.test_array_i_3d_transform
|
||||
del id_type.test_array_b_3d_transform
|
||||
|
||||
del id_type.test_array_f_2d_getset_transform
|
||||
del id_type.test_array_i_2d_getset_transform
|
||||
del id_type.test_array_b_2d_getset_transform
|
||||
|
||||
@staticmethod
|
||||
def compute_slice_len(s):
|
||||
if not isinstance(s, slice):
|
||||
@@ -297,6 +344,36 @@ class TestPropArrayIndex(unittest.TestCase):
|
||||
id_inst.test_array_f_2d_getset, self.size_2d, self.valid_indices_2d, self.invalid_indices_2d
|
||||
)
|
||||
|
||||
def test_indices_access_b_3d_transform(self):
|
||||
self.do_test_indices_access(
|
||||
id_inst.test_array_b_3d_transform, self.size_3d, self.valid_indices_3d, self.invalid_indices_3d
|
||||
)
|
||||
|
||||
def test_indices_access_i_3d_transform(self):
|
||||
self.do_test_indices_access(
|
||||
id_inst.test_array_i_3d_transform, self.size_3d, self.valid_indices_3d, self.invalid_indices_3d
|
||||
)
|
||||
|
||||
def test_indices_access_f_3d_transform(self):
|
||||
self.do_test_indices_access(
|
||||
id_inst.test_array_f_3d_transform, self.size_3d, self.valid_indices_3d, self.invalid_indices_3d
|
||||
)
|
||||
|
||||
def test_indices_access_b_2d_getset_transform(self):
|
||||
self.do_test_indices_access(
|
||||
id_inst.test_array_b_2d_getset_transform, self.size_2d, self.valid_indices_2d, self.invalid_indices_2d
|
||||
)
|
||||
|
||||
def test_indices_access_i_2d_getset_transform(self):
|
||||
self.do_test_indices_access(
|
||||
id_inst.test_array_i_2d_getset_transform, self.size_2d, self.valid_indices_2d, self.invalid_indices_2d
|
||||
)
|
||||
|
||||
def test_indices_access_f_2d_getset_transform(self):
|
||||
self.do_test_indices_access(
|
||||
id_inst.test_array_f_2d_getset_transform, self.size_2d, self.valid_indices_2d, self.invalid_indices_2d
|
||||
)
|
||||
|
||||
|
||||
class TestPropArrayForeach(unittest.TestCase):
|
||||
# Test foreach_get/_set access of Int and Float vector properties (bool ones do not support this).
|
||||
@@ -499,12 +576,37 @@ class TestPropArrayMultiDimensional(unittest.TestCase):
|
||||
def set_fn(id_arg, value):
|
||||
local_data["array"] = value
|
||||
|
||||
def get_tx_fn(id_arg, curr_value, is_set):
|
||||
return seq_items_xform(curr_value, lambda v: v + 1.0)
|
||||
|
||||
def set_tx_fn(id_arg, new_value, curr_value, is_set):
|
||||
return seq_items_xform(new_value, lambda v: v - 1.0)
|
||||
|
||||
id_type.temp = FloatVectorProperty(size=(dim_x, dim_y), 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
|
||||
|
||||
id_type.temp = FloatVectorProperty(
|
||||
size=(dim_x, dim_y), subtype='MATRIX', get_transform=get_tx_fn, set_transform=set_tx_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
|
||||
|
||||
id_type.temp = FloatVectorProperty(
|
||||
size=(dim_x, dim_y),
|
||||
subtype='MATRIX',
|
||||
get=get_fn,
|
||||
set=set_fn,
|
||||
get_transform=get_tx_fn,
|
||||
set_transform=set_tx_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
|
||||
|
||||
def test_matrix_3x3(self):
|
||||
self._test_matrix(3, 3)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user