Salome HOME
Join modifications from branch OCC_debug_for_3_2_0b1
[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   Constructor
45 */
46 SVTK_SignalHandler
47 ::SVTK_SignalHandler(SVTK_MainWindow* theMainWindow):
48   QObject(theMainWindow),
49   myMainWindow(theMainWindow)
50 {
51   SVTK_RenderWindowInteractor* anInteractor = theMainWindow->GetInteractor();
52
53   connect(anInteractor,SIGNAL(KeyPressed(QKeyEvent*)),
54           this,SIGNAL(KeyPressed(QKeyEvent*)) );
55   connect(anInteractor,SIGNAL(KeyReleased(QKeyEvent*)),
56           this,SIGNAL(KeyReleased(QKeyEvent*)));
57   connect(anInteractor,SIGNAL(MouseButtonPressed(QMouseEvent*)),
58           this,SIGNAL(MouseButtonPressed(QMouseEvent*)));
59   connect(anInteractor,SIGNAL(MouseButtonReleased(QMouseEvent*)),
60           this,SIGNAL(MouseButtonReleased(QMouseEvent*)));
61   connect(anInteractor,SIGNAL(MouseDoubleClicked(QMouseEvent*)),
62           this,SIGNAL(MouseDoubleClicked(QMouseEvent*)));
63   connect(anInteractor,SIGNAL(MouseMove(QMouseEvent*)),
64           this,SIGNAL(MouseMove(QMouseEvent*)));
65   connect(anInteractor,SIGNAL(contextMenuRequested(QContextMenuEvent*)),
66           this,SIGNAL(contextMenuRequested(QContextMenuEvent*)));
67   connect(anInteractor,SIGNAL(selectionChanged()),
68           this,SIGNAL(selectionChanged()));
69 }
70
71 /*!
72   Destructor
73 */
74 SVTK_SignalHandler
75 ::~SVTK_SignalHandler()
76 {
77 }
78
79 /*!
80   \return corresponding svtk main window
81 */
82 SVTK_MainWindow*
83 SVTK_SignalHandler
84 ::GetMainWindow()
85 {
86   return myMainWindow;
87 }
88
89
90 /*!
91   Redirect the request to #SVTK_MainWindow::Repaint (just for flexibility)
92 */
93 void
94 SVTK_SignalHandler
95 ::Repaint(bool theUpdateTrihedron)
96 {
97   myMainWindow->Repaint(theUpdateTrihedron);
98 }
99
100 /*!
101   Redirect the request to #SVTK_MainWindow::GetRenderer (just for flexibility)
102 */
103 SVTK_Renderer* 
104 SVTK_SignalHandler
105 ::GetRenderer()
106 {
107   return myMainWindow->GetRenderer();
108 }
109
110 /*!
111   Redirect the request to #SVTK_MainWindow::getRenderer (just for flexibility)
112 */
113 vtkRenderer* 
114 SVTK_SignalHandler
115 ::getRenderer()
116 {
117   return myMainWindow->getRenderer();
118 }
119
120 namespace SVTK
121 {
122   struct THighlightAction
123   {
124     bool myIsHighlight;
125     THighlightAction( bool theIsHighlight ):
126       myIsHighlight( theIsHighlight )
127     {}
128     
129     void
130     operator()( SALOME_Actor* theActor) 
131     {
132       if(theActor->GetMapper() && theActor->hasIO()){
133         theActor->Highlight( myIsHighlight );
134       }
135     }
136   };
137 }
138
139 /*!
140   SLOT: called on selection change
141 */
142 void
143 SVTK_SignalHandler
144 ::onSelectionChanged()
145 {
146   vtkActorCollection* anActors = myMainWindow->getRenderer()->GetActors();
147
148   using namespace SVTK;
149   ForEach<SALOME_Actor>(anActors,
150                         THighlightAction( false ));
151   SVTK_Selector* aSelector = myMainWindow->GetSelector();
152   const SALOME_ListIO& aListIO = aSelector->StoredIObjects();
153   SALOME_ListIteratorOfListIO anIter(aListIO);
154   for(; anIter.More(); anIter.Next()){
155     ForEachIf<SALOME_Actor>(anActors,
156                             TIsSameIObject<SALOME_Actor>(anIter.Value()),
157                             THighlightAction(true));
158   }
159
160   myMainWindow->Repaint(false);
161 }
162
163 /*!
164   Constructor
165 */
166 SVTK_View
167 ::SVTK_View(SVTK_MainWindow* theMainWindow) :
168   SVTK_SignalHandler(theMainWindow)
169 {
170 }
171
172 /*!
173   Destructor
174 */
175 SVTK_View
176 ::~SVTK_View()
177 {
178 }
179
180 /*!
181   Unhilights all objects in viewer
182 */
183 void 
184 SVTK_View
185 ::unHighlightAll() 
186 {
187   using namespace SVTK;
188   ForEach<SALOME_Actor>(getRenderer()->GetActors(),
189                         THighlightAction( false ));
190   Repaint();
191 }
192
193 /*!
194   Hilights/unhilights object in viewer
195   \param theIO - object to be updated
196   \param theIsHighlight - if it is true, object will be hilighted, otherwise it will be unhilighted
197   \param theIsUpdate - update current viewer
198 */
199 void
200 SVTK_View
201 ::highlight( const Handle(SALOME_InteractiveObject)& theIO, 
202              bool theIsHighlight, 
203              bool theIsUpdate ) 
204 {
205   using namespace SVTK;
206   ForEachIf<SALOME_Actor>(getRenderer()->GetActors(),
207                           TIsSameIObject<SALOME_Actor>( theIO ),
208                           THighlightAction(theIsHighlight));
209   Repaint();
210 }
211
212 /*!
213   Display object
214   \param theEntry - entry that corresponds to intractive objects
215 */
216 Handle(SALOME_InteractiveObject)
217 SVTK_View
218 ::FindIObject(const char* theEntry) 
219 {
220   using namespace SVTK;
221   SALOME_Actor* anActor = 
222     Find<SALOME_Actor>(getRenderer()->GetActors(),
223                        TIsSameEntry<SALOME_Actor>(theEntry));
224   if(anActor != NULL)
225     return anActor->getIO();
226  
227   return NULL;
228 }
229
230 /*!
231    Redirect the request to #SVTK_Renderer::SetPreselectionProp
232 */
233 void
234 SVTK_View
235 ::SetSelectionProp(const double& theRed, 
236                    const double& theGreen, 
237                    const double& theBlue, 
238                    const int& theWidth) 
239 {
240   GetRenderer()->SetSelectionProp(theRed,theGreen,theBlue,theWidth);
241 }
242
243 /*!
244   Redirect the request to #SVTK_Renderer::SetPreselectionProp
245 */
246 void
247 SVTK_View
248 ::SetPreselectionProp(const double& theRed, 
249                       const double& theGreen, 
250                       const double& theBlue, 
251                       const int& theWidth) 
252 {
253   GetRenderer()->SetPreselectionProp(theRed,theGreen,theBlue,theWidth);
254 }
255
256 /*!
257   Redirect the request to #SVTK_Renderer::SetPreselectionProp
258 */
259 void
260 SVTK_View
261 ::SetSelectionTolerance(const double& theTolNodes, 
262                         const double& theTolCell)
263 {
264   GetRenderer()->SetSelectionTolerance(theTolNodes,theTolCell);
265 }
266
267 /*!
268   \return true if object is in viewer or in collector
269   \param theIO - object to be checked
270 */
271 bool
272 SVTK_View
273 ::isInViewer(const Handle(SALOME_InteractiveObject)& theIObject)
274 {
275   using namespace SVTK;
276   SALOME_Actor* anActor = 
277     Find<SALOME_Actor>(getRenderer()->GetActors(),
278                        TIsSameIObject<SALOME_Actor>(theIObject));
279   return anActor != NULL;
280 }
281
282 /*!
283   \return true if object is displayed in viewer
284   \param theIO - object to be checked
285 */
286 bool
287 SVTK_View
288 ::isVisible(const Handle(SALOME_InteractiveObject)& theIObject)
289 {
290   using namespace SVTK;
291   SALOME_Actor* anActor = 
292     Find<SALOME_Actor>(getRenderer()->GetActors(),
293                        TIsSameIObject<SALOME_Actor>(theIObject));
294   return anActor != NULL && anActor->GetVisibility();
295 }
296
297 /*!
298   Changes name of object
299   \param theIObject - object to be renamed
300   \param theName - new name
301 */
302 void
303 SVTK_View
304 ::rename(const Handle(SALOME_InteractiveObject)& theIObject, 
305          const QString& theName)
306 {
307   using namespace SVTK;
308   ForEachIf<SALOME_Actor>(getRenderer()->GetActors(),
309                           TIsSameIObject<SALOME_Actor>(theIObject),
310                           TSetFunction<SALOME_Actor,const char*,QString>
311                           (&SALOME_Actor::setName,theName.latin1()));
312 }
313
314 /*!
315   \return current display mode (obsolete)
316 */
317 int
318 SVTK_View
319 ::GetDisplayMode() 
320 {
321   return myDisplayMode; 
322 }
323
324 /*!
325   Set current display mode
326   \param theMode - new display mode
327 */
328 void
329 SVTK_View
330 ::SetDisplayMode(int theMode)
331 {
332   if(theMode == 0) 
333     ChangeRepresentationToWireframe();
334   else 
335     ChangeRepresentationToSurface();
336   myDisplayMode = theMode;
337 }
338
339 /*!
340   Set current display mode
341   \param theIObject - object
342   \param theMode - new display mode
343 */
344 void
345 SVTK_View
346 ::SetDisplayMode(const Handle(SALOME_InteractiveObject)& theIObject, 
347                  int theMode)
348 {
349   using namespace SVTK;
350   ForEachIf<SALOME_Actor>(getRenderer()->GetActors(),
351                           TIsSameIObject<SALOME_Actor>(theIObject),
352                           TSetFunction<SALOME_Actor,int>
353                           (&SALOME_Actor::setDisplayMode,theMode));
354 }
355
356 /*!
357   Change all actors to wireframe
358 */
359 void
360 SVTK_View
361 ::ChangeRepresentationToWireframe()
362 {
363   ChangeRepresentationToWireframe(getRenderer()->GetActors());
364 }
365
366 /*!
367   Change all actors to shading
368 */
369 void
370 SVTK_View
371 ::ChangeRepresentationToSurface()
372 {
373   ChangeRepresentationToSurface(getRenderer()->GetActors());
374 }
375
376 /*!
377   Change to wireframe a list of vtkactor
378   theCollection - list of vtkactor
379 */
380 void
381 SVTK_View
382 ::ChangeRepresentationToWireframe(vtkActorCollection* theCollection)
383 {
384   using namespace SVTK;
385   ForEach<SALOME_Actor>(theCollection,
386                         TSetFunction<SALOME_Actor,int>
387                         (&SALOME_Actor::setDisplayMode,0));
388   Repaint();
389 }
390
391 /*!
392   Change to shading a list of vtkactor
393   theCollection - list of vtkactor
394 */
395 void
396 SVTK_View
397 ::ChangeRepresentationToSurface(vtkActorCollection* theCollection)
398 {
399   using namespace SVTK;
400   ForEach<SALOME_Actor>(theCollection,
401                         TSetFunction<SALOME_Actor,int>
402                         (&SALOME_Actor::setDisplayMode,1));
403   Repaint();
404 }
405
406 namespace SVTK
407 {
408   struct TErase
409   {
410     VTK::TSetFunction<vtkActor,int> mySetFunction;
411     TErase():
412       mySetFunction(&vtkActor::SetVisibility,false)
413     {}
414     void
415     operator()(SALOME_Actor* theActor)
416     {
417       theActor->SetVisibility(false);
418       // Erase dependent actors
419       vtkActorCollection* aCollection = vtkActorCollection::New(); 
420       theActor->GetChildActors(aCollection);
421       VTK::ForEach<vtkActor>(aCollection,mySetFunction);
422       aCollection->Delete();
423     }
424   };
425 }
426
427 /*!
428   To erase all existing VTK presentations
429 */
430 void
431 SVTK_View
432 ::EraseAll()
433 {   
434   using namespace SVTK;
435   ForEach<SALOME_Actor>(getRenderer()->GetActors(),
436                         TErase());
437   Repaint();
438 }
439
440 /*!
441   To display all existing VTK presentations
442 */
443 void
444 SVTK_View
445 ::DisplayAll()
446
447   using namespace SVTK;
448   ForEach<SALOME_Actor>(getRenderer()->GetActors(),
449                         TSetVisibility<SALOME_Actor>(true));
450   Repaint();
451 }
452
453 /*!
454   To erase VTK presentation
455   \param theActor - actor
456   \param theIsUpdate - updates current viewer
457 */
458 void
459 SVTK_View
460 ::Erase(SALOME_Actor* theActor, 
461         bool theIsUpdate)
462 {
463   SVTK::TErase()(theActor);
464
465   if(theIsUpdate)
466     Repaint();
467 }
468
469
470 /*!
471   To erase VTK presentation
472   \param theIObject - object
473   \param theIsUpdate - updates current viewer
474 */
475 void
476 SVTK_View
477 ::Erase(const Handle(SALOME_InteractiveObject)& theIObject, 
478         bool theIsUpdate)
479 {
480   using namespace SVTK;
481   ForEachIf<SALOME_Actor>(getRenderer()->GetActors(),
482                           TIsSameIObject<SALOME_Actor>(theIObject),
483                           TErase());
484   if(theIsUpdate)
485     Repaint();
486 }
487
488 /*!
489   To display the VTK presentation
490 */
491 void
492 SVTK_View
493 ::Display(SALOME_Actor* theActor, 
494           bool theIsUpdate)
495 {
496   GetRenderer()->AddActor(theActor);
497   theActor->SetVisibility(true);
498
499   if(theIsUpdate)
500     Repaint();
501 }
502
503 /*!
504   To display the VTK presentation
505 */
506 void
507 SVTK_View
508 ::Display(const Handle(SALOME_InteractiveObject)& theIObject, 
509           bool theIsUpdate)
510 {
511   using namespace SVTK;
512   ForEachIf<SALOME_Actor>(getRenderer()->GetActors(),
513                           TIsSameIObject<SALOME_Actor>(theIObject),
514                           TSetVisibility<SALOME_Actor>(true));
515
516   if(theIsUpdate)
517     Repaint();
518 }
519
520 /*!
521   To display VTK presentation with defined #SALOME_InteractiveObject and erase all others
522 */
523 void
524 SVTK_View
525 ::DisplayOnly(const Handle(SALOME_InteractiveObject)& theIObject)
526 {
527   EraseAll();
528   Display(theIObject);
529 }
530
531
532 namespace SVTK
533 {
534   struct TRemoveAction
535   {
536     SVTK_Renderer* myRenderer;
537     TRemoveAction(SVTK_Renderer* theRenderer): 
538       myRenderer(theRenderer)
539     {}
540     void
541     operator()(SALOME_Actor* theActor)
542     {
543       myRenderer->RemoveActor(theActor);
544     }
545   };
546 }
547
548 /*!
549   To remove the VTK presentation
550 */
551 void
552 SVTK_View
553 ::Remove(const Handle(SALOME_InteractiveObject)& theIObject, 
554          bool theIsUpdate)
555 {
556   using namespace SVTK;
557   ForEachIf<SALOME_Actor>(getRenderer()->GetActors(),
558                           TIsSameIObject<SALOME_Actor>(theIObject),
559                           TRemoveAction(GetRenderer()));
560   if(theIsUpdate)
561     Repaint();
562 }
563
564 /*!
565   To remove the VTK presentation
566 */
567 void
568 SVTK_View
569 ::Remove(SALOME_Actor* theActor, 
570          bool theIsUpdate)
571 {
572   GetRenderer()->RemoveActor(theActor);
573   if(theIsUpdate)
574     Repaint();
575 }
576
577 /*!
578   To remove all VTK presentations
579 */
580 void
581 SVTK_View
582 ::RemoveAll(bool theIsUpdate)
583 {
584   vtkRenderer* aRenderer = getRenderer();
585   if(vtkActorCollection* anActors = aRenderer->GetActors()){
586     anActors->InitTraversal();
587     while(vtkActor *anAct = anActors->GetNextActor()){
588       if(SALOME_Actor* aSAct = SALOME_Actor::SafeDownCast(anAct)){
589         if(aSAct->hasIO() && aSAct->getIO()->hasEntry())
590           aRenderer->RemoveActor( anAct );
591       }
592     }
593
594     if(theIsUpdate)
595       Repaint();
596   }
597 }
598
599 /*!
600   \return current transparency
601   \param theIObject - object
602 */
603 float
604 SVTK_View
605 ::GetTransparency(const Handle(SALOME_InteractiveObject)& theIObject) 
606 {
607   using namespace SVTK;
608   SALOME_Actor* anActor = 
609     Find<SALOME_Actor>(getRenderer()->GetActors(),
610                        TIsSameIObject<SALOME_Actor>(theIObject));
611   if(anActor)
612     return 1.0 - anActor->GetOpacity();
613   return -1.0;
614 }
615
616
617 /*!
618   Sets current transparency
619   \param theIObject - object
620   \param theTrans - new transparency
621 */
622 void
623 SVTK_View
624 ::SetTransparency(const Handle(SALOME_InteractiveObject)& theIObject, 
625                   float theTrans)
626 {
627   vtkFloatingPointType anOpacity = 1.0 - theTrans;
628   using namespace SVTK;
629   ForEachIf<SALOME_Actor>(getRenderer()->GetActors(),
630                           TIsSameIObject<SALOME_Actor>(theIObject),
631                           TSetFunction<SALOME_Actor,vtkFloatingPointType>
632                           (&SALOME_Actor::SetOpacity,anOpacity));
633 }
634
635 /*!
636   Change color
637   \param theIObject - object
638   \param theColor - new color
639 */
640 void
641 SVTK_View
642 ::SetColor(const Handle(SALOME_InteractiveObject)& theIObject,
643            const QColor& theColor) 
644 {
645   vtkFloatingPointType aColor[3] = {theColor.red()/255., theColor.green()/255., theColor.blue()/255.};
646
647   using namespace SVTK;
648   ForEachIf<SALOME_Actor>(getRenderer()->GetActors(),
649                           TIsSameIObject<SALOME_Actor>(theIObject),
650                           TSetFunction<SALOME_Actor,const vtkFloatingPointType*>
651                           (&SALOME_Actor::SetColor,aColor));
652 }
653
654
655 /*!
656   \return object color
657   \param theIObject - object
658 */
659 QColor
660 SVTK_View
661 ::GetColor(const Handle(SALOME_InteractiveObject)& theIObject) 
662 {
663   using namespace SVTK;
664   SALOME_Actor* anActor = 
665     Find<SALOME_Actor>(getRenderer()->GetActors(),
666                        TIsSameIObject<SALOME_Actor>(theIObject));
667   if(anActor){
668     vtkFloatingPointType r,g,b;
669     anActor->GetColor(r,g,b);
670     return QColor(int(r*255),int(g*255),int(b*255));
671   }
672
673   return QColor(0,0,0);
674 }
675