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