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 is similarly straight-forward:
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.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 );
}
}
}
}
}
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.
Extracting information from a material node itself is pretty simple. For example lets strip out all the information for a phong shader node: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 );
}
}
}
}
}
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..
}
}
Comments
Write a Comment