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

// MEL Command: nodeCreatedCB
//
// Description:
//              A simple plugin to register a mel proc to be called whenever a node is 
//              created. Registered Mel procedures should be declared to take a single
//              string argument (the name of the added node).
//
//              Warning: mel procedures registered with this method will be called 
//                               whenever a node is added to the DG. This may cause problems
//                               in certain cases. For example: each time a reference is 
//                               reloaded, each of its nodes is re-added to the DG.
//
// Flags:
//              -register/-r string: registers a mel callback. There is no limit
//                                                       to the number of callbacks that can be registered.
//
//              -unregister/-u string: unregister the specified callback.
//
//              -filter/-f string: by default all registered callbacks will be called
//                                                 whenever any node is created. Using the filter flag
//                                                 you can indicate that callbacks should only be
//                                                 called when certain node types are created.
//                                                 To determine the type of a particular node see the
//                                                 'objectType' and 'nodeType' commands.
//
//                                                 Note: only one filter can be in affect at a time,
//                                                 and it will be applied to all registered callbacks.
//
//              -fullDagPath/-fdp: if this flag is specified when registering a 
//                                                 callback, any dag node names passed into the mel
//                                                 procedure will include the full dag path.
//
// Note:
//              The -register, -unregister, and -filter flags are mutually exclusive, 
//              only one should be used per command invocation.
//
// Important:
//              Do not delete the node in your callback.
//
// Example Usage:
//
// // Appends the suffix '_ply' to all created mesh nodes
// //
// global proc myCB( string $node )
// {
//              print("calling polyCB " + $node + "\n");
//              string $type = `objectType $node`;
//              if ( $type == "mesh" ) {
//                      rename $node ($node+"_ply");
//              }       
// }
//
// nodeCreatedCB -register "myCB";
//
#include <nodeCreatedCBCmd.h>
#include <maya/MFnPlugin.h>
#include <maya/MObject.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MFnDagNode.h>
#include <maya/MDGMessage.h>
#include <maya/MArgDatabase.h>
#include <maya/MSyntax.h>
#include <maya/MGlobal.h>

#define kRegisterFlagLong               "-register"
#define kRegisterFlag                   "-r"
#define kUnregisterFlagLong             "-unregister"
#define kUnregisterFlag                 "-u"
#define kFilterFlagLong                 "-filter"
#define kFilterFlag                             "-f"
#define kFullDagPathFlagLong    "-fullDagPath"
#define kFullDagPathFlag                "-fdp"


// The id of the API callback. The API callback must be removed when this
// plug-in is unloaded.
//
MCallbackId             nodeCreatedCB::sId;
// The array of all registered Mel procedures.
//
MStringArray    nodeCreatedCB::sMelProcs;
// Flags to indicate whether or not a mel procedure should be passed the
// short or long names of dag nodes.
//
MIntArray               nodeCreatedCB::sFullDagPath;


MStatus nodeCreatedCB::doIt( const MArgList& args )
//
//      Description:
//              implements the MEL nodeCreatedCB command.
//
{
        MStatus stat = MS::kSuccess;

        MArgDatabase argData( syntax(), args );

        // Parse command flags.
        //
        if ( argData.isFlagSet( kRegisterFlag ) ) {
                // Register a new procedure.
                //
                MString proc;
                argData.getFlagArgument( kRegisterFlag, 0, proc );
                stat = registerMelProc( proc, argData.isFlagSet( kFullDagPathFlag ) );
        } else if ( argData.isFlagSet( kUnregisterFlag ) ) {
                // Unregister a procedure.
                //
                MString proc;
                argData.getFlagArgument( kUnregisterFlag, 0, proc );
                stat = unregisterMelProc( proc );
        } else if ( argData.isFlagSet( kFilterFlag ) ) {
                // Change the filter being applied.
                //
                MString filter;
                argData.getFlagArgument( kFilterFlag, 0, filter );
                stat = changeFilter( filter );
        }
        
        if ( stat.error() ) {
                MGlobal::displayError( stat.errorString() );
        }

        return stat;
}

MStatus nodeCreatedCB::registerMelProc( MString melProc, bool fullDagPath )
//
// Register a Mel procedure to be called whenever a node is added.
//
{
        MStatus stat = MS::kSuccess;
        if ( melProc.length() == 0 ) {
                // Basic error checking. An empty string is not a valid mel procedure
                // name
                //
                stat = MS::kFailure;
                stat.perror("invalid mel callback: " + melProc);
                return stat;
        }
        nodeCreatedCB::sMelProcs.append( melProc );
        nodeCreatedCB::sFullDagPath.append( fullDagPath );
        return stat;
}

