#include "cleanPerFaceAssignmentCmd.h"
#include <maya/MGlobal.h>
#include <maya/MDagPath.h>
#include <maya/MPlug.h>
#include <maya/MObjectArray.h>
#include <maya/MIntArray.h>
#include <maya/MStringArray.h>
#include <maya/MSelectionList.h>
#include <maya/MItSelectionList.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MFnMesh.h>
#include <maya/MItMeshPolygon.h>
#include <maya/MFnSet.h>
#ifdef DEBUG
#include <MIOStream.h>
#endif
MStatus cleanPerFaceAssignment::doIt( const MArgList& )
{
MStatus stat = MS::kSuccess;
MSelectionList list;
MGlobal::getActiveSelectionList( list );
MItSelectionList listIt( list);
for ( listIt.reset(); !listIt.isDone() ; listIt.next() ){
MDagPath path;
listIt.getDagPath( path );
path.extendToShape();
if ( path.apiType() == MFn::kMesh ){
MFnMesh meshFn( path );
MObjectArray sets, comps;
unsigned int instanceNumber = path.instanceNumber();
meshFn.getConnectedSetsAndMembers( instanceNumber, sets, comps, 1 );
#ifdef _DEBUG
for ( unsigned int i = 0; i < sets.length() ; i++ ){
MFnSet setFn ( sets[i]);
MItMeshPolygon faceIt( path, comps[i] );
cout << "-------------->" << endl;
cout << setFn.name() << endl;
cout << "FaceCount:" << faceIt.count() << endl;
for ( faceIt.reset() ; !faceIt.isDone() ; faceIt.next() ){
cout << faceIt.index() << " ";
}
cout << endl;
cout << "<--------------" << endl;
}
#endif // _DEBUG
MStringArray SGNames;
MIntArray sameConnectionFlag;
MIntArray sameSGFaceCount;
MStringArray memberFaceNames;
sameConnectionFlag.clear();
sameSGFaceCount.clear();
for ( unsigned int i = 0; i < sets.length() ; i++ ){
MFnSet setFn ( sets[i] );
SGNames.append( setFn.name() );
sameConnectionFlag.append( -1 );
MItMeshPolygon tempFaceIt ( path, comps[i] );
sameSGFaceCount.append( tempFaceIt.count() );
MString aMemberFaceName;
MString pathName = path.fullPathName();
bool optimizeList = true;
if (optimizeList)
{
int lastIndices[2] = { -1, -1 };
int currentIndex = -1;
bool haveAFace = false;
for ( ;!tempFaceIt.isDone() ; tempFaceIt.next() )
{
if (lastIndices[0] == -1)
{
lastIndices[0] = tempFaceIt.index();
lastIndices[1] = tempFaceIt.index();
}
else
{
currentIndex = tempFaceIt.index();
if (currentIndex > lastIndices[1] + 1)
{
aMemberFaceName += (pathName + ".f[" + lastIndices[0] + ":" + lastIndices[1] + "] ");
lastIndices[0] = currentIndex;
lastIndices[1] = currentIndex;
}
else
lastIndices[1] = currentIndex;
}
haveAFace = true;
}
if (haveAFace)
{
aMemberFaceName += (pathName + ".f[" + lastIndices[0] + ":" + lastIndices[1] + "] ");
}
}
else
{
for ( ;!tempFaceIt.isDone() ; tempFaceIt.next() ){
aMemberFaceName += (path.fullPathName() + ".f[" + tempFaceIt.index() + "] ");
}
}
memberFaceNames.append( aMemberFaceName );
}
for ( unsigned int i = 0; i < sets.length() ; i++ ){
MFnSet setFn ( sets[i]);
if ( sameConnectionFlag[i] == -1 ){
for ( unsigned int j = 0; j < sets.length() ; j++ ){
if ( i != j && sameConnectionFlag[j] == -1 ) {
MFnSet tempSetFn ( sets[j] );
if ( setFn.name() == tempSetFn.name() ){
sameConnectionFlag[j] = i;
sameSGFaceCount[i] += sameSGFaceCount[j];
sameSGFaceCount[j] = 0;
memberFaceNames[i] += memberFaceNames[j];
memberFaceNames[j] = "";
}
}
}
sameConnectionFlag[i] = i;
}
}
unsigned int tail = 0;
while( tail < sameConnectionFlag.length() ){
if ( sameSGFaceCount[tail] == 0 ){
SGNames.remove( tail );
memberFaceNames.remove( tail );
sameConnectionFlag.remove( tail );
sameSGFaceCount.remove( tail );
} else {
tail++;
}
}
MIntArray sortMapper;
for ( unsigned int i = 0; i < sameSGFaceCount.length() ; i++ ){
sortMapper.append( i );
}
bool needToSort = true;
while ( needToSort ){
unsigned int sortCount = 0;
if ( sameSGFaceCount.length() > 1 ){
for( unsigned int i = 0; i < ( sameSGFaceCount.length() -1 ) ; i++ ){
if ( sameSGFaceCount[sortMapper[i]] < sameSGFaceCount[sortMapper[i+1]] ){
int tmp = sortMapper[i];
sortMapper[i] = sortMapper[i+1];
sortMapper[i+1] = tmp;
sortCount++;
} else {
}
}
}else {
break;
}
if ( sortCount > 0 ){
needToSort = true;
} else {
needToSort = false;
}
}
MStringArray sortedSGNames;
MStringArray sortedMemberFaceNames;
MIntArray sortedSGFaceCount;
for ( unsigned int i = 0; i < sortMapper.length(); i++ ){
sortedSGNames.append( SGNames[sortMapper[i]] );
sortedSGFaceCount.append( sameSGFaceCount[sortMapper[i]] );
sortedMemberFaceNames.append( memberFaceNames[sortMapper[i]]);
}
#ifdef _DEBUG
for ( unsigned int i = 0; i < sortedSGFaceCount.length() ; i++ ){
cout << sortedSGNames[i] << " " << sortedSGFaceCount[i] << endl;
cout << sortedMemberFaceNames[i] << endl;
}
for ( unsigned int i = 0; i < sortMapper.length() ; i++ ){
cout << i << " -- " << sortMapper[i] << endl;
}
#endif // _DEBUG
bool executeImmediate = true;
for ( unsigned int i = 0; i < sortedSGFaceCount.length() ; i++ ){
MString resultString;
if ( i == 0 ){
resultString = ("select -r " + path.fullPathName() +";" );
} else {
resultString = ("select -r " + sortedMemberFaceNames[i] + ";");
}
if (executeImmediate )
MGlobal::executeCommand( resultString );
if (executeImmediate)
{
resultString = ("sets -e -forceElement " + sortedSGNames[i] + ";");
MGlobal::executeCommand( resultString );
}
else
resultString += ("sets -e -forceElement " + sortedSGNames[i] + ";");
if (!executeImmediate)
appendToResult( resultString );
}
}
}
return stat;
}
void* cleanPerFaceAssignment::creator()
{
return new cleanPerFaceAssignment();
}
cleanPerFaceAssignment::cleanPerFaceAssignment()
{}
cleanPerFaceAssignment::~cleanPerFaceAssignment()
{
}