2 VTK is now including a package for using VTK with wxPython, so this 
   3 module is now officially nothing but ancient history.  If for some 
   4 strange reason you really need this code (I don't know why, it didn't 
   5 work all that well anyway,) then just remove the triple quotes below. 
   6 I'm told that the module from Kitware is excellent and so you should 
   7 really use it.  See the URL below to get a copy from CVS. 
   9 http://public.kitware.com/cgi-bin/cvsweb.cgi/VTK/Wrapping/Python/vtk/wx/ 
  15 #---------------------------------------------------------------------- 
  16 # Name:        wxPython.lib.vtk 
  17 # Purpose:     Provides a wrapper around the vtkRenderWindow from the 
  18 #              VTK Visualization Toolkit.  Requires the VTK Python 
  19 #              extensions from http://www.kitware.com/ 
  23 # Created:     16-Nov-1999 
  25 # Copyright:   (c) 1999 by Total Control Software 
  26 # Licence:     wxWindows license 
  27 #---------------------------------------------------------------------- 
  29 # This class has been rewritten and improved by Prabhu Ramachandran 
  30 # <prabhu@aero.iitm.ernet.in>.  It has been tested under Win32 and 
  31 # Linux.  Many thanks to Eric Boix <frog@creatis.insa-lyon.fr> for 
  32 # testing it under Windows and finding and fixing many errors. 
  33 # Thanks also to Sebastien BARRE <sebastien@barre.nom.fr> for his 
  38     from vtkpython import * 
  40     raise ImportError, "VTK extension module not found" 
  42 from wxPython.wx import * 
  45 #---------------------------------------------------------------------- 
  54 class wxVTKRenderWindowBase(wxWindow): 
  56     A base 
class that enables one to embed a vtkRenderWindow into
 
  57     a wxPython widget
.  This 
class embeds the RenderWindow correctly
 
  58     under different platforms
.  Provided are some empty methods that
 
  59     can be overloaded to provide a user defined interaction behaviour
. 
  60     The event handling functions have names that are similar to the
 
  61     ones 
