// -------------------------------------------------------- void GeometryPolygonExporter::exportPolygonSources ( MFnMesh& fnMesh, const String& meshId, MStringArray& uvSetNames, MStringArray& colorSetNames, Sources* polygonSources, Sources* vertexSources, const bool hasFaceVertexNorms ) { // Initialize the members mMeshId = meshId; mUvSetNames = uvSetNames; mPolygonSources = polygonSources; mVertexSources = vertexSources; mHasFaceVertexNormals = hasFaceVertexNorms; mColorSetNames = colorSetNames; // If triangulation is requested, verify that it is // feasible by checking with all the mesh polygons if ( ExportOptions::exportTriangles() ) { triangulated = true; for ( MItMeshPolygon polyIt ( fnMesh.object() ); triangulated && !polyIt.isDone(); polyIt.next() ) { triangulated = polyIt.hasValidTriangulation(); } } // If we have a hole in a polygon, we can't write a <polylist>. // Either we write <polygons> with holes or we write triangles. // Get hole information from the mesh node. // The format for the holes information is explained in the MFnMesh documentation. MStatus status; fnMesh.getHoles ( mHoleInfoArray, mHoleVertexArray, &status ); holeCount = ( status != MStatus::kSuccess ) ? 0 : ( mHoleInfoArray.length() / 3 ); // Find how many shaders are used by this instance of the mesh. // Each instance may apply a number of different materials to different faces. // We can use the getConnectedShaders member function of MFnMesh to find out // this shader information for each instance. mShaders.clear(); mShaderIndices.clear(); fnMesh.getConnectedShaders ( 0, mShaders, mShaderIndices ); // Find the polygons that correspond to each materials and export them. uint realShaderCount = ( uint ) mShaders.length(); uint numShaders = ( uint ) std::max ( ( size_t ) 1, ( size_t ) mShaders.length() ); for ( uint shaderPosition=0; shaderPosition<numShaders; ++shaderPosition ) { // Set the current shader position mShaderPosition = shaderPosition; // Export the polygons of the current shader exportShaderPolygons ( fnMesh ); } }
// -------------------------------------------------------- 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); } } } }
// ---------------------------------------- bool GeometryPolygonExporter::getPolygonVertexCount( MItMeshPolygon &meshPolygonsIter, unsigned long &numVertices ) { bool addVertexCount = false; // Establish the number of vertexes in the polygon. // We don't need the vertex count list for triangulation if ( triangulated ) return addVertexCount; // The number of vertices numVertices = 0; // Retrieve the vertices and increment polygon count // Get the number of vertices in the current mesh's polygon unsigned long polygonVertexCount = meshPolygonsIter.polygonVertexCount(); if ( polygonVertexCount >= 3 ) { #ifdef VALIDATE_DATA // Skip over any duplicate vertices in this face. // Very rarely, a cunning user manages to corrupt // a face entry on the mesh and somehow configure // a face to include the same vertex multiple times. // This will cause the read-back of this data to // reject the face, and can crash other COLLADA // consumers, so better to lose the data here MIntArray vertexIndices; vertexIndices.setLength ( polygonVertexCount ); for ( int pv = 0; pv < polygonVertexCount; ++pv ) { vertexIndices[pv] = pv; } for ( uint n = 0; n < vertexIndices.length() - 1; ++n ) { for ( uint m = n + 1; m < vertexIndices.length(); ) { if ( vertexIndices[n] == vertexIndices[m] ) { vertexIndices.remove ( m ); } else ++m; } } // Get the number of vertices of the current polygon. numVertices = vertexIndices.length(); #else // Get the number of vertices of the current polygon. numVertices = polygonVertexCount; #endif addVertexCount = true; } return addVertexCount; }
// ---------------------------------------- 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(); }
int AttributeIndex<GDVAT_TEXCOORDS_0>(MItMeshPolygon &polyIt, unsigned int polyVertNum, const char* pAttributeName) { MStatus result; int index; result = polyIt.getUVIndex(polyVertNum, index, &MString(pAttributeName)); if( result == MS::kFailure ) return -1; return index; }
// ---------------------------------------- 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 GetMeshMatrix( MItMeshPolygon &pIt, int nMeshFaceIndex, MMatrix &geoMatrix ) { if ( nMeshFaceIndex < static_cast< int >( pIt.count() ) ) { MPointArray facePoints; int nOldIndex; pIt.setIndex( nMeshFaceIndex, nOldIndex ); pIt.getPoints( facePoints, MSpace::kWorld ); // Calculate cheezy coordinate system, if any edges are 0 length then all hell breaks loose MVector x = ( facePoints[ 2 ] - facePoints[ 0 ] ).normal(); MVector z = ( facePoints[ 1 ] - facePoints[ 0 ] ).normal(); MVector y = ( z ^ x ).normal(); z = x ^ y; memcpy( const_cast< double * >( geoMatrix[ 0 ] ), &x[ 0 ], 3 * sizeof( double ) ); memcpy( const_cast< double * >( geoMatrix[ 1 ] ), &y[ 0 ], 3 * sizeof( double ) ); memcpy( const_cast< double * >( geoMatrix[ 2 ] ), &z[ 0 ], 3 * sizeof( double ) ); MPoint center = pIt.center( MSpace::kWorld ); memcpy( const_cast< double * >( geoMatrix[ 3] ), ¢er[ 0 ], 3 * sizeof( double ) ); pIt.setIndex( nOldIndex, nMeshFaceIndex ); } else { merr << "Mesh face index " << nMeshFaceIndex << " out of range, only " << pIt.count() << " faces on mesh" << std::endl; } }
// ---------------------------------------- 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 ); } }
// ---------------------------------------- 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; }
/** Create a RIB compatible representation of a Maya polygon mesh. */ liqRibMeshData::liqRibMeshData( MObject mesh ) : numFaces( 0 ), numPoints ( 0 ), numNormals ( 0 ), nverts(), verts(), vertexParam(NULL), normalParam(NULL) { CM_TRACE_FUNC("liqRibMeshData::liqRibMeshData("<<MFnDagNode(mesh).fullPathName().asChar()<<")"); unsigned int i; unsigned int j; areaLight = false; LIQDEBUGPRINTF( "-> creating mesh\n" ); MFnMesh fnMesh( mesh ); objDagPath = fnMesh.dagPath(); MStatus astatus; name = fnMesh.name(); areaLight =( liquidGetPlugValue( fnMesh, "areaIntensity", areaIntensity, astatus ) == MS::kSuccess )? true : false ; if ( areaLight ) { MDagPath meshDagPath; meshDagPath = fnMesh.dagPath(); MTransformationMatrix worldMatrix = meshDagPath.inclusiveMatrix(); MMatrix worldMatrixM = worldMatrix.asMatrix(); worldMatrixM.get( transformationMatrix ); } numPoints = fnMesh.numVertices(); numNormals = fnMesh.numNormals(); // UV sets ------------------- // //const unsigned numSTs( fnMesh.numUVs() ); const unsigned numUVSets( fnMesh.numUVSets() ); MString currentUVSetName; MStringArray extraUVSetNames; fnMesh.getCurrentUVSetName( currentUVSetName ); { MStringArray UVSetNames; fnMesh.getUVSetNames( UVSetNames ); for ( unsigned i( 0 ); i<numUVSets; i++ ) if ( UVSetNames[i] != currentUVSetName ) extraUVSetNames.append( UVSetNames[i] ); } numFaces = fnMesh.numPolygons(); const unsigned numFaceVertices( fnMesh.numFaceVertices() ); if ( numPoints < 1 ) { // MGlobal::displayInfo( MString( "fnMesh: " ) + fnMesh.name() ); // cerr << "Liquid : Could not export degenerate mesh '"<< fnMesh.fullPathName( &astatus ).asChar() << "'" << endl << flush; return; } unsigned face = 0; unsigned faceVertex = 0; unsigned count; unsigned vertex; unsigned normal; float S; float T; MPoint point; liqTokenPointer pointsPointerPair; liqTokenPointer normalsPointerPair; liqTokenPointer pFaceVertexSPointer; liqTokenPointer pFaceVertexTPointer; // Allocate memory and tokens numFaces = numFaces; nverts = shared_array< liqInt >( new liqInt[ numFaces ] ); verts = shared_array< liqInt >( new liqInt[ numFaceVertices ] ); pointsPointerPair.set( "P", rPoint, numPoints ); pointsPointerPair.setDetailType( rVertex ); if ( numNormals == numPoints ) { normalsPointerPair.set( "N", rNormal, numPoints ); normalsPointerPair.setDetailType( rVertex ); } else { normalsPointerPair.set( "N", rNormal, numFaceVertices ); normalsPointerPair.setDetailType( rFaceVarying ); } // uv std::vector<liqTokenPointer> UVSetsArray; UVSetsArray.reserve( 1 + extraUVSetNames.length() ); liqTokenPointer currentUVSetUPtr; liqTokenPointer currentUVSetVPtr; liqTokenPointer currentUVSetNamePtr; liqTokenPointer extraUVSetsUPtr; liqTokenPointer extraUVSetsVPtr; liqTokenPointer extraUVSetsNamePtr; if(liqglo.liqglo_outputMeshAsRMSArrays) { currentUVSetUPtr.set( "s", rFloat, numFaceVertices ); currentUVSetUPtr.setDetailType( rFaceVarying ); currentUVSetVPtr.set( "t", rFloat, numFaceVertices ); currentUVSetVPtr.setDetailType( rFaceVarying ); currentUVSetNamePtr.set( "currentUVSet", rString, 1 ); currentUVSetNamePtr.setDetailType( rConstant ); if( numUVSets > 1 ) { extraUVSetsUPtr.set( "u_uvSet", rFloat, numFaceVertices, numUVSets-1 ); extraUVSetsUPtr.setDetailType( rFaceVarying ); extraUVSetsVPtr.set( "v_uvSet", rFloat, numFaceVertices, numUVSets-1 ); extraUVSetsVPtr.setDetailType( rFaceVarying ); extraUVSetsNamePtr.set( "extraUVSets", rString, numUVSets-1 ); extraUVSetsNamePtr.setDetailType( rConstant ); } } else { if ( numUVSets > 0 ) { liqTokenPointer pFaceVertexPointerPair; pFaceVertexPointerPair.set( "st", rFloat, numFaceVertices, 2 ); pFaceVertexPointerPair.setDetailType( rFaceVarying ); UVSetsArray.push_back( pFaceVertexPointerPair ); for ( unsigned j( 0 ); j<extraUVSetNames.length(); j++) { liqTokenPointer pFaceVertexPointerPair; pFaceVertexPointerPair.set( extraUVSetNames[j].asChar(), rFloat, numFaceVertices, 2 ); pFaceVertexPointerPair.setDetailType( rFaceVarying ); UVSetsArray.push_back( pFaceVertexPointerPair ); } if( liqglo.liqglo_outputMeshUVs ) { // Match MTOR, which also outputs face-varying STs as well for some reason - Paul // not anymore - Philippe pFaceVertexSPointer.set( "u", rFloat, numFaceVertices ); pFaceVertexSPointer.setDetailType( rFaceVarying ); pFaceVertexTPointer.set( "v", rFloat, numFaceVertices ); pFaceVertexTPointer.setDetailType( rFaceVarying ); } } } vertexParam = pointsPointerPair.getTokenFloatArray(); normalParam = normalsPointerPair.getTokenFloatArray(); // Read the mesh from Maya MFloatVectorArray normals; fnMesh.getNormals( normals ); for ( MItMeshPolygon polyIt ( mesh ); polyIt.isDone() == false; polyIt.next() ) { count = polyIt.polygonVertexCount(); nverts[face] = count; for( i=0; i<count; i++ ) // boucle sur les vertex de la face { vertex = polyIt.vertexIndex( i ); verts[faceVertex] = vertex; point = polyIt.point( i, MSpace::kObject ); pointsPointerPair.setTokenFloat( vertex, point.x, point.y, point.z ); normal = polyIt.normalIndex( i ); if( numNormals == numPoints ) normalsPointerPair.setTokenFloat( vertex, normals[normal].x, normals[normal].y, normals[normal].z ); else normalsPointerPair.setTokenFloat( faceVertex, normals[normal].x, normals[normal].y, normals[normal].z ); if( liqglo.liqglo_outputMeshAsRMSArrays ) { for( j=0; j<numUVSets; j++ ) { if(j==0) { MString uvSetName = currentUVSetName; // set uvSet name currentUVSetNamePtr.setTokenString( 0, currentUVSetName.asChar() ); // set uv values fnMesh.getPolygonUV( face, i, S, T, &uvSetName ); currentUVSetUPtr.setTokenFloat( faceVertex, S ); currentUVSetVPtr.setTokenFloat( faceVertex, 1-T ); } else { MString uvSetName = extraUVSetNames[j-1]; // set uvSet name extraUVSetsNamePtr.setTokenString( j-1, extraUVSetNames[j-1].asChar() ); // set uv values fnMesh.getPolygonUV( face, i, S, T, &uvSetName ); extraUVSetsUPtr.setTokenFloat( (numFaceVertices*(j-1)) + faceVertex, S ); extraUVSetsVPtr.setTokenFloat( (numFaceVertices*(j-1)) + faceVertex, 1-T ); } } } else { if ( numUVSets ) { for( j=0; j<numUVSets; j++ ) { MString uvSetName; if(j==0) { uvSetName = currentUVSetName; } else { uvSetName = extraUVSetNames[j-1]; } fnMesh.getPolygonUV( face, i, S, T, &uvSetName ); UVSetsArray[j].setTokenFloat( faceVertex, 0, S ); UVSetsArray[j].setTokenFloat( faceVertex, 1, 1-T ); //printf("V%d %s : %f %f => %f %f \n", i, uvSetName.asChar(), S, T, S, 1-T); if( liqglo.liqglo_outputMeshUVs && j==0) { // Match MTOR, which always outputs face-varying STs as well for some reason - Paul pFaceVertexSPointer.setTokenFloat( faceVertex, S ); pFaceVertexTPointer.setTokenFloat( faceVertex, 1-T ); } } } } // printf( "[%d] faceVertex = %d vertex = %d\n", i, faceVertex, vertex ); ++faceVertex; } ++face; } // Add tokens to array and clean up after tokenPointerArray.push_back( pointsPointerPair ); tokenPointerArray.push_back( normalsPointerPair ); if(liqglo.liqglo_outputMeshAsRMSArrays) { tokenPointerArray.push_back( currentUVSetNamePtr ); tokenPointerArray.push_back( currentUVSetUPtr ); tokenPointerArray.push_back( currentUVSetVPtr ); if( numUVSets > 1 ) { tokenPointerArray.push_back( extraUVSetsNamePtr ); tokenPointerArray.push_back( extraUVSetsUPtr ); tokenPointerArray.push_back( extraUVSetsVPtr ); } } else { if( UVSetsArray.size() ) tokenPointerArray.insert( tokenPointerArray.end(), UVSetsArray.begin(), UVSetsArray.end() ); if( liqglo.liqglo_outputMeshUVs ) { tokenPointerArray.push_back( pFaceVertexSPointer ); tokenPointerArray.push_back( pFaceVertexTPointer ); } } addAdditionalSurfaceParameters( mesh ); }
/* * get maya poly mesh data */ bool liqRibMeshData::getMayaData( MObject mesh, bool useNormals ) { bool ret = true; // LIQDEBUGPRINTF( "-> mesh getMayaData (useNormals = %s )\n", ( ( useNormals )? "Yes" : "No" ) ); MFnMesh fnMesh( mesh ); objDagPath = fnMesh.dagPath(); MStatus astatus; name = fnMesh.name(); longName = fnMesh.fullPathName(); numPoints = fnMesh.numVertices(); numFaces = fnMesh.numPolygons(); if ( useNormals ) numNormals = fnMesh.numNormals(); if ( numPoints < 1 ) { liquidMessage( "Could not export degenerate mesh " + longName, messageInfo ); return false; } // UV sets ------------------- // //const unsigned numSTs( fnMesh.numUVs() ); const unsigned numUVSets( fnMesh.numUVSets() ); MString currentUVSetName; fnMesh.getCurrentUVSetName( currentUVSetName ); MStringArray extraUVSetNames; MStringArray UVSetNames; fnMesh.getUVSetNames( UVSetNames ); for ( unsigned i( 0 ); i < numUVSets ; i++ ) if ( UVSetNames[i] != currentUVSetName ) extraUVSetNames.append( UVSetNames[i] ); const unsigned numFaceVertices( fnMesh.numFaceVertices() ); unsigned face ( 0 ); unsigned faceVertex ( 0 ); unsigned count; unsigned vertex; unsigned normal; float S; float T; MPoint point; liqTokenPointer pointsPointerPair; liqTokenPointer normalsPointerPair; liqTokenPointer pFaceVertexSPointer; liqTokenPointer pFaceVertexTPointer; // Allocate memory and tokens nverts = shared_array< RtInt >( new RtInt[ numFaces ] ); verts = shared_array< RtInt >( new RtInt[ numFaceVertices ] ); pointsPointerPair.set( "P", rPoint, numPoints ); pointsPointerPair.setDetailType( rVertex ); if ( useNormals ) { if ( numNormals == numPoints ) { normalsPointerPair.set( "N", rNormal, numPoints ); normalsPointerPair.setDetailType( rVertex ); } else { normalsPointerPair.set( "N", rNormal, numFaceVertices ); normalsPointerPair.setDetailType( rFaceVarying ); } } // uv std::vector<liqTokenPointer> UVSetsArray; UVSetsArray.reserve( 1 + extraUVSetNames.length() ); liqTokenPointer currentUVSetUPtr; liqTokenPointer currentUVSetVPtr; liqTokenPointer currentUVSetNamePtr; liqTokenPointer extraUVSetsUPtr; liqTokenPointer extraUVSetsVPtr; liqTokenPointer extraUVSetsNamePtr; if ( liqglo_outputMeshAsRMSArrays ) { currentUVSetUPtr.set( "s", rFloat, numFaceVertices ); currentUVSetUPtr.setDetailType( rFaceVarying ); currentUVSetVPtr.set( "t", rFloat, numFaceVertices ); currentUVSetVPtr.setDetailType( rFaceVarying ); currentUVSetNamePtr.set( "currentUVSet", rString, 1 ); currentUVSetNamePtr.setDetailType( rConstant ); if ( numUVSets > 1 ) { extraUVSetsUPtr.set( "u_uvSet", rFloat, numFaceVertices, numUVSets-1 ); extraUVSetsUPtr.setDetailType( rFaceVarying ); extraUVSetsVPtr.set( "v_uvSet", rFloat, numFaceVertices, numUVSets-1 ); extraUVSetsVPtr.setDetailType( rFaceVarying ); extraUVSetsNamePtr.set( "extraUVSets", rString, numUVSets-1 ); extraUVSetsNamePtr.setDetailType( rConstant ); } } else { if ( numUVSets > 0 ) { liqTokenPointer pFaceVertexPointerPair; pFaceVertexPointerPair.set( "st", rFloat, numFaceVertices, 2 ); pFaceVertexPointerPair.setDetailType( rFaceVarying ); UVSetsArray.push_back( pFaceVertexPointerPair ); for ( unsigned j( 0 ); j < extraUVSetNames.length() ; j++ ) { liqTokenPointer pFaceVertexPointerPair; pFaceVertexPointerPair.set( extraUVSetNames[j].asChar(), rFloat, numFaceVertices, 2 ); pFaceVertexPointerPair.setDetailType( rFaceVarying ); UVSetsArray.push_back( pFaceVertexPointerPair ); } if ( liqglo_outputMeshUVs ) { // Match MTOR, which also outputs face-varying STs as well for some reason - Paul // not anymore - Philippe pFaceVertexSPointer.set( "u", rFloat, numFaceVertices ); pFaceVertexSPointer.setDetailType( rFaceVarying ); pFaceVertexTPointer.set( "v", rFloat, numFaceVertices ); pFaceVertexTPointer.setDetailType( rFaceVarying ); } } } vertexParam = pointsPointerPair.getTokenFloatArray(); MFloatVectorArray normals; // Read the mesh normals from Maya if ( useNormals ) { normalParam = normalsPointerPair.getTokenFloatArray(); fnMesh.getNormals( normals ); } for ( MItMeshPolygon polyIt ( mesh ); polyIt.isDone() == false ; polyIt.next() ) { count = polyIt.polygonVertexCount(); nverts[face] = count; unsigned j, i = count; // printf("poly count = %d\n", count ); while ( i ) { --i; vertex = polyIt.vertexIndex( i ); verts[faceVertex] = vertex; point = polyIt.point( i, MSpace::kObject ); pointsPointerPair.setTokenFloat( vertex, point.x, point.y, point.z ); if ( useNormals ) { normal = polyIt.normalIndex( i ); if ( numNormals == numPoints ) normalsPointerPair.setTokenFloat( vertex, normals[normal].x, normals[normal].y, normals[normal].z ); else normalsPointerPair.setTokenFloat( faceVertex, normals[normal].x, normals[normal].y, normals[normal].z ); } if ( liqglo_outputMeshAsRMSArrays ) { for ( j = 0 ; j < numUVSets ; j++ ) { if ( j == 0) { MString uvSetName = currentUVSetName; // set uvSet name currentUVSetNamePtr.setTokenString( 0, currentUVSetName.asChar() ); // set uv values fnMesh.getPolygonUV( face, i, S, T, &uvSetName ); currentUVSetUPtr.setTokenFloat( faceVertex, S ); currentUVSetVPtr.setTokenFloat( faceVertex, 1-T ); } else { MString uvSetName = extraUVSetNames[j-1]; // set uvSet name extraUVSetsNamePtr.setTokenString( j-1, extraUVSetNames[j-1].asChar() ); // set uv values fnMesh.getPolygonUV( face, i, S, T, &uvSetName ); extraUVSetsUPtr.setTokenFloat( (numFaceVertices*(j-1)) + faceVertex, S ); extraUVSetsVPtr.setTokenFloat( (numFaceVertices*(j-1)) + faceVertex, 1-T ); } } } else { if ( numUVSets ) { for( j = 0; j < numUVSets; j++ ) { MString uvSetName = ( j == 0 )? currentUVSetName: extraUVSetNames[ j - 1 ] ; fnMesh.getPolygonUV( face, i, S, T, &uvSetName ); UVSetsArray[j].setTokenFloat( faceVertex, 0, S ); UVSetsArray[j].setTokenFloat( faceVertex, 1, 1 - T ); //printf("V%d %s : %f %f => %f %f \n", i, uvSetName.asChar(), S, T, S, 1-T); if ( liqglo_outputMeshUVs && j==0) { // Match MTOR, which always outputs face-varying STs as well for some reason - Paul pFaceVertexSPointer.setTokenFloat( faceVertex, S ); pFaceVertexTPointer.setTokenFloat( faceVertex, 1 - T ); } } } } ++faceVertex; } ++face; } // Add tokens to array and clean up after tokenPointerArray.push_back( pointsPointerPair ); if ( useNormals ) tokenPointerArray.push_back( normalsPointerPair ); if ( liqglo_outputMeshAsRMSArrays ) { tokenPointerArray.push_back( currentUVSetNamePtr ); tokenPointerArray.push_back( currentUVSetUPtr ); tokenPointerArray.push_back( currentUVSetVPtr ); if ( numUVSets > 1 ) { tokenPointerArray.push_back( extraUVSetsNamePtr ); tokenPointerArray.push_back( extraUVSetsUPtr ); tokenPointerArray.push_back( extraUVSetsVPtr ); } } else { if ( UVSetsArray.size() ) tokenPointerArray.insert( tokenPointerArray.end(), UVSetsArray.begin(), UVSetsArray.end() ); if ( liqglo_outputMeshUVs ) { tokenPointerArray.push_back( pFaceVertexSPointer ); tokenPointerArray.push_back( pFaceVertexTPointer ); } } return ret; }
MStatus liqAttachPrefAttribute::redoIt() { MFnTypedAttribute tAttr; MStatus status; for ( unsigned i( 0 ); i < objectNames.length(); i++ ) { MSelectionList nodeList; nodeList.add( objectNames[i] ); MObject depNodeObj; nodeList.getDependNode( 0, depNodeObj ); MDagPath dagNode; nodeList.getDagPath( 0, dagNode ); MFnDependencyNode depNode( depNodeObj ); MObject prefAttr; MString attrName, varName; // make sure the renderer description is up to date liqglo.liquidRenderer.setRenderer(); // build the name of the attribute varName = ( ( exportN && depNodeObj.hasFn( MFn::kMesh ) )? "N":"P" ); attrName = "rman"; attrName += varName; attrName += ( ( liqglo.liquidRenderer.requires__PREF )? "__":"" ); attrName += varName + "ref"; // create the attribute prefAttr = tAttr.create( attrName, attrName, MFnData::kPointArray ); if ( depNodeObj.hasFn( MFn::kNurbsSurface ) ) { MFnNurbsSurface nodeFn( depNodeObj ); MPointArray nodePArray; MItSurfaceCV cvs( dagNode, MObject::kNullObj, liqglo.liquidRenderer.requires_SWAPPED_UVS == false, &status ); while( !cvs.isDone() ) { while( !cvs.isRowDone() ) { MPoint pt = (worldSpace)? cvs.position( MSpace::kWorld ) : cvs.position( MSpace::kObject ); nodePArray.append( pt ); cvs.next(); } cvs.nextRow(); } nodeFn.addAttribute( prefAttr ); MFnPointArrayData pArrayData; MObject prefDefault = pArrayData.create( nodePArray ); MPlug nodePlug( depNodeObj, prefAttr ); nodePlug.setValue( prefDefault ); } else if ( depNodeObj.hasFn( MFn::kNurbsCurve ) ) { // Carsten: added support for PREF on nurbs curves // MFnNurbsCurve nodeFn( depNodeObj ); MPointArray nodePArray; nodeFn.getCVs( nodePArray ); nodeFn.addAttribute( prefAttr ); MFnPointArrayData pArrayData; MObject prefDefault = pArrayData.create( nodePArray ); MPlug nodePlug( depNodeObj, prefAttr ); nodePlug.setValue( prefDefault ); } else if ( depNodeObj.hasFn( MFn::kMesh ) ) { MFnMesh nodeFn( depNodeObj ); // Moritz: modified this line to dim nodePArray -- otherwise // nodePArray.set() in the wile loop below throws an exception // which was why __Pref didn't work MPointArray nodePArray( MFnMesh( depNodeObj ).numVertices() ); unsigned count; nodeFn.addAttribute( prefAttr ); if ( exportN ) { // export Nref unsigned vertex; unsigned normal; unsigned face = 0; unsigned faceVertex = 0; unsigned int numNormals = nodeFn.numNormals(); unsigned int numPoints = nodeFn.numVertices(); MFloatVectorArray normals; MVectorArray normalAttArray; nodeFn.getNormals( normals ); if ( numNormals > numPoints ) { // if we get more than 1 normal per vertex, // force the arraysize to the full facevarying size unsigned faceVaryingCount( 0 ); for ( unsigned pOn( 0 ); pOn < nodeFn.numPolygons(); pOn++ ) faceVaryingCount += nodeFn.polygonVertexCount( pOn ); normalAttArray.setLength( faceVaryingCount ); } else normalAttArray.setLength(normals.length()); for ( MItMeshPolygon polyIt ( depNodeObj ); polyIt.isDone() == false; polyIt.next() ) { count = polyIt.polygonVertexCount(); while ( count > 0 ) { --count; normal = polyIt.normalIndex( count ); vertex = polyIt.vertexIndex( count ); if( numNormals == numPoints ) normalAttArray.set(normals[normal], vertex); else normalAttArray.set(normals[normal], faceVertex); ++faceVertex; } ++face; } MFnVectorArrayData pArrayData; MObject prefDefault = pArrayData.create( normalAttArray ); MPlug nodePlug( depNodeObj, prefAttr ); nodePlug.setValue( prefDefault ); } else { // TODO: do we need to account for the altMeshExport algo that's // used in liquidRibMeshData? // Moritz: no, it's basically the same as the algo below for ( MItMeshPolygon polyIt( dagNode, MObject::kNullObj ); !polyIt.isDone(); polyIt.next()) { count = polyIt.polygonVertexCount(); while ( count > 0 ) { --count; unsigned vertexIndex = polyIt.vertexIndex( count ); MPoint nodePoint = (worldSpace)? polyIt.point( count, MSpace::kWorld ) : polyIt.point( count, MSpace::kObject ); // Moritz: this returns MS::kFailure but seems to work?! nodePArray.set( nodePoint, vertexIndex ); } } MFnPointArrayData pArrayData; MObject prefDefault = pArrayData.create( nodePArray ); MPlug nodePlug( depNodeObj, prefAttr ); nodePlug.setValue( prefDefault ); } } else cerr << "Neither a Nurbs nor a Mesh !!" << endl; } return MS::kSuccess; }
//------------------------------------------------------------------------------------------------------------------------------------------- void visualizeMeshNode::drawShadedTriangles(MItMeshPolygon& polyIter, MItMeshVertex& vertIter, M3dView::DisplayStyle style, meshStatus meshStat) //------------------------------------------------------------------------------------------------------------------------------------------- { //alles zeichnen glPushAttrib(GL_ALL_ATTRIB_BITS); glEnable(GL_POLYGON_OFFSET_FILL); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //glDepthMask(GL_FALSE); glPolygonMode(GL_BACK, GL_FILL); glShadeModel(GL_SMOOTH); //Dass muss ausßerhalb der displayList bleiben, weil dieser Wert nicht precompiliert werden darf float param1 = 0.45, param2 = 0.55; // im DebugMode werden die Params anhand der NodeParameter gesetzt if(style == M3dView::kWireFrame) { param1 = 0.45; param2 = 0.55; } else { switch(meshStat) { case kNone: { param1 = -0.5; param2 = -0.6; break; } case kHilited: { param1 = 0.45; param2 = 0.55; break; } } } #ifdef DEBUG MPlug tmpPlug(thisMObject(), pOffset1Obj); tmpPlug.getValue(param1); tmpPlug.setAttribute(pOffset2Obj); tmpPlug.getValue(param2); #endif glPolygonOffset( param1, param2 ); //jedes Poly zeichnen uint numPolys = polyIter.count(); uint i, x , l; MPoint point; MColor tmpCol; MPointArray triPoints; MIntArray triVtx; //glColor4f(0.0f, 0.0f, 1.0f, 0.2); for(i = 0; i < numPolys; i++, polyIter.next()) { polyIter.getTriangles(triPoints, triVtx); l = triVtx.length(); glBegin(GL_TRIANGLES); for(x = 0; x < l ; x+=3) { //view.setDrawColor( getCalColor(vtxColor, MColor(1.0,0.0,0.0), vtxWeightArray[ polyVtx[x] ] ) ); //view.setDrawColor( vtxColor * vtxWeightArray[ polyVtx[x] ]); //glColor4f(0.0f, 0.0f, 1.0f, vtxWeightArray[ polyVtx[x] ]); tmpCol = getCalColor(vtxColor, vtxColor2 , vtxWeightArray[ triVtx[x] ]); glColor4f(tmpCol.r, tmpCol.g,tmpCol.b, vtxWeightArray[ triVtx[x] ]); glVertex3d(triPoints[x].x, triPoints[x].y, triPoints[x].z); tmpCol = getCalColor(vtxColor, vtxColor2 , vtxWeightArray[ triVtx[x+1] ]); glColor4f(tmpCol.r, tmpCol.g,tmpCol.b, vtxWeightArray[ triVtx[x+1] ]); glVertex3d(triPoints[x+1].x, triPoints[x+1].y, triPoints[x+1].z); tmpCol = getCalColor(vtxColor, vtxColor2 , vtxWeightArray[ triVtx[x+2] ]); glColor4f(tmpCol.r, tmpCol.g,tmpCol.b, vtxWeightArray[ triVtx[x+2] ]); glVertex3d(triPoints[x+2].x, triPoints[x+2].y, triPoints[x+2].z); } glEnd(); } // glDisable(GL_POLYGON_OFFSET_FILL); glPopAttrib(); }
// -------------------------------------------------------- void GeometryPolygonExporter::writeVertexIndices ( COLLADASW::PrimitivesBase* primitivesBasePoly, PolygonSource *polygon, const int vertexIndex, const MIntArray &normalIndices, const int iteratorVertexIndex, MItMeshPolygon &meshPolygonsIter, MFnMesh &fnMesh, const int polyIndex ) { // Dump the indices size_t numAttributes = polygon->getVertexAttributes().size(); // Output each vertex attribute we need for ( size_t kk=0; kk<numAttributes; ++kk ) { const SourceInput& vertexAttributes = polygon->getVertexAttributes()[kk]; COLLADASW::InputSemantic::Semantics type = vertexAttributes.getType(); switch ( vertexAttributes.getType() ) { case COLLADASW::InputSemantic::VERTEX: case COLLADASW::InputSemantic::POSITION: primitivesBasePoly->appendValues ( vertexIndex ); break; case COLLADASW::InputSemantic::NORMAL: case COLLADASW::InputSemantic::TANGENT: case COLLADASW::InputSemantic::BINORMAL: { if (mHasFaceVertexNormals) { // The tangent and the binormal can use the index of the normal int currentVertexIndex = normalIndices [iteratorVertexIndex]; primitivesBasePoly->appendValues ( currentVertexIndex ); } else { // Assert, if we don't have initialized the normal indices, // but want to read them out here! MGlobal::displayError("No face vertex normals to proceed!"); COLLADABU_ASSERT ( mHasFaceVertexNormals ); return; } } break; case COLLADASW::InputSemantic::TEXTANGENT: case COLLADASW::InputSemantic::TEXBINORMAL: { // The texture binormal can use the index of the texture tangent. unsigned int texTangentIndex2 = meshPolygonsIter.tangentIndex ( iteratorVertexIndex ); primitivesBasePoly->appendValues ( texTangentIndex2 ); } break; case COLLADASW::InputSemantic::TEXCOORD: { int uvIndex = 0; int idx = vertexAttributes.getIdx(); meshPolygonsIter.getUVIndex ( iteratorVertexIndex, uvIndex, &mUvSetNames[idx] ); primitivesBasePoly->appendValues ( uvIndex ); } break; case COLLADASW::InputSemantic::COLOR: { MString& colorSetName = mColorSetNames[vertexAttributes.getIdx()]; int colorIndex = 0; { #if MAYA_API_VERSION >= 700 fnMesh.getColorIndex ( polyIndex, iteratorVertexIndex, colorIndex, &colorSetName ); #else fnMesh.getFaceVertexColorIndex ( polyIndex, iteratorVertexIndex, colorIndex ); #endif } primitivesBasePoly->appendValues ( colorIndex ); } break; case COLLADASW::InputSemantic::UNKNOWN: case COLLADASW::InputSemantic::UV: // case COLLADASW::EXTRA: default: break; // Not exported/supported } } }
// -------------------------------------------------------- void GeometryPolygonExporter::retrieveVertexIndices ( MIntArray &vertexIndices, MItMeshPolygon &meshPolygonsIter, uint &numPolygons, uint &numVertices ) { // 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 ) { numVertices = 3; MPointArray vertexPositions; MIntArray meshVertexIndices; meshPolygonsIter.getTriangles ( vertexPositions, meshVertexIndices ); vertexIndices.setLength ( meshVertexIndices.length() ); numPolygons = meshVertexIndices.length() / numVertices; // Map the vertex indices to iterator vertex indices so that we can // get information from the iterator about normals and such. uint meshVertexIndexCount = meshVertexIndices.length(); for ( uint mvi = 0; mvi < meshVertexIndexCount; ++mvi ) { int meshVertexIndex = meshVertexIndices[mvi]; int polygonVertexCount = meshPolygonsIter.polygonVertexCount(); int iteratorVertexIndex = 0; for ( int pv = 0; pv < polygonVertexCount; ++pv ) { if ( ( int ) meshPolygonsIter.vertexIndex ( pv ) == meshVertexIndex ) { iteratorVertexIndex = pv; } } vertexIndices[mvi] = iteratorVertexIndex; } } else numPolygons = 0; } else if ( polygonVertexCount >= 3 ) { numPolygons = 1; vertexIndices.setLength ( polygonVertexCount ); for ( int pv = 0; pv < polygonVertexCount; ++pv ) { vertexIndices[pv] = pv; } #ifdef VALIDATE_DATA // Skip over any duplicate vertices in this face. // Very rarely, a cunning user manages to corrupt // a face entry on the mesh and somehow configure // a face to include the same vertex multiple times. // This will cause the read-back of this data to // reject the face, and can crash other COLLADA // consumers, so better to lose the data here for ( uint n = 0; n < vertexIndices.length() - 1; ++n ) { for ( uint m = n + 1; m < vertexIndices.length(); ) { if ( vertexIndices[n] == vertexIndices[m] ) { vertexIndices.remove ( m ); } else ++m; } } // Get the number of vertices of the current polygon. numVertices = vertexIndices->length(); #else // Get the number of vertices of the current polygon. numVertices = polygonVertexCount; #endif } }
/** Create a RIB compatible subdivision surface representation using a Maya polygon mesh. */ liqRibSubdivisionData::liqRibSubdivisionData( MObject mesh ) : numFaces( 0 ), numPoints ( 0 ), nverts(), verts(), vertexParam( NULL ), interpolateBoundary( 0 ), uvDetail( rFaceVarying ), trueFacevarying( false ) { CM_TRACE_FUNC("liqRibSubdivisionData::liqRibSubdivisionData("<<MFnDagNode(mesh).fullPathName()<<")"); LIQDEBUGPRINTF( "-> creating subdivision surface\n" ); MFnMesh fnMesh( mesh ); name = fnMesh.name(); longName = fnMesh.fullPathName(); checkExtraTags( mesh ); numPoints = fnMesh.numVertices(); // UV sets ----------------- // const unsigned numSTs = fnMesh.numUVs(); const unsigned numUVSets = fnMesh.numUVSets(); MString currentUVSetName; MStringArray extraUVSetNames; fnMesh.getCurrentUVSetName( currentUVSetName ); MStringArray UVSetNames; fnMesh.getUVSetNames( UVSetNames ); for ( unsigned i( 0 ); i < numUVSets; i++ ) if( UVSetNames[i] != currentUVSetName ) extraUVSetNames.append( UVSetNames[i] ); numFaces = fnMesh.numPolygons(); const unsigned numFaceVertices( fnMesh.numFaceVertices() ); unsigned face( 0 ); unsigned faceVertex( 0 ); unsigned count; unsigned vertex; float S; float T; MPoint point; liqTokenPointer pointsPointerPair; liqTokenPointer pFaceVertexSPointer; liqTokenPointer pFaceVertexTPointer; // Allocate memory and tokens nverts = shared_array< RtInt >( new RtInt[ numFaces ] ); verts = shared_array< RtInt >( new RtInt[ numFaceVertices ] ); pointsPointerPair.set( "P", rPoint, numPoints ); pointsPointerPair.setDetailType( rVertex ); std::vector<liqTokenPointer> UVSetsArray; UVSetsArray.reserve( 1 + extraUVSetNames.length() ); if( numSTs > 0 ) { liqTokenPointer pFaceVertexPointerPair; pFaceVertexPointerPair.set( "st", rFloat, numFaceVertices, 2 ); pFaceVertexPointerPair.setDetailType( uvDetail ); UVSetsArray.push_back( pFaceVertexPointerPair ); for ( unsigned j( 0 ); j<extraUVSetNames.length(); j++) { liqTokenPointer pFaceVertexPointerPair; pFaceVertexPointerPair.set( extraUVSetNames[j].asChar(), rFloat, numFaceVertices, 2 ); pFaceVertexPointerPair.setDetailType( uvDetail ); UVSetsArray.push_back( pFaceVertexPointerPair ); } if( liqglo.liqglo_outputMeshUVs ) { // Match MTOR, which also outputs face-varying STs as well for some reason - Paul // not anymore - Philippe pFaceVertexSPointer.set( "u", rFloat, numFaceVertices ); pFaceVertexSPointer.setDetailType( uvDetail ); pFaceVertexTPointer.set( "v", rFloat, numFaceVertices ); pFaceVertexTPointer.setDetailType( uvDetail ); } } vertexParam = pointsPointerPair.getTokenFloatArray(); // Read the mesh from Maya for ( MItMeshPolygon polyIt ( mesh ); polyIt.isDone() == false; polyIt.next() ) { count = polyIt.polygonVertexCount(); nverts[face] = count; unsigned i = count; while( i ) { --i; vertex = polyIt.vertexIndex( i ); verts[faceVertex] = vertex; point = polyIt.point( i, MSpace::kObject ); pointsPointerPair.setTokenFloat( vertex, point.x, point.y, point.z ); if( UVSetsArray.size() ) { fnMesh.getPolygonUV( face, i, S, T ); UVSetsArray[0].setTokenFloat( faceVertex, 0, S ); UVSetsArray[0].setTokenFloat( faceVertex, 1, 1 - T ); for ( unsigned j( 1 ); j<=extraUVSetNames.length(); j++ ) { fnMesh.getPolygonUV( face, i, S, T, &extraUVSetNames[j] ); UVSetsArray[j].setTokenFloat( faceVertex, 0, S ); UVSetsArray[j].setTokenFloat( faceVertex, 1, 1 - T ); } if( liqglo.liqglo_outputMeshUVs ) { // Match MTOR, which always outputs face-varying STs as well for some reason - Paul pFaceVertexSPointer.setTokenFloat( faceVertex, S ); pFaceVertexTPointer.setTokenFloat( faceVertex, 1 - T ); } } ++faceVertex; } ++face; } // Add tokens to array and clean up after tokenPointerArray.push_back( pointsPointerPair ); if( UVSetsArray.size() ) tokenPointerArray.insert( tokenPointerArray.end(), UVSetsArray.begin(), UVSetsArray.end() ); if( liqglo.liqglo_outputMeshUVs ) { assert( !pFaceVertexSPointer ); tokenPointerArray.push_back( pFaceVertexSPointer ); assert( !pFaceVertexTPointer ); tokenPointerArray.push_back( pFaceVertexTPointer ); } addAdditionalSurfaceParameters( mesh ); }
// -------------------------------------------------------- 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(); } }