Check this out.
from maya.api import OpenMaya as om
tm = cmdx.om.MTransformationMatrix()
tm = tm.setScale(cmdx.om.MVector(-1, -1, -1), cmdx.om.MSpace.kWorld)
print(tm.scale(cmdx.om.MSpace.kWorld))
tm = cmdx.om.MTransformationMatrix(tm.asMatrix())
print(tm.scale(cmdx.om.MSpace.kWorld))
# [-1.0, -1.0, -1.0]
# [1.0, 1.0, -1.0]
And if that doesn't have you stumped, then this might.
from maya import cmds
cube, _ = cmds.polyCube()
cmds.scale(-1, -1, -1, cube)
# Get worldmatrix from cube
sl = om.MSelectionList()
sl.add(cube)
mobj = sl.getDependNode(0)
fn = om.MFnDependencyNode(mobj)
plug = fn.findPlug("worldMatrix", True).elementByLogicalIndex(0)
obj = plug.asMObject()
mat = om.MFnMatrixData(obj).matrix()
tm = cmdx.om.MTransformationMatrix(mat)
print(tm.scale(cmdx.om.MSpace.kWorld))
# [1.0, 1.0, -1.0]
That's right! The MTransformationMatrix is unable to represent the negative scale the X and Y axes in the matrix passed into it. For whatever reason, it removes the sign on the X and Y axis. Consistently.
Tested on Maya 2018.7 and 2020.2, Windows.
Solved! Go to Solution.
Solved by brentmc. Go to Solution.
Hi,
Unfortunately this is not a bug and is just a limitation in the Mathematics.
MTransformationMatrix is a bunch of components that are multiplied together to form a matrix.
So if you assign a matrix to an MTransformationMatrix it has to be decomposed back into components.
The problem is that many different combinations of components will produce the exact same matrix. e.g. a rotation of 360 is equivalent to a rotation of 720 etc. Once you convert to a matrix the information about the original components that produced that matrix is lost forever.
In your specific example try printing the rotation and you will see that it is not zero.
print(tm.rotation(False))
So the matrix has been decomposed into a Z rotation of 180 and a Z scale of -1. (which is a valid decomposition for that matrix)
I've included a GIF below that shows how these two matrices are equivalent. (using the letter "b")
--
Brent
Thanks for this, I had a suspicion this might the case.
I'm slowly but surely coming to the conclusion that to fully support user inputs to transforms I need more than just the final matrix. The first thing that bit me was not being able to spot rotations past 180 degrees, even though the user intended it. It's looking like instead of just a `worldMatrix`, I'll need separate translate/rotate/scale channels, along with pivots and a final parent matrix to account for hierarchy, to generate a `worldMatrix` of my own internally. Anyway, that's beside the point, this solves the issue for me. Thanks again.
You're welcome! I marked the question as solved.
Note: MTransformationMatrix keeps everything as separate components so the channels will be preserved as long as you don't set it from a matrix. (so you could still use this class to manage your channels and build the final matrix)
--
Brent