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.