How to BMesh select vertex group and delete only edges

Hi,
I have tried to find example code but noting works the way I need it to do. What I am trying to do is to get select only vertex group on my mesh and delete “only edges”. Here what I have so far and I’m stuck for a while mainly because I don’t know almost nothing about BMesh. This isn’t working script. Maybe Its not even possible delete only edges and maybe its only possible with operators, I’m trying to achieve it this way because its faster.

# Not sure about this line
bm.verts.layers.deform.verify()

# deform is active layer
deform = bm.verts.layers.deform.active

# select each vert in verts if vert is in deform layer and in vertex group index 0
edges_select = [v[deform] for v in bm.verts if v[deform][0] == 1]

# Delete edges (I need only edges but not sure which context is that)
bmesh.ops.delete(bm, geom=edges_select, context=2)

# Update
bmesh.update_edit_mesh(me, True)

when you post things like this, it’s always helpful if you tell us exactly what is failing so we don’t have to guess. IE) what your error message is, what the unexpected behavior is, etc.

With that out of the way- you’ve got a few problems, actually. first you’re assuming that only a single vertex group can exist on any given vertex- that is incorrect. v[deform][0] will return a tuple, because v[deform] is a list of tuples. If you have multiple vertex groups, a vert could be in any number of these, hence the list. Second problem is that you’re giving bmesh.ops.delete a context of 2 which doesn’t mean anything. context is an enum expecting a string, so you need to pass it “EDGES” or “VERTS” or whatever.

FYI: the verify() function will create the vert data layer if it doesn’t already exist. if you already know the vertex group exists you can safely skip it but there’s no harm in keeping it.

import bpy, bmesh

obj = bpy.context.active_object
bm = bmesh.from_edit_mesh(obj.data)

bm.verts.layers.deform.verify()

deform = bm.verts.layers.deform.active

verts_select = set()

for v in bm.verts:
    for group in v[deform].items():
        group_index, weight = group
        if group_index == 0:
            verts_select.add(v)

bmesh.ops.delete(bm, geom=list(verts_select), context="VERTS")

bmesh.update_edit_mesh(obj.data, destructive=True)
1 Like

I guess I tried to explain what I’m trying to do and then comment out code so you can see where I am going. I’ll try to ask better question next time. I understand importance of that.

Ok so now I understand that “layers.deform” are actually vertex groups. Im reading from this: https://docs.blender.org/api/blender_python_api_current/bmesh.html#customdata-access
and now it makes more sense what is layer and where are stored groups, uv and shape key data for mesh, for that bmesh face, edge or vert actually.

Can you please explain why is “verts_select” filled as set and then converted to list?

A set can only contain unique items, and bmesh ops will fail if geom has an element that appears more than once. Converting a set to a list is faster than using a conditional, but that would also work.

1 Like

Ok so I couldn’t make it work as I wanted initially. As I have suspected it is not even possible that way, but it can be done with operators. Here is what I needed but with bmesh because I’m already doing operations on data with bmesh.

import bpy

# Mesh needs to be in edit mode
bpy.ops.object.editmode_toggle()

# Select vertex group called 'Delete', needs to be active first
bpy.ops.object.vertex_group_set_active(group='Delete')
bpy.ops.object.vertex_group_select()

# Dissolve edges, not possible with bmesh.ops.delete
# it kinda makes sense because dissolve is
# probably higher function which uses delete to achieve dissolve result
bpy.ops.mesh.dissolve_edges()

bpy.ops.object.editmode_toggle()

It’s true, you can’t use bmesh.ops.delete to dissolve edges. that’s what bmesh.ops.dissolve_edges is for.

2 Likes