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