示例#1
0
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;
}
示例#2
0
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;

}
示例#3
0
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;
}
示例#4
0
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;
}
示例#5
0
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;
}
示例#7
0
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);			
			}

		}		
	}
}