Accessing Constraint Data [MEL]



 

 

Within Maya there are a number of different constraints that can be used to act upon a transform. The Hypergraph view above, shows a point constraint acting upon the transform locator3. You will notice that the constraint is using two locator nodes as the constraint targets.

Essentially a point constraint, can take the weighted sum of more than one transforms, in order to deduce a target point. This evaluated point will define the location of the locator3 transform after being affected by the point constraint.

Generally speaking, you will want to get any animation curves that are attached to the contraint node itself. The only animation curves should be those animating the weight values on the constraint to turn on and off the effect of the various target transforms. In this case, the point constraint would hold the attributes locator1W0 and locator2W1, and it would therefore be any anim curves attached to those attributes that would be important.

 

 

 

 

 

Accessing Targets & Weights

Each Target transform is associated by it's own weight. Basically we need to able to find the various transforms attached to the target array. We will also need to associate those nodes with one of the attributes.

The method I use to do this relies on naming convention to 'guess' the name of the attribute. This is by no means safe however, since you can change the names of the attributes if you wish. Therefore, this is possibly a bit problematic. So if anyone knows of a better way of doing this, then please let me know.

This function then returns an array of MObjects and an array of MStrings that contain our best guess for the associated attribute.

 

 

 

 

 

 

 

 

 

 

 

 

 

 


#include<maya/MItDag.h>
#include<maya/MFnCamera.h>

bool GetConstraintTargets( MObject constraint,
MObjectArray& targets,
MStringArray& attrnames)

{
 

// attach a function set to the constraint
MFnDependencyNode fn(constraint);

// get a plug to the target array
MPlug targetplug = fn.findPlug("target");

for(unsigned int i=0;i<targetplug.numElements():++i) {

  MPlug tplug = targetplug.elementByPhysicalIndex(i);

// now get one of the targets compound attr
// to find the connection

MPlug comp_plug = tplug.child(0);

// get connections to the component plug
MPlugArray conns;
comp_plug.connectedTo(conns,true,false);

// if we have some connections
if( conns.length() > 0 )
{

 

// attach a function set to the
// target to invent the name

MFnDependencyNode fnTarget(conns[0].node());

// invent a name for the attribute
char namebuffer[128];

sprintf( namebuffer,"%sW%d", fnTarget.name().asChar(),i);

// add the MObject and attr name to
// the output list

attrnames.append(namebuffer);
targets.append(conns[0].node());

} else {

  return false;

}

}

return true;

}

 

 

 

Accessing The Constrained Object

Ideally we want to find out the object that is actually being influenced by the constraint. To do this, we can again have a look at the node connections.

 

 

 

 

 

 

 

 

 

 


#include<maya/MPlugArray.h>
#include<maya/MFnDependencyNode.h>

bool GetAffectedObject( MObject constraint,
MObject& affected)

{
 

// attach a function set to the constraint
MFnDependencyNode fn(constraint);

// get a plug to the target array
MPlug plug = fn.findPlug("constraintTranslateX");

// get a list of connections to the plug

MPlugArray plugs;
plug.connectedTo(plugs,false,true);

// if we have a connection
if (plugs.length()>0)
{

  // return the affected node
affected = plugs[0].node();
return true;

}

// failed.
return false;

}


 

 

 

Putting It All Together

Not much to say. ;)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


#include<maya/MPlugArray.h>
#include<maya/MFnDependencyNode.h>

void OutputPointConstraint( MObject constraint )

{
 

MObjectArray targets;
MStringArray attrnames;

// get the target transforms
if(GetTargetConstraints(obj,targets,attrnames))
{

 


MObject affected;

// get the affected geometry
if (GetAffectedObject(obj,affected))
{

 

MFnDependencyNode fn(obj);
MFnDependencyNode fnAffected(affected);

// output some info about the constraint

cout << "POINT_CONSTRAINT "
<< fn.name().asChar()
<< " {\n"
<< "\taffected "
<< fnAffected.name().asChar()
<< "\n"
<< "\tnum_targets "
<< targets.length()
<< "\n";

// write each target object
for(unsigned int j=0;j<targets.length();++j) {

 

MFnDependencyNode fnTarget(targets[j]);

cout << "\t\t"
<< fnTarget.name().asChar()
<< " "
<< attrnames[j].asChar()
<< endl;

}

cout << "}\n";

}

}

}





 

 

What Next?

Transformation Data

IK Chains

Blend Shapes

Smooth Skinning

Rigid Skinning

Animation Data

Animation Curves

index

Rob Bateman [2004]

[HOME] [MEL] [API]