9 import maya.api.OpenMayaRender 
as omr
 
   10 import maya.api.OpenMaya 
as om
 
   32     The presence of this function tells Maya that the plugin produces, and 
   33     expects to be passed, objects created using the Maya Python API 2.0. 
   38 class MyCustomPrimitiveGenerator(omr.MPxPrimitiveGenerator):
 
   40         omr.MPxPrimitiveGenerator.__init__(self)
 
   42     def computeIndexCount(self, object, component):
 
   44         mesh = om.MFnMesh(object)
 
   46         return mesh.numFaceVertices()
 
   48     def generateIndexing(self, object, component, sourceIndexing, targetIndexing, indexBuffer):
 
   50         mesh = om.MFnMesh(object)
 
   52         for x 
in range(0, len(targetIndexing)):
 
   53             target = targetIndexing[x]
 
   54             if target != 
None and target.componentType() == omr.MComponentDataIndexing.kFaceVertex:
 
   56                 (triCounts, triVertIDs) = mesh.getTriangleOffsets()
 
   57                 numTriVerts = len(triVertIDs)
 
   59                 customNumTriVerts = numTriVerts * 2
 
   60                 indexData = indexBuffer.acquire(customNumTriVerts, 
True)  
 
   62                     return omr.MGeometry.kInvalidPrimitive
 
   64                 sharedIndices = target.indices()
 
   68                 nextNewVertexIndex = 0
 
   69                 for idx 
in range(0, len(sharedIndices)):
 
   70                     if sharedIndices[idx] > nextNewVertexIndex:
 
   71                         nextNewVertexIndex = sharedIndices[idx]
 
   72                 nextNewVertexIndex += 1
 
   74                 dataType = indexBuffer.dataType()
 
   77                 uintinc = sizeof(c_uint)
 
   78                 ushortinc = sizeof(c_ushort)
 
   82                 while triId < numTriVerts:
 
   84                     vertexId0 = sharedIndices[triVertIDs[triId]]
 
   85                     vertexId1 = sharedIndices[triVertIDs[triId+1]]
 
   86                     vertexId2 = sharedIndices[triVertIDs[triId+2]]
 
   89                     newVertexIndex = nextNewVertexIndex
 
   90                     nextNewVertexIndex += 1
 
   93                     if dataType == omr.MGeometry.kUnsignedInt32:
 
   95                         yaddr = address+uintinc
 
   96                         zaddr = address+2*uintinc
 
   99                         c_uint.from_address(xaddr).value = vertexId0
 
  100                         c_uint.from_address(yaddr).value = vertexId1
 
  101                         c_uint.from_address(zaddr).value = newVertexIndex
 
  104                         yaddr = address+uintinc
 
  105                         zaddr = address+2*uintinc
 
  108                         c_uint.from_address(xaddr).value = vertexId0
 
  109                         c_uint.from_address(yaddr).value = newVertexIndex
 
  110                         c_uint.from_address(zaddr).value = vertexId2
 
  112                     elif dataType == omr.MGeometry.kUnsignedChar:
 
  114                         yaddr = address+ushortinc
 
  115                         zaddr = address+2*ushortinc
 
  116                         address += 3*ushortinc
 
  118                         c_ushort.from_address(xaddr).value = vertexId0
 
  119                         c_ushort.from_address(yaddr).value = vertexId1
 
  120                         c_ushort.from_address(zaddr).value = newVertexIndex
 
  123                         yaddr = address+ushortinc
 
  124                         zaddr = address+2*ushortinc
 
  125                         address += 3*ushortinc
 
  127                         c_ushort.from_address(xaddr).value = vertexId0
 
  128                         c_ushort.from_address(yaddr).value = newVertexIndex
 
  129                         c_ushort.from_address(zaddr).value = vertexId2
 
  131                 indexBuffer.commit(indexData)
 
  133                 return (omr.MGeometry.kTriangles, 3)
 
  134         return omr.MGeometry.kInvalidPrimitive
 
  138 def createMyCustomPrimitiveGenerator():
 
  139     return MyCustomPrimitiveGenerator()
 
  144 class MyCustomPositionBufferGenerator(omr.MPxVertexBufferGenerator):
 
  146         omr.MPxVertexBufferGenerator.__init__(self)
 
  148     def getSourceIndexing(self, object, sourceIndexing):
 
  150         mesh = om.MFnMesh(object)
 
  152         (vertexCount, vertexList) = mesh.getVertices()
 
  153         vertCount = len(vertexList)
 
  155         vertices = sourceIndexing.indices()
 
  156         vertices.setLength(vertCount)
 
  158         for i 
in range(0, vertCount):
 
  159             vertices[i] = vertexList[i]
 
  162         sourceIndexing.setComponentType(omr.MComponentDataIndexing.kFaceVertex)
 
  166     def getSourceStreams(self, object, sourceStreams):
 
  170     def createVertexStream(self, object, vertexBuffer, targetIndexing, sharedIndexing, sourceStreams):
 
  173         descriptor = vertexBuffer.descriptor()
 
  176         if descriptor.dataType != omr.MGeometry.kFloat:
 
  180         dimension = descriptor.dimension
 
  185         if descriptor.semantic != omr.MGeometry.kPosition:
 
  190         mesh = om.MFnMesh(object)
 
  192         indices = targetIndexing.indices()
 
  194         vertexCount = len(indices)
 
  201         (triCounts, triVertIDs) = mesh.getTriangleOffsets()
 
  202         numTriVerts = len(triVertIDs)
 
  204         sharedIndices = sharedIndexing.indices()
 
  207         while triId < numTriVerts:
 
  210             vertexId1 = sharedIndices[triVertIDs[triId+1]]
 
  211             vertexId2 = sharedIndices[triVertIDs[triId+2]]
 
  214             extraVertices.append( [vertexId1, vertexId2] )
 
  216         newVertexCount = vertexCount + len(extraVertices)
 
  217         customBuffer = vertexBuffer.acquire(newVertexCount, 
True)   
 
  218         if customBuffer != 0:
 
  220             address = customBuffer
 
  221             floatinc = sizeof(c_float)
 
  225             while vertId < vertexCount:
 
  226                 vertexId = indices[vertId]
 
  228                 point = mesh.getPoint(vertexId)
 
  230                 c_float.from_address(address + (vertId * dimension) * floatinc).value = point.x
 
  231                 c_float.from_address(address + (vertId * dimension + 1) * floatinc).value = point.y
 
  232                 c_float.from_address(address + (vertId * dimension + 2) * floatinc).value = point.z
 
  237             for i 
