Continuing my explanation of maya’s python api, we come to the compound attribute.
This is a handy way to organize our arrays.
First we create our MFnCompoundAttribute class:
cAttr = OpenMaya.MFnCompoundAttribute()
Then we create an input array(we are using matrix as input) so let’s create that class.
mAttr = OpenMaya.MFnMatrixAttribute()
Then create our matrix array attribute that will be a child of our compound attribute:
testNode.inputs = mAttr.create('inputs', 'inputs')
mAttr.setKeyable(1)
mAttr.setArray(1)
testNode.addAttribute(testNode.inputs)
Next, we can create our ‘parent’ compound attribute:
testNode.poseList = cAttr.create("inputList", "inputList")
cAttr.addChild(rbfAttrNode.inputs) #Here is where we state the child
cAttr.setArray(1)
cAttr.setHidden(1)
testNode.addAttribute(testNode.inputList)
As you can see, we created a compound attribute with our inputs array set to be the child.
This creates a hierarchy that would make sense:
inputList - Our compound attribute
-inputList[0] - The first entry in the compound attribute array
-inputs -The first entry in out matrix array
-inputs[0] - matrix input 1
-inputs[1]- matrix input 2
-inputList[1] - The second entry in the compound attribute array
-inputs -The second entry in out matrix array
-inputs[0] - matrix input 1
-inputs[1] - matrix input 2
Next we will look at how to get the data from each plug when we need it:
-Note, I found this very confusing when I first tried to do this correctly. Explanations are in the code as comments:
#First we get our compound array dataBlock
inputListArrayDataHandle = dataBlock.inputArrayValue(testNode.inputList)
#Get the amount of children arrays - this returns an int
index = inputListArrayDataHandle.elementCount()
#This is how I got the data I wanted, this can change based on what you need
#Create empty list
inputData = []
#Loop through the children arrays of the compound attribute
for i in range(index):
#Go to the first child in the array
inputListArrayDataHandle.jumpToElement(i)
#(This is the first entry array(inputList[0] in the example above))
inputsDataHandle = inputListArrayDataHandle.inputValue()
# Get the child array attribute(The first entry in the children of the child array)
# (This is the inputs in the example above)
inputDataHandle = OpenMaya.MArrayDataHandle(inputsDataHandle .child(testNode.inputs))
#Get the number of children in the child array
index2 = attributeDataHandle.elementCount()
# Create an empty to list
data = []
#Loop through the number of matrix in the inputs array
#These are the inputs[0], inputs[1]....inputs[n] in the example above
for j in range(index2):
#I created another emtpy list to keep track of things
#I made this list set at 3 entries as I only wanted the transform data
out = [None, None, None]
#Go to the first entry in the inputs array
inputDataHandle .jumpToElement(j)
#Get the data as an MMatrix class
mMatrix = om.MMatrix(inputDataHandle .inputValue().asMatrix())
#Create a MTransformationMatrix class with the MMatrix variable
mTrans = om.MTransformationMatrix(mMatrix)
#Grab the wold position data
trs = mTrans.translation(1)
#Optional data that can be pulled from the matrix is(Not used in this example)
#quat = mTrans.rotation(1)
#axis, angle = quat.asAxisAngle()
# Set out array values (xyz, xyz, angle)
out[0] = trs[0]
out[1] = trs[1]
out[2] = trs[2]
if out: #Check that there is data to fill out list
for o in out:
data.append(o)
#Fill the top level list with the list
inputData.append(data)
With the above example we end up with a list of arrays:
inputData = [[0,0,0], [0,0,0], [0,0,0], [0,0,0], [0,0,0]]
I hope you find this helpful.