0
$\begingroup$

I'm trying to modify an object's vertex groups from a python script. I've come up with the following code which throws no errors, but doesn't change the values in the vertex groups:

class scaleWeight(bpy.types.Operator):
bl_idname = "object.scaleweight"
bl_label = "scale vertex groups"

def execute(self, context):
    ob = context.active_object

    try:
        assert ob.vertex_groups
    except:
        return

    for v in ob.data.vertices:
        #print(v.index)
        for grp in ob.vertex_groups:
            weight = grp.weight(v.index)
            #print('weight=', weight)
            try:
                grp.add(v.index, weight * 0.5, 'REPLACE')
            except:
                #print('err')
                continue

    ob.data.update()

    return {"FINISHED"}

Can anyone tell me where I've gone wrong here?

$\endgroup$
  • $\begingroup$ The try block is hiding the fact that grp.add() takes a list for the first param, not a single int. $\endgroup$ – sambler Nov 15 '17 at 9:34
3
$\begingroup$

Set the group weight on the vertex.

The VertexGroup.add(...) requires a list of indices, you have only given an int. Neeed to grp.add([v.index], weight * 0.5, 'REPLACE')

To get all verts in a vertex group.

Different take on this, iterate thru the vertices, and if they have been assigned to group (I've used selected group, change code for any) its group weight is multiplied by the scale factor.

This needs to be done in object mode, included a mode toggle.

import bpy

class SimpleOperator(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.simple_operator"
    bl_label = "Simple Object Operator"
    bl_options = {'REGISTER', 'UNDO'}

    scale_factor = bpy.props.FloatProperty(
        name="scale_factor", 
        default=1,
        min=0.001,
        options={'SKIP_SAVE'})

    @classmethod
    def poll(cls, context):
        obj = context.object
        return (obj is not None
                and hasattr(obj,"vertex_groups")
                and len(getattr(obj, "vertex_groups", [])))

    def execute(self, context):        
        obj = context.object
        mode = obj.mode
        me = obj.data
        # all groups (using selected)
        # groups = [g.index for g in obj.vertex_groups]
        # active group

        groups = [obj.vertex_groups.active_index]
        bpy.ops.object.mode_set(mode='OBJECT')
        for v in me.vertices:
            for g in v.groups:
                if g.group in groups:
                    g.weight *= self.scale_factor

        me.update()
        bpy.ops.object.mode_set(mode=mode)
        return {'FINISHED'}

def register():
    bpy.utils.register_class(SimpleOperator)

def unregister():
    bpy.utils.unregister_class(SimpleOperator)

if __name__ == "__main__":
    register()

    bpy.ops.object.simple_operator(scale_factor=0.5) # test call
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.