Salome HOME
NPAL 16561
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_VTKUtils.cxx
1 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 //
4 //  This library is free software; you can redistribute it and/or
5 //  modify it under the terms of the GNU Lesser General Public
6 //  License as published by the Free Software Foundation; either
7 //  version 2.1 of the License.
8 //
9 //  This library is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 //  Lesser General Public License for more details.
13 //
14 //  You should have received a copy of the GNU Lesser General Public
15 //  License along with this library; if not, write to the Free Software
16 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19
20
21 #include "SMESHGUI_VTKUtils.h"
22 #include "SMESHGUI_Utils.h"
23 #include "SMESHGUI_Filter.h"
24
25 #include "SMESHGUI.h"
26 #include "SMESH_Actor.h"
27 #include "SMESH_ObjectDef.h"
28 #include <SMDS_Mesh.hxx>
29
30 #include <SUIT_Desktop.h>
31 #include <SUIT_Session.h>
32 #include <SUIT_Study.h>
33 #include <SUIT_MessageBox.h>
34
35 #include <SALOME_ListIO.hxx>
36 #include <SALOME_ListIteratorOfListIO.hxx>
37
38 #include <SVTK_Selector.h>
39 #include <SVTK_ViewModel.h>
40 #include <SVTK_ViewWindow.h>
41
42 #include <LightApp_SelectionMgr.h>
43 #include <SalomeApp_Application.h>
44 #include <SalomeApp_Study.h>
45
46 #include <utilities.h>
47
48 #include <SALOMEconfig.h>
49 #include CORBA_CLIENT_HEADER(SMESH_Gen)
50 #include CORBA_CLIENT_HEADER(SMESH_Mesh)
51 #include CORBA_CLIENT_HEADER(SMESH_Group)
52 #include CORBA_CLIENT_HEADER(SMESH_Hypothesis)
53
54 #include <SALOMEDSClient_Study.hxx>
55 #include <SALOMEDSClient_SObject.hxx>
56
57 // VTK
58 #include <vtkRenderer.h>
59 #include <vtkActorCollection.h>
60 #include <vtkUnstructuredGrid.h>
61
62 // OCCT
63 #include <TColStd_IndexedMapOfInteger.hxx>
64 #include <Standard_ErrorHandler.hxx>
65
66 // STL
67 #include <set>
68 using namespace std;
69
70
71 namespace SMESH {
72
73   typedef map<TKeyOfVisualObj,TVisualObjPtr> TVisualObjCont;
74   static TVisualObjCont VISUAL_OBJ_CONT;
75
76   //================================================================================
77   /*!
78    * \brief Remove VisualObj and its actor from all views
79    */
80   //================================================================================
81
82   void RemoveVisualObjectWithActors( const char* theEntry )
83   {
84     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
85       ( SUIT_Session::session()->activeApplication() );
86     SUIT_ViewManager* aViewManager =
87       app ? app->getViewManager(SVTK_Viewer::Type(), true) : 0;
88     if ( aViewManager ) {
89       QPtrVector<SUIT_ViewWindow> views = aViewManager->getViews();
90       for ( int iV = 0; iV < views.count(); ++iV ) {
91         if ( SMESH_Actor* actor = FindActorByEntry( views[iV], theEntry)) {
92           if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV]))
93             vtkWnd->RemoveActor(actor);
94           actor->Delete();
95         }
96       }
97       SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( aViewManager->study() );
98       int aStudyId = aStudy->id();
99       TVisualObjCont::key_type aKey(aStudyId,theEntry);
100       TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.find(aKey);
101       if(anIter != VISUAL_OBJ_CONT.end()) {
102         // for unknown reason, object destructor is not called, so clear object manually
103         anIter->second->GetUnstructuredGrid()->SetCells(0,0,0);
104         anIter->second->GetUnstructuredGrid()->SetPoints(0);
105       }
106       VISUAL_OBJ_CONT.erase(aKey);
107     }
108   }
109   //================================================================================
110   /*!
111    * \brief Remove all VisualObjs and their actors from all views
112    */
113   //================================================================================
114
115   void RemoveAllObjectsWithActors()
116   {
117     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
118       ( SUIT_Session::session()->activeApplication() );
119     SUIT_ViewManager* aViewManager =
120       app ? app->getViewManager(SVTK_Viewer::Type(), true) : 0;
121     if ( aViewManager ) {
122       QPtrVector<SUIT_ViewWindow> views = aViewManager->getViews();
123       for ( int iV = 0; iV < views.count(); ++iV ) {
124         if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV])) {
125           vtkRenderer *aRenderer = vtkWnd->getRenderer();
126           vtkActorCollection *aCollection = aRenderer->GetActors();
127           aCollection->InitTraversal();
128           while(vtkActor *anAct = aCollection->GetNextActor()){
129             if(SMESH_Actor *actor = dynamic_cast<SMESH_Actor*>(anAct)){
130               vtkWnd->RemoveActor(actor);
131               actor->Delete();
132             }
133           }
134         }
135       }
136       TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.begin();
137       for ( ; anIter != VISUAL_OBJ_CONT.end(); ++anIter ) {
138         // for unknown reason, object destructor is not called, so clear object manually
139         anIter->second->GetUnstructuredGrid()->SetCells(0,0,0);
140         anIter->second->GetUnstructuredGrid()->SetPoints(0);
141       }
142       VISUAL_OBJ_CONT.clear();
143     }
144   }
145   //================================================================================
146   /*!
147    * \brief Notify the user on problems during visualization
148    */
149   //================================================================================
150
151   void OnVisuException()
152   {
153     SUIT_MessageBox::warn1 (SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"),
154                             QObject::tr("SMESH_VISU_PROBLEM"),
155                             QObject::tr("SMESH_BUT_OK"));
156   }
157   //================================================================================
158   /*!
159    * \brief Returns an updated visual object
160    */
161   //================================================================================
162
163   TVisualObjPtr GetVisualObj(int theStudyId, const char* theEntry){
164     TVisualObjPtr aVisualObj;
165     TVisualObjCont::key_type aKey(theStudyId,theEntry);
166     try{
167 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
168       OCC_CATCH_SIGNALS;
169 #endif
170       TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.find(aKey);
171       if(anIter != VISUAL_OBJ_CONT.end()){
172         aVisualObj = anIter->second;
173       }else{
174         SalomeApp_Application* app =
175           dynamic_cast<SalomeApp_Application*>( SMESHGUI::activeStudy()->application() );
176         _PTR(Study) aStudy = SMESHGUI::activeStudy()->studyDS();
177         _PTR(SObject) aSObj = aStudy->FindObjectID(theEntry);
178         if(aSObj){
179           _PTR(GenericAttribute) anAttr;
180           if(aSObj->FindAttribute(anAttr,"AttributeIOR")){
181             _PTR(AttributeIOR) anIOR = anAttr;
182             CORBA::String_var aVal = anIOR->Value().c_str();
183             CORBA::Object_var anObj = app->orb()->string_to_object( aVal.in() );
184             if(!CORBA::is_nil(anObj)){
185               //Try narrow to SMESH_Mesh interafce
186               SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObj);
187               if(!aMesh->_is_nil()){
188                 aVisualObj.reset(new SMESH_MeshObj(aMesh));
189                 TVisualObjCont::value_type aValue(aKey,aVisualObj);
190                 VISUAL_OBJ_CONT.insert(aValue);
191               }
192               //Try narrow to SMESH_Group interafce
193               SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObj);
194               if(!aGroup->_is_nil()){
195                 _PTR(SObject) aFatherSObj = aSObj->GetFather();
196                 if(!aFatherSObj) return aVisualObj;
197                 aFatherSObj = aFatherSObj->GetFather();
198                 if(!aFatherSObj) return aVisualObj;
199                 CORBA::String_var anEntry = aFatherSObj->GetID().c_str();
200                 TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in());
201                 if(SMESH_MeshObj* aMeshObj = dynamic_cast<SMESH_MeshObj*>(aVisObj.get())){
202                   aVisualObj.reset(new SMESH_GroupObj(aGroup,aMeshObj));
203                   TVisualObjCont::value_type aValue(aKey,aVisualObj);
204                   VISUAL_OBJ_CONT.insert(aValue);
205                 }
206               }
207               //Try narrow to SMESH_subMesh interafce
208               SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(anObj);
209               if(!aSubMesh->_is_nil()){
210                 _PTR(SObject) aFatherSObj = aSObj->GetFather();
211                 if(!aFatherSObj) return aVisualObj;
212                 aFatherSObj = aFatherSObj->GetFather();
213                 if(!aFatherSObj) return aVisualObj;
214                 CORBA::String_var anEntry = aFatherSObj->GetID().c_str();
215                 TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in());
216                 if(SMESH_MeshObj* aMeshObj = dynamic_cast<SMESH_MeshObj*>(aVisObj.get())){
217                   aVisualObj.reset(new SMESH_subMeshObj(aSubMesh,aMeshObj));
218                   TVisualObjCont::value_type aValue(aKey,aVisualObj);
219                   VISUAL_OBJ_CONT.insert(aValue);
220                 }
221               }
222             }
223           }
224         }
225       }
226     }catch(...){
227       INFOS("GetMeshObj - There is no SMESH_Mesh object for the SALOMEDS::Strudy and Entry!!!");
228       return TVisualObjPtr();
229     }
230     // Update object
231     bool objModified = false;
232     if ( aVisualObj ) {
233       try {
234 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
235         OCC_CATCH_SIGNALS;
236 #endif
237         objModified = aVisualObj->Update();
238       }
239       catch (...) {
240 #ifdef _DEBUG_
241         cout << "Exception in SMESHGUI_VTKUtils::GetVisualObj()" << endl;
242 #endif
243         OnVisuException();
244         RemoveVisualObjectWithActors( theEntry ); // remove this object
245         aVisualObj.reset();
246       }
247     }
248
249     if ( objModified ) {
250       // PAL16631. Mesurements showed that to show aVisualObj in SHADING(default) mode,
251       // ~10 times more memory is used than it occupies.
252       // Warn the user if there is less free memory than 30 sizes of a grid
253       // TODO: estimate memory usage in other modes and take current mode into account
254       int freeMB = SMDS_Mesh::CheckMemory(true);
255       int usedMB = aVisualObj->GetUnstructuredGrid()->GetActualMemorySize() / 1024;
256       if ( freeMB > 0 && usedMB * 30 > freeMB ) {
257 #ifdef _DEBUG_
258         cout << "SMESHGUI_VTKUtils::GetVisualObj(), freeMB=" << freeMB
259              << ", usedMB=" << usedMB<< endl;
260 #endif
261         int continu = 0;
262         if ( usedMB * 10 > freeMB )
263           // even dont try to show
264           SUIT_MessageBox::warn1 (SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"),
265                                   QObject::tr("SMESH_NO_MESH_VISUALIZATION"),
266                                   QObject::tr("SMESH_BUT_OK"));
267         else
268           // there is a chance to succeed
269           continu = SUIT_MessageBox::warn2
270             (SMESHGUI::desktop(),
271              QObject::tr("SMESH_WRN_WARNING"),
272              QObject::tr("SMESH_CONTINUE_MESH_VISUALIZATION"),
273              QObject::tr("SMESH_BUT_YES"),  QObject::tr("SMESH_BUT_NO"),
274              1, 0, 1);
275         if ( !continu ) {
276           // remove the corresponding actors from all views
277           RemoveVisualObjectWithActors( theEntry );
278           aVisualObj.reset();
279         }
280       }
281     }
282
283     return aVisualObj;
284   }
285
286
287   /*! Return active view window, if it instantiates SVTK_ViewWindow class,
288    *  overwise find or create corresponding view window, make it active and return it.
289    *  \note Active VVTK_ViewWindow can be returned, because it inherits SVTK_ViewWindow.
290    */
291   SVTK_ViewWindow* GetViewWindow (const SalomeApp_Module* theModule,
292                                   bool createIfNotFound)
293   {
294     SalomeApp_Application* anApp;
295     if (theModule)
296       anApp = theModule->getApp();
297     else
298       anApp = dynamic_cast<SalomeApp_Application*>
299         (SUIT_Session::session()->activeApplication());
300
301     if (anApp) {
302       if (SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(anApp->desktop()->activeWindow()))
303         return aView;
304
305       SUIT_ViewManager* aViewManager =
306         anApp->getViewManager(SVTK_Viewer::Type(), createIfNotFound);
307       if (aViewManager) {
308         if (SUIT_ViewWindow* aViewWindow = aViewManager->getActiveView()) {
309           if (SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(aViewWindow)) {
310             aViewWindow->raise();
311             aViewWindow->setFocus();
312             return aView;
313           }
314         }
315       }
316     }
317     return NULL;
318   }
319
320   SVTK_ViewWindow* FindVtkViewWindow (SUIT_ViewManager* theMgr,
321                                       SUIT_ViewWindow * theWindow)
322   {
323     if( !theMgr )
324       return NULL;
325
326     QPtrVector<SUIT_ViewWindow> views = theMgr->getViews();
327     if( views.containsRef( theWindow ) )
328       return GetVtkViewWindow( theWindow );
329     else
330       return NULL;
331   }
332
333   SVTK_ViewWindow* GetVtkViewWindow(SUIT_ViewWindow* theWindow){
334     return dynamic_cast<SVTK_ViewWindow*>(theWindow);
335   }
336
337 /*  SUIT_ViewWindow* GetActiveWindow()
338   {
339     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
340     if( !app )
341       return NULL;
342     SUIT_ViewManager* mgr = app->activeViewManager();
343     if( mgr )
344       return mgr->getActiveView();
345     else
346       return NULL;
347   }*/
348
349   SVTK_ViewWindow* GetCurrentVtkView(){
350     return GetVtkViewWindow( GetActiveWindow() );
351   }
352
353
354   void RepaintCurrentView()
355   {
356     if (SVTK_ViewWindow* wnd = GetCurrentVtkView())
357     {
358       try {
359 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
360         OCC_CATCH_SIGNALS;
361 #endif
362         wnd->getRenderer()->Render();
363         wnd->Repaint(false);
364       }
365       catch (...) {
366 #ifdef _DEBUG_
367         cout << "Exception in SMESHGUI_VTKUtils::RepaintCurrentView()" << endl;
368 #endif
369         OnVisuException();
370       }
371     }
372   }
373
374   void RepaintViewWindow(SVTK_ViewWindow* theWindow)
375   {
376     try {
377 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
378       OCC_CATCH_SIGNALS;
379 #endif
380       theWindow->getRenderer()->Render();
381       theWindow->Repaint();
382     }
383     catch (...) {
384 #ifdef _DEBUG_
385         cout << "Exception in SMESHGUI_VTKUtils::RepaintViewWindow(SVTK_ViewWindow)" << endl;
386 #endif
387       OnVisuException();
388     }
389   }
390
391   void RenderViewWindow(SVTK_ViewWindow* theWindow)
392   {
393     try {
394 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
395       OCC_CATCH_SIGNALS;
396 #endif
397       theWindow->getRenderer()->Render();
398       theWindow->Repaint();
399     }
400     catch (...) {
401 #ifdef _DEBUG_
402         cout << "Exception in SMESHGUI_VTKUtils::RenderViewWindow(SVTK_ViewWindow)" << endl;
403 #endif
404       OnVisuException();
405     }
406   }
407
408   void FitAll(){
409     if(SVTK_ViewWindow* wnd = GetCurrentVtkView() ){
410       try {
411 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
412         OCC_CATCH_SIGNALS;
413 #endif
414         wnd->onFitAll();
415         wnd->Repaint();
416       }
417       catch (...) {
418 #ifdef _DEBUG_
419         cout << "Exception in SMESHGUI_VTKUtils::FitAll()" << endl;
420 #endif
421         OnVisuException();
422       }
423     }
424   }
425
426
427   SMESH_Actor* FindActorByEntry(SUIT_ViewWindow *theWindow,
428                                 const char* theEntry)
429   {
430     if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWindow)){
431       vtkRenderer *aRenderer = aViewWindow->getRenderer();
432       vtkActorCollection *aCollection = aRenderer->GetActors();
433       aCollection->InitTraversal();
434       while(vtkActor *anAct = aCollection->GetNextActor()){
435         if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
436           if(anActor->hasIO()){
437             Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
438             if(anIO->hasEntry() && strcmp(anIO->getEntry(),theEntry) == 0){
439               return anActor;
440             }
441           }
442         }
443       }
444     }
445     return NULL;
446   }
447
448
449   SMESH_Actor* FindActorByEntry(const char* theEntry){
450     return FindActorByEntry(GetActiveWindow(),theEntry);
451   }
452
453
454   SMESH_Actor* FindActorByObject(CORBA::Object_ptr theObject){
455     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
456     if( !app )
457       return NULL;
458
459     if(!CORBA::is_nil(theObject)){
460       _PTR(Study) aStudy = GetActiveStudyDocument();
461       CORBA::String_var anIOR = app->orb()->object_to_string( theObject );
462       _PTR(SObject) aSObject = aStudy->FindObjectIOR(anIOR.in());
463       if(aSObject){
464         CORBA::String_var anEntry = aSObject->GetID().c_str();
465         return FindActorByEntry(anEntry.in());
466       }
467     }
468     return NULL;
469   }
470
471
472   SMESH_Actor* CreateActor(_PTR(Study) theStudy,
473                            const char* theEntry,
474                            int theIsClear)
475   {
476     SMESH_Actor *anActor = NULL;
477     CORBA::Long anId = theStudy->StudyId();
478     if(TVisualObjPtr aVisualObj = GetVisualObj(anId,theEntry)){
479       _PTR(SObject) aSObj = theStudy->FindObjectID(theEntry);
480       if(aSObj){
481         _PTR(GenericAttribute) anAttr;
482         if(aSObj->FindAttribute(anAttr,"AttributeName")){
483           _PTR(AttributeName) aName = anAttr;
484           std::string aNameVal = aName->Value();
485           anActor = SMESH_Actor::New(aVisualObj,theEntry,aNameVal.c_str(),theIsClear);
486         }
487       }
488     }
489     return anActor;
490   }
491
492
493   void DisplayActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){
494     if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){
495       try {
496 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
497         OCC_CATCH_SIGNALS;
498 #endif
499         vtkWnd->AddActor(theActor);
500         vtkWnd->Repaint();
501       }
502       catch (...) {
503 #ifdef _DEBUG_
504         cout << "Exception in SMESHGUI_VTKUtils::DisplayActor()" << endl;
505 #endif
506         OnVisuException();
507       }
508     }
509   }
510
511
512   void RemoveActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){
513     if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){
514       vtkWnd->RemoveActor(theActor);
515       if(theActor->hasIO()){
516         Handle(SALOME_InteractiveObject) anIO = theActor->getIO();
517         if(anIO->hasEntry()){
518           std::string anEntry = anIO->getEntry();
519           SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( vtkWnd->getViewManager()->study() );
520           int aStudyId = aStudy->id();
521           TVisualObjCont::key_type aKey(aStudyId,anEntry);
522           VISUAL_OBJ_CONT.erase(aKey);
523         }
524       }
525       theActor->Delete();
526       vtkWnd->Repaint();
527     }
528   }
529
530   void UpdateView(SUIT_ViewWindow *theWnd, EDisplaing theAction, const char* theEntry)
531   {
532     if(SVTK_ViewWindow* aViewWnd = GetVtkViewWindow(theWnd)){
533       vtkRenderer *aRenderer = aViewWnd->getRenderer();
534       vtkActorCollection *aCollection = aRenderer->GetActors();
535       aCollection->InitTraversal();
536       switch(theAction){
537       case eDisplayAll: {
538         while(vtkActor *anAct = aCollection->GetNextActor()){
539           if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
540             anActor->SetVisibility(true);
541           }
542         }
543         break;
544       }
545       case eDisplayOnly:
546       case eEraseAll: {
547         while(vtkActor *anAct = aCollection->GetNextActor()){
548           if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
549             anActor->SetVisibility(false);
550           }
551         }
552       }
553       default: {
554         if(SMESH_Actor *anActor = FindActorByEntry(theWnd,theEntry)){
555           switch(theAction) {
556             case eDisplay:
557             case eDisplayOnly:
558               anActor->SetVisibility(true);
559               if (theAction == eDisplayOnly) aRenderer->ResetCameraClippingRange();
560               break;
561             case eErase:
562               anActor->SetVisibility(false);
563               break;
564           }
565         } else {
566           switch(theAction){
567           case eDisplay:
568           case eDisplayOnly:{
569             SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( theWnd->getViewManager()->study() );
570             _PTR(Study) aDocument = aStudy->studyDS();
571             if((anActor = CreateActor(aDocument,theEntry,true))) {
572               DisplayActor(theWnd,anActor);
573               // FitAll(); - PAL16770(Display of a group performs an automatic fit all)
574             }
575             break;
576           }
577           }
578         }
579       }
580       }
581     }
582   }
583
584
585   void UpdateView(EDisplaing theAction, const char* theEntry){
586     SalomeApp_Study* aStudy = dynamic_cast< SalomeApp_Study* >( GetActiveStudy() );
587     SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( aStudy->application() );
588     SUIT_ViewWindow *aWnd = app->activeViewManager()->getActiveView();
589     UpdateView(aWnd,theAction,theEntry);
590   }
591
592   void UpdateView(){
593     if(SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView()){
594       LightApp_SelectionMgr* mgr = SMESHGUI::selectionMgr();
595       SALOME_ListIO selected; mgr->selectedObjects( selected );
596
597       if( selected.Extent() == 0){
598         vtkRenderer* aRenderer = aWnd->getRenderer();
599         vtkActorCollection *aCollection = aRenderer->GetActors();
600         aCollection->InitTraversal();
601         while(vtkActor *anAct = aCollection->GetNextActor()){
602           if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
603             if(anActor->hasIO())
604               if (!Update(anActor->getIO(),anActor->GetVisibility()))
605                 break; // avoid multiple warinings if visu failed
606           }
607         }
608       }else{
609         SALOME_ListIteratorOfListIO anIter( selected );
610         for(; anIter.More(); anIter.Next()){
611           Handle(SALOME_InteractiveObject) anIO = anIter.Value();
612           if ( !Update(anIO,true) )
613             break; // avoid multiple warinings if visu failed
614         }
615       }
616       RepaintCurrentView();
617     }
618   }
619
620
621   bool Update(const Handle(SALOME_InteractiveObject)& theIO,
622               bool theDisplay)
623   {
624     _PTR(Study) aStudy = GetActiveStudyDocument();
625     CORBA::Long anId = aStudy->StudyId();
626     if ( TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry())) {
627       if ( theDisplay )
628         UpdateView(SMESH::eDisplay,theIO->getEntry());
629       return true;
630     }
631     return false;
632   }
633
634
635   void UpdateSelectionProp( SMESHGUI* theModule ) {
636     if( !theModule )
637       return;
638
639     SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( theModule->application() );
640     if( !app )
641     {
642       MESSAGE( "UpdateSelectionProp: Application is null" );
643       return;
644     }
645
646     SUIT_ViewManager* vm = app->activeViewManager();
647     if( !vm )
648     {
649       MESSAGE( "UpdateSelectionProp: View manager is null" );
650       return;
651     }
652
653     QPtrVector<SUIT_ViewWindow> views = vm->getViews();
654
655     SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( theModule );
656     if( !mgr )
657     {
658       MESSAGE( "UpdateSelectionProp: Resource manager is null" );
659       return;
660     }
661
662     QColor aHiColor = mgr->colorValue( "SMESH", "selection_object_color", Qt::white ),
663            aSelColor = mgr->colorValue( "SMESH", "selection_element_color", Qt::yellow ),
664            aPreColor = mgr->colorValue( "SMESH", "highlight_color", Qt::cyan );
665
666     int SW = mgr->integerValue( "SMESH", "selection_width", 5 ),
667         PW = mgr->integerValue( "SMESH", "highlight_width", 5 );
668
669     double SP1 = mgr->doubleValue( "SMESH", "selection_precision_node", 0.025 ),
670            SP2 = mgr->doubleValue( "SMESH", "selection_precision_element", 0.001 ),
671            SP3 = mgr->doubleValue( "SMESH", "selection_precision_object", 0.025 );
672
673     for ( int i=0, n=views.count(); i<n; i++ ){
674       // update VTK viewer properties
675       if(SVTK_ViewWindow* aVtkView = GetVtkViewWindow( views[i] )){
676         // mesh element selection
677         aVtkView->SetSelectionProp(aSelColor.red()/255.,
678                                    aSelColor.green()/255.,
679                                    aSelColor.blue()/255.,
680                                    SW );
681         // tolerances
682         aVtkView->SetSelectionTolerance(SP1, SP2, SP3);
683
684         // pre-selection
685         aVtkView->SetPreselectionProp(aPreColor.red()/255.,
686                                       aPreColor.green()/255.,
687                                       aPreColor.blue()/255.,
688                                       PW);
689         // update actors
690         vtkRenderer* aRenderer = aVtkView->getRenderer();
691         vtkActorCollection *aCollection = aRenderer->GetActors();
692         aCollection->InitTraversal();
693         while(vtkActor *anAct = aCollection->GetNextActor()){
694           if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
695             anActor->SetHighlightColor(aHiColor.red()/255.,
696                                        aHiColor.green()/255.,
697                                        aHiColor.blue()/255.);
698             anActor->SetPreHighlightColor(aPreColor.red()/255.,
699                                           aPreColor.green()/255.,
700                                           aPreColor.blue()/255.);
701           }
702         }
703       }
704     }
705   }
706
707
708   //----------------------------------------------------------------------------
709   SVTK_Selector*
710   GetSelector(SUIT_ViewWindow *theWindow)
711   {
712     if(SVTK_ViewWindow* aWnd = GetVtkViewWindow(theWindow))
713       return aWnd->GetSelector();
714
715     return NULL;
716   }
717
718   void SetFilter(const Handle(VTKViewer_Filter)& theFilter,
719                  SVTK_Selector* theSelector)
720   {
721     if (theSelector)
722       theSelector->SetFilter(theFilter);
723   }
724
725   Handle(VTKViewer_Filter) GetFilter(int theId, SVTK_Selector* theSelector)
726   {
727     return theSelector->GetFilter(theId);
728   }
729
730   bool IsFilterPresent(int theId, SVTK_Selector* theSelector)
731   {
732     return theSelector->IsFilterPresent(theId);
733   }
734
735   void RemoveFilter(int theId, SVTK_Selector* theSelector)
736   {
737     theSelector->RemoveFilter(theId);
738   }
739
740   void RemoveFilters(SVTK_Selector* theSelector)
741   {
742     for ( int id = SMESHGUI_NodeFilter; theSelector && id < SMESHGUI_LastFilter; id++ )
743       theSelector->RemoveFilter( id );
744   }
745
746   bool IsValid(SALOME_Actor* theActor, int theCellId,
747                SVTK_Selector* theSelector)
748   {
749     return theSelector->IsValid(theActor,theCellId);
750   }
751
752
753   //----------------------------------------------------------------------------
754   void SetPointRepresentation(bool theIsVisible){
755     if(SVTK_ViewWindow* aViewWindow = GetCurrentVtkView()){
756       vtkRenderer *aRenderer = aViewWindow->getRenderer();
757       vtkActorCollection *aCollection = aRenderer->GetActors();
758       aCollection->InitTraversal();
759       while(vtkActor *anAct = aCollection->GetNextActor()){
760         if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
761           if(anActor->GetVisibility()){
762             anActor->SetPointRepresentation(theIsVisible);
763           }
764         }
765       }
766       RepaintCurrentView();
767     }
768   }
769
770
771   void SetPickable(SMESH_Actor* theActor){
772     if(SVTK_ViewWindow* aWnd = GetCurrentVtkView()){
773       int anIsAllPickable = (theActor == NULL);
774       vtkRenderer *aRenderer = aWnd->getRenderer();
775       vtkActorCollection *aCollection = aRenderer->GetActors();
776       aCollection->InitTraversal();
777       while(vtkActor *anAct = aCollection->GetNextActor()){
778         if(SALOME_Actor *anActor = dynamic_cast<SALOME_Actor*>(anAct)){
779           if(anActor->GetVisibility()){
780             anActor->SetPickable(anIsAllPickable);
781           }
782         }
783       }
784       if(theActor)
785         theActor->SetPickable(!anIsAllPickable);
786       RepaintCurrentView();
787     }
788   }
789
790
791   //----------------------------------------------------------------------------
792   int GetNameOfSelectedNodes(SVTK_Selector* theSelector,
793                              const Handle(SALOME_InteractiveObject)& theIO,
794                              QString& theName)
795   {
796     theName = "";
797     TColStd_IndexedMapOfInteger aMapIndex;
798     theSelector->GetIndex(theIO,aMapIndex);
799
800     for(int i = 1; i <= aMapIndex.Extent(); i++)
801       theName += QString(" %1").arg(aMapIndex(i));
802
803     return aMapIndex.Extent();
804   }
805
806   int GetNameOfSelectedElements(SVTK_Selector* theSelector,
807                                 const Handle(SALOME_InteractiveObject)& theIO,
808                                 QString& theName)
809   {
810     theName = "";
811     TColStd_IndexedMapOfInteger aMapIndex;
812     theSelector->GetIndex(theIO,aMapIndex);
813
814     typedef std::set<int> TIdContainer;
815     TIdContainer anIdContainer;
816     for( int i = 1; i <= aMapIndex.Extent(); i++)
817       anIdContainer.insert(aMapIndex(i));
818
819     TIdContainer::const_iterator anIter = anIdContainer.begin();
820     for(; anIter != anIdContainer.end(); anIter++)
821       theName += QString(" %1").arg(*anIter);
822
823     return aMapIndex.Extent();
824   }
825
826
827   int GetEdgeNodes(SVTK_Selector* theSelector,
828                    const TVisualObjPtr& theVisualObject,
829                    int& theId1,
830                    int& theId2)
831   {
832     const SALOME_ListIO& selected = theSelector->StoredIObjects();
833
834     if ( selected.Extent() != 1 )
835       return -1;
836
837     Handle(SALOME_InteractiveObject) anIO = selected.First();
838     if ( anIO.IsNull() || !anIO->hasEntry() )
839       return -1;
840
841     TColStd_IndexedMapOfInteger aMapIndex;
842     theSelector->GetIndex( anIO, aMapIndex );
843     if ( aMapIndex.Extent() != 2 )
844       return -1;
845
846     int anObjId = -1, anEdgeNum = -1;
847     for ( int i = 1; i <= aMapIndex.Extent(); i++ ) {
848       int aVal = aMapIndex( i );
849       if ( aVal > 0 )
850         anObjId = aVal;
851       else
852         anEdgeNum = abs( aVal ) - 1;
853     }
854
855     if ( anObjId == -1 || anEdgeNum == -1 )
856       return -1;
857
858     return theVisualObject->GetEdgeNodes( anObjId, anEdgeNum, theId1, theId2 ) ? 1 : -1;
859   }
860
861   //----------------------------------------------------------------------------
862   int GetNameOfSelectedNodes(LightApp_SelectionMgr *theMgr,
863                              const Handle(SALOME_InteractiveObject)& theIO,
864                              QString& theName)
865   {
866     theName = "";
867     if(theIO->hasEntry()){
868       if(FindActorByEntry(theIO->getEntry())){
869         TColStd_IndexedMapOfInteger aMapIndex;
870         theMgr->GetIndexes(theIO,aMapIndex);
871         for(int i = 1; i <= aMapIndex.Extent(); i++){
872           theName += QString(" %1").arg(aMapIndex(i));
873         }
874         return aMapIndex.Extent();
875       }
876     }
877     return -1;
878   }
879
880   int GetNameOfSelectedNodes(LightApp_SelectionMgr *theMgr, QString& theName){
881     theName = "";
882     SALOME_ListIO selected; theMgr->selectedObjects( selected );
883     if(selected.Extent() == 1){
884       Handle(SALOME_InteractiveObject) anIO = selected.First();
885       return GetNameOfSelectedNodes(theMgr,anIO,theName);
886     }
887     return -1;
888   }
889
890
891   int GetNameOfSelectedElements(LightApp_SelectionMgr *theMgr,
892                                 const Handle(SALOME_InteractiveObject)& theIO,
893                                 QString& theName)
894   {
895     theName = "";
896     if(theIO->hasEntry()){
897       if(FindActorByEntry(theIO->getEntry())){
898         TColStd_IndexedMapOfInteger aMapIndex;
899         theMgr->GetIndexes(theIO,aMapIndex);
900         typedef set<int> TIdContainer;
901         TIdContainer anIdContainer;
902         for( int i = 1; i <= aMapIndex.Extent(); i++)
903           anIdContainer.insert(aMapIndex(i));
904         TIdContainer::const_iterator anIter = anIdContainer.begin();
905         for(; anIter != anIdContainer.end(); anIter++){
906           theName += QString(" %1").arg(*anIter);
907         }
908         return aMapIndex.Extent();
909       }
910     }
911     return -1;
912   }
913
914
915   int GetNameOfSelectedElements(LightApp_SelectionMgr *theMgr, QString& theName)
916   {
917     theName = "";
918     SALOME_ListIO selected; theMgr->selectedObjects( selected );
919
920     if( selected.Extent() == 1){
921       Handle(SALOME_InteractiveObject) anIO = selected.First();
922       return GetNameOfSelectedElements(theMgr,anIO,theName);
923     }
924     return -1;
925   }
926
927   int GetSelected(LightApp_SelectionMgr*       theMgr,
928                   TColStd_IndexedMapOfInteger& theMap,
929                   const bool                   theIsElement)
930   {
931     theMap.Clear();
932     SALOME_ListIO selected; theMgr->selectedObjects( selected );
933
934     if ( selected.Extent() == 1 )
935     {
936       Handle(SALOME_InteractiveObject) anIO = selected.First();
937       if ( anIO->hasEntry() ) {
938         theMgr->GetIndexes( anIO, theMap );
939       }
940     }
941     return theMap.Extent();
942   }
943
944
945   int GetEdgeNodes( LightApp_SelectionMgr* theMgr, int& theId1, int& theId2 )
946   {
947     SALOME_ListIO selected; theMgr->selectedObjects( selected );
948
949     if ( selected.Extent() != 1 )
950       return -1;
951
952     Handle(SALOME_InteractiveObject) anIO = selected.First();
953     if ( anIO.IsNull() || !anIO->hasEntry() )
954       return -1;
955
956     SMESH_Actor *anActor = SMESH::FindActorByEntry( anIO->getEntry() );
957     if ( anActor == 0 )
958       return -1;
959
960     TColStd_IndexedMapOfInteger aMapIndex;
961     theMgr->GetIndexes( anIO, aMapIndex );
962     if ( aMapIndex.Extent() != 2 )
963       return -1;
964
965     int anObjId = -1, anEdgeNum = -1;
966     for ( int i = 1; i <= aMapIndex.Extent(); i++ ) {
967       int aVal = aMapIndex( i );
968       if ( aVal > 0 )
969         anObjId = aVal;
970       else
971         anEdgeNum = abs( aVal );
972     }
973
974     if ( anObjId == -1 || anEdgeNum == -1 )
975       return -1;
976
977     return anActor->GetObject()->GetEdgeNodes( anObjId, anEdgeNum, theId1, theId2 ) ? 1 : -1;
978   }
979
980   void SetControlsPrecision( const long theVal )
981   {
982     if( SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView() )
983     {
984       vtkRenderer *aRenderer = aWnd->getRenderer();
985       vtkActorCollection *aCollection = aRenderer->GetActors();
986       aCollection->InitTraversal();
987
988       while ( vtkActor *anAct = aCollection->GetNextActor())
989       {
990         if ( SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>( anAct ) )
991         {
992           anActor->SetControlsPrecision( theVal );
993           anActor->SetControlMode( anActor->GetControlMode() );
994         }
995       }
996
997     }
998   }
999 }