1 from __future__
import division
12 from builtins
import object
13 from builtins
import range
16 import maya.api.OpenMaya
as om
17 import maya.api.OpenMayaUI
as omui
18 import maya.api.OpenMayaAnim
as oma
19 import maya.api.OpenMayaRender
as omr
23 The presence of this function tells Maya that the plugin produces, and
24 expects to be passed, objects created using the Maya Python API 2.0.
28 def matrixAsArray(matrix):
31 array.append(matrix[i])
36 sole = [ [ 0.00, 0.0, -0.70 ],
48 [ -0.15, 0.0, -0.14 ],
49 [ -0.16, 0.0, -0.25 ],
50 [ -0.17, 0.0, -0.35 ],
51 [ -0.17, 0.0, -0.46 ],
52 [ -0.16, 0.0, -0.54 ],
53 [ -0.13, 0.0, -0.61 ],
54 [ -0.09, 0.0, -0.65 ],
55 [ -0.04, 0.0, -0.69 ],
56 [ -0.00, 0.0, -0.70 ] ]
57 heel = [ [ 0.00, 0.0, 0.06 ],
73 [ -0.00, 0.0, 0.06 ] ]
83 class footPrint(omui.MPxLocatorNode):
84 id = om.MTypeId( 0x00080062 )
85 drawDbClassification =
"drawdb/geometry/footPrint"
86 drawRegistrantId =
"FootprintNodePlugin"
96 unitFn = om.MFnUnitAttribute()
98 footPrint.size = unitFn.create(
"size",
"sz", om.MFnUnitAttribute.kDistance )
99 unitFn.default = om.MDistance(1.0)
101 om.MPxNode.addAttribute( footPrint.size )
104 omui.MPxLocatorNode.__init__(self)
106 def compute(self, plug, data):
109 def draw(self, view, path, style, status):
112 thisNode = self.thisMObject()
113 plug = om.MPlug( thisNode, footPrint.size )
114 sizeVal = plug.asMDistance()
115 multiplier = sizeVal.asCentimeters()
117 global sole, soleCount
118 global heel, heelCount
123 import maya.OpenMayaRender
as v1omr
124 glRenderer = v1omr.MHardwareRenderer.theRenderer()
125 glFT = glRenderer.glFunctionTable()
127 if ( style == omui.M3dView.kFlatShaded )
or ( style == omui.M3dView.kGouraudShaded ):
130 glFT.glPushAttrib( v1omr.MGL_CURRENT_BIT )
133 glFT.glDisable( v1omr.MGL_CULL_FACE )
135 if status == omui.M3dView.kActive:
136 view.setDrawColor( 13, omui.M3dView.kActiveColors )
138 view.setDrawColor( 13, omui.M3dView.kDormantColors )
140 glFT.glBegin( v1omr.MGL_TRIANGLE_FAN )
141 for i
in range(soleCount-1):
142 glFT.glVertex3f( sole[i][0] * multiplier, sole[i][1] * multiplier, sole[i][2] * multiplier )
145 glFT.glBegin( v1omr.MGL_TRIANGLE_FAN )
146 for i
in range(heelCount-1):
147 glFT.glVertex3f( heel[i][0] * multiplier, heel[i][1] * multiplier, heel[i][2] * multiplier )
154 glFT.glBegin( v1omr.MGL_LINES )
155 for i
in range(soleCount-1):
156 glFT.glVertex3f( sole[i][0] * multiplier, sole[i][1] * multiplier, sole[i][2] * multiplier )
157 glFT.glVertex3f( sole[i+1][0] * multiplier, sole[i+1][1] * multiplier, sole[i+1][2] * multiplier )
159 for i
in range(heelCount-1):
160 glFT.glVertex3f( heel[i][0] * multiplier, heel[i][1] * multiplier, heel[i][2] * multiplier )
161 glFT.glVertex3f( heel[i+1][0] * multiplier, heel[i+1][1] * multiplier, heel[i+1][2] * multiplier )
167 view.setDrawColor( om.MColor( (0.1, 0.8, 0.8, 1.0) ) )
168 view.drawText(
"Footprint", om.MPoint( 0.0, 0.0, 0.0 ), omui.M3dView.kCenter )
173 def boundingBox(self):
176 thisNode = self.thisMObject()
177 plug = om.MPlug( thisNode, footPrint.size )
178 sizeVal = plug.asMDistance()
179 multiplier = sizeVal.asCentimeters()
181 corner1 = om.MPoint( -0.17, 0.0, -0.7 )
182 corner2 = om.MPoint( 0.17, 0.0, 0.3 )
184 corner1 *= multiplier
185 corner2 *= multiplier
187 return om.MBoundingBox( corner1, corner2 )
194 class footPrintData(om.MUserData):
196 om.MUserData.__init__(self,
False)
198 self.fMultiplier = 0.0
199 self.fColor = [0.0, 0.0, 0.0]
200 self.fCustomBoxDraw =
False
201 self.fDrawOV = om.MDAGDrawOverrideInfo()
204 class footPrintDrawAgent(object):
208 self.mBoundingboxVertexBuffer =
None
209 self.mBoundingboxIndexBuffer =
None
210 self.mSoleVertexBuffer =
None
211 self.mHeelVertexBuffer =
None
212 self.mSoleWireIndexBuffer =
None
213 self.mHeelWireIndexBuffer =
None
214 self.mSoleShadedIndexBuffer =
None
215 self.mHeelShadedIndexBuffer =
None
218 if self.mShader
is not None:
219 shaderMgr = omr.MRenderer.getShaderManager()
220 if shaderMgr
is not None:
221 shaderMgr.releaseShader(self.mShader)
224 self.mBoundingboxVertexBuffer =
None
225 self.mBoundingboxIndexBuffer =
None
226 self.mSoleVertexBuffer =
None
227 self.mHeelVertexBuffer =
None
228 self.mSoleWireIndexBuffer =
None
229 self.mHeelWireIndexBuffer =
None
230 self.mSoleShadedIndexBuffer =
None
231 self.mHeelShadedIndexBuffer =
None
233 def beginDraw(self, context, color, scale):
237 if self.mShader
is not None:
238 self.mShader.setParameter(
"matColor", color)
239 self.mShader.setParameter(
"scale", scale)
240 self.mShader.bind(context)
241 self.mShader.activatePass(context, 0)
243 def drawShaded(self, context):
244 global soleCount, heelCount
247 if self.mSoleVertexBuffer
is not None and self.mSoleShadedIndexBuffer
is not None:
248 omr.MRenderUtilities.drawSimpleMesh(context, self.mSoleVertexBuffer, self.mSoleShadedIndexBuffer, omr.MGeometry.kTriangles, 0, 3 * (soleCount-2))
251 if self.mHeelVertexBuffer
is not None and self.mHeelShadedIndexBuffer
is not None:
252 omr.MRenderUtilities.drawSimpleMesh(context, self.mHeelVertexBuffer, self.mHeelShadedIndexBuffer, omr.MGeometry.kTriangles, 0, 3 * (heelCount-2))
254 def drawBoundingBox(self, context):
255 if self.mBoundingboxVertexBuffer
is not None and self.mBoundingboxIndexBuffer
is not None:
256 omr.MRenderUtilities.drawSimpleMesh(context, self.mBoundingboxVertexBuffer, self.mBoundingboxIndexBuffer, omr.MGeometry.kLines, 0, 24)
258 def drawWireframe(self, context):
259 global soleCount, heelCount
262 if self.mSoleVertexBuffer
is not None and self.mSoleWireIndexBuffer
is not None:
263 omr.MRenderUtilities.drawSimpleMesh(context, self.mSoleVertexBuffer, self.mSoleWireIndexBuffer, omr.MGeometry.kLines, 0, 2 * (soleCount-1))
266 if self.mHeelVertexBuffer
is not None and self.mHeelWireIndexBuffer
is not None:
267 omr.MRenderUtilities.drawSimpleMesh(context, self.mHeelVertexBuffer, self.mHeelWireIndexBuffer, omr.MGeometry.kLines, 0, 2 * (heelCount-1))
269 def endDraw(self, context):
270 if self.mShader
is not None:
271 self.mShader.unbind(context)
273 def initShader(self):
274 if self.mShader
is None:
275 shaderMgr = omr.MRenderer.getShaderManager()
276 if shaderMgr
is not None:
277 shaderCode = self.getShaderCode()
278 self.mShader = shaderMgr.getEffectsBufferShader(shaderCode, len(shaderCode),
"")
280 return self.mShader
is not None
282 def shaderCode(self):
285 def initBuffers(self):
286 global soleCount, sole
287 global heelCount, heel
289 if self.mBoundingboxVertexBuffer
is None:
291 rawData = [ [ -0.5, -0.5, -0.5 ],
300 desc = omr.MVertexBufferDescriptor(
"", omr.MGeometry.kPosition, omr.MGeometry.kFloat, 3)
301 self.mBoundingboxVertexBuffer = omr.MVertexBuffer(desc)
303 dataAddress = self.mBoundingboxVertexBuffer.acquire(count,
True)
304 data = ((ctypes.c_float * 3)*count).from_address(dataAddress)
306 for i
in range(count):
307 data[i][0] = rawData[i][0]
308 data[i][1] = rawData[i][1]
309 data[i][2] = rawData[i][2]
311 self.mBoundingboxVertexBuffer.commit(dataAddress)
315 if self.mBoundingboxIndexBuffer
is None:
330 self.mBoundingboxIndexBuffer = omr.MIndexBuffer(omr.MGeometry.kUnsignedInt32)
332 dataAddress = self.mBoundingboxIndexBuffer.acquire(count,
True)
333 data = (ctypes.c_uint * count).from_address(dataAddress)
335 for i
in range(count):
338 self.mBoundingboxIndexBuffer.commit(dataAddress)
342 if self.mSoleVertexBuffer
is None:
343 desc = omr.MVertexBufferDescriptor(
"", omr.MGeometry.kPosition, omr.MGeometry.kFloat, 3)
344 self.mSoleVertexBuffer = omr.MVertexBuffer(desc)
346 dataAddress = self.mSoleVertexBuffer.acquire(soleCount,
True)
347 data = ((ctypes.c_float * 3)*soleCount).from_address(dataAddress)
349 for i
in range(soleCount):
350 data[i][0] = sole[i][0]
351 data[i][1] = sole[i][1]
352 data[i][2] = sole[i][2]
354 self.mSoleVertexBuffer.commit(dataAddress)
358 if self.mHeelVertexBuffer
is None:
359 desc = omr.MVertexBufferDescriptor(
"", omr.MGeometry.kPosition, omr.MGeometry.kFloat, 3)
360 self.mHeelVertexBuffer = omr.MVertexBuffer(desc)
362 dataAddress = self.mHeelVertexBuffer.acquire(heelCount,
True)
363 data = ((ctypes.c_float * 3)*heelCount).from_address(dataAddress)
365 for i
in range(heelCount):
366 data[i][0] = heel[i][0]
367 data[i][1] = heel[i][1]
368 data[i][2] = heel[i][2]
370 self.mHeelVertexBuffer.commit(dataAddress)
374 if self.mSoleWireIndexBuffer
is None:
375 count = 2 * (soleCount-1)
397 self.mSoleWireIndexBuffer = omr.MIndexBuffer(omr.MGeometry.kUnsignedInt32)
399 dataAddress = self.mSoleWireIndexBuffer.acquire(count,
True)
400 data = (ctypes.c_uint * count).from_address(dataAddress)
402 for i
in range(count):
405 self.mSoleWireIndexBuffer.commit(dataAddress)
409 if self.mHeelWireIndexBuffer
is None:
410 count = 2 * (heelCount-1)
428 self.mHeelWireIndexBuffer = omr.MIndexBuffer(omr.MGeometry.kUnsignedInt32)
430 dataAddress = self.mHeelWireIndexBuffer.acquire(count,
True)
431 data = (ctypes.c_uint * count).from_address(dataAddress)
433 for i
in range(count):
436 self.mHeelWireIndexBuffer.commit(dataAddress)
440 if self.mSoleShadedIndexBuffer
is None:
441 count = 3 * (soleCount-2)
462 self.mSoleShadedIndexBuffer = omr.MIndexBuffer(omr.MGeometry.kUnsignedInt32)
464 dataAddress = self.mSoleShadedIndexBuffer.acquire(count,
True)
465 data = (ctypes.c_uint * count).from_address(dataAddress)
467 for i
in range(count):
470 self.mSoleShadedIndexBuffer.commit(dataAddress)
474 if self.mHeelShadedIndexBuffer
is None:
475 count = 3 * (heelCount-2)
492 self.mHeelShadedIndexBuffer = omr.MIndexBuffer(omr.MGeometry.kUnsignedInt32)
494 dataAddress = self.mHeelShadedIndexBuffer.acquire(count,
True)
495 data = (ctypes.c_uint * count).from_address(dataAddress)
497 for i
in range(count):
500 self.mHeelShadedIndexBuffer.commit(dataAddress)
507 class footPrintDrawAgentGL(footPrintDrawAgent):
509 footPrintDrawAgent.__init__(self)
511 def getShaderCode(self):
513 float4x4 gWVXf : WorldView;
514 float4x4 gPXf : Projection;
515 float4 matColor = float4(0.8, 0.2, 0.0, 1.0);
519 float3 position : POSITION;
523 float4 position : POSITION;
526 vsOutput footPrintVS(appdata IN)
528 float4x4 scaleMat = float4x4(scale, 0, 0, 0,
532 float4x4 transform = mul(gPXf, mul(gWVXf, scaleMat));
535 OUT.position = mul(transform, float4(IN.position, 1));
539 float4 footPrintPS(vsOutput IN) : COLOR
548 VertexShader = compile glslv footPrintVS();
549 PixelShader = compile glslf footPrintPS();
556 class footPrintDrawAgentDX(footPrintDrawAgent):
558 footPrintDrawAgent.__init__(self)
560 def getShaderCode(self):
562 extern float4x4 gWVXf : WorldView;
563 extern float4x4 gPXf : Projection;
564 extern float4 matColor = float4(0.8, 0.2, 0.0, 1.0);
565 extern float scale = 1.0;
568 float3 position : POSITION;
572 float4 position : SV_Position;
575 vsOutput footPrintVS(appdata IN)
577 float4x4 scaleMat = float4x4(scale, 0, 0, 0,
581 float4x4 transform = mul(mul(scaleMat, gWVXf), gPXf);
584 OUT.position = mul(float4(IN.position, 1), transform);
588 float4 footPrintPS(vsOutput IN) : SV_Target
597 SetVertexShader( CompileShader( vs_5_0, footPrintVS() ));
598 SetGeometryShader( NULL );
599 SetPixelShader( CompileShader( ps_5_0, footPrintPS() ));
609 class footPrintDrawOverride(omr.MPxDrawOverride):
612 return footPrintDrawOverride(obj)
615 def draw(context, data):
618 if not isinstance(footData, footPrintData):
622 objectOverrideInfo = footData.fDrawOV
625 debugDestination =
False
627 destination = context.renderingDestination()
628 destinationType =
"3d viewport"
629 if destination[0] == omr.MFrameContext.k2dViewport:
630 destinationType =
"2d viewport"
631 elif destination[0] == omr.MFrameContext.kImage:
632 destinationType =
"image"
634 print(
"footprint node render destination is " + destinationType +
". Destination name=" + str(destination[1]))
637 if objectOverrideInfo.overrideEnabled
and not objectOverrideInfo.enableVisible:
641 displayStyle = context.getDisplayStyle()
642 drawAsBoundingbox = (displayStyle & omr.MFrameContext.kBoundingBox)
or (objectOverrideInfo.lod == om.MDAGDrawOverrideInfo.kLODBoundingBox)
648 if drawAsBoundingbox
and not footData.fCustomBoxDraw:
651 animPlay = oma.MAnimControl.isPlaying()
652 animScrub = oma.MAnimControl.isScrubbing()
654 if (animPlay
or animScrub)
and not objectOverrideInfo.playbackVisible:
659 if context.inUserInteraction()
or context.userChangingViewContext():
660 if not animPlay
and not animScrub:
661 drawAsBoundingbox =
True
669 passCtx = context.getPassContext()
670 passSemantics = passCtx.passSemantics()
671 castingShadows =
False
672 for semantic
in passSemantics:
673 if semantic == omr.MPassContext.kShadowPassSemantic:
674 castingShadows =
True
676 debugPassInformation =
False
677 if debugPassInformation:
678 passId = passCtx.passIdentifier()
679 print(
"footprint node drawing in pass[" + str(passId) +
"], semantic[" + str(passSemantics) +
"]")
682 multiplier = footData.fMultiplier
683 color = [ footData.fColor[0], footData.fColor[1], footData.fColor[2], 1.0 ]
685 requireBlending =
False
689 if not castingShadows:
692 if displayStyle & omr.MFrameContext.kDefaultMaterial:
693 color[0] = color[1] = color[2] = (color[0] + color[1] + color[2]) / 3.0
697 elif displayStyle & omr.MFrameContext.kXray:
698 requireBlending =
True
703 stateMgr = context.getStateManager()
705 oldRasterState =
None
706 rasterStateModified =
False
708 if stateMgr
is not None and (displayStyle & omr.MFrameContext.kGouraudShaded):
712 if blendState
is None:
713 desc = omr.MBlendStateDesc()
714 desc.targetBlends[0].blendEnable =
True
715 desc.targetBlends[0].destinationBlend = omr.MBlendStatekInvSourceAlpha
716 desc.targetBlends[0].alphaDestinationBlend = omr.MBlendStatekInvSourceAlpha
717 blendState = stateMgr.acquireBlendState(desc)
719 if blendState
is not None:
720 oldBlendState = stateMgr.getBlendState()
721 stateMgr.setBlendState(blendState)
725 oldRasterState = stateMgr.getRasterizerState()
727 desc = oldRasterState.desc()
730 cullMode = omr.MRasterizerState.kCullNone
731 if desc.cullMode != cullMode:
733 if rasterState
is None:
735 desc.cullMode = cullMode
736 rasterState = stateMgr.acquireRasterizerState(desc)
738 if rasterState
is not None:
739 rasterStateModified =
True
740 stateMgr.setRasterizerState(rasterState)
748 if drawAgent
is None:
749 if omr.MRenderer.drawAPIIsOpenGL():
750 drawAgent = footPrintDrawAgentGL()
752 drawAgent = footPrintDrawAgentDX()
754 if not drawAgent
is None:
756 drawAgent.beginDraw( context, color, multiplier )
758 if drawAsBoundingbox:
759 drawAgent.drawBoundingBox( context )
763 overideTemplated = objectOverrideInfo.overrideEnabled
and objectOverrideInfo.displayType == om.MDAGDrawOverrideInfo.kDisplayTypeTemplate
765 overrideNoShaded = objectOverrideInfo.overrideEnabled
and not objectOverrideInfo.enableShading
767 if overideTemplated
or overrideNoShaded:
768 drawAgent.drawWireframe( context )
771 if (displayStyle & omr.MFrameContext.kGouraudShaded)
or (displayStyle & omr.MFrameContext.kTextured):
772 drawAgent.drawShaded( context )
774 if (displayStyle & omr.MFrameContext.kWireFrame):
775 drawAgent.drawWireframe( context )
777 drawAgent.endDraw( context )
784 if stateMgr
is not None and (displayStyle & omr.MFrameContext.kGouraudShaded):
785 if oldBlendState
is not None:
786 stateMgr.setBlendState(oldBlendState)
788 if rasterStateModified
and oldRasterState
is not None:
789 stateMgr.setRasterizerState(oldRasterState)
791 def __init__(self, obj):
792 omr.MPxDrawOverride.__init__(self, obj, footPrintDrawOverride.draw)
797 self.mCustomBoxDraw =
True
798 self.mCurrentBoundingBox = om.MBoundingBox()
800 def supportedDrawAPIs(self):
802 return omr.MRenderer.kOpenGL | omr.MRenderer.kDirectX11
804 def isBounded(self, objPath, cameraPath):
807 def boundingBox(self, objPath, cameraPath):
808 corner1 = om.MPoint( -0.17, 0.0, -0.7 )
809 corner2 = om.MPoint( 0.17, 0.0, 0.3 )
811 multiplier = self.getMultiplier(objPath)
812 corner1 *= multiplier
813 corner2 *= multiplier
815 self.mCurrentBoundingBox.clear()
816 self.mCurrentBoundingBox.expand( corner1 )
817 self.mCurrentBoundingBox.expand( corner2 )
819 return self.mCurrentBoundingBox
821 def disableInternalBoundingBoxDraw(self):
822 return self.mCustomBoxDraw
824 def prepareForDraw(self, objPath, cameraPath, frameContext, oldData):
827 if not isinstance(data, footPrintData):
828 data = footPrintData()
831 data.fMultiplier = self.getMultiplier(objPath)
832 color = omr.MGeometryUtilities.wireframeColor(objPath)
833 data.fColor = [ color.r, color.g, color.b ]
834 data.fCustomBoxDraw = self.mCustomBoxDraw
837 data.fDrawOV = objPath.getDrawOverrideInfo()
841 def hasUIDrawables(self):
844 def addUIDrawables(self, objPath, drawManager, frameContext, data):
846 pos = om.MPoint( 0.0, 0.0, 0.0 )
847 textColor = om.MColor( (0.1, 0.8, 0.8, 1.0) )
849 drawManager.beginDrawable()
851 drawManager.setColor( textColor )
852 drawManager.setFontSize( omr.MUIDrawManager.kSmallFontSize )
853 drawManager.text(pos,
"Footprint", omr.MUIDrawManager.kCenter )
855 drawManager.endDrawable()
857 def getMultiplier(self, objPath):
859 footprintNode = objPath.node()
860 plug = om.MPlug(footprintNode, footPrint.size)
862 sizeVal = plug.asMDistance()
863 return sizeVal.asCentimeters()
867 def initializePlugin(obj):
868 plugin = om.MFnPlugin(obj,
"Autodesk",
"3.0",
"Any")
871 plugin.registerNode(
"footPrint", footPrint.id, footPrint.creator, footPrint.initialize, om.MPxNode.kLocatorNode, footPrint.drawDbClassification)
873 sys.stderr.write(
"Failed to register node\n")
877 omr.MDrawRegistry.registerDrawOverrideCreator(footPrint.drawDbClassification, footPrint.drawRegistrantId, footPrintDrawOverride.creator)
879 sys.stderr.write(
"Failed to register override\n")
882 def uninitializePlugin(obj):
883 plugin = om.MFnPlugin(obj)
886 plugin.deregisterNode(footPrint.id)
888 sys.stderr.write(
"Failed to deregister node\n")
892 omr.MDrawRegistry.deregisterDrawOverrideCreator(footPrint.drawDbClassification, footPrint.drawRegistrantId)
894 sys.stderr.write(
"Failed to deregister override\n")