in range(0, len(extraVertices)):
 
  238                 vertexId1 = indices[extraVertices[i][0]]
 
  239                 vertexId2 = indices[extraVertices[i][1]]
 
  241                 point = mesh.getPoint(vertexId1)
 
  242                 point += mesh.getPoint(vertexId2)
 
  245                 c_float.from_address(address + (vertId * dimension) * floatinc).value = point.x
 
  246                 c_float.from_address(address + (vertId * dimension + 1) * floatinc).value = point.y
 
  247                 c_float.from_address(address + (vertId * dimension + 2) * floatinc).value = point.z
 
  251             vertexBuffer.commit(customBuffer)
 
  255 def createMyCustomPositionBufferGenerator():
 
  256     return MyCustomPositionBufferGenerator()
 
  261 class MyCustomNormalBufferGenerator(omr.MPxVertexBufferGenerator):
 
  263         omr.MPxVertexBufferGenerator.__init__(self)
 
  265     def getSourceIndexing(self, object, sourceIndexing):
 
  267         mesh = om.MFnMesh(object)
 
  269         (vertexCount, vertexList) = mesh.getVertices()
 
  270         vertCount = len(vertexList)
 
  272         vertices = sourceIndexing.indices()
 
  273         vertices.setLength(vertCount)
 
  275         for i 
in range(0, vertCount):
 
  276             vertices[i] = vertexList[i]
 
  279         sourceIndexing.setComponentType(omr.MComponentDataIndexing.kFaceVertex)
 
  283     def getSourceStreams(self, object, sourceStreams):
 
  287     def createVertexStream(self, object, vertexBuffer, targetIndexing, sharedIndexing, sourceStreams):
 
  290         descriptor = vertexBuffer.descriptor()
 
  293         if descriptor.dataType != omr.MGeometry.kFloat:
 
  297         dimension = descriptor.dimension
 
  302         if descriptor.semantic != omr.MGeometry.kNormal:
 
  307         mesh = om.MFnMesh(object)
 
  309         indices = targetIndexing.indices()
 
  311         vertexCount = len(indices)
 
  318         (triCounts, triVertIDs) = mesh.getTriangleOffsets()
 
  319         numTriVerts = len(triVertIDs)
 
  321         sharedIndices = sharedIndexing.indices()
 
  324         while triId < numTriVerts:
 
  327             vertexId1 = sharedIndices[triVertIDs[triId+1]]
 
  328             vertexId2 = sharedIndices[triVertIDs[triId+2]]
 
  331             extraVertices.append( [vertexId1, vertexId2] )
 
  333         newVertexCount = vertexCount + len(extraVertices)
 
  334         customBuffer = vertexBuffer.acquire(newVertexCount, 
True)   
 
  335         if customBuffer != 0:
 
  337             address = customBuffer
 
  338             floatinc = sizeof(c_float)
 
  340             normals = mesh.getNormals()
 
  344             while vertId < vertexCount:
 
  345                 vertexId = indices[vertId]
 
  347                 normal = normals[vertId]
 
  349                 c_float.from_address(address + (vertId * dimension) * floatinc).value = normal.x
 
  350                 c_float.from_address(address + (vertId * dimension + 1) * floatinc).value = normal.y
 
  351                 c_float.from_address(address + (vertId * dimension + 2) * floatinc).value = normal.z
 
  356             for i 
in range(0, len(extraVertices)):
 
  357                 vertexId1 = extraVertices[i][0]
 
  358                 vertexId2 = extraVertices[i][1]
 
  360                 normal = normals[vertexId1]
 
  361                 normal += normals[vertexId2]
 
  364                 c_float.from_address(address + (vertId * dimension) * floatinc).value = normal.x
 
  365                 c_float.from_address(address + (vertId * dimension + 1) * floatinc).value = normal.y
 
  366                 c_float.from_address(address + (vertId * dimension + 2) * floatinc).value = normal.z
 
  370             vertexBuffer.commit(customBuffer)
 
  374 def createMyCustomNormalBufferGenerator():
 
  375     return MyCustomNormalBufferGenerator()
 
  383 def initializePlugin(obj):
 
  385     omr.MDrawRegistry.registerPrimitiveGenerator(
"customPrimitiveTest", createMyCustomPrimitiveGenerator)
 
  387     omr.MDrawRegistry.registerVertexBufferGenerator(
"customPositionStream", createMyCustomPositionBufferGenerator)
 
  389     omr.MDrawRegistry.registerVertexBufferGenerator(
"customNormalStream", createMyCustomNormalBufferGenerator)
 
  391 def uninitializePlugin(obj):
 
  393     omr.MDrawRegistry.deregisterPrimitiveGenerator(
"customPrimitiveTest")
 
  395     omr.MDrawRegistry.deregisterVertexBufferGenerator(
"customPositionStream")
 
  397     omr.MDrawRegistry.deregisterVertexBufferGenerator(
"customNormalStream")