6

I wonder what is the quickest way to remove vertex groups in which all vertices have zero weight.

Currently I got nearly 100 groups listed there after days of hard working, and I'm sure some of them are completely zero-weight groups and should definitely be removed, but it seems not so easy to quickly locate and remove them all.

Duarte Farrajota Ramos
  • 59,425
  • 39
  • 130
  • 187
Leon Cheung
  • 27,718
  • 11
  • 89
  • 161

4 Answers4

10

This python snippet should work if you paste it into a Text Editor's new buffer and click Run Script.

import bpy

def survey(obj):
    maxWeight = {}
    for i in obj.vertex_groups:
        maxWeight[i.index] = 0

    for v in obj.data.vertices:
        for g in v.groups:
            gn = g.group
            w = obj.vertex_groups[g.group].weight(v.index)
            if (maxWeight.get(gn) is None or w>maxWeight[gn]):
                maxWeight[gn] = w
    return maxWeight

obj = bpy.context.active_object
maxWeight = survey(obj)
# fix bug pointed out by user2859
ka = []
ka.extend(maxWeight.keys())
ka.sort(key=lambda gn: -gn)
print (ka)
for gn in ka:
    if maxWeight[gn]<=0:
        print ("delete %d"%gn)
        obj.vertex_groups.remove(obj.vertex_groups[gn]) # actually remove the group
Mutant Bob
  • 9,243
  • 2
  • 29
  • 55
7

Just realized lately that we actually ignored one weight tool off the shelf - Clean.

You can simply click it then use the default Limit value 0.000. Done.

enter image description here

Leon Cheung
  • 27,718
  • 11
  • 89
  • 161
  • Note that it may not exactly solve the question, specifically, but might be useful for others who get smilar problem. – Leon Cheung Feb 02 '16 at 05:51
  • 1
    If you are having trouble cleaning, set the limit to 1.0, it only worked for me when I did it like this. – Renato May 19 '18 at 21:05
1

This version is: Delete all empty vertex_groups for all selected objects

import bpy

def del_empty_vgroup(obj): try: vertex_groups = obj.vertex_groups groups = {r : None for r in range(len(vertex_groups))}

    for vert in obj.data.vertices:
        for vg in vert.groups:
            i = vg.group
            if i in groups:
                del groups[i]

    lis = [k for k in groups]
    lis.sort(reverse=True)
    for i in lis:
        vertex_groups.remove(vertex_groups[i])
except:
    pass

for obj in bpy.context.selected_objects: del_empty_vgroup(obj)

X Y
  • 5,234
  • 1
  • 6
  • 20
0

This is a modification of CoDEmanX's code that doesn't delete mirror vertex groups, *.R vertex group has the info and *.L is empty, useful for objects with mirror modifier and armature deformation, use in the Text Editor https://github.com/sambler/myblendercontrib/blob/master/remove_unused_vertexGroups.py

import bpy
import re

ob = bpy.context.active_object
ob.update_from_editmode()

vgroup_used = {i: False for i, k in enumerate(ob.vertex_groups)}
vgroup_names = {i: k.name for i, k in enumerate(ob.vertex_groups)}

for v in ob.data.vertices:
    for g in v.groups:
        if g.weight > 0.0:
            vgroup_used[g.group] = True
            vgroup_name = vgroup_names[g.group]
            armatch = re.search('((.R|.L)(.(\d){1,}){0,1})(?!.)', vgroup_name)
            if armatch != None:
                tag = armatch.group()
                mirror_tag =  tag.replace(".R", ".L") if armatch.group(2) == ".R" else tag.replace(".L", ".R") 
                mirror_vgname = vgroup_name.replace(tag, mirror_tag)
                for i, name in sorted(vgroup_names.items(), reverse=True):
                    if mirror_vgname == name:
                        vgroup_used[i] = True
                        break
for i, used in sorted(vgroup_used.items(), reverse=True):
    if not used:
        ob.vertex_groups.remove(ob.vertex_groups[i])
Iszotic
  • 482
  • 5
  • 10