Friday, January 04, 2013

MTransformationMatrix and the Maya Python API

Here's my approach to how to work around the numerous limitations in the Maya Python API wrt. decomposing a matrix into its translate/rotate/scale components using MTransformationMatrix. This assumes you have a list of floats representing the elements of the matrix you want to decompose, and want to obtain the t/r/s components as 3-vectors stored as Python lists.

# Identity rotation/scale with translation (2,3,4):
listOfFloats = 
  [1.0, 0.0, 0.0, 0.0, 
   0.0, 1.0, 0.0, 0.0, 
   0.0, 0.0, 1.0, 0.0,
   2.0, 3.0, 4.0, 1.0]
# create MMatrix from list
mm = om.MMatrix()
om.MScriptUtil.createMatrixFromList(listOfFloats,mm)
# create MTransformationMatrix from MMatrix
mt = om.MTransformationMatrix(mm)
# translation is easy to obtain
translate = mt.translation(om.MSpace.kWorld)
# rotation needs to go past Quaternion representation due to API 
# limitations
rotate = mt.rotation().asEulerRotation()
# for scale we need to utilize MScriptUtil to deal with the native
# double pointers
scaleUtil = om.MScriptUtil()
scaleUtil.createFromList([0,0,0],3)
scaleVec = scaleUtil.asDoublePtr()
mt.getScale(scaleVec,om.MSpace.kWorld)
scale = [om.MScriptUtil.getDoubleArrayItem(scaleVec,i) for i in range(0,3)]

print 'Translation: %s, rotation: %s, scale: %s'%(translate,rotate,scale)

Please let me know if you know of neater ways of doing any of the above!

2 comments:

  1. Great post!

    For this line:
    translate = mm.translation(om.MSpace.kWorld)

    It should be:
    translate = mt.translation(om.MSpace.kWorld)

    An MMatrix doesn't have a translation attribute.

    ReplyDelete
  2. Thank you sir! This has been corrected.

    ReplyDelete