I'd like to set the matrix_basis
of an object. Unfortunately, the matrix isn't get updated correctly.
This is my test scene, consisting of an plane and a cylinder object:
My objective is to get alpha
, the plane's x angle, and apply it in some way to cylinder.
Here is the code:
import bpy
from math import *
from mathutils import *
plane = bpy.data.objects['plane']
cylinder = bpy.data.objects['cylinder']
alpha = plane.rotation_euler[0] # x rotation
print('alpha=%.2f' % degrees(alpha))
'''
# normal rotation matrix around x axis
# works fine
m = Matrix(( \
[1, 0, 0, 0], \
[0, cos(alpha), -sin(alpha), 0], \
[0, sin(alpha), cos(alpha), 0], \
[0, 0, 0, 1] \
))
'''
m = Matrix(( \
[1, 0, 0, 0], \
[0, cos(alpha), 0, 0], \
[0, sin(alpha), 1, 0], \
[0, 0, 0, 1] \
))
cylinder.matrix_basis = m
bpy.context.scene.update() # is this call needed?
# prints different matrix than m
print(cylinder.matrix_basis)
# for debugging
print(cylinder.matrix_world)
This is the console output of it:
alpha=-17.10
<Matrix 4x4 (1.0000, 0.0000, 0.0000, 0.0000)
(0.0000, 0.9890, 0.1478, 0.0000)
(0.0000, -0.1478, 0.9890, 0.0000)
(0.0000, 0.0000, 0.0000, 1.0000)>
<Matrix 4x4 (1.0000, 0.0000, 0.0000, 0.0000)
(0.0000, 0.9890, 0.1478, 0.0000)
(0.0000, -0.1478, 0.9890, 0.0000)
(0.0000, 0.0000, 0.0000, 1.0000)>
The first printed matrix is the matrix_basis
. As you can see, it differs from m
. For example, the element of the second row, third column have to be 0 but is 0.1478.
I haven't apply any constraints to cylinder
. So whats wrong by setting the basis_matrix
in this way?
Edit:
In addtion to @mont29 's answer, I've found the following document: issues in orientation-matrix in Blender <2.50
Current implementation of orientation-matrix system in Blender is not reliable: there are limitations / some nasty problems with mirrored/non-uniform-scaled geometry in Blender
Perhaps, it is not a bug, but a system design side-effect: insufficient/incomplete representation method of object orientation data with "all-in-one loc/rot/scale-matrix".
Yes, m
isn't orthogonal (m.is_orthogonal == False
), so Blender can't handle it.