Hi all - so I'm making a node that I need to update when it's worldSpace matrix changes - so I thought that MFnAttribute.setWorldSpace would be exactly what I was looking for. However, I can't seem to make it work - the attribute never seems to get set dirty!
Here's the relevant sections from my test plugin (it's written in python):
compute and initialize methods
def compute(self, plug, dataBlock):
print "compute called for:", plug.name()
if (plug == self.worldX):
if plug.isElement():
arrayIndex = plug.logicalIndex()
print "got worldX[%d]" % arrayIndex
else:
print "got worldX - uses default index 0"
arrayIndex = 0
outputArrayHandle = dataBlock.outputArrayValue( self.worldX )
builder = outputArrayHandle.builder();
outHandle = builder.addElement( arrayIndex );
outHandle.setFloat(worldMatrix(3,0))
return om.MStatus.kSuccess
return om.MStatus.kUnknownParameter
@classmethod
def initialize(cls):
nAttr = om.MFnNumericAttribute()
# worldX
cls.worldX = nAttr.create("worldX", "wx", om.MFnNumericData.kFloat, 0.0 )
nAttr.setArray(1)
nAttr.setWorldSpace(1)
print "set world space for worldX"
nAttr.setUsesArrayDataBuilder(1)
cls.addAttribute( cls.worldX )
Here's what I was using to test it:
test code
import pymel.core as pm
newFile(f=1)
nodeType = 'WorldXNode'
plug = nodeType + '.py'
if pm.pluginInfo(plug, q=1, loaded=1):
pm.unloadPlugin(plug)
pm.loadPlugin(plug)
tn = pm.createNode(nodeType)
pm.select(None)
tn.hide()
nodeName = tn.name()
# get the worldX - this SHOULD trigger a compute call for .worldX... but it doesn't
print "initial worldX get:", pm.getAttr(nodeName + '.worldX')
print "initial worldX[0] get:", pm.getAttr(nodeName + '.worldX[0]')
# set the parent translate to change world x
tn.getParent().tx.set(12)
print "set parent tx..."
# make sure that worldX is indeed set to be a worldSpace attr
attr = pm.api.MFnAttribute(tn.worldX.__apimplug__().attribute())
print "is worldX worldSpace?", attr.isWorldSpace()
# since we changed the worldMatrix, worldX should be dirty - but it isn't
print "worldX dirty?", pm.isDirty(nodeName + '.worldX', d=1), pm.isDirty(nodeName + '.worldX', c=1)
print "worldX[0] dirty?", pm.isDirty(nodeName + '.worldX[0]', d=1), pm.isDirty(nodeName + '.worldX[0]', c=1)
# query worldX again - since worldMatrix was changed, should trigger compute again
print "final worldX get:", pm.getAttr(nodeName + '.worldX')
print "final worldX[0] get:", pm.getAttr(nodeName + '.worldX')
# see what we SHOULD be getting back
print "true worldX:", tn.getParent().getTranslation(space='world')[0]
pm.dgDirty(nodeName + '.worldX[0]')