43 import maya.api.OpenMaya 
as om
 
   44 import maya.api.OpenMayaUI 
as omui
 
   45 import maya.api.OpenMayaAnim 
as oma
 
   46 import maya.api.OpenMayaRender 
as omr
 
   47 import maya.mel 
as mel
 
   51     The presence of this function tells Maya that the plugin produces, and 
   52     expects to be passed, objects created using the Maya Python API 2.0. 
   56 def matrixAsArray(matrix):
 
   59         array.append(matrix[i])
 
   64 sole = [ [  0.00, 0.0, -0.70 ],
 
   76                  [ -0.15, 0.0, -0.14 ],
 
   77                  [ -0.16, 0.0, -0.25 ],
 
   78                  [ -0.17, 0.0, -0.35 ],
 
   79                  [ -0.17, 0.0, -0.46 ],
 
   80                  [ -0.16, 0.0, -0.54 ],
 
   81                  [ -0.13, 0.0, -0.61 ],
 
   82                  [ -0.09, 0.0, -0.65 ],
 
   83                  [ -0.04, 0.0, -0.69 ],
 
   84                  [ -0.00, 0.0, -0.70 ] ]
 
   85 heel = [ [  0.00, 0.0,  0.06 ],
 
  100                  [ -0.13, 0.0,  0.06 ],
 
  101                  [ -0.00, 0.0,  0.06 ] ]
 
  109 the3dSolidShaders = {}
 
  111 def get3dSolidShader(color):
 
  114     if key 
in the3dSolidShaders:
 
  115         return the3dSolidShaders[key]
 
  119     shaderMgr = omr.MRenderer.getShaderManager()
 
  121         shader = shaderMgr.getStockShader(omr.MShaderManager.k3dSolidShader)
 
  124         shader.setParameter(footPrintGeometryOverride.colorParameterName_, color)
 
  125         the3dSolidShaders[key] = shader
 
  129 def releaseShaders():
 
  130     shaderMgr = omr.MRenderer.getShaderManager()
 
  132         for key, shader 
in the3dSolidShaders.items():
 
  133             shaderMgr.releaseShader(shader)
 
  135         the3dSolidShaders.clear()
 
  143 class footPrint(omui.MPxLocatorNode):
 
  144     id = om.MTypeId( 0x00080033 )
 
  145     drawDbClassification = 
"drawdb/geometry/footPrint_GeometryOverride" 
  146     drawRegistrantId = 
"FootprintNode_GeometryOverridePlugin" 
  156         unitFn = om.MFnUnitAttribute()
 
  158         footPrint.size = unitFn.create( 
"size", 
"sz", om.MFnUnitAttribute.kDistance )
 
  159         unitFn.default = om.MDistance(1.0)
 
  161         om.MPxNode.addAttribute( footPrint.size )
 
  164         omui.MPxLocatorNode.__init__(self)
 
  166     def compute(self, plug, data):
 
  169     def draw(self, view, path, style, status):
 
  172         thisNode = self.thisMObject()
 
  173         plug = om.MPlug( thisNode, footPrint.size )
 
  174         sizeVal = plug.asMDistance()
 
  175         multiplier = sizeVal.asCentimeters()
 
  177         global sole, soleCount
 
  178         global heel, heelCount
 
  183         import maya.OpenMayaRender 
as v1omr
 
  184         glRenderer = v1omr.MHardwareRenderer.theRenderer()
 
  185         glFT = glRenderer.glFunctionTable()
 
  187         if ( style == omui.M3dView.kFlatShaded ) 
or ( style == omui.M3dView.kGouraudShaded ):
 
  190             glFT.glPushAttrib( v1omr.MGL_CURRENT_BIT )
 
  193             glFT.glDisable( v1omr.MGL_CULL_FACE )
 
  195             if status == omui.M3dView.kActive:
 
  196                 view.setDrawColor( 13, omui.M3dView.kActiveColors )
 
  198                 view.setDrawColor( 13, omui.M3dView.kDormantColors )
 
  200             glFT.glBegin( v1omr.MGL_TRIANGLE_FAN )
 
  201             for i 
in xrange(soleCount-1):
 
  202                 glFT.glVertex3f( sole[i][0] * multiplier, sole[i][1] * multiplier, sole[i][2] * multiplier )
 
  205             glFT.glBegin( v1omr.MGL_TRIANGLE_FAN )
 
  206             for i 
