Python API 2.0 Reference
scripted/pyPanelCanvas.py
1 import maya.api.OpenMaya as om
2 import maya.api.OpenMayaAnim as oma
3 import maya.api.OpenMayaUI as omui
4 import maya.api.OpenMayaRender as omr
5 import maya.mel as mel
6 import maya.cmds as cmds
7 
8 ##############################################################################
9 # #
10 # Primitive drawings with MUIDrawManager using callbacks #
11 # #
12 ##############################################################################
13 
14 # Define a function that draws an icon
15 #
16 def iconFunc( drawMgr, userData ):
17  drawMgr.beginDrawable()
18 
19  path = mel.eval('getenv("MAYA_LOCATION")') + "/icons/mayaico.png"
20  drawMgr.icon( om.MPoint(0.0, 0.0, 3.0), path, 3.14 )
21 
22  drawMgr.endDrawable()
23 
24 # Define a function that draws text primitives in various alignments and sizes
25 #
26 def textFunc( drawMgr, userData ):
27  drawMgr.beginDrawable()
28 
29  drawMgr.text( om.MPoint(200.1, 200.2, 0.3), "left", omr.MUIDrawManager.kLeft, [200,200])
30  drawMgr.setColor( om.MColor( (1.0, 0.0, 0.0, 1.0) ) )
31  drawMgr.text( om.MPoint(200.1, 150.2, 0.3), "center", omr.MUIDrawManager.kCenter, [200,200])
32  drawMgr.setColor( om.MColor( (0.0, 1.0, 0.0, 1.0) ) )
33  drawMgr.text( om.MPoint(200.1, 200.2, 0.3), "right", omr.MUIDrawManager.kRight, [200,200])
34 
35  # Specify a background color
36  #
37  drawMgr.setFontSize( omr.MUIDrawManager.kSmallFontSize )
38  drawMgr.setColor( om.MColor( (0.0, 0.0, 1.0, 1.0) ) )
39  drawMgr.text( om.MPoint(700.1, 50.2, 0.3), "small", omr.MUIDrawManager.kLeft, [200,200], om.MColor((0., 1., 1., 1.)), False )
40 
41  drawMgr.endDrawable()
42 
43 
44 # Define a function that draws an outline of a rectangle, and a solid rectangle
45 #
46 def rectFunc( drawMgr, userData ):
47  drawMgr.beginDrawable()
48 
49  drawMgr.setColor( om.MColor( (1.0, 0.0, 1.0, 1.0) ) )
50  drawMgr.rect2d( om.MPoint(50, 150, 0.3), om.MVector(0.0,1.0,0.0), 100, 300, False )
51 
52  drawMgr.setColor( om.MColor( (0.0, 1.0, 1.0, 1.0) ) )
53  drawMgr.rect2d( om.MPoint(450.1, 500.2, 0.3), om.MVector(-0.5,0.866025,0.0), 100, 300, True )
54 
55  drawMgr.endDrawable()
56 
57 # Define a function that draws an arc, and a pie wedge (filled arc)
58 #
59 def arcFunc( drawMgr, userData ):
60  drawMgr.beginDrawable()
61 
62  drawMgr.setColor( om.MColor( (1.0, 1.0, 1.0, 1.0) ) )
63  drawMgr.arc2d( om.MPoint(750.1, 500.2, 0.3), om.MVector(0.866025, 0.5, 0.0), om.MVector(-0.5,0.866025,0.0), 100, False )
64 
65  drawMgr.setColor( om.MColor( (1.0, 1.0, 0.5, 1.0) ) )
66  drawMgr.arc2d( om.MPoint(750.1, 500.2, 0.3), om.MVector(-0.866025, -0.5, 0.0), om.MVector(0.5,-0.866025,0.0), 100, True )
67 
68  drawMgr.endDrawable()
69 
70 
71 # Define a function that draws the outline of a circle, and a solid circle
72 #
73 def circleFunc( drawMgr, userData ):
74  drawMgr.beginDrawable()
75 
76  drawMgr.setColor( om.MColor( (0.5, 1.0, 1.0, 1.0) ) )
77  drawMgr.circle2d( om.MPoint(500.1, 200.2, 0.3), 75, False )
78  drawMgr.setColor( om.MColor( (0.5, 1.0, 0.5, 1.0) ) )
79  drawMgr.circle2d( om.MPoint(675.1, 675.2, 0.3), 50, True )
80 
81  drawMgr.endDrawable()
82 
83 
84 def otherFunc( drawMgr, userData ):
85  # This callback doesn't actually draw anything, for testing purposes
86  pass
87 
88 def createScene():
89 
90  # Create an animated cylinder, and set a time range of [0,30]
91  #
92  cmds.file(force=1,new=1)
93  myCyl = cmds.polyCylinder()
94  cmds.setAttr( "pCylinder1.s",1, 3.3522764559816802, 1, type="double3" )
95 
96  cmds.playbackOptions(min=0, ast=0, max=30, aet=30)
97  cmds.currentTime( 0 )
98  cmds.setAttr( 'pCylinder1.tz', 12 )
99  cmds.setAttr( 'pCylinder1.rx', 30 )
100  cmds.setKeyframe( ['pCylinder1.tz','pCylinder1.rx'])
101 
102  cmds.currentTime(15)
103  cmds.setAttr( 'pCylinder1.tz', 0 )
104  cmds.setAttr( 'pCylinder1.rx', 0 )
105  cmds.setKeyframe( ['pCylinder1.tz','pCylinder1.rx'])
106 
107  cmds.currentTime(30)
108  cmds.setAttr( 'pCylinder1.tz', -12 )
109  cmds.setAttr( 'pCylinder1.rx', -30 )
110  cmds.setKeyframe( ['pCylinder1.tz','pCylinder1.rx'])
111 
112 def createGraphEditor():
113  # Create a Graph Editor for testing purposes
114  #
115  geName = 'myGraphEditorGraphEd';
116  if( cmds.scriptedPanel('myGraphEditor', exists=1) ):
117  cmds.deleteUI('myGraphEditor')
118 
119  geWindow = cmds.window(width=1200,height=800)
120  gePane = cmds.paneLayout(parent=geWindow)
121  cmds.scriptedPanel('myGraphEditor',type='graphEditor', parent=gePane,tearOff=False)
122  cmds.setParent('..')
123  cmds.showWindow(geWindow)
124  return [geName, geWindow]
125 
126 def maya_useNewAPI():
127  pass
128 
129 def initializePlugin( mobject ):
130  """
131  Description:
132  this method is called when the plug-in is loaded into Maya. It
133  registers all of the services that this plug-in provides with
134  Maya.
135 
136  Arguments:
137  mobject - a handle to the plug-in object (use MFnPlugin to access it)
138  """
139  createScene()
140  [geName, geWindow] = createGraphEditor()
141  geCanvas = omui.MPanelCanvas(geName)
142  global myCanvas
143  myCanvas = [geCanvas, geName, geWindow]
144  geCanvas.setAutoRefresh( False )
145 
146  # Note the reserved Graph Editor layers are as follows:
147  #
148  # MPanelCanvas.kGraphEditorBackground - 0
149  # MPanelCanvas.kGraphEditorGrid - 100
150  # MPanelCanvas.kGraphEditorAxisLabels - 1000
151  # MPanelCanvas.kGraphEditorCurves - 2000
152  # MPanelCanvas.kGraphEditorCurveNames - 3000
153  # MPanelCanvas.kGraphEditorTimeMarker - 4000
154  # MPanelCanvas.kGraphEditorRetimeToolText - 5000
155  # MPanelCanvas.kGraphEditorLastDefaultDraw - 10000
156  #
157  # To draw between, say, the Grid and the Axis labels, use a layer number
158  # greater than 100 but less than 1000.
159 
160  ##########################################################################
161  # #
162  # Screen space primitives #
163  # #
164  # (0,0) is the bottom left coordinate of the screen #
165  # (pixel width, pixel height) is the top right coordinate of the screen #
166  # #
167  ##########################################################################
168 
169  # Create 8 solid diamonds in screen space, of various colours, in various
170  # layers.
171  #
172  # The diamonds are drawn in between each reserved layer as follows:
173  #
174  layers = [ omui.MPanelCanvas.kGraphEditorBackground+55
175  , omui.MPanelCanvas.kGraphEditorGrid+55
176  , omui.MPanelCanvas.kGraphEditorAxisLabels+55
177  , omui.MPanelCanvas.kGraphEditorCurves+55
178  , omui.MPanelCanvas.kGraphEditorCurveNames+55
179  , omui.MPanelCanvas.kGraphEditorTimeMarker+55
180  , omui.MPanelCanvas.kGraphEditorTimeMarker+55
181  , omui.MPanelCanvas.kGraphEditorRetimeToolText+55
182  ]
183 
184  props = omui.MDrawProperties()
185  props.color = om.MColor( [0.2, 0.8, 0.6])
186  props.lineWidth = 0.5
187  props.lineStyle = omr.MUIDrawManager.kDotted
188  props.pointSize = 12.0
189 
190  # Half diagonals of each diamond
191  #
192  half_diags = [300-30*n for n in range(0,8)]
193 
194  # Color multipliers for each diamond
195  #
196  reds = [1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0]
197  greens = [0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0]
198  blues = [0.0, 0.0, 1.0, 1.0, 0.25, 0.25, 0.75, 0.75]
199 
200  # Each diamond consists of 6 points 3 for each triangle
201  # Define the start point of each diamond
202  #
203  starts = [6*n for n in range(0,8)]
204 
205  # Each diamond is centered at (330, 330)
206  #
207  cx = 330
208  cy = 330
209 
210  # Create a float vertex buffer to define the 8 diamonds
211  #
212  xArray = []
213  yArray = []
214  cArray = []
215 
216  a = 1.0
217  for r,g,b,h in zip(reds, greens, blues, half_diags):
218  xArray += [cx-h, cx, cx+h, cx+h, cx, cx-h]
219  yArray += [cy, cy-h, cy, cy, cy+h, cy]
220  cArray += [ [r*.25, g*.25, b, a], [r*.50, g*.50, b, a], [r*.75, g*.75, b, a], [r*.75, g*.75, b, a], [r, g, b, a], [r*.25, g*.25, b, a]]
221 
222  floatId = geCanvas.createFloatVertexBuffer( xArray, yArray, cArray )
223 
224  # Define the 8 diamonds, and add to a specific layer
225  #
226  for s,l in zip(starts, layers):
227  p = geCanvas.createPrimitive( omr.MGeometry.kTriangles, floatId, s, 6, props )
228  geCanvas.addPrimitive( p, l )
229 
230  # Create six line drawing of squares, using the various stippling patterns:
231  #
232  # kDotted, kShortDotted, kDashed, kShortDashed, kSolid, kSolid
233  #
234  layers = [ omui.MPanelCanvas.kGraphEditorCurves+55
235  , omui.MPanelCanvas.kGraphEditorCurves+55
236  , omui.MPanelCanvas.kGraphEditorAxisLabels+55
237  , omui.MPanelCanvas.kGraphEditorAxisLabels+55
238  , omui.MPanelCanvas.kGraphEditorCurveNames+55
239  , omui.MPanelCanvas.kGraphEditorTimeMarker+55
240  ]
241  patterns = [omr.MUIDrawManager.kDotted, omr.MUIDrawManager.kShortDotted, omr.MUIDrawManager.kDashed, omr.MUIDrawManager.kShortDashed, omr.MUIDrawManager.kSolid, omr.MUIDrawManager.kDotted]
242 
243  # Half sides of each square
244  #
245  half_sides = half_diags = [300-30*n for n in range(0,6)]
246 
247  # Color multipliers for each square
248  #
249  reds = [1.0, 0.0, 1.0, 0.0, 1.0, 0.0]
250  greens = [0.0, 1.0, 0.0, 1.0, 0.0, 1.0]
251  blues = [0.5, 0.5, 1.0, 1.0, 0.25, 0.25]
252 
253  # Each square consists of 5 points (4 line segments)
254  # Define the start point of each square
255  #
256  starts = [5*n for n in range(0,6)]
257 
258  # Each square is centered at (510, 510)
259  #
260  cx = 510
261  cy = 510
262 
263  xArray = []
264  yArray = []
265  cArray = []
266 
267  a = 1.0
268  for r,g,b,h in zip(reds, greens, blues, half_sides):
269  xArray += [cx-h, cx+h, cx+h, cx-h, cx-h]
270  yArray += [cy-h, cy-h, cy+h, cy+h, cy-h]
271  cArray += [ [r*.40, g*.40, b, a], [r*.50, g*.50, b, a], [r*.60, g*.60, b, a], [r*.75, g*.75, b, a], [r, g, b, a]]
272 
273  floatId = geCanvas.createFloatVertexBuffer( xArray, yArray, cArray )
274 
275  # Define the 6 squares, and add to a specific layer
276  #
277  for s,l,p in zip(starts, layers, patterns):
278  props.lineStyle = p
279  id = geCanvas.createPrimitive( omr.MGeometry.kLineStrip, floatId, s, 5, props )
280  geCanvas.addPrimitive( id, l )
281 
282 
283  ##########################################################################
284  # #
285  # Time based primitives #
286  # #
287  # The x-axis values are time (frames) #
288  # The y-values are as displayed in the Normal Graph Editor View #
289  # #
290  ##########################################################################
291 
292  # Draw 4 time based diamonds, in various layers
293  #
294  # The time based ranges of the diamonds are:
295  # [0,12], [1,11], [12,20], [13,20]
296  #
297  # The y based ranges of the diamonds are:
298  # [-40,+40], [-36,+36], [-20,+20], [-18,+18]
299  #
300 
301  layers = [ omui.MPanelCanvas.kGraphEditorAxisLabels+55
302  , omui.MPanelCanvas.kGraphEditorCurves+55
303  , omui.MPanelCanvas.kGraphEditorCurveNames+55
304  , omui.MPanelCanvas.kGraphEditorTimeMarker+55
305  ]
306 
307  props = omui.MDrawProperties()
308  props.color = om.MColor( [0.2, 0.8, 0.6])
309  props.lineWidth = 0.5
310  props.lineStyle = omr.MUIDrawManager.kDotted
311  props.pointSize = 12.0
312 
313  # Half diagonals of each diamond
314  #
315  half_diags_t = [6-n for n in range(0,4)]
316  half_diags_y = [40, 36, 20, 18]
317 
318  # Color multipliers for each diamond
319  #
320  reds = [1.0, 0.0, 1.0, 0.0]
321  greens = [0.0, 1.0, 0.0, 1.0]
322  blues = [0.25, 0.25, 0.75, 0.75]
323 
324  # Each diamond consists of 6 points 3 for each triangle
325  # Define the start point of each diamond
326  #
327  starts = [6*n for n in range(0,4)]
328 
329  # First 2 diamonds are centered at (6, 0), other 2 at (16, 0)
330  #
331  cxArray = [6, 6, 16, 16]
332 
333  # Create a time vertex buffer to define the 4 diamonds
334  #
335  tArray = []
336  yArray = []
337  cArray = []
338 
339  a = 1.0
340  for cx, r,g,b,ht, hy in zip(cxArray, reds, greens, blues, half_diags_t, half_diags_y):
341  tArray += [om.MTime(t) for t in [cx-ht, cx, cx+ht, cx+ht, cx, cx-ht]]
342  yArray += [0, -hy, 0, 0, hy, 0]
343  cArray += [ [r*.25, g*.25, b, a], [r*.50, g*.50, b, a], [r*.75, g*.75, b, a], [r*.75, g*.75, b, a], [r, g, b, a], [r*.25, g*.25, b, a]]
344 
345  timeId = geCanvas.createTimeVertexBuffer( tArray, yArray, cArray )
346 
347  # Define the 4 diamonds, and add to a specific layer
348  #
349  for s,l in zip(starts, layers):
350  p = geCanvas.createPrimitive( omr.MGeometry.kTriangles, timeId, s, 6, props )
351  geCanvas.addPrimitive( p, l )
352 
353  # Draw a time based box, from frame 0 to frame 30, and from -30 to +30 in y
354  # If the scene twoCurves.ma is loaded, the box should frame the two curves.
355  # If you drag the time line, the box moves accordingly, and always frames
356  # the two curves.
357  #
358 
359  tArray = [om.MTime(t) for t in [0,30,30,0,0]]
360  yArray = [30,30,-30,-30,30]
361  cArray = [[r*.2,1.0,1.0,1.0] for r in range(1,6)]
362 
363  timeId = geCanvas.createTimeVertexBuffer( tArray, yArray, cArray )
364 
365  props = omui.MDrawProperties()
366  props.color = om.MColor( [0.2, 0.8, 0.6])
367  props.lineWidth = 0.5
368  props.lineStyle = omr.MUIDrawManager.kDashed
369  props.pointSize = 12.0
370 
371  primId = geCanvas.createPrimitive( omr.MGeometry.kLineStrip, timeId, 0, 5, props )
372 
373  geCanvas.addPrimitive( primId, omui.MPanelCanvas.kGraphEditorCurveNames+56 )
374 
375  # Register the callbacks in specified layers.
376  #
377  geCanvas.registerDrawUICallback( omui.MPanelCanvas.kGraphEditorBackground+56, otherFunc )
378 
379  geCanvas.registerDrawUICallback( omui.MPanelCanvas.kGraphEditorGrid+56, iconFunc )
380 
381  geCanvas.registerDrawUICallback( omui.MPanelCanvas.kGraphEditorAxisLabels+56, textFunc )
382 
383  geCanvas.registerDrawUICallback( omui.MPanelCanvas.kGraphEditorCurves+56, rectFunc )
384 
385  geCanvas.registerDrawUICallback( omui.MPanelCanvas.kGraphEditorCurveNames+54, arcFunc )
386 
387  geCanvas.registerDrawUICallback( omui.MPanelCanvas.kGraphEditorTimeMarker+54, circleFunc )
388 
389  geCanvas.registerDrawUICallback( omui.MPanelCanvas.kGraphEditorRetimeToolText+56, otherFunc )
390 
391  geCanvas.setAutoRefresh( True )
392 
393  print geCanvas.isValid()
394 
395 
396 def uninitializePlugin( mobject ):
397  """
398  Description:
399  this method is called when the plug-in is unloaded from Maya. It
400  deregisters all of the services that it was providing.
401 
402  Arguments:
403  mobject - a handle to the plug-in object (use MFnPlugin to access it)
404  """
405  global myCanvas
406  [geCanvas, geName, geWindow] = myCanvas
407  cmds.deleteUI(geWindow)
408  print geCanvas.isValid()
409