Maya 4.0 API Quick Programming Tutorial

Report this File

Missing

Views:

38,967

Updated:

Jul 08, 2010

Readership Level:

Intermediate

Tags:

Maya Versions:

4.x

Platforms:

irix, linux, mac, windows

Owner:

Language:

English

Extracting Polygons


Extracting polygons is similarly straight-forward:

void extractPolygons()
{
MStatus stat;
MItDag dagIter( MItDag::kBreadthFirst, MFn::kInvalid, &stat );

for ( ; !dagIter.isDone(); dagIter.next())
{
MDagPath dagPath;
stat = dagIter.getPath( dagPath );

if ( stat )
{
MFnDagNode dagNode( dagPath, &stat );

if ( dagNode.isIntermediateObject()) continue;
if ( !dagPath.hasFn( MFn::kMesh )) continue;
if ( dagPath.hasFn( MFn::kTransform )) continue;

// get the mesh and all its vertices
MFnMesh fnMesh( dagPath );
MPointArray vertexList;
fnMesh.getPoints( vertexList, MSpace::kWorld );

// now iterate over all the polygons in the mesh
MItMeshPolygon piter( dagPath, comp );
for ( ; !piter.isDone(); piter.next())
{
// for each polygon you can get the indices of
// each of its vertices in the vertex list above
MIntArray vertexIdxs;
piter.getVertices( vertexIdxs );

if ( vertexIdxs.length() == 3 )
{
// process a triangle
MPoint point0 = vertexList[vertexIdxs[0]];
MPoint point1 = vertexList[vertexIdxs[1]];
MPoint point2 = vertexList[vertexIdxs[2]];

processTriangle( point0, point1, point2 );
}
}
}
}
}

From this basic code you can get a great deal of other information. You can query each vertex for light and texture coordinate information for example. What you can't easily get this way are the textures themselves, or the color of each material. This stuff is not in the DAG and must be extracted another way. In Maya all mesh elements can be associated with a material. The material can be something very simple, like a single lambert shaded color, or something much more complex, like a hierarchy of materials that include various light models, textures, transparencies etc. It can get pretty complicated and I haven't needed to understand all the intricacies.

 

 

Extracting Materials


Getting a single material associated with a polygon face is a little trickier than the code above but still not too bad. The trick is that this time you can't just iterate over the DAG to find the polygons, but rather you have to iterate over the whole DG to find all the materials first, and then use the materials to find all the polygons each material is associated with.

 

bool extractMaterials()
{
MStatus stat;
MItDag dagIter( MItDag::kBreadthFirst, MFn::kInvalid, &stat );

for ( ; !dagIter.isDone(); dagIter.next())
{
MDagPath dagPath;
stat = dagIter.getPath( dagPath );

if ( stat )
{
MFnDagNode dagNode( dagPath, &stat );

if ( dagNode.isIntermediateObject()) continue;
if ( !dagPath.hasFn( MFn::kMesh )) continue;
if ( dagPath.hasFn( MFn::kTransform )) continue;

MFnMesh fnMesh( dagPath );

// Here is the trick, get all the nodes connected to this
// mesh, whether they are on the DAG or not. This will
// include all the materials.
unsigned instanceNumber = dagPath.instanceNumber();
MObjectArray sets;
MObjectArray comps;

fnMesh.getConnectedSetsAndMembers( instanceNumber, sets,
comps, true );

// iterate over all the connected sets and look for materials
{ for ( u32 i = 0; i < sets.length(); i++ )
{
MObject set = sets[i];
MObject comp = comps[i];

MFnSet fnSet( set );
MFnDependencyNode dnSet( set );

MObject ssAttr = dnSet.attribute( MString( "surfaceShader" ) );

MPlug ssPlug( set, ssAttr );

MPlugArray srcPlugArray;
ssPlug.connectedTo( srcPlugArray, true, false );

if ( srcPlugArray.length() == 0 ) continue;

// this object contains a reference to a shader, or
// material, so we might call our own function to write
// that material to our own data structure for later export,
// and return a material index so we can attach that index
// to all the polygons we are going to extract below.
MObject srcNode = srcPlugArray[0].node();
u32 matIdx = makeMaterial( srcNode );

// we might want to stop processing this node right now if
// it is a material our exporter does not support
if ( material_is_not_supported( matIdx )) continue;

// otherwise, lets iterate over all the polygons that
// are colored with this material
MItMeshPolygon piter( dagPath, comp );
for ( ; !piter.isDone(); piter.next())
{
MIntArray vertexIdxs;
piter.getVertices( vertexIdxs );

// jump to our own code to export a polygon with a material
writePolygon( vertexIdxs, matIdx );
}
}
}
}
}


Extracting information from a material node itself is pretty simple. For example lets strip out all the information for a phong shader node:
void makeMaterial( MObject& srcNode )
{
if ( srcNode.hasFn( MFn::kPhong ))
{
MFnPhongShader phong( srcNode );

cerr << "Found phong shader: ""
<< phong.name().asChar() << "" << endl;

// extract all the phong parameters:
MColor glowColor = phong.incandescence();
MColor diffuseColor = phong.color() * phong.diffuseCoeff();
MColor specularColor = phong.specularColor();
Double cosinePower = phong.cosPower();
MColor transColor = phong.transparency();

// now build a material, and write it out..
}
}

Tutorial_next_page

Comments

Write a Comment

You must be logged in and have verified your email address to leave a comment. Login or create an account

Related Marketplace Items

  • Rapidrig_v2_silhouette

  • Mgtoolsthumbnails

  • Esuvee

  • Mainpreview

  • Mgtoolsthumbnails

  • Batchbake_example2

  • Rig_02

  • Ninjacity01