scripted/narrowPolyViewer.py

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