Salome HOME
PR: mergefrom_PAL_OCC_21Oct04
[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
579 void VTKViewer_RenderWindowInteractor::DisplayAll()
580
581   vtkActorCollection* aCollection = GetRenderer()->GetActors();
582   using namespace SALOME::VTK;
583   ForEach<SALOME_Actor>(aCollection,TSetVisibility<SALOME_Actor>(true));
584
585   emit RenderWindowModified() ;
586 }
587
588
589 void VTKViewer_RenderWindowInteractor::Erase(SALOME_Actor* theActor, bool update)
590 {
591   TErase()(theActor);
592
593   if(update)
594     emit RenderWindowModified();
595 }
596
597
598 void VTKViewer_RenderWindowInteractor::Erase(const Handle(SALOME_InteractiveObject)& theIObject, bool update)
599 {
600   using namespace SALOME::VTK;
601   ForEachIf<SALOME_Actor>(GetRenderer()->GetActors(),
602                           TIsSameIObject<SALOME_Actor>(theIObject),
603                           TErase());
604
605   if(update)
606     emit RenderWindowModified();
607 }
608
609
610 struct TRemoveAction{
611   vtkRenderer* myRen;
612   TRemoveAction(vtkRenderer* theRen): myRen(theRen){}
613   void operator()(SALOME_Actor* theActor){
614     myRen->RemoveActor(theActor);
615   }
616 };
617
618 void VTKViewer_RenderWindowInteractor::Remove(const Handle(SALOME_InteractiveObject)& theIObject, bool update)
619 {
620   vtkRenderer* aRen = GetRenderer();
621
622   using namespace SALOME::VTK;
623   ForEachIf<SALOME_Actor>(aRen->GetActors(),
624                           TIsSameIObject<SALOME_Actor>(theIObject),
625                           TRemoveAction(aRen));
626
627   if(update)
628     emit RenderWindowModified();
629 }
630
631
632 float VTKViewer_RenderWindowInteractor::GetTransparency(const Handle(SALOME_InteractiveObject)& theIObject) 
633 {
634   using namespace SALOME::VTK;
635   SALOME_Actor* anActor = 
636     Find<SALOME_Actor>(GetRenderer()->GetActors(),
637                        TIsSameIObject<SALOME_Actor>(theIObject));
638   if(anActor)
639     return 1.0 - anActor->GetOpacity();
640   return -1.0;
641 }
642
643
644 void VTKViewer_RenderWindowInteractor::SetTransparency(const Handle(SALOME_InteractiveObject)& theIObject, float theTrans)
645 {
646   float anOpacity = 1.0 - theTrans;
647   using namespace SALOME::VTK;
648   ForEachIf<SALOME_Actor>(GetRenderer()->GetActors(),
649                           TIsSameIObject<SALOME_Actor>(theIObject),
650                           TSetFunction<SALOME_Actor,float>
651                           (&SALOME_Actor::SetOpacity,anOpacity));
652 }
653
654
655 void VTKViewer_RenderWindowInteractor::Display(SALOME_Actor* theActor, bool update)
656 {
657   GetRenderer()->AddActor(theActor);
658   theActor->SetVisibility(true);
659
660   if(update)
661     emit RenderWindowModified();
662 }
663
664
665 void VTKViewer_RenderWindowInteractor::Display(const Handle(SALOME_InteractiveObject)& theIObject, bool update)
666 {
667   using namespace SALOME::VTK;
668   ForEachIf<SALOME_Actor>(GetRenderer()->GetActors(),
669                           TIsSameIObject<SALOME_Actor>(theIObject),
670                           TSetVisibility<SALOME_Actor>(true));
671
672   if(update)
673     emit RenderWindowModified() ;
674 }
675
676
677 void VTKViewer_RenderWindowInteractor::KeyPressed(QKeyEvent *event){}
678
679
680 struct THighlightAction{
681   bool myIsHighlight;
682   VTKViewer_InteractorStyleSALOME* myInteractorStyle;
683   THighlightAction(VTKViewer_InteractorStyleSALOME* theInteractorStyle,
684                    bool theIsHighlight): 
685     myInteractorStyle(theInteractorStyle),
686     myIsHighlight(theIsHighlight)
687   {}
688   void operator()(SALOME_Actor* theActor){
689     if(theActor->GetMapper()){
690       if(theActor->hasHighlight())
691         theActor->highlight(myIsHighlight);
692       else{
693         if(theActor->GetVisibility() && myIsHighlight)
694           myInteractorStyle->HighlightProp(theActor);
695         else if(!myIsHighlight)
696           myInteractorStyle->HighlightProp(NULL);
697       }
698     }
699   }
700 };
701
702 bool VTKViewer_RenderWindowInteractor::highlight( const Handle(SALOME_InteractiveObject)& theIObject, 
703                                                   bool hilight, 
704                                                   bool update)
705 {
706   using namespace SALOME::VTK;
707   ForEachIf<SALOME_Actor>(GetRenderer()->GetActors(),
708                           TIsSameIObject<SALOME_Actor>(theIObject),
709                           THighlightAction(myInteractorStyle,hilight));
710
711   if(update)
712     emit RenderWindowModified();
713
714   return false;
715 }
716
717
718 struct TUpdateAction{
719   void operator()(vtkActor* theActor){
720     theActor->ApplyProperties();
721   }
722 };
723
724 void VTKViewer_RenderWindowInteractor::Update() {
725   vtkRenderer* aRen = GetRenderer();
726
727   using namespace SALOME::VTK;
728   ForEach<vtkActor>(aRen->GetActors(),TUpdateAction());
729
730   aRen->ResetCamera();
731
732   emit RenderWindowModified();  
733 }
734
735
736 void VTKViewer_RenderWindowInteractor::unHighlightSubSelection(){
737   myPointActor->SetVisibility(false);
738   myEdgeActor->SetVisibility(false);
739   myCellActor->SetVisibility(false);
740 }
741
742
743 struct TUnHighlightAllAction{
744   void operator()(SALOME_Actor* theActor){
745     if(theActor->hasIO()){
746       if(theActor->hasHighlight())
747         theActor->highlight(false);
748     }
749   }
750 };
751
752 bool VTKViewer_RenderWindowInteractor::unHighlightAll(){
753   unHighlightSubSelection();
754
755   using namespace SALOME::VTK;
756   ForEach<SALOME_Actor>(GetRenderer()->GetActors(),
757                         TUnHighlightAllAction());
758
759   emit RenderWindowModified() ;
760   return false;
761 }
762
763 //-----------------
764 // Color methods
765 //-----------------
766
767 void VTKViewer_RenderWindowInteractor::SetColor(const Handle(SALOME_InteractiveObject)& theIObject,QColor theColor) 
768 {
769   float aColor[3] = {theColor.red()/255., theColor.green()/255., theColor.blue()/255.};
770   using namespace SALOME::VTK;
771   ForEachIf<SALOME_Actor>(GetRenderer()->GetActors(),
772                           TIsSameIObject<SALOME_Actor>(theIObject),
773                           TSetFunction<SALOME_Actor,const float*>
774                           (&SALOME_Actor::SetColor,aColor));
775 }
776
777
778 QColor VTKViewer_RenderWindowInteractor::GetColor(const Handle(SALOME_InteractiveObject)& theIObject) 
779 {
780   using namespace SALOME::VTK;
781   SALOME_Actor* anActor = 
782     Find<SALOME_Actor>(GetRenderer()->GetActors(),
783                        TIsSameIObject<SALOME_Actor>(theIObject));
784   if(anActor){
785     float r,g,b;
786     anActor->GetColor(r,g,b);
787     return QColor(int(r*255),int(g*255),int(b*255));
788   }
789   return QColor(0,0,0);
790 }
791
792
793 bool VTKViewer_RenderWindowInteractor::isInViewer(const Handle(SALOME_InteractiveObject)& theIObject)
794 {
795   using namespace SALOME::VTK;
796   SALOME_Actor* anActor = 
797     Find<SALOME_Actor>(GetRenderer()->GetActors(),
798                        TIsSameIObject<SALOME_Actor>(theIObject));
799   return anActor != NULL;
800 }
801
802
803 bool VTKViewer_RenderWindowInteractor::isVisible(const Handle(SALOME_InteractiveObject)& theIObject)
804 {
805   using namespace SALOME::VTK;
806   SALOME_Actor* anActor = 
807     Find<SALOME_Actor>(GetRenderer()->GetActors(),
808                        TIsSameIObject<SALOME_Actor>(theIObject));
809   return anActor != NULL && anActor->GetVisibility();
810 }
811
812
813 void VTKViewer_RenderWindowInteractor::rename(const Handle(SALOME_InteractiveObject)& theIObject, QString theName)
814 {
815   using namespace SALOME::VTK;
816   ForEachIf<SALOME_Actor>(GetRenderer()->GetActors(),
817                           TIsSameIObject<SALOME_Actor>(theIObject),
818                           TSetFunction<SALOME_Actor,const char*,QString>
819                           (&SALOME_Actor::setName,theName.latin1()));
820 }
821
822
823 //----------------------------------------------------------------------------
824 bool VTKViewer_RenderWindowInteractor::highlight(const TColStd_IndexedMapOfInteger& theMapIndex,
825                                                  SALOME_Actor* theMapActor, VTKViewer_Actor* theActor,
826                                                  TUpdateActor theFun, bool hilight, bool update)
827 {
828   if(theMapIndex.Extent() == 0) return false;
829   
830   if (hilight) {
831     setActorData(theMapIndex,theMapActor,theActor,theFun);
832     theActor->SetVisibility(true);
833   }
834   else {
835     theActor->SetVisibility(false);
836   }
837
838   if(update){
839     this->RenderWindow->Render();  
840     emit RenderWindowModified() ;
841   }
842
843   return false;
844 }
845   
846 void VTKViewer_RenderWindowInteractor::setActorData(const TColStd_IndexedMapOfInteger& theMapIndex,
847                                                     SALOME_Actor* theMapActor,
848                                                     VTKViewer_Actor *theActor,
849                                                     TUpdateActor theFun)
850 {
851   (*theFun)(theMapIndex,theMapActor,theActor);
852 }
853
854
855 //----------------------------------------------------------------------------
856 static void CellsUpdateActor(const TColStd_IndexedMapOfInteger& theMapIndex,
857                              SALOME_Actor* theMapActor, 
858                              VTKViewer_Actor* theActor)
859 {
860   theActor->MapCells(theMapActor,theMapIndex);
861 }
862   
863 bool VTKViewer_RenderWindowInteractor::highlightCell(const TColStd_IndexedMapOfInteger& theMapIndex,
864                                                      SALOME_Actor* theMapActor, 
865                                                      bool hilight, 
866                                                      bool update)
867 {
868   return highlight(theMapIndex,theMapActor,myCellActor,&CellsUpdateActor,hilight,update);
869 }
870   
871 void VTKViewer_RenderWindowInteractor::setCellData(const int& theIndex, 
872                                                    SALOME_Actor* theMapActor,
873                                                    VTKViewer_Actor* theActor)
874 {
875   TColStd_IndexedMapOfInteger MapIndex; 
876   MapIndex.Add(theIndex);
877   theActor->MapCells(theMapActor,MapIndex);
878 }
879
880
881 //----------------------------------------------------------------------------
882 static void PointsUpdateActor(const TColStd_IndexedMapOfInteger& theMapIndex,
883                               SALOME_Actor* theMapActor, 
884                               VTKViewer_Actor* theActor)
885 {
886   theActor->MapPoints(theMapActor,theMapIndex);
887 }
888   
889 bool VTKViewer_RenderWindowInteractor::highlightPoint(const TColStd_IndexedMapOfInteger& theMapIndex,
890                                                       SALOME_Actor* theMapActor, 
891                                                       bool hilight, 
892                                                       bool update)
893 {
894   return highlight(theMapIndex,theMapActor,myPointActor,&PointsUpdateActor,hilight,update);
895 }
896   
897 void VTKViewer_RenderWindowInteractor::setPointData(const int& theIndex, 
898                                                     SALOME_Actor* theMapActor,
899                                                     VTKViewer_Actor* theActor)
900 {
901   TColStd_IndexedMapOfInteger MapIndex; 
902   MapIndex.Add(theIndex);
903   theActor->MapPoints(theMapActor,MapIndex);
904 }
905
906   
907 //----------------------------------------------------------------------------
908 static void EdgesUpdateActor(const TColStd_IndexedMapOfInteger& theMapIndex,
909                              SALOME_Actor* theMapActor, 
910                              VTKViewer_Actor* theActor)
911 {
912   theActor->MapEdge(theMapActor,theMapIndex);
913 }
914   
915 bool VTKViewer_RenderWindowInteractor::highlightEdge(const TColStd_IndexedMapOfInteger& theMapIndex,
916                                                      SALOME_Actor* theMapActor, 
917                                                      bool hilight, 
918                                                      bool update)
919 {
920   return highlight(theMapIndex,theMapActor,myEdgeActor,&EdgesUpdateActor,hilight,update);
921 }
922   
923 void VTKViewer_RenderWindowInteractor::setEdgeData(const int& theCellIndex, 
924                                                    SALOME_Actor* theMapActor,
925                                                    const int& theEdgeIndex, 
926                                                    VTKViewer_Actor* theActor )
927 {
928   TColStd_IndexedMapOfInteger MapIndex; 
929   MapIndex.Add(theCellIndex); 
930   MapIndex.Add(theEdgeIndex);
931   theActor->MapEdge(theMapActor,MapIndex);
932 }