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)
#1 by Peter on 2010/12/07 - 10:22 pm
I know that theoretically it’s bad form to put maya.cmds into the main namespace because of potential naming clashes between python and cmds… but has that ever happened to you? So daring!
#2 by kiki on 2010/12/07 - 10:44 pm
Heh busted. 🙂 I used to do that more often to save on typing. Now I usually import maya.cmds as mc. It’s something we’ve standardized on at work and I’m writing more class-based pipeline code, making namespaces more important.
But as an example it’s easier to read without namespacing. Yeah, that’s my real excuse. 😉