]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/wxPython/lib/vtk.py
229c087be1958470b808ab097e0af796726c2e1f
   1 #---------------------------------------------------------------------- 
   2 # Name:        wxPython.lib.vtk 
   3 # Purpose:     Provides a wrapper around the vtkRenderWindow from the 
   4 #              VTK Visualization Toolkit.  Requires the VTK Python 
   5 #              extensions from http://www.kitware.com/ 
  11 # Copyright:   (c) 1999 by Total Control Software 
  12 # Licence:     wxWindows license 
  13 #---------------------------------------------------------------------- 
  15 # This class has been rewritten and improved by Prabhu Ramachandran 
  16 # <prabhu@aero.iitm.ernet.in>.  It has been tested under Win32 and 
  17 # Linux.  Many thanks to Eric Boix <frog@creatis.insa-lyon.fr> for 
  18 # testing it under Windows(TM) and finding and fixing many errors. 
  19 # Thanks also to Sebastien BARRE <sebastien@barre.nom.fr> for his 
  24     from vtkpython 
import * 
  26     raise ImportError, "VTK extension module not found" 
  28 from wxPython
.wx 
import * 
  31 #---------------------------------------------------------------------- 
  40 class wxVTKRenderWindowBase(wxScrolledWindow
): 
  42     A base class that enables one to embed a vtkRenderWindow into 
  43     a wxPython widget.  This class embeds the RenderWindow correctly 
  44     under different platforms.  Provided are some empty methods that 
  45     can be overloaded to provide a user defined interaction behaviour. 
  46     The event handling functions have names that are similar to the 
  47     ones in the vtkInteractorStyle class included with VTK. 
  50     def __init__(self
, parent
, id, position
=wxDefaultPosition
, 
  51                  size
=wxDefaultSize
, style
=0): 
  52         wxScrolledWindow
.__init
__(self
, parent
, id, position
, size
, style
) 
  53         style 
= style | wxWANTS_CHARS
 
  55         # This box is necessary to eliminate flicker and enable proper 
  56         # event handling under Linux/GTK. 
  57         self
.box 
= wxPanel(self
, -1, position
, size
, style
) 
  59         self
._RenderWindow 
= vtkRenderWindow() 
  64         if wxPlatform 
!= '__WXMSW__': 
  65             # We can't get the handle in wxGTK until after the widget 
  66             # is created, the window create event happens later so we'll 
  68             EVT_WINDOW_CREATE(self
.box
, self
.OnCreateWindow
) 
  69             EVT_PAINT       (self
, self
.OnExpose
) 
  71             # but in MSW, the window create event happens durring the above 
  72             # call to __init__ so we have to do it here. 
  73             hdl 
= self
.box
.GetHandle() 
  74             self
._RenderWindow
.SetWindowInfo(str(hdl
)) 
  75             EVT_PAINT       (self
.box
, self
.OnExpose
) 
  78         # common for all platforms 
  79         EVT_SIZE        (self
, self
.OnConfigure
) 
  81         # setup the user defined events. 
  85     def SetupEvents(self
): 
  86         "Setup the user defined event bindings." 
  87         # Remember to bind everything to self.box and NOT self 
  88         EVT_LEFT_DOWN    (self
.box
, self
.OnLeftButtonDown
) 
  89         EVT_MIDDLE_DOWN  (self
.box
, self
.OnMiddleButtonDown
) 
  90         EVT_RIGHT_DOWN   (self
.box
, self
.OnRightButtonDown
) 
  91         EVT_LEFT_UP      (self
.box
, self
.OnLeftButtonUp
) 
  92         EVT_MIDDLE_UP    (self
.box
, self
.OnMiddleButtonUp
) 
  93         EVT_RIGHT_UP     (self
.box
, self
.OnRightButtonUp
) 
  94         EVT_MOTION       (self
.box
, self
.OnMouseMove
) 
  95         EVT_ENTER_WINDOW (self
.box
, self
.OnEnter
) 
  96         EVT_LEAVE_WINDOW (self
.box
, self
.OnLeave
) 
  97         EVT_CHAR         (self
.box
, self
.OnChar
) 
  98         # Add your bindings if you want them in the derived class. 
 101     def GetRenderer(self
): 
 102         self