in xrange(heelCount-1):
 
  207                 glFT.glVertex3f( heel[i][0] * multiplier, heel[i][1] * multiplier, heel[i][2] * multiplier )
 
  214         glFT.glBegin( v1omr.MGL_LINES )
 
  215         for i 
in xrange(soleCount-1):
 
  216             glFT.glVertex3f( sole[i][0] * multiplier, sole[i][1] * multiplier, sole[i][2] * multiplier )
 
  217             glFT.glVertex3f( sole[i+1][0] * multiplier, sole[i+1][1] * multiplier, sole[i+1][2] * multiplier )
 
  219         for i 
in xrange(heelCount-1):
 
  220             glFT.glVertex3f( heel[i][0] * multiplier, heel[i][1] * multiplier, heel[i][2] * multiplier )
 
  221             glFT.glVertex3f( heel[i+1][0] * multiplier, heel[i+1][1] * multiplier, heel[i+1][2] * multiplier )
 
  229     def boundingBox(self):
 
  232         thisNode = self.thisMObject()
 
  233         plug = om.MPlug( thisNode, footPrint.size )
 
  234         sizeVal = plug.asMDistance()
 
  235         multiplier = sizeVal.asCentimeters()
 
  237         corner1 = om.MPoint( -0.17, 0.0, -0.7 )
 
  238         corner2 = om.MPoint( 0.17, 0.0, 0.3 )
 
  240         corner1 *= multiplier
 
  241         corner2 *= multiplier
 
  243         return om.MBoundingBox( corner1, corner2 )
 
  245     def getShapeSelectionMask(self):
 
  246         selType = om.MSelectionMask(
"footPrintSelection")
 
  247         return om.MSelectionMask( selType )
 
  255 class footPrintGeometryOverride(omr.MPxGeometryOverride):
 
  256     colorParameterName_ = 
"solidColor" 
  257     wireframeItemName_ = 
"footPrintLocatorWires" 
  258     shadedItemName_ = 
"footPrintLocatorTriangles" 
  262         return footPrintGeometryOverride(obj)
 
  264     def __init__(self, obj):
 
  265         omr.MPxGeometryOverride.__init__(self, obj)
 
  266         self.mLocatorNode = obj
 
  267         self.mMultiplier = 0.0
 
  268         self.mMultiplierChanged = 
True 
  273     def supportedDrawAPIs(self):
 
  275         return omr.MRenderer.kOpenGL | omr.MRenderer.kOpenGLCoreProfile | omr.MRenderer.kDirectX11
 
  277     def hasUIDrawables(self):
 
  281         plug = om.MPlug(self.mLocatorNode, footPrint.size)
 
  284             sizeVal = plug.asMDistance()
 
  285             newScale = sizeVal.asCentimeters()
 
  287         if newScale != self.mMultiplier:
 
  288             self.mMultiplier = newScale
 
  289             self.mMultiplierChanged = 
True 
  294     def isIndexingDirty(self, item):
 
  297     def isStreamDirty(self, desc):
 
  298         return self.mMultiplierChanged
 
  300     def updateRenderItems(self, dagPath, renderList ):
 
  301         shader = get3dSolidShader(omr.MGeometryUtilities.wireframeColor(dagPath))
 
  306             (footPrintGeometryOverride.wireframeItemName_, omr.MGeometry.kLines, omr.MGeometry.kWireframe),
 
  307             (footPrintGeometryOverride.shadedItemName_, omr.MGeometry.kTriangles, omr.MGeometry.kShaded)
 
  310         for itemName, geometryType, drawMode 
