arcLenNode.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.
// ==========================================================================
//+

#include <string.h>
#include <maya/MIOStream.h>
#include <math.h>

#include <maya/MPxNode.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnTypedAttribute.h>
#include <maya/MFnPlugin.h>
#include <maya/MFnNurbsCurve.h>
#include <maya/MString.h> 
#include <maya/MTypeId.h> 
#include <maya/MPlug.h> 
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h> 

class arcLen : public MPxNode
{
public:
                        arcLen();
    virtual             ~arcLen(); 

    virtual MStatus     compute( const MPlug& plug, MDataBlock& data );
    static  void*       creator();
    static  MStatus     initialize();

public:
    static  MObject     inputCurve;  // The input curve.
    static  MObject     output;      // The output value.
    static  MTypeId     id;          // The IFF type id
};

MTypeId     arcLen::id( 0x80001  );
MObject     arcLen::inputCurve;        
MObject     arcLen::output;       

arcLen::arcLen() {}
arcLen::~arcLen() {}

void* arcLen::creator()
{
    return new arcLen();
}

MStatus arcLen::compute( const MPlug& plug, MDataBlock& data )
{
    
    MStatus status;
 
    if( plug == output )
    {
        MDataHandle inputData = data.inputValue( inputCurve, &status );

        if( !status ) {
            status.perror("ERROR getting data");
        } else {
            MObject curve = inputData.asNurbsCurveTransformed();
            MFnNurbsCurve curveFn( curve, &status ); 
            if( !status ) {
                status.perror("ERROR creating curve function set");
            } else {
                double result = curveFn.length();
                MDataHandle outputHandle = data.outputValue( arcLen::output );
                outputHandle.set( result );
                data.setClean(plug);
            }
        }
    } else {
        return MS::kUnknownParameter;
    }

    return MS::kSuccess;
}

MStatus arcLen::initialize()
{
    MFnNumericAttribute numericAttr;
    MFnTypedAttribute   typedAttr;
    MStatus status;

    inputCurve = typedAttr.create( "inputCurve", "in", 
                                    MFnData::kNurbsCurve, 
                                    &status );

    if( !status ) {
        status.perror("ERROR creating arcLen curve attribute");
        return status;
    }

    output = numericAttr.create( "output", "out", 
                                    MFnNumericData::kDouble, 0.0, 
                                    &status );
    if( !status ) {
        status.perror("ERROR creating arcLen output attribute");
        return status;
    }
    numericAttr.setWritable(false);

    status = addAttribute( inputCurve );
    if( !status ) {
        status.perror("addAttribute(inputCurve)");
        return status;
    }

    status = addAttribute( output );
    if( !status ) {
        status.perror("addAttribute(output)");
        return status;
    }

    status = attributeAffects( inputCurve, output );
    if( !status ) {
        status.perror("attributeAffects(inputCurve, output)");
        return status;
    }

    return MS::kSuccess;
}

MStatus initializePlugin( MObject obj )
{
    MStatus   status;
    MFnPlugin plugin( obj, PLUGIN_COMPANY, "3.0", "Any");

    status = plugin.registerNode( "arcLen", arcLen::id, arcLen::creator,
                                               arcLen::initialize);
    if (!status) {
        status.perror("registerNode");
        return status;
    }

    return status;
}

MStatus uninitializePlugin( MObject obj)
{
    MStatus   status;
    MFnPlugin plugin( obj );

    status = plugin.deregisterNode( arcLen::id );
    if (!status) {
        status.perror("deregisterNode");
        return status;
    }

    return status;
}