// ---------------------------------------- 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::initializePolygonSource( const MFnMesh &fnMesh, MItMeshPolygon &meshPolygonsIter, PolygonSource &polygon, MIntArray &vertexIndices, uint &numPolygons, uint &numVertices ) { // Collect data in order to handle triangle-only export option // Retrieve the vertex indices and establish the number of polygons (in case of // triangulation more than one is possible) and the number of vertexes in the polygon. retrieveVertexIndices ( vertexIndices, meshPolygonsIter, numPolygons, numVertices ); // Iterate through the polygons (normally just one polygon, // just in case of triangulation it could be more than one) for ( uint polygonPosition=0; polygonPosition<numPolygons; ++polygonPosition ) { // Put the current face in the list of faces polygon.getFaceVertexCounts().push_back ( numVertices ); // Get the index of the current polygon int polyIndex = meshPolygonsIter.index(); // Iterate through the vertexes of the current polygon for ( uint vertexPosition=0; vertexPosition<numVertices; vertexPosition++ ) { // Handle front face vs back face by walking the vertexes backward on the back-face int iteratorVertexIndex = vertexIndices[polygonPosition * numVertices + vertexPosition]; int vertexIndex = meshPolygonsIter.vertexIndex ( iteratorVertexIndex ); // 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 ) { handleHoledPolygon(polygon, polyIndex, vertexIndex, numVertices, iteratorVertexIndex); } } } }
// ---------------------------------------- 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 ); } }
// -------------------------------------------------------- void GeometryPolygonExporter::writeElementVertexIndices( COLLADASW::PrimitivesBase* primitivesBasePoly, PolygonSource* polygon, MFnMesh &fnMesh, MItMeshPolygon &meshPolygonsIter, const uint exportType, const MIntArray &vertexIndices, const uint numPolygons, const uint numVertices ) { // Add the open tags for the polygons if ( exportType == PolygonSource::POLYGONS ) { if ( polygon->isHoled() ) { ( ( COLLADASW::Polygons* ) primitivesBasePoly )->openPolylistHoleElement(); } } // The face index uint currentFaceIndex = 0; // Check if the current face is a normal polygon or a hole and open the corresponding tag. if ( exportType == PolygonSource::POLYGONS ) { openPolygonOrHoleElement ( primitivesBasePoly, polygon, currentFaceIndex ); } // Get the index of the current polygon int polyIndex = meshPolygonsIter.index(); // Buffer the face normal indices MIntArray normalIndices; if ( mHasFaceVertexNormals ) { fnMesh.getFaceNormalIds ( polyIndex, normalIndices ); } // Iterate through the polygons (normally just one polygon, // just in case of triangulation it could be more than one) for ( uint polygonPosition=0; polygonPosition<numPolygons; ++polygonPosition ) { // Initialize the data for polygons with holes size_t numFaceVertices = polygon->getFaceVertexCounts().size(); uint currentFaceIndex = 0; uint faceVertexCounts = polygon->getFaceVertexCounts()[currentFaceIndex]; // Iterate through the vertexes of the current polygon for ( uint vertexPosition=0; vertexPosition<numVertices; ++vertexPosition ) { // Handle front face vs back face by walking the vertexes backward on the back-face uint vertexIndexPosition = polygonPosition * numVertices + vertexPosition; int iteratorVertexIndex = vertexIndices[vertexIndexPosition]; int vertexIndex = meshPolygonsIter.vertexIndex ( iteratorVertexIndex ); // If we write a holed polygon and the actual vertex position is the last // position of the current face, then go to the next face in the list. if ( exportType == PolygonSource::POLYGONS && polygon->isHoled() && vertexPosition == faceVertexCounts ) { // Increment, cause we have found the next face ++currentFaceIndex; // Close the tag for the last face ( ( COLLADASW::Polygons* ) primitivesBasePoly )->closeElement(); // Get the vertex count of the current face uint currentFaceVertexCount = polygon->getFaceVertexCounts()[currentFaceIndex]; // Add the vertex count of the current face to the sum of face vertexes faceVertexCounts += currentFaceVertexCount; // Check if the current face is a normal polygon or a hole and open the corresponding tag. openPolygonOrHoleElement ( primitivesBasePoly, polygon, currentFaceIndex ); } // Write the vertex indices writeVertexIndices ( primitivesBasePoly, polygon, vertexIndex, normalIndices, iteratorVertexIndex, meshPolygonsIter, fnMesh, polyIndex ); } } // Add the tags for the polygons if ( exportType == PolygonSource::POLYGONS ) { if ( polygon->isHoled() ) ( ( COLLADASW::Polygons* ) primitivesBasePoly )->closeElement(); ( ( COLLADASW::Polygons* ) primitivesBasePoly )->closeElement(); } }