blindDoubleDataCmd/blindDoubleDataCmd.cpp
 
 
 
blindDoubleDataCmd/blindDoubleDataCmd.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 <maya/MIOStream.h>

#include <maya/MFnPlugin.h>
#include <maya/MString.h>
#include <maya/MArgList.h>

#include <maya/MPxCommand.h>

#include <maya/MGlobal.h>
#include <maya/MItSelectionList.h>

#include <maya/MFnDependencyNode.h>
#include <maya/MFnTypedAttribute.h>

#include <maya/MPxData.h>
#include <maya/MTypeId.h>
#include <maya/MPlug.h>  
#include <maya/MFnPluginData.h>

//
// Proxy data class declaration
//
class blindDoubleData : public MPxData
{
public:
                                                        blindDoubleData();
    virtual                                     ~blindDoubleData();

    virtual MStatus         readASCII( const MArgList&, unsigned& lastElement );
    virtual MStatus         readBinary( istream& in, unsigned length );
    virtual MStatus         writeASCII( ostream& out );
    virtual MStatus         writeBinary( ostream& out );

        virtual void                    copy( const MPxData& );
        MTypeId                 typeId() const; 
        MString                 name() const;

    double                  value() const;
    void                    setValue( double );

        static const MString    typeName;
    static const MTypeId    id;
        static void*            creator();

private:
    double                  fValue; 
};

class blindDoubleDataCmd : public MPxCommand
{
public:
                                                blindDoubleDataCmd();
        virtual                         ~blindDoubleDataCmd(); 

        MStatus                         doIt( const MArgList& args );
        MStatus                         redoIt();
        MStatus                         undoIt();
        bool                            isUndoable() const;
        
public:
        static void*            creator();
        MItSelectionList*       iter;
};



//
// Proxy data class implementation
//
void* blindDoubleData::creator()
{
    return new blindDoubleData;
}

blindDoubleData::blindDoubleData()
    :fValue( 0 )
    , MPxData()
{
}

blindDoubleData::~blindDoubleData()
{}

double blindDoubleData::value() const
{
    return fValue;
}

void blindDoubleData::setValue( double newValue  )
{
    fValue = newValue;
}

void blindDoubleData::copy ( const MPxData& other )
{
        fValue = ((const blindDoubleData&)other).fValue;
}

MTypeId blindDoubleData::typeId() const
{
        return blindDoubleData::id;
}

MString blindDoubleData::name() const
{ 
        return blindDoubleData::typeName;
}

MStatus blindDoubleData::readASCII(  const MArgList& args,
                                unsigned& lastParsedElement )
{
    MStatus status;
    if( args.length() > 0 ) {
        fValue = args.asDouble( lastParsedElement++, &status  );
        return status; 
    } else {
        return MS::kFailure;
    }
}

MStatus blindDoubleData::writeASCII( ostream& out )
{
    out << fValue << " ";
    return MS::kSuccess;
}

MStatus blindDoubleData::readBinary( istream& in, unsigned )
{
    in.read( (char*) &fValue, sizeof( fValue ));
    return in.fail() ? MS::kFailure : MS::kSuccess;
}

MStatus blindDoubleData::writeBinary( ostream& out )
{
    out.write( (char*) &fValue, sizeof( fValue));
    return out.fail() ? MS::kFailure : MS::kSuccess;
}

//
// this is the unique type id used to identify the new user-defined type.
//
const MTypeId blindDoubleData::id( 0x80003 );
const MString blindDoubleData::typeName( "blindDoubleData" );


//
// Command class implementation
//

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

blindDoubleDataCmd::~blindDoubleDataCmd()
{
}

blindDoubleDataCmd::blindDoubleDataCmd()
        : MPxCommand()
{
}

MStatus blindDoubleDataCmd::doIt( const MArgList& )
{
        MStatus stat;

        // Create a selection list iterator
        //
    MSelectionList list;
    MGlobal::getActiveSelectionList( list );
        iter = new MItSelectionList( list,      MFn::kInvalid, &stat    );
        if ( MS::kSuccess == stat )
                stat = redoIt();

        return stat;
}

MStatus blindDoubleDataCmd::redoIt()
{
        MStatus     stat;                               // Status code
        MObject         dependNode;             // Selected dependency node

        // Iterate over all selected dependency nodes
        //
        for ( ; !iter->isDone(); iter->next() ) 
        {
                // Get the selected dependency node and create
                // a function set for it
                //
                if ( MS::kSuccess != iter->getDependNode( dependNode ) ) {
                        cerr << "Error getting the dependency node" << endl;
                        continue;
                }
                MFnDependencyNode fnDN( dependNode, &stat );
                if ( MS::kSuccess != stat ) {
                        cerr << "Error creating MFnDependencyNode" << endl;
                        continue;
                }

                // Create a new attribute for our blind data
                //
                // cerr << "Creating attr..." << endl;
        
                MFnTypedAttribute fnAttr;
                const MString fullName( "blindDoubleData" );
                const MString briefName( "BDD" );
                MObject newAttr = fnAttr.create( fullName, briefName,
                                                                                 blindDoubleData::id );

                // Now add the new attribute to the current dependency node
                //
                // cerr << "Adding attr..." << endl;
                fnDN.addAttribute( newAttr, MFnDependencyNode::kLocalDynamicAttr );
                
                // Create a plug to set and retrive value off the node.
                //
        MPlug plug( dependNode, newAttr );  

                // Instantiate blindDoubleData and set its value.
                //
                blindDoubleData * newData = new blindDoubleData;
                // cerr << "Setting value of attribute to 3.2" << endl;
                newData->setValue( 3.2 ); 

                // Set the value for the plug.
                //
        stat = plug.setValue( newData );

                // Now try to retrieve the value off the plug as an MObject.
                //
        MObject sData;
        stat = plug.getValue( sData );

        if ( stat != MS::kSuccess ) {
            cerr << "error getting value off plug" << endl;
            continue;
        }

                // Convert the data back to MPxData.
                //
        MFnPluginData pdFn( sData ); 
        blindDoubleData* data = ( blindDoubleData* ) pdFn.constData( &stat );

                // Get the value.
                //
                if ( NULL == data ) {
                        cerr << "error: failed to retrieve data." << endl;  
                }
        }
        return MS::kSuccess;
}

MStatus blindDoubleDataCmd::undoIt()
{
        return MS::kSuccess;
}

bool blindDoubleDataCmd::isUndoable() const
{
        return true;
}


//
// The following routines are used to register/unregister
// the command we are creating within Maya
//
MStatus initializePlugin( MObject obj )
{ 
        MStatus   status;
        MFnPlugin plugin( obj, PLUGIN_COMPANY, "3.0", "Any" );

        //
        // Registers the new data type.
        status = plugin.registerData("blindDoubleData", blindDoubleData::id,
                                                                                   blindDoubleData::creator);
        if (!status) {
                status.perror("registerData");
                return status;
        }
        
        //
        // Register the command.
        status = plugin.registerCommand("blindDoubleData",
                                                                        blindDoubleDataCmd::creator);
        if (!status) {
                plugin.deregisterData( blindDoubleData::id );
                status.perror("registerCommand");
                return status;
        }

        return MS::kSuccess;
}

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

        status = plugin.deregisterCommand( "blindDoubleData" );
        if (!status) {
                status.perror("deregisterCommand");
                return status;
        }

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

        return status;
}