# How to modify vertex groups through script

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?

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

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