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
scene.objects.link(copy)
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.
Thank you in advance