![]()
Deformer Node Example
This section describes the
offsetNodeplug-in, which is an example of a deformer node. This plug-in is available through the Maya API Devkit.Implementing the Proxy Deformer Node
The
offsetclass inherits fromMPxDeformerNodeand defines a number of virtual methods such asdeform().class offset : public MPxDeformerNode { public: offset(); virtual ~offset(); static void* creator(); static MStatus initialize(); // deformation function // virtual MStatus deform(MDataBlock& block, MItGeometry& iter, const MMatrix& mat, unsigned int multiIndex); virtual MObject& accessoryAttribute() const; virtual MStatus accessoryNodeSetup(MDagModifier& cmd); public: static MObject offsetMatrix; // offset center and axis static MTypeId id; private: };Initializing the Plug-in
The new deformer node must be registered with the
registerNode()method ofMFnPluginwhen initializing the plug-in.MStatus initializePlugin( MObject obj ) { MStatus result; MFnPlugin plugin( obj, "Autodesk", "3.0", "Any"); result = plugin.registerNode( "offset", offset::id, offset::creator, offset::initialize, MPxNode::kDeformerNode ); return result; }To remove the deformer node, you must deregister the plug-in through a call to the
deregisterNode()method ofMFnPlugin.MStatus uninitializePlugin( MObject obj) { MStatus result; MFnPlugin plugin( obj ); result = plugin.deregisterNode( offset::id ); return result; }Implementing the offsetNode
The
initialize()method is used to add and configure new attributes to proxy nodes. In the example below, theoffsetMatrixattribute is added to the node and is made connectable. Any changes to the input attribute,offsetMatrix,affects the output attribute,outputGeom.MStatus offset::initialize() { MFnMatrixAttribute mAttr; offsetMatrix=mAttr.create( "locateMatrix", "lm"); mAttr.setStorable(false); mAttr.setConnectable(true); addAttribute( offsetMatrix); attributeAffects( offset::offsetMatrix, offset::outputGeom ); return MStatus::kSuccess; }Deform Method
The
deform()method implements an algorithm to compute the deformation.In the
offsetclass, thedeform()method deforms a point with a squash algorithm. The geometry data is extracted from the datablock byMDataHandleand deforms each point of the geometry. Thedeform()method returns aMS::kSuccessto indicate a successful deformation. If not, the deformation encountered problems, such as invalid data input or insufficient memory.There are four required arguments for this method. The
blockargument refers to the node’s datablock where information on the geometry is stored. Theiterargument is the iterator for the geometry to be deformed. Themis the matrix used to transform points from local space to world space. ThemultiIndexis the index of the requested output geometry.MStatus offset::deform( MDataBlock& block, MItGeometry& iter, const MMatrix& /*m*/, unsigned int multiIndex) { MStatus returnStatus; MDataHandle envData = block.inputValue(envelope, &returnStatus); if (MS::kSuccess != returnStatus) return returnStatus; float env = envData.asFloat(); MDataHandle matData = block.inputValue(offsetMatrix, &returnStatus ); if (MS::kSuccess != returnStatus) return returnStatus; MMatrix omat = matData.asMatrix(); MMatrix omatinv = omat.inverse(); for ( ; !iter.isDone(); iter.next()) { MPoint pt = iter.position(); pt *= omatinv; float weight = weightValue(block,multiIndex,iter.index()); //offset algorithm pt.y = pt.y + env*weight; pt *= omat; iter.setPosition(pt); } return returnStatus; }The
weightValue()method above returns the weight value in the geometry.The weight value for each vertex, CV or lattice point is obtained through the
weightValue()method with the multi-index passed to the method. This value is then incorporated into theoffsetalgorithm to perform the desired deformation.Implementing Accessory Nodes
The
accessoryNodesetup()method creates and attaches an additional node to the deformer node. In this example, a locator is created and its matrix attributes are connected to the matrix input of the offset node.MStatus offset::accessoryNodeSetup(MDagModifier& cmd) { MStatus result; MObject objLoc = cmd.createNode(MString("locator"), MObject::kNullObj, &result); if (MS::kSuccess == result) { MFnDependencyNode fnLoc(objLoc); MString attrName; attrName.set("matrix"); MObject attrMat = fnLoc.attribute(attrName); result = cmd.connect(objLoc,attrMat,this->thisMObject(), offset::offsetMatrix); } return result; }The
accessoryAttribute()method returns the attribute that is connected to the accessory shape, which in this case isoffset::offsetMatrix. If the accessory shape is deleted, the deformer node is automatically deleted as well.Other methods
There are several other methods in this class will allow:
- listen to important modification events
- handle special case during set editing of points(reconnect using old input/output indicies if all points are deleted from the set and then added back in)