Data blocks and data handles

A node's attribute values are stored in its data block. The node owns its data block and uses it for computation. The data block is passed to the node's compute() method when the node receives a request to update one of its output plug. This will happen when the underlying framework updates any of the node's input values within its data block.

A data handle is used to access the data in the MDataBlock object. An MDataHandle object is a reference to a specific piece of data within the MDataBlock.

Important: A data block and its data are only valid during the execution of a node’s compute() method. Never maintain a pointer to a data block or any of its data after the compute() method exits.

To access input data, use MDataBlock::inputValue() to create an MDataHandle object for the input attribute. Then extract the data using the appropriate MDataHandle method.

For example, to extract a float from the incoming data block, use the MDataHandle::asFloat() method. In this example, input is the input attribute.

MStatus myNode::compute( const MPlug& plug, MDataBlock& datablock ) {

    [...]
    
    MDataHandle inputHandle = datablock.inputValue(input, &returnStatus);
    float& inputValue = inputHandle.asFloat();

To update an output attribute, use MDataBlock::outputValue() to create an MDataHandle object for the output attribute. Set the output data using MDataHandle::set().

In the following example, output is the node's output attribute:

MStatus myNode::compute( const MPlug& plug, MDataBlock& data ) {

    [...]

    float result = sin(inputValue);
    MDataHandle outputHandle = data.outputValue(output);
    outputHandle.set(result);
    data.setClean(plug);

After setting a new output attribute value, set its plug to clean using MDataBlock::setClean() to indicate that it is newly computed and no longer dirty.