- Main Page
- Related Pages
- Modules
- Classes
- Examples

# yTwistNode.cpp

    //-
    // ==========================================================================
    // Copyright 1995,2006,2008 Autodesk, Inc. All rights reserved.
    //
    // Use of this software is subject to the terms of the Autodesk
    // license agreement provided at the time of installation or download,
    // or which otherwise accompanies this software in either electronic
    // or hard copy form.
    // ==========================================================================
    //+
    //
    //  File: yTwist.cpp
    //
    //  Description:
    //      Example implementation of a deformer. This node
    //      twists the deformed vertices around the y-axis.
    //

    #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();

        // deformation function
        //
        virtual MStatus     deform(MDataBlock&      block,
                                   MItGeometry&     iter,
                                   const MMatrix&   mat,
                                   unsigned int     multiIndex);

    public:
        // yTwist attributes
        //
        static  MObject     angle;          // angle to twist

        static  MTypeId     id;

    private:

    };

    MTypeId     yTwist::id( 0x8000e );

    // yTwist attributes  //

    MObject     yTwist::angle;

    yTwist::yTwist()
    //
    //  Description:
    //      constructor
    //
    {
    }

    yTwist::~yTwist()
    //
    //  Description:
    //      destructor
    //
    {}

    void* yTwist::creator()
    //
    //  Description:
    //      create the yTwist
    //
    {
        return new yTwist();
    }

    MStatus yTwist::initialize()
    //
    //  Description:
    //      initialize the attributes
    //
    {
        // local attribute initialization
        //
        MFnNumericAttribute nAttr;
        angle=nAttr.create( "angle", "fa", MFnNumericData::kDouble );
            nAttr.setDefault(0.0);
            nAttr.setKeyable(true);
        addAttribute( angle);

        // affects
        //
        attributeAffects( yTwist::angle, yTwist::outputGeom );

        return MS::kSuccess;
    }

    MStatus
    yTwist::deform( MDataBlock& block,
                    MItGeometry& iter,
                    const MMatrix& /*m*/,
                    unsigned int /*multiIndex*/)
    //
    // Method: deform
    //
    // Description:   Deform the point with a yTwist algorithm
    //
    // Arguments:
    //   block      : the datablock of the node
    //   iter       : an iterator for the geometry to be deformed
    //   m          : matrix to transform the point into world space
    //   multiIndex : the index of the geometry that we are deforming
    //
    //
    {
        MStatus status = MS::kSuccess;

        // determine the angle of the yTwist
        //
        MDataHandle angleData = block.inputValue(angle,&status);
        McheckErr(status, "Error getting angle data handle\n");
        double magnitude = angleData.asDouble();

        // determine the envelope (this is a global scale factor)
        //
        MDataHandle envData = block.inputValue(envelope,&status);
        McheckErr(status, "Error getting envelope data handle\n");
        float env = envData.asFloat();

        // iterate through each point in the geometry
        //
        for ( ; !iter.isDone(); iter.next()) {

            MPoint pt = iter.position();

            // do the twist
            //
            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;
    }

    // standard initialization procedures
    //

    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;
    }