Salome HOME
Merge from OCC_development_generic_2006
[modules/gui.git] / src / SVTK / SVTK_View.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   : 
25 //  Author : 
26 //  Module : SALOME
27 //  $Header$
28
29 #include "SALOME_Actor.h"
30
31 #include "SVTK_View.h"
32 #include "SVTK_Renderer.h"
33 #include "SVTK_MainWindow.h"
34 #include "SVTK_RenderWindowInteractor.h"
35 #include "SALOME_ListIteratorOfListIO.hxx"
36
37 #include "VTKViewer_Algorithm.h"
38 #include "SVTK_Functor.h"
39
40 #include <vtkActorCollection.h>
41 #include <vtkRenderer.h>
42
43
44 //----------------------------------------------------------------------------
45 SVTK_SignalHandler
46 ::SVTK_SignalHandler(SVTK_MainWindow* theMainWindow):
47   QObject(theMainWindow),
48   myMainWindow(theMainWindow)
49 {
50   SVTK_RenderWindowInteractor* anInteractor = theMainWindow->GetInteractor();
51
52   connect(anInteractor,SIGNAL(KeyPressed(QKeyEvent*)),
53           this,SIGNAL(KeyPressed(QKeyEvent*)) );
54   connect(anInteractor,SIGNAL(KeyReleased(QKeyEvent*)),
55           this,SIGNAL(KeyReleased(QKeyEvent*)));
56   connect(anInteractor,SIGNAL(MouseButtonPressed(QMouseEvent*)),
57           this,SIGNAL(MouseButtonPressed(QMouseEvent*)));
58   connect(anInteractor,SIGNAL(MouseButtonReleased(QMouseEvent*)),
59           this,SIGNAL(MouseButtonReleased(QMouseEvent*)));
60   connect(anInteractor,SIGNAL(MouseDoubleClicked(QMouseEvent*)),
61           this,SIGNAL(MouseDoubleClicked(QMouseEvent*)));
62   connect(anInteractor,SIGNAL(MouseMove(QMouseEvent*)),
63           this,SIGNAL(MouseMove(QMouseEvent*)));
64   connect(anInteractor,SIGNAL(contextMenuRequested(QContextMenuEvent*)),
65           this,SIGNAL(contextMenuRequested(QContextMenuEvent*)));
66   connect(anInteractor,SIGNAL(selectionChanged()),
67           this,SIGNAL(selectionChanged()));
68 }
69
70 SVTK_SignalHandler
71 ::~SVTK_SignalHandler()
72 {
73 }
74
75 SVTK_MainWindow*
76 SVTK_SignalHandler
77 ::GetMainWindow()
78 {
79   return myMainWindow;
80 }
81
82
83 //----------------------------------------------------------------
84 void
85 SVTK_SignalHandler
86 ::Repaint(bool theUpdateTrihedron)
87 {
88   myMainWindow->Repaint(theUpdateTrihedron);
89 }
90
91 //----------------------------------------------------------------------------
92 SVTK_Renderer* 
93 SVTK_SignalHandler
94 ::GetRenderer()
95 {
96   return myMainWindow->GetRenderer();
97 }
98
99 vtkRenderer* 
100 SVTK_SignalHandler
101 ::getRenderer()
102 {
103   return myMainWindow->getRenderer();
104 }
105
106 //----------------------------------------------------------------
107 namespace SVTK
108 {
109   struct THighlightAction
110   {
111     bool myIsHighlight;
112     THighlightAction( bool theIsHighlight ):
113       myIsHighlight( theIsHighlight )
114     {}
115     
116     void
117     operator()( SALOME_Actor* theActor) 
118     {
119       if(theActor->GetMapper() && theActor->hasIO()){
120         theActor->Highlight( myIsHighlight );
121       }
122     }
123   };
124 }
125
126 void
127 SVTK_SignalHandler
128 ::onSelectionChanged()
129 {
130   vtkActorCollection* anActors = myMainWindow->getRenderer()->GetActors();
131
132   using namespace SVTK;
133   ForEach<SALOME_Actor>(anActors,
134                         THighlightAction( false ));
135   SVTK_Selector* aSelector = myMainWindow->GetSelector();
136   const SALOME_ListIO& aListIO = aSelector->StoredIObjects();
137   SALOME_ListIteratorOfListIO anIter(aListIO);
138   for(; anIter.More(); anIter.Next()){
139     ForEachIf<SALOME_Actor>(anActors,
140                             TIsSameIObject<SALOME_Actor>(anIter.Value()),
141                             THighlightAction(true));
142   }
143
144   myMainWindow->Repaint(false);
145 }
146
147
148 //----------------------------------------------------------------------------
149 SVTK_View
150 ::SVTK_View(SVTK_MainWindow* theMainWindow) :
151   SVTK_SignalHandler(theMainWindow)
152 {
153 }
154
155 //----------------------------------------------------------------------------
156 SVTK_View
157 ::~SVTK_View()
158 {
159 }
160
161 //----------------------------------------------------------------
162 void 
163 SVTK_View
164 ::unHighlightAll() 
165 {
166   using namespace SVTK;
167   ForEach<SALOME_Actor>(getRenderer()->GetActors(),
168                         THighlightAction( false ));
169   Repaint();
170 }
171
172 //----------------------------------------------------------------
173 void
174 SVTK_View
175 ::highlight( const Handle(SALOME_InteractiveObject)& theIO, 
176              bool theIsHighlight, 
177              bool theIsUpdate ) 
178 {
179   using namespace SVTK;
180   ForEachIf<SALOME_Actor>(getRenderer()->GetActors(),
181                           TIsSameIObject<SALOME_Actor>( theIO ),
182                           THighlightAction(theIsHighlight));
183   Repaint();
184 }
185
186 //----------------------------------------------------------------------------
187 void
188 SVTK_View
189 ::SetSelectionProp(const double& theRed, 
190                    const double& theGreen, 
191                    const double& theBlue, 
192                    const int& theWidth) 
193 {
194   GetRenderer()->SetSelectionProp(theRed,theGreen,theBlue,theWidth);
195 }
196
197 //----------------------------------------------------------------------------
198 void
199 SVTK_View
200 ::SetPreselectionProp(const double& theRed, 
201                       const double& theGreen, 
202                       const double& theBlue, 
203                       const int& theWidth) 
204 {
205   GetRenderer()->SetPreselectionProp(theRed,theGreen,theBlue,theWidth);
206 }
207
208 //----------------------------------------------------------------------------
209 void
210 SVTK_View
211 ::SetSelectionTolerance(const double& theTolNodes, 
212                         const double& theTolCell)
213 {
214   GetRenderer()->SetSelectionTolerance(theTolNodes,theTolCell);
215 }
216
217 //----------------------------------------------------------------------------
218 bool
219 SVTK_View
220 ::isInViewer(const Handle(SALOME_InteractiveObject)& theIObject)
221 {
222   using namespace SVTK;
223   SALOME_Actor* anActor = 
224     Find<SALOME_Actor>(getRenderer()->GetActors(),
225                        TIsSameIObject<SALOME_Actor>(theIObject));
226   return anActor != NULL;
227 }
228
229 //----------------------------------------------------------------------------
230 bool
231 SVTK_View
232 ::isVisible(const Handle(SALOME_InteractiveObject)& theIObject)
233 {
234   using namespace SVTK;
235   SALOME_Actor* anActor = 
236     Find<SALOME_Actor>(getRenderer()->GetActors(),
237                        TIsSameIObject<SALOME_Actor>(theIObject));
238   return anActor != NULL && anActor->GetVisibility();
239 }
240
241 //----------------------------------------------------------------------------
242 void
243 SVTK_View
244 ::rename(const Handle(SALOME_InteractiveObject)& theIObject, 
245          const QString& theName)
246 {
247   using namespace SVTK;
248   ForEachIf<SALOME_Actor>(getRenderer()->GetActors(),
249                           TIsSameIObject<SALOME_Actor>(theIObject),
250                           TSetFunction<SALOME_Actor,const char*,QString>
251                           (&SALOME_Actor::setName,theName.latin1()));
252 }
253
254 //----------------------------------------------------------------------------
255 int
256 SVTK_View
257 ::GetDisplayMode() 
258 {
259   return myDisplayMode; 
260 }
261
262 void
263 SVTK_View
264 ::SetDisplayMode(int theMode)
265 {
266   if(theMode == 0) 
267     ChangeRepresentationToWireframe();
268   else 
269     ChangeRepresentationToSurface();
270   myDisplayMode = theMode;
271 }
272
273 void
274 SVTK_View
275 ::SetDisplayMode(const Handle(SALOME_InteractiveObject)& theIObject, 
276                  int theMode)
277 {
278   using namespace SVTK;
279   ForEachIf<SALOME_Actor>(getRenderer()->GetActors(),
280                           TIsSameIObject<SALOME_Actor>(theIObject),
281                           TSetFunction<SALOME_Actor,int>
282                           (&SALOME_Actor::setDisplayMode,theMode));
283 }
284
285 //----------------------------------------------------------------------------
286 void
287 SVTK_View
288 ::ChangeRepresentationToWireframe()
289 {
290   ChangeRepresentationToWireframe(getRenderer()->GetActors());
291 }
292
293 void
294 SVTK_View
295 ::ChangeRepresentationToSurface()
296 {
297   ChangeRepresentationToSurface(getRenderer()->GetActors());
298 }
299
300
301 void
302 SVTK_View
303 ::ChangeRepresentationToWireframe(vtkActorCollection* theCollection)
304 {
305   using namespace SVTK;
306   ForEach<SALOME_Actor>(theCollection,
307                         TSetFunction<SALOME_Actor,int>
308                         (&SALOME_Actor::setDisplayMode,0));
309   Repaint();
310 }
311
312 void
313 SVTK_View
314 ::ChangeRepresentationToSurface(vtkActorCollection* theCollection)
315 {
316   using namespace SVTK;
317   ForEach<SALOME_Actor>(theCollection,
318                         TSetFunction<SALOME_Actor,int>
319                         (&SALOME_Actor::setDisplayMode,1));
320   Repaint();
321 }
322
323 //----------------------------------------------------------------------------
324 namespace SVTK
325 {
326   struct TErase
327   {
328     VTK::TSetFunction<vtkActor,int> mySetFunction;
329     TErase():
330       mySetFunction(&vtkActor::SetVisibility,false)
331     {}
332     void
333     operator()(SALOME_Actor* theActor)
334     {
335       theActor->SetVisibility(false);
336       // Erase dependent actors
337       vtkActorCollection* aCollection = vtkActorCollection::New(); 
338       theActor->GetChildActors(aCollection);
339       VTK::ForEach<vtkActor>(aCollection,mySetFunction);
340       aCollection->Delete();
341     }
342   };
343 }
344
345 void
346 SVTK_View
347 ::EraseAll()
348 {   
349   using namespace SVTK;
350   ForEach<SALOME_Actor>(getRenderer()->GetActors(),
351                         TErase());
352   Repaint();
353 }
354
355 void
356 SVTK_View
357 ::DisplayAll()
358
359   using namespace SVTK;
360   ForEach<SALOME_Actor>(getRenderer()->GetActors(),
361                         TSetVisibility<SALOME_Actor>(true));
362   Repaint();
363 }
364
365
366 void
367 SVTK_View
368 ::Erase(SALOME_Actor* theActor, 
369         bool theIsUpdate)
370 {
371   SVTK::TErase()(theActor);
372
373   if(theIsUpdate)
374     Repaint();
375 }
376
377
378 void
379 SVTK_View
380 ::Erase(const Handle(SALOME_InteractiveObject)& theIObject, 
381         bool theIsUpdate)
382 {
383   using namespace SVTK;
384   ForEachIf<SALOME_Actor>(getRenderer()->GetActors(),
385                           TIsSameIObject<SALOME_Actor>(theIObject),
386                           TErase());
387   if(theIsUpdate)
388     Repaint();
389 }
390
391 //----------------------------------------------------------------------------
392 void
393 SVTK_View
394 ::Display(SALOME_Actor* theActor, 
395           bool theIsUpdate)
396 {
397   GetRenderer()->AddActor(theActor);
398   theActor->SetVisibility(true);
399
400   if(theIsUpdate)
401     Repaint();
402 }
403
404 void
405 SVTK_View
406 ::Display(const Handle(SALOME_InteractiveObject)& theIObject, 
407           bool theIsUpdate)
408 {
409   using namespace SVTK;
410   ForEachIf<SALOME_Actor>(getRenderer()->GetActors(),
411                           TIsSameIObject<SALOME_Actor>(theIObject),
412                           TSetVisibility<SALOME_Actor>(true));
413
414   if(theIsUpdate)
415     Repaint();
416 }
417
418 void
419 SVTK_View
420 ::DisplayOnly(const Handle(SALOME_InteractiveObject)& theIObject)
421 {
422   EraseAll();
423   Display(theIObject);
424 }
425
426
427 //----------------------------------------------------------------------------
428 namespace SVTK
429 {
430   struct TRemoveAction
431   {
432     SVTK_Renderer* myRenderer;
433     TRemoveAction(SVTK_Renderer* theRenderer): 
434       myRenderer(theRenderer)
435     {}
436     void
437     operator()(SALOME_Actor* theActor)
438     {
439       myRenderer->RemoveActor(theActor);
440     }
441   };
442 }
443
444 void
445 SVTK_View
446 ::Remove(const Handle(SALOME_InteractiveObject)& theIObject, 
447          bool theIsUpdate)
448 {
449   using namespace SVTK;
450   ForEachIf<SALOME_Actor>(getRenderer()->GetActors(),
451                           TIsSameIObject<SALOME_Actor>(theIObject),
452                           TRemoveAction(GetRenderer()));
453   if(theIsUpdate)
454     Repaint();
455 }
456
457 void
458 SVTK_View
459 ::Remove(SALOME_Actor* theActor, 
460          bool theIsUpdate)
461 {
462   GetRenderer()->RemoveActor(theActor);
463   if(theIsUpdate)
464     Repaint();
465 }
466
467 void
468 SVTK_View
469 ::RemoveAll(bool theIsUpdate)
470 {
471   vtkRenderer* aRenderer = getRenderer();
472   if(vtkActorCollection* anActors = aRenderer->GetActors()){
473     anActors->InitTraversal();
474     while(vtkActor *anAct = anActors->GetNextActor()){
475       if(SALOME_Actor* aSAct = SALOME_Actor::SafeDownCast(anAct)){
476         if(aSAct->hasIO() && aSAct->getIO()->hasEntry())
477           aRenderer->RemoveActor( anAct );
478       }
479     }
480
481     if(theIsUpdate)
482       Repaint();
483   }
484 }
485
486 //----------------------------------------------------------------------------
487 float
488 SVTK_View
489 ::GetTransparency(const Handle(SALOME_InteractiveObject)& theIObject) 
490 {
491   using namespace SVTK;
492   SALOME_Actor* anActor = 
493     Find<SALOME_Actor>(getRenderer()->GetActors(),
494                        TIsSameIObject<SALOME_Actor>(theIObject));
495   if(anActor)
496     return 1.0 - anActor->GetOpacity();
497   return -1.0;
498 }
499
500
501 void
502 SVTK_View
503 ::SetTransparency(const Handle(SALOME_InteractiveObject)& theIObject, 
504                   float theTrans)
505 {
506   float anOpacity = 1.0 - theTrans;
507   using namespace SVTK;
508   ForEachIf<SALOME_Actor>(getRenderer()->GetActors(),
509                           TIsSameIObject<SALOME_Actor>(theIObject),
510                           TSetFunction<SALOME_Actor,float>
511                           (&SALOME_Actor::SetOpacity,anOpacity));
512 }
513
514 //----------------------------------------------------------------------------
515 void
516 SVTK_View
517 ::SetColor(const Handle(SALOME_InteractiveObject)& theIObject,
518            const QColor& theColor) 
519 {
520   float aColor[3] = {theColor.red()/255., theColor.green()/255., theColor.blue()/255.};
521
522   using namespace SVTK;
523   ForEachIf<SALOME_Actor>(getRenderer()->GetActors(),
524                           TIsSameIObject<SALOME_Actor>(theIObject),
525                           TSetFunction<SALOME_Actor,const float*>
526                           (&SALOME_Actor::SetColor,aColor));
527 }
528
529
530 QColor
531 SVTK_View
532 ::GetColor(const Handle(SALOME_InteractiveObject)& theIObject) 
533 {
534   using namespace SVTK;
535   SALOME_Actor* anActor = 
536     Find<SALOME_Actor>(getRenderer()->GetActors(),
537                        TIsSameIObject<SALOME_Actor>(theIObject));
538   if(anActor){
539     float r,g,b;
540     anActor->GetColor(r,g,b);
541     return QColor(int(r*255),int(g*255),int(b*255));
542   }
543
544   return QColor(0,0,0);
545 }
546