Problem with matrix_parent_inverse of childs of bones I am trying to move around objects by manipulating their transformation matrices with Python. If the objects are in a parent/child hierarchy you have to step down this hierarchy using the object's matrix_parent_inverse element. My code works fine with one exception: In case an object is a child of an armature's bone the child has a matrix_parent_inverse I do not understand.

Say, we have a cube as child of a cone as child of a cylinder, i. e. the hierarchy cube -> cone -> cylinder. bpy.data.objects["Cube"].matrix_parent_inverse gives me the inverse matrix of the cone at the time of parenting. Fine.

Now we have the same situation (at least in my opinion) when the cube is the child of a bone. The hierarchy is in this case cube -> bone -> armature. bpy.data.objects["Cube"].matrix_parent_inverse should give the same result as in the first situation but it does not. So my question is: What is the meaning of matrix_parent_inverse in this case or how can I get the correct one?

Sample code showing the different results (Blender 2.71):

import bpy

#------------------------------------------------------
# Make a parent hierarchy
# cube -&gt; cone -&gt; cylinder
# "-&gt;" means "is child of"
#------------------------------------------------------

# Delete the scene:
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()

# Create a cylinder at location (2, 3, 4):
bpy.ops.mesh.primitive_cylinder_add(location=(2, 3, 4))

# Create a cone and make it the cylinder's child at the same position:
bpy.ops.mesh.primitive_cone_add(location=(2, 3, 4))
bpy.context.scene.objects.active = bpy.data.objects["Cylinder"]
bpy.ops.object.parent_set(type='OBJECT')

# Create a cube at (0, 0, 0) and make it the cone's child:
bpy.ops.mesh.primitive_cube_add(location=(0, 0, 0))
bpy.context.scene.objects.active = bpy.data.objects["Cone"]
bpy.ops.object.parent_set(type='OBJECT')

# Print the cube's parent inverse matrix:
print(bpy.data.objects["Cube"].matrix_parent_inverse)


#------------------------------------------------------
# Make a parent hierarchy
# cube -&gt; bone -&gt; armature
# "-&gt;" means "is child of"
#------------------------------------------------------

# Delete the scene:
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()

# Create an armature at (2, 3, 4), a bone is created automatically as child:
bpy.ops.object.armature_add(location=(2, 3, 4))

# Create a cube at (0, 0, 0) and make it the bone's child:
bpy.ops.mesh.primitive_cube_add(location=(0, 0, 0))
bpy.context.scene.objects.active = bpy.data.objects["Armature"]
bpy.ops.object.mode_set(mode='POSE')
bpy.ops.object.parent_set(type='BONE')

# Print the cube's parent inverse matrix:
print(bpy.data.objects["Cube"].matrix_parent_inverse)


# =&gt; output:
#&lt;Matrix 4x4 (1.0000,  0.0000, 0.0000, -2.0000)
#            (0.0000,  1.0000, 0.0000, -3.0000)
#            (0.0000,  0.0000, 1.0000, -4.0000)
#            (0.0000,  0.0000, 0.0000,  1.0000)&gt;
#
#&lt;Matrix 4x4 (1.0000,  0.0000, 0.0000, -2.0000)
#            (0.0000,  0.0000, 1.0000, -5.0000)
#            (0.0000, -1.0000, 0.0000,  3.0000)
#            (0.0000,  0.0000, 0.0000,  1.0000)&gt;
#
# Both matrices should be the same but aren't.
Thanks to mont29's hint I have found a solution:
A bone seems to have two representations:


bpy.context.active_pose_bone.matrix_basis
&lt;armature&gt;.data.bones[x].matrix_local


Dependant on the context (pose mode/object mode) one sees the one or the other. There is a rotation by pi/2 around the x-axis and an offset of 1 in the z-axis between them. Here is the sample code from above again, the correction to make the second matrix equal to the first is added at the end.

import bpy
import mathutils
import math

#------------------------------------------------------
# Make a parent hierarchy
# cube -&gt; cone -&gt; cylinder
# "-&gt;" means "is child of"
#------------------------------------------------------

# Delete the scene:
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()

# Create a cylinder at location (2, 3, 4):
bpy.ops.mesh.primitive_cylinder_add(location=(2, 3, 4))

# Create a cone and make it the cylinder's child at the same position:
bpy.ops.mesh.primitive_cone_add(location=(2, 3, 4))
bpy.context.scene.objects.active = bpy.data.objects["Cylinder"]
bpy.ops.object.parent_set(type='OBJECT')

# Create a cube at (0, 0, 0) and make it the cone's child:
bpy.ops.mesh.primitive_cube_add(location=(0, 0, 0))
bpy.context.scene.objects.active = bpy.data.objects["Cone"]
bpy.ops.object.parent_set(type='OBJECT')

# Print the cube's parent inverse matrix:
cmpi=bpy.data.objects["Cube"].matrix_parent_inverse
print("cmpi:")
print(cmpi)

#------------------------------------------------------
# Make a parent hierarchy
# cube -&gt; bone -&gt; armature
# "-&gt;" means "is child of"
#------------------------------------------------------

# Delete the scene:
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()

# Create an armature at (2, 3, 4), a bone is created automatically as child:
bpy.ops.object.armature_add(location=(2, 3, 4))

# Create a cube at (0, 0, 0) and make it the bone's child:
bpy.ops.mesh.primitive_cube_add(location=(0, 0, 0))
bpy.context.scene.objects.active = bpy.data.objects["Armature"]
bpy.ops.object.mode_set(mode='POSE')
bpy.ops.object.parent_set(type='BONE')

# Print the cube's parent inverse matrix:
mpi=bpy.data.objects["Cube"].matrix_parent_inverse
print("mpi:")
print(mpi)

#------------------------------------------------------
# The correction to make the second matrix equal to
# the first
#------------------------------------------------------

ri=mathutils.Matrix.Rotation(math.pi/2, 4, 'X').inverted()
ti=mathutils.Matrix.Translation(mathutils.Vector((0,0,1))).inverted()
mpii=mpi.inverted()
mpiiriti=mpii*ri*ti
mpiiritii=mpiiriti.inverted()
print("mpiiritii:")
print(mpiiritii)

# Output (some formatting added by hand):
#
# cmpi:
# &lt;Matrix 4x4 ( 1.0000,  0.0000,  0.0000, -2.0000)
#             ( 0.0000,  1.0000,  0.0000, -3.0000)
#             ( 0.0000,  0.0000,  1.0000, -4.0000)
#             ( 0.0000,  0.0000,  0.0000,  1.0000)&gt;
# mpi:
# &lt;Matrix 4x4 ( 1.0000,  0.0000,  0.0000, -2.0000)
#             ( 0.0000,  0.0000,  1.0000, -5.0000)
#             ( 0.0000, -1.0000,  0.0000,  3.0000)
#             ( 0.0000,  0.0000,  0.0000,  1.0000)&gt;
# mpiiritii:
# &lt;Matrix 4x4 ( 1.0000, -0.0000,  0.0000, -2.0000)
#             (-0.0000,  1.0000,  0.0000, -3.0000)
#             ( 0.0000, -0.0000,  1.0000, -4.0000)
#             (-0.0000,  0.0000, -0.0000,  1.0000)&gt;