I’m working on a Blender add-on, and so far I could do everything and I’ve found answer to all my questions in the docs. Thank you all for this wonderful software and awesome documentation! But now it seems I’m unable to figure out on my own how to access armature data properly.
What I would need is, a list of bones, position+rotation quaternion pairs, in Cartesian coordinate system (right handed, +Y up, +X right, +Z front), where the root bone is in model space, but sub bones are relative to their parents. Can someone help me how to achieve this?
I’ve commented out all axis or other transformations (no more global_matrix and parent inverse matrix_local multiplications) and saved the data as they appear in blender’s bpy.
As you can see, some bones are correct, while others not. This is very confusing. Do I have to do some kind of “to model space” transformation on the bpy data manually in python? I assumed they are all in the same space (whatever that space is, model or world), isn’t that so? Can anyone please explain it to me, what’s going on, how could bone’s alignments differ?
Please advice, I really could use some help with this.
bzt
Okay, how to get data Z up as shown on the UI from bpy? It returns neither the mesh nor the bones as Z up, and that’s the reason why axis_conversion(from_forward='-Y', from_up='Z',to_forward='Z', to_up='Y') doesn’t work for me.
Using mesh.transform(global_matrix @ object.matrix_world) fixes it for the mesh, but then obviously the mesh and the armature isn’t aligned any more.
What should I do so that both the armature and mesh would return Z up coordinates from bpy, just as seen on the UI? (And then I could use axis_conversion consistently on both.)
Figured it out. Yes, blender suxx big time, just as I’ve suspected you must do a “to model space” conversion manually to actually get what you see on the UI… Otherwise the queried armature and mesh won’t align with each other.
For the bones:
for i,ob_main in enumerate(objects):
if ob_main.type != "ARMATURE":
continue
for b in ob_main.data.bones:
# this is armature's matrix_world
m = ob_main.matrix_world @ b.matrix_local
# now m is the translation matrix of the bone in model-space
And for the mesh:
for i, ob_main in enumerate(objects):
if ob_main.type != "MESH":
continue
# you must apply modifiers manually too, and use the object's matrix_world
o = ob_main.evaluated_get(depsgraph)
mesh = o.to_mesh()
mesh.transform(ob_main.matrix_world)
# now mesh.vertices[x].co contains model-space coordinates