._RenderWindow
.GetRenderers().InitTraversal() 
 103         return self
._RenderWindow
.GetRenderers().GetNextItem() 
 106     def GetRenderWindow(self
): 
 107         return self
._RenderWindow
 
 112             # if block needed because calls to render before creation 
 113             # will prevent the renderwindow from being embedded into a 
 115             self
._RenderWindow
.Render() 
 118     def OnExpose(self
, event
): 
 119         # I need this for the MDIDemo.  Somehow OnCreateWindow was 
 120         # not getting called. 
 121         if not self
.__Created
: 
 122             self
.OnCreateWindow(event
) 
 123         if (not self
.__InExpose
): 
 125             dc 
= wxPaintDC(self
.box
) 
 126             self
._RenderWindow
.Render() 
 130     def OnCreateWindow(self
, event
): 
 131         hdl 
= self
.box
.GetHandle() 
 133             self
._RenderWindow
.SetParentInfo(str(hdl
)) 
 135             self
._RenderWindow
.SetWindowInfo(str(hdl
)) 
 137                   "Unable to call vtkRenderWindow.SetParentInfo\n\n"\
 
 138                   "Using the SetWindowInfo method instead.  This\n"\
 
 139                   "is likely to cause a lot of flicker when\n"\
 
 140                   "rendering in the vtkRenderWindow.  Please\n"\
 
 141                   "use a recent Nightly VTK release (later than\n"\
 
 142                   "March 10 2001) to eliminate this problem." 
 143             dlg 
= wxMessageDialog(NULL
, msg
, "Warning!", 
 144                                    wxOK |wxICON_INFORMATION
) 
 150     def OnConfigure(self
, event
): 
 153         # Ugly hack that according to Eric Boix is necessary under 
 154         # Windows.  If possible Try commenting this out and test under 
 156         #self._RenderWindow.GetSize() 
 158         self
._RenderWindow
.SetSize(sz
.width
, sz
.height
) 
 161     def OnLeftButtonDown(self
, event
): 
 162         "Left mouse button pressed." 
 166     def OnMiddleButtonDown(self
, event
): 
 167         "Middle mouse button pressed." 
 171     def OnRightButtonDown(self
, event
): 
 172         "Right mouse button pressed." 
 176     def OnLeftButtonUp(self
, event
): 
 177         "Left mouse button released." 
 181     def OnMiddleButtonUp(self
, event
): 
 182         "Middle mouse button released." 
 186     def OnRightButtonUp(self
, event
): 
 187         "Right mouse button released." 
 191     def OnMouseMove(self
, event
): 
 196     def OnEnter(self
, event
): 
 197         "Entering the vtkRenderWindow." 
 201     def OnLeave(self
, event
): 
 202         "Leaving the vtkRenderWindow." 
 206     def OnChar(self
, event
): 
 207         "Process Key events." 
 211     def OnKeyDown(self
, event
): 
 216     def OnKeyUp(self
, event
): 
 223 class wxVTKRenderWindow(wxVTKRenderWindowBase
): 
 225     An example of a fully functional wxVTKRenderWindow that is 
 226     based on the vtkRenderWidget.py provided with the VTK sources. 
 229     def __init__(self
, parent
, id, position
=wxDefaultPosition
, 
 230                  size
=wxDefaultSize
, style
=0): 
 231         wxVTKRenderWindowBase
