void TraversalNeighborGen::recFace2(Visitor *v, TraversalData ch[2][2][2])
{
	TraversalData face[2];
	face[0] = ch[0][0][0];
	face[1] = ch[0][0][1];
	traverseFace(v, face, 2);

	face[0] = ch[0][1][0];
	face[1] = ch[0][1][1];
	traverseFace(v, face, 2);

	face[0] = ch[1][0][0];
	face[1] = ch[1][0][1];
	traverseFace(v, face, 2);

	face[0] = ch[1][1][0];
	face[1] = ch[1][1][1];
	traverseFace(v, face, 2);
}
Пример #2
0
//
//  Recursively traverse a mesh by processing each face, and the neighbouring faces along it's edges.
//  The initial invocation of this routine provides the basis for the new first vertex/edge
//  and faces.  
//
//  The result of this routine is an array of values that map the old CV indices to the new ones. Along
//  the a new list of reindexed CVs is built, along with a list of poly counts and connetions. These
//  can be used to build a new mesh with the reordering specfied by the seed face and vertices.
//
//
//  Inputs: 
//		path				: Path to the object being traversed
//		faceIdx				: Current face being traversed
//		v0, v1				: Veretices that define the direction of travel along the face
//		faceTraversal		: An array booleans to track which faces have been 
//							: traversed, controls the recursion  
//		origVertices		: The vertices from the original mesh. The could be obtained
//							: from the path, but are passed in for efficiency
//
// 	Outputs:
//		cvMapping			: Mapping of the existing vertices to their new indices
//							: the fist values in the final array will be the intial v0, v1
//		cvMappingInverse	: The inverse of the cvMapping
//							: the value of items v0 and v1 will be 0 and 1 respectively
//		newPolygonCounts	: Vertex counts for each of the new faces
//		newPolygonConnects  : Connections, specified in terms of new CV indices
//		newVertices			: The orginal vertices resorted based on the reindexing
//
//
MStatus meshMapUtils::traverseFace( 
	MDagPath&	path,
	int faceIdx, 
	int v0, 
	int v1, 
	MIntArray& faceTraversal,
	MIntArray& cvMapping,
	MIntArray& cvMappingInverse,
	MIntArray& newPolygonCounts,
	MIntArray& newPolygonConnects,
	MFloatPointArray& origVertices,
	MFloatPointArray& newVertices
)
{
	int vtxCnt = -1;
	int dir = 0;
	int dummy;		// For setIndex calls

	MStatus stat = MStatus::kSuccess;

	MFnMesh theMesh( path, &stat );
	MItMeshPolygon polyIt( path );
	MItMeshEdge edgeIt( path );

	if( stat != MStatus::kSuccess )
	{
		MGlobal::displayError( " theMesh.getPoint failed");
		return stat;
	}


	//
	// Skip over any faces already processed, this is not a failure
	// 
	if( faceTraversal[faceIdx] )
	{
		return MStatus::kSuccess;
	}

	//
	// get the vertex/edge information and sort it based on the user seed
	//
	MIntArray vtxOrig;
	MIntArray edgeOrig;

	polyIt.setIndex( faceIdx, dummy );
	polyIt.getEdges( edgeOrig );	   
	polyIt.getVertices( vtxOrig );	   

	vtxCnt = vtxOrig.length();

	// 
	// the sorted V/E info
	// 
	MIntArray vtxSorted( vtxCnt );
	MIntArray edgeSorted( vtxCnt );

	//
	// Build a new array ordered with v0, then v1, first figure out the 
	// starting point, and direction 
	//
	int v0Idx =	-1;
	int i;
	for( i = 0; i < vtxCnt; i++ )
	{
		if( vtxOrig[i] == v0 )
		{
			// We've found v0, now find in what direction we need to travel to find v1
					
			v0Idx =	i;
			
			if( vtxOrig[IDX(i+1, vtxCnt)] == v1 )
			{
				dir = 1;
			}
			else if( vtxOrig[IDX(i-1, vtxCnt)] == v1 )
			{
				dir = -1;
			}
			break;
		}
	}

	if (dir == 0)
	{
		MGlobal::displayError("Selected vertices are not adjacent");
		return MS::kFailure;
	}

	// Now sort the vertex/edge arrays
	for( i = 0; i < vtxCnt; i++ )
	{
		vtxSorted[i] = vtxOrig[IDX( v0Idx + i * dir, vtxCnt )];
		if( dir == 1 )
		{
			edgeSorted[i] = edgeOrig[IDX( v0Idx + i * dir, vtxCnt )];
		}
		else
		{
			edgeSorted[i] = edgeOrig[IDX( v0Idx - 1 + i * dir, vtxCnt )];
		}
	}


	// Add any new CVs to the vertex array being constructed
	for ( i = 0; i < vtxCnt; i++ )
	{
		MPoint pos;
		int index = vtxSorted[i];

		if( cvMapping[index] == -1  )
		{
			if( stat != MStatus::kSuccess )
			{
				MGlobal::displayError( " theMesh.getPoint failed");
				return stat;
			}

			// Added the new CV, and mark it as transferred
			newVertices.append( origVertices[index] );

			// Store the mapping from the old CV indices to the new ones
			cvMapping[index] = newVertices.length()-1;
			cvMappingInverse[newVertices.length()-1] = index;
		}

	}

	//
	//  Add the new face count 
	//
	newPolygonCounts.append( vtxCnt );

	//
	//  Add the new polyConnects
	
	for ( i = 0; i < vtxCnt; i++ )
	{
		newPolygonConnects.append( cvMapping[vtxSorted[i]] );
	}

	// Mark this face as complete 
	faceTraversal[faceIdx] = true;

	//
	//  Now recurse over the edges of this face
	// 
	for( i = 0; i < (int)edgeSorted.length(); i++ )
	{
		int nextEdge = edgeSorted[i];

		int2 nextEdgeVtx;
		stat = theMesh.getEdgeVertices(nextEdge, nextEdgeVtx );

		//
		// Find the vertex, in the sorted array, that starts the next edge
		int baseIdx = -1;
		bool swap = false;
		int j;
		for( j = 0; j < (int)vtxSorted.length(); j++ )
		{
			if( vtxSorted[j] == nextEdgeVtx[0] )
			{
				baseIdx = j;
				break;
			}
		}

		assert( baseIdx != -1 );
	
		// 
		// Now look forward and backward in the vertex array to find the
		// edge's other point, this indicates the edges direction. This
		// is needed to guide the next recursion level, and keep the
		// normals pointed consistenly
		//
		if( vtxSorted[IDX(baseIdx+1, vtxCnt)] == nextEdgeVtx[1] )
		{
			// Nothing
		}
		else if ( vtxSorted[IDX(baseIdx-1, vtxCnt)] == nextEdgeVtx[1] )
		{
			swap = true;
		}


		MIntArray connectedFaces;
		edgeIt.setIndex( nextEdge, dummy );
		edgeIt.getConnectedFaces( connectedFaces );

		// A single face is simply the current one. Recurse over the others
		if( connectedFaces.length() > 1 )
		{
			int nextFace;
			if( connectedFaces[0] == faceIdx )
			{
			   	nextFace = connectedFaces[1];
			}
			else
			{
			   	nextFace = connectedFaces[0];
			}

			int nextVtx0 = -1;
			int nextVtx1 = -1;
			if ( !swap )
			{
				nextVtx0 = nextEdgeVtx[1];
				nextVtx1 = nextEdgeVtx[0];
			}
			else
			{
				nextVtx0 = nextEdgeVtx[0];
				nextVtx1 = nextEdgeVtx[1];
			}

			stat = traverseFace( path, nextFace, nextVtx0, nextVtx1, faceTraversal,
					cvMapping, cvMappingInverse, 
					newPolygonCounts, newPolygonConnects, 
					origVertices, newVertices );

			// Break out of edge loop on error
			if( stat != MStatus::kSuccess )
			{
				break;
			}	
		}
	}

	return stat;
}