#include "meshOpFty.h"
#include <maya/MGlobal.h>
#include <maya/MIOStream.h>
#include <maya/MFloatPointArray.h>
#include <maya/MFnMesh.h>
#include <maya/MItMeshPolygon.h>
#include <maya/MItMeshEdge.h>
#define CHECK_STATUS(st) if ((st) != MS::kSuccess) { break; }
{
    unsigned int i, j;
    
    
    
    
    
    
    
    int divisionCount = 2;
    if (fOperationType == kExtrudeEdges
        || fOperationType == kExtrudeFaces
        || fOperationType == kDuplicateFaces
        || fOperationType == kExtractFaces)
    {
        
        
        
        
        
        
        
        
        
        MFn::Type componentType = getExpectedComponentType(fOperationType);
 
        switch (componentType)
        {
            for (i = 0; i < fComponentIDs.length(); ++i)
            {
                int2 vertices;
                adjacentVertexList.
append(vertices[0]);
                adjacentVertexList.
append(vertices[1]);
            }
            break;
            for (i = 0; i < fComponentIDs.length(); ++i)
            {
                for (j = 0; j < vertices.
length(); ++j)
 
                    adjacentVertexList.
append(vertices[j]);
            }
            break;
        default:    
            break;
        }
        for (i = 0; i < adjacentVertexList.
length(); ++i)
 
        {
            averageNormal += vertexNormal;
        }
        if (averageNormal.
length() < 0.001)
 
            averageNormal = 
MVector(0.0, 1.0, 0.0);
        translation = averageNormal;
    }
    
    
    
    
    
    
    
    bool extrudeTogether = true;
    
    
    switch (fOperationType)
    {
    case kSubdivideEdges: {
        CHECK_STATUS(status);
        break; }
    case kSubdivideFaces: {
        CHECK_STATUS(status);
        break; }
    case kExtrudeEdges: {
            &translation, extrudeTogether);
        CHECK_STATUS(status);
        break; }
    case kExtrudeFaces: {
            &translation, extrudeTogether);
        CHECK_STATUS(status);
        break; }
    case kCollapseEdges: {
        CHECK_STATUS(status);
        break; }
    case kCollapseFaces: {
        CHECK_STATUS(status);
        break; }
    case kDuplicateFaces: {
        CHECK_STATUS(status);
        break; }
    case kExtractFaces: {
        CHECK_STATUS(status);
        break; }
    case kSplitLightning: {
        status = doLightningSplit(meshFn);
        CHECK_STATUS(status);
        break; }
    default:
        break;
    }
    return status;
}
{
    unsigned int i, j;
    
    
    
    
    
    
    
    
    
    
    bool* faceTouched = new bool[fComponentIDs.length()];
    for (i = 0; i < fComponentIDs.length(); ++i)
        faceTouched[i] = false;
    
    
    
    
    
    for (; !itPoly.isDone(); itPoly.next())
    {
        if (fComponentIDs[0] == (int)itPoly.index()) break;
    }
    if (itPoly.isDone())
    {
        
        
        delete [] faceTouched;
    }
    
    
    
    
    
    
    int edge0, edge1;
    MPoint innerVert0, innerVert1;
 
    int nextFaceIndex = 0;
    
    
    
    
    itPoly.getEdges(edgeList);
    edge0 = edgeList[0];
    
    bool done = false;
    while (!done)
    {
        
        
        faceTouched[nextFaceIndex] = true;
        
        
        
        
        MPoint faceCenter = itPoly.center();
 
            
        
        
        
        
        itPoly.getConnectedFaces(faceList);
        nextFaceIndex = -1;
        for (i = 0; i < fComponentIDs.length(); ++i)
        {
            for (j = 0; j < faceList.
length(); ++j)
 
            {
                if (fComponentIDs[i] == faceList[j] && !faceTouched[i])
                {
                    nextFaceIndex = i;
                    break;
                }
            }
            if (nextFaceIndex != -1) break;
        }
        
        if (nextFaceIndex == -1)
        {
            
            
            
            
            done = true;
            edge1 = -1;
            for (i = 0; i < edgeList.
length(); ++i)
 
            {
                if (edgeList[i] != edge0)
                {
                    edge1 = edgeList[i];
                    break;
                }
            }
            if (edge1 == -1)
            {
                
                
                
                delete [] faceTouched;
            }
        }
        else
        {
            
            
            
            
            
            itPoly.reset();
            for (; !itPoly.isDone(); itPoly.next())
            {
                if (fComponentIDs[nextFaceIndex] == (int)itPoly.index()) break;
            }
            if (itPoly.isDone()) 
            {
                
                
                delete [] faceTouched;
            }
            
            
            
            itPoly.getEdges(nextFaceEdgeList);
            edge1 = -1;
            for (i = 0; i < edgeList.
length(); ++i)
 
            {
                for (j = 0; j < nextFaceEdgeList.
length(); ++j)
 
                {
                    if (edgeList[i] == nextFaceEdgeList[j])
                    {
                        edge1 = edgeList[i];
                        break;
                    }
                }
                if (edge1 != -1) break;
            }
            if (edge1 == -1)
            {
                
                
                delete [] faceTouched;
            }
            
            
            
            edgeList = nextFaceEdgeList;
        }
        
        
        
        
        
        
        
        MPoint edge0vert0, edge0vert1, edge1vert0, edge1vert1;
 
        for (; !itEdge.isDone(); itEdge.next())
        {
            if (itEdge.index() == edge0)
            {
                edge0vert0 = itEdge.point(0);
                edge0vert1 = itEdge.point(1);
            }
            if (itEdge.index() == edge1)
            {
                edge1vert0 = itEdge.point(0);
                edge1vert1 = itEdge.point(1);
            }
        }
        
        
        
        double distMax = edge0vert0.
distanceTo(edge1vert0);
 
        max0 = edge0vert0;
        max1 = edge1vert0;
        double newDist = edge0vert1.
distanceTo(edge1vert0);
 
        if (newDist > distMax)
        {
            max0 = edge0vert1;
            max1 = edge1vert0;
            distMax = newDist;
        }
        if (newDist > distMax)
        {
            max0 = edge0vert0;
            max1 = edge1vert1;
            distMax = newDist;
        }
        if (newDist > distMax)
        {
            max0 = edge0vert1;
            max1 = edge1vert1;
        }
        
        
        
        innerVert0 = (faceCenter + max0) / 2.0;
        innerVert1 = (faceCenter + max1) / 2.0;
        
        
        
        
        placements.
append((
int) MFnMesh::kInternalPoint);
        if (done) placements.
append((
int) MFnMesh::kOnEdge);
 
        
        if (done) edgeIDs.
append(edge1);
 
        
        if (done) edgeFactors.
append(0.5f);
 
        
        MFloatPoint point1((
float)innerVert0[0], (
float)innerVert0[1],
 
            (float)innerVert0[2], (float)innerVert0[3]);
        MFloatPoint point2((
float)innerVert1[0], (
float)innerVert1[1],
 
            (float)innerVert1[2], (float)innerVert1[3]);
        internalPoints.
append(point1);
        internalPoints.
append(point2);
        
        
        
        
        edge0 = edge1;
    }
    
    
    delete [] faceTouched;
    return meshFn.
split(placements, edgeIDs, edgeFactors, internalPoints);
 
}