MEL How-To #17

Back · Previous · Next Maya

Why are my "instantaneous" constraints not being applied to the target object?

OK, you've got two objects in a scene. You want to snap one to the other, just to line them up, before performing other operations on the target object. A couple constraints seems an obvious and simple way to achieve this.

// Create two objects for this example
string $locatorA[] = `spaceLocator -name "theSource"`;
string $locator = $locatorA[0];

string $cubeA[] = `polyCube -w 1 -h 2 -d 3 -sx 1 -sy 1 -sz 1 -ax 0 1 0 -tx 1 -name "theTarget"`;
string $cube = $cubeA[0];

// Move and Rotate the locator to some arbitrary location
move 1.23 2.5 3.14 $locator;
rotate 45 15 3.33 $locator;

// Now we snap the cube to the locator
string $myPointConstraintA[] = `pointConstraint $locator $cube`;
string $myOrientConstraintA[] = `orientConstraint $locator $cube`;

// We just wanted them lined up.. now that's done, so dump the constraint nodes
delete $myPointConstraintA $myOrientConstraintA

So we quickly execute that and... nothing happens. The cube is still sitting at the origin. What the heck?

The problem is that there's nothing that happens to convince Maya that it needs to update its display (visually or internally) between the creation and the destruction of the constraints and thus, the cube doesn't move. To coerce Maya to do the constraint evaluation, throw a ‘refresh’ command just before the constraints are deleted:

// Now we snap the cube to the locator
string $myPointConstraintA[] = `pointConstraint $locator $cube`;
string $myOrientConstraintA[] = `orientConstraint $locator $cube`;

// Tell Maya its display is "dirty"
refresh;

// We just wanted them lined up.. now that's done, so dump the constraint nodes
delete $myPointConstraint $myOrientConstraint

That works. But frankly, this is not a good way to achieve this alignment.

Instead of the roundabout constraint network you can use the ‘xform’ command to quickly copy the transformation of one to the other:

// Create two objects for this example
string $locatorA[] = `spaceLocator -name "theSource"`;
string $locator = $locatorA[0];

string $cubeA[] = `polyCube -w 1 -h 2 -d 3 -sx 1 -sy 1 -sz 1 -ax 0 1 0 -tx 1 -name "theTarget"`;
string $cube = $cubeA[0];

// Move and Rotate the locator to some arbitrary location
move 1.23 2.5 3.14 $locator;
rotate 45 15 3.33 $locator;

// Get the translation and rotation, in world space, of the locator
float $trans[] = `xform -worldSpace -q -translation $locator`;
float $rot[] = `xform -worldSpace -q -rotation $locator`;

// And apply to the cube
xform -worldSpace -translation $trans[0] $trans[1] $trans[2] $cube;
xform -worldSpace -rotation $rot[0] $rot[1] $rot[2] $cube;