# How to quickly remove all zero-weight vertex groups?

I wonder what is the quickest way to remove vertex groups in which all vetices 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.

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

• The last line contains a bug though. When it removes from vertex_groups the index changes, which might lead to an IndexErrors or even deleting the wrong groups. Oct 7, 2014 at 23:27
• Thanks. But like Mutant Bob said, it doesn't work very well. Oct 8, 2014 at 1:39
• @LeonCheung Just curious, as I think I must be blind.. Where did Mutant Bob say that?
– gandalf3
Oct 8, 2014 at 1:59
• @gandalf3 Oops, I really mean user2859. :P Oct 8, 2014 at 2:06
• @LeonCheung if the example isn't working, here is another variant Oct 8, 2014 at 22:47

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.

• Note that it may not exactly solve the question, specifically, but might be useful for others who get smilar problem. Feb 2, 2016 at 5:51
• If you are having trouble cleaning, set the limit to 1.0, it only worked for me when I did it like this. May 19, 2018 at 21:05

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])