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.
3 Answers
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
-
1$\begingroup$ The last line contains a bug though. When it removes from
vertex_groups
the index changes, which might lead to anIndexError
s or even deleting the wrong groups. $\endgroup$– user2859Oct 7, 2014 at 23:27 -
$\begingroup$ Thanks. But like Mutant Bob said, it doesn't work very well. $\endgroup$ Oct 8, 2014 at 1:39
-
$\begingroup$ @LeonCheung Just curious, as I think I must be blind.. Where did Mutant Bob say that? $\endgroup$– gandalf3 ♦Oct 8, 2014 at 1:59
-
1$\begingroup$ @gandalf3 Oops, I really mean user2859. :P $\endgroup$ Oct 8, 2014 at 2:06
-
1
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.
-
$\begingroup$ Note that it may not exactly solve the question, specifically, but might be useful for others who get smilar problem. $\endgroup$ Feb 2, 2016 at 5:51
-
1$\begingroup$ If you are having trouble cleaning, set the limit to 1.0, it only worked for me when I did it like this. $\endgroup$– RenatoMay 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])