//- // ========================================================================== // Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors. All // rights reserved. // // The coded instructions, statements, computer programs, and/or related // material (collectively the "Data") in these files contain unpublished // information proprietary to Autodesk, Inc. ("Autodesk") and/or its // licensors, which is protected by U.S. and Canadian federal copyright // law and by international treaties. // // The Data is provided for use exclusively by You. You have the right // to use, modify, and incorporate this Data into other products for // purposes authorized by the Autodesk software license agreement, // without fee. // // The copyright notices in the Software and this entire statement, // including the above license grant, this restriction and the // following disclaimer, must be included in all copies of the // Software, in whole or in part, and all derivative works of // the Software, unless such copies or derivative works are solely // in the form of machine-executable object code generated by a // source language processor. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. // AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED // WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF // NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR // PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR // TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS // BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, // DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK // AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY // OR PROBABILITY OF SUCH DAMAGES. // // ========================================================================== //+ /* file : deletedMsgCmd.cpp class: deletedMessage ---------------------- This plugin demonstrates each of the node deletion callbacks available in the Maya API. Callbacks are added to nodes by invoking the command: deletedMessage [ ...] This command will register 3 callbacks on the nodes. 1) MNodeMessage::addNodeAboutToDeleteCallback is used to register an about to delete callback on the nodes. This callback is executed once when the deletion operation is first performed, and is used to add commands to a DG modifier to be executed before the node is deleted. Since the operations performed by the DG modifier are undoable, when the node deletion is undone, the additional DG modifications added by this callback will also be undone or redone. 2) MNodeMessage::addNodePreRemovalCallback is used to register a callback that gets called whenever the deletion sequence is performed, whether it is the first time or on a redo of the delete. This callback will be called before any other changes are made as a result of the deletion, such as disconnecting any connections on the node. 3) MDGMessage::addNodeRemovedCallback is used to register a callback that is called when the node is removed. This callback will be received after the pre-removal callback, and after connections from the node are disconnected. Here is an example of the expected behavior of the callbacks registered on "nurbsSphere1" when the deletion is performed the first time: // Removal callback node: makeNurbSphere1 // Removal callback node: nurbsSphereShape1 // About to delete callback for node: nurbsSphere1 // Pre-removal callback for node: nurbsSphere1 // Removal callback node: nurbsSphere1 Here is an example of the expected behavior of the callbacks when the deletion is redone: // Removal callback node: makeNurbSphere1 // Removal callback node: nurbsSphereShape1 // Pre-removal callback for node: nurbsSphere1 // Removal callback node: nurbsSphere1 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Syntax string definitions class deletedMessage : public MPxCommand { public: virtual MStatus doIt( const MArgList& ); static void *creator(); static MSyntax newSyntax(); static void removeCallbacks(); // callback functions. static void aboutToDeleteCB(MObject& node, MDGModifier& modifier, void* clientData); static void preRemovalCB(MObject& node, void* clientData); static void removeCB(MObject& node, void* clientData); private: static MCallbackIdArray callbackIds; static bool nodeRemovedCBRegistered; }; MCallbackIdArray deletedMessage::callbackIds; bool deletedMessage::nodeRemovedCBRegistered = false; MStatus deletedMessage::doIt( const MArgList& args ) { MStatus status = MS::kSuccess; MArgDatabase argData(syntax(), args); MSelectionList objects; argData.getObjects(objects); for (unsigned int i = 0; i < objects.length(); i++) { MObject node; objects.getDependNode(i, node); callbackIds.append( MNodeMessage::addNodeAboutToDeleteCallback (node, aboutToDeleteCB, NULL, &status) ); if (!status) { MGlobal::displayWarning("Could not attach about to delete callback for node."); continue; } callbackIds.append( MNodeMessage::addNodePreRemovalCallback (node, preRemovalCB, NULL, &status) ); if (!status) { MGlobal::displayWarning("Could not attach pre-removal callback for node."); continue; } if (!nodeRemovedCBRegistered) { callbackIds.append( MDGMessage::addNodeRemovedCallback(removeCB, "dependNode", NULL, &status) ); if (!status) { MGlobal::displayWarning("Could not attach node removal callback."); continue; } nodeRemovedCBRegistered = true; } } return status; } void* deletedMessage::creator() { return new deletedMessage; } MSyntax deletedMessage::newSyntax() { MSyntax syntax; syntax.setObjectType(MSyntax::kSelectionList); syntax.setMinObjects(1); syntax.useSelectionAsDefault(true); return syntax; } void deletedMessage::aboutToDeleteCB(MObject& node, MDGModifier& modifier, void* clientData) { MFnDependencyNode nodeFn(node); MGlobal::displayInfo(MString("About to delete callback for node: ") + nodeFn.name()); // // If there were any other operations on the DG that needed to be performed // before the node was removed, they could be added to the MDGModifier. // For example, attributes could be removed from other nodes or connections // on related nodes could be disconnected. In this case there are no // operations to be added so just return. // } void deletedMessage::preRemovalCB(MObject& node, void* clientData) { MFnDependencyNode nodeFn(node); MGlobal::displayInfo(MString("Pre-removal callback for node: ") + nodeFn.name()); } void deletedMessage::removeCB(MObject& node, void* clientData) { MFnDependencyNode nodeFn(node); MGlobal::displayInfo(MString("Removal callback node: ") + nodeFn.name()); } void deletedMessage::removeCallbacks() { MMessage::removeCallbacks(callbackIds); } // standard initialize and uninitialize functions MStatus initializePlugin(MObject obj) { MFnPlugin pluginFn(obj, PLUGIN_COMPANY, "6.0"); MStatus status; status = pluginFn.registerCommand("deletedMessage", deletedMessage::creator, deletedMessage::newSyntax); if( !status) status.perror("register Command failed"); return status; } MStatus uninitializePlugin ( MObject obj ) { MFnPlugin pluginFn(obj); MStatus status = MS::kSuccess; deletedMessage::removeCallbacks(); status = pluginFn.deregisterCommand("deletedMessage"); return status; }