#include "apiMeshGeometryOverride.h"
#include "apiMeshShape.h"
#include "apiMeshGeom.h"
#include <maya/MGlobal.h>
#include <maya/MUserData.h>
#include <maya/MSelectionList.h>
#include <maya/MPxComponentConverter.h>
#include <maya/MSelectionContext.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MHWGeometry.h>
#include <maya/MShaderManager.h>
#include <maya/MViewport2Renderer.h>
#include <maya/MDrawContext.h>
#include <maya/MHWGeometryUtilities.h>
#include <maya/MObjectArray.h>
#include <maya/MFnSingleIndexedComponent.h>
#include <maya/MFnDagNode.h>
#include <maya/MDrawRegistry.h>
#include <set>
#include <vector>
{
public:
    apiMeshUserData()
    , fMessage("")
    , fNumModifications(0)
    {
    }
    virtual ~apiMeshUserData()
    {
    }
    int fNumModifications;
};
class apiMeshHWSelectionUserData : 
public MUserData 
{
public:
    apiMeshHWSelectionUserData()
    , fMeshGeom(NULL)
    {
    }
    virtual ~apiMeshHWSelectionUserData()
    {
    }
    apiMeshGeom* fMeshGeom;
};
static void callbackDataPrint(
{
    int numItems = renderItemList.
length();
 
    for (int i=0; i<numItems; i++)
    {
        item = renderItemList.
itemAt(i);
        if (item)
        {
        }
    }
    printf(
"tAPI mesh drawing in pass[%s], semantic[", passId.
asChar());
    for (
unsigned int i=0; i<passSem.
length(); i++)
 
        printf(" %s", passSem[i].asChar());
    printf("\n");
}
static void apiMeshPreDrawCallback(
{
    printf("PRE-draw callback triggered for render item list with data:\n");
    callbackDataPrint(context, renderItemList);
    printf("\n");
}
static void apiMeshPostDrawCallback(
{
    printf("POST-draw callback triggered for render item list with data:\n");
    callbackDataPrint(context, renderItemList);
    printf("\n");
}
{
public:
    meshVertComponentConverter() : 
MHWRender::MPxComponentConverter() {}
    virtual ~meshVertComponentConverter() {}
    {
        
        
        
        
        apiMeshHWSelectionUserData* selectionData = 
dynamic_cast<apiMeshHWSelectionUserData*
>(renderItem.
customData());
        if(selectionData)
        {
            apiMeshGeom* meshGeom = selectionData->fMeshGeom;
            
            {
                unsigned int numTriangles = 0;
                for (int i=0; i<meshGeom->faceCount; i++)
                {
                    int numVerts = meshGeom->face_counts[i];
                    if (numVerts > 2)
                    {
                        numTriangles += numVerts - 2;
                    }
                }
                fVertices.resize(3*numTriangles);
            }
            
            unsigned int base = 0;
            unsigned int idx = 0;
            for (int faceIdx=0; faceIdx<meshGeom->faceCount; faceIdx++)
            {
                
                int numVerts = meshGeom->face_counts[faceIdx];
                if (numVerts > 2)
                {
                    for (int v=1; v<numVerts-1; v++)
                    {
                        fVertices[idx++] = meshGeom->face_connects[base];
                        fVertices[idx++] = meshGeom->face_connects[base+v];
                        fVertices[idx++] = meshGeom->face_connects[base+v+1];
                    }
                    base += numVerts;
                }
            }
        }
    }
    {
        
        
        const int rawIdx = intersection.
index();
 
        int idx = 0;
        if(rawIdx >= 0 && rawIdx < (int)fVertices.size())
            idx = fVertices[rawIdx];
        fComponent.addElement(idx);
    }
    {
        
        return fComponentObject;
    }
    {
        
        return retVal;
    }
    static MPxComponentConverter* creator()
    {
        return new meshVertComponentConverter();
    }
private:
    std::vector<int> fVertices;
};
{
public:
    meshEdgeComponentConverter() : 
MHWRender::MPxComponentConverter() {}
    virtual ~meshEdgeComponentConverter() {}
    {
        
        
        
        
        
        
        
        
        
        apiMeshHWSelectionUserData* selectionData = 
dynamic_cast<apiMeshHWSelectionUserData*
>(renderItem.
customData());
        if(selectionData)
        {
            apiMeshGeom* meshGeom = selectionData->fMeshGeom;
            
            {
                unsigned int totalVerts = 0;
                for (int i=0; i<meshGeom->faceCount; i++)
                {
                    int numVerts = meshGeom->face_counts[i];
                    if (numVerts > 2)
                    {
                        totalVerts += numVerts;
                    }
                }
                fEdges.resize(totalVerts);
            }
            
            unsigned int idx = 0;
            int edgeId = 0;
            for (int faceIdx=0; faceIdx<meshGeom->faceCount; faceIdx++)
            {
                
                int numVerts = meshGeom->face_counts[faceIdx];
                if (numVerts > 2)
                {
                    for (int v=0; v<numVerts; v++)
                    {
                        fEdges[idx++] = edgeId;
                        ++edgeId;
                    }
                }
            }
        }
    }
    {
        
        
        const int rawIdx = intersection.
index();
 
        int idx = 0;
        if(rawIdx >= 0 && rawIdx < (int)fEdges.size())
            idx = fEdges[rawIdx];
        fComponent.addElement(idx);
    }
    {
        
        return fComponentObject;
    }
    {
        
    }
    static MPxComponentConverter* creator()
    {
        return new meshEdgeComponentConverter();
    }
private:
    std::vector<int> fEdges;
};
{
public:
    meshFaceComponentConverter() : 
MHWRender::MPxComponentConverter() {}
    virtual ~meshFaceComponentConverter() {}
    {
        
        
        
        
        
        
        
        
        
        apiMeshHWSelectionUserData* selectionData = 
dynamic_cast<apiMeshHWSelectionUserData*
>(renderItem.
customData());
        if(selectionData)
        {
            apiMeshGeom* meshGeom = selectionData->fMeshGeom;
            
            {
                unsigned int numTriangles = 0;
                for (int i=0; i<meshGeom->faceCount; i++)
                {
                    int numVerts = meshGeom->face_counts[i];
                    if (numVerts > 2)
                    {
                        numTriangles += numVerts - 2;
                    }
                }
                fFaces.resize(numTriangles);
            }
            
            unsigned int idx = 0;
            for (int faceIdx=0; faceIdx<meshGeom->faceCount; faceIdx++)
            {
                
                int numVerts = meshGeom->face_counts[faceIdx];
                if (numVerts > 2)
                {
                    for (int v=1; v<numVerts-1; v++)
                    {
                        fFaces[idx++] = faceIdx;
                    }
                }
            }
        }
    }
    {
        
        
        const int rawIdx = intersection.
index();
 
        int idx = 0;
        if(rawIdx >= 0 && rawIdx < (int)fFaces.size())
            idx = fFaces[rawIdx];
        fComponent.addElement(idx);
    }
    {
        
        return fComponentObject;
    }
    {
        
    }
    static MPxComponentConverter* creator()
    {
        return new meshFaceComponentConverter();
    }
private:
    std::vector<int> fFaces;
};
const MString apiMeshGeometryOverride::sWireframeItemName = 
"apiMeshWire";
 
const MString apiMeshGeometryOverride::sShadedTemplateItemName = 
"apiMeshShadedTemplateWire";
 
const MString apiMeshGeometryOverride::sSelectedWireframeItemName = 
"apiMeshSelectedWireFrame";
 
const MString apiMeshGeometryOverride::sVertexItemName = 
"apiMeshVertices";
 
const MString apiMeshGeometryOverride::sActiveVertexItemName = 
"apiMeshActiveVertices";
 
const MString apiMeshGeometryOverride::sVertexIdItemName = 
"apiMeshVertexIds";
 
const MString apiMeshGeometryOverride::sVertexPositionItemName = 
"apiMeshVertexPositions";
 
const MString apiMeshGeometryOverride::sShadedModeFaceCenterItemName = 
"apiMeshFaceCenterInShadedMode";
 
const MString apiMeshGeometryOverride::sWireframeModeFaceCenterItemName = 
"apiMeshFaceCenterInWireframeMode";
 
const MString apiMeshGeometryOverride::sShadedProxyItemName = 
"apiShadedProxy";
 
const MString apiMeshGeometryOverride::sAffectedEdgeItemName = 
"apiMeshAffectedEdges";
 
const MString apiMeshGeometryOverride::sAffectedFaceItemName = 
"apiMeshAffectedFaces";
 
const MString apiMeshGeometryOverride::sEdgeSelectionItemName = 
"apiMeshEdgeSelection";
 
const MString apiMeshGeometryOverride::sFaceSelectionItemName = 
"apiMeshFaceSelection";
 
const MString apiMeshGeometryOverride::sActiveVertexStreamName = 
"apiMeshSharedVertexStream";
 
const MString apiMeshGeometryOverride::sFaceCenterStreamName = 
"apiMeshFaceCenterStream";
 
apiMeshGeometryOverride::apiMeshGeometryOverride(
const MObject& obj)
: MPxGeometryOverride(obj)
, fMesh(NULL)
, fMeshGeom(NULL)
, fColorRemapTexture(NULL)
, fLinearSampler(NULL)
{
    
    if (status)
    {
        fMesh = dynamic_cast<apiMesh*>(node.userNode());
    }
    fDrawSharedActiveVertices = true; 
    fDrawFaceCenters = true; 
    
    fDrawActiveVerticesWithRamp = false;
    if (fDrawActiveVerticesWithRamp)
    {
        fDrawFaceCenters = false; 
    }
    
    
    
    fUseCustomColors = false;
    
    
    fProxyShader = 
        
        
        
        
        
        
        
        
        
        
        
        
    ;
    
    
    fInternalItems_NoShadowCast = false;
    fInternalItems_NoShadowReceive = false;
    fInternalItems_NoPostEffects = false;
    
    
    fExternalItems_NoShadowCast = false;
    fExternalItems_NoShadowReceive = false;
    fExternalItemsNonTri_NoShadowCast = false;
    fExternalItemsNonTri_NoShadowReceive = false;
    
    
    fExternalItems_NoPostEffects = true;
    fExternalItemsNonTri_NoPostEffects = true;
}
apiMeshGeometryOverride::~apiMeshGeometryOverride()
{
    fMesh = NULL;
    fMeshGeom = NULL;
    if (fColorRemapTexture)
    {
        if (textureMgr) 
        {
            fColorRemapTexture = NULL;
        }
    }
    if (fLinearSampler)
    {
        fLinearSampler = NULL;
    }
}
{
    
}
void apiMeshGeometryOverride::updateDG()
{
    
    
    fActiveVertices.clear();
    fActiveVerticesSet.clear();
    fActiveEdgesSet.clear();
    fActiveFacesSet.clear();
    if (fMesh)
    {
        fMeshGeom = fMesh->meshGeom();
        if (fMesh->hasActiveComponents())
        {
            if (activeComponents.
length())
 
            {
                if (fnComponent.elementCount())
                {
                    fnComponent.getElements( activeIds );
                    {
                        fActiveVertices = activeIds;
                        for (
unsigned int i=0; i<activeIds.
length(); ++i)
 
                            fActiveVerticesSet.
insert( activeIds[i] );
                    }
                    {
                        for (
unsigned int i=0; i<activeIds.
length(); ++i)
 
                            fActiveEdgesSet.insert( activeIds[i] );
                    }
                    {
                        for (
unsigned int i=0; i<activeIds.
length(); ++i)
 
                            fActiveFacesSet.insert( activeIds[i] );
                    }
                }
            }
        }
    }
}
{
    if (!shader)
        return;
    unsigned int numParams = params.
length();
 
    printf("DEBUGGING SHADER, BEGIN PARAM LIST OF LENGTH %d\n", numParams);
    for (unsigned int i=0; i<numParams; i++)
    {
        printf("ParamName='%s', ParamType=", params[i].asChar());
        {
            printf("'Invalid', ");
            break;
            printf("'Boolean', ");
            break;
            printf("'Integer', ");
            break;
            printf("'Float', ");
            break;
            printf("'Float2', ");
            break;
            printf("'Float3', ");
            break;
            printf("'Float4', ");
            break;
            printf("'Float4x4Row', ");
            break;
            printf("'Float4x4Col', ");
            break;
            printf("'1D Texture', ");
            break;
            printf("'2D Texture', ");
            break;
            printf("'3D Texture', ");
            break;
            printf("'Cube Texture', ");
            break;
            printf("'Sampler', ");
            break;
        default:
            printf("'Unknown', ");
            break;
        }
        printf(
"IsArrayParameter='%s'\n", shader->
isArrayParameter(params[i]) ? 
"YES" : 
"NO");
    }
    printf("END PARAM LIST\n");
}
{
    if (!shaderInstance)
        return;
    const MString colorParameterName = 
"solidColor";
 
}
{
    if (!shaderInstance)
        return;
    const float pointSizeArray[2] = {pointSize, pointSize};
    const MString pointSizeParameterName = 
"pointSize";
 
    shaderInstance->
setParameter( pointSizeParameterName, pointSizeArray );
}
{
    if (!shaderInstance)
        return;
    const float lineWidthArray[2] = {lineWidth, lineWidth};
    const MString lineWidthParameterName = 
"lineWidth";
 
    shaderInstance->
setParameter( lineWidthParameterName, lineWidthArray );
}
void apiMeshGeometryOverride::updateDormantAndTemplateWireframeItems(
{
    
    static const float dormantColor[] = { 0.0f, 0.0f, 1.0f, 1.0f };
    static const float templateColor[] = { 0.45f, 0.45f, 0.45f, 1.0f };
    static const float activeTemplateColor[] = { 1.0f, 0.5f, 0.5f, 1.0f };
    
    
    static const bool debugShader = false;
    
    
    
    int index = list.
indexOf(sWireframeItemName);
 
    if (index < 0)
    {
            sWireframeItemName,
            primitive);
        
        
            debugShader ? apiMeshPreDrawCallback : NULL,
            debugShader ? apiMeshPostDrawCallback : NULL);
        if (shader)
        {
            
            
            if (debugShader)
            {
                printShader( shader );
            }
            
        }
    }
    else
    {
        wireframeItem = list.
itemAt(index);
    }
    
    
    int index2 = list.
indexOf(sShadedTemplateItemName);
 
    if (index2 < 0)
    {
            sShadedTemplateItemName,
            primitive);
        
        
        list.
append(shadedTemplateItem);
            NULL, NULL);
        if (shader)
        {
            
            
            if (debugShader)
            {
                printShader( shader );
            }
            
        }
    }
    else
    {
        shadedTemplateItem = list.
itemAt(index2);
    }
    
    if (fExternalItemsNonTri_NoShadowCast)
    if (fExternalItemsNonTri_NoShadowReceive)
    if (fExternalItemsNonTri_NoPostEffects)
    
    
    if (wireframeItem)
    {
        switch (displayStatus) {
            if (shader)
            {
                setSolidColor( shader, !fUseCustomColors ? &(wireColor.
r) : templateColor);
            }
            break;
            if (shader)
            {
                setSolidColor( shader, !fUseCustomColors ? &(wireColor.
r) : activeTemplateColor );
            }
            break;
            if (shader)
            {
                setSolidColor( shader, !fUseCustomColors ? &(wireColor.
r) : dormantColor);
            }
            break;
            if (shader)
            {
                static const float theColor[] = { 0.5f, 0.0f, 1.0f, 1.0f };
                setSolidColor( shader, !fUseCustomColors ? &(wireColor.
r) : theColor );
            }
            break;
        default:
            break;
        }
    }
    
    
    if (shadedTemplateItem)
    {
        switch (displayStatus) {
            if (shader)
            {
                setSolidColor( shader, !fUseCustomColors ? &(wireColor.
r) : templateColor );
            }
            shadedTemplateItem->
enable(isTemplate);
            break;
            if (shader)
            {
                setSolidColor( shader, !fUseCustomColors ? &(wireColor.
r) : activeTemplateColor );
            }
            shadedTemplateItem->
enable(isTemplate);
            break;
            if (shader)
            {
                setSolidColor( shader, !fUseCustomColors ? &(wireColor.
r) : dormantColor);
            }
            shadedTemplateItem->
enable(isTemplate);
            break;
        default:
            shadedTemplateItem->
enable(
false);
            break;
        }
    }
}
void apiMeshGeometryOverride::updateActiveWireframeItem(
const MDagPath& path,
 
{
    int index = list.
indexOf(sSelectedWireframeItemName);
 
    if (index < 0)
    {
            sSelectedWireframeItemName,
        
        
        
        
        
        
        static const bool drawThick = false;
        if (shader)
        {
            
            
        }
    }
    else
    {
        selectItem = list.
itemAt(index);
    }
    if (selectItem)
    {
    }
    switch (displayStatus) {
        if (shader)
        {
            static const float theColor[] = { 0.0f, 0.8f, 0.0f, 1.0f };
            setSolidColor( shader, !fUseCustomColors ? &(wireColor.
r) : theColor );
        }
        break;
        if (shader)
        {
            static const float theColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
            setSolidColor( shader, !fUseCustomColors ? &(wireColor.
r) : theColor );
        }
        break;
        if (shader)
        {
            static const float theColor[] = { 0.0f, 0.5f, 0.7f, 1.0f };
            setSolidColor( shader, !fUseCustomColors ? &(wireColor.
r) : theColor );
        }
        break;
    default:
        break;
    };
    
    apiMeshUserData* myCustomData = 
dynamic_cast<apiMeshUserData*
>(selectItem->
customData());
    if (!myCustomData)
    {
        
        myCustomData = new apiMeshUserData();
        myCustomData->fMessage = "I'm custom data!";
    }
    else
    {
        
        myCustomData->fNumModifications++;
    }
}
{
    
    bool enableNumiercDisplay = false;
    
    
    int index = list.
indexOf(sVertexIdItemName);
 
    if (index < 0)
    {
            sVertexIdItemName,
        
        if (shader)
        {
            
            vertexItem->
setShader(shader, &sVertexIdItemName);
        }
    }
    else
    {
        vertexItem = list.
itemAt(index);
    }
    if (vertexItem)
    {
        if (shader)
        {
            
            static const float theColor[] = { 1.0f, 1.0f, 0.0f, 1.0f };
            setSolidColor( shader, theColor);
        }
        vertexItem->
enable(enableNumiercDisplay);
    }
    
    
    index = list.
indexOf(sVertexPositionItemName);
    if (index < 0)
    {
            sVertexPositionItemName,
        
        if (shader)
        {
            
            vertexItem2->
setShader(shader, &sVertexPositionItemName);
        }
    }
    else
    {
        vertexItem2 = list.
itemAt(index);
    }
    if (vertexItem2)
    {
        if (shader)
        {
            
            static const float theColor[] = { 0.0f, 1.0f, 1.0f, 1.0f };
            setSolidColor( shader, theColor);
        }
        vertexItem2->
enable(enableNumiercDisplay);
    }
}
{
    int index = list.
indexOf(sVertexItemName);
 
    if (index < 0)
    {
            sVertexItemName,
        
        
        
        
        
        if (shader)
        {
            
            static const float pointSize = 3.0f;
            setSolidPointSize( shader, pointSize );
            
            
        }
    }
    else
    {
        vertexItem = list.
itemAt(index);
    }
    if (vertexItem)
    {
        if (shader)
        {
            
            static const float theColor[] = { 0.0f, 0.0f, 1.0f, 1.0f };
            setSolidColor( shader, theColor);
        }
        
        
        {
            
            
            
            else
        }
        else
        {
        }
        apiMeshHWSelectionUserData* mySelectionData = 
dynamic_cast<apiMeshHWSelectionUserData*
>(vertexItem->
customData());
        if (!mySelectionData)
        {
            
            mySelectionData = new apiMeshHWSelectionUserData();
        }
        
        mySelectionData->fMeshGeom = fMeshGeom;
    }
}
{
    int index = list.
indexOf(sActiveVertexItemName);
 
    if (index < 0)
    {
            sActiveVertexItemName,
        
        
        if (shader)
        {
            
            static const float pointSize = 5.0f;
            setSolidPointSize( shader, pointSize );
            
            
            if (fDrawActiveVerticesWithRamp )
            {
                
                if (!fColorRemapTexture)
                {
                    
                    float colorArray[12];
                    colorArray[0] = 1.0f; colorArray[1] = 0.0f; colorArray[2] = 0.0f; colorArray[3] = 1.0f;
                    colorArray[4] = 0.0f; colorArray[5] = 1.0f; colorArray[6] = 0.0f; colorArray[7] = 1.0f;
                    colorArray[8] = 0.0f; colorArray[9] = 0.0f; colorArray[10] = 1.0f; colorArray[11] = 1.0f;
                    unsigned int arrayLen = 3;
                    textureDesc.
fWidth = arrayLen;
                    fColorRemapTexture =
                        textureMgr->
acquireTexture(
"", textureDesc, &( colorArray[0] ), 
false);
                }
                if (!fLinearSampler)
                {
                }
                if (fColorRemapTexture && fLinearSampler)
                {
                    
                    texAssignment.
texture = fColorRemapTexture;
                    
                    
                }
            }
            
            
            if (fDrawSharedActiveVertices)
            {
                activeItem->
setShader(shader, &sActiveVertexStreamName );
            }
            else
            {
            }
            
        }
    }
    else
    {
        activeItem = list.
itemAt(index);
    }
    if (activeItem)
    {
        if (shader)
        {
            
            static const float theColor[] = { 1.0f, 1.0f, 0.0f, 1.0f };
            setSolidColor( shader, theColor);
        }
        const bool enable = (fActiveVerticesSet.size() > 0 && enableActiveComponentDisplay(path));
    }
}
{
    int index = list.
indexOf(sWireframeModeFaceCenterItemName);
 
    if (index < 0)
    {
            sWireframeModeFaceCenterItemName,
        list.
append(wireframeModeFaceCenterItem);
            MHWRender::MShaderManager::k3dFatPointShader );
        if (shader)
        {
            
            static const float pointSize = 5.0f;
            setSolidPointSize( shader, pointSize );
            wireframeModeFaceCenterItem->
setShader(shader, &sFaceCenterStreamName );
            
        }
    }
    else
    {
        wireframeModeFaceCenterItem = list.
itemAt(index);
    }
    if (wireframeModeFaceCenterItem)
    {
        if (shader)
        {
            
            static const float theColor[] = { 0.0f, 0.0f, 1.0f, 1.0f };
            setSolidColor( shader, theColor);
        }
        
        if(isTemplate)
            wireframeModeFaceCenterItem->
enable( 
false );
    }
}
{
    static const unsigned int shadedDrawMode =
    int index = list.
indexOf(sShadedModeFaceCenterItemName);
 
    if (index < 0)
    {
            sShadedModeFaceCenterItemName,
        list.
append(shadedModeFaceCenterItem);
            MHWRender::MShaderManager::k3dFatPointShader );
        if (shader)
        {
            
            static const float pointSize = 5.0f;
            setSolidPointSize( shader, pointSize );
            shadedModeFaceCenterItem->
setShader(shader, &sFaceCenterStreamName );
            
        }
    }
    else
    {
        shadedModeFaceCenterItem = list.
itemAt(index);
    }
    if (shadedModeFaceCenterItem)
    {
        if (shader)
        {
            
            setSolidColor( shader, &(wireColor.
r));
        }
        switch(displayStatus){
            shadedModeFaceCenterItem->
enable(
true);
            break;
        default:
            shadedModeFaceCenterItem->
enable(
false);
            break;
        }
    }
}
bool apiMeshGeometryOverride::enableActiveComponentDisplay(
const MDagPath &path)
 const 
{
    bool enable = true;
    
    
    
    
    
    
    {
        enable = false;
    }
    else
    {
        
        
            enable = false;
    }
    return enable;
}
void apiMeshGeometryOverride::updateAffectedComponentItems(
{
    
    
    int index = list.
indexOf(sAffectedEdgeItemName);
 
    if (index < 0)
    {
            sAffectedEdgeItemName,
        
        
        if (shader)
        {
            
            
        }
    }
    else
    {
        componentItem = list.
itemAt(index);
    }
    if (componentItem)
    {
        if (shader)
        {
            
            static const float lineSize = 1.0f;
            setLineWidth( shader, lineSize );
            
            static const float theColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
            setSolidColor( shader, theColor);
        }
        const bool enable = ((fActiveVerticesSet.size() > 0 || fActiveEdgesSet.size() > 0) && enableActiveComponentDisplay(path));
        componentItem->
enable( enable );
    }
    
    
    componentItem = NULL;
    index = list.
indexOf(sAffectedFaceItemName);
    if (index < 0)
    {
            sAffectedFaceItemName,
        
        
        if (shader)
        {
            
            
        }
    }
    else
    {
        componentItem = list.
itemAt(index);
    }
    if (componentItem)
    {
        if (shader)
        {
            
            static const float theColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
            setSolidColor( shader, theColor);
        }
        const bool enable = ((fActiveVerticesSet.size() > 0 || fActiveFacesSet.size() > 0) && enableActiveComponentDisplay(path));
        componentItem->
enable( enable );
    }
}
void apiMeshGeometryOverride::updateSelectionComponentItems(
{
    
    
    int index = list.
indexOf(sEdgeSelectionItemName);
 
    if (index < 0)
    {
            sEdgeSelectionItemName,
        
        
        
        
        if (shader)
        {
            
            
        }
    }
    else
    {
        selectionItem = list.
itemAt(index);
    }
    if (selectionItem)
    {
        apiMeshHWSelectionUserData* mySelectionData = 
dynamic_cast<apiMeshHWSelectionUserData*
>(selectionItem->
customData());
        if (!mySelectionData)
        {
            
            mySelectionData = new apiMeshHWSelectionUserData();
        }
        
        mySelectionData->fMeshGeom = fMeshGeom;
    }
    
    
    index = list.
indexOf(sFaceSelectionItemName);
    if (index < 0)
    {
            sFaceSelectionItemName,
        
        
        
        
            MHWRender::MShaderManager::k3dSolidShader );
        if (shader)
        {
            
            
        }
    }
    else
    {
        selectionItem = list.
itemAt(index);
    }
    if (selectionItem)
    {
        apiMeshHWSelectionUserData* mySelectionData = 
dynamic_cast<apiMeshHWSelectionUserData*
>(selectionItem->
customData());
        if (!mySelectionData)
        {
            
            mySelectionData = new apiMeshHWSelectionUserData();
        }
        
        mySelectionData->fMeshGeom = fMeshGeom;
    }
}
void apiMeshGeometryOverride::updateProxyShadedItem(
{
    
    static const float dormantColor[] = { 0.0f, 0.0f, 1.0f, 1.0f };
    static const float templateColor[] = { 0.45f, 0.45f, 0.45f, 1.0f };
    static const float activeTemplateColor[] = { 1.0f, 0.5f, 0.5f, 1.0f };
    
    
    
    
    
    static const bool raiseAboveShaded = true;
    unsigned int shadedDrawMode =
    
    
    bool useFragmentShader = fProxyShader < 0;
    if ( !useFragmentShader )
    
    
    
    bool filledProxy = ( useFragmentShader
                        ||
    if (filledProxy)
    {
    }
    int index = list.
indexOf(sShadedProxyItemName);
 
    if (index < 0)
    {
            sShadedProxyItemName,
            primitive);
        if (fExternalItems_NoShadowCast)
        else
        if (fExternalItems_NoShadowReceive)
        else
        if (fExternalItems_NoPostEffects)
        
        
        if (useFragmentShader)
        {
            shader = shaderMgr->
getFragmentShader(
"mayaLambertSurface", 
"outSurfaceFinal", 
true);
            static const float sBlue[] = {0.4f, 0.4f, 1.0f};
        }
        else
        {
        }
        if (shader)
        {
            if (!filledProxy)
                setLineWidth(shader, 10.0f);
            
            
        }
    }
    else
    {
        proxyItem = list.
itemAt(index);
    }
    
    
    
    
    
    if (fExternalItems_NoShadowCast)
    else
    if (fExternalItems_NoShadowReceive)
    else
    if (fExternalItems_NoPostEffects)
    
    
    
    bool haveShadedItems = false;
    for (
int i=0; i<list.
length(); i++)
 
    {
        if (!item)
            continue;
            )
        {
            if (item->
name() != sShadedTemplateItemName)
 
            {
                haveShadedItems = true;
                break;
            }
        }
    }
    
    
    
    if (filledProxy)
    {
        
        else
            proxyItem->
enable(!haveShadedItems);
    }
    else
        proxyItem->
enable(!haveShadedItems);
    
    
    
    
    if (proxyItem)
    {
        switch (displayStatus) {
            if (shader)
            {
                setSolidColor( shader, !fUseCustomColors ? &(wireColor.
r) : templateColor);
            }
            break;
            if (shader)
            {
                setSolidColor( shader, !fUseCustomColors ? &(wireColor.
r) : activeTemplateColor );
            }
            break;
            if (shader)
            {
                setSolidColor( shader, !fUseCustomColors ? &(wireColor.
r) : dormantColor);
            }
            break;
        default:
            break;
        }
    }
}
void apiMeshGeometryOverride::updateRenderItems(
{
    if (!renderer) return;
    if (!shaderMgr) return;
    MPlug castsShadowsPlug = dagNode.findPlug(
"castsShadows", 
false);
 
    fCastsShadows = castsShadowsPlug.
asBool();
    MPlug receiveShadowsPlug = dagNode.findPlug(
"receiveShadows", 
false);
 
    fReceivesShadows = receiveShadowsPlug.
asBool();
    
    updateDormantAndTemplateWireframeItems(path, list, shaderMgr);
    updateActiveWireframeItem(path, list, shaderMgr);
    
    updateDormantVerticesItem(path, list, shaderMgr);
    updateActiveVerticesItem(path, list, shaderMgr);
    
    updateVertexNumericItems(path, list, shaderMgr);
    
    if(fDrawFaceCenters)
    {
        updateWireframeModeFaceCenterItem(path, list, shaderMgr);
        updateShadedModeFaceCenterItem(path, list, shaderMgr);
    }
    
    updateAffectedComponentItems(path, list, shaderMgr);
    
    updateSelectionComponentItems(path, list, shaderMgr);
    
    updateProxyShadedItem(path, list, shaderMgr);
    
    
    
    
    const bool testShadedOverrides = fInternalItems_NoShadowCast || fInternalItems_NoShadowReceive || fInternalItems_NoPostEffects;
    if (testShadedOverrides)
    {
        for (
int i=0; i<list.
length(); i++)
 
        {
            if (!item)
                continue;
                )
            {
                if (item->
name() != sShadedTemplateItemName
 
                    
                    )
                {
                    if (fInternalItems_NoShadowCast)
                    else
                    if (fInternalItems_NoShadowReceive)
                    else
                    if (fInternalItems_NoPostEffects)
                }
            }
        }
    }
}
void apiMeshGeometryOverride::cloneVertexBuffer(
        unsigned int bufferSize,
        bool debugPopulateGeometry)
{
    if (!srcBuffer)
        return;
    if (destBuffer)
    {
        if (debugPopulateGeometry)
        {
            printf(">>> Clone data for active vertex requirement with name %s. Semantic = %d\n",
        }
        void* destDataBuffer = destBuffer->
acquire(bufferSize, 
true );
 
        void* srcDataBuffer = srcBuffer->
map();
 
        if (srcDataBuffer && destDataBuffer)
        if (destDataBuffer)
            destBuffer->
commit(destDataBuffer);
    }
}
void apiMeshGeometryOverride::updateGeometryRequirements(
        unsigned int activeVertexCount,
        unsigned int totalVerts,
        bool debugPopulateGeometry)
{
    
    float* positions = NULL;
    float* vertexNumericIds = NULL;
    float* vertexNumericIdPositions = NULL;
    float* vertexNumericLocations = NULL;
    float* vertexNumericLocationPositions = NULL;
    float* activeVertexPositions = NULL;
    float* activeVertexUVs = NULL;
    float* faceCenterPositions = NULL;
    float* normals = NULL;
    float* cpv = NULL;
    float* uvs = NULL;
    int numUVs = fMeshGeom->uvcoords.uvcount();
    int numVertexReqs = descList.
length();
 
    bool* satisfiedRequirements = new bool[numVertexReqs];
    for (int reqNum=0; reqNum<numVertexReqs; reqNum++)
    {
        satisfiedRequirements[reqNum] = false;
        {
            continue;
        }
        
        
        if (fDrawSharedActiveVertices && (desc.
name() == sActiveVertexStreamName))
 
        {
            {
                {
                    if (!activeVertexPositionBuffer)
                    {
                        if (activeVertexPositionBuffer)
                        {
                            satisfiedRequirements[reqNum] = true;
                            if (debugPopulateGeometry)
                            {
                                printf(">>> Fill in data for active vertex requirement[%d] with name %s. Semantic = %d\n",
                            }
                            activeVertexPositions = (
float*)activeVertexPositionBuffer->
acquire(activeVertexCount, 
true );
                        }
                    }
                }
                break;
                {
                    if (!activeVertexUVBuffer)
                    {
                        if (activeVertexUVBuffer)
                        {
                            satisfiedRequirements[reqNum] = true;
                            if (debugPopulateGeometry)
                            {
                                printf(">>> Fill in data for active vertex requirement[%d] with name %s. Semantic = %d\n",
                            }
                            activeVertexUVs = (
float*)activeVertexUVBuffer->
acquire(activeVertexCount, 
true );
                        }
                    }
                }
            default:
                
                break;
            }
        }
        
        
        else if (fDrawFaceCenters && (desc.
name() == sFaceCenterStreamName))
 
        {
            {
                {
                    if (!faceCenterPositionBuffer)
                    {
                        if (faceCenterPositionBuffer)
                        {
                            satisfiedRequirements[reqNum] = true;
                            if (debugPopulateGeometry)
                            {
                                printf(">>> Fill in data for face center requirement[%d] with name %s. Semantic = %d\n",
                            }
                            faceCenterPositions = (
float*)faceCenterPositionBuffer->
acquire(fMeshGeom->faceCount, 
true );
                        }
                    }
                }
                break;
            default:
                
                break;
            }
        }
        
        
        else
        {
            if (debugPopulateGeometry)
            {
                printf(">>> Fill in data for requirement[%d] with name %s. Semantic = %d\n",
            }
            {
                {
                    if (desc.
name() == sVertexIdItemName)
 
                    {
                        if (!vertexNumericIdPositionBuffer)
                        {
                            if (vertexNumericIdPositionBuffer)
                            {
                                satisfiedRequirements[reqNum] = true;
                                if (debugPopulateGeometry)
                                    printf("Acquire 1float-numeric position buffer\n");
                                vertexNumericIdPositions = (
float*)vertexNumericIdPositionBuffer->
acquire(totalVerts, 
true );
                            }
                        }
                    }
                    else if (desc.
name() == sVertexPositionItemName)
 
                    {
                        if (!vertexNumericLocationPositionBuffer)
                        {
                            if (vertexNumericLocationPositionBuffer)
                            {
                                satisfiedRequirements[reqNum] = true;
                                if (debugPopulateGeometry)
                                    printf("Acquire 3float-numeric position buffer\n");
                                vertexNumericLocationPositions = (
float*)vertexNumericLocationPositionBuffer->
acquire(totalVerts, 
true );
                            }
                        }
                    }
                    else
                    {
                        if (!positionBuffer)
                        {
                            if (positionBuffer)
                            {
                                satisfiedRequirements[reqNum] = true;
                                if (debugPopulateGeometry)
                                    printf("Acquire unnamed position buffer\n");
                                positions = (
float*)positionBuffer->
acquire(totalVerts, 
true );
                            }
                        }
                    }
                }
                break;
                {
                    if (!normalBuffer)
                    {
                        if (normalBuffer)
                        {
                            satisfiedRequirements[reqNum] = true;
                            normals = (
float*)normalBuffer->
acquire(totalVerts, 
true );
                        }
                    }
                }
                break;
                {
                    static const MString numericValue(
"numericvalue");
 
                    static const MString numeric3Value(
"numeric3value");
 
                    
                    {
                        if (!vertexNumericIdBuffer)
                        {
                            if (vertexNumericIdBuffer)
                            {
                                satisfiedRequirements[reqNum] = true;
                                if (debugPopulateGeometry)
                                    printf("Acquire 1float numeric buffer\n");
                                vertexNumericIds = (
float*)vertexNumericIdBuffer->
acquire(totalVerts, 
true );
                            }
                        }
                    }
                    
                    {
                        if (!vertexNumericLocationBuffer)
                        {
                            if (vertexNumericLocationBuffer)
                            {
                                satisfiedRequirements[reqNum] = true;
                                if (debugPopulateGeometry)
                                    printf("Acquire 3float numeric location buffer\n");
                                vertexNumericLocations = (
float*)vertexNumericLocationBuffer->
acquire(totalVerts, 
true );
                            }
                        }
                    }
                    
                    else if (desc.
name() != sVertexIdItemName &&
 
                             desc.
name() != sVertexPositionItemName)
                    {
                        if (!uvBuffer)
                        {
                            if (uvBuffer)
                            {
                                satisfiedRequirements[reqNum] = true;
                                if (debugPopulateGeometry)
                                    printf("Acquire a uv buffer\n");
                                uvs = (
float*)uvBuffer->
acquire(totalVerts, 
true );
                            }
                        }
                    }
                }
                break;
                {
                    if (!cpvBuffer)
                    {
                        if (cpvBuffer)
                        {
                            satisfiedRequirements[reqNum] = true;
                            cpv = (
float*)cpvBuffer->
acquire(totalVerts, 
true );
                        }
                    }
                }
                break;
            default:
                
                break;
            }
        }
    }
    int vid = 0;
    int pid = 0;
    int nid = 0;
    int uvid = 0;
    int cid = 0;
    for (int i=0; i<fMeshGeom->faceCount; i++)
    {
        
        int numVerts = fMeshGeom->face_counts[i];
        if (numVerts > 2)
        {
            for (int j=0; j<numVerts; j++)
            {
                if (positions || vertexNumericIdPositions || 
                    vertexNumericLocationPositions || vertexNumericLocations)
                {
                    MPoint position = fMeshGeom->vertices[fMeshGeom->face_connects[vid]];
 
                    
                    if (positions)
                    {
                        positions[pid] = (float)position[0];
                        positions[pid+1] = (float)position[1];
                        positions[pid+2] = (float)position[2];
                    }
                    
                    if (vertexNumericIdPositions)
                    {
                        vertexNumericIdPositions[pid] = (float)(position[0])+1.0f;
                        vertexNumericIdPositions[pid+1] = (float)(position[1])+1.0f;
                        vertexNumericIdPositions[pid+2] = (float)(position[2])+1.0f;
                    }
                    
                    if (vertexNumericLocationPositions)
                    {
                        vertexNumericLocationPositions[pid] = (float)(position[0])+3.0f;
                        vertexNumericLocationPositions[pid+1] = (float)(position[1])+3.0f;
                        vertexNumericLocationPositions[pid+2] = (float)(position[2])+3.0f;
                    }
                    
                    if (vertexNumericLocations)
                    {
                        vertexNumericLocations[pid] = (float)position[0];
                        vertexNumericLocations[pid+1] = (float)position[1];
                        vertexNumericLocations[pid+2] = (float)position[2];
                    }
                    pid += 3;
                }
                if (normals)
                {
                    MVector normal = fMeshGeom->normals[fMeshGeom->face_connects[vid]];
 
                    normals[nid++] = (float)normal[0];
                    normals[nid++] = (float)normal[1];
                    normals[nid++] = (float)normal[2];
                }
                if (uvs)
                {
                    float u = 0.0f;
                    float v = 0.0f;
                    if (numUVs > 0)
                    {
                        int uvNum = fMeshGeom->uvcoords.uvId(vid);
                        fMeshGeom->uvcoords.getUV(uvNum, u, v);
                    }
                    uvs[uvid++] = u;
                    uvs[uvid++] = v;
                }
                
                
                if (cpv)
                {
                    MPoint position = fMeshGeom->vertices[fMeshGeom->face_connects[vid]];
 
                    cpv[cid++] = (float)position[0];
                    cpv[cid++] = (float)position[1];
                    cpv[cid++] = (float)position[2];
                    cpv[cid++] = 1.0f;
                }
                
                if (vertexNumericIds)
                {
                    vertexNumericIds[vid] = (float)(fMeshGeom->face_connects[vid]);
                }
                vid++;
            }
        }
        else if (numVerts > 0)
        {
            vid += numVerts;
        }
    }
    if (positions)
    {
        positionBuffer->
commit(positions);
    }
    if (normals)
    {
        normalBuffer->
commit(normals);
    }
    if (uvs)
    {
    }
    if (cpv)
    {
    }
    
    if (vertexNumericIds)
    {
        vertexNumericIdBuffer->
commit(vertexNumericIds);
    }
    if (vertexNumericIdPositions)
    {
        vertexNumericIdPositionBuffer->
commit(vertexNumericIdPositions);
    }
    if (vertexNumericLocations)
    {
        vertexNumericLocationBuffer->
commit(vertexNumericLocations);
    }
    if (vertexNumericLocationPositions)
    {
        vertexNumericLocationPositionBuffer->
commit(vertexNumericLocationPositions);
    }
    
    
    
    if (activeVertexPositions && activeVertexPositionBuffer)
    {
        if (debugPopulateGeometry)
        {
            printf(">>> Fill in the data for active vertex position buffer base on component list\n");
        }
        
        
        pid = 0;
        unsigned int vertexCount = fMeshGeom->vertices.length(); 
        if (activeVertexCount > vertexCount)
            activeVertexCount = vertexCount;
        for (unsigned int i=0; i<activeVertexCount; i++)
        {
            unsigned int idx = fActiveVertices[i];
            if (idx < vertexCount)
            {
                MPoint position = fMeshGeom->vertices[ idx ];
 
                activeVertexPositions[pid++] = (float)position[0];
                activeVertexPositions[pid++] = (float)position[1];
                activeVertexPositions[pid++] = (float)position[2];
            }
        }
        activeVertexPositionBuffer->
commit(activeVertexPositions);
    }
    if (activeVertexUVs && activeVertexUVBuffer)
    {
        if (debugPopulateGeometry)
        {
            printf(">>> Fill in the data for active vertex uv buffer base on component list\n");
        }
        
        
        pid = 0;
        if (activeVertexCount > fMeshGeom->vertices.length())
            activeVertexCount = fMeshGeom->vertices.length();
        for (unsigned int i=0; i<activeVertexCount; i++)
        {
            activeVertexUVs[pid++] = (float)i/ (float)activeVertexCount;
        }
        activeVertexUVBuffer->
commit(activeVertexUVs);
    }
    
    
    
    if (faceCenterPositions && faceCenterPositionBuffer)
    {
        if (debugPopulateGeometry)
        {
            printf(">>> Fill in the data for face center position buffer\n");
        }
        
        
        pid = 0;
        vid = 0;
        for (int faceId=0; faceId < fMeshGeom->faceCount; faceId++)
        {
            
            double x = 0.0;
            double y = 0.0;
            double z = 0.0;
            
            int numVerts = fMeshGeom->face_counts[faceId];
            if (numVerts > 2){
                for (int v=0; v<numVerts; v++)
                {
                    MPoint face_vertex_position = fMeshGeom->vertices[fMeshGeom->face_connects[vid]];
 
                    x += face_vertex_position[0];
                    y += face_vertex_position[1];
                    z += face_vertex_position[2];
                    vid++;
                }
                faceCenterPosition[0] = (float)x/numVerts;
                faceCenterPosition[1] = (float)y/numVerts;
                faceCenterPosition[2] = (float)z/numVerts;
                faceCenterPositions[pid++] = (float)faceCenterPosition[0];
                faceCenterPositions[pid++] = (float)faceCenterPosition[1];
                faceCenterPositions[pid++] = (float)faceCenterPosition[2];
            }
            else if(numVerts > 0)
            {
                vid += numVerts;
            }
        }
        faceCenterPositionBuffer->
commit(faceCenterPositions);
    }
    
    for (int reqNum=0; reqNum<numVertexReqs; reqNum++)
    {
        if (satisfiedRequirements[reqNum] || !descList.
getDescriptor(reqNum, desc))
 
        {
            continue;
        }
        if (fDrawSharedActiveVertices && (desc.
name() == sActiveVertexStreamName))
 
        {
            {
                {
                    satisfiedRequirements[reqNum] = true;
                    cloneVertexBuffer(activeVertexPositionBuffer, data, desc, activeVertexCount, debugPopulateGeometry);
                }
                break;
                {
                    satisfiedRequirements[reqNum] = true;
                    cloneVertexBuffer(activeVertexUVBuffer, data, desc, activeVertexCount, debugPopulateGeometry);
                }
            default:
                break;
            }
        }
        else if (fDrawFaceCenters && (desc.
name() == sFaceCenterStreamName))
 
        {
            {
                {
                    satisfiedRequirements[reqNum] = true;
                    cloneVertexBuffer(faceCenterPositionBuffer, data, desc, fMeshGeom->faceCount, debugPopulateGeometry);
                }
                break;
            default:
                break;
            }
        }
        else
        {
            {
                {
                    if (desc.
name() == sVertexIdItemName)
 
                    {
                        satisfiedRequirements[reqNum] = true;
                        cloneVertexBuffer(vertexNumericIdPositionBuffer, data, desc, totalVerts, debugPopulateGeometry);
                    }
                    else if (desc.
name() == sVertexPositionItemName)
 
                    {
                        satisfiedRequirements[reqNum] = true;
                        cloneVertexBuffer(vertexNumericLocationPositionBuffer, data, desc, totalVerts, debugPopulateGeometry);
                    }
                    else
                    {
                        satisfiedRequirements[reqNum] = true;
                        cloneVertexBuffer(positionBuffer, data, desc, totalVerts, debugPopulateGeometry);
                    }
                }
                break;
                {
                    satisfiedRequirements[reqNum] = true;
                    cloneVertexBuffer(normalBuffer, data, desc, totalVerts, debugPopulateGeometry);
                }
                break;
                {
                    static const MString numericValue(
"numericvalue");
 
                    static const MString numeric3Value(
"numeric3value");
 
                    {
                        satisfiedRequirements[reqNum] = true;
                        cloneVertexBuffer(vertexNumericIdBuffer, data, desc, totalVerts, debugPopulateGeometry);
                    }
                    {
                        satisfiedRequirements[reqNum] = true;
                        cloneVertexBuffer(vertexNumericLocationBuffer, data, desc, totalVerts, debugPopulateGeometry);
                    }
                    else if (desc.
name() != sVertexIdItemName &&
 
                             desc.
name() != sVertexPositionItemName)
                    {
                        satisfiedRequirements[reqNum] = true;
                        cloneVertexBuffer(uvBuffer, data, desc, totalVerts, debugPopulateGeometry);
                    }
                }
                break;
                {
                    satisfiedRequirements[reqNum] = true;
                    cloneVertexBuffer(cpvBuffer, data, desc, totalVerts, debugPopulateGeometry);
                }
                break;
            default:
                break;
            }
        }
        if (!satisfiedRequirements[reqNum])
        {
            
            
            if (destBuffer)
            {
                if (debugPopulateGeometry)
                {
                    printf(">>> Dummy data for active vertex requirement with name %s. Semantic = %d\n",
                }
                void* destDataBuffer = destBuffer->
acquire(totalVerts, 
true );
 
                if (destDataBuffer)
                {
                    destBuffer->
commit(destDataBuffer);
                }
            }
        }
    }
    delete satisfiedRequirements;
}
                                                            unsigned int totalVerts)
{
    
    
    if (!wireIndexBuffer)
    {
        if (wireIndexBuffer)
        {
            unsigned int* buffer = (
unsigned int*)wireIndexBuffer->
acquire(2*totalVerts, 
true );
 
            if (buffer)
            {
                int vid = 0;
                int first = 0;
                unsigned int idx = 0;
                for (int faceIdx=0; faceIdx<fMeshGeom->faceCount; faceIdx++)
                {
                    
                    int numVerts = fMeshGeom->face_counts[faceIdx];
                    if (numVerts > 2)
                    {
                        first = vid;
                        for (int v=0; v<numVerts-1; v++)
                        {
                            buffer[idx++] = vid++;
                            buffer[idx++] = vid;
                        }
                        buffer[idx++] = vid++;
                        buffer[idx++] = first;
                    }
                    else
                    {
                        vid += numVerts;
                    }
                }
                wireIndexBuffer->
commit(buffer);
            }
        }
    }
    
    if (wireIndexBuffer)
    {
    }
}
                                                              unsigned int numTriangles)
{
    if (indexBuffer)
    {
        unsigned int* buffer = (
unsigned int*)indexBuffer->
acquire(3*numTriangles, 
true );
 
        if (buffer)
        {
            
            
            unsigned int base = 0;
            unsigned int idx = 0;
            for (int faceIdx=0; faceIdx<fMeshGeom->faceCount; faceIdx++)
            {
                
                int numVerts = fMeshGeom->face_counts[faceIdx];
                if (numVerts > 2)
                {
                    for (int v=1; v<numVerts-1; v++)
                    {
                        buffer[idx++] = base;
                        buffer[idx++] = base+v;
                        buffer[idx++] = base+v+1;
                    }
                    base += numVerts;
                }
            }
        }
    }
}
                                                        unsigned int numTriangles,
                                                        unsigned int activeVertexCount,
                                                        bool debugPopulateGeometry)
{
    if (indexBuffer)
    {
        unsigned int* buffer = NULL;
        
        
        
        
        
        
        
        
        if (fDrawSharedActiveVertices)
        {
            buffer = (
unsigned int*)indexBuffer->
acquire(activeVertexCount, 
true );
            if (buffer)
            {
                if (debugPopulateGeometry)
                    printf(">>> Set up indexing for shared vertices\n");
                for (unsigned int i=0; i<activeVertexCount; i++)
                {
                    buffer[i] = i;
                }
            }
        }
        
        
        else
        {
            if (debugPopulateGeometry)
                printf(">>> Set up indexing for unshared vertices\n");
            buffer = (
unsigned int*)indexBuffer->
acquire(3*numTriangles, 
true );
            if (buffer)
            {
                for (unsigned int i=0; i<3*numTriangles; i++)
                {
                    buffer[i] = 3*numTriangles+1;
                }
                const std::set<int>& selectionIdSet = fActiveVerticesSet;
                std::set<int>::const_iterator selectionIdSetIter;
                std::set<int>::const_iterator selectionIdSetIterEnd = selectionIdSet.end();
                
                
                unsigned int base = 0;
                unsigned int lastFound = 0;
                unsigned int idx = 0;
                for (int faceIdx=0; faceIdx<fMeshGeom->faceCount; faceIdx++)
                {
                    
                    int numVerts = fMeshGeom->face_counts[faceIdx];
                    if (numVerts > 2)
                    {
                        for (int v=1; v<numVerts-1; v++)
                        {
                            int vertexId = fMeshGeom->face_connects[base];
                            selectionIdSetIter = selectionIdSet.find( vertexId );
                            if (selectionIdSetIter != selectionIdSetIterEnd)
                            {
                                buffer[idx++] = base;
                                lastFound = base;
                            }
                            vertexId = fMeshGeom->face_connects[base+v];
                            selectionIdSetIter = selectionIdSet.find( vertexId );
                            if (selectionIdSetIter != selectionIdSetIterEnd)
                            {
                                buffer[idx++] = base+v;
                                lastFound = base+v;
                            }
                            vertexId = fMeshGeom->face_connects[base+v+1];
                            selectionIdSetIter = selectionIdSet.find( vertexId );
                            if (selectionIdSetIter != selectionIdSetIterEnd)
                            {
                                buffer[idx++] = base+v+1;
                                lastFound = base+v+1;
                            }
                        }
                        base += numVerts;
                    }
                }
                for (unsigned int i=0; i<3*numTriangles; i++)
                {
                    if (buffer[i] == 3*numTriangles+1)
                        buffer[i] = lastFound;
                }
            }
        }
        if (buffer)
    }
}
{
    if (indexBuffer)
    {
        unsigned int* buffer = NULL;
        buffer = (
unsigned int*)indexBuffer->
acquire(fMeshGeom->faceCount, 
true );
        if (buffer)
        {
            if (debugPopulateGeometry)
                printf(">>> Set up indexing for face centers\n");
            for (int i=0; i<fMeshGeom->faceCount; i++)
            {
                    buffer[i] = 0;
            }
            unsigned int idx = 0;
            for (int i=0; i<fMeshGeom->faceCount; i++)
            {
                
                int numVerts = fMeshGeom->face_counts[i];
                if (numVerts > 2)
                {
                    buffer[idx] = idx;
                    idx++;
                }
            }
        }
        if (buffer)
    }
}
                                                      unsigned int totalVerts,
                                                      bool fromSelection)
{
    if (indexBuffer)
    {
        unsigned int totalEdges = 2*totalVerts;
        unsigned int totalEdgesP1 = 2*totalVerts+1;
        unsigned int* buffer = (
unsigned int*)indexBuffer->
acquire(totalEdges, 
true );
 
        if (buffer)
        {
            for (unsigned int i=0; i<totalEdges; i++)
            {
                buffer[i] = totalEdgesP1;
            }
            const bool displayAll = !fromSelection;
            const bool displayActives = (!displayAll && fActiveEdgesSet.size() > 0);
            const bool displayAffected = (!displayAll && !displayActives);
            const std::set<int>& selectionIdSet = (displayActives ? fActiveEdgesSet : fActiveVerticesSet);
            std::set<int>::const_iterator selectionIdSetIter;
            std::set<int>::const_iterator selectionIdSetIterEnd = selectionIdSet.end();
            unsigned int base = 0;
            unsigned int lastFound = 0;
            unsigned int idx = 0;
            int edgeId = 0;
            for (int faceIdx=0; faceIdx<fMeshGeom->faceCount; faceIdx++)
            {
                
                int numVerts = fMeshGeom->face_counts[faceIdx];
                if (numVerts > 2)
                {
                    for (int v=0; v<numVerts; v++)
                    {
                        bool enableEdge = displayAll;
                        unsigned int vindex1 = base + (v % numVerts);
                        unsigned int vindex2 = base + ((v+1) % numVerts);
                        if( displayAffected )
                        {
                            
                            
                            
                            int vertexId = fMeshGeom->face_connects[vindex1];
                            selectionIdSetIter = selectionIdSet.find( vertexId );
                            if (selectionIdSetIter != selectionIdSetIterEnd)
                            {
                                enableEdge = true;
                                lastFound = vindex1;
                            }
                            if (!enableEdge)
                            {
                                int vertexId2 = fMeshGeom->face_connects[vindex2];
                                selectionIdSetIter = selectionIdSet.find( vertexId2 );
                                if (selectionIdSetIter != selectionIdSetIterEnd)
                                {
                                    enableEdge = true;
                                    lastFound = vindex2;
                                }
                            }
                        }
                        else if( displayActives )
                        {
                            
                            
                            selectionIdSetIter = selectionIdSet.find( edgeId );
                            if (selectionIdSetIter != selectionIdSetIterEnd)
                            {
                                enableEdge = true;
                                lastFound = vindex1;
                            }
                        }
                        
                        if (enableEdge)
                        {
                            buffer[idx++] = vindex1;
                            buffer[idx++] = vindex2;
                        }
                        ++edgeId;
                    }
                    base += numVerts;
                }
            }
            if(!displayAll)
            {
                for (unsigned int i=0; i<totalEdges; i++)
                {
                    if (buffer[i] == totalEdgesP1)
                        buffer[i] = lastFound;
                }
            }
        }
        if (buffer)
    }
}
                                                    unsigned int numTriangles,
                                                    bool fromSelection)
{
    if (indexBuffer)
    {
        unsigned int numTriangleVertices = 3*numTriangles;
        unsigned int* buffer = (
unsigned int*)indexBuffer->
acquire(numTriangleVertices, 
true );
 
        if (buffer)
        {
            for (unsigned int i=0; i<numTriangleVertices; i++)
            {
                buffer[i] = numTriangleVertices+1;
            }
            const bool displayAll = !fromSelection;
            const bool displayActives = (!displayAll && fActiveFacesSet.size() > 0);
            const bool displayAffected = (!displayAll && !displayActives);
            const std::set<int>& selectionIdSet = (displayActives ? fActiveFacesSet : fActiveVerticesSet);
            std::set<int>::const_iterator selectionIdSetIter;
            std::set<int>::const_iterator selectionIdSetIterEnd = selectionIdSet.end();
            unsigned int base = 0;
            unsigned int lastFound = 0;
            unsigned int idx = 0;
            for (int faceIdx=0; faceIdx<fMeshGeom->faceCount; faceIdx++)
            {
                
                int numVerts = fMeshGeom->face_counts[faceIdx];
                if (numVerts > 2)
                {
                    bool enableFace = displayAll;
                    if( displayAffected )
                    {
                        
                        
                        for (int v=1; v<numVerts-1; v++)
                        {
                            int vertexId = fMeshGeom->face_connects[base];
                            selectionIdSetIter = selectionIdSet.find( vertexId );
                            if (selectionIdSetIter != selectionIdSetIterEnd)
                            {
                                enableFace = true;
                                lastFound = base;
                            }
                            if (!enableFace)
                            {
                                int vertexId2 = fMeshGeom->face_connects[base+v];
                                selectionIdSetIter = selectionIdSet.find( vertexId2 );
                                if (selectionIdSetIter != selectionIdSetIterEnd)
                                {
                                    enableFace = true;
                                    lastFound = base+v;
                                }
                            }
                            if (!enableFace)
                            {
                                int vertexId3 = fMeshGeom->face_connects[base+v+1];
                                selectionIdSetIter = selectionIdSet.find( vertexId3 );
                                if (selectionIdSetIter != selectionIdSetIterEnd)
                                {
                                    enableFace = true;
                                    lastFound = base+v+1;
                                }
                            }
                        }
                    }
                    else if( displayActives )
                    {
                        selectionIdSetIter = selectionIdSet.find( faceIdx );
                        if (selectionIdSetIter != selectionIdSetIterEnd)
                        {
                            enableFace = true;
                            lastFound = base;
                        }
                    }
                    
                    
                    
                    if (enableFace)
                    {
                        for (int v=1; v<numVerts-1; v++)
                        {
                            buffer[idx++] = base;
                            buffer[idx++] = base+v;
                            buffer[idx++] = base+v+1;
                        }
                    }
                    base += numVerts;
                }
            }
            if(!displayAll)
            {
                for (unsigned int i=0; i<numTriangleVertices; i++)
                {
                    if (buffer[i] == numTriangleVertices+1)
                        buffer[i] = lastFound;
                }
            }
        }
        if (buffer)
    }
}
                                                              unsigned int numTriangles)
{
    if (indexBuffer)
    {
        unsigned int* buffer = (
unsigned int*)indexBuffer->
acquire(3*numTriangles, 
true );
 
        if (buffer)
        {
            
            
            unsigned int base = 0;
            unsigned int idx = 0;
            for (int faceIdx=0; faceIdx<fMeshGeom->faceCount; faceIdx++)
            {
                
                int numVerts = fMeshGeom->face_counts[faceIdx];
                if (numVerts > 2)
                {
                    for (int v=1; v<numVerts-1; v++)
                    {
                        buffer[idx++] = base;
                        buffer[idx++] = base+v;
                        buffer[idx++] = base+v+1;
                    }
                    base += numVerts;
                }
            }
        }
    }
}
void apiMeshGeometryOverride::populateGeometry(
{
    static bool debugPopulateGeometry = false;
    if (debugPopulateGeometry)
        printf("> Begin populate geometry\n");
    
    unsigned int activeVertexCount = fActiveVertices.length();
    
    unsigned int numTriangles = 0;
    unsigned int totalVerts = 0;
    for (int i=0; i<fMeshGeom->faceCount; i++)
    {
        int numVerts = fMeshGeom->face_counts[i];
        if (numVerts > 2)
        {
            numTriangles += numVerts - 2;
            totalVerts += numVerts;
        }
    }
    
    updateGeometryRequirements(requirements, data,  activeVertexCount, totalVerts,
        debugPopulateGeometry);
    
    int numItems = renderItems.
length();
 
    for (int i=0; i<numItems; i++)
    {
        if (!item) continue;
        
        
        
        static const bool debugStuff = false;
        if (debugStuff)
        {
            int numBufs = itemBuffers.
length();
 
            for (int bufNum=0; bufNum<numBufs; bufNum++)
            {
                {
                    printf(
"Buffer Required for Item #%d ('%s'):\n", i, item->
name().
asChar());
                    printf(
"\tBufferName: %s\n", desc.
name().
asChar());
                    printf("\n");
                }
            }
            
            
            apiMeshUserData* myCustomData = 
dynamic_cast<apiMeshUserData*
>(item->
customData());
            if (myCustomData)
            {
                printf("Custom data on Item #%d: '%s', modified count='%d'\n\n", i, myCustomData->fMessage.asChar(), myCustomData->fNumModifications);
            }
            else
            {
                printf("No custom data on Item #%d\n\n", i);
            }
        }
        
        
        if (item->
name() == sActiveVertexItemName)
 
        {
            updateIndexingForVertices( item, data, numTriangles, activeVertexCount, debugPopulateGeometry);
        }
        
        
        if ((item->
name() == sShadedModeFaceCenterItemName || item->
name() == sWireframeModeFaceCenterItemName) && fDrawFaceCenters)
 
        {
            updateIndexingForFaceCenters( item, data, debugPopulateGeometry);
        }
        
        
        else if (item->
name() == sVertexItemName ||
 
                 item->
name() == sVertexIdItemName ||
                 item->
name() == sVertexPositionItemName)
        {
            updateIndexingForDormantVertices( item, data, numTriangles );
        }
        
        
        else if (item->
name() == sWireframeItemName
 
                 || item->
name() == sShadedTemplateItemName
                 || item->
name() == sSelectedWireframeItemName
                     && item->
name() == sShadedProxyItemName))
        {
            updateIndexingForWireframeItems(wireIndexBuffer, item, data, totalVerts);
        }
        
        
        
        
        else if (item->
name() == sAffectedEdgeItemName)
 
        {
            updateIndexingForEdges(item, data, totalVerts, true ); 
        }
        else if (item->
name() == sEdgeSelectionItemName)
 
        {
            updateIndexingForEdges(item, data, totalVerts, false ); 
        }
        
        
        
        
        else if (item->
name() == sAffectedFaceItemName)
 
        {
            updateIndexingForFaces(item, data, numTriangles, true ); 
        }
        else if (item->
name() == sFaceSelectionItemName)
 
        {
            updateIndexingForFaces(item, data, numTriangles, false ); 
        }
        
        
        {
                updateIndexingForShadedTriangles(item, data, numTriangles);
        }
    }
    if (debugPopulateGeometry)
        printf("> End populate geometry\n");
}
void apiMeshGeometryOverride::cleanUp()
{
    fMeshGeom = NULL;
    fActiveVertices.clear();
    fActiveVerticesSet.clear();
    fActiveEdgesSet.clear();
    fActiveFacesSet.clear();
}
void apiMeshGeometryOverride::updateSelectionGranularity(
{
    {
        if(globalComponentMask.
intersects(supportedComponents))
 
        {
        }
    }
    else if (pointSnappingActive())
    {
    }
}
MStatus apiMeshGeometryOverride::registerComponentConverters()
 
{
    if(status) {
        if(status) {
        }
    }
    return status;
}
MStatus apiMeshGeometryOverride::deregisterComponentConverters()
 
{
    if(status) {
        if(status) {
        }
    }
    return status;
}
bool apiMeshGeometryOverride::traceCallSequence() const
{
    
    return false;
}
void apiMeshGeometryOverride::handleTraceMessage( 
const MString &message )
 const 
{
    
    fprintf(stderr, "apiMeshGeometryOverride: ");
    fprintf(stderr, message.
asChar());
    fprintf(stderr, "\n");
}