12 import maya.api.OpenMaya
as om
13 import maya.api.OpenMayaUI
as omui
14 import maya.api.OpenMayaRender
as omr
18 The presence of this function tells Maya that the plugin produces, and
19 expects to be passed, objects created using the Maya Python API 2.0.
24 class geometryReplicator(om.MPxSurfaceShape):
25 id = om.MTypeId(0x00080069)
26 drawDbClassification =
"drawdb/geometry/geometryReplicator_py"
27 drawRegistrantId =
"geometryReplicatorPlugin_py"
34 om.MPxSurfaceShape.__init__(self)
38 return geometryReplicator()
42 nAttr = om.MFnNumericAttribute()
44 geometryReplicator.aShowCPV = nAttr.create(
"showCPV",
"sc", om.MFnNumericData.kBoolean, 0)
45 om.MPxNode.addAttribute(geometryReplicator.aShowCPV)
47 geometryReplicator.aBaseMesh = nAttr.create(
"isBaseMesh",
"bm", om.MFnNumericData.kBoolean, 0)
48 om.MPxNode.addAttribute(geometryReplicator.aBaseMesh)
50 def postConstructor(self):
51 self.isRenderable =
True
56 def boundingBox(self):
57 corner1 = om.MPoint( -0.5, 0.0, -0.5 )
58 corner2 = om.MPoint( 0.5, 0.0, 0.5 )
60 return om.MBoundingBox( corner1, corner2 )
72 class geometryReplicatorShapeUI(omui.MPxSurfaceShapeUI):
74 omui.MPxSurfaceShapeUI.__init__(self)
78 return geometryReplicatorShapeUI()
89 class geometryReplicatorGeometryOverride(omr.MPxGeometryOverride):
90 def __init__(self, obj):
91 omr.MPxGeometryOverride.__init__(self, obj)
92 self.fThisNode = om.MObject(obj)
93 self.fType = om.MFn.kInvalid
94 self.fPath = om.MDagPath()
98 return geometryReplicatorGeometryOverride(obj)
100 def supportedDrawAPIs(self):
102 return (omr.MRenderer.kOpenGL | omr.MRenderer.kDirectX11)
104 def isCPVShown(self):
106 plug = om.MPlug(self.fThisNode, geometryReplicator.aShowCPV)
111 def isBaseMesh(self):
113 plug = om.MPlug(self.fThisNode, geometryReplicator.aBaseMesh)
118 def requiresUnsharedGeometricStreams(self, requirements):
125 descList = requirements.vertexRequirements()
126 for desc
in descList:
127 if desc.semantic == omr.MGeometry.kTexture
and desc.semanticName
in [
"vertexid",
"faceid",
"localuvcoord"]:
132 if not self.fPath.isValid():
133 fnThisNode = om.MFnDependencyNode(self.fThisNode)
135 messageAttr = fnThisNode.attribute(
"message")
136 messagePlug = om.MPlug(self.fThisNode, messageAttr)
138 connections = messagePlug.connectedTo(
False,
True)
139 for plug
in connections:
141 if node.hasFn(om.MFn.kMesh)
or node.hasFn(om.MFn.kNurbsSurface)
or node.hasFn(om.MFn.kNurbsCurve)
or node.hasFn(om.MFn.kBezierCurve):
142 path = om.MDagPath.getAPathTo(node)
144 self.fType = path.apiType()
147 def updateRenderItems(self, path, list):
148 if not self.fPath.isValid():
150 shaderManager = omr.MRenderer.getShaderManager()
151 if shaderManager
is None:
154 if self.fType == om.MFn.kNurbsCurve
or self.fType == om.MFn.kBezierCurve:
157 index = list.indexOf(
"geometryReplicatorCurve")
159 curveItem = omr.MRenderItem.create(
"geometryReplicatorCurve", omr.MRenderItem.NonMaterialSceneItem, omr.MGeometry.kLines)
160 curveItem.setDrawMode(omr.MGeometry.kAll)
161 list.append(curveItem)
163 shader = shaderManager.getStockShader(omr.MShaderManager.k3dSolidShader)
164 if shader
is not None:
165 theColor = [1.0, 0.0, 0.0, 1.0]
166 shader.setParameter(
"solidColor", theColor)
168 curveItem.setShader(shader)
169 shaderManager.releaseShader(shader)
172 curveItem = list[index]
174 if curveItem
is not None:
175 curveItem.enable(
True)
177 elif self.fType == om.MFn.kMesh:
180 index = list.indexOf(
"geometryReplicatorWireframe")
182 wireframeItem = omr.MRenderItem.create(
"geometryReplicatorWireframe", omr.MRenderItem.DecorationItem, omr.MGeometry.kLines)
183 wireframeItem.setDrawMode(omr.MGeometry.kWireframe)
184 wireframeItem.setDepthPriority(omr.MRenderItem.sActiveWireDepthPriority)
185 list.append(wireframeItem)
187 shader = shaderManager.getStockShader(omr.MShaderManager.k3dSolidShader)
188 if shader
is not None:
189 theColor = [1.0, 0.0, 0.0, 1.0]
190 shader.setParameter(
"solidColor", theColor)
192 wireframeItem.setShader(shader)
193 shaderManager.releaseShader(shader)
196 wireframeItem = list[index]
198 if wireframeItem
is not None:
199 wireframeItem.enable(
True)
202 showCPV = self.isCPVShown()
203 index = list.indexOf(
"StandardShadedItem", omr.MGeometry.kTriangles, omr.MGeometry.kShaded)
205 shadedItem = list[index]
206 if shadedItem
is not None:
207 shadedItem.enable(
not showCPV)
209 index = list.indexOf(
"StandardShadedItem", omr.MGeometry.kTriangles, omr.MGeometry.kTextured)
211 shadedItem = list[index]
212 if shadedItem
is not None:
213 shadedItem.enable(
not showCPV)
216 index = list.indexOf(
"geometryReplicatorCPV")
218 cpvItem = list[index]
219 if cpvItem
is not None:
220 cpvItem.enable(showCPV)
225 cpvItem = omr.MRenderItem.create(
"geometryReplicatorCPV", omr.MRenderItem.MaterialSceneItem, omr.MGeometry.kTriangles)
226 cpvItem.setDrawMode(omr.MGeometry.kShaded | omr.MGeometry.kTextured)
229 shader = shaderManager.getStockShader(omr.MShaderManager.k3dCPVSolidShader)
230 if shader
is not None:
231 cpvItem.setShader(shader)
233 shaderManager.releaseShader(shader)
235 def populateGeometry(self, requirements, renderItems, data):
236 if not self.fPath.isValid():
243 options = omr.MGeometryExtractor.kPolyGeom_Normal
244 if self.isBaseMesh():
245 options = options | omr.MGeometryExtractor.kPolyGeom_BaseMesh
246 if self.requiresUnsharedGeometricStreams(requirements):
247 options = options | omr.MGeometryExtractor.kPolyGeom_NotSharing
249 extractor = omr.MGeometryExtractor(requirements, self.fPath, options)
250 if extractor
is None:
254 descList = requirements.vertexRequirements()
255 for desc
in descList:
257 if desc.semantic == omr.MGeometry.kPosition
or desc.semantic == omr.MGeometry.kPosition
or desc.semantic == omr.MGeometry.kNormal
or desc.semantic == omr.MGeometry.kTexture
or desc.semantic == omr.MGeometry.kTangent
or desc.semantic == omr.MGeometry.kBitangent
or desc.semantic == omr.MGeometry.kColor:
258 vertexBuffer = data.createVertexBuffer(desc)
259 if vertexBuffer
is not None:
264 vertexCount = extractor.vertexCount()
265 vertices = vertexBuffer.acquire(vertexCount,
True)
266 if vertices
is not None:
267 extractor.populateVertexBuffer(vertices, vertexCount, desc)
268 vertexBuffer.commit(vertices)
271 for item
in renderItems:
272 indexBuffer = data.createIndexBuffer(omr.MGeometry.kUnsignedInt32)
273 if indexBuffer
is None:
280 if item.primitive() == omr.MGeometry.kTriangles:
281 triangleDesc = omr.MIndexBufferDescriptor(omr.MIndexBufferDescriptor.kTriangle,
"", omr.MGeometry.kTriangles, 3)
282 numTriangles = extractor.primitiveCount(triangleDesc)
284 indices = indexBuffer.acquire(3 * numTriangles,
True)
285 extractor.populateIndexBuffer(indices, numTriangles, triangleDesc)
286 indexBuffer.commit(indices)
288 elif item.primitive() == omr.MGeometry.kLines:
289 edgeDesc = omr.MIndexBufferDescriptor(omr.MIndexBufferDescriptor.kEdgeLine,
"", omr.MGeometry.kLines, 2)
290 numEdges = extractor.primitiveCount(edgeDesc)
292 indices = indexBuffer.acquire(2 * numEdges,
True)
293 extractor.populateIndexBuffer(indices, numEdges, edgeDesc)
294 indexBuffer.commit(indices)
296 item.associateWithIndexBuffer(indexBuffer)
309 def initializePlugin(obj):
310 plugin = om.MFnPlugin(obj,
"Autodesk",
"3.0",
"Any")
312 plugin.registerShape(
"geometryReplicator_py", geometryReplicator.id, geometryReplicator.creator, geometryReplicator.initialize, geometryReplicatorShapeUI.creator, geometryReplicator.drawDbClassification)
314 sys.stderr.write(
"Failed to register shape\n")
318 omr.MDrawRegistry.registerGeometryOverrideCreator(geometryReplicator.drawDbClassification, geometryReplicator.drawRegistrantId, geometryReplicatorGeometryOverride.creator)
320 sys.stderr.write(
"Failed to register override\n")
323 def uninitializePlugin(obj):
324 plugin = om.MFnPlugin(obj)
326 omr.MDrawRegistry.deregisterGeometryOverrideCreator(geometryReplicator.drawDbClassification, geometryReplicator.drawRegistrantId)
328 sys.stderr.write(
"Failed to deregister override\n")
332 plugin.deregisterNode(geometryReplicator.id)
334 sys.stderr.write(
"Failed to deregister shape\n")