ValueError : Matrix has no inverse

Hey everyone,

I’m writing an exporter and need to rotate the bone matrices so that Y is up. This is some code that has (I’m fairly sure) worked in the past with v2.70. But now with v4.0, it tells me the matrix has no inverse.

Can anyone see anything obvious wrong with my code?

def convertBoneMatrix(self, pose_bone):
        matrix = pose_bone.matrix.copy()

        if not pose_bone.parent:
            matrix = matrix * Matrix.Rotation(1.5707963267948966, 4, 'Z')
        else:
            parent_matrix = pose_bone.parent.matrix
            matrix = (parent_matrix * Matrix.Rotation(1.5707963267948966, 4, 'Z')).invert() * matrix * Matrix.Rotation(1.5707963267948966, 4, 'Z')#Fails here
        
        matrix.transpose()
        return matrix

Any further information needed please don’t hesitate to ask. Thankyou.

It appears that Matrix.invert() does not return a value… so

Matrix.Rotation(...).invert() * another_matrix

is meaningless.

>>> m = Matrix.Rotation(pi/2, 4, 'Z')
>>> m
Matrix(((7.549790126404332e-08, -1.0, 0.0, 0.0),
    (1.0, 7.549790126404332e-08, 0.0, 0.0),
    (0.0, 0.0, 1.0, 0.0),
    (0.0, 0.0, 0.0, 1.0)))
>>> m.invert()
>>> m
Matrix(((7.549790126404332e-08, 1.0, 0.0, -0.0),
    (-1.0, 7.549790126404332e-08, -0.0, 0.0),
    (0.0, -0.0, 1.0, -0.0),
    (-0.0, 0.0, -0.0, 1.0)))
>>> m.invert()

>>> mi = m.invert()
>>> mi                       #### this returns nothing

>>> m * mi
Traceback (most recent call last):
  File "<blender_console>", line 1, in <module>
TypeError: Element-wise multiplication: not supported between 'Matrix' and 'NoneType' types

To fix your code, get the Matrix.invert() step out of the math equation. Put the .invert() call on a separate line of code.

Ah of course. Thanks. It still fails with the same error though.

def convertBoneMatrix(self, pose_bone):
        matrix = pose_bone.matrix.copy()

        if not pose_bone.parent:
            matrix = matrix * Matrix.Rotation(1.5707963267948966, 4, 'Z')
        else:
            parent_matrix = pose_bone.parent.matrix
            matrix = parent_matrix * Matrix.Rotation(1.5707963267948966, 4, 'Z')
            matrix.invert()#Fails here
            matrix = matrix * Matrix.Rotation(1.5707963267948966, 4, 'Z')
        
        matrix.transpose()
        return matrix

Next, I would advise you to print out parent_matrix. I can’t do that for you…

Matrix.Rotation(pi/2, 4, ‘Z’) is invertible… so the problem has to be parent_matrix, or the result of the multiplication.

Matrix multiplication is done with @ rather than * since V2.80.
eg matrix = matrix * Matrix.Rotation(1.5707963267948966, 4, 'Z') should be matrix = matrix @ Matrix.Rotation(1.5707963267948966, 4, 'Z') or (arguably) better matrix @= Matrix.Rotation(1.5707963267948966, 4, 'Z') or even better from math import pi; matrix @= Matrix.Rotation(pi/2, 4, 'Z')

See https://blender.stackexchange.com/questions/129473/typeerror-element-wise-multiplication-not-supported-between-matrix-and-vect

Also you can get the inverted matrix with matrix.inverted() rather than the in-place matrix.invert()

2 Likes

Ah thanks. This is the print out before and after the multiplication.

parent_matrix = pose_bone.parent.matrix
print(parent_matrix)

<Matrix 4x4 (1.0000, 0.0000,  0.0000,  0.0000)
            (0.0000, 0.0000, -1.0000,  0.0000)
            (0.0000, 1.0000,  0.0000, -1.0000)
            (0.0000, 0.0000,  0.0000,  1.0000)>

matrix = parent_matrix * Matrix.Rotation(1.5707963267948966, 4, ‘Z’)
print(matrix)

<Matrix 4x4 (0.0000, -0.0000,  0.0000,  0.0000)
            (0.0000,  0.0000, -0.0000,  0.0000)
            (0.0000,  0.0000,  0.0000, -0.0000)
            (0.0000,  0.0000,  0.0000,  1.0000)>

@Gorgious I’ll give that a go thankyou.

Replacing ‘*’ with ‘@’ was all that was needed! Thankyou both for you help!

To elaborate * is still a valid operator between matrices but it will multiply the matrices element wise, meaning Matrix 1 row 1 column 1 will be multiplied with Matrix 2 row 1 column 1, etc…
90 degree rotation matrices have their ones and zeroes swapped in regard to say an identity matrix so I’m not surprised it lead to an un-invertable matrix.

Further reading https://peps.python.org/pep-0465/#background-what-s-wrong-with-the-status-quo

Cheers

2 Likes