0
$\begingroup$

I have an armature with a hierarchy of bones animated in a specific manner. The animation is obtained with use of EasyMocap and Python. My goal is to import individual meshes that resemble bones (like "Pelvis", "thigh_L", "thigh_R", etc.) from another .blend file and ensure that each mesh follows the respective bone's animation from the armature.

Armature Hierarchy: The root bone is m_avg_root which has a child m_avg_Pelvis. From m_avg_Pelvis, there are three children: m_avg_L_Hip, m_avg_R_Hip, and m_avg_Spine1. Each of these bones has its respective hierarchy, creating a structure that resembles a humanoid skeleton.

Mesh Structure: The meshes are individual objects without any hierarchy, and they represent bones in the human body. Examples include "Elbow.L", "foot_L", "Hand.R", "Head", "Pelvis", and so on.

Problem: I tried to use a script to automatically assign vertex groups to these meshes and then use the "Armature" modifier to bind them to the respective bones. However, instead of following the movements of their respective bones, the meshes are circling around the armature in an erratic manner.

To further describe the behavior: from a top view, the meshes orbit around the armature according to its rotation, maintaining a consistent distance that seems to match the distance of m_avg_root from the center of the armature.

Additionally, while trying to fix the issue, I noticed that each bone in the modifier has its parent set to "0" and its "parent bone" set as m_avg_root, with "parent type" set as "bone". I'm unsure if this is the intended configuration.

How can I correctly bind each mesh to follow its corresponding bone in the armature?

This is the script I use:

    import bpy

filepath = r"C:\Users\[..]\bones.blend"

object_list = ["Elbow.L", "Elbow.R", "foot_L", "foot_R", "Hand.L", "Hand.R", 
               "Head", "leg_L", "leg_R", "Neck", "Pelvis", "ribcage", 
               "Shoulder.L", "Shoulder.R", "thigh_L", "thigh_R"]

for object_name in object_list:

    with bpy.data.libraries.load(filepath) as (data_from, data_to):
        data_to.objects = [name for name in data_from.objects if name == object_name]

   
    for obj in data_to.objects:
        if obj is not None:
            bpy.context.collection.objects.link(obj)
            

bones_and_meshes = {
    "m_avg_Pelvis": "Pelvis",
    "m_avg_L_Hip": "thigh_L",
    "m_avg_L_Knee": "leg_L",
    "m_avg_L_Ankle": "foot_L",
    "m_avg_R_Hip": "thigh_R",
    "m_avg_R_Knee": "leg_R",
    "m_avg_R_Ankle": "foot_R",
    "m_avg_Spine1": "ribcage",
    "m_avg_Spine2": "ribcage",
    "m_avg_Spine3": "ribcage",
    "m_avg_Neck": "Neck",
    "m_avg_Head": "Head",
    "m_avg_L_Collar": "Shoulder.L",
    "m_avg_L_Shoulder": "Shoulder.L",
    "m_avg_L_Elbow": "Elbow.L",
    "m_avg_L_Wrist": "Hand.L",
    "m_avg_R_Collar": "Shoulder.R",
    "m_avg_R_Shoulder": "Shoulder.R",
    "m_avg_R_Elbow": "Elbow.R",
    "m_avg_R_Wrist": "Hand.R"
}


bone_list = list(bones_and_meshes.keys())


for bone_name in bone_list:


    with bpy.data.libraries.load(filepath) as (data_from, data_to):
        data_to.objects = [name for name in data_from.objects if name == bone_name]

   
    for obj in data_to.objects:
        if obj is not None:
            bpy.context.collection.objects.link(obj)
   
            mesh = bpy.data.objects[bones_and_meshes[obj.name]]
     
            mesh.location = (0,0,0)
 
            mesh.rotation_euler = (0,0,0)
   
            mesh.parent = obj
   
            mesh.parent_type = 'BONE'
   
            mesh.parent_bone = obj.name
            

def create_vertex_group(obj, name):
    if obj.type != 'MESH':
        return

    if name not in obj.vertex_groups:
        obj.vertex_groups.new(name=name)

    return obj.vertex_groups[name]


bone_mesh_map = {
    'Pelvis': 'm_avg_Pelvis',
    'thigh_L': 'm_avg_L_Hip',
    'leg_L': 'm_avg_L_Knee',
    'foot_L': 'm_avg_L_Ankle',
    'thigh_R': 'm_avg_R_Hip',
    'leg_R': 'm_avg_R_Knee',
    'foot_R': 'm_avg_R_Ankle',
    'ribcage': ['m_avg_Spine1', 'm_avg_Spine2', 'm_avg_Spine3'],
    'Neck': 'm_avg_Neck',
    'Head': 'm_avg_Head',
    'Shoulder.L': ['m_avg_L_Collar', 'm_avg_L_Shoulder'],
    'Elbow.L': 'm_avg_L_Elbow',
    'Hand.L': 'm_avg_L_Wrist',
    'Shoulder.R': ['m_avg_R_Collar', 'm_avg_R_Shoulder'],
    'Elbow.R': 'm_avg_R_Elbow',
    'Hand.R': 'm_avg_R_Wrist'
}


armature = bpy.context.scene.objects['0']


for mesh_name, bone_names in bone_mesh_map.items():
    
    if not isinstance(bone_names, list):
        bone_names = [bone_names]

    mesh = bpy.context.scene.objects[mesh_name]


    for bone_name in bone_names:

        vg = create_vertex_group(mesh, bone_name)
      
        vg.add([v.index for v in mesh.data.vertices], 1.0, 'ADD')


    mesh.parent = armature

    mesh.parent_type = 'ARMATURE'

bpy.context.view_layer.update()

How it looks

$\endgroup$

0

You must log in to answer this question.

Browse other questions tagged .