So basically I've got a python node called *simpleLocator* with an attribute called *pointCount *(type *kInt*) which is used to generate some random points. These points can be passed out as an array with the attribute *outPoints *(type *kDoubleArray *for this example). I've setup * attributeAffects*() so that outPoints depends on pointCount, so it should update if the user edits the number of points. This node needs to draw the points every frame with OpenGL as well, but only compute as needed. So far so good. Here's my example code (also attached to this post), stripped to the bare essentials and it almost works:
http://hastebin.com/vixiyaruda.py When compute() is called though, plug never equals aOutPoints. Ever, ever. def compute( self, plug, data ): if plug == simpleLocator.aOutPoints: print( 'aOutPoints needs to be computed, but we never get here...' ) return om.MStatus.kSuccess else: return om.MStatus.kUnknownParameter What's normal practice here? Should I just query my simpleLocator.aPointCount every time draw is called and only call generatePoints() if the value of aPointCount has been changed? Should I derive from a node other than MPxLocator and implement my own draw method? Does MPxLocator behave different in C++? Any help, any insight would be greatly appreciated. Thanks. -shawn PS- If you're curious, the real node is generating blue noise for thousands of points and is fairly expensive to calculate. -- view archives: http://groups.google.com/group/python_inside_maya change your subscription settings: http://groups.google.com/group/python_inside_maya/subscribe
""" import maya.cmds as mc pluginFile = 'SimpleLocator.py' pluginNode = 'simpleLocator' # unload if mc.pluginInfo( pluginFile, q=True, l=True ): # cleanup nodes first for node in mc.ls( type=pluginNode ): tf = mc.listRelatives( node, p=True )[0] print( 'Deleting node: %s' % node ) mc.delete( node ) mc.delete( tf ) print( 'Unloading plugin: %s' % pluginFile ) mc.unloadPlugin( pluginFile, force=True ) # load print( 'Loading plugin: %s' % pluginFile ) mc.loadPlugin( pluginFile, quiet=True ) print( 'Creating test node: %s' % pluginNode ) mc.createNode( pluginNode ) """ import sys import random import maya.OpenMaya as om import maya.OpenMayaMPx as mpx import maya.OpenMayaRender as mr nodeTypeName = 'simpleLocator' nodeTypeId = om.MTypeId(0x00070) glRenderer = mr.MHardwareRenderer.theRenderer() glFT = glRenderer.glFunctionTable() class simpleLocator( mpx.MPxLocatorNode ): # class variables aPointCount = om.MObject() aOutPoints = om.MObject() def __init__( self ): mpx.MPxLocatorNode.__init__( self ) self.pointCount = 10 self.points = [] self.generatePoints() def generatePoints( self ): random.seed( 1242) self.points = [] for i in xrange( self.pointCount ): self.points.append( (random.uniform(-5,5), random.uniform(-5,5), 0) ) def drawPoints( self ): glFT.glPointSize( 4 ) glFT.glBegin( mr.MGL_POINTS ) for p in self.points: glFT.glVertex3f( p[0], p[1], p[2] ) glFT.glEnd() def compute( self, plug, data ): if plug == simpleLocator.aOutPoints: print( 'aOutPoints needs to be computed.' ) return om.MStatus.kSuccess else: return om.MStatus.kUnknownParameter def draw( self, view, path, style, status ): view.beginGL() self.drawPoints() view.endGL() def nodeCreator(): return mpx.asMPxPtr( simpleLocator() ) def nodeInitializer(): nAttr = om.MFnNumericAttribute() tAttr = om.MFnTypedAttribute() simpleLocator.aPointCount = nAttr.create( 'pointCount', 'ptc', om.MFnNumericData.kInt ) nAttr.setKeyable( True ) nAttr.setDefault( 100 ) simpleLocator.addAttribute( simpleLocator.aPointCount ) simpleLocator.aOutPoints = tAttr.create( 'outPoints', 'opts', om.MFnData.kDoubleArray ) tAttr.setStorable( False ) tAttr.setWritable( False ) tAttr.setReadable( True ) simpleLocator.addAttribute( simpleLocator.aOutPoints ) simpleLocator.attributeAffects( simpleLocator.aPointCount, simpleLocator.aOutPoints ) return om.MStatus.kSuccess def initializePlugin( obj ): plugin = mpx.MFnPlugin( obj ) try: plugin.registerNode( nodeTypeName, nodeTypeId, nodeCreator, nodeInitializer, mpx.MPxNode.kLocatorNode ) except: sys.stderr.write( 'Failed to register node: %s' % nodeTypeName ) raise def uninitializePlugin( obj ): plugin = mpx.MFnPlugin( obj ) try: plugin.deregisterNode( nodeTypeId ) except: sys.stderr.write( 'Failed to deregister node: %s' % nodeTypeName ) raise