#include <maya/MFnMesh.h>
#include <maya/MFloatPoint.h>
#include <maya/MFloatPointArray.h>
#include <maya/MIntArray.h>
#include <maya/MFnTypedAttribute.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MPxNode.h>
#include <maya/MObject.h>
#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MFnMeshData.h>
#include <maya/MIOStream.h>
#include <maya/MItMeshVertex.h>
#include "blindDataMesh.h"
#define McheckErr(stat,msg)         \
    if ( MS::kSuccess != stat ) {   \
        cerr << msg;                \
        return MS::kFailure;        \
    }
MTypeId blindDataMesh::id( 0x60EA );
 
void* blindDataMesh::creator()
{
    return new blindDataMesh;
}
MStatus blindDataMesh::initialize()
 
{
    blindDataMesh::outputMesh = typedAttr.
create( 
"outputMesh", 
"out",
    McheckErr(returnStatus, "ERROR creating blindDataMesh output attribute\n");
    returnStatus = addAttribute(blindDataMesh::outputMesh);
    McheckErr(returnStatus, "ERROR adding outputMesh attribute\n");
    blindDataMesh::seed = numAttr.
create( 
"randomSeed", 
"seed",
    McheckErr(returnStatus, "ERROR creating blindDataMesh input attribute\n");
    returnStatus = addAttribute(blindDataMesh::seed);
    McheckErr(returnStatus, "ERROR adding input attribute\n");
    returnStatus = attributeAffects(blindDataMesh::seed,
                                    blindDataMesh::outputMesh);
    McheckErr(returnStatus, "ERROR in attributeAffects\n");
}
{
    int i, j;
    srand(seed);
    float planeSize = 20.0f;
    float planeOffset = planeSize / 2.0f;
    float planeDim = 0.5f;
    int numDivisions = (int) (planeSize / planeDim);
    
    
    int numFaces = numDivisions * numDivisions;
    
    
    
    
    
    
    
    
    
    for (i = 0; i < (numDivisions + 1); ++i)
    {
        for (j = 0; j < (numDivisions + 1); ++j)
        {
            float height;
            if (i == 0 && j == 0)
            {
                height = ((rand() % 101) / 100.0f - 0.5f);
            }
            else if (i == 0)
            {
                float previousHeight = vertices[j - 1][1];
                height = previousHeight + ((rand() % 101) / 100.0f - 0.5f);
            }
            else if (j == 0)
            {
                float previousHeight = vertices[(i-1)*(numDivisions + 1)][1];
                height = previousHeight + ((rand() % 101) / 100.0f - 0.5f);
            }
            else
            {
                float previousHeight
                    = vertices[(i-1)*(numDivisions + 1) + j][1];
                float previousHeight2
                    = vertices[i*(numDivisions + 1) + j - 1][1];
                height = (previousHeight + previousHeight2)
                    / 2.0f + ((rand() % 101) / 100.0f - 0.5f);
            }
                j * planeDim - planeOffset );
        }
    }
    
    
    
    for (i = 0; i < numFaces; ++i)
    {
    }
    
    
    for (i = 0; i < numDivisions; ++i)
    {
        for (j = 0; j < numDivisions; ++j)
        {
            faceVertices.
append(i*(numDivisions+1) + j);
            faceVertices.
append(i*(numDivisions+1) + j + 1);
            faceVertices.
append((i+1)*(numDivisions+1) + j + 1);
            faceVertices.
append((i+1)*(numDivisions+1) + j);
        }
    }
        faceDegrees, faceVertices, outData, &stat);
    return newMesh;
}
{
    if (plug == outputMesh) {
        
        
        
        
        
        McheckErr(returnStatus,"ERROR getting random number generator seed\n");
        long seed = seedHandle.
asLong();
 
        
        
        
        
        
        
        
        
        McheckErr(returnStatus, "ERROR getting polygon data handle\n");
        McheckErr(returnStatus, "ERROR creating outputData");
        createMesh(seed, newOutputData, returnStatus);
        McheckErr(returnStatus, "ERROR creating new plane");
        returnStatus = setMeshBlindData(newOutputData);
        McheckErr(returnStatus, "ERROR setting the blind Data on the plane");
        outputHandle.
set(newOutputData);
    } else
}
{
    
    
    
    int blindDataID = 60;
    {
        
        longNames.
append(
"red_color");
        
        longNames.
append(
"blue_color");
            blindDataID, longNames, shortNames, formatNames );
        if (!stat) return stat;
    }
    else if (!stat) return stat;
    
    
    
    
    
    
    
    double lowest = 1e10, highest = -1e10;
    for ( ; !itVertex.isDone(); itVertex.next() )
    {
        MPoint vertexPosition = itVertex.position();
 
        double height = vertexPosition[1];
        if (height < lowest) lowest = height;
        if (height > highest) highest = height;
    }
    double range = highest - lowest;
    for ( itVertex.reset(mesh); !itVertex.isDone(); itVertex.next() )
    {
        MPoint vertexPosition = itVertex.position();
 
        double height = vertexPosition[1] - lowest;
        double red, green, blue;
        
        
        
        red = 2.0 * ( height / range ) - 1.0;
        if (height > range/2.0) {
            if (red < 0.7) green = 0.7;
            else green = red;
        }
        else green = 0.7 * (1.0 - (((range/2.0) - height) / (range/2.0))
            * (((range/2.0) - height) / (range/2.0)));
        if (height > range/2.0) blue = red;
        else blue = 1.0 - (green*green);
        if (red < 0.0) red = 0.0;
        
        
        if (!stat) return stat;
        if (!stat) return stat;
        if (!stat) return stat;
    }
    return stat;
}