What's the best practice for polymorthic properties? I want to associate a type with an object; Cylinder, Thread, Cube etc. For each type I want properties associated, but as the object can only be one type at it only need one set of properties.
What I was hoping to be able to do was define a class from PropertyGroup
then subclass that, and set the custom type on the object. Something like this
class ObjectParameters(bpy.types.PropertyGroup):
type: bpy.props.StringProperty()
class CylinderParameters(ObjectParameters):
height: bpy.props.FloatProperty()
radius: bpy.props.FloatProperty()
class ThreadParameters(ObjectParameters):
height: bpy.props.FloatProperty()
pitch: bpy.props.FloatProperty()
radius: bpy.props.FloatProperty()
bpy.utils.register_class(ObjectParameters)
bpy.utils.register_class(CylinderParameters)
bpy.utils.register_class(ThreadParameters)
bpy.types.Object.object_parameters = bpy.props.PointerProperty(type=ObjectParameters)
cube = bpy.data.objects['Cube']
print(cube.object_parameters)
cube.object_parameters = CylinderParameters()
print(cube.object_parameters)
That fails as you can't create an instance of CylinderParameters; and even if you could cylinder_parameters
is read-only so you wouldn't be able to change it.
The best option I've come up with so far is this; creating properties for each type on bpy.types.Object
then having another one select between them.
import bpy
class CylinderParameters(bpy.types.PropertyGroup):
height: bpy.props.FloatProperty()
radius: bpy.props.FloatProperty()
class ThreadParameters(bpy.types.PropertyGroup):
height: bpy.props.FloatProperty()
pitch: bpy.props.FloatProperty()
radius: bpy.props.FloatProperty()
bpy.utils.register_class(CylinderParameters)
bpy.utils.register_class(ThreadParameters)
bpy.types.Object.object_type = bpy.props.EnumProperty(items=[
('NONE', 'None', '', 1),
('cylinder_parameters', 'Cylinder', '', 2),
('thread_parameters', 'Thread', '', 3),
], default='NONE')
bpy.types.Object.cylinder_parameters = bpy.props.PointerProperty(type=CylinderParameters)
bpy.types.Object.thread_parameters = bpy.props.PointerProperty(type=ThreadParameters)
cube = bpy.data.objects['Cube']
print('init type', cube.object_type)
cube.object_type = 'cylinder_parameters'
print(cube.object_type)
print(getattr(cube, cube.object_type))
The other way is to just update a custom property on the object with a dictionary e.g.
cube = bpy.data.objects['Cube']
cube['parameters'] = {'type': 'cylinder', 'height': 56, 'radius': 1}
print(cube['parameters'])
Whats the best way to do this?