in the vtkInteractorStyle 
class included 
with VTK
. 
  64     def __init__(self, parent, id, position=wxDefaultPosition, 
  65                  size=wxDefaultSize, style=0): 
  66         wxWindow.__init__(self, parent, id, position, size, style | wxWANTS_CHARS) 
  67         self._RenderWindow = vtkRenderWindow() 
  72         if wxPlatform != '__WXMSW__': 
  73             # We can't get the handle in wxGTK until after the widget 
  74             # is created, the window create event happens later so we'll 
  76             EVT_WINDOW_CREATE(self, self.OnCreateWindow) 
  77             EVT_PAINT       (self, self.OnExpose) 
  79             # but in MSW, the window create event happens durring the above 
  80             # call to __init__ so we have to do it here. 
  81             hdl = self.GetHandle() 
  82             self._RenderWindow.SetWindowInfo(str(hdl)) 
  83             EVT_PAINT       (self, self.OnExpose) 
  86         # common for all platforms 
  87         EVT_SIZE        (self, self.OnConfigure) 
  89         # setup the user defined events. 
  93     def SetupEvents(self): 
  94         "Setup the user defined event bindings." 
  95         # Remember to bind everything to self.box and NOT self 
  96         EVT_LEFT_DOWN    (self, self.OnLeftButtonDown) 
  97         EVT_MIDDLE_DOWN  (self, self.OnMiddleButtonDown) 
  98         EVT_RIGHT_DOWN   (self, self.OnRightButtonDown) 
  99         EVT_LEFT_UP      (self, self.OnLeftButtonUp) 
 100         EVT_MIDDLE_UP    (self, self.OnMiddleButtonUp) 
 101         EVT_RIGHT_UP     (self, self.OnRightButtonUp) 
 102         EVT_MOTION       (self, self.OnMouseMove) 
 103         EVT_ENTER_WINDOW (self, self.OnEnter) 
 104         EVT_LEAVE_WINDOW (self, self.OnLeave) 
 105         EVT_CHAR         (self, self.OnChar) 
 106         # Add your bindings if you want them in the derived class. 
 109     def GetRenderer(self): 
 110         self._RenderWindow.GetRenderers().InitTraversal() 
 111         return self._RenderWindow.GetRenderers().GetNextItem() 
 114     def GetRenderWindow(self): 
 115         return self._RenderWindow 
 120             # if block needed because calls to render before creation 
 121             # will prevent the renderwindow from being embedded into a 
 123             self._RenderWindow.Render() 
 126     def OnExpose(self, event): 
 127         # I need this for the MDIDemo.  Somehow OnCreateWindow was 
 128         # not getting called. 
 129         if not self.__Created: 
 130             self.OnCreateWindow(event) 
 131         if (not self.__InExpose): 
 134             self._RenderWindow.Render() 
 138     def OnCreateWindow(self, event): 
 139         hdl = self.GetHandle() 
 141             self._RenderWindow.SetParentInfo(str(hdl)) 
 143             self._RenderWindow.SetWindowInfo(str(hdl)) 
 145                   "Unable to call vtkRenderWindow.SetParentInfo\n\n"\ 
 146                   "Using the SetWindowInfo method instead.  This\n"\ 
 147                   "is likely to cause a lot of flicker when\n"\ 
 148                   "rendering in the vtkRenderWindow.  Please\n"\ 
 149                   "use a recent Nightly VTK release (later than\n"\ 
 150                   "March 10 2001) to eliminate this problem." 
 151             dlg = wxMessageDialog(NULL, msg, "Warning!", 
 152                                    wxOK |wxICON_INFORMATION) 
 158     def OnConfigure(self, event): 
 161         # Ugly hack that according to Eric Boix is necessary under 
 162         # Windows.  If possible Try commenting this out and test under 
 164         #self._RenderWindow.GetSize() 
 166         self._RenderWindow.SetSize(sz.width, sz.height) 
 169     def OnLeftButtonDown(self, event): 
 170         "Left mouse button pressed." 
 174     def OnMiddleButtonDown(self, event): 
 175         "Middle mouse button pressed." 
 179     def OnRightButtonDown(self, event): 
 180         "Right mouse button pressed." 
 184     def OnLeftButtonUp(self, event): 
 185         "Left mouse button released." 
 189     def OnMiddleButtonUp(self, event): 
 190         "Middle mouse button released." 
 194     def OnRightButtonUp(self, event): 
 195         "Right mouse button released." 
 199     def OnMouseMove(self, event): 
 204     def OnEnter(self, event): 
 205         "Entering the vtkRenderWindow." 
 209     def OnLeave(self, event): 
 210         "Leaving the vtkRenderWindow." 
 214     def OnChar(self, event): 
 215         "Process Key events." 
 219     def OnKeyDown(self, event): 
 224     def OnKeyUp(self, event): 
 231 class wxVTKRenderWindow(wxVTKRenderWindowBase): 
 233     An example of a fully functional wxVTKRenderWindow that 
is 
 234     based on the vtkRenderWidget
