Hi all,
Given a world matrix, how can I convert this into translate/rotate suitable
for a node with a potentially edited..
- rotateAxis
- rotatePivot
- rotatePivotTranslate
- jointOrient, in the case of joints
In addition to being the child of another node with equally edited pivots
and axes and orientations.
Here’s what works if the target node has a parent, but zeroed out axes,
pivots and orients.
from maya import cmdsfrom maya.api import OpenMaya as om
def setup():
cmds.file(new=True, force=True)
cube1, _ = cmds.polyCube(width=5)
cube2, _ = cmds.polyCube(width=5)
cmds.parent(cube2, cube1)
cmds.rotate(0, 0, 30, cube1)
cmds.rotate(0, 0, -60, cube2)
cmds.move(0, 2, 0, cube1)
cmds.move(5.1, 2, 0, cube2, absolute=True)
# Now make a new world matrix
cube3, _ = cmds.polyCube(width=6, height=0.5, depth=0.5)
cmds.move(4, 2, -2, cube3, absolute=True)
cmds.rotate(25, 15, 50, cube3)
Starting off with some general setup, this is for a scene that looks like
this, where I would like to copy the worldmatrix of one onto the other.
[image: image.png]
Here’s some boilerplate for applying a MMatrix onto any node.
def setMatrix(mobj, matrix):
fn = om.MFnDagNode(mobj)
# Decompose
tm = om.MTransformationMatrix(matrix)
translate = tm.translation(om.MSpace.kPostTransform)
rotate = tm.rotation()
# Assign
tx = fn.findPlug("translateX", False)
ty = fn.findPlug("translateY", False)
tz = fn.findPlug("translateZ", False)
rx = fn.findPlug("rotateX", False)
ry = fn.findPlug("rotateY", False)
rz = fn.findPlug("rotateZ", False)
tx.setDouble(translate.x)
ty.setDouble(translate.y)
tz.setDouble(translate.z)
rx.setMAngle(om.MAngle(rotate.x, om.MAngle.kRadians))
ry.setMAngle(om.MAngle(rotate.y, om.MAngle.kRadians))
rz.setMAngle(om.MAngle(rotate.z, om.MAngle.kRadians))
And finally, the meat of our problem.
def copyMatrix(mobj1, mobj2):
# Parent inverse
obj2fn = om.MFnDagNode(mobj2)
parentInverseMatrixPlug = obj2fn.findPlug("parentInverseMatrix",
True).elementByLogicalIndex(0)
parentInverseMatrix =
om.MFnMatrixData(parentInverseMatrixPlug.asMObject()).matrix()
# Get target worldmatrix we'd like cube2 to receive
obj1fn = om.MFnDagNode(mobj1)
worldMatrixPlug = obj1fn.findPlug("worldMatrix",
False).elementByLogicalIndex(0)
worldMatrix = om.MFnMatrixData(worldMatrixPlug.asMObject()).matrix()
# Cancel out the parent matrix
outMatrix = worldMatrix * parentInverseMatrix
# Apply the thing and profit
setMatrix(mobj2, outMatrix)
setup()
selectionList = om.MSelectionList()
selectionList.add("pCube2")
selectionList.add("pCube3")
cube2obj = selectionList.getDependNode(0)
cube3obj = selectionList.getDependNode(1)
# Copy from pCube3 -> pCube2
copyMatrix(cube3obj, cube2obj)
This works just fine. When you run it, you’ll find pCube2 perfectly aligns
with pCube3, whilst still being parented to pCube1. Great.
[image: image.png]
Problem
Now let’s give pCube2 a custom rotatePivot. We’ll swap out our setup() with
this.
def setup():
cmds.file(new=True, force=True)
cube1, _ = cmds.polyCube(width=5)
cube2, _ = cmds.polyCube(width=5)
cmds.parent(cube2, cube1)
# Here's our rotate pivot
cmds.setAttr(cube2 + ".rotatePivot", -2.5, 0, 0, type="double3")
cmds.move(0, 2, 0, cube1)
cmds.move(5.1, 0, 0, cube2, relative=True)
cmds.rotate(0, 0, 30, cube1)
cmds.rotate(0, 0, -60, cube2)
cube3, _ = cmds.polyCube(width=6, height=0.5, depth=0.5)
cmds.move(4, 2, -2, cube3, absolute=True)
cmds.rotate(25, 15, 50, cube3)
And presto, we’ve got a problem.
[image: image.png]
I figure maybe I could somehow include the pivots..
def copyMatrix(mobj1, mobj2):
# Parent inverse
obj2fn = om.MFnDagNode(mobj2)
parentInverseMatrixPlug = obj2fn.findPlug("parentInverseMatrix",
True).elementByLogicalIndex(0)
parentInverseMatrix =
om.MFnMatrixData(parentInverseMatrixPlug.asMObject()).matrix()
# Get target worldmatrix we'd like cube2 to receive
obj1fn = om.MFnDagNode(mobj1)
worldMatrixPlug = obj1fn.findPlug("worldMatrix",
False).elementByLogicalIndex(0)
worldMatrix = om.MFnMatrixData(worldMatrixPlug.asMObject()).matrix()
rotatePivot = obj1fn.findPlug("rotatePivot",
False).asMDataHandle().asVector()
rotatePivotTranslate = obj1fn.findPlug("rotatePivotTranslate",
False).asMDataHandle().asVector()
# Cancel out the parent matrix
tm = om.MTransformationMatrix(worldMatrix * parentInverseMatrix)
tm.setRotatePivot(om.MPoint(rotatePivot), om.MSpace.kPostTransform, False)
tm.setRotatePivotTranslation(rotatePivotTranslate, om.MSpace.kPostTransform)
# Apply the thing and profit
setMatrix(mobj2, tm.asMatrix())
But it doesn’t work and also makes my brain spin.
So the question is; given an arbitrary world matrix from node A, how can I
apply it to the translate/rotate of node B such that its world matrix is
identical?
--
You received this message because you are subscribed to the Google Groups
"Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/python_inside_maya/CAFRtmOBeNYv4G2ftidW9RCOGviFCcNiAgHVGOmjqCiRrcNystQ%40mail.gmail.com.