// ---------------------------------------- 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 ); } }
/** 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::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 ); } }
/** 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 ); }