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
@@ -69,18 +69,28 @@ def _run_runtime_group_register_access(args):
|
||||
do_register = args.get("do_register", False)
|
||||
do_access = args.get("do_access", False)
|
||||
do_get_set = args.get("do_get_set", False)
|
||||
do_transform = args.get("do_transform", False)
|
||||
property_type = args.get("property_type", 'IntProperty')
|
||||
property_definition_cb = getattr(bpy.props, property_type)
|
||||
|
||||
assert (not (do_get_set and do_transform))
|
||||
|
||||
# Define basic 'transform' callbacks to test setting value,
|
||||
# default to just setting untransformed value for 'unknown'/undefined property types.
|
||||
property_transform_cb = {
|
||||
property_transform_set_cb = {
|
||||
'BoolProperty': lambda v: not v,
|
||||
'IntProperty': lambda v: v + 1,
|
||||
'FloatVectorProperty': lambda v: [v[2] + 1.0, v[0], v[1]],
|
||||
'StringProperty': lambda v: ("B" if (v and v[0] == "A") else "A") + v[1:],
|
||||
}.get(property_type, lambda v: v)
|
||||
|
||||
property_transform_get_cb = {
|
||||
'BoolProperty': lambda v: not v,
|
||||
'IntProperty': lambda v: v - 1,
|
||||
'FloatVectorProperty': lambda v: [v[0], v[1], v[2]],
|
||||
'StringProperty': lambda v: ("B" if (v and v[0] == "A") else "A") + v[1:],
|
||||
}.get(property_type, lambda v: v)
|
||||
|
||||
if do_get_set:
|
||||
class DummyGroup(bpy.types.PropertyGroup):
|
||||
dummy_prop: property_definition_cb(
|
||||
@@ -95,6 +105,12 @@ def _run_runtime_group_register_access(args):
|
||||
"dummy_prop",
|
||||
val),
|
||||
)
|
||||
elif do_transform:
|
||||
class DummyGroup(bpy.types.PropertyGroup):
|
||||
dummy_prop: property_definition_cb(
|
||||
get_transform=lambda self, curr_v, is_set: property_transform_get_cb(curr_v),
|
||||
set_transform=lambda self, curr_v, new_v, is_set: property_transform_set_cb(curr_v),
|
||||
)
|
||||
else:
|
||||
class DummyGroup(bpy.types.PropertyGroup):
|
||||
dummy_prop: property_definition_cb()
|
||||
@@ -115,9 +131,14 @@ def _run_runtime_group_register_access(args):
|
||||
bpy.utils.register_class(DummyGroup)
|
||||
bpy.types.Scene.dummy_group = bpy.props.PointerProperty(type=DummyGroup)
|
||||
|
||||
for i in range(iterations):
|
||||
v = sce.dummy_group.dummy_prop
|
||||
sce.dummy_group.dummy_prop = property_transform_cb(v)
|
||||
if do_transform:
|
||||
for i in range(iterations):
|
||||
v = sce.dummy_group.dummy_prop
|
||||
sce.dummy_group.dummy_prop = v
|
||||
else:
|
||||
for i in range(iterations):
|
||||
v = sce.dummy_group.dummy_prop
|
||||
sce.dummy_group.dummy_prop = property_transform_set_cb(v)
|
||||
|
||||
del bpy.types.Scene.dummy_group
|
||||
bpy.utils.unregister_class(DummyGroup)
|
||||
@@ -165,4 +186,10 @@ def generate(env):
|
||||
{"do_access": True, "do_get_set": True, "property_type": 'FloatVectorProperty'}),
|
||||
BPYRNATest("Py-Defined StringProperty Custom Get/Set Access", _run_runtime_group_register_access, 10 * 1000,
|
||||
{"do_access": True, "do_get_set": True, "property_type": 'StringProperty'}),
|
||||
BPYRNATest("Py-Defined BoolProperty Custom Transform Access", _run_runtime_group_register_access, 1000 * 1000,
|
||||
{"do_access": True, "do_transform": True, "property_type": 'BoolProperty'}),
|
||||
BPYRNATest("Py-Defined FloatVectorProperty Custom Transform Access", _run_runtime_group_register_access, 1000 * 1000,
|
||||
{"do_access": True, "do_transform": True, "property_type": 'FloatVectorProperty'}),
|
||||
BPYRNATest("Py-Defined StringProperty Custom Transform Access", _run_runtime_group_register_access, 1000 * 1000,
|
||||
{"do_access": True, "do_transform": True, "property_type": 'StringProperty'}),
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user