#include <maya/MIOStream.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <maya/MFn.h>
#include <maya/MPxNode.h>
#include <maya/MPxManipContainer.h>
#include <maya/MPxSelectionContext.h>
#include <maya/MPxContextCommand.h>
#include <maya/MModelMessage.h>
#include <maya/MFnPlugin.h>
#include <maya/MGlobal.h>
#include <maya/MItSelectionList.h>
#include <maya/MPoint.h>
#include <maya/MVector.h>
#include <maya/MDagPath.h>
#include <maya/MManipData.h>
#include <maya/MItDependencyNodes.h>
#include <maya/MItDependencyGraph.h>
#include <maya/MFnNurbsSurface.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnPointOnSurfaceManip.h>
static const double BUMP_SCALE = 0.5;
    {
            " nodes");
    }
    {
    }
    {
    }
    
    
}
{
public:
    surfaceBumpManip();
    virtual ~surfaceBumpManip();
    
    static void * creator();
    
    MManipData surfacePointChangedCallback(
unsigned index);
 
public:
private:
    
    int saved_u,saved_v;
    
    unsigned dummyPlugIndex;
};
MTypeId surfaceBumpManip::id( 0x80023 );
 
surfaceBumpManip::surfaceBumpManip() : saved_u(-1),saved_v(-1)
{ 
    
    
}
surfaceBumpManip::~surfaceBumpManip() 
{
}
void *surfaceBumpManip::creator()
{
     return new surfaceBumpManip();
}
MStatus surfaceBumpManip::initialize()
 
{
}
MStatus surfaceBumpManip::createChildren()
 
{
    
    
    fPointOnSurfaceManip = addPointOnSurfaceManip("surfaceBumpManip", "point");
    pointOnSurfaceManip.setDrawSurface(true);
    pointOnSurfaceManip.setDrawArrows(true);
    pointOnSurfaceManip.setParameters(0.0,0.0);
    
    return stat;
}
{
    
    
    
    findSurfacePlug(node, surfacePlug, fSurfaceShape);
    {
        stat = pointOnSurfaceManip.connectToSurfacePlug(surfacePlug);
            return stat;
        }
    }
    else {
    }
    
    
    
    
    
    
    MPlug dummyPlug = nodeFn.findPlug(
"dummyPlug", &stat);
 
    {
        dummyPlug = nodeFn.findPlug("dummyPlug", &stat);
        {
        }
    }
    
    
    
    
    dummyPlugIndex = addManipToPlugConversionCallback(dummyPlug, 
        (manipToPlugConversionCallback) 
        &surfaceBumpManip::surfacePointChangedCallback);
    
    
    
    
    pointOnSurfaceManip.set(matrix);
    finishAddingManips();
    return stat;
}
void surfaceBumpManip::draw(
M3dView & view, 
 
{
    
    
}
MManipData surfaceBumpManip::surfacePointChangedCallback(
unsigned index) {
 
    
    
    if (index != dummyPlugIndex)
    {
        return obj;
    }
    
    
    double u = 0.0;
    double v = 0.0;
    pointOnSurfaceManip.getParameters(u,v);
    
    
    
    
    
    int u_int = 0;
    int v_int = 0;
    {
        u_int = (int)(floor(u+1.5)) % nurbsSurface.numSpansInU();
        if (u_int < 0)
            u_int += nurbsSurface.numSpansInU();
    }
    else {
        u_int = (int)(floor(u+1.5));
    }
    {
        v_int = (int)(floor(v+1.5)) % nurbsSurface.numSpansInV();
        if (v_int < 0)
            v_int += nurbsSurface.numSpansInV();
    }
    else {
        v_int = (int)(floor(v+1.5));
    }
    
    
    if (u_int == saved_u && v_int == saved_v)
    {
    }
    
    
    if (saved_u == -1)
    {
        saved_u = u_int;
        saved_v = v_int;
    }
    
    
    saved_u = u_int;
    saved_v = v_int;
    
    MPoint perturbedPosition = savedPoint + 
 
        BUMP_SCALE*nurbsSurface.normal((
double)u_int,(
double)v_int,
MSpace::kObject);
    
}
{
public:
    SurfaceBumpContext();
    
    static void updateManipulators(void * data);
private:
    MCallbackId id1;
};
SurfaceBumpContext::SurfaceBumpContext()
{
    MString str(
"Plugin Surface Bump Manipulator");
 
    setTitleString(str);
}
void SurfaceBumpContext::toolOnSetup(
MEvent &)
 
{
    MString str(
"Drag the manipulator around the surface");
 
    setHelpString(str);
    updateManipulators(this);
                                     updateManipulators, 
                                     this, &status);
    if (!status) {
    }
}
void SurfaceBumpContext::toolOffCleanup()
{
    if (!status) {
    }
}
void SurfaceBumpContext::updateManipulators(void * data)
{
    
    SurfaceBumpContext * ctxPtr = (SurfaceBumpContext *) data;
    ctxPtr->deleteManipulators(); 
        for (; !iter.isDone(); iter.next()) {
            
            
            
            iter.getDependNode(dependNode);
            {
                    "a depend node.");
                continue;
            }
            
            
            MString manipName (
"surfaceBumpManip");
 
            surfaceBumpManip* manipulator =
                (surfaceBumpManip *) surfaceBumpManip::newManipulator(
                    manipName, 
                    manipObject);
            if (NULL != manipulator) {
                
                
                ctxPtr->addManipulator(manipObject);
                
                
                if (!manipulator->connectToDependNode(dependNode))
                {
                        " object: " + dependNodeFn.name());
                }
            } 
        }
    }
}
{
public:
    surfaceBumpContext() {};
public:
    static void* creator();
};
{
    return new SurfaceBumpContext();
}
void *surfaceBumpContext::creator()
{
    return new surfaceBumpContext;
}
{
    MFnPlugin plugin(obj, PLUGIN_COMPANY, 
"6.0", 
"Any");
 
    status = plugin.registerContextCommand("surfaceBumpContext",
                                           &surfaceBumpContext::creator);
    if (!status) {
        return status;
    }
    status = plugin.registerNode("surfaceBumpManip", surfaceBumpManip::id, 
                                 &surfaceBumpManip::creator, &surfaceBumpManip::initialize,
    if (!status) {
        return status;
    }
    return status;
}
{
    status = plugin.deregisterContextCommand("surfaceBumpContext");
    if (!status) {
        return status;
    }
    status = plugin.deregisterNode(surfaceBumpManip::id);
    if (!status) {
        return status;
    }
    return status;
}