Salome HOME
PR: merge from tag BR_CCRT2_mergeto_V2_1_0b1
[modules/kernel.git] / src / VTKViewer / VTKViewer_RenderWindowInteractor.cxx
1 //  SALOME VTKViewer : build VTK viewer into Salome desktop
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : VTKViewer_RenderWindowInteractor.cxx
25 //  Author : Nicolas REJNERI
26 //  Module : SALOME
27 //  $Header$
28
29 #include "VTKViewer_RenderWindowInteractor.h"
30
31 #include "VTKViewer_InteractorStyleSALOME.h"
32 #include "VTKViewer_RenderWindow.h"
33 #include "VTKViewer_ViewFrame.h"
34
35 #include "VTKViewer_Algorithm.h"
36 #include "VTKViewer_Functor.h"
37
38 #include "QAD_Application.h"
39 #include "QAD_Desktop.h"
40
41 #include "VTKViewer_Actor.h"
42
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <math.h>
47
48 // VTK Includes
49 #include <vtkObjectFactory.h>
50 #include <vtkPicker.h>
51 #include <vtkCellPicker.h>
52 #include <vtkPointPicker.h>
53 #include <vtkRendererCollection.h>
54
55 // QT Includes
56 #include <qkeycode.h>
57
58 #include <TColStd_IndexedMapOfInteger.hxx>
59
60 #include "utilities.h"
61
62 using namespace std;
63
64 #ifdef _DEBUG_
65 static int MYDEBUG = 0;
66 #else
67 static int MYDEBUG = 0;
68 #endif
69
70
71 VTKViewer_RenderWindowInteractor* VTKViewer_RenderWindowInteractor::New() {
72   vtkObject *ret = vtkObjectFactory::CreateInstance("VTKViewer_RenderWindowInteractor") ;
73   if( ret ) {
74     return dynamic_cast<VTKViewer_RenderWindowInteractor *>(ret) ;
75   }
76   return new VTKViewer_RenderWindowInteractor;
77 }
78
79 VTKViewer_RenderWindowInteractor::VTKViewer_RenderWindowInteractor() {
80   this->Enabled = 0 ;
81   this->mTimer = new QTimer( this ) ;
82   myDisplayMode = 0;
83   myGUIWindow = 0;
84
85   myBasicPicker = vtkPicker::New();
86   myCellPicker = vtkCellPicker::New();
87   myPointPicker = vtkPointPicker::New();
88
89   myCellActor = VTKViewer_Actor::New(); 
90   myCellActor->PickableOff();
91   myCellActor->GetProperty()->SetColor(1,1,0);
92   myCellActor->GetProperty()->SetLineWidth(5);
93   myCellActor->GetProperty()->SetRepresentationToSurface();
94
95   myEdgeActor = VTKViewer_Actor::New(); 
96   myEdgeActor->PickableOff();
97   myEdgeActor->GetProperty()->SetColor(1,0,0);
98   myEdgeActor->GetProperty()->SetLineWidth(5);
99   myEdgeActor->GetProperty()->SetRepresentationToWireframe();
100
101   myPointActor = VTKViewer_Actor::New(); 
102   myPointActor->PickableOff();
103   myPointActor->GetProperty()->SetColor(1,1,0);
104   myPointActor->GetProperty()->SetPointSize(5);
105   myPointActor->GetProperty()->SetRepresentationToPoints();
106
107   connect(mTimer, SIGNAL(timeout()), this, SLOT(TimerFunc())) ;
108 }
109
110
111 VTKViewer_RenderWindowInteractor::~VTKViewer_RenderWindowInteractor() {
112   if(MYDEBUG) INFOS("VTKViewer_RenderWindowInteractor::~VTKViewer_RenderWindowInteractor()");
113
114   delete mTimer ;
115
116   myViewFrame->RemoveActor(myCellActor);
117   myViewFrame->RemoveActor(myEdgeActor);
118   myViewFrame->RemoveActor(myPointActor);
119
120   myCellActor->Delete();
121   myEdgeActor->Delete();
122   myPointActor->Delete();
123
124   myBasicPicker->Delete();
125   myCellPicker->Delete();
126   myPointPicker->Delete();
127 }
128
129 void VTKViewer_RenderWindowInteractor::PrintSelf(ostream& os, vtkIndent indent) {
130   vtkRenderWindowInteractor::PrintSelf(os, indent) ;
131   //
132   // :NOTE: Fri Apr 21 21:51:05 2000 Pagey
133   // QGL specific stuff goes here. One should add output 
134   // lines here if any protected members are added to
135   // the class. 
136   //
137 }
138
139 //
140 // We never allow the VTKViewer_RenderWindowInteractor to control 
141 // the event loop. The application always has the control. 
142 //
143 void VTKViewer_RenderWindowInteractor::Initialize() {
144   //
145   // We cannot do much unless there is a render window 
146   // associated with this interactor. 
147   //
148   if( ! RenderWindow ) {
149     vtkErrorMacro(<< "VTKViewer_RenderWindowInteractor::Initialize(): No render window attached!") ;
150     return ;
151   }
152
153   //
154   // We cannot hand a render window which is not a VTKViewer_RenderWindow. 
155   // One way to force this is to use dynamic_cast and hope that 
156   // it works. If the dynamic_cast does not work, we flag an error
157   // and get the hell out.
158   //
159   vtkRenderWindow *my_render_win = dynamic_cast<vtkRenderWindow *>(RenderWindow) ;
160   if( !my_render_win ) {
161     vtkErrorMacro(<< "VTKViewer_RenderWindowInteractor::Initialize() can only handle VTKViewer_RenderWindow.") ;
162     return ;
163   }
164
165   //
166   // If the render window has zero size, then set it to a default 
167   // value of 300x300.
168   // 
169   int* aSize = my_render_win->GetSize();
170   this->Size[0] = ((aSize[0] > 0) ? aSize[0] : 300);
171   this->Size[1] = ((aSize[1] > 0) ? aSize[1] : 300);
172
173   this->SetPicker(myBasicPicker);
174
175   SetSelectionTolerance();
176
177   //
178   // Enable the interactor. 
179   //
180   this->Enable() ;
181
182   //
183   // Start the rendering of the window. 
184   //
185   my_render_win->Start() ;
186
187   //
188   // The interactor has been initialized.
189   //
190   this->Initialized = 1 ;
191
192   return ;
193 }
194
195
196 //----------------------------------------------------------------------------
197 void VTKViewer_RenderWindowInteractor::setGUIWindow(QWidget* theWindow){
198   myGUIWindow = theWindow;
199 }
200
201 //----------------------------------------------------------------------------
202 void VTKViewer_RenderWindowInteractor::setViewFrame(VTKViewer_ViewFrame* theViewFrame){
203   myViewFrame = theViewFrame;
204
205   myViewFrame->InsertActor(myCellActor);
206   myViewFrame->InsertActor(myEdgeActor);
207   myViewFrame->InsertActor(myPointActor);
208 }
209
210 //----------------------------------------------------------------------------
211 void VTKViewer_RenderWindowInteractor::MoveInternalActors()
212 {
213   myViewFrame->MoveActor(myCellActor);
214   myViewFrame->MoveActor(myEdgeActor);
215   myViewFrame->MoveActor(myPointActor);
216 }
217
218 //----------------------------------------------------------------------------
219 void VTKViewer_RenderWindowInteractor::SetInteractorStyle(vtkInteractorObserver *theInteractor){
220   myInteractorStyle = dynamic_cast<VTKViewer_InteractorStyleSALOME*>(theInteractor);
221   vtkRenderWindowInteractor::SetInteractorStyle(theInteractor);
222 }
223
224
225 void VTKViewer_RenderWindowInteractor::SetSelectionMode(Selection_Mode theMode)
226 {
227   myCellActor->SetVisibility(false);
228   myEdgeActor->SetVisibility(false);
229   myPointActor->SetVisibility(false);
230
231   switch(theMode){
232   case ActorSelection:
233     this->SetPicker(myBasicPicker);
234     break;
235   case NodeSelection:
236     this->SetPicker(myPointPicker);
237     break;
238   case CellSelection:
239   case EdgeSelection:
240   case FaceSelection:
241   case VolumeSelection:
242   case EdgeOfCellSelection:
243     this->SetPicker(myCellPicker);
244     break;
245   }
246
247   myInteractorStyle->OnSelectionModeChanged();
248 }
249
250 void VTKViewer_RenderWindowInteractor::SetSelectionProp(const double& theRed, const double& theGreen, 
251                                                         const double& theBlue, const int& theWidth) 
252 {
253   myCellActor->GetProperty()->SetColor(theRed, theGreen, theBlue);
254   myCellActor->GetProperty()->SetLineWidth(theWidth);
255
256   myPointActor->GetProperty()->SetColor(theRed, theGreen, theBlue);
257   myPointActor->GetProperty()->SetPointSize(theWidth);
258 }
259
260 void VTKViewer_RenderWindowInteractor::SetSelectionTolerance(const double& theTolNodes, const double& theTolItems)
261 {
262   myTolNodes = theTolNodes;
263   myTolItems = theTolItems;
264
265   myBasicPicker->SetTolerance(myTolItems);
266   myCellPicker->SetTolerance(myTolItems);
267   myPointPicker->SetTolerance(myTolNodes);
268
269 }
270
271 void VTKViewer_RenderWindowInteractor::Enable() {
272   //
273   // Do not need to do anything if already enabled.
274   //
275   if( this->Enabled ) {
276     return ;
277   }
278   
279   //
280   // Attach slots to every useful signal of the render window. 
281   //
282   this->ConnectSlots() ;
283   
284   this->Enabled = 1 ;
285   this->Modified() ;
286 }
287
288 void VTKViewer_RenderWindowInteractor::Disable() {
289   if( ! this->Enabled ) {
290     return ;
291   }
292
293   this->DisconnectSlots() ;
294   this->Enabled = 0 ;
295   this->Modified() ;
296 }
297
298 // ================================== 
299 void VTKViewer_RenderWindowInteractor::Start() {
300   //
301   // We do not allow this interactor to control the 
302   // event loop. Only the QtApplication objects are
303   // allowed to do that. 
304   //
305   vtkErrorMacro(<<"VTKViewer_RenderWindowInteractor::Start() not allowed to start event loop.") ;
306   return ;
307 }
308
309 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])) {
312     this->Size[0] = w;
313     this->Size[1] = h;
314     this->RenderWindow->SetSize(w,h);
315   }
316 }
317
318 int VTKViewer_RenderWindowInteractor::CreateTimer(int vtkNotUsed(timertype)) {
319   //
320   // Start a one-shot timer for 10ms. 
321   //
322   mTimer->start(10, TRUE) ;
323   return 1 ;
324 }
325
326 int VTKViewer_RenderWindowInteractor::DestroyTimer(void) {
327   //
328   // :TRICKY: Tue May  2 00:17:32 2000 Pagey
329   //
330   // QTimer will automatically expire after 10ms. So 
331   // we do not need to do anything here. In fact, we 
332   // should not even Stop() the QTimer here because doing 
333   // this will skip some of the processing that the TimerFunc()
334   // does and will result in undesirable effects. For 
335   // example, this will result in vtkLODActor to leave
336   // the models in low-res mode after the mouse stops
337   // moving. 
338   //
339   return 1 ;
340 }
341
342 void VTKViewer_RenderWindowInteractor::TimerFunc() {
343   if( ! this->Enabled ) {
344     return ;
345   }
346
347   ((vtkInteractorStyle*)this->InteractorStyle)->OnTimer() ;
348   emit RenderWindowModified() ;
349 }
350
351 void VTKViewer_RenderWindowInteractor::ConnectSlots() {
352   ProcessSlotConnections(true) ;
353 }
354
355 void VTKViewer_RenderWindowInteractor::DisconnectSlots() {
356   ProcessSlotConnections(false) ;
357 }
358
359 void VTKViewer_RenderWindowInteractor::ProcessSlotConnections(bool conn) {
360   //
361   // We cannot do much unless there is a render window 
362   // associated with this interactor. 
363   //
364   if( ! myGUIWindow ) {
365     vtkErrorMacro(<< "VTKViewer_RenderWindowInteractor::Initialize(): No render window attached!") ;
366     return ;
367   }
368
369   
370   bool (*slot_func) ( const QObject * sender, 
371                       const char * signal, 
372                       const QObject * receiver, 
373                       const char * member ) ;
374   if( conn ) {
375     slot_func = &QObject::connect ;
376   } else {
377     slot_func = &QObject::disconnect ;
378   }
379   //
380   // We cannot hand a render window which is not a VTKViewer_RenderWindow. 
381   // One way to force this is to use dynamic_cast and hope that 
382   // it works. If the dynamic_cast does not work, we flag an error
383   // and get the hell out.
384   //
385   if( ! myGUIWindow ) {
386     vtkErrorMacro(<< "VTKViewer_RenderWindowInteractor::Initialize() can only handle VTKViewer_RenderWindow.") ;
387     return ;
388   }
389
390   slot_func ( myGUIWindow, SIGNAL(ButtonPressed(const QMouseEvent *)), 
391               this,          SLOT(ButtonPressed(const QMouseEvent *)) ) ;
392   slot_func( myGUIWindow, SIGNAL(ButtonReleased(const QMouseEvent *)), 
393              this,          SLOT(ButtonReleased(const QMouseEvent *)) ) ;
394   
395   
396   slot_func( myGUIWindow, SIGNAL(LeftButtonPressed(const QMouseEvent *)), 
397              this,          SLOT(LeftButtonPressed(const QMouseEvent *)) ) ;
398   slot_func( myGUIWindow, SIGNAL(LeftButtonReleased(const QMouseEvent *)), 
399              this,          SLOT(LeftButtonReleased(const QMouseEvent *)) ) ;
400   
401   slot_func( myGUIWindow, SIGNAL(MiddleButtonPressed(const QMouseEvent *)), 
402              this,          SLOT(MiddleButtonPressed(const QMouseEvent *)) ) ;
403   slot_func( myGUIWindow, SIGNAL(MiddleButtonReleased(const QMouseEvent *)), 
404              this,          SLOT(MiddleButtonReleased(const QMouseEvent *)) ) ;
405   
406   slot_func( myGUIWindow, SIGNAL(RightButtonPressed(const QMouseEvent *)), 
407              this,          SLOT(RightButtonPressed(const QMouseEvent *)) ) ;
408   slot_func( myGUIWindow, SIGNAL(RightButtonReleased(const QMouseEvent *)), 
409              this,          SLOT(RightButtonReleased(const QMouseEvent *)) ) ;
410   
411   slot_func( myGUIWindow, SIGNAL(MouseMove(const QMouseEvent *)), 
412              this,          SLOT(MouseMove(const QMouseEvent *)) ) ;
413   
414   slot_func( myGUIWindow, SIGNAL(KeyPressed(QKeyEvent *)),
415              this,          SLOT(KeyPressed(QKeyEvent *)) ) ;
416   
417   slot_func( this,          SIGNAL(RenderWindowModified()), 
418              myGUIWindow, SLOT(update()) ) ;
419
420 }
421
422 void VTKViewer_RenderWindowInteractor::MouseMove(const QMouseEvent *event) {
423   if( ! this->Enabled ) {
424     return ;
425   }
426   myInteractorStyle->OnMouseMove(0, 0, event->x(), event->y()/*this->Size[1] - event->y() - 1*/) ;
427   if (myInteractorStyle->needsRedrawing() )
428     emit RenderWindowModified() ; 
429 }
430
431 void VTKViewer_RenderWindowInteractor::LeftButtonPressed(const QMouseEvent *event) {
432   if( ! this->Enabled ) {
433     return ;
434   }
435   myInteractorStyle->OnLeftButtonDown((event->state() & ControlButton), 
436                                       (event->state() & ShiftButton), 
437                                       event->x(), event->y());
438 }
439
440 void VTKViewer_RenderWindowInteractor::LeftButtonReleased(const QMouseEvent *event) {
441   if( ! this->Enabled ) {
442     return ;
443   }
444   myInteractorStyle->OnLeftButtonUp( (event->state() & ControlButton), 
445                                      (event->state() & ShiftButton), 
446                                      event->x(), event->y() ) ;
447 }
448
449 void VTKViewer_RenderWindowInteractor::MiddleButtonPressed(const QMouseEvent *event) {
450   if( ! this->Enabled ) {
451     return ;
452   }
453   myInteractorStyle->OnMiddleButtonDown((event->state() & ControlButton), 
454                                         (event->state() & ShiftButton), 
455                                         event->x(), event->y() ) ;
456 }
457
458 void VTKViewer_RenderWindowInteractor::MiddleButtonReleased(const QMouseEvent *event) {
459   if( ! this->Enabled ) {
460     return ;
461   }
462   myInteractorStyle->OnMiddleButtonUp( (event->state() & ControlButton), 
463                                        (event->state() & ShiftButton), 
464                                        event->x(), event->y() ) ;
465 }
466
467 void VTKViewer_RenderWindowInteractor::RightButtonPressed(const QMouseEvent *event) {
468   if( ! this->Enabled ) {
469     return ;
470   }
471   myInteractorStyle->OnRightButtonDown( (event->state() & ControlButton), 
472                                         (event->state() & ShiftButton), 
473                                         event->x(), event->y() ) ;
474 }
475
476 void VTKViewer_RenderWindowInteractor::RightButtonReleased(const QMouseEvent *event) {
477   if( ! this->Enabled ) {
478     return ;
479   }
480   myInteractorStyle->OnRightButtonUp( (event->state() & ControlButton), 
481                                       (event->state() & ShiftButton), 
482                                       event->x(), event->y() ) ;
483 }
484
485 void VTKViewer_RenderWindowInteractor::ButtonPressed(const QMouseEvent *event) {
486   return ;
487 }
488
489 void VTKViewer_RenderWindowInteractor::ButtonReleased(const QMouseEvent *event) {
490   return ;
491 }
492
493
494 int VTKViewer_RenderWindowInteractor::GetDisplayMode() {
495   return myDisplayMode;
496 }
497
498 void VTKViewer_RenderWindowInteractor::SetDisplayMode(int theMode) {
499   if(theMode == 0) 
500     ChangeRepresentationToWireframe();
501   else 
502     ChangeRepresentationToSurface();
503   myDisplayMode = theMode;
504 }
505
506
507 void VTKViewer_RenderWindowInteractor::SetDisplayMode(const Handle(SALOME_InteractiveObject)& theIObject, int theMode){
508   using namespace SALOME::VTK;
509   ForEachIf<SALOME_Actor>(GetRenderer()->GetActors(),
510                           TIsSameIObject<SALOME_Actor>(theIObject),
511                           TSetFunction<SALOME_Actor,int>
512                           (&SALOME_Actor::setDisplayMode,theMode));
513 }
514
515
516 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToWireframe()
517 {
518   ChangeRepresentationToWireframe(GetRenderer()->GetActors());
519 }
520
521 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToSurface()
522 {
523   ChangeRepresentationToSurface(GetRenderer()->GetActors());
524 }
525
526
527 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToWireframe(vtkActorCollection* theCollection)
528 {
529   using namespace SALOME::VTK;
530   ForEach<SALOME_Actor>(theCollection,
531                         TSetFunction<SALOME_Actor,int>
532                         (&SALOME_Actor::setDisplayMode,0));
533   emit RenderWindowModified();
534 }
535
536 void VTKViewer_RenderWindowInteractor::ChangeRepresentationToSurface(vtkActorCollection* theCollection)
537 {
538   using namespace SALOME::VTK;
539   ForEach<SALOME_Actor>(theCollection,
540                         TSetFunction<SALOME_Actor,int>
541                         (&SALOME_Actor::setDisplayMode,1));
542   emit RenderWindowModified();
543 }
544
545
546 vtkRenderer* VTKViewer_RenderWindowInteractor::GetRenderer()
547 {
548   vtkRendererCollection * theRenderers =  this->RenderWindow->GetRenderers();
549   theRenderers->InitTraversal();
550   return theRenderers->GetNextItem();
551 }
552
553
554 struct TErase{
555   SALOME::VTK::TSetFunction<vtkActor,int> mySetFunction;
556   TErase():
557     mySetFunction(&vtkActor::SetVisibility,false)
558   {}
559   void operator()(SALOME_Actor* theActor){
560     theActor->SetVisibility(false);
561     // Erase dependent actors
562     vtkActorCollection* aCollection = vtkActorCollection::New(); 
563     theActor->GetChildActors(aCollection);
564     SALOME::VTK::ForEach<vtkActor>(aCollection,mySetFunction);
565     aCollection->Delete();
566   }
567 };
568
569 void VTKViewer_RenderWindowInteractor::EraseAll()
570 {   
571   using namespace SALOME::VTK;
572   ForEach<SALOME_Actor>(GetRenderer()->GetActors(),
573                         TErase());
574
575   emit RenderWindowModified() ;
576 }
577
578 void VTKViewer_RenderWindowInteractor::DisplayAll()
579
580   vtkActorCollection* aCollection = GetRenderer()->GetActors();
581   using namespace SALOME::VTK;
582   ForEach<SALOME_Actor>(aCollection,TSetVisibility<SALOME_Actor>(true));
583
584   emit RenderWindowModified() ;
585 }
586
587
588 void VTKViewer_RenderWindowInteractor::Erase(SALOME_Actor* theActor, bool update)
589 {
590   TErase()(theActor);
591
592   if(update)
593     emit RenderWindowModified();
594 }
595
596
597 void VTKViewer_RenderWindowInteractor::Erase(const Handle(SALOME_InteractiveObject)& theIObject, bool update)
598 {
599   using namespace SALOME::VTK;
600   ForEachIf<SALOME_Actor>(GetRenderer()->GetActors(),
601                           TIsSameIObject<SALOME_Actor>(theIObject),
602                           TErase());
603
604   if(update)
605     emit RenderWindowModified();
606 }
607
608
609 struct TRemoveAction{
610   vtkRenderer* myRen;
611   TRemoveAction(vtkRenderer* theRen): myRen(theRen){}
612   void operator()(SALOME_Actor* theActor){
613     myRen->RemoveActor(theActor);
614   }
615 };
616
617 void VTKViewer_RenderWindowInteractor::Remove(const Handle(SALOME_InteractiveObject)& theIObject, bool update)
618 {
619   vtkRenderer* aRen = GetRenderer();
620
621   using namespace SALOME::VTK;
622   ForEachIf<SALOME_Actor>(aRen->GetActors(),
623                           TIsSameIObject<SALOME_Actor>(theIObject),
624                           TRemoveAction(aRen));
625
626   
627 }
628
629 void VTKViewer_RenderWindowInteractor::Remove( SALOME_Actor* SActor, bool updateViewer )
630 {
631   if ( SActor != 0 )
632   {
633     GetRenderer()->RemoveProp( SActor );
634     if ( updateViewer )
635       emit RenderWindowModified();
636   }
637 }
638
639 void VTKViewer_RenderWindowInteractor::RemoveAll( const bool updateViewer )
640 {
641   vtkRenderer* aRenderer = GetRenderer();
642   vtkActorCollection* anActors = aRenderer->GetActors();
643   if ( anActors )
644   {
645     anActors->InitTraversal();
646     while ( vtkActor *anAct = anActors->GetNextActor() )
647     {
648       if ( anAct->IsA( "SALOME_Actor" ) )
649       {
650         SALOME_Actor* aSAct = (SALOME_Actor*)anAct;
651         if ( aSAct->hasIO() && aSAct->getIO()->hasEntry() )
652           aRenderer->RemoveActor( anAct );
653       }
654     }
655
656     if ( updateViewer )
657       emit RenderWindowModified();
658   }
659 }
660
661
662 float VTKViewer_RenderWindowInteractor::GetTransparency(const Handle(SALOME_InteractiveObject)& theIObject) 
663 {
664   using namespace SALOME::VTK;
665   SALOME_Actor* anActor = 
666     Find<SALOME_Actor>(GetRenderer()->GetActors(),
667                        TIsSameIObject<SALOME_Actor>(theIObject));
668   if(anActor)
669     return 1.0 - anActor->GetOpacity();
670   return -1.0;
671 }
672
673
674 void VTKViewer_RenderWindowInteractor::SetTransparency(const Handle(SALOME_InteractiveObject)& theIObject, float theTrans)
675 {
676   float anOpacity = 1.0 - theTrans;
677   using namespace SALOME::VTK;
678   ForEachIf<SALOME_Actor>(GetRenderer()->GetActors(),
679                           TIsSameIObject<SALOME_Actor>(theIObject),
680                           TSetFunction<SALOME_Actor,float>
681                           (&SALOME_Actor::SetOpacity,anOpacity));
682 }
683
684
685 void VTKViewer_RenderWindowInteractor::Display(SALOME_Actor* theActor, bool update)
686 {
687   GetRenderer()->AddActor(theActor);
688   theActor->SetVisibility(true);
689
690   if(update)
691     emit RenderWindowModified();
692 }
693
694
695 void VTKViewer_RenderWindowInteractor::Display(const Handle(SALOME_InteractiveObject)& theIObject, bool update)
696 {
697   using namespace SALOME::VTK;
698   ForEachIf<SALOME_Actor>(GetRenderer()->GetActors(),
699                           TIsSameIObject<SALOME_Actor>(theIObject),
700                           TSetVisibility<SALOME_Actor>(true));
701
702   if(update)
703     emit RenderWindowModified() ;
704 }
705
706
707 void VTKViewer_RenderWindowInteractor::KeyPressed(QKeyEvent *event){}
708
709
710 struct THighlightAction{
711   bool myIsHighlight;
712   VTKViewer_InteractorStyleSALOME* myInteractorStyle;
713   THighlightAction(VTKViewer_InteractorStyleSALOME* theInteractorStyle,
714                    bool theIsHighlight): 
715     myInteractorStyle(theInteractorStyle),
716     myIsHighlight(theIsHighlight)
717   {}
718   void operator()(SALOME_Actor* theActor){
719     if(theActor->GetMapper()){
720       if(theActor->hasHighlight())
721         theActor->highlight(myIsHighlight);
722       else{
723         if(theActor->GetVisibility() && myIsHighlight)
724           myInteractorStyle->HighlightProp(theActor);
725         else if(!myIsHighlight)
726           myInteractorStyle->HighlightProp(NULL);
727       }
728     }
729   }
730 };
731
732 bool VTKViewer_RenderWindowInteractor::highlight( const Handle(SALOME_InteractiveObject)& theIObject, 
733                                                   bool hilight, 
734                                                   bool update)
735 {
736   using namespace SALOME::VTK;
737   ForEachIf<SALOME_Actor>(GetRenderer()->GetActors(),
738                           TIsSameIObject<SALOME_Actor>(theIObject),
739                           THighlightAction(myInteractorStyle,hilight));
740
741   if(update)
742     emit RenderWindowModified();
743
744   return false;
745 }
746
747
748 struct TUpdateAction{
749   void operator()(vtkActor* theActor){
750     theActor->ApplyProperties();
751   }
752 };
753
754 void VTKViewer_RenderWindowInteractor::Update() {
755   vtkRenderer* aRen = GetRenderer();
756
757   using namespace SALOME::VTK;
758   ForEach<vtkActor>(aRen->GetActors(),TUpdateAction());
759
760   aRen->ResetCamera();
761
762   emit RenderWindowModified();  
763 }
764
765
766 void VTKViewer_RenderWindowInteractor::unHighlightSubSelection(){
767   myPointActor->SetVisibility(false);
768   myEdgeActor->SetVisibility(false);
769   myCellActor->SetVisibility(false);
770 }
771
772
773 struct TUnHighlightAllAction{
774   void operator()(SALOME_Actor* theActor){
775     if(theActor->hasIO()){
776       if(theActor->hasHighlight())
777         theActor->highlight(false);
778     }
779   }
780 };
781
782 bool VTKViewer_RenderWindowInteractor::unHighlightAll(){
783   unHighlightSubSelection();
784
785   using namespace SALOME::VTK;
786   ForEach<SALOME_Actor>(GetRenderer()->GetActors(),
787                         TUnHighlightAllAction());
788
789   emit RenderWindowModified() ;
790   return false;
791 }
792
793 //-----------------
794 // Color methods
795 //-----------------
796
797 void VTKViewer_RenderWindowInteractor::SetColor(const Handle(SALOME_InteractiveObject)& theIObject,QColor theColor) 
798 {
799   float aColor[3] = {theColor.red()/255., theColor.green()/255., theColor.blue()/255.};
800   using namespace SALOME::VTK;
801   ForEachIf<SALOME_Actor>(GetRenderer()->GetActors(),
802                           TIsSameIObject<SALOME_Actor>(theIObject),
803                           TSetFunction<SALOME_Actor,const float*>
804                           (&SALOME_Actor::SetColor,aColor));
805 }
806
807
808 QColor VTKViewer_RenderWindowInteractor::GetColor(const Handle(SALOME_InteractiveObject)& theIObject) 
809 {
810   using namespace SALOME::VTK;
811   SALOME_Actor* anActor = 
812     Find<SALOME_Actor>(GetRenderer()->GetActors(),
813                        TIsSameIObject<SALOME_Actor>(theIObject));
814   if(anActor){
815     float r,g,b;
816     anActor->GetColor(r,g,b);
817     return QColor(int(r*255),int(g*255),int(b*255));
818   }
819   return QColor(0,0,0);
820 }
821
822
823 bool VTKViewer_RenderWindowInteractor::isInViewer(const Handle(SALOME_InteractiveObject)& theIObject)
824 {
825   using namespace SALOME::VTK;
826   SALOME_Actor* anActor = 
827     Find<SALOME_Actor>(GetRenderer()->GetActors(),
828                        TIsSameIObject<SALOME_Actor>(theIObject));
829   return anActor != NULL;
830 }
831
832
833 bool VTKViewer_RenderWindowInteractor::isVisible(const Handle(SALOME_InteractiveObject)& theIObject)
834 {
835   using namespace SALOME::VTK;
836   SALOME_Actor* anActor = 
837     Find<SALOME_Actor>(GetRenderer()->GetActors(),
838                        TIsSameIObject<SALOME_Actor>(theIObject));
839   return anActor != NULL && anActor->GetVisibility();
840 }
841
842
843 void VTKViewer_RenderWindowInteractor::rename(const Handle(SALOME_InteractiveObject)& theIObject, QString theName)
844 {
845   using namespace SALOME::VTK;
846   ForEachIf<SALOME_Actor>(GetRenderer()->GetActors(),
847                           TIsSameIObject<SALOME_Actor>(theIObject),
848                           TSetFunction<SALOME_Actor,const char*,QString>
849                           (&SALOME_Actor::setName,theName.latin1()));
850 }
851
852
853 //----------------------------------------------------------------------------
854 bool VTKViewer_RenderWindowInteractor::highlight(const TColStd_IndexedMapOfInteger& theMapIndex,
855                                                  SALOME_Actor* theMapActor, VTKViewer_Actor* theActor,
856                                                  TUpdateActor theFun, bool hilight, bool update)
857 {
858   if(theMapIndex.Extent() == 0) return false;
859   
860   if (hilight) {
861     setActorData(theMapIndex,theMapActor,theActor,theFun);
862     theActor->SetVisibility(true);
863   }
864   else {
865     theActor->SetVisibility(false);
866   }
867
868   if(update){
869     this->RenderWindow->Render();  
870     emit RenderWindowModified() ;
871   }
872
873   return false;
874 }
875   
876 void VTKViewer_RenderWindowInteractor::setActorData(const TColStd_IndexedMapOfInteger& theMapIndex,
877                                                     SALOME_Actor* theMapActor,
878                                                     VTKViewer_Actor *theActor,
879                                                     TUpdateActor theFun)
880 {
881   (*theFun)(theMapIndex,theMapActor,theActor);
882 }
883
884
885 //----------------------------------------------------------------------------
886 static void CellsUpdateActor(const TColStd_IndexedMapOfInteger& theMapIndex,
887                              SALOME_Actor* theMapActor, 
888                              VTKViewer_Actor* theActor)
889 {
890   theActor->MapCells(theMapActor,theMapIndex);
891 }
892   
893 bool VTKViewer_RenderWindowInteractor::highlightCell(const TColStd_IndexedMapOfInteger& theMapIndex,
894                                                      SALOME_Actor* theMapActor, 
895                                                      bool hilight, 
896                                                      bool update)
897 {
898   return highlight(theMapIndex,theMapActor,myCellActor,&CellsUpdateActor,hilight,update);
899 }
900   
901 void VTKViewer_RenderWindowInteractor::setCellData(const int& theIndex, 
902                                                    SALOME_Actor* theMapActor,
903                                                    VTKViewer_Actor* theActor)
904 {
905   TColStd_IndexedMapOfInteger MapIndex; 
906   MapIndex.Add(theIndex);
907   theActor->MapCells(theMapActor,MapIndex);
908 }
909
910
911 //----------------------------------------------------------------------------
912 static void PointsUpdateActor(const TColStd_IndexedMapOfInteger& theMapIndex,
913                               SALOME_Actor* theMapActor, 
914                               VTKViewer_Actor* theActor)
915 {
916   theActor->MapPoints(theMapActor,theMapIndex);
917 }
918   
919 bool VTKViewer_RenderWindowInteractor::highlightPoint(const TColStd_IndexedMapOfInteger& theMapIndex,
920                                                       SALOME_Actor* theMapActor, 
921                                                       bool hilight, 
922                                                       bool update)
923 {
924   return highlight(theMapIndex,theMapActor,myPointActor,&PointsUpdateActor,hilight,update);
925 }
926   
927 void VTKViewer_RenderWindowInteractor::setPointData(const int& theIndex, 
928                                                     SALOME_Actor* theMapActor,
929                                                     VTKViewer_Actor* theActor)
930 {
931   TColStd_IndexedMapOfInteger MapIndex; 
932   MapIndex.Add(theIndex);
933   theActor->MapPoints(theMapActor,MapIndex);
934 }
935
936   
937 //----------------------------------------------------------------------------
938 static void EdgesUpdateActor(const TColStd_IndexedMapOfInteger& theMapIndex,
939                              SALOME_Actor* theMapActor, 
940                              VTKViewer_Actor* theActor)
941 {
942   theActor->MapEdge(theMapActor,theMapIndex);
943 }
944   
945 bool VTKViewer_RenderWindowInteractor::highlightEdge(const TColStd_IndexedMapOfInteger& theMapIndex,
946                                                      SALOME_Actor* theMapActor, 
947                                                      bool hilight, 
948                                                      bool update)
949 {
950   return highlight(theMapIndex,theMapActor,myEdgeActor,&EdgesUpdateActor,hilight,update);
951 }
952   
953 void VTKViewer_RenderWindowInteractor::setEdgeData(const int& theCellIndex, 
954                                                    SALOME_Actor* theMapActor,
955                                                    const int& theEdgeIndex, 
956                                                    VTKViewer_Actor* theActor )
957 {
958   TColStd_IndexedMapOfInteger MapIndex; 
959   MapIndex.Add(theCellIndex); 
960   MapIndex.Add(theEdgeIndex);
961   theActor->MapEdge(theMapActor,MapIndex);
962 }