yTwistNode.cpp
#include <string.h>
#include <maya/MIOStream.h>
#include <math.h>
#include <maya/MPxDeformerNode.h>
#include <maya/MItGeometry.h>
#include <maya/MTypeId.h> 
#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnPlugin.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MPoint.h>
#include <maya/MMatrix.h>
#define McheckErr(stat,msg)             \
        if ( MS::kSuccess != stat ) {   \
                cerr << msg;                            \
                return MS::kFailure;            \
        }
class yTwist : public MPxDeformerNode
{
public:
                                                yTwist();
        virtual                         ~yTwist();
        static  void*           creator();
        static  MStatus         initialize();
        
        
    virtual MStatus     deform(MDataBlock&              block,
                                                           MItGeometry&         iter,
                                                           const MMatrix&       mat,
                                                           unsigned int         multiIndex);
public:
        
        
        static  MObject     angle;              
        
        static  MTypeId         id;
private:
};
MTypeId     yTwist::id( 0x8000e );
MObject     yTwist::angle;
yTwist::yTwist() 
{ 
}
yTwist::~yTwist()
{}
void* yTwist::creator()
{
        return new yTwist();
}
MStatus yTwist::initialize()
{
        
        
        MFnNumericAttribute nAttr;
        angle=nAttr.create( "angle", "fa", MFnNumericData::kDouble );
            nAttr.setDefault(0.0);
            nAttr.setKeyable(true);
        addAttribute( angle); 
        
        
    attributeAffects( yTwist::angle, yTwist::outputGeom );
        return MS::kSuccess;
}
MStatus
yTwist::deform( MDataBlock& block,
                                MItGeometry& iter,
                                const MMatrix& ,
                                unsigned int )
{
        MStatus status = MS::kSuccess;
        
        
        
        MDataHandle angleData = block.inputValue(angle,&status);
        McheckErr(status, "Error getting angle data handle\n");
        double magnitude = angleData.asDouble();
        
        
        MDataHandle envData = block.inputValue(envelope,&status);
        McheckErr(status, "Error getting envelope data handle\n");      
        float env = envData.asFloat();  
        
        
        for ( ; !iter.isDone(); iter.next()) {
                
                MPoint pt = iter.position();
                
                
                double ff = magnitude*pt.y*env;
                if (ff != 0.0) {
                        double cct= cos(ff);
                        double cst= sin(ff);
                        double tt= pt.x*cct-pt.z*cst;
                        pt.z= pt.x*cst + pt.z*cct;
                        pt.x=tt;;
                }
                iter.setPosition(pt);
        }
        return status;
}
MStatus initializePlugin( MObject obj )
{
        MStatus result;
        MFnPlugin plugin( obj, PLUGIN_COMPANY, "3.0", "Any");
        result = plugin.registerNode( "yTwist", yTwist::id, yTwist::creator, 
                                                                  yTwist::initialize, MPxNode::kDeformerNode );
        return result;
}
MStatus uninitializePlugin( MObject obj)
{
        MStatus result;
        MFnPlugin plugin( obj );
        result = plugin.deregisterNode( yTwist::id );
        return result;
}