#include "meshReorderCmd.h"
#include "meshMapUtils.h"
#include <maya/MIOStream.h>
#include <maya/MItSelectionList.h>
#include <maya/MItMeshVertex.h>
#include <maya/MArgList.h>
#include <maya/MFnMesh.h>
#include <maya/MFnMeshData.h>
#include <maya/MDagPathArray.h>
#include <maya/MString.h>
meshReorderCommand::meshReorderCommand()
{
fClampedArray = NULL;
fRepArray = NULL;
fColorArrays = NULL;
fVertexColorArrays = NULL;
fColorIdsArrays = NULL;
fUArrays = NULL;
fVArrays = NULL;
fUVIdsArrays = NULL;
}
meshReorderCommand::~meshReorderCommand()
{
resetColorsUVsMemory();
}
void* meshReorderCommand::creator()
{
return new meshReorderCommand;
}
MStatus meshReorderCommand::parseArgs(const MArgList& args)
{
MStatus stat;
MString err;
if( args.length() != 3 )
{
displayError("3 vertices must be specified");
return MS::kFailure;
}
MObjectArray selectedComponent(3);
MDagPathArray selectedPath;
selectedPath.setLength(3);
int argIdx = 0;
for (unsigned int j = 0; j < 3; j++)
{
MString arg;
if( ( stat = args.get( argIdx, arg )) != MStatus::kSuccess )
{
displayError( "Can't parse arg");
return stat;
}
MSelectionList list;
if (! list.add( arg ) )
{
err = arg + ": no such component";
displayError(err);
return MS::kFailure;
}
MItSelectionList selectionIt (list, MFn::kComponent);
if (selectionIt.isDone ())
{
err = arg + ": not a component";
displayError (err);
return MS::kFailure;
}
if( selectionIt.getDagPath (selectedPath[j], selectedComponent[j]) != MStatus::kSuccess )
{
displayError( "Can't get path for");
return stat;
}
if (!selectedPath[j].node().hasFn(MFn::kMesh) && !(selectedPath[j].node().hasFn(MFn::kTransform) && selectedPath[j].hasFn(MFn::kMesh)))
{
err = arg + ": Invalid type! Only a mesh or its transform can be specified!";
displayError (err);
return MStatus::kFailure;
}
argIdx++;
}
if( ( stat = meshMapUtils::validateFaceSelection( selectedPath, selectedComponent, &fFaceIdxSrc, &fFaceVtxSrc ) ) != MStatus::kSuccess )
{
displayError("Selected vertices don't define a unique face on source mesh");
return stat;
}
fDagPathSrc = selectedPath[0];
return stat;
}
MStatus meshReorderCommand::doIt(const MArgList& args)
{
MStatus stat = MStatus::kSuccess;
if ( ( stat = parseArgs( args ) ) != MStatus::kSuccess )
{
displayError ("Error parsing arguments");
return stat;
}
return redoIt();
}
MStatus meshReorderCommand::redoIt()
{
MStatus stat = MStatus::kSuccess;
MIntArray newPolygonCounts;
MIntArray newPolygonConnects;
MFloatPointArray origVertices;
MFloatPointArray newVertices;
unsigned i;
MFnMesh theMesh( fDagPathSrc, &stat );
if( stat != MStatus::kSuccess )
{
displayError(" MFnMesh creation");
return stat;
}
stat = theMesh.getPoints (origVertices, MSpace::kObject );
if( stat != MStatus::kSuccess )
{
displayError(" MFnMesh getPoints");
return stat;
}
MIntArray faceTraversal( theMesh.numPolygons(), false );
MIntArray cvMapping(theMesh.numVertices(), -1);
MIntArray cvMappingInverse(theMesh.numVertices(), -1);
stat = meshMapUtils::traverseFace( fDagPathSrc, fFaceIdxSrc, fFaceVtxSrc[0], fFaceVtxSrc[1], faceTraversal,
cvMapping, cvMappingInverse,
newPolygonCounts, newPolygonConnects,
origVertices, newVertices );
if ( stat != MStatus::kSuccess )
{
displayError(" could not process all the mesh faces.");
return stat;
}
fVertices.copy(origVertices);
MItMeshPolygon polyIter(fDagPathSrc.node());
while(!polyIter.isDone())
{
fPolygonCounts.append(polyIter.polygonVertexCount());
for(i = 0; i < polyIter.polygonVertexCount(); i++)
{
fPolygonConnects.append(polyIter.vertexIndex(i));
}
polyIter.next();
}
fColorSetNames.clear();
theMesh.getColorSetNames(fColorSetNames);
int numColorSets = fColorSetNames.length();
fColorArrays = new MColorArray[numColorSets];
fColorIdsArrays = new MIntArray[numColorSets];
collectColorsUVs(theMesh, false);
stat = theMesh.createInPlace( newVertices.length(), newPolygonCounts.length(), newVertices, newPolygonCounts, newPolygonConnects );
if ( stat != MStatus::kSuccess )
{
displayError(" MFnMesh::createInPlace failed.");
fCVMapping.clear();
fCVMappingInverse.clear();
fVertices.clear();
fPolygonCounts.clear();
fPolygonConnects.clear();
delete [] fColorArrays; fColorArrays = NULL;
delete [] fColorIdsArrays;fColorIdsArrays = NULL;
resetColorsUVsMemory();
return stat;
}
assignColorsUVs(theMesh, cvMapping, cvMappingInverse, false);
fCVMapping = cvMapping;
fCVMappingInverse = cvMappingInverse;
return stat;
}
MStatus meshReorderCommand::undoIt()
{
MStatus stat = MStatus::kSuccess;
MFnMesh theMesh( fDagPathSrc );
fColorSetNames.clear();
theMesh.getColorSetNames(fColorSetNames);
collectColorsUVs(theMesh, true);
stat = theMesh.createInPlace( fVertices.length(), fPolygonCounts.length(), fVertices, fPolygonCounts, fPolygonConnects );
assignColorsUVs(theMesh, fCVMappingInverse, fCVMapping, true);
fCVMapping.clear();
fCVMappingInverse.clear();
fVertices.clear();
fPolygonCounts.clear();
fPolygonConnects.clear();
delete [] fColorArrays; fColorArrays = NULL;
delete [] fColorIdsArrays;fColorIdsArrays = NULL;
return stat;
}
void meshReorderCommand::collectColorsUVs(MFnMesh &theMesh, bool isUndo)
{
int i;
int numColorSets = fColorSetNames.length();
fClampedArray = new bool[numColorSets];
fRepArray = new MFnMesh::MColorRepresentation[numColorSets];
fVertexColorArrays = new MColorArray[numColorSets];
for (i = 0; i < numColorSets; i++)
{
fClampedArray[i] = theMesh.isColorClamped(fColorSetNames[i]);
fRepArray[i] = theMesh.getColorRepresentation(fColorSetNames[i]);
theMesh.getVertexColors(fVertexColorArrays[i], &(fColorSetNames[i]));
if(!isUndo) {
theMesh.getColors(fColorArrays[i], &(fColorSetNames[i]));
unsigned nth = 0;
fColorIdsArrays[i].setLength(theMesh.numColors(fColorSetNames[i]));
MItMeshPolygon polyIter(fDagPathSrc.node());
while(!polyIter.isDone())
{
for(unsigned j = 0; j < polyIter.polygonVertexCount(); j++)
{
unsigned polygonIdx = polyIter.index();
int colorId;
theMesh.getColorIndex(polygonIdx, j, colorId, &(fColorSetNames[i]));
fColorIdsArrays[i][nth] = colorId;
nth++;
}
polyIter.next();
}
}
theMesh.deleteColorSet(fColorSetNames[i]);
}
fUVSetNames.clear();
theMesh.getUVSetNames(fUVSetNames);
int numUVSets = fUVSetNames.length();
fUArrays = new MFloatArray[numUVSets];
fVArrays = new MFloatArray[numUVSets];
fUVIdsArrays = new MIntArray[numUVSets];
for (i = 0; i < numUVSets; i++)
{
MIntArray uvCounts;
MIntArray uvIds;
theMesh.getAssignedUVs(uvCounts, uvIds, &(fUVSetNames[i]));
unsigned nth = 0;
fUVIdsArrays[i].setLength(fVertices.length());
MItMeshPolygon polyIter(fDagPathSrc.node());
while(!polyIter.isDone())
{
for(unsigned j = 0; j < polyIter.polygonVertexCount(); j++)
{
unsigned vertexIdx = polyIter.vertexIndex(j);
fUVIdsArrays[i][vertexIdx] = uvIds[nth];
nth++;
}
polyIter.next();
}
theMesh.getUVs(fUArrays[i], fVArrays[i], &(fUVSetNames[i]));
theMesh.deleteUVSet(fUVSetNames[i]);
}
}
void meshReorderCommand::assignColorsUVs(MFnMesh &theMesh, MIntArray &colorMapping, MIntArray &uvMapping, bool isUndo)
{
int i;
MString defaultColorSetName;
theMesh.getCurrentColorSetName(defaultColorSetName);
int numColorSets = fColorSetNames.length();
for (i = 0; i < numColorSets; i++)
{
if (fColorSetNames[i] != defaultColorSetName)
{
theMesh.createColorSet(fColorSetNames[i], NULL, fClampedArray[i], fRepArray[i]);
}
if (fVertexColorArrays[i].length() > 0 && fVertexColorArrays[i].length() == fVertices.length())
{
if(!isUndo)
{
theMesh.setVertexColors(fVertexColorArrays[i], colorMapping, NULL, fRepArray[i]);
} else {
theMesh.setColors(fColorArrays[i], NULL, fRepArray[i]);
theMesh.assignColors(fColorIdsArrays[i], &(fColorSetNames[i]));
}
}
}
MString defaultUVSetName;
theMesh.getCurrentUVSetName(defaultUVSetName);
int numUVSets = fUVSetNames.length();
for (i = 0; i < numUVSets; i++)
{
if (fUVSetNames[i] != defaultUVSetName)
{
theMesh.createUVSet(fUVSetNames[i]);
}
if (fUArrays[i].length() > 0 && fUArrays[i].length() == fVArrays[i].length())
{
theMesh.setUVs(fUArrays[i], fVArrays[i], &(fUVSetNames[i]));
MItMeshPolygon polyIter(fDagPathSrc.node());
while(!polyIter.isDone())
{
for(unsigned j = 0; j < polyIter.polygonVertexCount(); j++)
{
unsigned polygonIdx = polyIter.index();
unsigned vertexIdx = polyIter.vertexIndex(j);
int uvId = fUVIdsArrays[i][uvMapping[vertexIdx]];
theMesh.assignUV(polygonIdx, j, uvId);
}
polyIter.next();
}
}
}
resetColorsUVsMemory();
}
void meshReorderCommand::resetColorsUVsMemory()
{
if (fClampedArray != NULL)
{
delete [] fClampedArray;
fClampedArray = NULL;
}
if (fRepArray != NULL)
{
delete [] fRepArray;
fRepArray = NULL;
}
if (fVertexColorArrays != NULL)
{
delete [] fVertexColorArrays;
fVertexColorArrays = NULL;
}
if (fUArrays != NULL)
{
delete [] fUArrays;
fUArrays = NULL;
}
if (fVArrays != NULL)
{
delete [] fVArrays;
fVArrays = NULL;
}
if (fUVIdsArrays != NULL)
{
delete [] fUVIdsArrays;
fUVIdsArrays = NULL;
}
fColorSetNames.clear();
fUVSetNames.clear();
}