Accessing Transform Data [MEL]



Finding all Transforms
in a Scene

Transforms are probably the most important of data types in the maya API. An object is not visible in the scene unless it has a transform to place it correctly.


The code listing on the right will output all names of transform nodes in maya.Whilst this at first may seem sensible, it has the disadvantage of usually adding in redundant data.


A better idea is to build up a list of important transforms by querying the parents of the important shapes in your scene (ie, meshes, lights etc). This method should ensure you export a more compact data set. One potential issue arising is that each object may have multiple parents. This is the way in which instancing is supported.



// create an iterator to go through all transforms
MItDag it(MItDag::DepthFirst, MFn::kTransform);


// attach the function set to the object

// only want non-history items
if( !fn.isIntermediateObject() ) {


// print mesh name
<<"Transform "<< <<endl;

// described in the sections below


// get next transform;



Transformation Data


Maya transform data can be accessed via the MFnTransform class. This will allow you to access the scale, rotation and translation data.


When a transform is an IK joint then you will probably also want the orientation of the joint.


The example i present here will actually output Quaternion rotation values. If you wish to get the rotation data in euler angles (why?) then change the JointOrient and Rotation variables to be MEulerRotation types. The writing code can then ignore the 'w' parameter, and just output x,y,z rotation values.

















void outputTransformData(MObject& obj)

// attach the function set to the object

// If you want the transform data as a matrix
// then you can do something like this. I personally
am more interested in getting quaternions....
MMatrix mat = fn.transformation().asMatrix();

MQuaternion JointOrient(0,0,0,1);
MQuaternion Rotation(0,0,0,1);
double Scale[3];

// get the transforms local translation
MVector Translation = fn.translation();

// get the transforms scale

// get the transforms rotation as a quaternion

//if the transform is an IK joint then it will contain
//a joint orientation as well as a rotation

if( fn.object().hasFn(MFn::kJoint) )

  MFnIkJoint fnJoint(fn.object());


cout << "scale "
<< Scale[0] <<
" "
<< Scale[1] <<
" "
<< Scale[2] <<
cout << "translation "
<< Translation.x <<
" "
<< Translation.y <<
" "
<< Translation.z <<
cout << "rotation "
<< Rotation.x << " "
<< Rotation.y << " "
<< Rotation.z << " "
<< Rotation.w << endl;
cout << "jointOrient "
<< JointOrient.x << " "
<< JointOrient.y << " "
<< JointOrient.z << " "
<< JointOrient.w << endl;



Accessing Parenting Information

Each transform may have a number of child nodes. These will either be other transforms or actual scene objects (meshes, lights, camera's etc).

There are four main functions you can use to extract the hierarchy data, parentCount, parent, childCount and child.

The reason the transform can have multiple parents is to enable support for instancing. ie, a geometry instance is simply a piece of geometry that is parented under two transforms.

This function will actually work for any shape or transform node within maya. (ie, any node that is derived from kDagNode).

As mentioned earlier, it is generally better to be selective with which transforms you eport from maya. It may be wise to use the methods described here to work up through the transform hierarchy from the important shape types you want to export (lights/meshes/cameras/curves etc).



void outputParentingInfo(MObject& obj)

// attach the function set to the object

// output parent names
<< "numParents " << fn.parentCount() << endl;

// list each parent
for( int i=0; i!=fn.parentCount(); ++i ) {


// get a handle to the parent
MObject obj = fn.parent(i);

// attach a function set to the parent object

cout << << endl;


// output child count
<< "numChildren " << fn.childCount() << endl;

// list each child name
for( int i=0; i!=fn.childCount(); ++i ) {


// get a handle to the child
MObject obj = fn.child(i);

// attach a function set to the child object

cout << << endl;





What Next?

Soft Skinning Data (SkinClusters)

Rigid Skinning Data (JointClusters)

Inverse Kinematic Data


Rob Bateman [2004]