bool HesperisPolygonalMeshIO::CreateMeshData(APolygonalMesh * data, const MDagPath & path) { MGlobal::displayInfo(MString("todo poly mesh write ")+path.fullPathName()); MStatus stat; MFnMesh fmesh(path.node(), &stat); if(!stat) { MGlobal::displayInfo(MString(" not a mesh ") + path.fullPathName()); return false; } unsigned np = fmesh.numVertices(); unsigned nf = fmesh.numPolygons(); unsigned ni = fmesh.numFaceVertices(); data->create(np, ni, nf); Vector3F * pnts = data->points(); unsigned * inds = data->indices(); unsigned * cnts = data->faceCounts(); MPointArray ps; MPoint wp; MMatrix worldTm; worldTm = GetWorldTransform(path); fmesh.getPoints(ps, MSpace::kObject); unsigned i = 0; for(;i<np;i++) { wp = ps[i] * worldTm; pnts[i].set((float)wp.x, (float)wp.y, (float)wp.z); } unsigned j; unsigned acc = 0; MIntArray vertices; MItMeshPolygon faceIt(path); for(i=0; !faceIt.isDone(); faceIt.next(), i++) { cnts[i] = faceIt.polygonVertexCount(); faceIt.getVertices(vertices); for(j = 0; j < vertices.length(); j++) { inds[acc] = vertices[j]; acc++; } } data->computeFaceDrift(); return true; }
void LuxRenderer::defineTriangleMesh(mtlu_MayaObject *obj, bool noObjectDef = false) { MObject meshObject = obj->mobject; MStatus stat = MStatus::kSuccess; MFnMesh meshFn(meshObject, &stat); CHECK_MSTATUS(stat); MItMeshPolygon faceIt(meshObject, &stat); CHECK_MSTATUS(stat); MPointArray points; meshFn.getPoints(points); MFloatVectorArray normals; meshFn.getNormals( normals, MSpace::kWorld ); MFloatArray uArray, vArray; meshFn.getUVs(uArray, vArray); logger.debug(MString("Translating mesh object ") + meshFn.name().asChar()); MString meshFullName = obj->fullNiceName; MIntArray trianglesPerFace, triVertices; meshFn.getTriangles(trianglesPerFace, triVertices); int numTriangles = 0; for( size_t i = 0; i < trianglesPerFace.length(); i++) numTriangles += trianglesPerFace[i]; // lux render does not have a per vertex per face normal definition, here we can use one normal and uv per vertex only // So I create the triangles with unique vertices, normals and uvs. Of course this way vertices etc. cannot be shared. int numPTFloats = numTriangles * 3 * 3; logger.debug(MString("Num Triangles: ") + numTriangles + " num tri floats " + numPTFloats); float *floatPointArray = new float[numPTFloats]; float *floatNormalArray = new float[numPTFloats]; float *floatUvArray = new float[numTriangles * 3 * 2]; logger.debug(MString("Allocated ") + numPTFloats + " floats for point and normals"); MIntArray triangelVtxIdListA; MFloatArray floatPointArrayA; MPointArray triPoints; MIntArray triVtxIds; MIntArray faceVtxIds; MIntArray faceNormalIds; int *triangelVtxIdList = new int[numTriangles * 3]; for( uint sgId = 0; sgId < obj->shadingGroups.length(); sgId++) { MString slotName = MString("slot_") + sgId; } int triCount = 0; int vtxCount = 0; for(faceIt.reset(); !faceIt.isDone(); faceIt.next()) { int faceId = faceIt.index(); int numTris; faceIt.numTriangles(numTris); faceIt.getVertices(faceVtxIds); MIntArray faceUVIndices; faceNormalIds.clear(); for( uint vtxId = 0; vtxId < faceVtxIds.length(); vtxId++) { faceNormalIds.append(faceIt.normalIndex(vtxId)); int uvIndex; faceIt.getUVIndex(vtxId, uvIndex); faceUVIndices.append(uvIndex); } int perFaceShadingGroup = 0; if( obj->perFaceAssignments.length() > 0) perFaceShadingGroup = obj->perFaceAssignments[faceId]; //logger.info(MString("Face ") + faceId + " will receive SG " + perFaceShadingGroup); for( int triId = 0; triId < numTris; triId++) { int faceRelIds[3]; faceIt.getTriangle(triId, triPoints, triVtxIds); for( uint triVtxId = 0; triVtxId < 3; triVtxId++) { for(uint faceVtxId = 0; faceVtxId < faceVtxIds.length(); faceVtxId++) { if( faceVtxIds[faceVtxId] == triVtxIds[triVtxId]) { faceRelIds[triVtxId] = faceVtxId; } } } uint vtxId0 = faceVtxIds[faceRelIds[0]]; uint vtxId1 = faceVtxIds[faceRelIds[1]]; uint vtxId2 = faceVtxIds[faceRelIds[2]]; uint normalId0 = faceNormalIds[faceRelIds[0]]; uint normalId1 = faceNormalIds[faceRelIds[1]]; uint normalId2 = faceNormalIds[faceRelIds[2]]; uint uvId0 = faceUVIndices[faceRelIds[0]]; uint uvId1 = faceUVIndices[faceRelIds[1]]; uint uvId2 = faceUVIndices[faceRelIds[2]]; floatPointArray[vtxCount * 3] = points[vtxId0].x; floatPointArray[vtxCount * 3 + 1] = points[vtxId0].y; floatPointArray[vtxCount * 3 + 2] = points[vtxId0].z; floatNormalArray[vtxCount * 3] = normals[normalId0].x; floatNormalArray[vtxCount * 3 + 1] = normals[normalId0].y; floatNormalArray[vtxCount * 3 + 2] = normals[normalId0].z; floatUvArray[vtxCount * 2] = uArray[uvId0]; floatUvArray[vtxCount * 2 + 1] = vArray[uvId0]; vtxCount++; floatPointArray[vtxCount * 3] = points[vtxId1].x; floatPointArray[vtxCount * 3 + 1] = points[vtxId1].y; floatPointArray[vtxCount * 3 + 2] = points[vtxId1].z; floatNormalArray[vtxCount * 3] = normals[normalId1].x; floatNormalArray[vtxCount * 3 + 1] = normals[normalId1].y; floatNormalArray[vtxCount * 3 + 2] = normals[normalId1].z; floatUvArray[vtxCount * 2] = uArray[uvId1]; floatUvArray[vtxCount * 2 + 1] = vArray[uvId1]; vtxCount++; floatPointArray[vtxCount * 3] = points[vtxId2].x; floatPointArray[vtxCount * 3 + 1] = points[vtxId2].y; floatPointArray[vtxCount * 3 + 2] = points[vtxId2].z; floatNormalArray[vtxCount * 3] = normals[normalId2].x; floatNormalArray[vtxCount * 3 + 1] = normals[normalId2].y; floatNormalArray[vtxCount * 3 + 2] = normals[normalId2].z; floatUvArray[vtxCount * 2] = uArray[uvId2]; floatUvArray[vtxCount * 2 + 1] = vArray[uvId2]; vtxCount++; //logger.debug(MString("Vertex count: ") + vtxCount + " maxId " + ((vtxCount - 1) * 3 + 2) + " ptArrayLen " + (numTriangles * 3 * 3)); triangelVtxIdList[triCount * 3] = triCount * 3; triangelVtxIdList[triCount * 3 + 1] = triCount * 3 + 1; triangelVtxIdList[triCount * 3 + 2] = triCount * 3 + 2; triCount++; } } //generatetangents bool Generate tangent space using miktspace, useful if mesh has a normal map that was also baked using miktspace (such as blender or xnormal) false //subdivscheme string Subdivision algorithm, options are "loop" and "microdisplacement" "loop" //displacementmap string Name of the texture used for the displacement. Subdivscheme parameter must always be provided, as load-time displacement is handled by the loop-subdivision code. none - optional. (loop subdiv can be used without displacement, microdisplacement will not affect the mesh without a displacement map specified) //dmscale float Scale of the displacement (for an LDR map, this is the maximum height of the displacement in meter) 0.1 //dmoffset float Offset of the displacement. 0 //dmnormalsmooth bool Smoothing of the normals of the subdivided faces. Only valid for loop subdivision. true //dmnormalsplit bool Force the mesh to split along breaks in the normal. If a mesh has no normals (flat-shaded) it will rip open on all edges. Only valid for loop subdivision. false //dmsharpboundary bool Try to preserve mesh boundaries during subdivision. Only valid for loop subdivision. false //nsubdivlevels integer Number of subdivision levels. This is only recursive for loop subdivision, microdisplacement will need much larger values (such as 50). 0 bool generatetangents = false; getBool(MString("mtlu_mesh_generatetangents"), meshFn, generatetangents); int subdivscheme = 0; const char *subdAlgos[] = {"loop", "microdisplacement"}; getInt(MString("mtlu_mesh_subAlgo"), meshFn, subdivscheme); const char *subdalgo = subdAlgos[subdivscheme]; float dmscale; getFloat(MString("mtlu_mesh_dmscale"), meshFn, dmscale); float dmoffset; getFloat(MString("mtlu_mesh_dmoffset"), meshFn, dmoffset); MString displacementmap; getString(MString("mtlu_mesh_displacementMap"), meshFn, displacementmap); const char *displacemap = displacementmap.asChar(); bool dmnormalsmooth = true; getBool(MString("mtlu_mesh_dmnormalsmooth"), meshFn, dmnormalsmooth); bool dmnormalsplit = false; getBool(MString("mtlu_mesh_dmnormalsplit"), meshFn, dmnormalsplit); bool dmsharpboundary = false; getBool(MString("mtlu_mesh_dmsharpboundary"), meshFn, dmsharpboundary); int nsubdivlevels = 0; getInt(MString("mtlu_mesh_subdivlevel"), meshFn, nsubdivlevels); // a displacment map needs its own texture defintion MString displacementTextureName = ""; if(displacementmap.length() > 0) { ParamSet dmParams = CreateParamSet(); dmParams->AddString("filename", &displacemap); displacementTextureName = meshFn.name() + "_displacementMap"; this->lux->texture(displacementTextureName.asChar(), "float", "imagemap", boost::get_pointer(dmParams)); } ParamSet triParams = CreateParamSet(); int numPointValues = numTriangles * 3; int numUvValues = numTriangles * 3 * 2; clock_t startTime = clock(); logger.info(MString("Adding mesh values to params.")); triParams->AddInt("indices", triangelVtxIdList, numTriangles * 3); triParams->AddPoint("P", floatPointArray, numPointValues); triParams->AddNormal("N", floatNormalArray, numPointValues); triParams->AddFloat("uv", floatUvArray, numUvValues); if( nsubdivlevels > 0) triParams->AddInt("nsubdivlevels", &nsubdivlevels, 1); triParams->AddBool("generatetangents", &generatetangents, 1); triParams->AddString("subdivscheme", &subdalgo , 1); if(displacementmap.length() > 0) { triParams->AddFloat("dmoffset", &dmoffset, 1); triParams->AddFloat("dmscale", &dmscale, 1); const char *dmft = displacementTextureName.asChar(); triParams->AddString("displacementmap", &dmft); } triParams->AddBool("dmnormalsmooth", &dmnormalsmooth, 1); triParams->AddBool("dmnormalsplit", &dmnormalsplit, 1); triParams->AddBool("dmsharpboundary", &dmsharpboundary, 1); clock_t pTime = clock(); if(!noObjectDef) this->lux->objectBegin(meshFullName.asChar()); this->lux->shape("trianglemesh", boost::get_pointer(triParams)); if(!noObjectDef) this->lux->objectEnd(); clock_t eTime = clock(); logger.info(MString("Timing: Parameters: ") + ((pTime - startTime)/CLOCKS_PER_SEC) + " objTime " + ((eTime - pTime)/CLOCKS_PER_SEC) + " all " + ((eTime - startTime)/CLOCKS_PER_SEC)); return; }
bool tm_polygon_edgestoring::calculate( MIntArray &edgesArray) { if(!objectIsSet) { MGlobal::displayError("tm_polygon_edgestoring::calculate - Object is not set."); return false; } MFnMesh meshFn( meshObject); MItMeshEdge edgeIt(meshObject); MItMeshPolygon faceIt(meshObject); unsigned numInputEdges = edgesArray.length(); int *visitedEdges = new int[numInputEdges]; for( unsigned e = 0; e < numInputEdges; e++) visitedEdges[e] = 0; std::list <int> ringEdgesList; int prevIndex; MIntArray faces; MIntArray edgeFaces; MIntArray faceEdges; int edgeIndex = edgesArray[0]; ringEdgesList.push_back( edgeIndex); visitedEdges[0] = 1; edgeIt.setIndex( edgeIndex, prevIndex); edgeIt.getConnectedFaces( faces); unsigned numFaces = faces.length(); unsigned numFaceEdges; for( unsigned face = 0; face < numFaces; face++) { edgeIndex = edgesArray[0]; int lastFace, newFace; if( face == 1) lastFace = faces[0]; else lastFace = -1; unsigned COUNTER = 0; while( COUNTER < 32000) { COUNTER++; edgeIt.setIndex( edgeIndex, prevIndex); edgeIt.getConnectedFaces( edgeFaces); if(edgeFaces.length() > 1) { if( edgeFaces[0] == lastFace) newFace = edgeFaces[1]; else newFace = edgeFaces[0]; } else newFace = edgeFaces[0]; faceIt.setIndex( newFace, prevIndex); lastFace = newFace; bool founded = false; for( unsigned e = 0; e < numInputEdges; e++) { if( edgesArray[e] == edgeIndex) continue; if( visitedEdges[e] == 1) continue; faceIt.getEdges( faceEdges); numFaceEdges = faceEdges.length(); for( unsigned fe = 0; fe < numFaceEdges; fe++) { if( faceEdges[fe] == edgesArray[e]) { founded = true; edgeIndex = edgesArray[e]; visitedEdges[e] = 1; if( face == 0) ringEdgesList.push_front( edgeIndex); else ringEdgesList.push_back( edgeIndex); } if( founded) break; } if( founded) break; } if(!founded) break; } } if (visitedEdges != NULL) delete [] visitedEdges; unsigned numRingEdges = (unsigned)ringEdgesList.size(); edgesArray.setLength( numRingEdges); for( unsigned e = 0; e < numRingEdges; e++) { edgesArray[e] = *ringEdgesList.begin(); ringEdgesList.pop_front(); } return true; }
MStatus tm_polySplitFty::doIt() // // Description: // Performs the actual tm_polySplit operation on the given object and UVs // { MStatus status = MS::kSuccess; MVector vector; MPoint point; MFnMesh meshFn( fMesh); int edgeVertices[2]; MItMeshEdge edgeIt( fMesh); int prevIndex; meshFn.getEdgeVertices( fSelEdges[0], edgeVertices); meshFn.getPoint( edgeVertices[0], point); meshFn.getPoint( edgeVertices[1], averagePos); averagePos = (point + averagePos) * 0.5; #ifdef _DEBUG cout << endl << "##########################tm_polySplitFty::doIt" << endl; cout<<"loop="<<fa_loop<<" loopMode="<<fa_loop_mode<<" loop_angle="<<fa_loop_angle<<" loop_maxcount="<<fa_maxcount<<endl; #endif //getting valid edges { if( fa_loop) { if(!getLoopFromFirst( fa_loop_mode, fa_loop_angle, fa_maxcount)) { MGlobal::displayError( "tm_polySplit command failed: Bad edges selected." ); return MStatus::kFailure; } } else { if(!getRing()) { MGlobal::displayError( "tm_polySplit command failed: Bad edges selected." ); return MStatus::kFailure; } } {// close edges: MIntArray conFacesA; edgeIt.setIndex( fSelEdges[0], prevIndex); edgeIt.getConnectedFaces( conFacesA); if( conFacesA.length() > 1) { MIntArray conFacesB; edgeIt.setIndex( fSelEdges[fSelEdges.length() - 1], prevIndex); edgeIt.getConnectedFaces( conFacesB); if( conFacesB.length() > 1) { if( conFacesA[0] == conFacesB[0]) fSelEdges.append( fSelEdges[0]); else if( conFacesA[0] == conFacesB[1]) fSelEdges.append( fSelEdges[0]); else if( conFacesA[1] == conFacesB[0]) fSelEdges.append( fSelEdges[0]); else if( conFacesA[1] == conFacesB[1]) fSelEdges.append( fSelEdges[0]); } } } } #ifdef _DEBUG cout << endl << "fSelEdges = ";for( unsigned i=0;i<fSelEdges.length();i++) cout << fSelEdges[i] << " ";cout << endl; #endif edgesCount = fSelEdges.length(); if(edgesCount < 2) { MGlobal::displayError( "tm_polySplit command failed: Can't find more than one ring edge." ); return MStatus::kFailure; } MItMeshVertex vtxIt( fMesh); MItMeshPolygon faceIt( fMesh); MIntArray conFaces; MIntArray conEdges; MIntArray faceEdges; unsigned numConFaces; if( firstTime) { splitedPoints_start_N.setLength( edgesCount); splitedPoints_dir_N.setLength( edgesCount); splitedPoints_ndir_N.setLength( edgesCount); splitedPoints_start_R.setLength( edgesCount); splitedPoints_dir_R.setLength( edgesCount); splitedPoints_ndir_R.setLength( edgesCount); oldVtxCount = meshFn.numVertices(); oldUVsCount = meshFn.numUVs(); #ifdef _DEBUG cout << endl << "oldVtxCount = " << oldVtxCount << endl; cout << endl << "oldUVsCount = " << oldUVsCount << endl; #endif //######################################## finding inverted edges invEdge.setLength(edgesCount); #ifdef _DEBUG cout << "### finding inverted edges:" << endl; #endif for( unsigned i = 0; i < edgesCount; i++) invEdge[i] = 0; int zero_vtx_index = 0; edgeIt.setIndex( fSelEdges[0], prevIndex); edgeIt.getConnectedFaces( conFaces); numConFaces = conFaces.length(); int nextEdgeId = -1; int nextFaceId = -1; for( unsigned cf = 0; cf < numConFaces; cf++) { faceIt.setIndex( conFaces[cf], prevIndex); faceIt.getEdges( faceEdges); unsigned numFaceEdges = faceEdges.length(); for( unsigned fe = 0; fe < numFaceEdges; fe++) { if( faceEdges[fe] == fSelEdges[1]) { nextFaceId = conFaces[cf]; break; } } if( nextEdgeId != -1) break; } if( nextFaceId == -1) { #ifdef _DEBUG cout << "nextFaceId == -1 (edgeId[" << fSelEdges[0] << "]);" << endl; #endif return MStatus::kFailure; } meshFn.getEdgeVertices( fSelEdges[0], edgeVertices); int vtxIndex = edgeVertices[zero_vtx_index]; unsigned e = 1; bool founded = true; int nextEdgeVertices[2]; int COUNTER = 0; while( e < edgesCount) { COUNTER++; if(COUNTER > 32000) { #ifdef _DEBUG cout << "(COUNTER > 32000) on finding inverted edges!" << endl; #endif break; } meshFn.getEdgeVertices( fSelEdges[e], nextEdgeVertices); vtxIt.setIndex( vtxIndex, prevIndex); vtxIt.getConnectedEdges( conEdges); unsigned numConEdges = conEdges.length(); faceIt.setIndex( nextFaceId, prevIndex); faceIt.getEdges( faceEdges); unsigned numFaceEdges = faceEdges.length(); #ifdef _DEBUG cout << COUNTER << ") edgeId = " << fSelEdges[e-1] << ", numConEdges = " << numConEdges; cout << ", vtxIndex = " << vtxIndex << ", nextFaceId = " << nextFaceId << ":" << endl; #endif bool nextEdgeId_founded = false; for( unsigned ce = 0; ce < numConEdges; ce++) { if((conEdges[ce] == fSelEdges[e-1]) || (conEdges[ce] == nextEdgeId)) continue; for( unsigned fe = 0; fe < numFaceEdges; fe++) { if( conEdges[ce] == faceEdges[fe]) { nextEdgeId = conEdges[ce]; nextEdgeId_founded = true; break; } } if( nextEdgeId_founded) break; } if(!nextEdgeId_founded) { #ifdef _DEBUG cout << "nextEdgeId was not founded, edge " << fSelEdges[e-1] << endl; cout << "connected edges: "; for( unsigned ce = 0; ce < numConEdges; ce++) cout << conEdges[ce] << ", "; cout << endl; cout << "connected face edges: "; for( unsigned fe = 0; fe < numFaceEdges; fe++) cout << faceEdges[fe] << ", "; cout << endl; #endif break; } int cEdgeVertices[2]; meshFn.getEdgeVertices( nextEdgeId, cEdgeVertices); int cEdge_oppVtx; int searchVtxIndex = 1; if( nextEdgeId == fSelEdges[e]) searchVtxIndex = 0; if( cEdgeVertices[0] == vtxIndex) cEdge_oppVtx = cEdgeVertices[1]; else cEdge_oppVtx = cEdgeVertices[0]; #ifdef _DEBUG cout << "nextEdgeId = " << nextEdgeId << ", cEdge_oppVtx = " << cEdge_oppVtx << endl; #endif founded = false; if(cEdge_oppVtx == nextEdgeVertices[searchVtxIndex]) { invEdge[e] = 1; zero_vtx_index = 1; founded = true; } if(cEdge_oppVtx == nextEdgeVertices[1-searchVtxIndex]) { zero_vtx_index = 0; founded = true; } if(!founded) { vtxIndex = cEdge_oppVtx; continue; } if(e == (edgesCount-1)) break; edgeIt.setIndex( fSelEdges[e], prevIndex); edgeIt.getConnectedFaces( conFaces); numConFaces = conFaces.length(); if( numConFaces < 2) { #ifdef _DEBUG cout << "numConFaces < 2 (edgeId[" << fSelEdges[e] << "]);" << endl; #endif break; } if( conFaces[0] == nextFaceId) nextFaceId = conFaces[1]; else nextFaceId = conFaces[0]; vtxIndex = nextEdgeVertices[zero_vtx_index]; e++; #ifdef _DEBUG cout << "founded, conFaces = " << conFaces[0] << ", " << conFaces[1] << " => " << nextFaceId << endl; #endif } } //######################################## getting edges vertices UVs information MFloatArray edgeUVs_u( edgesCount*4, -1.0f); MFloatArray edgeUVs_v( edgesCount*4, -1.0f); MIntArray edge_conFacesIds( edgesCount*2, -1); MIntArray edge_conFacesNum( edgesCount, -1); for( unsigned e = 0; e < edgesCount; e++) { //#ifdef _DEBUG //cout << "edgeId #" << fSelEdges[e] << ":" << endl; //#endif meshFn.getEdgeVertices( fSelEdges[e], edgeVertices); edgeIt.setIndex( fSelEdges[e], prevIndex); edgeIt.getConnectedFaces( conFaces); numConFaces = conFaces.length(); edge_conFacesNum[e] = numConFaces; bool swap = false; if((numConFaces > 1) && (conFaces[0] > conFaces[1])) swap = true; for( unsigned cf = 0; cf < numConFaces; cf++) { int cFaceId = cf; if( swap) cFaceId = 1 - cf; edge_conFacesIds[e*2 + cf] = conFaces[cFaceId]; for( int ev = 0; ev < 2 ; ev++) { int numVtxUVs; float uvPiont[2]; vtxIt.setIndex( edgeVertices[ev], prevIndex); vtxIt.numUVs( numVtxUVs); if( numVtxUVs <= 0) continue; MStatus stat = vtxIt.getUV( conFaces[cFaceId], uvPiont); if(!stat) continue; unsigned uvArrayIndex = (e*4) + (cf*2) + ev; edgeUVs_u.set( uvPiont[0], uvArrayIndex); edgeUVs_v.set( uvPiont[1], uvArrayIndex); //#ifdef _DEBUG //cout << "faceId #" << conFaces[cFaceId] << ", vtxId #" << edgeVertices[ev] << " = ("; //cout << edgeUVs_u[uvArrayIndex] << ", " << edgeUVs_v[uvArrayIndex] << ");" << endl; //#endif } } } //###################################### get points starts and vectors: for( unsigned i = 0; i < edgesCount; i++) { meshFn.getEdgeVertices( fSelEdges[i], edgeVertices); if ( invEdge[i] == 1) { meshFn.getPoint( edgeVertices[1], splitedPoints_start_N[i]); meshFn.getPoint( edgeVertices[0], point); } else { meshFn.getPoint( edgeVertices[0], splitedPoints_start_N[i]); meshFn.getPoint( edgeVertices[1], point); } splitedPoints_dir_N[i] = point - splitedPoints_start_N[i]; splitedPoints_ndir_N[i] = splitedPoints_dir_N[i]; splitedPoints_ndir_N[i].normalize(); splitedPoints_start_R[i] = point; splitedPoints_dir_R[i] = splitedPoints_start_N[i] - point; splitedPoints_ndir_R[i] = splitedPoints_dir_R[i]; splitedPoints_ndir_R[i].normalize(); } /* #ifdef _DEBUG cout << endl << "splitedPoints_start_N = "; for( unsigned i=0;i<splitedPoints_start_N.length();i++) cout << splitedPoints_start_N[0]<<","<<splitedPoints_start_N[1]<<","<<splitedPoints_start_N[2] << " "; cout << endl << "splitedPoints_dir_N = "; for( unsigned i=0;i<splitedPoints_dir_N.length();i++) cout << splitedPoints_dir_N[0]<<","<<splitedPoints_dir_N[1]<<","<<splitedPoints_dir_N[2] << " "; cout << endl; #endif */ //######################################## do the split: MFloatPointArray internalPoints; MIntArray placements( edgesCount, MFnMesh::kOnEdge); MFloatArray edgeFactors( edgesCount, 0.5); status = meshFn.split( placements, fSelEdges, edgeFactors, internalPoints); if( !status) { MGlobal::displayError( "can't split with given data"); return status; } #ifdef _DEBUG cout << endl << " ! split success ! " << endl; #endif newVtxCount = meshFn.numVertices(); newUVsCount = meshFn.numUVs(); //###################################### get UVs starts and vectors: #ifdef _DEBUG cout << endl << "newVtxCount = " << newVtxCount << endl; cout << endl << "newUVsCount = " << newUVsCount << endl; #endif unsigned edgeNum = 0; unsigned uvNum = 0; unsigned numNewUVs = newUVsCount - oldUVsCount; splitedUVsU_start_N.setLength( numNewUVs); splitedUVsV_start_N.setLength( numNewUVs); splitedUVsU_start_R.setLength( numNewUVs); splitedUVsV_start_R.setLength( numNewUVs); splitedUVsU_dir_N.setLength( numNewUVs); splitedUVsV_dir_N.setLength( numNewUVs); splitedUVsU_dir_R.setLength( numNewUVs); splitedUVsV_dir_R.setLength( numNewUVs); splitedUVsU_ndir_N.setLength( numNewUVs); splitedUVsV_ndir_N.setLength( numNewUVs); splitedUVsU_ndir_R.setLength( numNewUVs); splitedUVsV_ndir_R.setLength( numNewUVs); for( int j = oldVtxCount; j < newVtxCount; j++) { MIntArray conFaces; int numVtxUVs; vtxIt.setIndex( j, prevIndex); vtxIt.numUVs( numVtxUVs); if( numVtxUVs > 0) { //#ifdef _DEBUG //cout << "vtx #" << j << " (edge #" << fSelEdges[edgeNum] << ") :" << endl; //#endif bool swap = false; if((edge_conFacesNum[edgeNum] > 1) && (numVtxUVs > 1)) { MItMeshPolygon faceIt( fMesh); faceIt.setIndex( edge_conFacesIds[edgeNum*2], prevIndex); int numFaceVtx = faceIt.polygonVertexCount(); bool has = false; //#ifdef _DEBUG //cout << "((numConFaces > 1) && (numVtxUVs > 1)) : ( "; //#endif for( int fVtx = 0; fVtx < numFaceVtx; fVtx++) { int uvIndex; faceIt.getUVIndex( fVtx, uvIndex); //#ifdef _DEBUG //cout << uvIndex << " "; //#endif if( uvIndex == (uvNum + oldUVsCount)) has = true; } if( !has) swap = true; //#ifdef _DEBUG //cout << ") uv = " << (uvNum + oldUVsCount) << " => swap = " << swap << endl; //#endif } for( int uvi = 0; uvi < numVtxUVs; uvi++) { unsigned uvArrayIndex_a; if( swap) uvArrayIndex_a = (edgeNum*4) + ((1-uvi)*2); else uvArrayIndex_a = (edgeNum*4) + (uvi*2); unsigned uvArrayIndex_b = uvArrayIndex_a; if(invEdge[edgeNum] == 1) uvArrayIndex_a++; else uvArrayIndex_b++; splitedUVsU_start_N[uvNum] = edgeUVs_u[uvArrayIndex_a]; splitedUVsV_start_N[uvNum] = edgeUVs_v[uvArrayIndex_a]; splitedUVsU_start_R[uvNum] = edgeUVs_u[uvArrayIndex_b]; splitedUVsV_start_R[uvNum] = edgeUVs_v[uvArrayIndex_b]; splitedUVsU_dir_N[uvNum] = edgeUVs_u[uvArrayIndex_b] - edgeUVs_u[uvArrayIndex_a]; splitedUVsV_dir_N[uvNum] = edgeUVs_v[uvArrayIndex_b] - edgeUVs_v[uvArrayIndex_a]; splitedUVsU_dir_R[uvNum] = edgeUVs_u[uvArrayIndex_a] - edgeUVs_u[uvArrayIndex_b]; splitedUVsV_dir_R[uvNum] = edgeUVs_v[uvArrayIndex_a] - edgeUVs_v[uvArrayIndex_b]; float dist = sqrt((splitedUVsU_dir_N[uvNum]*splitedUVsU_dir_N[uvNum]) + (splitedUVsV_dir_N[uvNum]*splitedUVsV_dir_N[uvNum])); if(dist == 0) { splitedUVsU_ndir_N[uvNum] = 0; splitedUVsV_ndir_N[uvNum] = 0; splitedUVsU_ndir_R[uvNum] = 0; splitedUVsV_ndir_R[uvNum] = 0; } else { splitedUVsU_ndir_N[uvNum] = splitedUVsU_dir_N[uvNum] / dist; splitedUVsV_ndir_N[uvNum] = splitedUVsV_dir_N[uvNum] / dist; splitedUVsU_ndir_R[uvNum] = splitedUVsU_dir_R[uvNum] / dist; splitedUVsV_ndir_R[uvNum] = splitedUVsV_dir_R[uvNum] / dist; } /*#ifdef _DEBUG cout << "uvNum #" << (uvNum + oldUVsCount) << " (uvi=" << uvi << ") : ( "; cout << edgeUVs_u[uvArrayIndex_a] << ", "; cout << edgeUVs_v[uvArrayIndex_a] << ") - ( "; cout << edgeUVs_u[uvArrayIndex_b] << ", "; cout << edgeUVs_v[uvArrayIndex_b] << ");" << endl; #endif */ uvNum++; } } edgeNum++; } //################################################################################## return status; }
void MayaObject::getMeshData(MPointArray& points, MFloatVectorArray& normals, MFloatArray& uArray, MFloatArray& vArray, MIntArray& triPointIndices, MIntArray& triNormalIndices, MIntArray& triUvIndices, MIntArray& triMatIndices) { MStatus stat; MObject meshObject = this->mobject; MMeshSmoothOptions options; MFnMesh tmpMesh(this->mobject, &stat); MFnMeshData meshData; MObject dataObject; MObject smoothedObj; // create smooth mesh if needed if (tmpMesh.findPlug("displaySmoothMesh").asBool()) { stat = tmpMesh.getSmoothMeshDisplayOptions(options); if (stat) { if (!tmpMesh.findPlug("useSmoothPreviewForRender", false, &stat).asBool()) { //Logging::debug(MString("useSmoothPreviewForRender turned off")); int smoothLevel = tmpMesh.findPlug("renderSmoothLevel", false, &stat).asInt(); options.setDivisions(smoothLevel); } if (options.divisions() > 0) { dataObject = meshData.create(); smoothedObj = tmpMesh.generateSmoothMesh(dataObject, &options, &stat); if (stat) { meshObject = smoothedObj; } } } } MFnMesh meshFn(meshObject, &stat); CHECK_MSTATUS(stat); MItMeshPolygon faceIt(meshObject, &stat); CHECK_MSTATUS(stat); meshFn.getPoints(points); meshFn.getNormals(normals, MSpace::kObject); meshFn.getUVs(uArray, vArray); uint numVertices = points.length(); uint numNormals = normals.length(); uint numUvs = uArray.length(); //Logging::debug(MString("numVertices ") + numVertices); //Logging::debug(MString("numNormals ") + numNormals); //Logging::debug(MString("numUvs ") + numUvs); // some meshes may have no uv's // to avoid problems I add a default uv coordinate if (numUvs == 0) { Logging::warning(MString("Object has no uv's: ") + this->shortName); uArray.append(0.0); vArray.append(0.0); } for (uint nid = 0; nid < numNormals; nid++) { if (normals[nid].length() < 0.1f) Logging::warning(MString("Malformed normal in ") + this->shortName); } MPointArray triPoints; MIntArray triVtxIds; MIntArray faceVtxIds; MIntArray faceNormalIds; for (faceIt.reset(); !faceIt.isDone(); faceIt.next()) { int faceId = faceIt.index(); int numTris; faceIt.numTriangles(numTris); faceIt.getVertices(faceVtxIds); int perFaceShadingGroup = 0; if (this->perFaceAssignments.length() > 0) perFaceShadingGroup = this->perFaceAssignments[faceId]; MIntArray faceUVIndices; faceNormalIds.clear(); for (uint vtxId = 0; vtxId < faceVtxIds.length(); vtxId++) { faceNormalIds.append(faceIt.normalIndex(vtxId)); int uvIndex; if (numUvs == 0) { faceUVIndices.append(0); } else{ faceIt.getUVIndex(vtxId, uvIndex); //if (uvIndex > uArray.length()) // Logging::info(MString("-----------------> UV Problem!!! uvIndex ") + uvIndex + " > uvArray in object " + this->shortName); faceUVIndices.append(uvIndex); } } for (int triId = 0; triId < numTris; triId++) { int faceRelIds[3]; faceIt.getTriangle(triId, triPoints, triVtxIds); for (uint triVtxId = 0; triVtxId < 3; triVtxId++) { for (uint faceVtxId = 0; faceVtxId < faceVtxIds.length(); faceVtxId++) { if (faceVtxIds[faceVtxId] == triVtxIds[triVtxId]) { faceRelIds[triVtxId] = faceVtxId; } } } uint vtxId0 = faceVtxIds[faceRelIds[0]]; uint vtxId1 = faceVtxIds[faceRelIds[1]]; uint vtxId2 = faceVtxIds[faceRelIds[2]]; uint normalId0 = faceNormalIds[faceRelIds[0]]; uint normalId1 = faceNormalIds[faceRelIds[1]]; uint normalId2 = faceNormalIds[faceRelIds[2]]; uint uvId0 = faceUVIndices[faceRelIds[0]]; uint uvId1 = faceUVIndices[faceRelIds[1]]; uint uvId2 = faceUVIndices[faceRelIds[2]]; triPointIndices.append(vtxId0); triPointIndices.append(vtxId1); triPointIndices.append(vtxId2); triNormalIndices.append(normalId0); triNormalIndices.append(normalId1); triNormalIndices.append(normalId2); triUvIndices.append(uvId0); triUvIndices.append(uvId1); triUvIndices.append(uvId2); triMatIndices.append(perFaceShadingGroup); //Logging::debug(MString("vtxIds ") + vtxId0 + " " + vtxId1 + " " + vtxId2); //Logging::debug(MString("nIds ") + normalId0 + " " + normalId1 + " " + normalId2); //Logging::debug(MString("uvIds ") + uvId0 + " " + uvId1 + " " + uvId2); } } }
PxrUsdMayaShadingModeExportContext::AssignmentVector PxrUsdMayaShadingModeExportContext::GetAssignments() const { AssignmentVector ret; MStatus status; MFnDependencyNode seDepNode(_shadingEngine, &status); if (!status) { return ret; } MPlug dsmPlug = seDepNode.findPlug("dagSetMembers", true, &status); if (!status) { return ret; } SdfPathSet seenBoundPrimPaths; for (unsigned int i = 0; i < dsmPlug.numConnectedElements(); i++) { MPlug dsmElemPlug(dsmPlug.connectionByPhysicalIndex(i)); MStatus status = MS::kFailure; MFnDagNode dagNode(PxrUsdMayaUtil::GetConnected(dsmElemPlug).node(), &status); if (!status) { continue; } MDagPath dagPath; if (!dagNode.getPath(dagPath)) continue; SdfPath usdPath = PxrUsdMayaUtil::MDagPathToUsdPath(dagPath, _mergeTransformAndShape); // If _overrideRootPath is not empty, replace the root namespace with it if (!_overrideRootPath.IsEmpty() ) { usdPath = usdPath.ReplacePrefix(usdPath.GetPrefixes()[0], _overrideRootPath); } // If this path has already been processed, skip it. if (!seenBoundPrimPaths.insert(usdPath).second) continue; // If the bound prim's path is not below a bindable root, skip it. if (SdfPathFindLongestPrefix(_bindableRoots.begin(), _bindableRoots.end(), usdPath) == _bindableRoots.end()) { continue; } MObjectArray sgObjs, compObjs; // Assuming that instancing is not involved. status = dagNode.getConnectedSetsAndMembers(0, sgObjs, compObjs, true); if (!status) continue; for (size_t j = 0; j < sgObjs.length(); j++) { // If the shading group isn't the one we're interested in, skip it. if (sgObjs[j] != _shadingEngine) continue; VtIntArray faceIndices; if (!compObjs[j].isNull()) { MItMeshPolygon faceIt(dagPath, compObjs[j]); faceIndices.reserve(faceIt.count()); for ( faceIt.reset() ; !faceIt.isDone() ; faceIt.next() ) { faceIndices.push_back(faceIt.index()); } } ret.push_back(std::make_pair(usdPath, faceIndices)); } } return ret; }
void CoronaRenderer::defineMesh(mtco_MayaObject *obj) { MObject meshObject = obj->mobject; MStatus stat = MStatus::kSuccess; bool hasDisplacement = false; Corona::Abstract::Map *displacementMap = NULL; float displacementMin = 0.0f; float displacementMax = 0.01f; // I do it here for displacement mapping, maybe we should to another place getObjectShadingGroups(obj->dagPath, obj->perFaceAssignments, obj->shadingGroups); if( obj->shadingGroups.length() > 0) { MFnDependencyNode shadingGroup(obj->shadingGroups[0]); MString sgn = shadingGroup.name(); MObject displacementObj = getConnectedInNode(obj->shadingGroups[0], "displacementShader"); MString doo = getObjectName(displacementObj); if( (displacementObj != MObject::kNullObj) && (displacementObj.hasFn(MFn::kDisplacementShader))) { MObject displacementMapObj = getConnectedInNode(displacementObj, "displacement"); if( (displacementMapObj != MObject::kNullObj) && (displacementMapObj.hasFn(MFn::kFileTexture))) { MFnDependencyNode displacmentMapNode(displacementObj); getFloat("mtco_displacementMin", displacmentMapNode, displacementMin); getFloat("mtco_displacementMax", displacmentMapNode, displacementMax); MString fileTexturePath = getConnectedFileTexturePath(MString("displacement"), displacmentMapNode); if( fileTexturePath != "") { MapLoader loader; displacementMap = loader.loadBitmap(fileTexturePath.asChar()); hasDisplacement = true; } } } } MFnMesh meshFn(meshObject, &stat); CHECK_MSTATUS(stat); MItMeshPolygon faceIt(meshObject, &stat); CHECK_MSTATUS(stat); MPointArray points; meshFn.getPoints(points); MFloatVectorArray normals; meshFn.getNormals( normals, MSpace::kWorld ); MFloatArray uArray, vArray; meshFn.getUVs(uArray, vArray); //logger.debug(MString("Translating mesh object ") + meshFn.name().asChar()); MString meshFullName = makeGoodString(meshFn.fullPathName()); Corona::TriangleData td; Corona::IGeometryGroup* geom = NULL; geom = this->context.scene->addGeomGroup(); obj->geom = geom; for( uint vtxId = 0; vtxId < points.length(); vtxId++) { geom->getVertices().push(Corona::Pos(points[vtxId].x,points[vtxId].y,points[vtxId].z)); } for( uint nId = 0; nId < normals.length(); nId++) { geom->getNormals().push(Corona::Dir(normals[nId].x,normals[nId].y,normals[nId].z)); } for( uint tId = 0; tId < uArray.length(); tId++) { geom->getMapCoords().push(Corona::Pos(uArray[tId],vArray[tId],0.0f)); geom->getMapCoordIndices().push(geom->getMapCoordIndices().size()); } MPointArray triPoints; MIntArray triVtxIds; MIntArray faceVtxIds; MIntArray faceNormalIds; for(faceIt.reset(); !faceIt.isDone(); faceIt.next()) { int faceId = faceIt.index(); int numTris; faceIt.numTriangles(numTris); faceIt.getVertices(faceVtxIds); MIntArray faceUVIndices; faceNormalIds.clear(); for( uint vtxId = 0; vtxId < faceVtxIds.length(); vtxId++) { faceNormalIds.append(faceIt.normalIndex(vtxId)); int uvIndex; faceIt.getUVIndex(vtxId, uvIndex); faceUVIndices.append(uvIndex); } for( int triId = 0; triId < numTris; triId++) { int faceRelIds[3]; faceIt.getTriangle(triId, triPoints, triVtxIds); for( uint triVtxId = 0; triVtxId < 3; triVtxId++) { for(uint faceVtxId = 0; faceVtxId < faceVtxIds.length(); faceVtxId++) { if( faceVtxIds[faceVtxId] == triVtxIds[triVtxId]) { faceRelIds[triVtxId] = faceVtxId; } } } uint vtxId0 = faceVtxIds[faceRelIds[0]]; uint vtxId1 = faceVtxIds[faceRelIds[1]]; uint vtxId2 = faceVtxIds[faceRelIds[2]]; uint normalId0 = faceNormalIds[faceRelIds[0]]; uint normalId1 = faceNormalIds[faceRelIds[1]]; uint normalId2 = faceNormalIds[faceRelIds[2]]; uint uvId0 = faceUVIndices[faceRelIds[0]]; uint uvId1 = faceUVIndices[faceRelIds[1]]; uint uvId2 = faceUVIndices[faceRelIds[2]]; if( hasDisplacement ) { Corona::DisplacedTriangleData tri; tri.displacement.map = displacementMap; MPoint p0 = points[vtxId0]; MPoint p1 = points[vtxId1]; MPoint p2 = points[vtxId2]; tri.v[0] = Corona::AnimatedPos(Corona::Pos(p0.x, p0.y, p0.z)); tri.v[1] = Corona::AnimatedPos(Corona::Pos(p1.x, p1.y, p1.z)); tri.v[2] = Corona::AnimatedPos(Corona::Pos(p2.x, p2.y, p2.z)); MVector n0 = normals[normalId0]; MVector n1 = normals[normalId1]; MVector n2 = normals[normalId2]; Corona::Dir dir0(n0.x, n0.y, n0.z); Corona::Dir dir1(n1.x, n1.y, n1.z); Corona::Dir dir2(n2.x, n2.y, n2.z); tri.n[0] = Corona::AnimatedDir(dir0); tri.n[1] = Corona::AnimatedDir(dir1); tri.n[2] = Corona::AnimatedDir(dir2); Corona::Pos uv0(uArray[uvId0],vArray[uvId0],0.0); Corona::Pos uv1(uArray[uvId1],vArray[uvId1],0.0); Corona::Pos uv2(uArray[uvId2],vArray[uvId2],0.0); Corona::StaticArray<Corona::Pos, 3> uvp; uvp[0] = uv0; uvp[1] = uv1; uvp[2] = uv2; tri.t.push(uvp); tri.materialId = 0; tri.displacement.min = displacementMin; tri.displacement.max = displacementMax; geom->addPrimitive(tri); }else{ Corona::TriangleData tri; tri.v = Corona::AnimatedPosI3(vtxId0, vtxId1, vtxId2); tri.n = Corona::AnimatedDirI3(normalId0, normalId1, normalId2); tri.t[0] = uvId0; tri.t[1] = uvId1; tri.t[2] = uvId2; tri.materialId = 0; geom->addPrimitive(tri); } } } }