1
$\begingroup$

So I'm very new to Blender, and I've downloaded a 3D model consisting of a mesh and an armature. I'd like to write the data needed to pose the model via linear blend skinning (namely its rest pose joint transforms, rest pose vertex positions, and blend skinning weights) to some file format that I can access in python (such as a .h5 or .npy file) for use in some computer vision work I'm doing. While saving the joint transforms and vertex positions via scripting was pretty straightforward, I have no idea how to access the model's blend skinning weights (which are bound by vertex group). Is there any way to access the blend skinning weights of a model as a $V \times J$ matrix, where $V$ is the number of vertices in the mesh and $J$ is the number of joints in the armature? Thanks.

$\endgroup$

1 Answer 1

2
$\begingroup$

After a bit of digging, I was able to adapt a solution based on this forum post. Here's the code in case anyone else finds it helpful:

def get_skinning_weights():
    ## create the dict for the groups attache the index to the name
    obj = bpy.context.active_object

    # get the names of the bones in the armature associated with the object
    for modifier in obj.modifiers:
        if modifier.type == 'ARMATURE':
            armature = modifier.object.data
            armature_bones = {bone.name for bone in armature.bones}
            break
        
    # get the mapping from group indices to bones
    group_to_bone = {i: group.name for i, group in enumerate(obj.vertex_groups)}
    
    # determine the bone weights associated with each vertex
    mesh = obj.data
    for vertex in mesh.vertices: ##in each vertex of the mesh
        print('Vertex', vertex.index)
        for group in vertex.groups: #first loop to calculate the total weight and the space allowed if some are locked
            group_index = group.group
            group_bone = group_to_bone[group_index]
            if group_bone in armature_bones: ##if it's a bone
                print('\t', group_bone, group.weight)
            else:
                print('\t', 'NOT A BONE:', group_bone, group.weight)
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .