← All ideas
  • Published 25 Mar 2023

Remove Empty Vertex Groups option in the Vertex Group Specials Menu (code and video below)

I think we should add a button to the Vertex Groups > Vertex Group Specials menu, which removes any groups that contain no vertex points, or a very minor amount (i.e. < 0.1)

I've coded a sample which people are free to use, scrutinize and improve (I've only been coding for three months, so my apologies for the low level of coding).

This will be useful for people using auto rigging addons like Rigify and AutoRigPro, when your character is made up of several pieces.

For example, Rigify comes with 160 Vertex Groups. If you're rigging Mario, and you parent his hat to the Rigify armature, all 160 Vertex Groups will be added to his hat, when you may only want 1 group (i.e. spine.006). This new button would remove any empty vertex groups or any vertex groups having a very minor influence.

For a Vertex Group to qualify and avoid the cull, it would need to contain a vertex point with a weight value above 0.1, but I think we could improve this function by having a floating menu appear, where the user can set their own threshold.

I'll paste the code below. I've also included a quick video of it in action.

Would love to hear what people here think.

Best

Gary

Video: vimeo.com/811549292/3c49cd3d1f

Code:

import bpy

#This is the operator and where you type the functions def my_operator(): #1. MAKE A GROUP LIST FOR average_weight

def make_group_list():
    obj = []
    temp_list = []
    group_list = []
    so = bpy.context.selected_objects
    for i in so:
        obj.append(i)
        for i in obj:
            #I've used .extend here (with square brackets) to add every item to the list
            temp_list.extend([group[0] for group in i.vertex_groups.items()])
            for group_name in temp_list:
                if group_name not in group_list:
                    group_list.append(group_name)
    return group_list


#2. CHECK THE AVERAGE WEIGHT OF EACH VERTEX POINT
def average_weight(vertex_group_names, obj):
    mesh = obj.data
    for vertex in mesh.vertices:
        for group in vertex.groups:
            if group.group in vertex_group_names and group.weight > 0.1:
                return False
    return True


#3. DELETE THE GROUP
def delete_group(obj, vertex_group):
    obj.vertex_groups.remove(vertex_group)

# GROUP_LIST DEFINED
group_list = make_group_list()

#4. MAIN FOR LOOP
for obj in bpy.context.selected_objects: 
    for vertex_group_name in group_list:
        vertex_group = obj.vertex_groups.get(vertex_group_name)
        if vertex_group is not None:
            if average_weight([vertex_group.index], obj):
                delete_group(obj,vertex_group)


#This is the class, where you define the button

class RemoveEmptyGroupsOperator(bpy.types.Operator): bl_idname = "object.remove_empty_groups_operator" bl_label = "Remove Empty Groups"

#This just says, when the button defined above is clicked, it'll run the code def execute(self, context): my_operator() return {'FINISHED'}

#This add the button to the menu def add_to_vertex_group_specials_menu(self, context): self.layout.operator("object.remove_empty_groups_operator")

#Add the operator to the vertex group specials menu bpy.types.MESH_MT_vertex_group_context_menu.append(add_to_vertex_group_specials_menu)

#This registers the entire thing

def register(): bpy.utils.register_class(RemoveEmptyGroupsOperator)

def unregister(): bpy.utils.unregister_class(RemoveEmptyGroupsOperator)

if name == " main ": register()

100%

Development Status: Open

Upvote 5 Downvote 0
garycarse
25 Mar 2023

1 Comment

Epicrex

We need this, especially an option to do this at once for every selected object. Under the "Object > Clean Up" menu would be a great location.