meshMapUtils.cpp
#include <assert.h>
#include "meshMapUtils.h"
#include <maya/MIntArray.h>
#include <maya/MFnMesh.h>
#include <maya/MItMeshEdge.h>
#include <maya/MItMeshPolygon.h>
#include <maya/MGlobal.h>
#include <maya/MFloatPointArray.h>
#include <maya/MDagPath.h>
#include <maya/MDagPathArray.h>
#include <maya/MObjectArray.h>
#include <maya/MItMeshVertex.h>
#define IDX(i, l) ( ( i + l ) % l )
void meshMapUtils::intersectArrays( MIntArray& selection, MIntArray& moreFaces )
{
int j = selection.length() - 1;
while ( j >= 0 )
{
bool found = false;;
for( unsigned int i = 0 ; i < moreFaces.length(); i++ )
{
if( selection[j] == moreFaces[i] )
{
found = true;
break;
}
}
if( !found )
{
selection.remove(j);
}
j--;
}
}
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;
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;
}
if( faceTraversal[faceIdx] )
{
return MStatus::kSuccess;
}
MIntArray vtxOrig;
MIntArray edgeOrig;
polyIt.setIndex( faceIdx, dummy );
polyIt.getEdges( edgeOrig );
polyIt.getVertices( vtxOrig );
vtxCnt = vtxOrig.length();
MIntArray vtxSorted( vtxCnt );
MIntArray edgeSorted( vtxCnt );
int v0Idx = -1;
int i;
for( i = 0; i < vtxCnt; i++ )
{
if( vtxOrig[i] == v0 )
{
v0Idx = i;
if( vtxOrig[IDX(i+1, vtxCnt)] == v1 )
{
dir = 1;
}
else if( vtxOrig[IDX(i-1, vtxCnt)] == v1 )
{
dir = -1;
}
else
{
assert( dir != 0 );
}
break;
}
}
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 )];
}
}
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;
}
newVertices.append( origVertices[index] );
cvMapping[index] = newVertices.length()-1;
cvMappingInverse[newVertices.length()-1] = index;
}
}
newPolygonCounts.append( vtxCnt );
for ( i = 0; i < vtxCnt; i++ )
{
newPolygonConnects.append( cvMapping[vtxSorted[i]] );
}
faceTraversal[faceIdx] = true;
for( i = 0; i < (int)edgeSorted.length(); i++ )
{
int nextEdge = edgeSorted[i];
int2 nextEdgeVtx;
stat = theMesh.getEdgeVertices(nextEdge, nextEdgeVtx );
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 );
if( vtxSorted[IDX(j+1, vtxCnt)] == nextEdgeVtx[1] )
{
}
else if ( vtxSorted[IDX(j-1, vtxCnt)] == nextEdgeVtx[1] )
{
swap = true;
}
MIntArray connectedFaces;
edgeIt.setIndex( nextEdge, dummy );
edgeIt.getConnectedFaces( connectedFaces );
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 );
if( stat != MStatus::kSuccess )
{
break;
}
}
}
return stat;
}
MStatus meshMapUtils::validateFaceSelection( MDagPathArray& paths, MObjectArray& components, int *faceIdx, MIntArray *seedVtx )
{
MStatus stat = MStatus::kSuccess;
MIntArray finalFaceList;
if ( paths.length() != 3 && components.length() != 3 )
{
return MStatus::kFailure;
}
seedVtx->clear();
for (unsigned int i = 0; i < 3; i++)
{
MItMeshVertex fIt ( paths[i], components[i], &stat );
if( stat != MStatus::kSuccess || fIt.isDone() )
{
MGlobal::displayError( " MItMeshVertex failed");
return MStatus::kFailure;
}
seedVtx->append( fIt.index() );
MIntArray faceList;
stat = fIt.getConnectedFaces ( faceList );
if( stat != MStatus::kSuccess )
{
MGlobal::displayError( " getConnectedFaces failed");
return MStatus::kFailure;
}
if( i == 0 )
{
finalFaceList = faceList;
}
else
{
meshMapUtils::intersectArrays( finalFaceList, faceList );
}
}
if( finalFaceList.length() != 1 )
{
return MStatus::kFailure;
}
else
{
*faceIdx = finalFaceList[0];
}
MDagPath p0( paths[0] );
MDagPath p1( paths[1] );
MDagPath p2( paths[2] );
if( !(p0 == p1 ) || !(p0 == p2 ))
{
return MStatus::kFailure;
}
return MStatus::kSuccess;
}