4
$\begingroup$

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.

$\endgroup$
7
$\begingroup$

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
$\endgroup$
  • 1
    $\begingroup$ 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. $\endgroup$ – user2859 Oct 7 '14 at 23:27
  • $\begingroup$ Thanks. But like Mutant Bob said, it doesn't work very well. $\endgroup$ – Leon Cheung Oct 8 '14 at 1:39
  • $\begingroup$ @LeonCheung Just curious, as I think I must be blind.. Where did Mutant Bob say that? $\endgroup$ – gandalf3 Oct 8 '14 at 1:59
  • 1
    $\begingroup$ @gandalf3 Oops, I really mean user2859. :P $\endgroup$ – Leon Cheung Oct 8 '14 at 2:06
  • 1
    $\begingroup$ @LeonCheung if the example isn't working, here is another variant $\endgroup$ – user2859 Oct 8 '14 at 22:47
6
$\begingroup$

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

$\endgroup$
  • $\begingroup$ Note that it may not exactly solve the question, specifically, but might be useful for others who get smilar problem. $\endgroup$ – Leon Cheung Feb 2 '16 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$ – Renato May 19 '18 at 21:05
0
$\begingroup$

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])
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.