6

I am working with a makehuman model in blender. To change the pose of the model I modify the scale and rotation parameters of the bones. The code looks similar to

bpy.context.object.pose.bones['hand.fk.R'].rotation_euler[0] = 0

My goal is now to get the location of a specific vertex after some pose changes. I already tried to transform the vertex location with the object world matrix

bpy.data.objects['makehuman'].matrix_world * v.co

but since the world matrix is an identity matrix the result is the same independent from the current pose.

How can I derive the vertex location after a pose change, or is it even possible?

stacker
  • 38,549
  • 31
  • 141
  • 243
Masala
  • 335
  • 3
  • 10

1 Answers1

6

You can use Object.to_mesh() to create a mesh datablock, which has deformations and modifiers applied. Mesh.transform() that with .matrix_world for world space:

import bpy

C = bpy.context
ob = C.object

print(ob.data.vertices[0].co, "- Vert 0 (original)")

me = ob.to_mesh(scene=C.scene, apply_modifiers=True, settings='PREVIEW')
print(me.vertices[0].co, " - Vert 0 (deformed/modified)")

me.transform(ob.matrix_world)
print(me.vertices[0].co, " - Vert 0 (deformed/modified, world space)")

bpy.data.meshes.remove(me)

Note that vertex indices may differ after modifiers are applied (e.g. Array, Bevel, ...).

Alternatively, the bmesh module can be used to achieve the same as the above script.

CodeManX
  • 29,298
  • 3
  • 89
  • 128
  • When the indices differ, how can i get the coordinated of a transformed vertex. I tried the above code, and if the vertex is unchanged, the index stays also the same, but in the other case i don't know how to derive the old vertex? – Masala Oct 22 '13 at 13:03
  • I haven't thought about this issue before, actually. With standard API, you could turn off the show_viewport of all modifiers temporarily, except the Armature modifier. to_mesh() will respect it. Obviously same problem with bmesh module. Maybe anyone else knows a good solution. It's not a problem however, as long as you don't use any fancy modifers on your posed meshed. – CodeManX Oct 22 '13 at 13:17
  • As far as I can say, I don't use any modifier on my posed mesh (if you mean the mesh from ob.to_mesh). However, I am new to blender, and I don't understand what you mean with turn off the show_viewport and how this could solve my problem? – Masala Oct 22 '13 at 14:23
  • Armature is a modifier (and an object type), so you need to apply modifiers with to_mesh(). If there's no modifier on your posed object other than the Armature modifier, access via index should be fine. If there are any other modifiers, you could temporarily turn them off in viewport (in python, by setting the .show_viewport property of each modifier), then use to_mesh(). Here is a code example – CodeManX Oct 22 '13 at 17:32
  • Ok, now it works. The problem was, that I had to update the scene, before your code. Thanks for your help. – Masala Oct 23 '13 at 06:05
  • What do you mean by "Alternatively, the bmesh module can be used to achieve the same as the above script.". Could be a little more specific? – ther Mar 10 '15 at 14:18
  • The Bmesh module offers the same capabilities AFAIK: bm = bmesh.new(); bm.from_object(..., deform=True); bm.transform(...) – CodeManX Mar 10 '15 at 17:34
  • I am new to blender and I have no idea what you just said. However, I would like to try it. I am assuming it has something to do with the python console, but what must I do apply this in blender? – user3677758 Oct 27 '16 at 19:07