Set a bones matrix to a custom matrix I have a script in which I compute a custom matrix for each bone of a skeleton. I know I have switch to edit mode but then I read that the property edit_bone.matrix is read-only for bones. Now, because I know how matrices work, I thought, I would just set the bones matrix to Identity() (edit_bone.head to (0, 0, 0) and edit_bone.tail to (0, 1, 0)). But when I then do transform the bone the outcome is not what I expected. The script-snippet is the following:

for bone in self._data.edit_bones:
    ebone = armature.edit_bones.new(bone.name)
    # ebone.head = (0.0, 0.0, 0.0) # already default
    ebone.tail = (0.0, 1.0, 0.0)
    t_matrix = Matrix(bone.transform) # use blender-intern Matrix
    # the following call should set ebone.matrix to t_matrix
    # cannot do that directly, is currently wrong
    ebone.transform(t_matrix)
    print(t_matrix, ebone.matrix, sep='\n')


This gives the following output:

&lt;Matrix 4x4 (-0.9665, -0.2564, -0.0119, 17.7405)
            ( 0.0171, -0.0183, -0.9997,  0.0280)
            ( 0.2561, -0.9664,  0.0221, -0.0120)
            ( 0.0000,  0.0000,  0.0000,  1.0000)&gt;
&lt;Matrix 4x4 (-0.0530, -0.0119,  0.9985, 17.7405)
            ( 0.0227, -0.9997, -0.0107,  0.0280)
            ( 0.9983,  0.0221,  0.0533, -0.0120)
            ( 0.0000,  0.0000,  0.0000,  1.0000)&gt;


Notice how the translation is correct but I don't understand why the other part isn't. Can anyone give an insight what is going on and provide a solution to my problem?
bone.transform() also didn't work very well for me, so I used a method I found in a blenderartists post to extract the roll and tail from a matrix:

def vec_roll_to_mat3(vec, roll):
    target = Vector((0, 0.1, 0))
    nor = vec.normalized()
    axis = target.cross(nor)
    if axis.dot(axis) &gt; 0.0000000001: # this seems to be the problem for some bones, no idea how to fix
        axis.normalize()
        theta = target.angle(nor)
        bMatrix = Matrix.Rotation(theta, 3, axis)
    else:
        updown = 1 if target.dot(nor) &gt; 0 else -1
        bMatrix = Matrix.Scale(updown, 3)

        # C code:
        #bMatrix[0][0]=updown; bMatrix[1][0]=0.0;    bMatrix[2][0]=0.0;
        #bMatrix[0][1]=0.0;    bMatrix[1][1]=updown; bMatrix[2][1]=0.0;
        #bMatrix[0][2]=0.0;    bMatrix[1][2]=0.0;    bMatrix[2][2]=1.0;
        bMatrix[2][2] = 1.0

    rMatrix = Matrix.Rotation(roll, 3, nor)
    mat = rMatrix * bMatrix
    return mat

def mat3_to_vec_roll(mat):
    vec = mat.col[1]
    vecmat = vec_roll_to_mat3(mat.col[1], 0)
    vecmatinv = vecmat.inverted()
    rollmat = vecmatinv * mat
    roll = math.atan2(rollmat[0][2], rollmat[2][2])
    return vec, roll


Then, to set it:

tail, roll = mat3_to_vec_roll(matrix)
bone.head = matrix.to_translation()
bone.tail = tail*boneLength + bone.head
bone.roll = roll