1 #include "VTKViewer_RenderWindowInteractor.h"
2 #include "VTKViewer_RenderWindow.h"
3 #include "VTKViewer_InteractorStyle.h"
4 #include "SUIT_ViewModel.h"
5 #include "VTKViewer_ViewWindow.h"
7 //#include "SUIT_Application.h"
8 //#include "SUIT_Desktop.h"
10 //#include "SALOME_Selection.h"
11 #include "VTKViewer_Actor.h"
12 #include "VTKViewer_Algorithm.h"
13 #include "VTKViewer_Functor.h"
21 #include <vtkAssemblyNode.h>
23 #include <vtkInteractorStyle.h>
24 #include <vtkObjectFactory.h>
25 #include <vtkPicker.h>
26 #include <vtkCellPicker.h>
27 #include <vtkPointPicker.h>
28 #include <vtkUnstructuredGrid.h>
29 #include <vtkPolyDataMapper.h>
30 #include <vtkSphereSource.h>
31 #include <vtkDataSet.h>
32 #include <vtkMaskPoints.h>
33 #include <vtkVertex.h>
34 #include <vtkRendererCollection.h>
35 #include <vtkPolyDataWriter.h>
40 /*! Create new instance of VTKViewer_RenderWindowInteractor*/
41 VTKViewer_RenderWindowInteractor* VTKViewer_RenderWindowInteractor::New()
43 vtkObject *ret = vtkObjectFactory::CreateInstance("VTKViewer_RenderWindowInteractor") ;
45 return dynamic_cast<VTKViewer_RenderWindowInteractor *>(ret) ;
47 return new VTKViewer_RenderWindowInteractor;
51 VTKViewer_RenderWindowInteractor::VTKViewer_RenderWindowInteractor()
54 this->mTimer = new QTimer( this ) ;
57 myBasicPicker = vtkPicker::New();
58 myCellPicker = vtkCellPicker::New();
59 myPointPicker = vtkPointPicker::New();
61 myCellActor = VTKViewer_Actor::New();
62 myCellActor->PickableOff();
63 myCellActor->GetProperty()->SetColor(1,1,0);
64 myCellActor->GetProperty()->SetLineWidth(5);
65 myCellActor->GetProperty()->SetRepresentationToSurface();
67 myEdgeActor = VTKViewer_Actor::New();
68 myEdgeActor->PickableOff();
69 myEdgeActor->GetProperty()->SetColor(1,0,0);
70 myEdgeActor->GetProperty()->SetLineWidth(5);
71 myEdgeActor->GetProperty()->SetRepresentationToWireframe();
73 myPointActor = VTKViewer_Actor::New();
74 myPointActor->PickableOff();
75 myPointActor->GetProperty()->SetColor(1,1,0);
76 myPointActor->GetProperty()->SetPointSize(5);
77 myPointActor->GetProperty()->SetRepresentationToPoints();
79 connect(mTimer, SIGNAL(timeout()), this, SLOT(TimerFunc())) ;
83 VTKViewer_RenderWindowInteractor::~VTKViewer_RenderWindowInteractor()
87 if ( GetRenderWindow() ) {
88 myViewWnd->RemoveActor(myCellActor);
89 myViewWnd->RemoveActor(myEdgeActor);
90 myViewWnd->RemoveActor(myPointActor);
93 myCellActor->Delete();
94 myEdgeActor->Delete();
95 myPointActor->Delete();
97 myBasicPicker->Delete();
98 myCellPicker->Delete();
99 myPointPicker->Delete();
102 void VTKViewer_RenderWindowInteractor::PrintSelf(ostream& os, vtkIndent indent)
104 vtkRenderWindowInteractor::PrintSelf(os, indent) ;
106 // :NOTE: Fri Apr 21 21:51:05 2000 Pagey
107 // QGL specific stuff goes here. One should add output
108 // lines here if any protected members are added to
114 * Initializes the event handlers without an XtAppContext. This is \n
115 * good for when you don`t have a user interface, but you still \n
116 * want to have mouse interaction.\n
117 * We never allow the VTKViewer_RenderWindowInteractor to control \n
118 * the event loop. The application always has the control.
120 void VTKViewer_RenderWindowInteractor::Initialize()
123 // We cannot do much unless there is a render window
124 // associated with this interactor.
126 if( ! RenderWindow ) {
127 vtkErrorMacro(<< "VTKViewer_RenderWindowInteractor::Initialize(): No render window attached!") ;
132 // We cannot hand a render window which is not a VTKViewer_RenderWindow.
133 // One way to force this is to use dynamic_cast and hope that
134 // it works. If the dynamic_cast does not work, we flag an error
135 // and get the hell out.
137 vtkRenderWindow *my_render_win = dynamic_cast<vtkRenderWindow *>(RenderWindow) ;
138 if( !my_render_win ) {
139 vtkErrorMacro(<< "VTKViewer_RenderWindowInteractor::Initialize() can only handle VTKViewer_RenderWindow.") ;
144 // If the render window has zero size, then set it to a default
147 int* aSize = my_render_win->GetSize();
148 this->Size[0] = ((aSize[0] > 0) ? aSize[0] : 300);
149 this->Size[1] = ((aSize[1] > 0) ? aSize[1] : 300);
151 this->SetPicker(myBasicPicker);
153 SetSelectionTolerance();
156 // Enable the interactor.
161 // Start the rendering of the window.
163 my_render_win->Start() ;
166 // The interactor has been initialized.
168 this->Initialized = 1 ;
173 /*!Sets view window and add to it selection actors.*/
174 void VTKViewer_RenderWindowInteractor::setViewWindow(VTKViewer_ViewWindow* theViewWnd){
175 myViewWnd = theViewWnd;
178 myViewWnd->InsertActor(myCellActor);
179 myViewWnd->InsertActor(myEdgeActor);
180 myViewWnd->InsertActor(myPointActor);
184 /*!Move selection actors to view window.*/
185 void VTKViewer_RenderWindowInteractor::MoveInternalActors()
187 myViewWnd->MoveActor(myCellActor);
188 myViewWnd->MoveActor(myEdgeActor);
189 myViewWnd->MoveActor(myPointActor);
192 /*!Sets interactor style.*/
193 void VTKViewer_RenderWindowInteractor::SetInteractorStyle(vtkInteractorObserver *theInteractor){
194 myInteractorStyle = dynamic_cast<VTKViewer_InteractorStyle*>(theInteractor);
195 vtkRenderWindowInteractor::SetInteractorStyle(theInteractor);
200 void VTKViewer_RenderWindowInteractor::SetSelectionMode(Selection_Mode theMode)
202 myCellActor->SetVisibility(false);
203 myEdgeActor->SetVisibility(false);
204 myPointActor->SetVisibility(false);
208 this->SetPicker(myBasicPicker);
211 this->SetPicker(myPointPicker);
216 case VolumeSelection:
217 case EdgeOfCellSelection:
218 this->SetPicker(myCellPicker);
222 myInteractorStyle->OnSelectionModeChanged();
226 /*!Sets selection properties.
227 *\param theRed - red component of color
228 *\param theGreen - green component of color
229 *\param theBlue - blue component of color
230 *\param theWidth - point size and line width
232 void VTKViewer_RenderWindowInteractor::SetSelectionProp(const double& theRed, const double& theGreen,
233 const double& theBlue, const int& theWidth)
235 myCellActor->GetProperty()->SetColor(theRed, theGreen, theBlue);
236 myCellActor->GetProperty()->SetLineWidth(theWidth);
238 myPointActor->GetProperty()->SetColor(theRed, theGreen, theBlue);
239 myPointActor->GetProperty()->SetPointSize(theWidth);
242 /*!Sets selection tolerance
243 *\param theTolNodes - nodes selection tolerance
244 *\param theTolItems - selection tolerance for basic and cell pickers.
246 void VTKViewer_RenderWindowInteractor::SetSelectionTolerance(const double& theTolNodes, const double& theTolItems)
248 myTolNodes = theTolNodes;
249 myTolItems = theTolItems;
251 myBasicPicker->SetTolerance(myTolItems);
252 myCellPicker->SetTolerance(myTolItems);
253 myPointPicker->SetTolerance(myTolNodes);
258 * Enable/Disable interactions. By default interactors are enabled when \n
259 * initialized. Initialize() must be called prior to enabling/disabling \n
260 * interaction. These methods are used when a window/widget is being \n
261 * shared by multiple renderers and interactors. This allows a "modal" \n
262 * display where one interactor is active when its data is to be displayed \n
263 * and all other interactors associated with the widget are disabled \n
264 * when their data is not displayed.
266 void VTKViewer_RenderWindowInteractor::Enable()
269 // Do not need to do anything if already enabled.
271 if( this->Enabled ) {
280 void VTKViewer_RenderWindowInteractor::Disable()
282 if( ! this->Enabled ) {
291 * This will start up the X event loop and never return. If you \n
292 * call this method it will loop processing X events until the \n
293 * application is exited.
295 void VTKViewer_RenderWindowInteractor::Start()
298 // We do not allow this interactor to control the
299 // event loop. Only the QtApplication objects are
300 // allowed to do that.
302 vtkErrorMacro(<<"VTKViewer_RenderWindowInteractor::Start() not allowed to start event loop.") ;
306 * Event loop notification member for Window size change
308 void VTKViewer_RenderWindowInteractor::UpdateSize(int w, int h)
310 // if the size changed send this on to the RenderWindow
311 if ((w != this->Size[0])||(h != this->Size[1])) {
314 this->RenderWindow->SetSize(w,h);
319 * Timer methods must be overridden by platform dependent subclasses.
320 * flag is passed to indicate if this is first timer set or an update
321 * as Win32 uses repeating timers, whereas X uses One shot more timer
322 * if flag == VTKXI_TIMER_FIRST Win32 and X should createtimer
323 * otherwise Win32 should exit and X should perform AddTimeOut
326 int VTKViewer_RenderWindowInteractor::CreateTimer(int vtkNotUsed(timertype))
329 /// Start a one-shot timer for 10ms.
331 mTimer->start(10, TRUE) ;
335 /**@see CreateTimer(int )
338 int VTKViewer_RenderWindowInteractor::DestroyTimer(void)
341 // :TRICKY: Tue May 2 00:17:32 2000 Pagey
343 /*! QTimer will automatically expire after 10ms. So
344 * we do not need to do anything here. In fact, we
345 * should not even Stop() the QTimer here because doing
346 * this will skip some of the processing that the TimerFunc()
347 * does and will result in undesirable effects. For
348 * example, this will result in vtkLODActor to leave
349 * the models in low-res mode after the mouse stops
355 /*! Not all of these slots are needed in VTK_MAJOR_VERSION=3,\n
356 * but moc does not understand "#if VTK_MAJOR_VERSION". Hence, \n
357 * we have to include all of these for the time being. Once,\n
358 * this bug in MOC is fixed, we can separate these.
360 void VTKViewer_RenderWindowInteractor::TimerFunc()
362 if( ! this->Enabled ) {
366 ((vtkInteractorStyle*)this->InteractorStyle)->OnTimer() ;
367 emit RenderWindowModified() ;
370 /*!Emit render window modified on mouse move,\n
371 *if interactor style needs redrawing and render window enabled.*/
372 void VTKViewer_RenderWindowInteractor::MouseMove(QMouseEvent *event) {
373 if( ! this->Enabled ) {
376 myInteractorStyle->OnMouseMove(0, 0, event->x(), event->y()/*this->Size[1] - event->y() - 1*/) ;
377 if (myInteractorStyle->needsRedrawing() )
378 emit RenderWindowModified() ;
381 /*!Reaction on left button pressed.\n
382 *Same as left button down for interactor style.\n
383 *If render window enabled.
385 void VTKViewer_RenderWindowInteractor::LeftButtonPressed(const QMouseEvent *event) {
386 if( ! this->Enabled ) {
389 myInteractorStyle->OnLeftButtonDown((event->state() & ControlButton),
390 (event->state() & ShiftButton),
391 event->x(), event->y());
394 /*!Reaction on left button releases.\n
395 *Same as left button up for interactor style.\n
396 *If render window enabled.
398 void VTKViewer_RenderWindowInteractor::LeftButtonReleased(const QMouseEvent *event) {
399 if( ! this->Enabled ) {
402 myInteractorStyle->OnLeftButtonUp( (event->state() & ControlButton),
403 (event->state() & ShiftButton),
404 event->x(), event->y() ) ;
407 /*!Reaction on middle button pressed.\n
408 *Same as middle button down for interactor style.\n
409 *If render window enabled.
411 void VTKViewer_RenderWindowInteractor::MiddleButtonPressed(const QMouseEvent *event) {
412 if( ! this->Enabled ) {
415 myInteractorStyle->OnMiddleButtonDown((event->state() & ControlButton),
416 (event->state() & ShiftButton),
417 event->x(), event->y() ) ;
420 /*!Reaction on middle button released.\n
421 *Same as middle button up for interactor style.\n
422 *If render window enabled.
424 void VTKViewer_RenderWindowInteractor::MiddleButtonReleased(const QMouseEvent *event) {
425 if( ! this->Enabled ) {
428 myInteractorStyle->OnMiddleButtonUp( (event->state() & ControlButton),
429 (event->state() & ShiftButton),
430 event->x(), event->y() ) ;
433 /*!Reaction on right button pressed.\n
434 *Same as right button down for interactor style.\n
435 *If render window enabled.
437 void VTKViewer_RenderWindowInteractor::RightButtonPressed(const QMouseEvent *event) {
438 if( ! this->Enabled ) {
441 myInteractorStyle->OnRightButtonDown( (event->state() & ControlButton),
442 (event->state() & ShiftButton),
443 event->x(), event->y() ) ;
446 /*!Reaction on right button released.\n
447 *Same as right button up for interactor style.If render window enabled.\n
448 *Emit context menu requested, if interactor style state equal VTK_INTERACTOR_STYLE_CAMERA_NONE.
450 void VTKViewer_RenderWindowInteractor::RightButtonReleased(const QMouseEvent *event) {
451 if( ! this->Enabled ) {
454 bool isOperation = myInteractorStyle->CurrentState() != VTK_INTERACTOR_STYLE_CAMERA_NONE;
455 myInteractorStyle->OnRightButtonUp( (event->state() & ControlButton),
456 (event->state() & ShiftButton),
457 event->x(), event->y() );
460 QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
461 event->pos(), event->globalPos(),
463 emit contextMenuRequested( &aEvent );
467 /*!Reaction on button pressed.
468 *\warning Do nothing.
470 void VTKViewer_RenderWindowInteractor::ButtonPressed(const QMouseEvent *event) {
474 /*!Reaction on button released..
475 *\warning Do nothing.
477 void VTKViewer_RenderWindowInteractor::ButtonReleased(const QMouseEvent *event) {
481 /*!Gets display mode.*/
482 int VTKViewer_RenderWindowInteractor::GetDisplayMode() {
483 return myDisplayMode;
486 /*!Sets display mode.*/
487 void VTKViewer_RenderWindowInteractor::SetDisplayMode(int theMode) {
489 ChangeRepresentationToWireframe();
491 ChangeRepresentationToSurface();
492 myDisplayMode = theMode;
495 /*!Change all actors to wireframe*/
496 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToWireframe()
498 ChangeRepresentationToWireframe(GetRenderer()->GetActors());
501 /*!Change all actors to surface*/
502 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToSurface()
504 ChangeRepresentationToSurface(GetRenderer()->GetActors());
507 /*!Change all actors from \a theCollection to wireframe and
508 * emit render window modified.
510 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToWireframe(vtkActorCollection* theCollection)
513 ForEach<VTKViewer_Actor>(theCollection,
514 TSetFunction<VTKViewer_Actor,int>
515 (&VTKViewer_Actor::setDisplayMode,0));
516 emit RenderWindowModified();
519 /*!Change all actors from \a theCollection to surface and
520 * emit render window modified.
522 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToSurface(vtkActorCollection* theCollection)
525 ForEach<VTKViewer_Actor>(theCollection,
526 TSetFunction<VTKViewer_Actor,int>
527 (&VTKViewer_Actor::setDisplayMode,1));
528 emit RenderWindowModified();
532 vtkRenderer* VTKViewer_RenderWindowInteractor::GetRenderer()
534 vtkRendererCollection * theRenderers = this->RenderWindow->GetRenderers();
535 theRenderers->InitTraversal();
536 return theRenderers->GetNextItem();
540 void VTKViewer_RenderWindowInteractor::EraseAll()
544 /*!Display all actors.
545 *Sets visible for all actors from renderer collection and emit render window modified.
547 void VTKViewer_RenderWindowInteractor::DisplayAll()
550 vtkActorCollection* aCollection = GetRenderer()->GetActors();
551 ForEach<VTKViewer_Actor>(aCollection,TSetVisibility<VTKViewer_Actor>(true));
553 emit RenderWindowModified() ;
557 void VTKViewer_RenderWindowInteractor::Erase( VTKViewer_Actor* SActor, bool update)
561 /*!Remove \a SActor from renderer and emit update window, if \a updateViewer - true*/
562 void VTKViewer_RenderWindowInteractor::Remove( VTKViewer_Actor* SActor, bool updateViewer )
566 GetRenderer()->RemoveProp( SActor );
568 emit RenderWindowModified();
572 /*!Remove actors from render window collection(not implemented).
573 *Emit render window modified, if \a updateViewer - true.
575 void VTKViewer_RenderWindowInteractor::RemoveAll( const bool updateViewer )
577 vtkRenderer* aRenderer = GetRenderer();
578 vtkActorCollection* anActors = aRenderer->GetActors();
581 anActors->InitTraversal();
582 while ( vtkActor *anAct = anActors->GetNextActor() )
584 if ( anAct->IsA( "VTKViewer_Actor" ) )
590 emit RenderWindowModified();
594 /*!\brief Display the \a theActor.*/
595 /*! Add actor to renderer and set visibility to true.
596 * Emit render window modified, if \a update - true.
598 void VTKViewer_RenderWindowInteractor::Display( VTKViewer_Actor* theActor, bool update)
600 GetRenderer()->AddActor(theActor);
601 theActor->SetVisibility(true);
604 emit RenderWindowModified();
607 void VTKViewer_RenderWindowInteractor::KeyPressed(QKeyEvent *event)
612 /*!Structure with one function "operator()", which call apply properties for actor.*/
613 struct TUpdateAction{
614 /*!Apply properties for \a theActor.*/
615 void operator()(vtkActor* theActor){
616 theActor->ApplyProperties();
620 /*!Update all actors from renderer and emit render window modified.*/
621 void VTKViewer_RenderWindowInteractor::Update() {
623 vtkRenderer* aRen = GetRenderer();
624 ForEach<vtkActor>(aRen->GetActors(),TUpdateAction());
628 emit RenderWindowModified();
631 /*!Unhighlight all selection actors.*/
632 void VTKViewer_RenderWindowInteractor::unHighlightSubSelection(){
633 myPointActor->SetVisibility(false);
634 myEdgeActor->SetVisibility(false);
635 myCellActor->SetVisibility(false);
638 /*!@see unHighlightSubSelection()
639 * Also emit render window modified.
641 bool VTKViewer_RenderWindowInteractor::unHighlightAll(){
642 unHighlightSubSelection();
644 emit RenderWindowModified() ;
649 /*! \li Sets actors data and sets visibility to true, if flag \a hilight - true,
650 * else sets visibility to false.
651 * \li Emit render window modified, if flag \a update - true.
653 bool VTKViewer_RenderWindowInteractor::highlight(const TColStd_IndexedMapOfInteger& theMapIndex,
654 VTKViewer_Actor* theMapActor, VTKViewer_Actor* theActor,
655 TUpdateActor theFun, bool hilight, bool update)
657 if(theMapIndex.Extent() == 0) return false;
660 setActorData(theMapIndex,theMapActor,theActor,theFun);
661 theActor->SetVisibility(true);
664 theActor->SetVisibility(false);
668 this->RenderWindow->Render();
669 emit RenderWindowModified() ;
675 /*!Sets actors data.*/
676 void VTKViewer_RenderWindowInteractor::setActorData(const TColStd_IndexedMapOfInteger& theMapIndex,
677 VTKViewer_Actor * theMapActor,
678 VTKViewer_Actor * theActor,
681 (*theFun)(theMapIndex,theMapActor,theActor);
683 theMapActor->GetPosition(aPos);
684 theActor->SetPosition(aPos);