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