]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/wxPython/lib/vtk.py
860b30ad45aaa92f51ca749061a62af04efa4b77
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 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(wxWindow
):
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 wxWindow
.__init
__(self
, parent
, id, position
, size
, style | wxWANTS_CHARS
)
53 self
._RenderWindow
= vtkRenderWindow()
58 if wxPlatform
!= '__WXMSW__':
59 # We can't get the handle in wxGTK until after the widget
60 # is created, the window create event happens later so we'll
62 EVT_WINDOW_CREATE(self
, self
.OnCreateWindow
)
63 EVT_PAINT (self
, self
.OnExpose
)
65 # but in MSW, the window create event happens durring the above
66 # call to __init__ so we have to do it here.
67 hdl
= self
.GetHandle()
68 self
._RenderWindow
.SetWindowInfo(str(hdl
))
69 EVT_PAINT (self
, self
.OnExpose
)
72 # common for all platforms
73 EVT_SIZE (self
, self
.OnConfigure
)
75 # setup the user defined events.
79 def SetupEvents(self
):
80 "Setup the user defined event bindings."
81 # Remember to bind everything to self.box and NOT self
82 EVT_LEFT_DOWN (self
, self
.OnLeftButtonDown
)
83 EVT_MIDDLE_DOWN (self
, self
.OnMiddleButtonDown
)
84 EVT_RIGHT_DOWN (self
, self
.OnRightButtonDown
)
85 EVT_LEFT_UP (self
, self
.OnLeftButtonUp
)
86 EVT_MIDDLE_UP (self
, self
.OnMiddleButtonUp
)
87 EVT_RIGHT_UP (self
, self
.OnRightButtonUp
)
88 EVT_MOTION (self
, self
.OnMouseMove
)
89 EVT_ENTER_WINDOW (self
, self
.OnEnter
)
90 EVT_LEAVE_WINDOW (self
, self
.OnLeave
)
91 EVT_CHAR (self
, self
.OnChar
)
92 # Add your bindings if you want them in the derived class.
95 def GetRenderer(self
):
96 self
._RenderWindow
.GetRenderers().InitTraversal()
97 return self
._RenderWindow
.GetRenderers().GetNextItem()
100 def GetRenderWindow(self
):
101 return self
._RenderWindow
106 # if block needed because calls to render before creation
107 # will prevent the renderwindow from being embedded into a
109 self
._RenderWindow
.Render()
112 def OnExpose(self
, event
):
113 # I need this for the MDIDemo. Somehow OnCreateWindow was
114 # not getting called.
115 if not self
.__Created
:
116 self
.OnCreateWindow(event
)
117 if (not self
.__InExpose
):
120 self
._RenderWindow
.Render()
124 def OnCreateWindow(self
, event
):
125 hdl
= self
.GetHandle()
127 self
._RenderWindow
.SetParentInfo(str(hdl
))
129 self
._RenderWindow
.SetWindowInfo(str(hdl
))
131 "Unable to call vtkRenderWindow.SetParentInfo\n\n"\
132 "Using the SetWindowInfo method instead. This\n"\
133 "is likely to cause a lot of flicker when\n"\
134 "rendering in the vtkRenderWindow. Please\n"\
135 "use a recent Nightly VTK release (later than\n"\
136 "March 10 2001) to eliminate this problem."
137 dlg
= wxMessageDialog(NULL
, msg
, "Warning!",
138 wxOK |wxICON_INFORMATION
)
144 def OnConfigure(self
, event
):
147 # Ugly hack that according to Eric Boix is necessary under
148 # Windows. If possible Try commenting this out and test under
150 #self._RenderWindow.GetSize()
152 self
._RenderWindow
.SetSize(sz
.width
, sz
.height
)
155 def OnLeftButtonDown(self
, event
):
156 "Left mouse button pressed."
160 def OnMiddleButtonDown(self
, event
):
161 "Middle mouse button pressed."
165 def OnRightButtonDown(self
, event
):
166 "Right mouse button pressed."
170 def OnLeftButtonUp(self
, event
):
171 "Left mouse button released."
175 def OnMiddleButtonUp(self
, event
):
176 "Middle mouse button released."
180 def OnRightButtonUp(self
, event
):
181 "Right mouse button released."
185 def OnMouseMove(self
, event
):
190 def OnEnter(self
, event
):
191 "Entering the vtkRenderWindow."
195 def OnLeave(self
, event
):
196 "Leaving the vtkRenderWindow."
200 def OnChar(self
, event
):
201 "Process Key events."
205 def OnKeyDown(self
, event
):
210 def OnKeyUp(self
, event
):
217 class wxVTKRenderWindow(wxVTKRenderWindowBase
):
219 An example of a fully functional wxVTKRenderWindow that is
220 based on the vtkRenderWidget.py provided with the VTK sources.
223 def __init__(self
, parent
, id, position
=wxDefaultPosition
,
224 size
=wxDefaultSize
, style
=0):
225 wxVTKRenderWindowBase
.__init
__(self
, parent
, id, position
, size
,
228 self
._CurrentRenderer
= None
229 self
._CurrentCamera
= None
230 self
._CurrentZoom
= 1.0
231 self
._CurrentLight
= None
233 self
._ViewportCenterX
= 0
234 self
._ViewportCenterY
= 0
236 self
._Picker
= vtkCellPicker()
237 self
._PickedAssembly
= None
238 self
._PickedProperty
= vtkProperty()
239 self
._PickedProperty
.SetColor(1,0,0)
240 self
._PrePickedProperty
= None
242 self
._OldFocus
= None
244 # these record the previous mouse position
249 def OnLeftButtonDown(self
, event
):
250 "Left mouse button pressed."
251 self
.StartMotion(event
)
254 def OnMiddleButtonDown(self
, event
):
255 "Middle mouse button pressed."
256 self
.StartMotion(event
)
259 def OnRightButtonDown(self
, event
):
260 "Right mouse button pressed."
261 self
.StartMotion(event
)
264 def OnLeftButtonUp(self
, event
):
265 "Left mouse button released."
266 self
.EndMotion(event
)
269 def OnMiddleButtonUp(self
, event
):
270 "Middle mouse button released."
271 self
.EndMotion(event
)
274 def OnRightButtonUp(self
, event
):
275 "Right mouse button released."
276 self
.EndMotion(event
)
279 def OnMouseMove(self
, event
):
280 event
.x
, event
.y
= event
.GetPositionTuple()
281 if event
.LeftIsDown():
282 if event
.ShiftDown():
283 self
.Pan(event
.x
, event
.y
)
285 self
.Rotate(event
.x
, event
.y
)
287 elif event
.MiddleIsDown():
288 self
.Pan(event
.x
, event
.y
)
290 elif event
.RightIsDown():
291 self
.Zoom(event
.x
, event
.y
)
294 def OnEnter(self
, event
):
295 self
.__OldFocus
= wxWindow_FindFocus()
297 x
, y
= event
.GetPositionTuple()
298 self
.UpdateRenderer(x
,y
)
301 def OnLeave(self
, event
):
302 if (self
._OldFocus
!= None):
303 self
.__OldFocus
.SetFocus()
306 def OnChar(self
, event
):
307 key
= event
.KeyCode()
308 if (key
== ord('r')) or (key
== ord('R')):
310 elif (key
== ord('w')) or (key
== ord('W')):
312 elif (key
== ord('s')) or (key
== ord('S')):
314 elif (key
== ord('p')) or (key
== ord('P')):
315 x
, y
= event
.GetPositionTuple()
321 # Start of internal functions
322 def GetZoomFactor(self
):
323 return self
._CurrentZoom
326 def SetZoomFactor(self
, zf
):
327 self
._CurrentZoom
= zf
335 if (self
._CurrentLight
):
336 light
= self
._CurrentLight
337 light
.SetPosition(self
._CurrentCamera
.GetPosition())
338 light
.SetFocalPoint(self
._CurrentCamera
.GetFocalPoint())
340 wxVTKRenderWindowBase
.Render(self
)
343 def UpdateRenderer(self
, x
, y
):
345 UpdateRenderer will identify the renderer under the mouse and set
346 up _CurrentRenderer, _CurrentCamera, and _CurrentLight.
352 renderers
= self
._RenderWindow
.GetRenderers()
353 numRenderers
= renderers
.GetNumberOfItems()
355 self
._CurrentRenderer
= None
356 renderers
.InitTraversal()
357 for i
in range(0,numRenderers
):
358 renderer
= renderers
.GetNextItem()
361 vx
= float (x
)/(windowX
-1)
363 vy
= (windowY
-float(y
)-1)/(windowY
-1)
364 (vpxmin
,vpymin
,vpxmax
,vpymax
) = renderer
.GetViewport()
366 if (vx
>= vpxmin
and vx
<= vpxmax
and
367 vy
>= vpymin
and vy
<= vpymax
):
368 self
._CurrentRenderer
= renderer
369 self
._ViewportCenterX
= float(windowX
)*(vpxmax
-vpxmin
)/2.0\
371 self
._ViewportCenterY
= float(windowY
)*(vpymax
-vpymin
)/2.0\
373 self
._CurrentCamera
= self
._CurrentRenderer
.GetActiveCamera()
374 lights
= self
._CurrentRenderer
.GetLights()
375 lights
.InitTraversal()
376 self
._CurrentLight
= lights
.GetNextItem()
383 def GetCurrentRenderer(self
):
384 return self
._CurrentRenderer
387 def StartMotion(self
, event
):
388 x
, y
= event
.GetPositionTuple()
389 self
.UpdateRenderer(x
,y
)
393 def EndMotion(self
, event
=None):
394 if self
._CurrentRenderer
:
399 def Rotate(self
,x
,y
):
400 if self
._CurrentRenderer
:
402 self
._CurrentCamera
.Azimuth(self
._LastX
- x
)
403 self
._CurrentCamera
.Elevation(y
- self
._LastY
)
404 self
._CurrentCamera
.OrthogonalizeViewUp()
409 self
._CurrentRenderer
.ResetCameraClippingRange()
413 def PanAbsolute(self
, x_vec
, y_vec
):
414 if self
._CurrentRenderer
:
416 renderer
= self
._CurrentRenderer
417 camera
= self
._CurrentCamera
418 (pPoint0
,pPoint1
,pPoint2
) = camera
.GetPosition()
419 (fPoint0
,fPoint1
,fPoint2
) = camera
.GetFocalPoint()
421 if (camera
.GetParallelProjection()):
422 renderer
.SetWorldPoint(fPoint0
,fPoint1
,fPoint2
,1.0)
423 renderer
.WorldToDisplay()
424 fx
,fy
,fz
= renderer
.GetDisplayPoint()
425 renderer
.SetDisplayPoint(fx
+x_vec
,
428 renderer
.DisplayToWorld()
429 fx
,fy
,fz
,fw
= renderer
.GetWorldPoint()
430 camera
.SetFocalPoint(fx
,fy
,fz
)
432 renderer
.SetWorldPoint(pPoint0
,pPoint1
,pPoint2
,1.0)
433 renderer
.WorldToDisplay()
434 fx
,fy
,fz
= renderer
.GetDisplayPoint()
435 renderer
.SetDisplayPoint(fx
+x_vec
,
438 renderer
.DisplayToWorld()
439 fx
,fy
,fz
,fw
= renderer
.GetWorldPoint()
440 camera
.SetPosition(fx
,fy
,fz
)
443 (fPoint0
,fPoint1
,fPoint2
) = camera
.GetFocalPoint()
444 # Specify a point location in world coordinates
445 renderer
.SetWorldPoint(fPoint0
,fPoint1
,fPoint2
,1.0)
446 renderer
.WorldToDisplay()
447 # Convert world point coordinates to display coordinates
448 dPoint
= renderer
.GetDisplayPoint()
449 focalDepth
= dPoint
[2]
451 aPoint0
= self
._ViewportCenterX
+ x_vec
452 aPoint1
= self
._ViewportCenterY
+ y_vec
454 renderer
.SetDisplayPoint(aPoint0
,aPoint1
,focalDepth
)
455 renderer
.DisplayToWorld()
457 (rPoint0
,rPoint1
,rPoint2
,rPoint3
) = renderer
.GetWorldPoint()
459 rPoint0
= rPoint0
/rPoint3
460 rPoint1
= rPoint1
/rPoint3
461 rPoint2
= rPoint2
/rPoint3
463 camera
.SetFocalPoint((fPoint0
- rPoint0
) + fPoint0
,
464 (fPoint1
- rPoint1
) + fPoint1
,
465 (fPoint2
- rPoint2
) + fPoint2
)
467 camera
.SetPosition((fPoint0
- rPoint0
) + pPoint0
,
468 (fPoint1
- rPoint1
) + pPoint1
,
469 (fPoint2
- rPoint2
) + pPoint2
)
475 self
.PanAbsolute(x
- self
._LastX
, - y
+ self
._LastY
)
481 if self
._CurrentRenderer
:
483 renderer
= self
._CurrentRenderer
484 camera
= self
._CurrentCamera
486 zoomFactor
= math
.pow(1.02,(0.5*(self
._LastY
- y
)))
487 self
._CurrentZoom
= self
._CurrentZoom
* zoomFactor
489 if camera
.GetParallelProjection():
490 parallelScale
= camera
.GetParallelScale()/zoomFactor
491 camera
.SetParallelScale(parallelScale
)
493 camera
.Dolly(zoomFactor
)
494 renderer
.ResetCameraClippingRange()
503 if self
._CurrentRenderer
:
504 self
._CurrentRenderer
.ResetCamera()
510 actors
= self
._CurrentRenderer
.GetActors()
511 numActors
= actors
.GetNumberOfItems()
512 actors
.InitTraversal()
513 for i
in range(0,numActors
):
514 actor
= actors
.GetNextItem()
515 actor
.GetProperty().SetRepresentationToWireframe()
521 actors
= self
._CurrentRenderer
.GetActors()
522 numActors
= actors
.GetNumberOfItems()
523 actors
.InitTraversal()
524 for i
in range(0,numActors
):
525 actor
= actors
.GetNextItem()
526 actor
.GetProperty().SetRepresentationToSurface()
531 def PickActor(self
,x
,y
):
532 if self
._CurrentRenderer
:
533 renderer
= self
._CurrentRenderer
534 picker
= self
._Picker
536 windowY
= self
.GetSize().height
537 picker
.Pick(x
,(windowY
- y
- 1),0.0,renderer
)
538 assembly
= picker
.GetAssembly()
540 if (self
._PickedAssembly
!= None and
541 self
._PrePickedProperty
!= None):
542 self
._PickedAssembly
.SetProperty(self
._PrePickedProperty
)
543 # release hold of the property
544 self
._PrePickedProperty
.UnRegister(self
._PrePickedProperty
)
545 self
._PrePickedProperty
= None
547 if (assembly
!= None):
548 self
._PickedAssembly
= assembly
549 self
._PrePickedProperty
= self
._PickedAssembly
.GetProperty()
550 # hold onto the property
551 self
._PrePickedProperty
.Register(self
._PrePickedProperty
)
552 self
._PickedAssembly
.SetProperty(self
._PickedProperty
)