Search code examples
pythonmaya

how do you multiply a matrix to another with openMaya?


I'm trying to create a script for mirroring transforms across the yz plane in Maya.

I was able to set up a node network that gets the desired results. I took a node at the origin with sz set to -1 and a source node from the left side (lf_grp for this test), and fed their worldMatrix attrs into a multMatrix node. Then I passed the output (multMatrix.matrixSum) through a decompose matrix and into my destination node.

I'd really prefer to not create a bunch of nodes to do my mirroring - running a create/connect/disconnect/delete cycle every time is slow and painful... I'd rather just "math the crap out of it" through my script, but I can't seem to figure out how to actually multiply my two matrices...

Oh, I'm using the MTransformationMatrix since it handles a few things for you that the MMatrix does not - like rotation order (at least from what I've read...)

Thank you for any help you can give!

import maya.cmds as mc
import maya.OpenMaya as om

src_xfm = 'lf_grp'
mir_matrix_vals = [-1.0, -0.0, -0.0, 0.0,
                   0.0, 1.0, 0.0, 0.0,
                   0.0, 0.0, 1.0, 0.0,
                   0.0, 0.0, 0.0, 1.0]

# get src xfm matrix
#
selList = om.MSelectionList()
selList.add(src_xfm)
mDagPath = om.MDagPath()
selList.getDagPath(0, mDagPath)

src_xfmFn = om.MFnTransform(mDagPath)
src_matrix = src_xfmFn.transformation()

# construct mir xfm matrix
#
mir_matrix = om.MTransformationMatrix()
tmp_matrix = om.MMatrix()
om.MScriptUtil().createMatrixFromList(mir_matrix_vals, tmp_matrix)
mir_matrix = om.MTransformationMatrix(tmp_matrix)

# multiply matrices to get mirrored matrix
#
dst_matrix = src_matrix * mir_matrix  # HOW DO YOU DO THIS????

Solution

  • Here's how do to it using the openMaya api version 2.

    Nowadays this is the preferred method for doing Python api work - among other things it's a lot less wordy and avoids MScriptUtil, which is prone to crashiness if used incorrectly. It's also faster for most things.

    This is the plain matrix multiplication:

    from maya.api.OpemMaya import MMatrix
    mat1  = MMatrix ([0.707107, 0, -0.707107, 0, 0.5, 0.707107, 0.5, 0, 0.5, -0.707107, 0.5, 0, 0, 0, 0, 1])
    mat2 = MMatrix([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 100, 200, 300, 1])
    print mat1 * mat2
    # (((0.707107, 0, -0.707107, 0), (0.5, 0.707107, 0.5, 0), (0.5, -0.707107, 0.5, 0), (100, 200, 300, 1)))
    

    You can't directly multiply an MTransformationMatrix -- that class isn't a linear algebra matrix, it's an accessor for the various position, rotation, scale, shear and pivot data functions of a matrix. You use it if you want get around doing all of the concatenating math yourself on a transform node, like setting its rotation without changing its scale.

    You can get the underlyying matrix from an MTransformationMatrix with its asMatrix() function. To apply a matrix to an object :

    from maya.api.OpenMaya import MTransformationMatrix, MGlobal, MSelectionList, MFnDagNode
    
    sel = MGlobal.getActiveSelectionList()  # selection
    dagpath = sel.getDependNode(0)          # first node
    transform_node  = MFnTransform(dagpath) # MFnTransform
    xfm= transform_node.transformation().asMatrix()  # matrix
    new_matrix = mat1 * xfm                 # math
    new_trans = MTransformationMatrix(new_matrix)
    transform_node.setTransformation(new_trans)