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")