Armature generator based on vertex groups (addon)

Hello!

Intro

I was working on a new addon in blender wich will generate an armature that its bones names are the same with name of vertex groups of object and in they are placed in the positions of the heaviest weight in each vertex groups.
Be aware, I used AI and it helped me in so many parts, so it is kind of NOT completely done by me.

Why this addon?

Because sometimes you may download a model that is not rigged but it has very nice vertex groups. As the number of vertex groups are too much, it takes forever to create a rig manually. So this addon does it for you! you select your object and press a button and boom! you got your armature, just parent your object using “Armature Deform” and you are done with rigging it.

I need help

I have made it but it has a problem!
The bones are not at the positions they should be.
For example:


In this image, you can see all of the bones take place around the head, which should take place all over the body, not just head (my model has face bones).

This is the code I wrote:

import bpy
from mathutils import Vector

class OBJECT_OT_create_bones(bpy.types.Operator):
    bl_idname = "object.create_bones"
    bl_label = "Create Bones"
    bl_description = "Create bones with names the same as vertex groups of an object and in the positions of the heaviest weight in vertex groups"
    bl_options = {'REGISTER', 'UNDO'}

    def execute(self, context):
        obj = context.active_object
        if obj is None:
            self.report({'ERROR'}, "No active object")
            return {'CANCELLED'}

        # Put the armature object in edit mode
        arm_obj = bpy.data.objects.new(obj.name + "_armature", bpy.data.armatures.new(obj.name + "_armature"))
        context.scene.collection.objects.link(arm_obj)
        context.view_layer.objects.active = arm_obj
        bpy.ops.object.mode_set(mode='EDIT')

        # Create the bones
        for vg in obj.vertex_groups:
            bone_name = vg.name
            bone = arm_obj.data.edit_bones.new(bone_name)
            bone.head = obj.matrix_world @ obj.data.vertices[vg.index].co
            bone.tail = bone.head + Vector((0, 0, 1))

        # Put the armature object back in object mode
        bpy.ops.object.mode_set(mode='OBJECT')

        return {'FINISHED'}

class VIEW3D_PT_create_bones_panel(bpy.types.Panel):
    bl_label = "Create Bones"
    bl_idname = "VIEW3D_PT_create_bones_panel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "Create Bones"

    def draw(self, context):
        layout = self.layout

        row = layout.row()
        row.label(text="Create Bones:")
        row.operator("object.create_bones", text="Create Bones")

def register():
    bpy.utils.register_class(OBJECT_OT_create_bones)
    bpy.utils.register_class(VIEW3D_PT_create_bones_panel)

def unregister():
    bpy.utils.unregister_class(OBJECT_OT_create_bones)
    bpy.utils.unregister_class(VIEW3D_PT_create_bones_panel)

if __name__ == "__main__":
    register() 

How can I fix this? Can someone help?

This line does not put the bone in the location of the heaviest weight.

vg.index is just the index of the vertex group. So if you have 10 vertex groups index will be 0 for the first one and 9 for the last. So this will put the bones in the positions of the first 10 vertices of the model.
You’d need to iterate over the vertex group to find the heaviest weight, and then look up the vertex corresponding to that.

That’s the disadvantage of using AI. You don’t really know what you’re doing. You can use the AI to create the code for you. But then you must go through it and understand what each part does or the chances of generating nonsense are quite high.

I’m not sure people on this forum are willing to fix A.I. generated code for someone who does not understand the code by him/herself…

4 Likes

Exactly you’re right, I changed the code 6 times myself before I post it here.

Uh, well I am a bit new to python, it’s about a year I’m working with it so I may sometimes need help. Thanks for understanding :))

So, for each vertex group, I need to check for the vertex that the maximum weight of all vertices in the vertex group is assigned to, right?

Thanks for help

Getting assistance on modifying broken code written by AI isn’t within the scope of this forum.