#include <stdlib.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MPxLocatorNode.h>
#include <maya/MEvaluationNode.h>
#include <maya/MFnPlugin.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnUnitAttribute.h>
#include <maya/MTime.h>
#include <maya/MDrawRegistry.h>
#include <maya/MPxDrawOverride.h>
#include <maya/MUserData.h>
{
public:
    simpleEvaluationDraw();
    virtual ~simpleEvaluationDraw();
    static void*            creator();
    
    
    double scaleXBy;    
    bool scaleUpToDate; 
public:
    
    double doExpensiveCalculation( int c, double t );
    static  MString     drawDbClassification;
 
};
MObject simpleEvaluationDraw::aTimeInput;
 
MObject simpleEvaluationDraw::aCopies;
 
MTypeId simpleEvaluationDraw::id(0x0008002C);
 
MString simpleEvaluationDraw::drawDbClassification(
"drawdb/geometry/simpleEvaluationDraw");
 
MString simpleEvaluationDraw::drawRegistrantId(
"simpleEvaluationDrawPlug");
 
simpleEvaluationDraw::simpleEvaluationDraw()
    : scaleXBy( 1.0 )
    , scaleUpToDate( false )
{}
simpleEvaluationDraw::~simpleEvaluationDraw() {}
void* simpleEvaluationDraw::creator()
{
    return new simpleEvaluationDraw();
}
double simpleEvaluationDraw::doExpensiveCalculation( int c, double t )
{
    
    
    
    unsigned int end = c * c *c * c * c;
    double result = 0;
    for ( unsigned int i = 0; i < end ; i++ )
        result = result + i*c*t;
    result = fmod(result,7.0)+1.0;
    return result;
}
{
    if(evalType == kLeaveDirty)
    {
        scaleUpToDate = false;
    }
    {
        if ( status )
        {
            if ( status )
            {
                
                
                int copies = copiesData.
asInt();
 
                if ( ! scaleUpToDate )
                {
                    scaleXBy = doExpensiveCalculation( copies, t );
                    
                    
                    scaleUpToDate = true;
                }
            }
        }
    }
}
class simpleEvaluationDrawData : 
public MUserData  
{
public:
    simpleEvaluationDrawData();
    virtual ~simpleEvaluationDrawData() {};
    double scaleXBy;
    bool scaleUpToDate;
    double evalTime;
    double copies;
};
simpleEvaluationDrawData::simpleEvaluationDrawData() : 
MUserData(false) 
    , rectangleColor(1.0f, 0.0f, 0.0f, 1.0f)    
    , scaleXBy( 0.0 )
    , scaleUpToDate( false )
{
}
{
public:
    {
        return new simpleEvaluationDrawOverride(obj);
    }
    virtual ~simpleEvaluationDrawOverride();
protected:
private:
    simpleEvaluationDrawOverride(
const MObject& obj);
};
simpleEvaluationDrawOverride::simpleEvaluationDrawOverride(
const MObject& obj)
{
}
simpleEvaluationDrawOverride::~simpleEvaluationDrawOverride()
{
}
DrawAPI simpleEvaluationDrawOverride::supportedDrawAPIs()
 const 
{
    
    return (kOpenGL | kDirectX11 | kOpenGLCoreProfile);
}
bool simpleEvaluationDrawOverride::isBounded(
const MDagPath& ,
 
{
    return false;
}
{
}
MUserData* simpleEvaluationDrawOverride::prepareForDraw(
 
{
    simpleEvaluationDrawData* data = dynamic_cast<simpleEvaluationDrawData*>(oldData);
    if (!data) {
        data = new simpleEvaluationDrawData();
    }
    if (status) 
    {
        
        {
            
            float blue = (float) rand()/RAND_MAX;
            data->rectangleColor.b = blue;
        }
        
        {
            if ( status )
            {
                simpleEvaluationDraw* sed = dynamic_cast<simpleEvaluationDraw*>(dnNode.userNode());
                if ( sed )
                {
                    if ( ! sed->scaleUpToDate )
                    {
                        
                        MPlug timePlug( drawNode, simpleEvaluationDraw::aTimeInput );
 
                        MPlug copiesPlug( drawNode, simpleEvaluationDraw::aCopies );
 
                        MTime t = timePlug.asMTime();
 
                        sed->scaleXBy = sed->doExpensiveCalculation( copiesPlug.asInt(), t.
value() );
                    }
                    data->scaleXBy = sed->scaleXBy;
                    sed->scaleUpToDate = true;
                }
            }
        }
    }
    return data;
}
void simpleEvaluationDrawOverride::addUIDrawables(
{
    const simpleEvaluationDrawData* thisdata = dynamic_cast<const simpleEvaluationDrawData*>(data);
    if (!thisdata) {
        return;
    }
    {
        drawManager.
setColor(thisdata->rectangleColor);
        double xpos = rand()/RAND_MAX*10.0;
        MPoint position(xpos, 0.0, 0.5 );
 
        drawManager.
rect(position, rectUp, normal, 5 * thisdata->scaleXBy, 5, 
false );
    }
    if ( status )
        {
        if ( status )
        {
            simpleEvaluationDraw* sed = dynamic_cast<simpleEvaluationDraw*>(dnNode.userNode());
            if ( sed )
                sed->scaleUpToDate = false; 
        }
    }
}
MStatus simpleEvaluationDraw::initialize()
 
{
}
{
    MFnPlugin plugin( obj, PLUGIN_COMPANY, 
"3.0", 
"Any");
 
    status = plugin.registerNode(
        "simpleEvaluationDraw",
        simpleEvaluationDraw::id,
        &simpleEvaluationDraw::creator,
        &simpleEvaluationDraw::initialize,
        &simpleEvaluationDraw::drawDbClassification);
    if (!status) {
        status.
perror(
"registerNode");
        return status;
    }
        simpleEvaluationDraw::drawDbClassification,
        simpleEvaluationDraw::drawRegistrantId,
        simpleEvaluationDrawOverride::Creator);
    if (!status) {
        status.
perror(
"registerDrawOverrideCreator");
        return status;
    }
    return status;
}
{
    status = MDrawRegistry::deregisterGeometryOverrideCreator(
        simpleEvaluationDraw::drawDbClassification,
        simpleEvaluationDraw::drawRegistrantId);
    if (!status) {
        status.
perror(
"deregisterGeometryOverrideCreator");
        return status;
    }
    status = plugin.deregisterNode( simpleEvaluationDraw::id );
    if (!status) {
        status.
perror(
"deregisterNode");
        return status;
    }
    return status;
}