1 /*=========================================================================
3 Program: Visualization Toolkit
4 Module: $RCSfile: wxVTKRenderWindowInteractor.cxx,v $
6 Date: $Date: 2008/09/26 14:09:55 $
7 Version: $Revision: 1.1 $
9 Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen
11 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
13 This software is distributed WITHOUT ANY WARRANTY; without even
14 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 PURPOSE. See the above copyright notice for more information.
17 =========================================================================*/
19 #include "wxVTKRenderWindowInteractor.h"
21 //This is needed for vtk 3.1 :
22 #ifndef VTK_MAJOR_VERSION
23 # include "vtkVersion.h"
26 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
27 # include "vtkCommand.h"
29 # include "vtkInteractorStyle.h"
34 //Keep this for compatibilty reason, this was introduced in wxGTK 2.4.0
35 #if (!wxCHECK_VERSION(2, 4, 0))
36 wxWindow* wxGetTopLevelParent(wxWindow *win)
38 while ( win && !win->IsTopLevel() )
39 win = win->GetParent();
44 //=======================================================================
46 // To access objc calls on cocoa
49 #import <Cocoa/Cocoa.h>
50 // This trick is no longer need in VTK CVS, should get rid of that:
53 #error Build mismatch you need both wxWidgets and VTK to be configure against Cocoa to work
54 #endif //VTK_USE_COCOA
58 # include <gdk/gdkx.h> // GDK_WINDOW_XWINDOW is found here in wxWidgets 2.8.0
59 # include "gdk/gdkprivate.h"
61 #include <wx/gtk/win_gtk.h>
63 #include <wx/gtk1/win_gtk.h>
65 #define GetXWindow(wxwin) (wxwin)->m_wxwindow ? \
66 GDK_WINDOW_XWINDOW(GTK_PIZZA((wxwin)->m_wxwindow)->bin_window) : \
67 GDK_WINDOW_XWINDOW((wxwin)->m_widget->window)
71 #include "wx/x11/privx.h"
72 #define GetXWindow(wxwin) ((Window)(wxwin)->GetHandle())
76 //For more info on this class please go to:
78 //This hack is for some buggy wxGTK version:
79 #if wxCHECK_VERSION(2, 3, 2) && !wxCHECK_VERSION(2, 4, 1) && defined(__WXGTK__)
80 # define WX_USE_X_CAPTURE 0
82 # define WX_USE_X_CAPTURE 1
85 #define ID_wxVTKRenderWindowInteractor_TIMER 1001
90 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
91 IMPLEMENT_DYNAMIC_CLASS(wxVTKRenderWindowInteractor, wxGLCanvas)
93 IMPLEMENT_DYNAMIC_CLASS(wxVTKRenderWindowInteractor, wxWindow)
96 //---------------------------------------------------------------------------
97 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
98 BEGIN_EVENT_TABLE(wxVTKRenderWindowInteractor, wxGLCanvas)
100 BEGIN_EVENT_TABLE(wxVTKRenderWindowInteractor, wxWindow)
102 //refresh window by doing a Render
103 EVT_PAINT (wxVTKRenderWindowInteractor::OnPaint)
104 EVT_ERASE_BACKGROUND(wxVTKRenderWindowInteractor::OnEraseBackground)
105 EVT_MOTION (wxVTKRenderWindowInteractor::OnMotion)
107 //Bind the events to the event converters
108 EVT_LEFT_DOWN (wxVTKRenderWindowInteractor::OnButtonDown)
109 EVT_MIDDLE_DOWN (wxVTKRenderWindowInteractor::OnButtonDown)
110 EVT_RIGHT_DOWN (wxVTKRenderWindowInteractor::OnButtonDown)
111 EVT_LEFT_UP (wxVTKRenderWindowInteractor::OnButtonUp)
112 EVT_MIDDLE_UP (wxVTKRenderWindowInteractor::OnButtonUp)
113 EVT_RIGHT_UP (wxVTKRenderWindowInteractor::OnButtonUp)
114 #if !(VTK_MAJOR_VERSION == 3 && VTK_MINOR_VERSION == 1)
115 EVT_ENTER_WINDOW(wxVTKRenderWindowInteractor::OnEnter)
116 EVT_LEAVE_WINDOW(wxVTKRenderWindowInteractor::OnLeave)
117 EVT_MOUSEWHEEL (wxVTKRenderWindowInteractor::OnMouseWheel)
118 // If we use EVT_KEY_DOWN instead of EVT_CHAR, capital versions
119 // of all characters are always returned. EVT_CHAR also performs
120 // other necessary keyboard-dependent translations.
121 //EVT_KEY_DOWN (wxVTKRenderWindowInteractor::OnKeyDown)
122 EVT_CHAR (wxVTKRenderWindowInteractor::OnKeyDown)
123 EVT_KEY_UP (wxVTKRenderWindowInteractor::OnKeyUp)
125 EVT_TIMER (ID_wxVTKRenderWindowInteractor_TIMER, wxVTKRenderWindowInteractor::OnTimer)
126 EVT_SIZE (wxVTKRenderWindowInteractor::OnSize)
129 //---------------------------------------------------------------------------
130 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
131 wxVTKRenderWindowInteractor::wxVTKRenderWindowInteractor() : vtkRenderWindowInteractor(), wxGLCanvas()
133 wxVTKRenderWindowInteractor::wxVTKRenderWindowInteractor() : vtkRenderWindowInteractor(), wxWindow()
135 , timer(this, ID_wxVTKRenderWindowInteractor_TIMER)
136 , ActiveButton(wxEVT_NULL)
141 , RenderWhenDisabled(1)
145 this->RenderWindow = NULL;
146 this->SetRenderWindow(vtkRenderWindow::New());
147 this->RenderWindow->Delete();
149 //this->SetBackgroundColour( wxColour(255,0,255) );
151 //---------------------------------------------------------------------------
152 wxVTKRenderWindowInteractor::wxVTKRenderWindowInteractor(wxWindow *parent,
157 const wxString &name)
158 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
159 : vtkRenderWindowInteractor(), wxGLCanvas(parent, id, pos, size, style, name)
161 : vtkRenderWindowInteractor(), wxWindow(parent, id, pos, size, style, name)
163 , timer(this, ID_wxVTKRenderWindowInteractor_TIMER)
164 , ActiveButton(wxEVT_NULL)
169 , RenderWhenDisabled(1)
173 this->RenderWindow = NULL;
174 this->SetRenderWindow(vtkRenderWindow::New());
175 this->RenderWindow->Delete();
177 // this->SetBackgroundColour( wxColour(255,0,0) );
179 //---------------------------------------------------------------------------
180 wxVTKRenderWindowInteractor::~wxVTKRenderWindowInteractor()
182 // LG : trompe la mort !
183 SetRenderWindow(NULL);
184 SetReferenceCount(0);
186 //---------------------------------------------------------------------------
187 wxVTKRenderWindowInteractor * wxVTKRenderWindowInteractor::New()
189 // we don't make use of the objectfactory, because we're not registered
190 return new wxVTKRenderWindowInteractor;
192 //---------------------------------------------------------------------------
193 void wxVTKRenderWindowInteractor::Initialize()
195 int *size = RenderWindow->GetSize();
196 // enable everything and start rendering
198 //RenderWindow->Start();
200 // set the size in the render window interactor
204 // this is initialized
207 //---------------------------------------------------------------------------
208 void wxVTKRenderWindowInteractor::Enable()
210 // if already enabled then done
216 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
221 //---------------------------------------------------------------------------
222 bool wxVTKRenderWindowInteractor::Enable(bool enable)
224 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
225 return wxGLCanvas::Enable(enable);
227 return wxWindow::Enable(enable);
230 //---------------------------------------------------------------------------
231 void wxVTKRenderWindowInteractor::Disable()
233 // if already disabled then done
237 // that's it (we can't remove the event handler like it should be...)
241 //---------------------------------------------------------------------------
242 void wxVTKRenderWindowInteractor::Start()
244 // the interactor cannot control the event loop
245 vtkErrorMacro( << "wxVTKRenderWindowInteractor::Start() "
246 "interactor cannot control event loop.");
248 //---------------------------------------------------------------------------
249 void wxVTKRenderWindowInteractor::UpdateSize(int x, int y)
253 // if the size changed tell render window
254 if ( x != Size[0] || y != Size[1] )
256 // adjust our (vtkRenderWindowInteractor size)
259 // and our RenderWindow's size
260 RenderWindow->SetSize(x, y);
264 //---------------------------------------------------------------------------
265 int wxVTKRenderWindowInteractor::CreateTimer(int WXUNUSED(timertype))
267 // it's a one shot timer
268 if (!timer.Start(10, TRUE))
274 //---------------------------------------------------------------------------
275 int wxVTKRenderWindowInteractor::DestroyTimer()
280 //---------------------------------------------------------------------------
281 void wxVTKRenderWindowInteractor::OnTimer(wxTimerEvent& WXUNUSED(event))
286 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
288 InvokeEvent(vtkCommand::TimerEvent, NULL);
291 InteractorStyle->OnTimer();
295 //---------------------------------------------------------------------------
296 // NOTE on implementation:
297 // Bad luck you ended up in the only tricky place of this code.
298 // A few note, wxWidgets still refuse to provide such convenient method
299 // so I have to maintain it myself, eventhough this is completely integrated
301 // Anyway if this happen to break for you then compare to a recent version of wxPython
302 // and look for the function long wxPyGetWinHandle(wxWindow* win)
303 // in wxPython/src/helpers.cpp
304 long wxVTKRenderWindowInteractor::GetHandleHack()
306 //helper function to hide the MSW vs GTK stuff
309 // __WXMSW__ is for Win32
310 //__WXMAX__ stands for using Carbon C-headers, using either the CarbonLib/CFM or the native Mach-O builds (which then also use the latest features available)
311 // __WXGTK__ is for both gtk 1.2.x and gtk 2.x
312 #if defined(__WXMSW__) || defined(__WXMAC__)
313 handle_tmp = (long)this->GetHandle();
316 //__WXCOCOA__ stands for using the objective-c Cocoa API
318 // Here is how to find the NSWindow
319 wxTopLevelWindow* toplevel = dynamic_cast<wxTopLevelWindow*>(
320 wxGetTopLevelParent( this ) );
321 if (toplevel != NULL )
323 handle_tmp = (long)toplevel->GetNSWindow();
325 // The NSView will be deducted from
326 // [(NSWindow*)Handle contentView]
327 // if only I knew how to write that in c++
330 // Find and return the actual X-Window.
331 #if defined(__WXGTK__) || defined(__WXX11__)
332 return (long)GetXWindow(this);
336 // handle_tmp = (long)this->GetXWindow();
341 //---------------------------------------------------------------------------
342 void wxVTKRenderWindowInteractor::OnPaint(wxPaintEvent& WXUNUSED(event))
345 //must always be here
348 //do it here rather than in the cstor: this is safer.
351 Handle = GetHandleHack();
352 RenderWindow->SetWindowId(reinterpret_cast<void *>(Handle));
354 RenderWindow->SetParentId(reinterpret_cast<void *>(this->GetParent()->GetHWND()));
357 // get vtk to render to the wxWindows
358 //bbtkDebugMessage("Wx",9,"wxVTKRenderWindowInteractor::OnPaint"<<std::endl);
359 //std::cout << "wxVTKRenderWindowInteractor::OnPaint"<<std::endl;
362 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
363 // bbtkDebugMessage("Core",9,"wxVTKRenderWindowInteractor::OnPaint public wxGLCanvas, virtual public vtkRenderWindowInteractor \n");
365 // bbtkDebugMessage("Core",9,"wxVTKRenderWindowInteractor::OnPaint public wxWindow, virtual public vtkRenderWindowInteractor \n");
369 //---------------------------------------------------------------------------
370 void wxVTKRenderWindowInteractor::OnEraseBackground(wxEraseEvent &event)
372 //printf("EED wxVTKRenderWindowInteractor::OnEraseBackground \n");
373 //turn off background erase to reduce flickering on MSW
376 //---------------------------------------------------------------------------
377 void wxVTKRenderWindowInteractor::OnSize(wxSizeEvent& WXUNUSED(event))
380 GetClientSize(&w, &h);
388 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
389 InvokeEvent(vtkCommand::ConfigureEvent, NULL);
391 //this will check for Handle
394 //---------------------------------------------------------------------------
395 void wxVTKRenderWindowInteractor::OnMotion(wxMouseEvent &event)
402 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
403 SetEventInformationFlipY(event.GetX(), event.GetY(),
404 event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
406 InvokeEvent(vtkCommand::MouseMoveEvent, NULL);
408 InteractorStyle->OnMouseMove(event.ControlDown(), event.ShiftDown(),
409 event.GetX(), Size[1] - event.GetY() - 1);
412 //---------------------------------------------------------------------------
413 #if !(VTK_MAJOR_VERSION == 3 && VTK_MINOR_VERSION == 1)
414 void wxVTKRenderWindowInteractor::OnEnter(wxMouseEvent &event)
421 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
423 SetEventInformationFlipY(event.GetX(), event.GetY(),
424 event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
426 InvokeEvent(vtkCommand::EnterEvent, NULL);
429 InteractorStyle->OnEnter(event.ControlDown(), event.ShiftDown(),
430 event.GetX(), Size[1] - event.GetY() - 1);
433 //---------------------------------------------------------------------------
434 void wxVTKRenderWindowInteractor::OnLeave(wxMouseEvent &event)
441 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
443 SetEventInformationFlipY(event.GetX(), event.GetY(),
444 event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
446 InvokeEvent(vtkCommand::LeaveEvent, NULL);
449 InteractorStyle->OnLeave(event.ControlDown(), event.ShiftDown(),
450 event.GetX(), Size[1] - event.GetY() - 1);
453 //---------------------------------------------------------------------------
454 void wxVTKRenderWindowInteractor::OnKeyDown(wxKeyEvent &event)
461 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
463 int keycode = event.GetKeyCode();
467 // TODO: Unicode in non-Unicode mode ??
471 SetEventInformationFlipY(event.GetX(), event.GetY(),
472 event.ControlDown(), event.ShiftDown(), key, 0, NULL);
474 InvokeEvent(vtkCommand::KeyPressEvent, NULL);
475 InvokeEvent(vtkCommand::CharEvent, NULL);
477 InteractorStyle->OnKeyDown(event.ControlDown(), event.ShiftDown(),
478 event.GetKeyCode(), 1);
482 //---------------------------------------------------------------------------
483 void wxVTKRenderWindowInteractor::OnKeyUp(wxKeyEvent &event)
490 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
492 int keycode = event.GetKeyCode();
496 // TODO: Unicode in non-Unicode mode ??
500 SetEventInformationFlipY(event.GetX(), event.GetY(),
501 event.ControlDown(), event.ShiftDown(), key, 0, NULL);
502 InvokeEvent(vtkCommand::KeyReleaseEvent, NULL);
504 InteractorStyle->OnKeyUp(event.ControlDown(), event.ShiftDown(),
505 event.GetKeyCode(), 1);
509 #endif //!(VTK_MAJOR_VERSION == 3 && VTK_MINOR_VERSION == 1)
510 //---------------------------------------------------------------------------
511 void wxVTKRenderWindowInteractor::OnButtonDown(wxMouseEvent &event)
513 if (!Enabled || (ActiveButton != wxEVT_NULL))
517 ActiveButton = event.GetEventType();
519 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
520 SetEventInformationFlipY(event.GetX(), event.GetY(),
521 event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
524 if(event.RightDown())
526 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
528 InvokeEvent(vtkCommand::RightButtonPressEvent, NULL);
531 InteractorStyle->OnRightButtonDown(event.ControlDown(), event.ShiftDown(),
532 event.GetX(), Size[1] - event.GetY() - 1);
535 else if(event.LeftDown())
537 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
539 InvokeEvent(vtkCommand::LeftButtonPressEvent, NULL);
542 InteractorStyle->OnLeftButtonDown(event.ControlDown(), event.ShiftDown(),
543 event.GetX(), Size[1] - event.GetY() - 1);
546 else if(event.MiddleDown())
548 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
550 InvokeEvent(vtkCommand::MiddleButtonPressEvent, NULL);
553 InteractorStyle->OnMiddleButtonDown(event.ControlDown(), event.ShiftDown(),
554 event.GetX(), Size[1] - event.GetY() - 1);
557 //save the button and capture mouse until the button is released
559 //1. it is possible (WX_USE_X_CAPTURE)
560 //2. user decided to.
561 if ((ActiveButton != wxEVT_NULL) && WX_USE_X_CAPTURE && UseCaptureMouse)
566 //---------------------------------------------------------------------------
567 void wxVTKRenderWindowInteractor::OnButtonUp(wxMouseEvent &event)
569 //EVT_xxx_DOWN == EVT_xxx_UP - 1
570 //This is only needed if two mouse buttons are pressed at the same time.
571 //In wxWindows 2.4 and later: better use of wxMOUSE_BTN_RIGHT or
572 //wxEVT_COMMAND_RIGHT_CLICK
573 if (!Enabled || (ActiveButton != (event.GetEventType()-1)))
578 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
579 SetEventInformationFlipY(event.GetX(), event.GetY(),
580 event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
583 if(ActiveButton == wxEVT_RIGHT_DOWN)
585 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
587 InvokeEvent(vtkCommand::RightButtonReleaseEvent, NULL);
590 InteractorStyle->OnRightButtonUp(event.ControlDown(), event.ShiftDown(),
591 event.GetX(), Size[1] - event.GetY() - 1);
594 else if(ActiveButton == wxEVT_LEFT_DOWN)
596 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
598 InvokeEvent(vtkCommand::LeftButtonReleaseEvent, NULL);
601 InteractorStyle->OnLeftButtonUp(event.ControlDown(), event.ShiftDown(),
602 event.GetX(), Size[1] - event.GetY() - 1);
605 else if(ActiveButton == wxEVT_MIDDLE_DOWN)
607 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
609 InvokeEvent(vtkCommand::MiddleButtonReleaseEvent, NULL);
612 InteractorStyle->OnMiddleButtonUp(event.ControlDown(), event.ShiftDown(),
613 event.GetX(), Size[1] - event.GetY() - 1);
616 //if the ActiveButton is realeased, then release mouse capture
617 if ((ActiveButton != wxEVT_NULL) && WX_USE_X_CAPTURE && UseCaptureMouse)
621 ActiveButton = wxEVT_NULL;
623 //---------------------------------------------------------------------------
624 void wxVTKRenderWindowInteractor::OnMouseWheel(wxMouseEvent& event)
626 // Mouse wheel was only added after VTK 4.4 (I think...)
627 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 2)
629 //Set vtk event information ... The numebr of wheel rotations is stored in
630 //the x varible. y varible is zero
631 SetEventInformationFlipY(event.GetWheelRotation() / event.GetWheelDelta(), 0,
632 event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
633 if(event.GetWheelRotation() > 0)
637 // InvokeEvent(vtkCommand::MouseWheelForwardEvent, NULL);
643 // InvokeEvent(vtkCommand::MouseWheelBackwardEvent, NULL);
649 //---------------------------------------------------------------------------
650 void wxVTKRenderWindowInteractor::Render()
653 if (!RenderWhenDisabled)
655 //the user doesn't want us to render when the toplevel frame
656 //is disabled - first find the top level parent
657 wxWindow *topParent = wxGetTopLevelParent(this);
660 //if it exists, check whether it's enabled
661 //if it's not enabeld, RenderAllowed will be false
662 RenderAllowed = topParent->IsEnabled();
668 if(Handle && (Handle == GetHandleHack()) )
670 RenderWindow->Render();
672 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 2)
673 else if(GetHandleHack())
675 //this means the user has reparented us; let's adapt to the
676 //new situation by doing the WindowRemap dance
677 //store the new situation
678 Handle = GetHandleHack();
679 RenderWindow->SetNextWindowId(reinterpret_cast<void *>(Handle));
680 RenderWindow->WindowRemap();
681 RenderWindow->Render();
686 //---------------------------------------------------------------------------
687 void wxVTKRenderWindowInteractor::SetRenderWhenDisabled(int newValue)
689 //Change value of __RenderWhenDisabled ivar.
690 //If __RenderWhenDisabled is false (the default), this widget will not
691 //call Render() on the RenderWindow if the top level frame (i.e. the
692 //containing frame) has been disabled.
694 //This prevents recursive rendering during wxSafeYield() calls.
695 //wxSafeYield() can be called during the ProgressMethod() callback of
696 //a VTK object to have progress bars and other GUI elements updated -
697 //it does this by disabling all windows (disallowing user-input to
698 //prevent re-entrancy of code) and then handling all outstanding
701 //However, this often triggers an OnPaint() method for wxVTKRWIs,
702 //resulting in a Render(), resulting in Update() being called whilst
705 RenderWhenDisabled = (bool)newValue;
707 //---------------------------------------------------------------------------
709 // Set the variable that indicates that we want a stereo capable window
710 // be created. This method can only be called before a window is realized.
712 void wxVTKRenderWindowInteractor::SetStereo(int capable)
714 if (Stereo != capable)
717 RenderWindow->StereoCapableWindowOn();
718 RenderWindow->SetStereoTypeToCrystalEyes();
723 //---------------------------------------------------------------------------
726 void wxVTKRenderWindowInteractor::PrintSelf(ostream& os, vtkIndent indent)
728 this->Superclass::PrintSelf(os, indent);
733 const char * wxVTKRenderWindowInteractor::GetClassName() const
735 return "wxVTKRenderWindowInteractor";
741 //=======================================================================