Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/gui.git] / src / SVTK / SVTK_ViewModel.cxx
1 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
2 // 
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either 
6 // version 2.1 of the License.
7 // 
8 // This library is distributed in the hope that it will be useful 
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public  
14 // License along with this library; if not, write to the Free Software 
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #include <qpopupmenu.h>
20 #include <qcolordialog.h>
21
22 #include <vtkCamera.h>
23 #include <vtkRenderer.h>
24 #include <vtkActorCollection.h>
25
26 #include "SUIT_Session.h"
27
28 #include "SVTK_Selection.h"
29 #include "SVTK_ViewModel.h"
30 #include "SVTK_ViewWindow.h"
31 #include "SVTK_View.h"
32 #include "SVTK_MainWindow.h"
33 #include "SVTK_Prs.h"
34
35 #include "VTKViewer_ViewModel.h"
36
37 #include <SALOME_Actor.h>
38 #include <SALOME_InteractiveObject.hxx>
39
40 // in order NOT TO link with SalomeApp, here the code returns SALOMEDS_Study.
41 // SalomeApp_Study::studyDS() does it as well, but -- here it is retrieved from 
42 // SALOMEDS::StudyManager - no linkage with SalomeApp. 
43
44 // Temporarily commented to avoid awful dependecy on SALOMEDS
45 // TODO: better mechanism of storing display/erse status in a study
46 // should be provided...
47 //static _PTR(Study) getStudyDS() 
48 //{
49 //  SALOMEDSClient_Study* aStudy = NULL;
50 //  _PTR(StudyManager) aMgr( new SALOMEDS_StudyManager() );
51   // get id of SUIT_Study, if it's a SalomeApp_Study, it will return
52   //    id of its underlying SALOMEDS::Study
53 //  SUIT_Application* app = SUIT_Session::session()->activeApplication();
54 //  if ( !app )  return _PTR(Study)(aStudy); 
55 //  SUIT_Study* stud = app->activeStudy();
56 //  if ( !stud ) return _PTR(Study)(aStudy);  
57 //  const int id = stud->id(); // virtual method, must return SALOMEDS_Study id
58   // get SALOMEDS_Study with this id from StudyMgr
59 //  return aMgr->GetStudyByID( id );
60 //}
61
62 /*!
63   Constructor
64 */
65 SVTK_Viewer::SVTK_Viewer()
66 {
67   myTrihedronSize = 105;
68   myTrihedronRelative = true;
69 }
70
71 /*!
72   Destructor
73 */
74 SVTK_Viewer::~SVTK_Viewer() 
75 {
76 }
77
78 /*!
79   \return background color
80 */
81 QColor
82 SVTK_Viewer
83 ::backgroundColor() const
84 {
85   return myBgColor;
86 }
87
88 /*!
89   Changes background color
90   \param theColor - new background color
91 */
92 void
93 SVTK_Viewer
94 ::setBackgroundColor( const QColor& theColor )
95 {
96   if ( !theColor.isValid() )
97     return;
98
99   QPtrVector<SUIT_ViewWindow> aViews = myViewManager->getViews();
100   for(int i = 0, iEnd = aViews.size(); i < iEnd; i++){
101     if(SUIT_ViewWindow* aViewWindow = aViews.at(i)){
102       if(TViewWindow* aView = dynamic_cast<TViewWindow*>(aViewWindow)){
103         aView->setBackgroundColor(theColor);
104       }
105     }
106   }
107
108   myBgColor = theColor;
109 }
110
111 /*!Create new instance of view window on desktop \a theDesktop.
112  *\retval SUIT_ViewWindow* - created view window pointer.
113  */
114 SUIT_ViewWindow*
115 SVTK_Viewer::
116 createView( SUIT_Desktop* theDesktop )
117 {
118   TViewWindow* aViewWindow = new TViewWindow(theDesktop);
119   aViewWindow->Initialize(this);
120
121   aViewWindow->setBackgroundColor( backgroundColor() );
122   aViewWindow->SetTrihedronSize( trihedronSize(), trihedronRelative() );
123
124   return aViewWindow;
125 }
126
127 /*!
128   \return trihedron size
129 */
130 vtkFloatingPointType SVTK_Viewer::trihedronSize() const
131 {
132   return myTrihedronSize;
133 }
134
135 /*!
136   \return true if thihedron changes size in accordance with bounding box
137 */
138 bool SVTK_Viewer::trihedronRelative() const
139 {
140   return myTrihedronRelative;
141 }
142
143 /*!
144   Sets trihedron size and relativeness( whether thihedron changes size in accordance with bounding box)
145   \param theSize - new size
146   \param theRelative - new relativeness
147 */
148 void SVTK_Viewer::setTrihedronSize( const vtkFloatingPointType theSize, const bool theRelative )
149 {
150   myTrihedronSize = theSize;
151   myTrihedronRelative = theRelative;
152
153   if (SUIT_ViewManager* aViewManager = getViewManager()) {
154     QPtrVector<SUIT_ViewWindow> aViews = aViewManager->getViews();
155     for ( uint i = 0; i < aViews.count(); i++ )
156     {
157       if ( TViewWindow* aView = dynamic_cast<TViewWindow*>(aViews.at( i )) )
158               aView->SetTrihedronSize( theSize, theRelative );
159     }
160   }
161 }
162
163 /*!
164   Sets new view manager
165   \param theViewManager - new view manager
166 */
167 void SVTK_Viewer::setViewManager(SUIT_ViewManager* theViewManager)
168 {
169   SUIT_ViewModel::setViewManager(theViewManager);
170
171   if ( !theViewManager )
172     return;
173
174   connect(theViewManager, SIGNAL(mousePress(SUIT_ViewWindow*, QMouseEvent*)), 
175           this, SLOT(onMousePress(SUIT_ViewWindow*, QMouseEvent*)));
176   
177   connect(theViewManager, SIGNAL(mouseMove(SUIT_ViewWindow*, QMouseEvent*)), 
178           this, SLOT(onMouseMove(SUIT_ViewWindow*, QMouseEvent*)));
179   
180   connect(theViewManager, SIGNAL(mouseRelease(SUIT_ViewWindow*, QMouseEvent*)), 
181           this, SLOT(onMouseRelease(SUIT_ViewWindow*, QMouseEvent*)));
182 }
183
184 /*!
185   Builds popup for vtk viewer
186 */
187 void
188 SVTK_Viewer
189 ::contextMenuPopup( QPopupMenu* thePopup )
190 {
191   thePopup->insertItem( VTKViewer_Viewer::tr( "MEN_DUMP_VIEW" ), this, SLOT( onDumpView() ) );
192   thePopup->insertItem( VTKViewer_Viewer::tr( "MEN_CHANGE_BACKGROUD" ), this, SLOT( onChangeBgColor() ) );
193
194   thePopup->insertSeparator();
195
196   if(TViewWindow* aView = dynamic_cast<TViewWindow*>(myViewManager->getActiveView())){
197     if ( !aView->getMainWindow()->getToolBar()->isVisible() ){
198       thePopup->insertItem( VTKViewer_Viewer::tr( "MEN_SHOW_TOOLBAR" ), this, SLOT( onShowToolbar() ) );
199     }
200     aView->RefreshDumpImage();
201   }
202 }
203
204 /*!
205   SLOT: called on mouse button press, empty implementation
206 */
207 void 
208 SVTK_Viewer
209 ::onMousePress(SUIT_ViewWindow* vw, QMouseEvent* event)
210 {}
211
212 /*!
213   SLOT: called on mouse move, empty implementation
214 */
215 void 
216 SVTK_Viewer
217 ::onMouseMove(SUIT_ViewWindow* vw, QMouseEvent* event)
218 {}
219
220 /*!
221   SLOT: called on mouse button release, empty implementation
222 */
223 void 
224 SVTK_Viewer
225 ::onMouseRelease(SUIT_ViewWindow* vw, QMouseEvent* event)
226 {}
227
228 /*!
229   Enables/disables selection
230   \param isEnabled - new state
231 */
232 void 
233 SVTK_Viewer
234 ::enableSelection(bool isEnabled)
235 {
236   mySelectionEnabled = isEnabled;
237   //!! To be done for view windows
238 }
239
240 /*!
241   Enables/disables selection of many object
242   \param isEnabled - new state
243 */
244 void
245 SVTK_Viewer
246 ::enableMultiselection(bool isEnable)
247 {
248   myMultiSelectionEnabled = isEnable;
249   //!! To be done for view windows
250 }
251
252 /*!
253   SLOT: called on dump view operation is activated, stores scene to raster file
254 */
255 void
256 SVTK_Viewer
257 ::onDumpView()
258 {
259   if(SUIT_ViewWindow* aView = myViewManager->getActiveView())
260     aView->onDumpView();
261 }
262
263 /*!
264   SLOT: called if background color is to be changed changed, passes new color to view port
265 */
266 void
267 SVTK_Viewer
268 ::onChangeBgColor()
269 {
270   if(SUIT_ViewWindow* aView = myViewManager->getActiveView()){
271     QColor aColor = QColorDialog::getColor( backgroundColor(), aView);
272     setBackgroundColor(aColor);
273   }
274 }
275
276 /*!
277   SLOT: called when popup item "Show toolbar" is activated, shows toolbar of active view window
278 */
279 void
280 SVTK_Viewer
281 ::onShowToolbar() 
282 {
283   QPtrVector<SUIT_ViewWindow> aViews = myViewManager->getViews();
284   for(int i = 0, iEnd = aViews.size(); i < iEnd; i++){
285     if(TViewWindow* aView = dynamic_cast<TViewWindow*>(aViews.at(i))){
286       aView->getMainWindow()->getToolBar()->show();
287     }
288   }
289 }
290
291 /*!
292   Display presentation
293   \param prs - presentation
294 */
295 void
296 SVTK_Viewer
297 ::Display( const SALOME_VTKPrs* prs )
298 {
299   // try do downcast object
300   if(const SVTK_Prs* aPrs = dynamic_cast<const SVTK_Prs*>( prs )){
301     if(aPrs->IsNull())
302       return;
303     if(vtkActorCollection* anActorCollection = aPrs->GetObjects()){
304       // get SALOMEDS Study
305       // Temporarily commented to avoid awful dependecy on SALOMEDS
306       // TODO: better mechanism of storing display/erse status in a study
307       // should be provided...
308       // _PTR(Study) aStudy(getStudyDS());
309       anActorCollection->InitTraversal();
310       while(vtkActor* anActor = anActorCollection->GetNextActor()){
311         if(SALOME_Actor* anAct = SALOME_Actor::SafeDownCast(anActor)){
312           // Set visibility flag
313           // Temporarily commented to avoid awful dependecy on SALOMEDS
314           // TODO: better mechanism of storing display/erse status in a study
315           // should be provided...
316           //Handle(SALOME_InteractiveObject) anObj = anAct->getIO();
317           //if(!anObj.IsNull() && anObj->hasEntry() && aStudy){
318           //  ToolsGUI::SetVisibility(aStudy,anObj->getEntry(),true,this);
319           //}
320           // just display the object
321           QPtrVector<SUIT_ViewWindow> aViews = myViewManager->getViews();
322           for(int i = 0, iEnd = aViews.size(); i < iEnd; i++){
323             if(SVTK_ViewWindow* aViewWindow = dynamic_cast<SVTK_ViewWindow*>(aViews.at(i))){
324               if(SVTK_View* aView = aViewWindow->getView()){
325                 aView->Display(anAct,false);
326                 if(anAct->IsSetCamera()){
327                   vtkRenderer* aRenderer = aView->getRenderer();
328                   anAct->SetCamera( aRenderer->GetActiveCamera() );
329                 }
330               }
331             }
332           }
333         }
334       }
335     }
336   }
337 }
338
339 /*!
340   Erase presentation
341   \param prs - presentation
342   \param forced - removes object from view
343 */
344 void
345 SVTK_Viewer
346 ::Erase( const SALOME_VTKPrs* prs, const bool forced )
347 {
348   // try do downcast object
349   if(const SVTK_Prs* aPrs = dynamic_cast<const SVTK_Prs*>( prs )){
350     if(aPrs->IsNull())
351       return;
352     if(vtkActorCollection* anActorCollection = aPrs->GetObjects()){
353       // get SALOMEDS Study
354       // Temporarily commented to avoid awful dependecy on SALOMEDS
355       // TODO: better mechanism of storing display/erse status in a study
356       // should be provided...
357       //_PTR(Study) aStudy(getStudyDS());
358       anActorCollection->InitTraversal();
359       while(vtkActor* anActor = anActorCollection->GetNextActor())
360         if(SALOME_Actor* anAct = SALOME_Actor::SafeDownCast(anActor)){
361           // Set visibility flag
362           // Temporarily commented to avoid awful dependecy on SALOMEDS
363           // TODO: better mechanism of storing display/erse status in a study
364           // should be provided...
365           //Handle(SALOME_InteractiveObject) anObj = anAct->getIO();
366           //if(!anObj.IsNull() && anObj->hasEntry() && aStudy){
367           //  ToolsGUI::SetVisibility(aStudy,anObj->getEntry(),false,this);
368           //}
369           // just display the object
370           QPtrVector<SUIT_ViewWindow> aViews = myViewManager->getViews();
371           for(int i = 0, iEnd = aViews.size(); i < iEnd; i++){
372             if(SVTK_ViewWindow* aViewWindow = dynamic_cast<SVTK_ViewWindow*>(aViews.at(i)))
373               if(SVTK_View* aView = aViewWindow->getView())
374                 if ( forced )
375                   aView->Remove(anAct,false);
376                 else
377                   aView->Erase(anAct,forced);
378           }
379         }
380     }
381   }
382 }
383
384 /*!
385   Erase all presentations
386   \param forced - removes all objects from view
387 */
388 void
389 SVTK_Viewer
390 ::EraseAll( const bool forced )
391 {
392   // Temporarily commented to avoid awful dependecy on SALOMEDS
393   // TODO: better mechanism of storing display/erse status in a study
394   // should be provided...
395   //_PTR(Study) aStudy(getStudyDS());
396   QPtrVector<SUIT_ViewWindow> aViews = myViewManager->getViews();
397   for(int i = 0, iEnd = aViews.size(); i < iEnd; i++){
398     if(SVTK_ViewWindow* aViewWindow = dynamic_cast<SVTK_ViewWindow*>(aViews.at(i)))
399       if(SVTK_View* aView = aViewWindow->getView()){
400         vtkRenderer* aRenderer =  aView->getRenderer();
401         vtkActorCollection* anActorCollection = aRenderer->GetActors();
402         anActorCollection->InitTraversal();
403         while(vtkActor* anActor = anActorCollection->GetNextActor()){
404           if(SALOME_Actor* anAct = SALOME_Actor::SafeDownCast(anActor)){
405             // Set visibility flag
406             // Temporarily commented to avoid awful dependecy on SALOMEDS
407             // TODO: better mechanism of storing display/erse status in a study
408             // should be provided...
409             //Handle(SALOME_InteractiveObject) anObj = anAct->getIO();
410             //if(!anObj.IsNull() && anObj->hasEntry() && aStudy)
411             //  ToolsGUI::SetVisibility(aStudy,anObj->getEntry(),false,this);
412             if(forced)
413               aRenderer->RemoveActor(anAct);
414             else{
415               // just erase actor
416               anAct->SetVisibility( false );
417               // erase dependent actors
418               vtkActorCollection* aCollection = vtkActorCollection::New();
419               anAct->GetChildActors( aCollection );
420               aCollection->InitTraversal();
421               while(vtkActor* aSubAct = aCollection->GetNextActor())
422                 aSubAct->SetVisibility( false );
423               aCollection->Delete();
424             }
425           }
426         }
427       }
428   }
429   Repaint();
430 }
431
432 /*!
433   Create presentation corresponding to the entry
434   \param entry - entry
435 */
436 SALOME_Prs* 
437 SVTK_Viewer
438 ::CreatePrs( const char* entry )
439 {
440   SVTK_Prs* prs = new SVTK_Prs();
441   if ( entry ) {
442     if(SVTK_ViewWindow* aViewWindow = dynamic_cast<SVTK_ViewWindow*>(getViewManager()->getActiveView()))
443       if(SVTK_View* aView = aViewWindow->getView()){
444         vtkRenderer* aRenderer =  aView->getRenderer();
445         vtkActorCollection* theActors = aRenderer->GetActors();
446         theActors->InitTraversal();
447         vtkActor* ac;
448         while( ( ac = theActors->GetNextActor() ) ) {
449           SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
450           if ( anActor && anActor->hasIO() && !strcmp( anActor->getIO()->getEntry(), entry ) ) {
451             prs->AddObject( ac );
452           }
453         }
454       }
455   }
456   return prs;
457 }
458
459 /*!
460   Auxiliary method called before displaying of objects
461 */
462 void
463 SVTK_Viewer
464 ::BeforeDisplay( SALOME_Displayer* d )
465 {
466   d->BeforeDisplay( this, SALOME_VTKViewType() );
467 }
468
469 /*!
470   Auxiliary method called after displaying of objects
471 */
472 void
473 SVTK_Viewer::AfterDisplay( SALOME_Displayer* d )
474 {
475   d->AfterDisplay( this, SALOME_VTKViewType() );
476 }
477
478 /*!
479   \return true if object is displayed in viewer
480   \param obj - object to be checked
481 */
482 bool
483 SVTK_Viewer
484 ::isVisible( const Handle(SALOME_InteractiveObject)& io )
485 {
486   QPtrVector<SUIT_ViewWindow> aViews = myViewManager->getViews();
487   for(int i = 0, iEnd = aViews.size(); i < iEnd; i++)
488     if(SUIT_ViewWindow* aViewWindow = aViews.at(i))
489       if(TViewWindow* aViewWnd = dynamic_cast<TViewWindow*>(aViewWindow))
490         if(SVTK_View* aView = aViewWnd->getView())
491           if(!aView->isVisible( io ))
492             return false;
493
494   return true;
495 }
496
497 /*!
498   Updates current viewer
499 */
500 void 
501 SVTK_Viewer
502 ::Repaint()
503 {
504 //  if (theUpdateTrihedron) onAdjustTrihedron();
505   QPtrVector<SUIT_ViewWindow> aViews = myViewManager->getViews();
506   for(int i = 0, iEnd = aViews.size(); i < iEnd; i++)
507     if(TViewWindow* aViewWindow = dynamic_cast<TViewWindow*>(aViews.at(i)))
508       if(SVTK_View* aView = aViewWindow->getView())
509         aView->Repaint();
510 }