Properties for vertex groups

Hi all,

I try to append a property to all vertex groups. Well at least i already appended it, but as i want to use the property for a panel, it says me that the active vertex group don’t have that property.

Well here are the few important code lines:


def init_properties():
    bpy.types.VertexGroup.mass = (name="Mass", description="Mass of Vertex Group", default=1.0, min=0.0)

class panel(bpy.types.Panel):
    [...]

    def draw(self, context):
        [...]
        
        row = layout.row()
        row.prop(context.scene.objects.active.vertex_groups.active, "mass", text="Mass")

I wonder why it won’t work, as i can use that inside the console and get the ‘mass’ property. Somebody has an idea?

Edit:

I’ve just seen that there is a difference between defining such properties for a scene, objects and vertex groups. As i define the same property for a scene, objects and vertex groups, i can use the prop for scene, for all objects, but at least not for vertex groups.

Here some commands inside the console to show what i mean (of course beeing in editmode with an active vertGroup):


>>> bpy.types.Scene.ScnInt = bpy.props.IntProperty(name="SceneInt", description="Integer Value")
>>> bpy.types.Scene.ScnInt
(<build-in function IntProperty>, {'attr': 'ScnInt', 'description': 'Integer Value', 'name': 'SceneInt'})

>>> bpy.context.scene.ScnInt
0

>>> bpy.types.Object.ObjInt = bpy.props.IntProperty(name="ObjectInt", description="Integer Value")
 >>> bpy.types.Object.ObjInt
 (<build-in function IntProperty>, {'attr': 'ObjInt', 'description': 'Integer Value', 'name': 'ObjectInt'})
 
 >>> bpy.context.scene.objects.active.ObjInt
 0
 
 >>> bpy.types.VertexGroup.VGInt = bpy.props.IntProperty(name="VertGrInt", description="Integer Value")
 >>> bpy.types.VertexGroup.VGInt
 (<build-in function IntProperty>, {'description': 'Integer Value', 'name': 'VertGrInt'})
 
 >>> bpy.context.scene.objects.active.vertex_groups.active.VGInt
 (<build-in function IntProperty>, {'description': 'Integer Value', 'name': 'VertGrInt'})
 

So also there is no ‘attr’ for vertex groups added. Now i’m wondering if there is a possibility for adding propertys to each vertex group (i need a property defined for each vgroup, not only one for all like weight, i want to have an individual attribute changing with each vgroup).

Couldn’t you create a ‘dictionary’ for your groups and save (and get!) there their information?
vertex_groups as well as groups seem not to allow ‘extras’ …

I checked on irc with ideasman_42 (the main developer of the Blender Python api) and he confirmed that it’s impossible to add a custom property to vertex groups. You can only add properties to classes that are subclasses of the ID-type, which explains why Scenes and Objects work correctly, but VertexGroups don’t.

So probably it’s best to go with PKHG’s suggestion.

Hey thanks for this information (actually i also thought so, because the vertex group classes are read only)

Well another Problem. I am trying the dictionary way mentionned by PKHG, but at least i want to save the dictionary as a valid CollectionProperty as a property of types.Object. Well registering a normal property seems to be no problem here (something like IntProp, BoolProp, FloatProp, etc.) Also it’s no problem to create a simply global or local property of the collection type, but as i want to register a collection for types.Objects, it requires a type. Without type, nothing happens, with type, blender crashes…

Using Blender 2.55, r32738, the first two lines raise an error, the third kills the programm:


>>> bpy.types.Object.collProp = bpy.props.CollectionProperty(name="coll")
TypeError: Required argument 'type' (pos 2) not found
Traceback (most recent call)>
    File "<blender_console", line 1, in <module>
ValueError: bpy_struct "Object" registration error: collProp could not register

>>> bpy.types.Object.collProp = bpy.props.CollectionProperty(name="coll", type=bpy.types.VertexGroupElement)
SystemError: CollectionProperty(...): expected an RNA type derived from IDPropertyGroup
Traceback (most recent call)>
    File "<blender_console", line 1, in <module>
ValueError: bpy_struct "Object" registration error: collProp could not register

>>> bpy.types.Object.collProp = bpy.props.CollectionProperty(name="coll", type="myType")
...

It crashes with all kind of strings, at least i don’t know which kind of type is correct here

Edit: Haha, solved it… sometimes the simple way is the best^^
Just use this line:

>>> bpy.types.Object.collProp = bpy.props.CollectionProperty(name="coll", type=bpy.typesIDPropertyGroup)

But now i’ve the problem that i can’t use my collection. It’s kind of only usable in bpy.types.Object, in bpy.data.objects[…] it is read-only. Is there a solution for this or should i stop trying to register a collection to bpy.types.Object? Seems to be impossible to stay confirm with the blender data…

I tried now the simple way of using a dict by following lines:


bpy.types.Object.vg_dict = {}
for obj in bpy.data.objects:
    for vg in obj.vertex_groups:
        obj.vg_dict[vg.name] = bpy.props.FloatProperty(name='prop')
        obj.vg_dict[vg.name] = 1.0

class VIEW3D_PT_MyClass(bpy.types.Panel):
    [...]

    def draw(self.context):
        layout = self.layout

        [...]

        obj = context.scene.objects.active
        vg_name = obj.vertex_groups.active.name

        update_vertex_group_dict(obj)
        row = layout.row()

        print("Name:", vg_name, " - Value:", obj.vg_dict[vg_name], "
Dict:", obj.vg_dict)
        row.prop(obj, "vg_dict[%s]" % vg_name, text="VG Prop")

The update function checks all vertex groups and gives them a valid value.
While running the script i get following lines with a active vertex group:

Name: Group - Value: 1.0
Dict: {‘Group’: 1.0, ‘Group.001’: 1.0}
rna_uiItemR: property not found: Object.vg_dict[Group]

So know i am wondering why it can’t find the property inside the layout.prop() function, but as printing manually, everything is fine.

This works :wink:


import bpy
bpy.types.Object.collProp = bpy.props.CollectionProperty({},type=bpy.types.IDPropertyGroup)
#print(dir(bpy.context.object))    

bpy.ops.mesh.primitive_plane_add(view_align=False, enter_editmode=False, location=(0, 0, 0), rotation=(0, 0, 0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))
plane = bpy.context.object
plane.name = "PKHG"
plane.collProp.add()
plane.collProp[0]["Hallo"]= "Peter was here!"
print(plane.collProp[0]["Hallo"])

Cool, thanks for the code.

I just tried it, actually i can’t use it (the Collection works on a different way i thought, it is just for int, float and string values, i can’t put another float property inside of it…)

It’s like the way i tried now with the dict. At least, i can save a property in my dict, but it don’t want to find this as well to use it for a panel.

Anyway, now i know how the collections are working :slight_smile:

So, i solved the problem. At last not the way i wanted, but it’s working now.

First of all, looks like it is impossible to define (on a simple way) a dictionary property or a property for each vertex group (well it is impossible to define a readable property to a type not inherited from ID).

My solution for the problem, a bit troubling, but working:
Define a active property which is always changing.
Define a dict for all vertex groups of a object.

Inside the draw Panel, define also two operators for saving the active prop to the dict and loading the right value from the dict to the active prop.

Not the best solution, but working :slight_smile: