Looking at the API docs I found VertexGroup.add(index, weight, type)
, but It cannot be called in Edit Mode. When I try to call it, I always get:
RuntimeError: VertexGroup.add(): cannot be called while object is in edit mode.
The buttons in the vertex group list use bpy.ops.objects.vertex_group_assign()
, but to work with it you have to manipulate selections, this is not nice to do from a script.
Why I try to use VertexGroup.add()
in Edit Mode? My script works this way:
Human weight paint a bone, "Arm_1.L", "Arm_1.L" shares vertices with "Arm_2.L" in this case they share half the vertices (4 bone arm rig, trick to have nice deform in certain movements). When script run, all selected vertices that exist in both groups (Arm_1.L and Arm_2.L) will copy the weights of Arm_1.L into Arm_2.L but inverted. This way, I only need to weight paint "Arm_1.L" and "Arm_3.L", the script will fill the weights for "Arm_2.L".
import bpy
# ensure we are in edit mode
bpy.ops.object.mode_set(mode="EDIT")
# configurable parameters
src_group = "Arm_03.L"
dst_group = "Arm_02.L"
obj = bpy.context.edit_object
src_group_index = obj.vertex_groups[src_group].index
dst_group_index = obj.vertex_groups[dst_group].index
mesh = obj.data
sel_verts = [v for v in mesh.vertices if v.select]
#sel_verts = mesh.vertices
# SEGFAULT in this line
bpy.ops.object.mode_set(mode="OBJECT")
print("Working")
for v in sel_verts:
v1in = False
v2in = False
for g in v.groups:
if g.group == src_group_index:
v1in = True
if g.group == dst_group_index:
v2in = True
if v1in and v2in:
print("True")
obj.vertex_groups[dst_group].add([v.index], 1.0 - obj.vertex_groups[src_group].weight(v.index), 'REPLACE')
print("Finished")