.__init
__(self
, parent
, id, position
, size
, 
 234         self
._CurrentRenderer 
= None 
 235         self
._CurrentCamera 
= None 
 236         self
._CurrentZoom 
= 1.0 
 237         self
._CurrentLight 
= None 
 239         self
._ViewportCenterX 
= 0 
 240         self
._ViewportCenterY 
= 0 
 242         self
._Picker 
= vtkCellPicker() 
 243         self
._PickedAssembly 
= None 
 244         self
._PickedProperty 
= vtkProperty() 
 245         self
._PickedProperty
.SetColor(1,0,0) 
 246         self
._PrePickedProperty 
= None 
 248         self
._OldFocus 
= None 
 250         # these record the previous mouse position 
 255     def OnLeftButtonDown(self
, event
): 
 256         "Left mouse button pressed." 
 257         self
.StartMotion(event
) 
 260     def OnMiddleButtonDown(self
, event
): 
 261         "Middle mouse button pressed." 
 262         self
.StartMotion(event
) 
 265     def OnRightButtonDown(self
, event
): 
 266         "Right mouse button pressed." 
 267         self
.StartMotion(event
) 
 270     def OnLeftButtonUp(self
, event
): 
 271         "Left mouse button released." 
 272         self
.EndMotion(event
) 
 275     def OnMiddleButtonUp(self
, event
): 
 276         "Middle mouse button released." 
 277         self
.EndMotion(event
) 
 280     def OnRightButtonUp(self
, event
): 
 281         "Right mouse button released." 
 282         self
.EndMotion(event
) 
 285     def OnMouseMove(self
, event
): 
 286         event
.x
, event
.y 
= event
.GetPositionTuple() 
 287         if event
.LeftIsDown(): 
 288             if event
.ShiftDown(): 
 289                 self
.Pan(event
.x
, event
.y
) 
 291                 self
.Rotate(event
.x
, event
.y
) 
 293         elif event
.MiddleIsDown(): 
 294             self
.Pan(event
.x
, event
.y
) 
 296         elif event
.RightIsDown(): 
 297             self
.Zoom(event
.x
, event
.y
) 
 300     def OnEnter(self
, event
): 
 301         self
.__OldFocus 
= wxWindow_FindFocus() 
 303         x
, y 
= event
.GetPositionTuple() 
 304         self
.UpdateRenderer(x
,y
) 
 307     def OnLeave(self
, event
): 
 308         if (self
._OldFocus 
!= None): 
 309             self
.__OldFocus
.SetFocus() 
 312     def OnChar(self
, event
): 
 313         key 
= event
.KeyCode() 
 314         if (key 
== ord('r')) or (key 
== ord('R')): 
 316         elif (key 
== ord('w')) or (key 
== ord('W')): 
 318         elif (key 
== ord('s')) or (key 
== ord('S')): 
 320         elif (key 
== ord('p')) or (key 
== ord('P')): 
 321             x
, y 
= event
.GetPositionTuple() 
 327     # Start of internal functions 
 328     def GetZoomFactor(self
): 
 329         return self
._CurrentZoom
 
 332     def SetZoomFactor(self
, zf
): 
 333         self
._CurrentZoom 
= zf
 
 341         if (self
._CurrentLight
): 
 342             light 
= self
._CurrentLight
 
 343             light
.SetPosition(self
._CurrentCamera
.GetPosition()) 
 344             light
.SetFocalPoint(self
._CurrentCamera
.GetFocalPoint()) 
 346         wxVTKRenderWindowBase
.Render(self
) 
 349     def UpdateRenderer(self
, x
, y
): 
 351         UpdateRenderer will identify the renderer under the mouse and set 
 352         up _CurrentRenderer, _CurrentCamera, and _CurrentLight. 
 358         renderers 
= self
._RenderWindow
.GetRenderers() 
 359         numRenderers 
= renderers
.GetNumberOfItems() 
 361         self
._CurrentRenderer 
= None 
 362         renderers
.InitTraversal() 
 363         for i 
in range(0,numRenderers
): 
 364             renderer 
= renderers
.GetNextItem() 
 367                 vx 
= float (x
)/(windowX
-1) 
 369                 vy 
= (windowY
-float(y
)-1)/(windowY
-1) 
 370             (vpxmin
,vpymin
,vpxmax
,vpymax
) = renderer
.GetViewport() 
 372             if (vx 
>= vpxmin 
and vx 
<= vpxmax 
and 
 373                 vy 
>= vpymin 
and vy 
<= vpymax
): 
 374                 self
._CurrentRenderer 
= renderer
 
 375                 self
._ViewportCenterX 
= float(windowX
)*(vpxmax
-vpxmin
)/2.0\
 
 377                 self
._ViewportCenterY 
= float(windowY
)*(vpymax
-vpymin
)/2.0\
 
 379                 self
._CurrentCamera 
= self
._CurrentRenderer
.GetActiveCamera() 
 380                 lights 
= self
._CurrentRenderer
.GetLights() 
 381                 lights
.InitTraversal() 
 382                 self
._CurrentLight 
= lights
.GetNextItem() 
 389     def GetCurrentRenderer(self
): 
 390         return self
._CurrentRenderer
 
 393     def StartMotion(self
, event
): 
 394         x
, y 
= event
.GetPositionTuple() 
 395         self
.UpdateRenderer(x
,y
) 
 396         self
.box
.CaptureMouse() 
 399     def EndMotion(self
, event
=None): 
 400         if self
._CurrentRenderer
: 
 402         self
.box
.ReleaseMouse() 
 405     def Rotate(self
,x
,y
): 
 406         if self
._CurrentRenderer
: 
 408             self
._CurrentCamera
.Azimuth(self
._LastX 
- x
) 
 409             self
._CurrentCamera
.Elevation(y 
- self
._LastY
) 
 410             self
._CurrentCamera
.OrthogonalizeViewUp() 
 415             self
._CurrentRenderer
.ResetCameraClippingRange() 
 419     def PanAbsolute(self
, x_vec
, y_vec
): 
 420         if self
._CurrentRenderer
: 
 422             renderer 
= self
._CurrentRenderer
 
 423             camera 
= self
._CurrentCamera
 
 424             (pPoint0
,pPoint1
,pPoint2
) = camera
.GetPosition() 
 425             (fPoint0
,fPoint1
,fPoint2
) = camera
.GetFocalPoint() 
 427             if (camera
.GetParallelProjection()): 
 428                 renderer
.SetWorldPoint(fPoint0
,fPoint1
,fPoint2
,1.0) 
 429                 renderer
.WorldToDisplay() 
 430                 fx
,fy
,fz 
= renderer
.GetDisplayPoint() 
 431                 renderer
.SetDisplayPoint(fx
+x_vec
, 
 434                 renderer
.DisplayToWorld() 
 435                 fx
,fy
,fz
,fw 
= renderer
.GetWorldPoint() 
 436                 camera
.SetFocalPoint(fx
,fy
,fz
) 
 438                 renderer
.SetWorldPoint(pPoint0
,pPoint1
,pPoint2
,1.0) 
 439                 renderer
.WorldToDisplay() 
 440                 fx
,fy
,fz 
= renderer
.GetDisplayPoint() 
 441                 renderer
.SetDisplayPoint(fx
+x_vec
, 
 444                 renderer
.DisplayToWorld() 
 445                 fx
,fy
,fz
,fw 
= renderer
.GetWorldPoint() 
 446                 camera
.SetPosition(fx
,fy
,fz
) 
 449                 (fPoint0
,fPoint1
,fPoint2
) = camera
.GetFocalPoint() 
 450                 # Specify a point location in world coordinates 
 451                 renderer
.SetWorldPoint(fPoint0
,fPoint1
,fPoint2
,1.0) 
 452                 renderer
.WorldToDisplay() 
 453                 # Convert world point coordinates to display coordinates 
 454                 dPoint 
= renderer
.GetDisplayPoint() 
 455                 focalDepth 
= dPoint
[2] 
 457                 aPoint0 
= self
._ViewportCenterX 
+ x_vec
 
 458                 aPoint1 
= self
._ViewportCenterY 
+ y_vec
 
 460                 renderer
.SetDisplayPoint(aPoint0
,aPoint1
,focalDepth
) 
 461                 renderer
.DisplayToWorld() 
 463                 (rPoint0
,rPoint1
,rPoint2
,rPoint3
) = renderer
.GetWorldPoint() 
 465                     rPoint0 
= rPoint0
/rPoint3
 
 466                     rPoint1 
= rPoint1
/rPoint3
 
 467                     rPoint2 
= rPoint2
/rPoint3
 
 469                 camera
.SetFocalPoint((fPoint0 
- rPoint0
) + fPoint0
, 
 470                                      (fPoint1 
- rPoint1
) + fPoint1
, 
 471                                      (fPoint2 
- rPoint2
) + fPoint2
) 
 473                 camera
.SetPosition((fPoint0 
- rPoint0
) + pPoint0
, 
 474                                    (fPoint1 
- rPoint1
) + pPoint1
, 
 475                                    (fPoint2 
- rPoint2
) + pPoint2
) 
 481         self
.PanAbsolute(x 
- self
._LastX
, - y 
+ self
._LastY
) 
 487         if self
._CurrentRenderer
: 
 489             renderer 
= self
._CurrentRenderer
 
 490             camera 
= self
._CurrentCamera
 
 492             zoomFactor 
= math
.pow(1.02,(0.5*(self
._LastY 
- y
))) 
 493             self
._CurrentZoom 
= self
._CurrentZoom 
* zoomFactor
 
 495             if camera
.GetParallelProjection(): 
 496                 parallelScale 
= camera
.GetParallelScale()/zoomFactor
 
 497                 camera
.SetParallelScale(parallelScale
) 
 499                 camera
.Dolly(zoomFactor
) 
 500                 renderer
.ResetCameraClippingRange() 
 509         if self
._CurrentRenderer
: 
 510             self
._CurrentRenderer
.ResetCamera() 
 516         actors 
= self
._CurrentRenderer
.GetActors() 
 517         numActors 
= actors
.GetNumberOfItems() 
 518         actors
.InitTraversal() 
 519         for i 
in range(0,numActors
): 
 520             actor 
= actors
.GetNextItem() 
 521             actor
.GetProperty().SetRepresentationToWireframe() 
 527         actors 
= self
._CurrentRenderer
.GetActors() 
 528         numActors 
= actors
.GetNumberOfItems() 
 529         actors
.InitTraversal() 
 530         for i 
in range(0,numActors
): 
 531             actor 
= actors
.GetNextItem() 
 532             actor
.GetProperty().SetRepresentationToSurface() 
 537     def PickActor(self
,x
,y
): 
 538         if self
._CurrentRenderer
: 
 539             renderer 
= self
._CurrentRenderer
 
 540             picker 
= self
._Picker
 
 542             windowY 
= self
.GetSize().height
 
 543             picker
.Pick(x
,(windowY 
- y 
- 1),0.0,renderer
) 
 544             assembly 
= picker
.GetAssembly() 
 546             if (self
._PickedAssembly 
!= None and 
 547                 self
._PrePickedProperty 
!= None): 
 548                 self
._PickedAssembly
.SetProperty(self
._PrePickedProperty
) 
 549                 # release hold of the property 
 550                 self
._PrePickedProperty
.UnRegister(self
._PrePickedProperty
) 
 551                 self
._PrePickedProperty 
= None 
 553             if (assembly 
!= None): 
 554                 self
._PickedAssembly 
= assembly
 
 555                 self
._PrePickedProperty 
= self
._PickedAssembly
.GetProperty() 
 556                 # hold onto the property 
 557                 self
._PrePickedProperty
.Register(self
._PrePickedProperty
) 
 558                 self
._PickedAssembly
.SetProperty(self
._PickedProperty
)