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

//
// polyMessageCmd.cpp
//
// Description:
//     Sample plug-in that demonstrates how to register/de-register
//     a callback with the MPolyMessage class.
//
//     This plug-in will register a new command in maya called
//     "polyMessage" which adds a callback for the all nodes on
//     the active selection list. A message is printed to stdout
//     whenever a component id of one of the poly nodes is modified.
//
#include <maya/MIOStream.h>
#include <maya/MPxCommand.h>
#include <maya/MFnPlugin.h>
#include <maya/MArgList.h>
#include <maya/MUintArray.h>
#include <maya/MSelectionList.h>
#include <maya/MGlobal.h>
#include <maya/MPlug.h>
#include <maya/MPolyMessage.h>
#include <maya/MDagPath.h>
#include <maya/MCallbackIdArray.h>

// This table will keep track of the registered callbacks
// so they can be removed when the plug-ins is unloaded.
//
MCallbackIdArray callbackIds;

//
// Callback function
//
//    Prints out plug information when connections are made or broken.
//    See MNodeMessage.h for all of the available AttributeMessage types.
//

void userCB( MUintArray componentIds[], unsigned int count, void *clientData )
{
    cout << "poly component id modified";
    cout << endl;
    
    if ( count != MPolyMessage::kLastErrorIndex )
        return;
    
    unsigned int i, id;
    unsigned int kDeletedId = MPolyMessage::deletedId();
    MUintArray vertexIds = componentIds[MPolyMessage::kVertexIndex];
    for ( i = 0; i < vertexIds.length(); i++ )
    {
        id = vertexIds[i];
        if ( id == kDeletedId )
            cout << "vertex " << i << " deleted" << endl;
        else if ( i != id )
            cout << "vertex " << i << " " << id << endl;
    }
    
    MUintArray edgeIds = componentIds[MPolyMessage::kEdgeIndex];
    for ( i = 0; i < edgeIds.length(); i++ )
    {
        id = edgeIds[i];
        if ( id == kDeletedId )
            cout << "edge " << i << " deleted"  << endl;
        else if ( i != id )
            cout << "edge " << i << " " << id << endl;
    }
    
    MUintArray faceIds = componentIds[MPolyMessage::kFaceIndex];
    for ( i = 0; i < faceIds.length(); i++ )
    {
        id = faceIds[i];
        if ( id == kDeletedId )
            cout << "face " << i << " deleted" << endl;
        else if ( i != id )
            cout << "face " << i << " " << id << endl;
    }
}

//
// Command class declaration
//

class polyMessageCmd : public MPxCommand
{
public:
                    polyMessageCmd() {};
    virtual         ~polyMessageCmd(); 
    MStatus         doIt( const MArgList& args );
    static void*    creator();
};

//
// Command class implementation
//

polyMessageCmd::~polyMessageCmd() {}

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

MStatus polyMessageCmd::doIt( const MArgList& )
//
// Takes the  nodes that are on the active selection list and adds an
// attriubte changed callback to each one.
//
{
    MStatus         stat;
    MObject         node;
    MSelectionList  list;
    MCallbackId     id;
    
    // Register node callbacks for all nodes on the active list.
    //
    MGlobal::getActiveSelectionList( list );

    for ( unsigned int i=0; i<list.length(); i++ )
    {
        list.getDependNode( i, node );
        
        MDagPath dp;
        MObject shapeNode = node;
        if ( MS::kSuccess == MDagPath::getAPathTo( node, dp ) )
            if ( MS::kSuccess == dp.extendToShape() )
                shapeNode = dp.node();
        
        bool wantIdChanges[3];
        wantIdChanges[MPolyMessage::kVertexIndex] = true;
        wantIdChanges[MPolyMessage::kEdgeIndex] = true;        
        wantIdChanges[MPolyMessage::kFaceIndex] = true;
        
        id = MPolyMessage::addPolyComponentIdChangedCallback( shapeNode,
                                                        wantIdChanges, 3,
                                                        userCB,
                                                        NULL,
                                                        &stat);

        // If the callback was successfully added then add the
        // callback id to our callback table so it can be removed
        // when the plugin is unloaded.
        //
        if ( stat ) {
            callbackIds.append( id );
        } else {
            cout << "MPolyMessage.addCallback failed\n";
        }
    }
        
    return stat;
}

//
// Plugin registration
//

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

    return plugin.registerCommand( "polyMessage", polyMessageCmd::creator );
}

MStatus uninitializePlugin( MObject obj)
{
    // Remove all callbacks
    //
    for (unsigned int i=0; i<callbackIds.length(); i++ ) {
        MMessage::removeCallback( (MCallbackId)callbackIds[i] );
    }

    MFnPlugin plugin( obj );
    return plugin.deregisterCommand( "polyMessage" );
}