flipUVCmd.cpp
#include <flipUVCmd.h>
#include <maya/MIOStream.h>
#include <maya/MSyntax.h>
#include <maya/MArgDatabase.h>
#include <maya/MIntArray.h>
#include <maya/MFloatArray.h>
#include <maya/MFnMesh.h>
static const char * horizFlag                   = "-h";
static const char * horizFlagLong               = "-horizontal";
static const char * globalFlag                  = "-fg";
static const char * globalFlagLong              = "-flipGlobal";
static const char * extendFlag                  = "-es";
static const char * extendFlagLong              = "-extendToShell";
const char * flipUVCmd::cmdName = "flipUV";
flipUVCmd::flipUVCmd() :
        horizontal(false),
        extendToShell(false),
        flipGlobal(false)
{}
flipUVCmd::~flipUVCmd() {}
void *flipUVCmd::creator() { return new flipUVCmd; }
MSyntax flipUVCmd::newSyntax ()
{
        MStatus status;
        
        MSyntax syntax = MPxPolyTweakUVCommand::newSyntax();
        status = syntax.addFlag(horizFlag, horizFlagLong, MSyntax::kBoolean);
        CHECK_MSTATUS_AND_RETURN(status, syntax);
        status = syntax.addFlag(globalFlag, globalFlagLong, MSyntax::kBoolean);
        CHECK_MSTATUS_AND_RETURN(status, syntax);
        status = syntax.addFlag(extendFlag, extendFlagLong, MSyntax::kBoolean);
        CHECK_MSTATUS_AND_RETURN(status, syntax);
        return syntax;
}
MStatus flipUVCmd::parseSyntax (MArgDatabase &argData)
{
        MStatus status;
        
        
        if (argData.isFlagSet(horizFlag)) {
                status = argData.getFlagArgument(horizFlag, 0, horizontal);
                CHECK_MSTATUS_AND_RETURN_IT(status);
        }
        if (argData.isFlagSet(globalFlag)) {
                status = argData.getFlagArgument(globalFlag, 0, flipGlobal);
                CHECK_MSTATUS_AND_RETURN_IT(status);
        }
        if (argData.isFlagSet(extendFlag)) {
                status = argData.getFlagArgument(extendFlag, 0, extendToShell);
                CHECK_MSTATUS_AND_RETURN_IT(status);
        }
        return MS::kSuccess;
}
MStatus flipUVCmd::getTweakedUVs(
        const MObject & meshObj,                                        
        MIntArray & uvList,                                             
        MFloatArray & uPos,                                             
        MFloatArray & vPos )                                    
{
        MStatus status;
        unsigned int i;
        MFloatArray uArray;
        MFloatArray vArray;
        
        MFnMesh mesh( meshObj );
        
        status = mesh.getUVs(uArray, vArray);
        CHECK_MSTATUS_AND_RETURN_IT(status);
        unsigned int nbUvShells = 1;
        MIntArray uvShellIds;
        if ((!flipGlobal) || extendToShell)
        {
                
                status = mesh.getUvShellsIds(uvShellIds, nbUvShells);
                CHECK_MSTATUS_AND_RETURN_IT(status);
        }
        if (extendToShell)
        {
                
                bool *selected = new bool[nbUvShells];
                for (i = 0 ; i<nbUvShells ; i++)
                        selected[i] = false;
                for (i = 0 ; i<uvList.length() ; i++)
                {
                        int indx = uvList[i];
                        selected[uvShellIds[indx]] = true;
                }
                
                
                unsigned int numUvs = mesh.numUVs();
                unsigned int numSelUvs = 0;
                
                
                
                uvList.setLength(numUvs);
                for (i = 0 ; i<numUvs ; i++)
                {
                        if (selected[uvShellIds[i]])
                                uvList[numSelUvs++] = i;
                }
                
                uvList.setLength(numSelUvs);
                delete [] selected;
        }
        
        if (flipGlobal) nbUvShells = 1;
        float *minMax = new float[nbUvShells*4];
        for (i = 0 ; i<nbUvShells ; i++)
        {
                minMax[4*i+0] =  1e30F;                         
                minMax[4*i+1] =  1e30F;                         
                minMax[4*i+2] = -1e30F;                         
                minMax[4*i+3] = -1e30F;                         
        }
        
        
        for (i = 0 ; i<uvList.length() ; i++)
        {
                int indx = uvList[i];
                int shellId = 0;
                if (!flipGlobal) shellId = uvShellIds[indx];
                if (uArray[indx] < minMax[4*shellId+0]) 
                        minMax[4*shellId+0] = uArray[indx];
                if (vArray[indx] < minMax[4*shellId+1])
                        minMax[4*shellId+1] = vArray[indx];
                if (uArray[indx] > minMax[4*shellId+2]) 
                        minMax[4*shellId+2] = uArray[indx];
                if (vArray[indx] > minMax[4*shellId+3])
                        minMax[4*shellId+3] = vArray[indx];
        }
        
        uPos.setLength(uvList.length());
        vPos.setLength(uvList.length());
        for (i = 0 ; i<uvList.length() ; i++)
        {
                int shellId = 0;
                int indx = uvList[i];
                if (!flipGlobal) shellId = uvShellIds[indx];
                
                
                if (horizontal)
                {
                        uPos[i] = minMax[4*shellId+0] + minMax[4*shellId+2] -
                                uArray[indx];
                        vPos[i] = vArray[indx];
                }
                else
                {
                        uPos[i] = uArray[indx];
                        vPos[i] = minMax[4*shellId+1] + minMax[4*shellId+3] -
                                vArray[indx];
                }
        }
        delete [] minMax;
        return MS::kSuccess;
}