Python API 2.0 Reference: scripted/narrowPolyViewer.py

scripted/narrowPolyViewer.py
1 from __future__ import division
2 #-
3 # ==========================================================================
4 # Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors. All
5 # rights reserved.
6 #
7 # The coded instructions, statements, computer programs, and/or related
8 # material (collectively the "Data") in these files contain unpublished
9 # information proprietary to Autodesk, Inc. ("Autodesk") and/or its
10 # licensors, which is protected by U.S. and Canadian federal copyright
11 # law and by international treaties.
12 #
13 # The Data is provided for use exclusively by You. You have the right
14 # to use, modify, and incorporate this Data into other products for
15 # purposes authorized by the Autodesk software license agreement,
16 # without fee.
17 #
18 # The copyright notices in the Software and this entire statement,
19 # including the above license grant, this restriction and the
20 # following disclaimer, must be included in all copies of the
21 # Software, in whole or in part, and all derivative works of
22 # the Software, unless such copies or derivative works are solely
23 # in the form of machine-executable object code generated by a
24 # source language processor.
25 #
26 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
27 # AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED
28 # WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF
29 # NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR
30 # PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR
31 # TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS
32 # BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL,
33 # DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK
34 # AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY
35 # OR PROBABILITY OF SUCH DAMAGES.
36 #
37 # ==========================================================================
38 #+
39 
40 ########################################################################
41 # DESCRIPTION:
42 #
43 # This example demonstrates how to use the "MPx3dModelView" and "MPxModelEditorCommand"
44 # classes to implement a viewer. The viewer will highlight narrow polygons and
45 # must be given a geometry that is triangulated.
46 #
47 # To use this example, do the following:
48 #
49 # (1) Load the plug-in.
50 # (2) Create the mesh geometry and triangulate it.
51 # (3) Select the mesh geometry.
52 # (4) Execute the script showNarrowPolyViewer.py.
53 # (5) Manipulate a vertex to create a narrow polygon.
54 # Narrow polygons will be shaded as defined by the tolerance set in the plug-in.
55 #
56 ########################################################################
57 
58 from builtins import next
59 from builtins import range
60 import sys
61 import math
62 import maya.OpenMaya as OpenMaya
63 import maya.OpenMayaMPx as OpenMayaMPx
64 import maya.OpenMayaUI as OpenMayaUI
65 import maya.OpenMayaRender as OpenMayaRender
66 
67 glRenderer = OpenMayaRender.MHardwareRenderer.theRenderer()
68 glFT = glRenderer.glFunctionTable()
69 
70 kPluginCmdName = "spNarrowPolyViewer"
71 
72 kInitFlag = "-in"
73 kInitFlagLong = "-init"
74 
75 kResultsFlag = "-r"
76 kResultsFlagLong = "-results"
77 
78 kClearFlag = "-cl"
79 kClearFlagLong = "-clear"
80 
81 kToleranceFlag = "-tol"
82 kToleranceFlagLong = "-tolerance"
83 
84 class narrowPolyViewer(OpenMayaMPx.MPx3dModelView):
85  def __init__(self):
86  OpenMayaMPx.MPx3dModelView.__init__(self)
87 
88  self.fOldCamera = OpenMaya.MDagPath()
89  self.fCameraList = OpenMaya.MDagPathArray()
90  self.fCurrentPass = 0
91  self.fDrawManips = True
92  self.fOldDisplayStyle = OpenMayaUI.M3dView.kWireFrame
93  self.fLightTest = False
94  self.fListList = OpenMaya.MDagPathArray()
95  self.tol = 10.0
96 
97  self.setMultipleDrawEnable(True)
98 
99  def multipleDrawPassCount(self):
100  return self.fCameraList.length() + 1
101 
102  def setCameraList(self, cameraList):
103  setMultipleDrawEnable(True)
104  self.fCameraList.clear()
105 
106  for i in range(cameraList.length()):
107  self.fCameraList.append(cameraList[i])
108 
109  self.refresh()
110 
111  def removeAllCameras(self):
112  self.fCameraList.clear()
113  self.refresh()
114 
115  def getCameraHUDName(self):
116  cameraPath = OpenMaya.MDagPath()
117  self.getCamera(cameraPath)
118 
119  cameraPath.pop()
120 
121  hudName = "spNarrowPolyViewer: " + cameraPath.partialPathName()
122  return hudName
123 
124  def setIsolateSelect(self, list):
125  self.setViewSelected(True)
126  return self.setObjectsToView(list)
127 
128  def setIsolateSelectOff(self):
129  return self.setViewSelected(False)
130 
131  def preMultipleDraw(self):
132  self.fCurrentPass = 0
133  self.fDrawManips = False
134 
135  dagPath = OpenMaya.MDagPath()
136 
137  try:
138  oldCamera = OpenMaya.MDagPath()
139  self.getCamera(oldCamera)
140 
141  self.fOldCamera = oldCamera
142 
143  displayHUD(False)
144 
145  sList = OpenMaya.MSelectionList()
147 
148  sList.getDagPath(0, dagPath)
149  except:
150  # sys.stderr.write("ERROR: spNarrowPolyViewer.preMultipleDraw b\n")
151  pass
152 
153  try:
154  itMeshPolygon = OpenMaya.MItMeshPolygon(dagPath, OpenMaya.cvar.MObject_kNullObj)
155 
156  if None == itMeshPolygon:
157  return;
158 
159  self.beginGL()
160 
161  while not itMeshPolygon.isDone():
162  points = OpenMaya.MPointArray()
163  itMeshPolygon.getPoints(points, OpenMaya.MSpace.kWorld)
164  length = points.length()
165 
166  if length == 3:
167  for i in range(length):
168  p = points[i]
169  p1 = points[(i+1)%length]
170  p2 = points[(i+2)%length]
171 
172  v1 = OpenMaya.MVector(p1 - p)
173  v2 = OpenMaya.MVector(p2 - p)
174 
175  angle = v1.angle(v2) * 180.0 / math.pi
176 
177  if math.fabs(angle - self.tol) < 0.0001 or angle < self.tol:
178  glFT.glBegin( OpenMayaRender.MGL_POLYGON )
179  glFT.glVertex3f(points[0].x, points[0].y, points[0].z)
180  glFT.glVertex3f(points[1].x, points[1].y, points[1].z)
181  glFT.glVertex3f(points[2].x, points[2].y, points[2].z)
182 
183  glFT.glNormal3f(points[0].x, points[0].y, points[0].z)
184  glFT.glNormal3f(points[1].x, points[1].y, points[1].z)
185  glFT.glNormal3f(points[2].x, points[2].y, points[2].z)
186 
187  glFT.glTexCoord3f(points[0].x, points[0].y, points[0].z)
188  glFT.glTexCoord3f(points[1].x, points[1].y, points[1].z)
189  glFT.glTexCoord3f(points[2].x, points[2].y, points[2].z)
190  glFT.glEnd()
191 
192  next(itMeshPolygon)
193 
194  self.endGL()
195  except:
196  # sys.stderr.write("ERROR: spNarrowPolyViewer.preMultipleDraw c\n")
197  pass
198 
199  def postMultipleDraw(self):
200  try:
201  self.setCamera(self.fOldCamera)
202  self.fDrawManips = True
203  self.updateViewingParameters()
204  except:
205  sys.stderr.write("ERROR: spNarrowPolyViewer.postMultipleDraw\n")
206  raise
207 
208  def preMultipleDrawPass(self, index):
209  self.fCurrentPass = index
210 
211  try:
212  self.setDisplayAxis(False)
213  self.setDisplayAxisAtOrigin(False)
214  self.setDisplayCameraAnnotation(False)
215 
216  dagPath = OpenMaya.MDagPath()
217 
218  if self.fCurrentPass == 0:
219  self.getCamera(dagPath)
220  else:
221  nCameras = self.fCameraList.length()
222  if self.fCurrentPass <= nCameras:
223  dagPath = self.fCameraList[self.fCurrentPass-1]
224  else:
225  sys.stderr.write("ERROR: ...too many passes specified\n")
226  return
227 
228  self.setCameraInDraw(dagPath)
229 
230  self.setObjectDisplay(OpenMayaUI.M3dView.kDisplayEverything, True)
231 
232  if dagPath == self.fOldCamera:
233  self.fDrawManips = True
234  self.setObjectDisplay(OpenMayaUI.M3dView.kDisplayGrid, True)
235 
236  self.setFogEnabled(True)
237 
238  self.setBackgroundFogEnabled(False)
239 
240  self.setObjectDisplay(OpenMayaUI.M3dView.kDisplayLights, True)
241  self.setObjectDisplay(OpenMayaUI.M3dView.kDisplayCameras, True)
242  self.setObjectDisplay(OpenMayaUI.M3dView.kDisplayIkHandles, True)
243  self.setObjectDisplay(OpenMayaUI.M3dView.kDisplayDimensions, True)
244  self.setObjectDisplay(OpenMayaUI.M3dView.kDisplaySelectHandles, True)
245 
246  textPos = OpenMaya.MPoint(0.0, 0.0, 0.0)
247  str = "Main View"
248  self.drawText(str, textPos, OpenMayaUI.M3dView.kLeft)
249  else:
250  self.fDrawManips = False
251  self.setObjectDisplay(OpenMayaUI.M3dView.kDisplayGrid, False)
252 
253  self.setFogEnabled(True)
254 
255  self.setObjectDisplay(OpenMayaUI.M3dView.kDisplayLights, False)
256  self.setObjectDisplay(OpenMayaUI.M3dView.kDisplayCameras, False)
257  self.setObjectDisplay(OpenMayaUI.M3dView.kDisplayIkHandles, False)
258  self.setObjectDisplay(OpenMayaUI.M3dView.kDisplayDimensions, False)
259  self.setObjectDisplay(OpenMayaUI.M3dView.kDisplaySelectHandles, False)
260  except:
261  sys.stderr.write("ERROR: spNarrowPolyViewer.preMultipleDrawPass\n")
262  raise
263 
264  # note do not have light test in here
265 
266  # self.setLightingMode(OpenMayaUI.kLightDefault)
267 
268  if ((self.fCurrentPass % 2) == 0):
269  self.setObjectDisplay(OpenMayaUI.M3dView.kDisplayNurbsSurfaces, True );
270  self.setObjectDisplay(OpenMayaUI.M3dView.kDisplayNurbsCurves, True );
271 
272  self.updateViewingParameters()
273 
274  def postMultipleDrawPass(self, index):
275  self.setObjectDisplay(OpenMayaUI.M3dView.kDisplayEverything, True)
276 
277  def okForMultipleDraw(self, dagPath):
278  if not self.fDrawManips and dagPath.hasFn(OpenMaya.MFn.kManipulator3D):
279  return False
280  return True
281 
282  def multipleDrawPassCount(self):
283  return self.fCameraList.length() + 1
284 
285  def viewType(self):
286  return "spNarrowPolyViewer";
287 
288 
289 
290 
291 class narrowPolyViewerCmd(OpenMayaMPx.MPxModelEditorCommand):
292  def __init__(self):
293  OpenMayaMPx.MPxModelEditorCommand.__init__(self)
294  self.fCameraList = OpenMaya.MDagPathArray()
295 
296  def appendSyntax(self):
297  try:
298  theSyntax = self._syntax()
299  theSyntax.addFlag(kInitFlag, kInitFlagLong)
300  theSyntax.addFlag(kResultsFlag, kResultsFlagLong)
301  theSyntax.addFlag(kClearFlag, kClearFlagLong)
302  theSyntax.addFlag(kToleranceFlag, kToleranceFlagLong, OpenMaya.MSyntax.kDouble)
303 
304  except:
305  sys.stderr.write( "ERROR: creating syntax for model editor command: %s" % kPluginCmdName )
306 
307  def doEditFlags(self):
308  try:
309  user3dModelView = self.modelView()
310 
311  if user3dModelView.viewType() == kPluginCmdName:
312  argData = self._parser()
313 
314  if argData.isFlagSet(kInitFlag):
315  self.initTests(user3dModelView)
316  elif argData.isFlagSet(kResultsFlag):
317  self.testResults(user3dModelView)
318  elif argData.isFlagSet(kClearFlag):
319  self.clearResults(user3dModelView)
320  elif argData.isFlagSet(kToleranceFlag):
321  tol = argData.flagArgumentDouble(kToleranceFlag, 0)
322  user3dModelView.tol = tol
323  user3dModelView.refresh(True, True)
324  else:
325  return OpenMaya.kUnknownParameter
326  except:
327  sys.stderr.write( "ERROR: in doEditFlags for model editor command: %s" % kPluginCmdName )
328 
329  def initTests(self, view):
330  clearResults(self, view)
331 
332  # Add every camera into the scene. Don't change the main camera,
333  # it is OK that it gets reused.
334  #
335  cameraPath = OpenMaya.MDagPath()
336  dagIterator = OpenMaya.MItDag(OpenMaya.MItDag.kDepthFirst, OpenMaya.MFn.kCamera)
337 
338  while not dagIterator.isDone():
339  try:
340  dagIterator.getPath(cameraPath)
341  camera = OpenMaya.MFnCamera(cameraPath)
342  except:
343  continue
344 
345  OpenMaya.MGlobal.displayInfo(camera.fullPathName())
346  self.fCameraList.append(cameraPath)
347 
348  next(dagIterator)
349 
350  try:
351  view.setCameraList(self.fCameraList)
352  except:
353  OpenMaya.MGlobal.displayError("Could not set list of cameras\n")
354  raise
355 
356  view.refresh()
357 
358  def testResults(self, view):
359  print("fCameraLIst.length() = %d " % (self.fCameraList.length(), ))
360  length = self.fCameraList.length()
361 
362  def clearResults(self, view):
363  view.removeAllCameras()
364  self.fCameraList.clear()
365 
366 
367 
368 def cmdCreator():
369  return OpenMayaMPx.asMPxPtr( narrowPolyViewerCmd() )
370 
371 def viewerCreator():
372  return OpenMayaMPx.asMPxPtr( narrowPolyViewer() )
373 
374 # initialize the script plug-in
375 def initializePlugin(mobject):
376  mplugin = OpenMayaMPx.MFnPlugin(mobject)
377  try:
378  mplugin.registerModelEditorCommand( kPluginCmdName, cmdCreator, viewerCreator)
379  except:
380  sys.stderr.write( "Failed to register model editor command: %s" % kPluginCmdName )
381  raise
382 
383 # uninitialize the script plug-in
384 def uninitializePlugin(mobject):
385  mplugin = OpenMayaMPx.MFnPlugin(mobject)
386  try:
387  mplugin.deregisterModelEditorCommand( kPluginCmdName )
388  except:
389  sys.stderr.write( "Failed to deregister model editor command: %s" % kPluginCmdName )
390  raise
391