// ----------------------------------------
bool GeometryPolygonExporter::verifyPolygonsForHoles(
    const MFnMesh &fnMesh )
{
    // If we want to export triangles, holes aren't of note.
    if ( triangulated ) return false;

    // Iterate through all polygons of the current mesh and
    // verify their polygons for holes.
    MItMeshPolygon meshPolygonsIter ( fnMesh.object() );
    for ( meshPolygonsIter.reset(); !meshPolygonsIter.isDone(); meshPolygonsIter.next() )
    {
        // Is this polygon shaded by this shader?
        int polyIndex = meshPolygonsIter.index();
        uint realShaderCount = ( uint ) mShaders.length();
        if ( mShaderPosition < realShaderCount &&
                ( uint ) mShaderIndices[polyIndex] != mShaderPosition ) continue;
        if ( mShaderPosition >= realShaderCount &&
                ( mShaderIndices[polyIndex] >= 0 &&
                  mShaderIndices[polyIndex] < ( int ) realShaderCount ) ) continue;

        // Look for holes in this polygon
        // ASSUMPTION: Holes are automatically removed by triangulation.
        // ASSUMPTION: The iterator gives the hole vertices at the end of the enumeration.
        // ASSUMPTION: Hole vertices are never used as surface vertices or repeated between holes or inside a hole.
        if ( meshPolygonsIter.isHoled() && !triangulated )
        {
            return true;
        }
    }

    return false;
}
// ----------------------------------------
void GeometryPolygonExporter::writeShaderPolygons(
    COLLADASW::PrimitivesBase* primitivesBasePoly,
    const uint exportType,
    MFnMesh &fnMesh )
{
    // Number of polygons (could also be triangles)
    uint numPolygons = 0;

    // Generate the polygon set inputs.
    Sources polygonSetInputs;
    getVerticesInputAttributes( polygonSetInputs );

    // Iterate through all polygons of the current mesh and create them to export
    MItMeshPolygon meshPolygonsIter ( fnMesh.object() );
    for ( meshPolygonsIter.reset(); !meshPolygonsIter.isDone(); meshPolygonsIter.next() )
    {
        // Is this polygon shaded by this shader?
        uint realShaderCount = ( uint ) mShaders.length();
        int polyIndex = meshPolygonsIter.index();
        if ( mShaderPosition < realShaderCount &&
                ( uint ) mShaderIndices[polyIndex] != mShaderPosition ) continue;
        if ( mShaderPosition >= realShaderCount &&
                ( mShaderIndices[polyIndex] >= 0 &&
                  mShaderIndices[polyIndex] < ( int ) realShaderCount ) ) continue;

        // Create a polygon to store the vertex indexes to export
        PolygonSource polygon ( polygonSetInputs );

        // Create the polygon with the initialization data
        MIntArray vertexIndices;
        uint numPolygons = 0, numVertices = 0;
        initializePolygonSource ( fnMesh, meshPolygonsIter, polygon, vertexIndices, numPolygons, numVertices );

        // If we have polygons to export, push it into the polygon list
        if ( numPolygons > 0 )
        {
            writeElementVertexIndices ( primitivesBasePoly, &polygon, fnMesh, meshPolygonsIter, exportType, vertexIndices, numPolygons, numVertices );
        }
    }

    primitivesBasePoly->finish();
}
// ----------------------------------------
uint GeometryPolygonExporter::getShaderPolygonsCount(
    const MFnMesh &fnMesh )
{
    uint numPolygons = 0;

    // Iterate through all polygons of the current mesh.
    // Check their polygons for holes and retrieve the vertexCountList.
    MItMeshPolygon meshPolygonsIter ( fnMesh.object() );
    for ( meshPolygonsIter.reset(); !meshPolygonsIter.isDone(); meshPolygonsIter.next() )
    {
        // Is this polygon shaded by this shader?
        int polyIndex = meshPolygonsIter.index();
        uint realShaderCount = ( uint ) mShaders.length();
        if ( mShaderPosition < realShaderCount &&
                ( uint ) mShaderIndices[polyIndex] != mShaderPosition ) continue;
        if ( mShaderPosition >= realShaderCount &&
                ( mShaderIndices[polyIndex] >= 0 &&
                  mShaderIndices[polyIndex] < ( int ) realShaderCount ) ) continue;

        // Get the polygon count
        uint numMeshPolygons = 0, numVertices = 0;

        // Get the number of vertices in the current mesh's polygon
        int polygonVertexCount = meshPolygonsIter.polygonVertexCount();
        if ( triangulated && polygonVertexCount > 3 )
        {
            int numTriangles;
            meshPolygonsIter.numTriangles ( numTriangles );
            if ( numTriangles > 0 ) numMeshPolygons = (uint) numTriangles;
        }
        else if ( polygonVertexCount >= 3 )
        {
            numMeshPolygons = 1;
        }

        numPolygons += numMeshPolygons;
    }

    return numPolygons;
}
// ----------------------------------------
bool GeometryPolygonExporter::verifyTriangulation ( MFnMesh &fnMesh )
{
    // Iterate through all polygons of the current mesh
    MItMeshPolygon meshPolygonsIter ( fnMesh.object() );
    for ( meshPolygonsIter.reset(); !meshPolygonsIter.isDone(); meshPolygonsIter.next() )
    {
        // Is this polygon shaded by this shader?
        uint realShaderCount = ( uint ) mShaders.length();
        int polyIndex = meshPolygonsIter.index();
        if ( mShaderPosition < realShaderCount &&
                ( uint ) mShaderIndices[polyIndex] != mShaderPosition ) continue;
        if ( mShaderPosition >= realShaderCount &&
                ( mShaderIndices[polyIndex] >= 0 &&
                  mShaderIndices[polyIndex] < ( int ) realShaderCount ) ) continue;

        // Get the number of vertices in the current mesh's polygon
        if ( meshPolygonsIter.polygonVertexCount() != 3) return false;
    }

    // All polygons are triangles
    return true;
}
// ----------------------------------------
void GeometryPolygonExporter::writeVertexCountList(
    COLLADASW::PrimitivesBase* primitivesBase,
    const MFnMesh &fnMesh )
{
    // Iterate through all polygons of the current mesh.
    // Check their polygons for holes and retrieve the vertexCountList.
    MItMeshPolygon meshPolygonsIter ( fnMesh.object() );
    for ( meshPolygonsIter.reset(); !meshPolygonsIter.isDone(); meshPolygonsIter.next() )
    {
        // Is this polygon shaded by this shader?
        int polyIndex = meshPolygonsIter.index();
        uint realShaderCount = ( uint ) mShaders.length();
        if ( mShaderPosition < realShaderCount &&
                ( uint ) mShaderIndices[polyIndex] != mShaderPosition ) continue;
        if ( mShaderPosition >= realShaderCount &&
                ( mShaderIndices[polyIndex] >= 0 &&
                  mShaderIndices[polyIndex] < ( int ) realShaderCount ) ) continue;

        // Get the polygon count
        unsigned long vertexCount;
        if ( getPolygonVertexCount ( meshPolygonsIter, vertexCount ) )
            primitivesBase->appendValues( vertexCount );
    }
}