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 python_inside_maya+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CAFRtmOBeNYv4G2ftidW9RCOGviFCcNiAgHVGOmjqCiRrcNystQ%40mail.gmail.com.