Salome HOME
60942b8447fad78848741abf477bf8cda2b15076
[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/
18 //
19 #include <qpopupmenu.h>\r
20 #include <qcolordialog.h>\r
21 \r
22 #include <vtkCamera.h>\r
23 #include <vtkRenderer.h>\r
24 #include <vtkActorCollection.h>\r
25 \r
26 #include "SUIT_Session.h"\r
27 \r
28 #include "SVTK_Selection.h"\r
29 #include "SVTK_ViewModel.h"\r
30 #include "SVTK_ViewWindow.h"\r
31 #include "SVTK_Prs.h"\r
32 \r
33 #include "VTKViewer_ViewModel.h"\r
34 \r
35 #include "SVTK_RenderWindowInteractor.h"\r
36 #include "SVTK_RenderWindow.h"\r
37 \r
38 //#include <ToolsGUI.h>\r
39 \r
40 #include <SALOME_Actor.h>\r
41 #include <SALOME_InteractiveObject.hxx>\r
42 \r
43 // Temporarily commented to avoid awful dependecy on SALOMEDS\r
44 // TODO: better mechanism of storing display/erse status in a study\r
45 // should be provided...\r
46 //#include "Utils_ORB_INIT.hxx"\r
47 //#include "Utils_SINGLETON.hxx"\r
48 //#include "SALOME_ModuleCatalog_impl.hxx"\r
49 //#include "SALOME_NamingService.hxx"\r
50 \r
51 //#include "SALOMEDSClient.hxx"\r
52 //#include "SALOMEDS_StudyManager.hxx"\r
53 \r
54 // in order NOT TO link with SalomeApp, here the code returns SALOMEDS_Study.\r
55 // SalomeApp_Study::studyDS() does it as well, but -- here it is retrieved from \r
56 // SALOMEDS::StudyManager - no linkage with SalomeApp. \r
57 \r
58 // Temporarily commented to avoid awful dependecy on SALOMEDS\r
59 // TODO: better mechanism of storing display/erse status in a study\r
60 // should be provided...\r
61 //static _PTR(Study) getStudyDS() \r
62 //{\r
63 //  SALOMEDSClient_Study* aStudy = NULL;\r
64 //  _PTR(StudyManager) aMgr( new SALOMEDS_StudyManager() );\r
65   // get id of SUIT_Study, if it's a SalomeApp_Study, it will return\r
66   //    id of its underlying SALOMEDS::Study\r
67 //  SUIT_Application* app = SUIT_Session::session()->activeApplication();\r
68 //  if ( !app )  return _PTR(Study)(aStudy); \r
69 //  SUIT_Study* stud = app->activeStudy();\r
70 //  if ( !stud ) return _PTR(Study)(aStudy);  \r
71 //  const int id = stud->id(); // virtual method, must return SALOMEDS_Study id\r
72   // get SALOMEDS_Study with this id from StudyMgr\r
73 //  return aMgr->GetStudyByID( id );\r
74 //}\r
75 \r
76 //==========================================================\r
77 SVTK_Viewer::SVTK_Viewer()\r
78 {\r
79   myTrihedronSize = 100;\r
80 }\r
81 \r
82 //==========================================================\r
83 SVTK_Viewer::~SVTK_Viewer() \r
84 {\r
85 }\r
86 \r
87 QColor SVTK_Viewer::backgroundColor() const\r
88 {\r
89   return myBgColor;\r
90 }\r
91 \r
92 void SVTK_Viewer::setBackgroundColor( const QColor& c )\r
93 {\r
94   if ( c.isValid() )\r
95     myBgColor = c;\r
96 }\r
97 \r
98 //==========================================================\r
99 SUIT_ViewWindow* SVTK_Viewer::createView( SUIT_Desktop* theDesktop )\r
100 {\r
101   SVTK_ViewWindow* vw = new SVTK_ViewWindow( theDesktop, this );\r
102   vw->setBackgroundColor( backgroundColor() );\r
103   vw->SetTrihedronSize( trihedronSize() );\r
104   return vw;\r
105 }\r
106 \r
107 int SVTK_Viewer::trihedronSize() const\r
108 {\r
109   return myTrihedronSize;\r
110 }\r
111 \r
112 void SVTK_Viewer::setTrihedronSize( const int sz )\r
113 {\r
114   myTrihedronSize = sz;\r
115 \r
116   SUIT_ViewManager* vm = getViewManager();\r
117   if ( !vm )\r
118     return;\r
119 \r
120   QPtrVector<SUIT_ViewWindow> vec = vm->getViews();\r
121   for ( int i = 0; i < vec.count(); i++ )\r
122   {\r
123     SUIT_ViewWindow* win = vec.at( i );\r
124     if ( !win || !win->inherits( "SVTK_ViewWindow" ) )\r
125       continue;\r
126 \r
127     SVTK_ViewWindow* vw = (SVTK_ViewWindow*)win;\r
128     vw->SetTrihedronSize( sz );\r
129   }\r
130 }\r
131 \r
132 //==========================================================\r
133 void SVTK_Viewer::setViewManager(SUIT_ViewManager* theViewManager)\r
134 {\r
135   SUIT_ViewModel::setViewManager(theViewManager);\r
136 \r
137   if ( !theViewManager )\r
138     return;\r
139 \r
140   connect(theViewManager, SIGNAL(mousePress(SUIT_ViewWindow*, QMouseEvent*)), \r
141           this, SLOT(onMousePress(SUIT_ViewWindow*, QMouseEvent*)));\r
142   \r
143   connect(theViewManager, SIGNAL(mouseMove(SUIT_ViewWindow*, QMouseEvent*)), \r
144           this, SLOT(onMouseMove(SUIT_ViewWindow*, QMouseEvent*)));\r
145   \r
146   connect(theViewManager, SIGNAL(mouseRelease(SUIT_ViewWindow*, QMouseEvent*)), \r
147           this, SLOT(onMouseRelease(SUIT_ViewWindow*, QMouseEvent*)));\r
148 }\r
149 \r
150 //==========================================================\r
151 void SVTK_Viewer::contextMenuPopup( QPopupMenu* thePopup )\r
152 {\r
153   thePopup->insertItem( VTKViewer_Viewer::tr( "MEN_DUMP_VIEW" ), this, SLOT( onDumpView() ) );\r
154   thePopup->insertItem( VTKViewer_Viewer::tr( "MEN_CHANGE_BACKGROUD" ), this, SLOT( onChangeBgColor() ) );\r
155 \r
156   thePopup->insertSeparator();\r
157 \r
158   SVTK_ViewWindow* aView = (SVTK_ViewWindow*)(myViewManager->getActiveView());\r
159   if ( aView && !aView->getToolBar()->isVisible() )\r
160     thePopup->insertItem( VTKViewer_Viewer::tr( "MEN_SHOW_TOOLBAR" ), this, SLOT( onShowToolbar() ) );\r
161 }\r
162 \r
163 //==========================================================\r
164 void SVTK_Viewer::onMousePress(SUIT_ViewWindow* vw, QMouseEvent* event)\r
165 {\r
166   if(SVTK_ViewWindow* aVW = dynamic_cast<SVTK_ViewWindow*>(vw)){\r
167     if(SVTK_RenderWindowInteractor* aRWI = aVW->getRWInteractor()){\r
168       switch(event->button()) {\r
169       case LeftButton:\r
170         aRWI->LeftButtonPressed(event) ;\r
171         break ;\r
172       case MidButton:\r
173         aRWI->MiddleButtonPressed(event) ;\r
174         break ;\r
175       case RightButton:\r
176         aRWI->RightButtonPressed(event) ;\r
177         break;\r
178       default:\r
179         break ;\r
180       }\r
181     }\r
182   }\r
183 }\r
184 \r
185 //==========================================================\r
186 void \r
187 SVTK_Viewer\r
188 ::onMouseMove(SUIT_ViewWindow* vw, QMouseEvent* event)\r
189 {\r
190   if(SVTK_ViewWindow* aVW = dynamic_cast<SVTK_ViewWindow*>(vw)){\r
191     if(SVTK_RenderWindowInteractor* aRWI = aVW->getRWInteractor()){\r
192       aRWI->MouseMove( event );\r
193     }\r
194   }\r
195 }\r
196 \r
197 //==========================================================\r
198 void \r
199 SVTK_Viewer\r
200 ::onMouseRelease(SUIT_ViewWindow* vw, QMouseEvent* event)\r
201 {\r
202   if(SVTK_ViewWindow* aVW = dynamic_cast<SVTK_ViewWindow*>(vw)){\r
203     if(SVTK_RenderWindowInteractor* aRWI = aVW->getRWInteractor()){\r
204       switch(event->button()) {\r
205       case LeftButton:\r
206         aRWI->LeftButtonReleased(event) ;\r
207         break ;\r
208       case MidButton:\r
209         aRWI->MiddleButtonReleased(event) ;\r
210         break ;\r
211       case RightButton:\r
212         aRWI->RightButtonReleased(event) ;\r
213         break;\r
214       default:\r
215         break ;\r
216       }\r
217     }\r
218   }\r
219 }\r
220 \r
221 //==========================================================\r
222 void \r
223 SVTK_Viewer\r
224 ::enableSelection(bool isEnabled)\r
225 {\r
226   mySelectionEnabled = isEnabled;\r
227   //!! To be done for view windows\r
228 }\r
229 \r
230 //==========================================================\r
231 void\r
232 SVTK_Viewer\r
233 ::enableMultiselection(bool isEnable)\r
234 {\r
235   myMultiSelectionEnabled = isEnable;\r
236   //!! To be done for view windows\r
237 }\r
238 \r
239 void SVTK_Viewer::onDumpView()\r
240 {\r
241   SVTK_ViewWindow* aView = (SVTK_ViewWindow*)(myViewManager->getActiveView());\r
242   if ( aView )\r
243     aView->onDumpView();\r
244 }\r
245 \r
246 //==========================================================\r
247 void SVTK_Viewer::onChangeBgColor()\r
248 {\r
249   QPtrVector<SUIT_ViewWindow> aViews = myViewManager->getViews();\r
250   for(int i = 0, iEnd = aViews.size(); i < iEnd; i++)\r
251     if(SUIT_ViewWindow* aViewWindow = aViews.at(i))\r
252       if(SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(aViewWindow)){\r
253         QColor aColor = QColorDialog::getColor( aView->backgroundColor(), aView);\r
254         if ( aColor.isValid() )\r
255           aView->setBackgroundColor(aColor);\r
256       }\r
257 }\r
258 \r
259 //==========================================================\r
260 void\r
261 SVTK_Viewer\r
262 ::onShowToolbar() \r
263 {\r
264   QPtrVector<SUIT_ViewWindow> aViews = myViewManager->getViews();\r
265   for(int i = 0, iEnd = aViews.size(); i < iEnd; i++)\r
266     if(SUIT_ViewWindow* aViewWindow = aViews.at(i))\r
267       if(SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(aViewWindow))\r
268         aView->getToolBar()->show();    \r
269 }\r
270 \r
271 //==========================================================\r
272 void\r
273 SVTK_Viewer\r
274 ::Display( const SALOME_VTKPrs* prs )\r
275 {\r
276   // try do downcast object\r
277   if(const SVTK_Prs* aPrs = dynamic_cast<const SVTK_Prs*>( prs )){\r
278     if(aPrs->IsNull())\r
279       return;\r
280     if(vtkActorCollection* anActorCollection = aPrs->GetObjects()){\r
281       // get SALOMEDS Study\r
282       // Temporarily commented to avoid awful dependecy on SALOMEDS\r
283       // TODO: better mechanism of storing display/erse status in a study\r
284       // should be provided...\r
285       // _PTR(Study) aStudy(getStudyDS());\r
286       anActorCollection->InitTraversal();\r
287       while(vtkActor* anActor = anActorCollection->GetNextActor()){\r
288         if(SALOME_Actor* anAct = SALOME_Actor::SafeDownCast(anActor)){\r
289           // Set visibility flag\r
290           // Temporarily commented to avoid awful dependecy on SALOMEDS\r
291           // TODO: better mechanism of storing display/erse status in a study\r
292           // should be provided...\r
293           //Handle(SALOME_InteractiveObject) anObj = anAct->getIO();\r
294           //if(!anObj.IsNull() && anObj->hasEntry() && aStudy){\r
295           //  ToolsGUI::SetVisibility(aStudy,anObj->getEntry(),true,this);\r
296           //}\r
297           // just display the object\r
298           QPtrVector<SUIT_ViewWindow> aViews = myViewManager->getViews();\r
299           for(int i = 0, iEnd = aViews.size(); i < iEnd; i++){\r
300             if(SUIT_ViewWindow* aViewWindow = aViews.at(i)){\r
301               if(SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(aViewWindow)){\r
302                 if(SVTK_RenderWindowInteractor* aRWI = aView->getRWInteractor()){\r
303                   aRWI->Display(anAct,false);\r
304                   if(anAct->IsSetCamera()){\r
305                     vtkRenderer* aRenderer =  aView->getRenderer();\r
306                     anAct->SetCamera( aRenderer->GetActiveCamera() );\r
307                   }\r
308                 }\r
309               }\r
310             }\r
311           }\r
312         }\r
313       }\r
314     }\r
315   }\r
316 }\r
317 \r
318 //==========================================================\r
319 void\r
320 SVTK_Viewer\r
321 ::Erase( const SALOME_VTKPrs* prs, const bool forced )\r
322 {\r
323   // try do downcast object\r
324   if(const SVTK_Prs* aPrs = dynamic_cast<const SVTK_Prs*>( prs )){\r
325     if(aPrs->IsNull())\r
326       return;\r
327     if(vtkActorCollection* anActorCollection = aPrs->GetObjects()){\r
328       // get SALOMEDS Study\r
329       // Temporarily commented to avoid awful dependecy on SALOMEDS\r
330       // TODO: better mechanism of storing display/erse status in a study\r
331       // should be provided...\r
332       //_PTR(Study) aStudy(getStudyDS());\r
333       anActorCollection->InitTraversal();\r
334       while(vtkActor* anActor = anActorCollection->GetNextActor())\r
335         if(SALOME_Actor* anAct = SALOME_Actor::SafeDownCast(anActor)){\r
336           // Set visibility flag\r
337           // Temporarily commented to avoid awful dependecy on SALOMEDS\r
338           // TODO: better mechanism of storing display/erse status in a study\r
339           // should be provided...\r
340           //Handle(SALOME_InteractiveObject) anObj = anAct->getIO();\r
341           //if(!anObj.IsNull() && anObj->hasEntry() && aStudy){\r
342           //  ToolsGUI::SetVisibility(aStudy,anObj->getEntry(),false,this);\r
343           //}\r
344           // just display the object\r
345           QPtrVector<SUIT_ViewWindow> aViews = myViewManager->getViews();\r
346           for(int i = 0, iEnd = aViews.size(); i < iEnd; i++){\r
347             if(SUIT_ViewWindow* aViewWindow = aViews.at(i))\r
348               if(SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(aViewWindow))\r
349                 if(SVTK_RenderWindowInteractor* aRWI = aView->getRWInteractor())\r
350                   if ( forced )\r
351                     aRWI->Remove(anAct,false);\r
352                   else\r
353                     aRWI->Erase(anAct,forced);\r
354           }\r
355         }\r
356     }\r
357   }\r
358 }\r
359   \r
360 //==========================================================\r
361 void\r
362 SVTK_Viewer\r
363 ::EraseAll( const bool forced )\r
364 {\r
365   // Temporarily commented to avoid awful dependecy on SALOMEDS\r
366   // TODO: better mechanism of storing display/erse status in a study\r
367   // should be provided...\r
368   //_PTR(Study) aStudy(getStudyDS());\r
369   QPtrVector<SUIT_ViewWindow> aViews = myViewManager->getViews();\r
370   for(int i = 0, iEnd = aViews.size(); i < iEnd; i++){\r
371     if(SUIT_ViewWindow* aViewWindow = aViews.at(i)){\r
372       if(SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(aViewWindow)){\r
373         vtkRenderer* aRenderer =  aView->getRenderer();\r
374         vtkActorCollection* anActorCollection = aRenderer->GetActors();\r
375         anActorCollection->InitTraversal();\r
376         while(vtkActor* anActor = anActorCollection->GetNextActor()){\r
377           if(SALOME_Actor* anAct = SALOME_Actor::SafeDownCast(anActor)){\r
378             // Set visibility flag\r
379             // Temporarily commented to avoid awful dependecy on SALOMEDS\r
380             // TODO: better mechanism of storing display/erse status in a study\r
381             // should be provided...\r
382             //Handle(SALOME_InteractiveObject) anObj = anAct->getIO();\r
383             //if(!anObj.IsNull() && anObj->hasEntry() && aStudy)\r
384             //  ToolsGUI::SetVisibility(aStudy,anObj->getEntry(),false,this);\r
385             if(forced)\r
386               aRenderer->RemoveActor(anAct);\r
387             else{\r
388               // just erase actor\r
389               anAct->SetVisibility( false );\r
390               // erase dependent actors\r
391               vtkActorCollection* aCollection = vtkActorCollection::New();\r
392               anAct->GetChildActors( aCollection );\r
393               aCollection->InitTraversal();\r
394               while(vtkActor* aSubAct = aCollection->GetNextActor())\r
395                 aSubAct->SetVisibility( false );\r
396               aCollection->Delete();\r
397             }\r
398           }\r
399         }\r
400       }\r
401     }\r
402   }\r
403   Repaint();\r
404 }\r
405 \r
406 //==========================================================\r
407 SALOME_Prs* \r
408 SVTK_Viewer\r
409 ::CreatePrs( const char* entry )\r
410 {\r
411   SVTK_Prs* prs = new SVTK_Prs();\r
412   if ( entry ) {\r
413     vtkRenderer* rnr =  ( (SVTK_ViewWindow*) getViewManager()->getActiveView() )->getRenderer();\r
414     vtkActorCollection* theActors = rnr->GetActors();\r
415     theActors->InitTraversal();\r
416     vtkActor* ac;\r
417     while( ( ac = theActors->GetNextActor() ) ) {\r
418       SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );\r
419       if ( anActor && anActor->hasIO() && !strcmp( anActor->getIO()->getEntry(), entry ) ) {\r
420         prs->AddObject( ac );\r
421       }\r
422     }\r
423   }\r
424   return prs;\r
425 }\r
426 \r
427 //==========================================================\r
428 void\r
429 SVTK_Viewer\r
430 ::BeforeDisplay( SALOME_Displayer* d )\r
431 {\r
432   d->BeforeDisplay( this, SALOME_VTKViewType() );\r
433 }\r
434 \r
435 //==========================================================\r
436 void\r
437 SVTK_Viewer::AfterDisplay( SALOME_Displayer* d )\r
438 {\r
439   d->AfterDisplay( this, SALOME_VTKViewType() );\r
440 }\r
441 \r
442 //==========================================================\r
443 bool\r
444 SVTK_Viewer\r
445 ::isVisible( const Handle(SALOME_InteractiveObject)& io )\r
446 {\r
447   QPtrVector<SUIT_ViewWindow> aViews = myViewManager->getViews();\r
448   for(int i = 0, iEnd = aViews.size(); i < iEnd; i++)\r
449     if(SUIT_ViewWindow* aViewWindow = aViews.at(i))\r
450       if(SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(aViewWindow))\r
451         if(SVTK_RenderWindowInteractor* aRWI = aView->getRWInteractor())\r
452           if(!aRWI->isVisible( io ))\r
453             return false;\r
454   return true;\r
455 }\r
456 \r
457 //==========================================================\r
458 void \r
459 SVTK_Viewer\r
460 ::Repaint()\r
461 {\r
462 //  if (theUpdateTrihedron) onAdjustTrihedron();\r
463   QPtrVector<SUIT_ViewWindow> aViews = myViewManager->getViews();\r
464   for(int i = 0, iEnd = aViews.size(); i < iEnd; i++)\r
465     if(SUIT_ViewWindow* aViewWindow = aViews.at(i))\r
466       if(SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(aViewWindow))\r
467         if(SVTK_RenderWindow* aRW = aView->getRenderWindow())\r
468           aRW->update();\r
469 }\r
470 \r
471 void \r
472 SVTK_Viewer\r
473 ::onSelectionChanged()\r
474 {\r
475   emit selectionChanged();\r
476 }\r
477 \r