Manipulate vertex groups via bmesh?

From what I’m seeing, there doesn’t appear to be a way to do it, unless I’m missing something?

A script I’m currently working on needs to stay in edit mode, but it also needs to add verts to a vertex group. vertex_group.add() doesn’t work in edit mode where bpy.ops.object.vertex_group_assign() ONLY works in edit mode (but requires you to change the selection).

I feel like I have two hacky solutions available- I could drop out of edit mode, set the vertex group indices, go back to edit mode (rebuild my bmesh, etc). Or the lesser of two evils- I could cache the current selection, select the verts needed, run object.vertex_group_assign(), then restore the original selection.

While either of those technically work, I wonder why there isn’t a more direct way to work with vertex groups within the python API? bmesh seems to be a smart candidate for this, it would be consistent with how face maps, uvs, vertex colors, and just about everything else are manipulated while in edit mode.

1 Like

This example uses BMesh to manipulate edit-mode vertex groups directly using dictionary like access where the keys are vertex group indices and the values are floating point weights.

There is an issue

# This example assumes we have a mesh object in edit-mode

import bpy
import bmesh

obj = bpy.context.edit_object
me = obj.data

bm = bmesh.from_edit_mesh(me)

# Ensure custom data exists.
bm.verts.layers.deform.verify()

deform = bm.verts.layers.deform.active

for v in bm.verts:
    g = v[deform]
    # First & second vertex group (by index)
    g[0] = 0.5
    g[1] = 0.75

    # Print the weights
    print(g.items())
1 Like

Oh so they are stored in deform layers? For some reason I had assumed that layer had something to do with morph targets or something along those lines. Thanks for pointing me in the right direction, this helps a ton!

IMO, the API doc is not very clear on how to use BMesh custom layer data. I’d really appreciate some clarification and further explanation in the documentation – I tried to figure this out for myself a while back and just couldn’t do it! Thanks. Now I have a reference if I ever need this in the future.

The examples on accessing UVs are the most complete, and once you understand UVs the rest is fairly self explanatory (except in situations where the layer name does not correlate with the actual thing it’s storing, ie deform layer holding vertex groups heh). What’s not entirely clear to me is why some data is stored in some elements but not others. IE, vertex colors are stored in loops, not verts… but vertex groups are stored in verts, not loops! UVs make sense, because you could have more than one uv coordinate per very if it’s on a seam.

As for vertex colors specifically, they are more attributed to faces than vertices. Them being stored in loops allows each face to have a unique, solid color. This wouldn’t be possible if vertex colors were stored per vertex (it would just be a gradual color transition between verts like weight painting) :slight_smile:

Ah okay that does make sense