#include <maya/MIOStream.h>
#include <maya/MFnPlugin.h>
#include <maya/MString.h>
#include <maya/MFloatArray.h>
#include <maya/MArgList.h>
#include <maya/MPxCommand.h>
#include <maya/MSyntax.h>
#include <maya/MArgDatabase.h>
#include <maya/MGlobal.h>
#include <maya/MDagPath.h>
#include <maya/MItSelectionList.h>
#include <maya/MSelectionList.h>
#include <maya/MItMeshPolygon.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MFnSet.h>
#include <maya/MPlugArray.h>
#include <maya/MPlug.h>
#include <math.h>
#define kExitFlag   "-ea"
#define kExitFlagLong   "-exitAfterNthPairs"
{
public:
                         peltOverlap();
                ~peltOverlap() override; 
    static void*    creator();
private:
        unsigned int    checkCrossingEdges(
MFloatArray &face1Orig, 
 
    unsigned int    fNthPairs;
};
peltOverlap::peltOverlap()
    : fNthPairs (1)
{}
peltOverlap::~peltOverlap() {}
void* peltOverlap::creator()
{
    return new peltOverlap;
}
{
     return syntax;
}
{
    if (argData.isFlagSet(kExitFlag)) {
        status = argData.getFlagArgument(kExitFlag, 0, fNthPairs);
        if (status != MS::kSuccess) {
        return status;
        }
    }
    status = argData.getObjects(fShadingGroups);
    if (status != MS::kSuccess || fShadingGroups.length() < 1) {
        status = MS::kFailure;
    }
    return status;
}
{
    MStatus status = parseArgs ( args );
 
    if ( !status ) return status;
    
    for (unsigned int i = 0; i < fShadingGroups.length(); i++ ) 
    {
        
        
        for(
unsigned int j = 0; j < faces.
length(); j++) 
 
        {
        if (nodeType == "mesh") {
        }
        }
        numOverlapUVFaces(fShadingGroups[i], flattenFaces);
    }
    return MS::kSuccess;
}
{
    for(
unsigned int i = 0; i < flattenFaces.
length(); i++) {
 
        selList.
add(flattenFaces[i]);
 
        iter.getUVs(uArray, vArray);
        
        float cu = 0.f;
        float cv = 0.f;
        unsigned int j;
        for(j = 0; j < uArray.
length(); j++) {
 
                cu += uArray[j];
            cv += vArray[j];
        }
        float rsqr = 0.f;
        for(j = 0; j < uArray.
length(); j++) {
 
                float du = uArray[j] - cu;
            float dv = vArray[j] - cv;
            float dsqr = du*du + dv*dv;
            rsqr = dsqr > rsqr ? dsqr : rsqr;
        }
        center[2*i]   = cu;
        center[2*i+1] = cv;
        radius[i]  = sqrt(rsqr);
    }
}
{
    iter.getUVs(uArray, vArray);
    if (uArray.
length() == 0 || vArray.
length() == 0) 
return false;
 
    
    float u = uArray[uArray.
length() - 1];
 
    float v = vArray[vArray.
length() - 1];
 
    for(
unsigned int j = 0; j < uArray.
length(); j++) {
 
        orig[2*j]   = uArray[j];
        orig[2*j+1] = vArray[j];
        vec[2*j]    = u - uArray[j];
        vec[2*j+1]  = v - vArray[j];
        u = uArray[j];
        v = vArray[j];
    }
    return true;
}
{
    float sum = 0.f;
    unsigned int num = orig.
length() / 2;
 
    for (unsigned int i = 0; i < num; i++) {
        unsigned int idx  = 2 * i;
        unsigned int idy  = (i + 1 ) % num;
        idy = 2 * idy + 1;
        unsigned int idy2 = (i + num - 1) % num; 
        idy2 = 2 * idy2 + 1;
        sum += orig[idx] * (orig[idy] - orig[idy2]);
    }
    return fabs(sum) * 0.5f;
}
unsigned int peltOverlap::checkCrossingEdges(
)
{
    unsigned int face1Size = face1Orig.
length();
 
    unsigned int face2Size = face2Orig.
length();
 
    for (unsigned int i = 0; i < face1Size; i += 2) {
        float o1x = face1Orig[i];
        float o1y = face1Orig[i+1];
        float v1x = face1Vec[i];
        float v1y = face1Vec[i+1];
        float n1x =  v1y;
        float n1y = -v1x;
        for (unsigned int j = 0; j < face2Size; j += 2) {
            
            
            float o2x = face2Orig[j];
            float o2y = face2Orig[j+1];
            float v2x = face2Vec[j];
            float v2y = face2Vec[j+1];
            float n2x =  v2y;
            float n2y = -v2x;
            
            
            float denum = v2x * n1x + v2y * n1y;
            
            if (fabs(denum) < 0.000001f) continue;
            float t2 = ((o1x-o2x)* n1x + (o1y-o2y) * n1y) / denum;
            if (t2 < 0.00001f || t2 > 0.99999f) continue;
            
            
            denum = v1x * n2x + v1y * n2y;
            
            if (fabs(denum) < 0.000001f) continue;
            float t1 = ((o2x-o1x)* n2x + (o2y-o1y) * n2y) / denum;
            
            if (t1 > 0.00001f && t1 < 0.99999f) return 1;
        }
    }
    return 0;
}
{
    MFloatArray  face1Orig, face1Vec, face2Orig, face2Vec, center, radius;
 
    
    unsigned int numOverlap = 0;
    createBoundingCircle(flattenFaces, center, radius);
    for(
unsigned int i = 0; i < flattenFaces.
length() && numOverlap < fNthPairs; i++) {
 
            if(!createRayGivenFace(flattenFaces[i], face1Orig, face1Vec)) continue;
        const float cui  = center[2*i];
        const float cvi  = center[2*i+1];
        const float ri  = radius[i];
        
        
        
        for(
unsigned int j = i+1; j < flattenFaces.
length() && numOverlap < fNthPairs; j++) {
 
            const float &cuj = center[2*j];
            const float &cvj = center[2*j+1];
            const float &rj  = radius[j];
            float du = cuj - cui;
            float dv = cvj - cvi;
            float dsqr = du*du + dv*dv;
            
            if (dsqr >= (ri+rj)*(ri+rj)) continue;
            if(!createRayGivenFace(flattenFaces[j], face2Orig, face2Vec)) continue;
            
            
            if (checkCrossingEdges(face1Orig, face1Vec, face2Orig, face2Vec)) {
                numOverlap++;
                appendToResult(flattenFaces[i]);
                appendToResult(flattenFaces[j]);
                continue;
            }
        }
    }
}
{
    MFnPlugin plugin( obj, PLUGIN_COMPANY, 
"3.0", 
"Any");
 
    status = plugin.registerCommand( "peltOverlap",
                     peltOverlap::creator,
                     peltOverlap::newSyntax);
    if (!status) {
        status.
perror(
"registerCommand");
 
        return status;
    }
    return status;
}
{
    status = plugin.deregisterCommand( "peltOverlap" );
    if (!status) {
        status.
perror(
"deregisterCommand");
 
        return status;
    }
    return status;
}