Location of vertices in a bone's vertex group

Hello,

Currently I have an animated model with bones and their corresponding vertex groups. I am trying to track the location of each vertex in all the vertex groups as the animation steps through. My first solution:


ob = bpy.data.objects["running-01"]
vertex_loc = ob.matrix_world * my_vertex.co

does not work because both ob.matrix_world and my_vertex.co stay constant for all frames.

I needed to group the vertices of the object into their respective vertex group, so I used this code, which works.


# Dictionary mapping vertex group index to its name
group_lookup = {g.index: g.name for g in ob.vertex_groups}

# Dictionary mapping vertex group names to the indicies of vertices that make
# up the group.
verts = {name: [] for name in group_lookup.values()}

# Go through each vertex and see what group it is a part of.
for v in ob.data.vertices:
   for g in v.groups:
       verts[group_lookup[g.group]].append(v.index)

I have then tried to get the pose bone matrix and do something like this to get the proper location of the vertex at each frame:


my_vertex = ob.data.vertices[verts["Head"][0]]
vertex_loc = ob.matrix_world * bpy.data.objects["running-01"].pose.bones["Head"].matrix * my_vertex.co

However, this too does not work; the vertex_loc changes (because the PoseBone matrix changes) but it is at an incorrect position.

Is there a different matrix I should be using to do perform this task? I have also tried multiplying the parent matrices as well and still did not get the correct location.

Instead of doing the calculation yourself, you can use the to_mesh method of your object, which will return a mesh data_block with all the modifiers applied. You can then explore the data of this object in order to get the modified positions. One important thing : as long as your modifiers doesn’t change the topology of your mesh (like a subdivision surface), the vertex indices should remain the same.


mesh_data = ob.to_mesh(bpy.context.scene, True, 'PREVIEW')
my_vertex = mesh_data.vertices[verts["Head"][0]]
vertex_loc = my_vertex.co

This worked very well! Thank you!