Hi all - I’m trying to make a custom MPxNode that has an array attribute, that I’m building with an MArrayDataBuilder.
However, even thought I call both MArrayDataHandle.setClean() and setAllClean() after building the array, the compute seems to always get called whenever I call getAttr on the array attribute without an index, and whenever I call evaluateNumElements(). I can, however, call getAttr on a specific element - getAttr myNode.myAttr[3] - without triggering the compute.
Is this normal?
Here’s some code to illustrate what I mean - you can execute this straight from a script editor:
from pymel.api.plugins import DependNode
import maya.OpenMaya as om
class MyNode(DependNode):
_typeId = om.MTypeId(0x812EF)
_name = 'MyNode'
@classmethod
def initialize(cls):
# input
nAttr = om.MFnNumericAttribute()
cls.input = nAttr.create( "input", "in", om.MFnNumericData.kFloat, 0.0 )
nAttr.setStorable(True)
cls.addAttribute(cls.input)
nAttr = om.MFnNumericAttribute()
cls.myAttr = nAttr.create("myAttr", "mya", om.MFnNumericData.kFloat, 0.0)
nAttr.setStorable(True)
nAttr.setArray(True)
nAttr.setUsesArrayDataBuilder(True)
cls.addAttribute(cls.myAttr)
cls.attributeAffects(cls.input, cls.myAttr)
def compute(self, plug, dataBlock):
print "compute called on %s" % plug.name()
if plug == self.myAttr:
arrayHandle = dataBlock.outputArrayValue(self.myAttr)
numElements = arrayHandle.elementCount()
print "numElements: ", numElements
if arrayHandle.elementCount() < 10:
builder = arrayHandle.builder()
elemHandle = builder.addLast()
elemHandle.setFloat(numElements)
elemHandle.setClean()
arrayHandle.set(builder)
arrayHandle.setClean()
arrayHandle.setAllClean()
print "new numElements: ", arrayHandle.elementCount()
return
elif plug == self.input:
dataBlock.setClean(self.input)
return
return om.kUnknownParameter
MyNode.register()
import pymel.core as pm
import maya.cmds as cmds
mynode = pm.createNode('MyNode')
attrName = "%s.myAttr" %mynode
print cmds.getAttr(attrName)
print mynode.myAttr.evaluateNumElements()
print mynode.myAttr.numElements()
print "dirty?", mynode.myAttr.isDirty()
print cmds.getAttr(attrName)
A few notes: