Salome HOME
Merge with branch V2_2_0_VISU_improvement
[modules/gui.git] / src / VTKViewer / VTKViewer_RenderWindowInteractor.cxx
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"
6
7 //#include "SUIT_Application.h"
8 //#include "SUIT_Desktop.h"
9
10 //#include "SALOME_Selection.h"
11 #include "VTKViewer_Actor.h"
12 #include "VTKViewer_Algorithm.h"
13 #include "VTKViewer_Functor.h"
14
15 //#include <stdio.h>
16 //#include <stdlib.h>
17 //#include <string.h>
18 //#include <math.h>
19
20 // VTK Includes
21 #include <vtkAssemblyNode.h>
22 #include <vtkActor.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>
36
37 // QT Includes
38 #include <qkeycode.h>
39
40 //****************************************************************
41 VTKViewer_RenderWindowInteractor* VTKViewer_RenderWindowInteractor::New() 
42 {
43   vtkObject *ret = vtkObjectFactory::CreateInstance("VTKViewer_RenderWindowInteractor") ;
44   if( ret ) {
45     return dynamic_cast<VTKViewer_RenderWindowInteractor *>(ret) ;
46   }
47   return new VTKViewer_RenderWindowInteractor;
48 }
49
50 //****************************************************************
51 VTKViewer_RenderWindowInteractor::VTKViewer_RenderWindowInteractor() 
52 {
53   this->Enabled = 0 ;
54   this->mTimer = new QTimer( this ) ;
55   myDisplayMode = 0;
56
57   myBasicPicker = vtkPicker::New();
58   myCellPicker = vtkCellPicker::New();
59   myPointPicker = vtkPointPicker::New();
60
61   myCellActor = VTKViewer_Actor::New(); 
62   myCellActor->PickableOff();
63   myCellActor->GetProperty()->SetColor(1,1,0);
64   myCellActor->GetProperty()->SetLineWidth(5);
65   myCellActor->GetProperty()->SetRepresentationToSurface();
66
67   myEdgeActor = VTKViewer_Actor::New(); 
68   myEdgeActor->PickableOff();
69   myEdgeActor->GetProperty()->SetColor(1,0,0);
70   myEdgeActor->GetProperty()->SetLineWidth(5);
71   myEdgeActor->GetProperty()->SetRepresentationToWireframe();
72
73   myPointActor = VTKViewer_Actor::New(); 
74   myPointActor->PickableOff();
75   myPointActor->GetProperty()->SetColor(1,1,0);
76   myPointActor->GetProperty()->SetPointSize(5);
77   myPointActor->GetProperty()->SetRepresentationToPoints();
78
79   connect(mTimer, SIGNAL(timeout()), this, SLOT(TimerFunc())) ;
80 }
81
82 //****************************************************************
83 VTKViewer_RenderWindowInteractor::~VTKViewer_RenderWindowInteractor() 
84 {
85   delete mTimer ;
86
87   if ( GetRenderWindow() ) {
88     myViewWnd->RemoveActor(myCellActor);
89     myViewWnd->RemoveActor(myEdgeActor);
90     myViewWnd->RemoveActor(myPointActor);
91   }
92
93   myCellActor->Delete();
94   myEdgeActor->Delete();
95   myPointActor->Delete();
96
97   myBasicPicker->Delete();
98   myCellPicker->Delete();
99   myPointPicker->Delete();
100 }
101
102 //****************************************************************
103 void VTKViewer_RenderWindowInteractor::PrintSelf(ostream& os, vtkIndent indent) 
104 {
105   vtkRenderWindowInteractor::PrintSelf(os, indent) ;
106   //
107   // :NOTE: Fri Apr 21 21:51:05 2000 Pagey
108   // QGL specific stuff goes here. One should add output 
109   // lines here if any protected members are added to
110   // the class. 
111   //
112 }
113
114 //****************************************************************
115 // We never allow the VTKViewer_RenderWindowInteractor to control 
116 // the event loop. The application always has the control. 
117 //
118 void VTKViewer_RenderWindowInteractor::Initialize()
119 {
120   //
121   // We cannot do much unless there is a render window 
122   // associated with this interactor. 
123   //
124   if( ! RenderWindow ) {
125     vtkErrorMacro(<< "VTKViewer_RenderWindowInteractor::Initialize(): No render window attached!") ;
126     return ;
127   }
128   
129   //
130   // We cannot hand a render window which is not a VTKViewer_RenderWindow. 
131   // One way to force this is to use dynamic_cast and hope that 
132   // it works. If the dynamic_cast does not work, we flag an error
133   // and get the hell out.
134   //
135   vtkRenderWindow *my_render_win = dynamic_cast<vtkRenderWindow *>(RenderWindow) ;
136   if( !my_render_win ) {
137     vtkErrorMacro(<< "VTKViewer_RenderWindowInteractor::Initialize() can only handle VTKViewer_RenderWindow.") ;
138     return ;
139   }
140  
141   //
142   // If the render window has zero size, then set it to a default 
143   // value of 300x300.
144   // 
145   int* aSize = my_render_win->GetSize();
146   this->Size[0] = ((aSize[0] > 0) ? aSize[0] : 300);
147   this->Size[1] = ((aSize[1] > 0) ? aSize[1] : 300);
148
149   this->SetPicker(myBasicPicker);
150
151   SetSelectionTolerance();
152
153   //
154   // Enable the interactor. 
155   //
156   this->Enable() ;
157   
158   //
159   // Start the rendering of the window. 
160   //
161   my_render_win->Start() ;
162   
163   //
164   // The interactor has been initialized.
165   //
166   this->Initialized = 1 ;
167
168   return ;
169 }
170
171
172 //----------------------------------------------------------------------------
173 void VTKViewer_RenderWindowInteractor::setViewWindow(VTKViewer_ViewWindow* theViewWnd){
174   myViewWnd = theViewWnd;
175
176   if ( myViewWnd ) {
177     myViewWnd->InsertActor(myCellActor);
178     myViewWnd->InsertActor(myEdgeActor);
179     myViewWnd->InsertActor(myPointActor);
180   }
181 }
182
183 //----------------------------------------------------------------------------
184 void VTKViewer_RenderWindowInteractor::MoveInternalActors()
185 {
186   myViewWnd->MoveActor(myCellActor);
187   myViewWnd->MoveActor(myEdgeActor);
188   myViewWnd->MoveActor(myPointActor);
189 }
190
191 //----------------------------------------------------------------------------
192 void VTKViewer_RenderWindowInteractor::SetInteractorStyle(vtkInteractorObserver *theInteractor){
193   myInteractorStyle = dynamic_cast<VTKViewer_InteractorStyle*>(theInteractor);
194   vtkRenderWindowInteractor::SetInteractorStyle(theInteractor);
195 }
196
197
198 /*void VTKViewer_RenderWindowInteractor::SetSelectionMode(Selection_Mode theMode)
199 {
200   myCellActor->SetVisibility(false);
201   myEdgeActor->SetVisibility(false);
202   myPointActor->SetVisibility(false);
203
204   switch(theMode){
205   case ActorSelection:
206     this->SetPicker(myBasicPicker);
207     break;
208   case NodeSelection:
209     this->SetPicker(myPointPicker);
210     break;
211   case CellSelection:
212   case EdgeSelection:
213   case FaceSelection:
214   case VolumeSelection:
215   case EdgeOfCellSelection:
216     this->SetPicker(myCellPicker);
217     break;
218   }
219
220   myInteractorStyle->OnSelectionModeChanged();
221 }*/
222
223 //****************************************************************
224 void VTKViewer_RenderWindowInteractor::SetSelectionProp(const double& theRed, const double& theGreen, 
225                                                         const double& theBlue, const int& theWidth) 
226 {
227   myCellActor->GetProperty()->SetColor(theRed, theGreen, theBlue);
228   myCellActor->GetProperty()->SetLineWidth(theWidth);
229
230   myPointActor->GetProperty()->SetColor(theRed, theGreen, theBlue);
231   myPointActor->GetProperty()->SetPointSize(theWidth);
232 }
233
234 //****************************************************************
235 void VTKViewer_RenderWindowInteractor::SetSelectionTolerance(const double& theTolNodes, const double& theTolItems)
236 {
237   myTolNodes = theTolNodes;
238   myTolItems = theTolItems;
239
240   myBasicPicker->SetTolerance(myTolItems);
241   myCellPicker->SetTolerance(myTolItems);
242   myPointPicker->SetTolerance(myTolNodes);
243
244 }
245
246 //****************************************************************
247 void VTKViewer_RenderWindowInteractor::Enable()
248 {
249   //
250   // Do not need to do anything if already enabled.
251   //
252   if( this->Enabled ) {
253     return ;
254   }
255   
256   this->Enabled = 1 ;
257   this->Modified() ;
258 }
259
260 //****************************************************************
261 void VTKViewer_RenderWindowInteractor::Disable()
262 {
263   if( ! this->Enabled ) {
264     return ;
265   }
266   
267   this->Enabled = 0 ;
268   this->Modified() ;
269 }
270
271 //****************************************************************
272 void VTKViewer_RenderWindowInteractor::Start()
273 {
274   //
275   // We do not allow this interactor to control the 
276   // event loop. Only the QtApplication objects are
277   // allowed to do that. 
278   //
279   vtkErrorMacro(<<"VTKViewer_RenderWindowInteractor::Start() not allowed to start event loop.") ;
280 }
281
282 //****************************************************************
283 void VTKViewer_RenderWindowInteractor::UpdateSize(int w, int h)
284 {
285   // if the size changed send this on to the RenderWindow
286   if ((w != this->Size[0])||(h != this->Size[1])) {
287     this->Size[0] = w;
288     this->Size[1] = h;
289     this->RenderWindow->SetSize(w,h);
290   }
291 }
292
293 //****************************************************************
294 int VTKViewer_RenderWindowInteractor::CreateTimer(int vtkNotUsed(timertype))
295 {
296   //
297   // Start a one-shot timer for 10ms. 
298   //
299   mTimer->start(10, TRUE) ;
300   return 1 ;
301 }
302
303 //****************************************************************
304 int VTKViewer_RenderWindowInteractor::DestroyTimer(void)
305 {
306   //
307   // :TRICKY: Tue May  2 00:17:32 2000 Pagey
308   //
309   // QTimer will automatically expire after 10ms. So 
310   // we do not need to do anything here. In fact, we 
311   // should not even Stop() the QTimer here because doing 
312   // this will skip some of the processing that the TimerFunc()
313   // does and will result in undesirable effects. For 
314   // example, this will result in vtkLODActor to leave
315   // the models in low-res mode after the mouse stops
316   // moving. 
317   //
318   return 1 ;
319 }
320
321 //****************************************************************
322 void VTKViewer_RenderWindowInteractor::TimerFunc()
323 {
324   if( ! this->Enabled ) {
325     return ;
326   }
327   
328   ((vtkInteractorStyle*)this->InteractorStyle)->OnTimer() ;
329   emit RenderWindowModified() ;
330 }
331
332 void VTKViewer_RenderWindowInteractor::MouseMove(QMouseEvent *event) {
333   if( ! this->Enabled ) {
334     return ;
335   }
336   myInteractorStyle->OnMouseMove(0, 0, event->x(), event->y()/*this->Size[1] - event->y() - 1*/) ;
337   if (myInteractorStyle->needsRedrawing() )
338     emit RenderWindowModified() ; 
339 }
340
341 void VTKViewer_RenderWindowInteractor::LeftButtonPressed(const QMouseEvent *event) {
342   if( ! this->Enabled ) {
343     return ;
344   }
345   myInteractorStyle->OnLeftButtonDown((event->state() & ControlButton), 
346                                       (event->state() & ShiftButton), 
347                                       event->x(), event->y());
348 }
349
350 void VTKViewer_RenderWindowInteractor::LeftButtonReleased(const QMouseEvent *event) {
351   if( ! this->Enabled ) {
352     return ;
353   }
354   myInteractorStyle->OnLeftButtonUp( (event->state() & ControlButton), 
355                                      (event->state() & ShiftButton), 
356                                      event->x(), event->y() ) ;
357 }
358
359 void VTKViewer_RenderWindowInteractor::MiddleButtonPressed(const QMouseEvent *event) {
360   if( ! this->Enabled ) {
361     return ;
362   }
363   myInteractorStyle->OnMiddleButtonDown((event->state() & ControlButton), 
364                                         (event->state() & ShiftButton), 
365                                         event->x(), event->y() ) ;
366 }
367
368 void VTKViewer_RenderWindowInteractor::MiddleButtonReleased(const QMouseEvent *event) {
369   if( ! this->Enabled ) {
370     return ;
371   }
372   myInteractorStyle->OnMiddleButtonUp( (event->state() & ControlButton), 
373                                        (event->state() & ShiftButton), 
374                                        event->x(), event->y() ) ;
375 }
376
377 void VTKViewer_RenderWindowInteractor::RightButtonPressed(const QMouseEvent *event) {
378   if( ! this->Enabled ) {
379     return ;
380   }
381   myInteractorStyle->OnRightButtonDown( (event->state() & ControlButton), 
382                                         (event->state() & ShiftButton), 
383                                         event->x(), event->y() ) ;
384 }
385
386 void VTKViewer_RenderWindowInteractor::RightButtonReleased(const QMouseEvent *event) {
387   if( ! this->Enabled ) {
388     return ;
389   }
390   bool isOperation = myInteractorStyle->CurrentState() != VTK_INTERACTOR_STYLE_CAMERA_NONE;
391   myInteractorStyle->OnRightButtonUp( (event->state() & ControlButton),
392                                       (event->state() & ShiftButton),
393                                       event->x(), event->y() );
394   if ( !isOperation )
395   {
396     QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
397                               event->pos(), event->globalPos(),
398                               event->state() );
399     emit contextMenuRequested( &aEvent );
400   }
401 }
402
403 void VTKViewer_RenderWindowInteractor::ButtonPressed(const QMouseEvent *event) {
404   return ;
405 }
406
407 void VTKViewer_RenderWindowInteractor::ButtonReleased(const QMouseEvent *event) {
408   return ;
409 }
410
411
412 int VTKViewer_RenderWindowInteractor::GetDisplayMode() {
413   return myDisplayMode;
414 }
415
416 void VTKViewer_RenderWindowInteractor::SetDisplayMode(int theMode) {
417   if(theMode == 0)
418     ChangeRepresentationToWireframe();
419   else
420     ChangeRepresentationToSurface();
421   myDisplayMode = theMode;
422 }
423
424 //****************************************************************
425 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToWireframe()
426 // change all actors to wireframe
427 {
428   ChangeRepresentationToWireframe(GetRenderer()->GetActors());
429 }
430
431 //****************************************************************
432 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToSurface()
433 {
434   ChangeRepresentationToSurface(GetRenderer()->GetActors());
435 }
436
437
438 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToWireframe(vtkActorCollection* theCollection)
439 {
440   using namespace VTK;
441   ForEach<VTKViewer_Actor>(theCollection,
442                         TSetFunction<VTKViewer_Actor,int>
443                         (&VTKViewer_Actor::setDisplayMode,0));
444   emit RenderWindowModified();
445 }
446
447 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToSurface(vtkActorCollection* theCollection)
448 {
449   using namespace VTK;
450   ForEach<VTKViewer_Actor>(theCollection,
451                         TSetFunction<VTKViewer_Actor,int>
452                         (&VTKViewer_Actor::setDisplayMode,1));
453   emit RenderWindowModified();
454 }
455
456 //****************************************************************
457 vtkRenderer* VTKViewer_RenderWindowInteractor::GetRenderer()
458 {
459   vtkRendererCollection * theRenderers =  this->RenderWindow->GetRenderers();
460   theRenderers->InitTraversal();
461   return theRenderers->GetNextItem();
462 }
463
464 //****************************************************************
465 void VTKViewer_RenderWindowInteractor::EraseAll()
466 {
467 }
468
469 //****************************************************************
470 void VTKViewer_RenderWindowInteractor::DisplayAll()
471 {
472   using namespace VTK;
473   vtkActorCollection* aCollection = GetRenderer()->GetActors();
474   ForEach<VTKViewer_Actor>(aCollection,TSetVisibility<VTKViewer_Actor>(true));
475
476   emit RenderWindowModified() ;
477 }
478
479 //****************************************************************
480 void VTKViewer_RenderWindowInteractor::Erase( VTKViewer_Actor* SActor, bool update)
481 {
482 }
483
484 void VTKViewer_RenderWindowInteractor::Remove( VTKViewer_Actor* SActor, bool updateViewer )
485 {
486   if ( SActor != 0 )
487   {
488     GetRenderer()->RemoveProp( SActor );
489     if ( updateViewer )
490       emit RenderWindowModified();
491   }
492 }
493
494 void VTKViewer_RenderWindowInteractor::RemoveAll( const bool updateViewer )
495 {
496   vtkRenderer* aRenderer = GetRenderer();
497   vtkActorCollection* anActors = aRenderer->GetActors();
498   if ( anActors )
499   {
500     anActors->InitTraversal();
501     while ( vtkActor *anAct = anActors->GetNextActor() )
502     {
503       if ( anAct->IsA( "VTKViewer_Actor" ) )
504       {
505       }
506     }
507
508     if ( updateViewer )
509       emit RenderWindowModified();
510   }
511 }
512
513
514
515
516 void VTKViewer_RenderWindowInteractor::Display( VTKViewer_Actor* theActor, bool update)
517 {
518   GetRenderer()->AddActor(theActor);
519   theActor->SetVisibility(true);
520
521   if(update)
522     emit RenderWindowModified();
523 }
524
525 void VTKViewer_RenderWindowInteractor::KeyPressed(QKeyEvent *event)
526 {
527   // NOT_IMPLEMENTED
528 }
529
530
531 struct TUpdateAction{
532   void operator()(vtkActor* theActor){
533     theActor->ApplyProperties();
534   }
535 };
536
537 void VTKViewer_RenderWindowInteractor::Update() {
538   using namespace VTK;
539   vtkRenderer* aRen = GetRenderer();
540   ForEach<vtkActor>(aRen->GetActors(),TUpdateAction());
541
542   aRen->ResetCamera();
543
544   emit RenderWindowModified();  
545 }
546
547
548 void VTKViewer_RenderWindowInteractor::unHighlightSubSelection(){
549   myPointActor->SetVisibility(false);
550   myEdgeActor->SetVisibility(false);
551   myCellActor->SetVisibility(false);
552 }
553
554 bool VTKViewer_RenderWindowInteractor::unHighlightAll(){
555   unHighlightSubSelection();
556
557   emit RenderWindowModified() ;
558   return false;
559 }
560
561
562 //----------------------------------------------------------------------------
563 bool VTKViewer_RenderWindowInteractor::highlight(const TColStd_IndexedMapOfInteger& theMapIndex,
564                                                  VTKViewer_Actor* theMapActor, VTKViewer_Actor* theActor,
565                                                  TUpdateActor theFun, bool hilight, bool update)
566 {
567   if(theMapIndex.Extent() == 0) return false;
568
569   if (hilight) {
570     setActorData(theMapIndex,theMapActor,theActor,theFun);
571     theActor->SetVisibility(true);
572   }
573   else {
574     theActor->SetVisibility(false);
575   }
576
577   if(update){
578     this->RenderWindow->Render();
579     emit RenderWindowModified() ;
580   }
581
582   return false;
583 }
584
585 void VTKViewer_RenderWindowInteractor::setActorData(const TColStd_IndexedMapOfInteger& theMapIndex,
586                                                     VTKViewer_Actor * theMapActor,
587                                                     VTKViewer_Actor * theActor,
588                                                     TUpdateActor theFun)
589 {
590   (*theFun)(theMapIndex,theMapActor,theActor);
591   float aPos[3];
592   theMapActor->GetPosition(aPos);
593   theActor->SetPosition(aPos);
594 }