Attributes and plugs

Dependency nodes have attributes and plugs.

Plugs are a means to pass input and output between nodes. Attributes are

The node attributes added with MPxNode.addAttribute() in nodeInitializer() are used by Maya to define the input and output connection points of our node when it is instantiated in the Dependency Graph.

These connection points are known as plugs, and are represented by instances of MPlug. The call to MPxNode.attributeAffects() in nodeInitializer() determines the causal input > output link between these plugs. Ultimately, the Dependency Graph keeps track of the directed edges of connected plugs among all the nodes. During Maya's ongoing Dependency Graph evaluation process, if data associated to a plug is changed, this plug is marked as dirty, meaning that its cached value is stale and must be recomputed. The plug hierarchy is recursively traversed to mark the remaining affected plugs as dirty.

Maya then calls the compute() method on each node containing a dirty plug, passing an instance of MPlug as well as MDataBlock. The related attribute of the passed MPlug should be checked to determine what to compute. This is done using MPlug's overloaded equality operator '=='.

The passed MDataBlock instance contains MDataHandle objects, which store the values associated to their respective attributes. The float input value is obtained as follows:

sampleInDataHandle = pDataBlock.inputValue( myNode.sampleInAttribute )
sampleInValue = sampleInDataHandle.asFloat()

The compute() method should conclude by setting a newly computed value to the correct output MDataHandle. The call to MDataHandle.setClean() removes the dirty flag from its corresponding plug.

If the plug passed into the compute() function is not related to an output attribute we can compute, the function should return OpenMaya.kUnknownParameter. This lets Maya know that the plug's value should be computed using one of our base class's compute() functions.

A custom node is defined by creating a Maya Dependency Graph plug-in. Such a plug-in contains a class which inherits from MPxNode or one of its subclasses. This new class will override the MPxNode.compute() function to define the custom node's behavior. Once a Dependency Graph plug-in is loaded into Maya, the Script Editor can be used to create an instance of the node.

In the previous diagram, the initializePlugin() function makes a call to mplugin.registerNode(), passing the parameter "mynode" to declare the custom node type's name. An instance of this node can therefore be created using the following Python script:

import maya.cmds as cmds
cmds.createNode( "mynode" )

The result is an instance of a node whose input and output MPlugs are initialized according to the attributes declared in the plug-in (nodeInitializer()). More concretely, the attributes declared in the plug-in will dictate how the MPlugs will be created in terms of their type, default value, visibility in the UI, readability (usable as input), writeability (usable as output), and whether or not the run-time value should be stored to a file when the scene is saved.

Observe that in the nodeInitializer() function of our plug-in definition, we declare an affects relationship between:

The affects relationship, declared using MPxNode.attributeAffects(), tells Maya which inputs are required to compute a given output. As such, for any given instance of our node, if the MPlug associated to its inputAttribute1 is marked dirty, the dirty flag will also propagate to the MPlug associated to its outputAttribute. This dirty flag propagation will therefore cause the node's compute() function to be called to clean the dirty outputAttribute MPlug.