How to get coordinates of special vertices in an animated mesh with Python?

I try to get the positions of special vertices while animating. I only found quastions about positions of special vertices in one frame or positions of all vertices in an animation. But I need the combination.

My animation bases on a MakeHuman object (created with skeleton: default no toes and randomized via Modeling-> Random: Randomize, exported as mhx2 with options feet on ground, expressions, poses and in meter).

Import with MHX2 Runtime:

bpy.ops.import_scene.makehuman_mhx2(filter_glob="*.mhx2", filepath=link, useHelpers=False, useOffset=True, useOverride=True, useCustomShapes=True, useFaceShapes=True, useFaceShapeDrivers=True, useFaceRigDrivers=True, useRig=True, useRotationLimits=True, useDeflector=False, useHairDynamics=False, useHairOnProxy=False, useConservativeMasks=True, useSubsurf=False, useMasks='MODIFIER', useHumanType='BOTH', mergeBodyParts=False, rigType='EXPORTED', genitalia='NONE', hairType='NONE')


My animations bases on moving a bone and in changing facial shapes. I do not add shapekeys for every frame. I want to see the process of moving in my frames, but I need coordinates of a few special vertices for each frame.

My final goal is to get a bounding box around the face. If the object moves head to see the stars, I want the bottom line of bounding box directly under the chin. This is the reason I need the coordinates of some specific vertices. The lowest z-value is my buttom z-value for my bounding box. If you already have a script with pixel coordinates this is fine also. If there is another, better way than the coordinates of vertices, please also comment.

Here first of all my experiences:

My problem is that coordinates of vertices do not change over frames. If I add a new mesh with the animations, the IDs of vertices change. I searched for special indices with bpy.app.debug = True and in properties “Mesh display”: Indices

I tried several ways:

First way: direct request: coordinates do not change

import bmesh
import bpy

obj = bpy.context.active_object
for f in range(0, 51):
bpy.context.scene.frame_set(f)
mesh = obj.data
print(mesh.vertices[5554].co)


Second way: create new meshes in object mode (package bmesh) (source: Lofting: can I copy a Shape-Keyed mesh for each frame of its animation?)

import bmesh
import bpy

bm = bmesh.new()
bpy.app.debug = True  # indices can be switched on
obj = bpy.data.objects["human:Body"]
me=ob.data
for f in range(0, 51):
bpy.context.scene.frame_set(f)

bm.from_object(ob, scene)
rme=bpy.data.meshes.new("Rib")
bm.to_mesh(rme)

copy = bpy.data.objects.new("Rib", rme)
copy.matrix_world = ob.matrix_world
mesh=rme

print(mesh.vertices[5554].co)

bm.clear()  # interesting without.
bpy.ops.object.select_all(action='DESELECT')
copy.select = True
for child in copy.children:
child.select = True
bpy.ops.object.delete()


I also tried the “EDIT” mode version with:

import bpy

bpy.data.scenes['Scene'].frame_set(0)
hum_body = bpy.data.objects["human:Body"]
hum_body.select = True
bpy.ops.object.set_object_mode(mode="EDIT")
bm = bmesh.from_edit_mesh(hum_body.data)
bmesh.update_edit_mesh(hum_body.data)  # with and without this

for f in range(0, 51):
bpy.context.scene.frame_set(f)
print(bm.verts[5554].co)


Problem: IDs of vertices change in Ribs. I also tried the IDs in the new Rib, but they are not the same for different MakeHuman objects. I need a possibility that works for all objects (I want to move over several objects in a loop).

Third way: Like second way but without bmesh (source: Vertex coordinate after pose change and Iterating vertex of every frame in Blender)

import bpy

obj = bpy.context.active_object
scn = bpy.context.scene

mod_mesh = obj.to_mesh(scn, True, 'RENDER')
for f in range(0, 51):
bpy.context.scene.frame_set(f)
bpy.context.scene.update()
print(mod_mesh.vertices[5554].co)

bpy.data.meshes.remove(mod_mesh)


I have to admit that I did not understand CoDEmanX hint in the comments to not change the IDs (Vertex coordinate after pose change)

Fourth way:

Set vertex as parent for empty. Because position of vertex does not change, position of empty is not affected.

By selecting

hum_boday.modifiers["ARMATURE"].show_in_editmode = True


and

hum_body. modifiers["ARMATURE"].show_on_cage = True


the mesh is also moves in EDIT-mode. But I can not see a difference for my positions.

My blender Version is 2.79. If you need a .blend file as minimal example, please explain how to add one.