in fullItemList:
 
  312             index = renderList.indexOf(itemName)
 
  314                 renderItem = omr.MRenderItem.create(
 
  316                     omr.MRenderItem.DecorationItem,
 
  318                 renderItem.setDrawMode(drawMode)
 
  319                 renderItem.setDepthPriority(5)
 
  321                 renderList.append(renderItem)
 
  323                 renderItem = renderList[index]
 
  326                 renderItem.setShader(shader)
 
  327                 renderItem.enable(
True)
 
  329     def populateGeometry(self, requirements, renderItems, data):
 
  330         vertexBufferDescriptorList = requirements.vertexRequirements()
 
  332         for vertexBufferDescriptor 
in vertexBufferDescriptorList:
 
  333             if vertexBufferDescriptor.semantic == omr.MGeometry.kPosition:
 
  334                 verticesCount = soleCount+heelCount
 
  335                 verticesBuffer = data.createVertexBuffer(vertexBufferDescriptor)
 
  336                 verticesPositionDataAddress = verticesBuffer.acquire(verticesCount, 
True)
 
  337                 verticesPositionData = ((ctypes.c_float * 3)*verticesCount).from_address(verticesPositionDataAddress)   
 
  339                 verticesPointerOffset = 0
 
  343                 for vtxList 
in (heel, sole):
 
  345                         verticesPositionData[verticesPointerOffset][0] = vtx[0] * self.mMultiplier
 
  346                         verticesPositionData[verticesPointerOffset][1] = vtx[1] * self.mMultiplier
 
  347                         verticesPositionData[verticesPointerOffset][2] = vtx[2] * self.mMultiplier
 
  348                         verticesPointerOffset += 1
 
  350                 verticesBuffer.commit(verticesPositionDataAddress)
 
  354         for item 
in renderItems:
 
  358             indexBuffer = data.createIndexBuffer(omr.MGeometry.kUnsignedInt32)
 
  360             if item.name() == footPrintGeometryOverride.wireframeItemName_:
 
  364                 numPrimitive = heelCount + soleCount - 2
 
  365                 numIndex = numPrimitive * 2
 
  367                 indicesAddress = indexBuffer.acquire(numIndex, 
True)
 
  368                 indices = (ctypes.c_uint * numIndex).from_address(indicesAddress)
 
  374                     if i < (heelCount - 1) * 2:
 
  376                         primitiveIndex = i / 2
 
  378                         startIndex = heelCount
 
  379                         primitiveIndex = i / 2 - heelCount + 1
 
  381                     indices[i] = startIndex + primitiveIndex
 
  382                     indices[i+1] = startIndex + primitiveIndex + 1
 
  386                 indexBuffer.commit(indicesAddress)
 
  388             elif item.name() == footPrintGeometryOverride.shadedItemName_:
 
  391                 numPrimitive = heelCount + soleCount - 4
 
  392                 numIndex = numPrimitive * 3
 
  394                 indicesAddress = indexBuffer.acquire(numIndex, 
True)
 
  395                 indices = (ctypes.c_uint * numIndex).from_address(indicesAddress)
 
  401                     if i < (heelCount - 2) * 3:
 
  403                         primitiveIndex = i / 3
 
  405                         startIndex = heelCount
 
  406                         primitiveIndex = i / 3 - heelCount + 2
 
  408                     indices[i] = startIndex
 
  409                     indices[i+1] = startIndex + primitiveIndex + 1
 
  410                     indices[i+2] = startIndex + primitiveIndex + 2
 
  414                 indexBuffer.commit(indicesAddress)
 
  416             item.associateWithIndexBuffer(indexBuffer)
 
  418         mMultiplierChanged = 
False 
  420 def initializePlugin(obj):
 
  421     plugin = om.MFnPlugin(obj, 
"Autodesk", 
"3.0", 
"Any")
 
  424         plugin.registerNode(
"footPrint_GeometryOverride", footPrint.id, footPrint.creator, footPrint.initialize, om.MPxNode.kLocatorNode, footPrint.drawDbClassification)
 
  426         sys.stderr.write(
"Failed to register node\n")
 
  430         omr.MDrawRegistry.registerGeometryOverrideCreator(footPrint.drawDbClassification, footPrint.drawRegistrantId, footPrintGeometryOverride.creator)
 
  432         sys.stderr.write(
"Failed to register override\n")
 
  436         om.MSelectionMask.registerSelectionType(
"footPrintSelection")
 
  437         mel.eval(
"selectType -byName \"footPrintSelection\" 1")
 
  439         sys.stderr.write(
"Failed to register selection mask\n")
 
  442 def uninitializePlugin(obj):
 
  443     plugin = om.MFnPlugin(obj)
 
  446         plugin.deregisterNode(footPrint.id)
 
  448         sys.stderr.write(
"Failed to deregister node\n")
 
  452         omr.MDrawRegistry.deregisterGeometryOverrideCreator(footPrint.drawDbClassification, footPrint.drawRegistrantId)
 
  454         sys.stderr.write(
"Failed to deregister override\n")
 
  458         om.MSelectionMask.deregisterSelectionType(
"footPrintSelection") 
 
  460         sys.stderr.write(
"Failed to deregister selection mask\n")
 
  466         sys.stderr.write(
"Failed to release shaders\n")