A few weeks ago I got stuck while writing a foot snapping tool — the snapping code I used to use didn’t work on the rigs we inherited because there were a lot of pivot changes. I tried a bunch of more elegant ways to fix this but ended up doing the old standby:
delete `orientConstraint`;
delete `pointConstraint`;
Now, that solution wasn’t a satisfying one to me, so I kept looking for a better one.
Turns out there’s an easy fix. If you use getAttr on a transform node’s .worldMatrix, you get back the proper 4×4 set of float values that represents its final position in world space. Afterwards you can set the matrix of another object using xform. It’s pretty simple in either MEL or Python.
// this snaps one object to another using worldSpace matrix coordinates
string $sel[] = `ls -sl`;
float $m[] = `getAttr ($sel[1] + ".worldMatrix")`;
xform -ws -m $m[0] $m[1] $m[2] $m[3] $m[4] $m[5] $m[6] $m[7] $m[8] $m[9] $m[10] $m[11] $m[12] $m[13] $m[14] $m[15] ($sel[0]);
The MEL code is a bit ugly because of having to specifically reference each item in the array of floats, but it works. Here’s the Python equivalent. I keep it now as a button my shelf.
# uses matrices to snap one object to another
import maya
# yes, I put all my commands into the main namespace
from maya.cmds import *
sel = ls(sl=True)
mat = getAttr(sel[1] + ".worldMatrix")
xform(sel[0], ws=True, m=mat)