Add to/remove from vertex groups not working

I wrote a Python script to fix vertex groups that are supposed to only contain vertices on one side of the mesh (right or left) but when I run it, the vertex groups are not affected. I attached a .blend file adding vertex groups to the cube I made to test this script.

The script runs through each vertex and prints a line on each iteration: print(v.index,to_add,to_remove,v.co), where v is the vertex, to_add is a list of tuples of vertices to add to a group, and to_remove is a list of groups to remove v from. I’d expect that to_add would only contain the index of the vertex with the same y and z coordinates as v, but negative x coordinate. Here is the result of the print statement:


0 [] [] <Vector (1.0000, 1.0000, -1.0000)>
1 [('Group2.R', 2, 1.0)] ['Group2.L'] <Vector (1.0000, -1.0000, -1.0000)>
2 [('Group2.L', 1, 1.0)] ['Group2.R'] <Vector (-1.0000, -1.0000, -1.0000)>
3 [] [] <Vector (-1.0000, 1.0000, -1.0000)>
4 [('Group1.R', 7, 1.0)] ['Group1.L'] <Vector (1.0000, 1.0000, 1.0000)>
5 [('Group1.R', 6, 1.0)] ['Group1.L'] <Vector (1.0000, -1.0000, 1.0000)>
6 [('Group1.L', 5, 1.0)] ['Group1.R'] <Vector (-1.0000, -1.0000, 1.0000)>
7 [('Group1.L', 4, 1.0)] ['Group1.R'] <Vector (-1.0000, 1.0000, 1.0000)>

Although the program determines that vertices should be added to and removed from groups, it does not actually make changes to the vertex groups. On the cube in the .blend file, the .L groups contain vertices on both the left and right side and the .R groups are empty (and they remain the same after running the script).

I run the script from object mode. When I run it in edit mode I get an error, “RuntimeError: Error: VertexGroup.add(): cannot be called while object is in edit mode.” I am using Blender 2.79.


import bpy

l = ["Cube"]
#p = [20, 79, 80, 100, 156, 215, 216, 239]

def getVIdx(v,vIdx,flag):
    if flag == 0:
        return vIdx[(round(v.co[0],4),round(v.co[1],4),round(v.co[2],4))]
    elif flag == 1:
        return vIdx[(-round(v.co[0],4),round(v.co[1],4),round(v.co[2],4))]

for i in l:
    vIdx = {}
    o = bpy.data.objects[i]
    for i in range(len(o.data.vertices)):
        v = o.data.vertices[i]
        vIdx[(round(v.co[0],4),round(v.co[1],4),round(v.co[2],4))] = i
    for v in o.data.vertices:
        to_add = []
        to_remove = []
        if v.co[0] > 0:
            for g in v.groups:
                gname = o.vertex_groups[g.group].name
                if gname[-2:] == ".L":
                    to_add.append((gname[:-2]+".R",getVIdx(v,vIdx,1),g.weight))
                    to_remove.append(gname)
        elif v.co[0] < 0:
            for g in v.groups:
                gname = o.vertex_groups[g.group].name
                if gname[-2:] == ".R":
                    to_add.append((gname[:-2]+".L",getVIdx(v,vIdx,1),g.weight))
                    to_remove.append(gname)
        print(v.index,to_add,to_remove,v.co)
        for i in to_add:
#            if i[1] in p:
#                print("ADD",i)
            o.vertex_groups[i[0]].add([i[1]],i[2],"REPLACE")
        for i in to_remove:
#            if v.index in p:
#                print("REMOVE",i,v.index)
            o.vertex_groups[i].remove([v.index])
    o.data.update()

Attachments

vertex_group_rl.blend (505 KB)