MStatus nodeCreatedCB::unregisterMelProc( MString melProc )
//
// Unregister a Mel procedure.
//
{
        MStatus stat = MS::kFailure;
        int numProcs = nodeCreatedCB::sMelProcs.length();
        for ( int i = 0; i < numProcs; i++ ) {
                // Search the array of registered callbacks for melProc and
                // remove it. If melProc exists more than once, only one instance
                // of it will be removed.
                //
                if ( nodeCreatedCB::sMelProcs[i] == melProc ) {
                        nodeCreatedCB::sMelProcs.remove(i);
                        nodeCreatedCB::sFullDagPath.remove(i);
                        stat = MS::kSuccess;
                        break;
                }
        }

        if ( !stat ) {
                // Report an error if melProc was not found.
                //
                stat.perror(melProc + " is not a registered callback.");
        }

        return stat;
}

MStatus nodeCreatedCB::changeFilter( MString filter )
//
// Change the node type filter.
//
{
        MStatus stat = MS::kSuccess;
        // We don't want to add sCallbackFunc more than once as that will cause
        // all registered Mel procs to be called multiple times. So we first
        // remove, then re-add the callback.
        //
        MDGMessage::removeCallback( nodeCreatedCB::sId );
        nodeCreatedCB::sId = MDGMessage::addNodeAddedCallback( nodeCreatedCB::sCallbackFunc, filter );
        return stat;
}

void nodeCreatedCB::sCallbackFunc( MObject& node, void* clientData )
//
// The API callback called whenever a node is added. This function handles
// calling all registered MEL callbacks and passing them the appropriate
// node name argument.
//
{
        int numProcs = nodeCreatedCB::sMelProcs.length();
        for ( int i = 0; i < numProcs; i++ ) {
                MString melCmd = nodeCreatedCB::sMelProcs[i];
                MString nodeName;
                if ( nodeCreatedCB::sFullDagPath[i] && 
                         node.hasFn( MFn::kDagNode ) ) {
                        MFnDagNode dagObj( node );
                        nodeName = dagObj.fullPathName();
                } else {
                        MFnDependencyNode dn( node );
                        nodeName = dn.name();
                }
                melCmd += " \"" + nodeName + "\"";
                MGlobal::executeCommand( melCmd );
        }
}

MSyntax nodeCreatedCB::newSyntax()
//
// Create the syntax object for the nodeCreateCB command.
//
{
        MSyntax syntax;

        syntax.addFlag( kRegisterFlag, kRegisterFlagLong, MSyntax::kString );
        syntax.addFlag( kUnregisterFlag, kUnregisterFlagLong, MSyntax::kString );
        syntax.addFlag( kFilterFlag, kFilterFlagLong, MSyntax::kString );
        syntax.addFlag( kFullDagPathFlag, kFullDagPathFlagLong );

        return syntax;
}
                                                                                                                
void* nodeCreatedCB::creator()                                                                          
{                                                                                                                               
        return new nodeCreatedCB;                                                                               
}
                                                                                                                        
MStatus initializePlugin( MObject obj )                                         
{                                                                                                                               
        MFnPlugin       plugin( obj, PLUGIN_COMPANY, "6.0" );                           
        MStatus         stat;                                                                                   
        stat = plugin.registerCommand( "nodeCreatedCB",                                 
                                        nodeCreatedCB::creator,
                                                                        nodeCreatedCB::newSyntax );         
        if ( !stat )                                                                                            
                stat.perror("registerCommand"); 
        
        // add the API callback.
        //
        nodeCreatedCB::sId = MDGMessage::addNodeAddedCallback( nodeCreatedCB::sCallbackFunc );

        return stat;                                                                                            
}                                                                                                                               
MStatus uninitializePlugin( MObject obj )                                               
{                                                                                                                               
        MFnPlugin       plugin( obj );                                                                  
        MStatus         stat;                                                                                   
        stat = plugin.deregisterCommand( "nodeCreatedCB" );                             
        if ( !stat )                                                                                            
                stat.perror("deregisterCommand");                                               

        // Remove the API callback, necessary to prevent crashes.
        //
        MDGMessage::removeCallback( nodeCreatedCB::sId );

        nodeCreatedCB::sMelProcs.clear();
        nodeCreatedCB::sFullDagPath.clear();
        
        return stat;                                                                                            
}


Autodesk® Maya® 2011 © 1997-2010 Autodesk, Inc. All rights reserved. Generated with doxygen 1.5.6