.py provided 
with the VTK sources
. 
 237     def __init__(self, parent, id, position=wxDefaultPosition, 
 238                  size=wxDefaultSize, style=0): 
 239         wxVTKRenderWindowBase.__init__(self, parent, id, position, size, 
 242         self._CurrentRenderer = None 
 243         self._CurrentCamera = None 
 244         self._CurrentZoom = 1.0 
 245         self._CurrentLight = None 
 247         self._ViewportCenterX = 0 
 248         self._ViewportCenterY = 0 
 250         self._Picker = vtkCellPicker() 
 251         self._PickedAssembly = None 
 252         self._PickedProperty = vtkProperty() 
 253         self._PickedProperty.SetColor(1,0,0) 
 254         self._PrePickedProperty = None 
 256         self._OldFocus = None 
 258         # these record the previous mouse position 
 263     def OnLeftButtonDown(self, event): 
 264         "Left mouse button pressed." 
 265         self.StartMotion(event) 
 268     def OnMiddleButtonDown(self, event): 
 269         "Middle mouse button pressed." 
 270         self.StartMotion(event) 
 273     def OnRightButtonDown(self, event): 
 274         "Right mouse button pressed." 
 275         self.StartMotion(event) 
 278     def OnLeftButtonUp(self, event): 
 279         "Left mouse button released." 
 280         self.EndMotion(event) 
 283     def OnMiddleButtonUp(self, event): 
 284         "Middle mouse button released." 
 285         self.EndMotion(event) 
 288     def OnRightButtonUp(self, event): 
 289         "Right mouse button released." 
 290         self.EndMotion(event) 
 293     def OnMouseMove(self, event): 
 294         event.x, event.y = event.GetPositionTuple() 
 295         if event.LeftIsDown(): 
 296             if event.ShiftDown(): 
 297                 self.Pan(event.x, event.y) 
 299                 self.Rotate(event.x, event.y) 
 301         elif event.MiddleIsDown(): 
 302             self.Pan(event.x, event.y) 
 304         elif event.RightIsDown(): 
 305             self.Zoom(event.x, event.y) 
 308     def OnEnter(self, event): 
 309         self.__OldFocus = wxWindow_FindFocus() 
 311         x, y = event.GetPositionTuple() 
 312         self.UpdateRenderer(x,y) 
 315     def OnLeave(self, event): 
 316         if (self._OldFocus != None): 
 317             self.__OldFocus.SetFocus() 
 320     def OnChar(self, event): 
 321         key = event.KeyCode() 
 322         if (key == ord('r')) or (key == ord('R')): 
 324         elif (key == ord('w')) or (key == ord('W')): 
 326         elif (key == ord('s')) or (key == ord('S')): 
 328         elif (key == ord('p')) or (key == ord('P')): 
 329             x, y = event.GetPositionTuple() 
 335     # Start of internal functions 
 336     def GetZoomFactor(self): 
 337         return self._CurrentZoom 
 340     def SetZoomFactor(self, zf): 
 341         self._CurrentZoom = zf 
 349         if (self._CurrentLight): 
 350             light = self._CurrentLight 
 351             light.SetPosition(self._CurrentCamera.GetPosition()) 
 352             light.SetFocalPoint(self._CurrentCamera.GetFocalPoint()) 
 354         wxVTKRenderWindowBase.Render(self) 
 357     def UpdateRenderer(self, x, y): 
 359         UpdateRenderer will identify the renderer under the mouse 
and set 
 360         up _CurrentRenderer
, _CurrentCamera
, and _CurrentLight
. 
 366         renderers = self._RenderWindow.GetRenderers() 
 367         numRenderers = renderers.GetNumberOfItems() 
 369         self._CurrentRenderer = None 
 370         renderers.InitTraversal() 
 371         for i in range(0,numRenderers): 
 372             renderer = renderers.GetNextItem() 
 375                 vx = float (x)/(windowX-1) 
 377                 vy = (windowY-float(y)-1)/(windowY-1) 
 378             (vpxmin,vpymin,vpxmax,vpymax) = renderer.GetViewport() 
 380             if (vx >= vpxmin and vx <= vpxmax and 
 381                 vy >= vpymin and vy <= vpymax): 
 382                 self._CurrentRenderer = renderer 
 383                 self._ViewportCenterX = float(windowX)*(vpxmax-vpxmin)/2.0\ 
 385                 self._ViewportCenterY = float(windowY)*(vpymax-vpymin)/2.0\ 
 387                 self._CurrentCamera = self._CurrentRenderer.GetActiveCamera() 
 388                 lights = self._CurrentRenderer.GetLights() 
 389                 lights.InitTraversal() 
 390                 self._CurrentLight = lights.GetNextItem() 
 397     def GetCurrentRenderer(self): 
 398         return self._CurrentRenderer 
 401     def StartMotion(self, event): 
 402         x, y = event.GetPositionTuple() 
 403         self.UpdateRenderer(x,y) 
 407     def EndMotion(self, event=None): 
 408         if self._CurrentRenderer: 
 413     def Rotate(self,x,y): 
 414         if self._CurrentRenderer: 
 416             self._CurrentCamera.Azimuth(self._LastX - x) 
 417             self._CurrentCamera.Elevation(y - self._LastY) 
 418             self._CurrentCamera.OrthogonalizeViewUp() 
 423             self._CurrentRenderer.ResetCameraClippingRange() 
 427     def PanAbsolute(self, x_vec, y_vec): 
 428         if self._CurrentRenderer: 
 430             renderer = self._CurrentRenderer 
 431             camera = self._CurrentCamera 
 432             (pPoint0,pPoint1,pPoint2) = camera.GetPosition() 
 433             (fPoint0,fPoint1,fPoint2) = camera.GetFocalPoint() 
 435             if (camera.GetParallelProjection()): 
 436                 renderer.SetWorldPoint(fPoint0,fPoint1,fPoint2,1.0) 
 437                 renderer.WorldToDisplay() 
 438                 fx,fy,fz = renderer.GetDisplayPoint() 
 439                 renderer.SetDisplayPoint(fx+x_vec, 
 442                 renderer.DisplayToWorld() 
 443                 fx,fy,fz,fw = renderer.GetWorldPoint() 
 444                 camera.SetFocalPoint(fx,fy,fz) 
 446                 renderer.SetWorldPoint(pPoint0,pPoint1,pPoint2,1.0) 
 447                 renderer.WorldToDisplay() 
 448                 fx,fy,fz = renderer.GetDisplayPoint() 
 449                 renderer.SetDisplayPoint(fx+x_vec, 
 452                 renderer.DisplayToWorld() 
 453                 fx,fy,fz,fw = renderer.GetWorldPoint() 
 454                 camera.SetPosition(fx,fy,fz) 
 457                 (fPoint0,fPoint1,fPoint2) = camera.GetFocalPoint() 
 458                 # Specify a point location in world coordinates 
 459                 renderer.SetWorldPoint(fPoint0,fPoint1,fPoint2,1.0) 
 460                 renderer.WorldToDisplay() 
 461                 # Convert world point coordinates to display coordinates 
 462                 dPoint = renderer.GetDisplayPoint() 
 463                 focalDepth = dPoint[2] 
 465                 aPoint0 = self._ViewportCenterX + x_vec 
 466                 aPoint1 = self._ViewportCenterY + y_vec 
 468                 renderer.SetDisplayPoint(aPoint0,aPoint1,focalDepth) 
 469                 renderer.DisplayToWorld() 
 471                 (rPoint0,rPoint1,rPoint2,rPoint3) = renderer.GetWorldPoint() 
 473                     rPoint0 = rPoint0/rPoint3 
 474                     rPoint1 = rPoint1/rPoint3 
 475                     rPoint2 = rPoint2/rPoint3 
 477                 camera.SetFocalPoint((fPoint0 - rPoint0) + fPoint0, 
 478                                      (fPoint1 - rPoint1) + fPoint1, 
 479                                      (fPoint2 - rPoint2) + fPoint2) 
 481                 camera.SetPosition((fPoint0 - rPoint0) + pPoint0, 
 482                                    (fPoint1 - rPoint1) + pPoint1, 
 483                                    (fPoint2 - rPoint2) + pPoint2) 
 489         self.PanAbsolute(x - self._LastX, - y + self._LastY) 
 495         if self._CurrentRenderer: 
 497             renderer = self._CurrentRenderer 
 498             camera = self._CurrentCamera 
 500             zoomFactor = math.pow(1.02,(0.5*(self._LastY - y))) 
 501             self._CurrentZoom = self._CurrentZoom * zoomFactor 
 503             if camera.GetParallelProjection(): 
 504                 parallelScale = camera.GetParallelScale()/zoomFactor 
 505                 camera.SetParallelScale(parallelScale) 
 507                 camera.Dolly(zoomFactor) 
 508                 renderer.ResetCameraClippingRange() 
 517         if self._CurrentRenderer: 
 518             self._CurrentRenderer.ResetCamera() 
 524         actors = self._CurrentRenderer.GetActors() 
 525         numActors = actors.GetNumberOfItems() 
 526         actors.InitTraversal() 
 527         for i in range(0,numActors): 
 528             actor = actors.GetNextItem() 
 529             actor.GetProperty().SetRepresentationToWireframe() 
 535         actors = self._CurrentRenderer.GetActors() 
 536         numActors = actors.GetNumberOfItems() 
 537         actors.InitTraversal() 
 538         for i in range(0,numActors): 
 539             actor = actors.GetNextItem() 
 540             actor.GetProperty().SetRepresentationToSurface() 
 545     def PickActor(self,x,y): 
 546         if self._CurrentRenderer: 
 547             renderer = self._CurrentRenderer 
 548             picker = self._Picker 
 550             windowY = self.GetSize().height 
 551             picker.Pick(x,(windowY - y - 1),0.0,renderer) 
 552             assembly = picker.GetAssembly() 
 554             if (self._PickedAssembly != None and 
 555                 self._PrePickedProperty != None): 
 556                 self._PickedAssembly.SetProperty(self._PrePickedProperty) 
 557                 # release hold of the property 
 558                 self._PrePickedProperty.UnRegister(self._PrePickedProperty) 
 559                 self._PrePickedProperty = None 
 561             if (assembly != None): 
 562                 self._PickedAssembly = assembly 
 563                 self._PrePickedProperty = self._PickedAssembly.GetProperty() 
 564                 # hold onto the property 
 565                 self._PrePickedProperty.Register(self._PrePickedProperty) 
 566                 self._PickedAssembly.SetProperty(self._PickedProperty)