Hi there,
working with array attributes starts at the "initialize" function, where you can define array or array data attributes in more then one way. Which way to choose depends on how you would like to use the attributes later in maya.
Based on your description, I would suggest to use an array attribute and not an array data attribute.
The difference is: An array attribute has for each element of the array its own plug (like "node.attr[0]" in Maya). An array data attribute has one plug containing the whole array as one data object.
To declare a attribute as an array you have to call some extra functions while creating the attribute with MFn*Attribute.
For example:
MStatus TestNode::initialize() {
MStatus status;
MFnNumericAttribute nAttr;
arrayAttribute = nAttr.create("foo", "foo", MFnNumericData::kFloat, 0, &status);
nAttr.setArray(true);
nAttr.setUsesArrayDataBuilder(true);
status = addAttribute(arrayAttribute);
// more initialization code
}
The functions "setArray" and the more optional "setUsesArrayDataBuilder" define the attribute as an array attribute.
For getting the data of the array attribute inside the compute function you have to use the MArrayDataHandle class.
This class offers functions to work on array attribute data.
For example:
MStatus TestNode::compute(const MPlug &plug, MDataBlock &data) {
MStatus status;
MArrayDataHandle arrayHandle = data.inputArrayValue(arrayAttribute, &status);
MFloatArray values(arrayHandle.elementCount(), 0);
for (unsigned int i = 0; i < values.length(); i++) {
arrayHandle.jumpToArrayElement(i);
MDataHandle elementHandle = arrayHandle.inputValue(&status);
values[i] = elementHandle.asFloat();
}
// more computation
}
This example shows a straight forward approach for getting array values from data. Please notice, that this approach ignores array elements "logical index". For more information about the difference between "logical" and "physical" index in array attributes refer to the documentation of the MArrayDataHandle class.
For writing to array attributes the "setUsesArrayDataBuilder" function mentioned earlier gets relevant.
For example:
MStatus TestNode::compute(const MPlug &plug, MDataBlock &data) {
// some computation
MArrayDataHandle outputArrayHandle = data.outputArrayValue(outputArrayAttribute, &status);
MArrayDataBuilder outputArrayBuilder = outputArrayHandle.builder();
for (unsigned int i = 0; i < values.length(); i++) {
MDataHandle outputElementHandle = outputArrayBuilder.addLast(&status);
outputElementHandle.setFloat(values[i]);
}
outputArrayHandle.set(outputArrayBuilder);
outputArrayHandle.setAllClean();
// more computation
}
This example shows how to write to an array attribute using the MArrayDataBuilder class. To enable the usage of this class the "setUsesArrayDataBuilder" function must get called with "true" in the initialize function. Also important is to call the "setAllClean" function at the end of writing to the attribute to mark all array plugs as no more dirty.
I hope this helps.