66 import maya.OpenMaya
as OpenMaya
67 import maya.OpenMayaMPx
as OpenMayaMPx
68 import maya.OpenMayaRender
as OpenMayaRender
69 import maya.OpenMayaUI
as OpenMayaUI
75 kPluginNodeTypeName =
"spBasicShape"
78 glRenderer = OpenMayaRender.MHardwareRenderer.theRenderer()
79 glFT = glRenderer.glFunctionTable()
83 kActiveAffectedColor = 8
98 radius = kDefaultRadius
99 height = kDefaultHeight
100 width = kDefaultWidth
101 shapeType = kDefaultShapeType
108 class basicShape(OpenMayaMPx.MPxSurfaceShape):
110 OpenMayaMPx.MPxSurfaceShape.__init__(self)
119 self.__myGeometry = basicGeom()
123 def postConstructor(self):
125 When instances of this node are created internally, the MObject associated
126 with the instance is not created until after the constructor of this class
127 is called. This means that no member functions of MPxSurfaceShape can
128 be called in the constructor.
129 The postConstructor solves this problem. Maya will call this function
130 after the internal object has been created.
131 As a general rule do all of your initialization in the postConstructor.
133 self.setRenderable(
True)
137 def compute(self, plug, dataBlock):
139 Since there are no output attributes this is not necessary but
140 if we wanted to compute an output mesh for rendering it would
141 be done here base on the inputs.
143 return OpenMaya.kUnknownParameter
147 def getInternalValue(self, plug, datahandle):
149 Handle internal attributes.
150 In order to impose limits on our attribute values we
151 mark them internal and use the values in fGeometry intead.
153 if (plug == basicShape.aRadius):
154 datahandle.setDouble(self.__myGeometry.radius)
156 elif (plug == basicShape.aHeight):
157 datahandle.setDouble(self.__myGeometry.height)
159 elif (plug == basicShape.aWidth):
160 datahandle.setDouble(self.__myGeometry.width)
163 return OpenMayaMPx.MPxSurfaceShape.getInternalValue(self, plug, datahandle)
169 def setInternalValue(self, plug, datahandle):
171 Handle internal attributes.
172 In order to impose limits on our attribute values we
173 mark them internal and use the values in fGeometry intead.
178 if (plug == basicShape.aRadius):
179 radius = datahandle.asDouble()
184 self.__myGeometry.radius = radius
186 elif (plug == basicShape.aHeight):
187 val = datahandle.asDouble()
190 self.__myGeometry.height = val
192 elif (plug == basicShape.aWidth):
193 val = datahandle.asDouble()
196 self.__myGeometry.width = val
199 return OpenMayaMPx.MPxSurfaceShape.setInternalValue(self, plug, datahandle)
210 def boundingBox(self):
212 Returns the bounding box for the shape.
213 In this case just use the radius and height attributes
214 to determine the bounding box.
218 geom = self.geometry()
237 This function gets the values of all the attributes and
238 assigns them to the fGeometry. Calling MPlug::getValue
239 will ensure that the values are up-to-date.
243 this_object = self.thisMObject()
246 self.__myGeometry.radius = plug.asDouble()
248 plug.setAttribute(basicShape.aHeight)
249 self.__myGeometry.height = plug.asDouble()
251 plug.setAttribute(basicShape.aWidth)
252 self.__myGeometry.width = plug.asDouble()
254 plug.setAttribute(basicShape.aShapeType)
255 self.__myGeometry.shapeType = plug.asShort()
257 return self.__myGeometry
261 stream=OpenMaya.MStreamUtils.stdOutStream()
262 OpenMaya.MStreamUtils.writeCharBuffer(stream,msg)
268 class basicShapeUI(OpenMayaMPx.MPxSurfaceShapeUI):
270 __kDrawRectangle, __kDrawCircle, __kDrawTriangle = range(3)
271 __kDrawWireframe, __kDrawWireframeOnShaded, __kDrawSmoothShaded, __kDrawFlatShaded, __kLastToken = range(5)
274 OpenMayaMPx.MPxSurfaceShapeUI.__init__(self)
278 def getDrawRequests(self, info, objectAndActiveOnly, queue):
280 The draw data is used to pass geometry through the
281 draw queue. The data should hold all the information
282 needed to draw the shape.
286 request = info.getPrototype(self)
288 shapeNode = self.surfaceShape()
289 geom = shapeNode.geometry()
290 self.getDrawData(geom, data)
291 request.setDrawData(data)
294 if (
not info.objectDisplayStatus(OpenMayaUI.M3dView.kDisplayMeshes)):
298 if (info.displayStyle() == OpenMayaUI.M3dView.kWireFrame):
299 self.getDrawRequestsWireframe(request, info)
302 elif (info.displayStyle() == OpenMayaUI.M3dView.kGouraudShaded):
303 request.setToken(basicShapeUI.__kDrawSmoothShaded)
304 self.getDrawRequestsShaded(request, info, queue, data)
307 elif (info.displayStyle() == OpenMayaUI.M3dView.kFlatShaded):
308 request.setToken(basicShapeUI.__kDrawFlatShaded)
309 self.getDrawRequestsShaded(request, info, queue, data)
315 def draw(self, request, view):
317 From the given draw request, get the draw data and determine
318 which basic to draw and with what values.
321 data = request.drawData()
322 shapeNode = self.surfaceShape()
323 geom = shapeNode.geometry()
324 token = request.token()
328 if ((token == basicShapeUI.__kDrawSmoothShaded)
or
329 (token == basicShapeUI.__kDrawFlatShaded)):
331 material = request.material()
332 material.setMaterial(request.multiPath(), request.isTransparent())
340 drawTexture = material.materialIsTextured()
and not view.usingDefaultMaterial()
344 material.applyTexture(view, data)
346 glFT.glPushAttrib( OpenMayaRender.MGL_ALL_ATTRIB_BITS )
348 if ((token == basicShapeUI.__kDrawSmoothShaded)
or
349 (token == basicShapeUI.__kDrawFlatShaded)):
350 glFT.glEnable(OpenMayaRender.MGL_POLYGON_OFFSET_FILL)
351 glFT.glPolygonMode(OpenMayaRender.MGL_FRONT_AND_BACK, OpenMayaRender.MGL_FILL)
353 glFT.glEnable(OpenMayaRender.MGL_TEXTURE_2D)
355 glFT.glPolygonMode(OpenMayaRender.MGL_FRONT_AND_BACK, OpenMayaRender.MGL_LINE)
358 if (geom.shapeType == basicShapeUI.__kDrawCircle):
360 glFT.glBegin(OpenMayaRender.MGL_POLYGON)
361 for i
in range(0,360):
362 rad = (i*2*math.pi)/360;
363 glFT.glNormal3f(0.0, 0.0, 1.0)
365 glFT.glTexCoord3f(geom.radius*math.cos(0), geom.radius*math.sin(0), 0.0)
366 glFT.glVertex3f(geom.radius*math.cos(0), geom.radius*math.sin(0), 0.0)
368 glFT.glTexCoord3f(geom.radius*math.cos(rad), geom.radius*math.sin(rad), 0.0)
369 glFT.glVertex3f(geom.radius*math.cos(rad), geom.radius*math.sin(rad), 0.0)
372 elif (geom.shapeType == basicShapeUI.__kDrawRectangle):
374 glFT.glBegin(OpenMayaRender.MGL_QUADS)
376 glFT.glTexCoord2f(-1*(geom.width/2), -1*(geom.height/2))
377 glFT.glVertex3f(-1*(geom.width/2), -1*(geom.height/2), 0.0)
378 glFT.glNormal3f(0, 0, 1.0)
380 glFT.glTexCoord2f(-1*(geom.width/2), (geom.height/2))
381 glFT.glVertex3f(-1*(geom.width/2), (geom.height/2), 0.0)
382 glFT.glNormal3f(0, 0, 1.0)
384 glFT.glTexCoord2f((geom.width/2), (geom.height/2))
385 glFT.glVertex3f((geom.width/2), (geom.height/2), 0.0)
386 glFT.glNormal3f(0, 0, 1.0)
388 glFT.glTexCoord2f((geom.width/2), -1*(geom.height/2))
389 glFT.glVertex3f((geom.width/2), -1*(geom.height/2), 0.0)
390 glFT.glNormal3f(0, 0, 1.0)
395 glFT.glBegin(OpenMayaRender.MGL_TRIANGLES)
396 glFT.glTexCoord2f(-1*(geom.width/2), -1*(geom.height/2))
397 glFT.glVertex3f(-1*(geom.width/2), -1*(geom.height/2), 0.0)
398 glFT.glNormal3f(0.0, 0.0, 1.0)
400 glFT.glTexCoord2f(0.0, (geom.height/2))
401 glFT.glVertex3f(0.0, (geom.height/2), 0.0)
402 glFT.glNormal3f(0.0, 0.0, 1.0)
404 glFT.glTexCoord2f((geom.width/2), -1*(geom.height/2))
405 glFT.glVertex3f((geom.width/2), -1*(geom.height/2), 0.0)
406 glFT.glNormal3f(0.0, 0.0, 1.0)
409 if ((token == basicShapeUI.__kDrawSmoothShaded)
or
410 (token == basicShapeUI.__kDrawFlatShaded)):
411 glFT.glDisable(OpenMayaRender.MGL_POLYGON_OFFSET_FILL)
414 glFT.glDisable(OpenMayaRender.MGL_TEXTURE_2D)
421 def select(self, selectInfo, selectionList, worldSpaceSelectPts):
423 Select function. Gets called when the bbox for the object is selected.
424 This function just selects the object without doing any intersection tests.
429 item.add(selectInfo.selectPath())
431 selectInfo.addSelection(item, xformedPt, selectionList,
432 worldSpaceSelectPts, priorityMask,
False)
436 def getDrawRequestsWireframe(self, request, info):
438 request.setToken(basicShapeUI.__kDrawWireframe)
440 displayStatus = info.displayStatus()
441 activeColorTable = OpenMayaUI.M3dView.kActiveColors
442 dormantColorTable = OpenMayaUI.M3dView.kDormantColors
444 if (displayStatus == OpenMayaUI.M3dView.kLead):
445 request.setColor(kLeadColor, activeColorTable)
447 elif (displayStatus == OpenMayaUI.M3dView.kActive):
448 request.setColor(kActiveColor, activeColorTable)
450 elif (displayStatus == OpenMayaUI.M3dView.kActiveAffected):
451 request.setColor(kActiveAffectedColor, activeColorTable)
453 elif (displayStatus == OpenMayaUI.M3dView.kDormant):
454 request.setColor(kDormantColor, dormantColorTable)
456 elif (displayStatus == OpenMayaUI.M3dView.kHilite):
457 request.setColor(kHiliteColor, activeColorTable)
461 def getDrawRequestsShaded(self, request, info, queue, data):
463 path = info.multiPath()
465 material = OpenMayaMPx.MPxSurfaceShapeUI.material(self, path)
466 usingDefaultMat = view.usingDefaultMaterial()
470 displayStatus = info.displayStatus()
474 material.evaluateMaterial(view, path)
476 print "Couldn't evaluate material"
479 drawTexture =
not usingDefaultMat
480 if (drawTexture
and material.materialIsTextured()):
481 material.evaluateTexture(data)
483 request.setMaterial(material)
491 if ((displayStatus == OpenMayaUI.M3dView.kActive)
or
492 (displayStatus == OpenMayaUI.M3dView.kLead)
or
493 (displayStatus == OpenMayaUI.M3dView.kHilite)):
494 wireRequest = info.getPrototype(self)
495 wireRequest.setDrawData(data)
496 self.getDrawRequestsWireframe(wireRequest, info)
497 wireRequest.setToken(basicShapeUI.__kDrawWireframeOnShaded)
498 wireRequest.setDisplayStyle(OpenMayaUI.M3dView.kWireFrame)
499 queue.add(wireRequest)
504 return OpenMayaMPx.asMPxPtr( basicShape() )
508 return OpenMayaMPx.asMPxPtr( basicShapeUI() )
511 def nodeInitializer():
514 basicShape.aShapeType = enumAttr.create(
"shapeType",
"st", kDefaultShapeType)
515 enumAttr.addField(
"rectangle", 0)
516 enumAttr.addField(
"circle", 1)
517 enumAttr.addField(
"triangle", 2)
518 enumAttr.setHidden(
False)
519 enumAttr.setKeyable(
True)
520 basicShape.addAttribute(basicShape.aShapeType)
524 def setOptions(attr):
525 attr.setHidden(
False)
526 attr.setKeyable(
True)
527 attr.setInternal(
True)
531 basicShape.aRadius = numericAttr.create(
"radius",
"r", OpenMaya.MFnNumericData.kDouble, kDefaultRadius)
532 setOptions(numericAttr)
533 basicShape.addAttribute(basicShape.aRadius)
535 basicShape.aHeight = numericAttr.create("height",
"ht", OpenMaya.MFnNumericData.kDouble, kDefaultHeight)
536 setOptions(numericAttr)
537 basicShape.addAttribute(basicShape.aHeight)
539 basicShape.aWidth = numericAttr.create(
"width2",
"wt2", OpenMaya.MFnNumericData.kDouble, kDefaultWidth)
540 setOptions(numericAttr)
541 basicShape.addAttribute(basicShape.aWidth)
544 def initializePlugin(mobject):
545 mplugin = OpenMayaMPx.MFnPlugin(mobject,
"Autodesk",
"8.5",
"Any")
547 mplugin.registerShape( kPluginNodeTypeName, spBasicShapeNodeId,
548 nodeCreator, nodeInitializer, uiCreator )
550 sys.stderr.write(
"Failed to register node: %s" % kPluginNodeTypeName )
555 def uninitializePlugin(mobject):
556 mplugin = OpenMayaMPx.MFnPlugin(mobject)
558 mplugin.deregisterNode( spBasicShapeNodeId )
560 sys.stderr.write(
"Failed to deregister node: %s" % kPluginNodeTypeName )