8 from builtins
import range
10 import maya.api.OpenMayaRender
as omr
11 import maya.api.OpenMaya
as om
33 The presence of this function tells Maya that the plugin produces, and
34 expects to be passed, objects created using the Maya Python API 2.0.
39 class MyCustomPrimitiveGenerator(omr.MPxPrimitiveGenerator):
41 omr.MPxPrimitiveGenerator.__init__(self)
43 def computeIndexCount(self, object, component):
45 mesh = om.MFnMesh(object)
47 return mesh.numFaceVertices()
49 def generateIndexing(self, object, component, sourceIndexing, targetIndexing, indexBuffer):
51 mesh = om.MFnMesh(object)
53 for x
in range(0, len(targetIndexing)):
54 target = targetIndexing[x]
55 if target !=
None and target.componentType() == omr.MComponentDataIndexing.kFaceVertex:
57 (triCounts, triVertIDs) = mesh.getTriangleOffsets()
58 numTriVerts = len(triVertIDs)
60 customNumTriVerts = numTriVerts * 2
61 indexData = indexBuffer.acquire(customNumTriVerts,
True)
63 return omr.MGeometry.kInvalidPrimitive
65 sharedIndices = target.indices()
69 nextNewVertexIndex = 0
70 for idx
in range(0, len(sharedIndices)):
71 if sharedIndices[idx] > nextNewVertexIndex:
72 nextNewVertexIndex = sharedIndices[idx]
73 nextNewVertexIndex += 1
75 dataType = indexBuffer.dataType()
78 uintinc = sizeof(c_uint)
79 ushortinc = sizeof(c_ushort)
83 while triId < numTriVerts:
85 vertexId0 = sharedIndices[triVertIDs[triId]]
86 vertexId1 = sharedIndices[triVertIDs[triId+1]]
87 vertexId2 = sharedIndices[triVertIDs[triId+2]]
90 newVertexIndex = nextNewVertexIndex
91 nextNewVertexIndex += 1
94 if dataType == omr.MGeometry.kUnsignedInt32:
96 yaddr = address+uintinc
97 zaddr = address+2*uintinc
100 c_uint.from_address(xaddr).value = vertexId0
101 c_uint.from_address(yaddr).value = vertexId1
102 c_uint.from_address(zaddr).value = newVertexIndex
105 yaddr = address+uintinc
106 zaddr = address+2*uintinc
109 c_uint.from_address(xaddr).value = vertexId0
110 c_uint.from_address(yaddr).value = newVertexIndex
111 c_uint.from_address(zaddr).value = vertexId2
113 elif dataType == omr.MGeometry.kUnsignedChar:
115 yaddr = address+ushortinc
116 zaddr = address+2*ushortinc
117 address += 3*ushortinc
119 c_ushort.from_address(xaddr).value = vertexId0
120 c_ushort.from_address(yaddr).value = vertexId1
121 c_ushort.from_address(zaddr).value = newVertexIndex
124 yaddr = address+ushortinc
125 zaddr = address+2*ushortinc
126 address += 3*ushortinc
128 c_ushort.from_address(xaddr).value = vertexId0
129 c_ushort.from_address(yaddr).value = newVertexIndex
130 c_ushort.from_address(zaddr).value = vertexId2
132 indexBuffer.commit(indexData)
134 return (omr.MGeometry.kTriangles, 3)
135 return omr.MGeometry.kInvalidPrimitive
139 def createMyCustomPrimitiveGenerator():
140 return MyCustomPrimitiveGenerator()
145 class MyCustomPositionBufferGenerator(omr.MPxVertexBufferGenerator):
147 omr.MPxVertexBufferGenerator.__init__(self)
149 def getSourceIndexing(self, object, sourceIndexing):
151 mesh = om.MFnMesh(object)
153 (vertexCount, vertexList) = mesh.getVertices()
154 vertCount = len(vertexList)
156 vertices = sourceIndexing.indices()
157 vertices.setLength(vertCount)
159 for i
in range(0, vertCount):
160 vertices[i] = vertexList[i]
163 sourceIndexing.setComponentType(omr.MComponentDataIndexing.kFaceVertex)
167 def getSourceStreams(self, object, sourceStreams):
171 def createVertexStream(self, object, vertexBuffer, targetIndexing, sharedIndexing, sourceStreams):
174 descriptor = vertexBuffer.descriptor()
177 if descriptor.dataType != omr.MGeometry.kFloat:
181 dimension = descriptor.dimension
186 if descriptor.semantic != omr.MGeometry.kPosition:
191 mesh = om.MFnMesh(object)
193 indices = targetIndexing.indices()
195 vertexCount = len(indices)
202 (triCounts, triVertIDs) = mesh.getTriangleOffsets()
203 numTriVerts = len(triVertIDs)
205 sharedIndices = sharedIndexing.indices()
208 while triId < numTriVerts:
211 vertexId1 = sharedIndices[triVertIDs[triId+1]]
212 vertexId2 = sharedIndices[triVertIDs[triId+2]]
215 extraVertices.append( [vertexId1, vertexId2] )
217 newVertexCount = vertexCount + len(extraVertices)
218 customBuffer = vertexBuffer.acquire(newVertexCount,
True)
219 if customBuffer != 0:
221 address = customBuffer
222 floatinc = sizeof(c_float)
226 while vertId < vertexCount:
227 vertexId = indices[vertId]
229 point = mesh.getPoint(vertexId)
231 c_float.from_address(address + (vertId * dimension) * floatinc).value = point.x
232 c_float.from_address(address + (vertId * dimension + 1) * floatinc).value = point.y
233 c_float.from_address(address + (vertId * dimension + 2) * floatinc).value = point.z
238 for i
in range(0, len(extraVertices)):
239 vertexId1 = indices[extraVertices[i][0]]
240 vertexId2 = indices[extraVertices[i][1]]
242 point = mesh.getPoint(vertexId1)
243 point += mesh.getPoint(vertexId2)
246 c_float.from_address(address + (vertId * dimension) * floatinc).value = point.x
247 c_float.from_address(address + (vertId * dimension + 1) * floatinc).value = point.y
248 c_float.from_address(address + (vertId * dimension + 2) * floatinc).value = point.z
252 vertexBuffer.commit(customBuffer)
256 def createMyCustomPositionBufferGenerator():
257 return MyCustomPositionBufferGenerator()
262 class MyCustomNormalBufferGenerator(omr.MPxVertexBufferGenerator):
264 omr.MPxVertexBufferGenerator.__init__(self)
266 def getSourceIndexing(self, object, sourceIndexing):
268 mesh = om.MFnMesh(object)
270 (vertexCount, vertexList) = mesh.getVertices()
271 vertCount = len(vertexList)
273 vertices = sourceIndexing.indices()
274 vertices.setLength(vertCount)
276 for i
in range(0, vertCount):
277 vertices[i] = vertexList[i]
280 sourceIndexing.setComponentType(omr.MComponentDataIndexing.kFaceVertex)
284 def getSourceStreams(self, object, sourceStreams):
288 def createVertexStream(self, object, vertexBuffer, targetIndexing, sharedIndexing, sourceStreams):
291 descriptor = vertexBuffer.descriptor()
294 if descriptor.dataType != omr.MGeometry.kFloat:
298 dimension = descriptor.dimension
303 if descriptor.semantic != omr.MGeometry.kNormal:
308 mesh = om.MFnMesh(object)
310 indices = targetIndexing.indices()
312 vertexCount = len(indices)
319 (triCounts, triVertIDs) = mesh.getTriangleOffsets()
320 numTriVerts = len(triVertIDs)
322 sharedIndices = sharedIndexing.indices()
325 while triId < numTriVerts:
328 vertexId1 = sharedIndices[triVertIDs[triId+1]]
329 vertexId2 = sharedIndices[triVertIDs[triId+2]]
332 extraVertices.append( [vertexId1, vertexId2] )
334 newVertexCount = vertexCount + len(extraVertices)
335 customBuffer = vertexBuffer.acquire(newVertexCount,
True)
336 if customBuffer != 0:
338 address = customBuffer
339 floatinc = sizeof(c_float)
341 normals = mesh.getNormals()
345 while vertId < vertexCount:
346 vertexId = indices[vertId]
348 normal = normals[vertId]
350 c_float.from_address(address + (vertId * dimension) * floatinc).value = normal.x
351 c_float.from_address(address + (vertId * dimension + 1) * floatinc).value = normal.y
352 c_float.from_address(address + (vertId * dimension + 2) * floatinc).value = normal.z
357 for i
in range(0, len(extraVertices)):
358 vertexId1 = extraVertices[i][0]
359 vertexId2 = extraVertices[i][1]
361 normal = normals[vertexId1]
362 normal += normals[vertexId2]
365 c_float.from_address(address + (vertId * dimension) * floatinc).value = normal.x
366 c_float.from_address(address + (vertId * dimension + 1) * floatinc).value = normal.y
367 c_float.from_address(address + (vertId * dimension + 2) * floatinc).value = normal.z
371 vertexBuffer.commit(customBuffer)
375 def createMyCustomNormalBufferGenerator():
376 return MyCustomNormalBufferGenerator()
384 def initializePlugin(obj):
386 omr.MDrawRegistry.registerPrimitiveGenerator(
"customPrimitiveTest", createMyCustomPrimitiveGenerator)
388 omr.MDrawRegistry.registerVertexBufferGenerator(
"customPositionStream", createMyCustomPositionBufferGenerator)
390 omr.MDrawRegistry.registerVertexBufferGenerator(
"customNormalStream", createMyCustomNormalBufferGenerator)
392 def uninitializePlugin(obj):
394 omr.MDrawRegistry.deregisterPrimitiveGenerator(
"customPrimitiveTest")
396 omr.MDrawRegistry.deregisterVertexBufferGenerator(
"customPositionStream")
398 omr.MDrawRegistry.deregisterVertexBufferGenerator(
"customNormalStream")