Salome HOME
Fix for Bug NPAL16771 (EDF 556 SMESH : Can't select some groups of nodes in the VTK...
[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 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       int freeMB = SMDS_Mesh::CheckMemory(true);
254       int usedMB = aVisualObj->GetUnstructuredGrid()->GetActualMemorySize() / 1024;
255       if ( freeMB > 0 && usedMB * 30 > freeMB ) {
256         int continu = SUIT_MessageBox::warn2
257           (SMESHGUI::desktop(),
258            QObject::tr("SMESH_WRN_WARNING"),
259            QObject::tr("SMESH_CONTINUE_MESH_VISUALIZATION"),
260            QObject::tr("SMESH_BUT_YES"),  QObject::tr("SMESH_BUT_NO"),
261            1, 0, 1);
262         if ( !continu ) {
263           // remove the corresponding actors from all views
264           RemoveVisualObjectWithActors( theEntry );
265           aVisualObj.reset();
266         }
267       }
268     }
269
270     return aVisualObj;
271   }
272
273
274   /*! Return active view window, if it instantiates SVTK_ViewWindow class,
275    *  overwise find or create corresponding view window, make it active and return it.
276    *  \note Active VVTK_ViewWindow can be returned, because it inherits SVTK_ViewWindow.
277    */
278   SVTK_ViewWindow* GetViewWindow (const SalomeApp_Module* theModule,
279                                   bool createIfNotFound)
280   {
281     SalomeApp_Application* anApp;
282     if (theModule)
283       anApp = theModule->getApp();
284     else
285       anApp = dynamic_cast<SalomeApp_Application*>
286         (SUIT_Session::session()->activeApplication());
287
288     if (anApp) {
289       if (SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(anApp->desktop()->activeWindow()))
290         return aView;
291
292       SUIT_ViewManager* aViewManager =
293         anApp->getViewManager(SVTK_Viewer::Type(), createIfNotFound);
294       if (aViewManager) {
295         if (SUIT_ViewWindow* aViewWindow = aViewManager->getActiveView()) {
296           if (SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(aViewWindow)) {
297             aViewWindow->raise();
298             aViewWindow->setFocus();
299             return aView;
300           }
301         }
302       }
303     }
304     return NULL;
305   }
306
307   SVTK_ViewWindow* FindVtkViewWindow (SUIT_ViewManager* theMgr,
308                                       SUIT_ViewWindow * theWindow)
309   {
310     if( !theMgr )
311       return NULL;
312
313     QPtrVector<SUIT_ViewWindow> views = theMgr->getViews();
314     if( views.containsRef( theWindow ) )
315       return GetVtkViewWindow( theWindow );
316     else
317       return NULL;
318   }
319
320   SVTK_ViewWindow* GetVtkViewWindow(SUIT_ViewWindow* theWindow){
321     return dynamic_cast<SVTK_ViewWindow*>(theWindow);
322   }
323
324 /*  SUIT_ViewWindow* GetActiveWindow()
325   {
326     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
327     if( !app )
328       return NULL;
329     SUIT_ViewManager* mgr = app->activeViewManager();
330     if( mgr )
331       return mgr->getActiveView();
332     else
333       return NULL;
334   }*/
335
336   SVTK_ViewWindow* GetCurrentVtkView(){
337     return GetVtkViewWindow( GetActiveWindow() );
338   }
339
340
341   void RepaintCurrentView()
342   {
343     if (SVTK_ViewWindow* wnd = GetCurrentVtkView())
344     {
345       try {
346 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
347         OCC_CATCH_SIGNALS;
348 #endif
349         wnd->getRenderer()->Render();
350         wnd->Repaint(false);
351       }
352       catch (...) {
353         OnVisuException();
354 #ifdef _DEBUG_
355         cout << "Exception in SMESHGUI_VTKUtils::RepaintCurrentView()" << endl;
356 #endif
357       }
358     }
359   }
360
361   void RepaintViewWindow(SVTK_ViewWindow* theWindow)
362   {
363     try {
364 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
365       OCC_CATCH_SIGNALS;
366 #endif
367       theWindow->getRenderer()->Render();
368       theWindow->Repaint();
369     }
370     catch (...) {
371       OnVisuException();
372 #ifdef _DEBUG_
373         cout << "Exception in SMESHGUI_VTKUtils::RepaintViewWindow(SVTK_ViewWindow)" << endl;
374 #endif
375     }
376   }
377
378   void RenderViewWindow(SVTK_ViewWindow* theWindow)
379   {
380     try {
381 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
382       OCC_CATCH_SIGNALS;
383 #endif
384       theWindow->getRenderer()->Render();
385       theWindow->Repaint();
386     }
387     catch (...) {
388       OnVisuException();
389 #ifdef _DEBUG_
390         cout << "Exception in SMESHGUI_VTKUtils::RenderViewWindow(SVTK_ViewWindow)" << endl;
391 #endif
392     }
393   }
394
395   void FitAll(){
396     if(SVTK_ViewWindow* wnd = GetCurrentVtkView() ){
397       try {
398 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
399         OCC_CATCH_SIGNALS;
400 #endif
401         wnd->onFitAll();
402         wnd->Repaint();
403       }
404       catch (...) {
405         OnVisuException();
406 #ifdef _DEBUG_
407         cout << "Exception in SMESHGUI_VTKUtils::FitAll()" << endl;
408 #endif
409       }
410     }
411   }
412
413
414   SMESH_Actor* FindActorByEntry(SUIT_ViewWindow *theWindow,
415                                 const char* theEntry)
416   {
417     if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWindow)){
418       vtkRenderer *aRenderer = aViewWindow->getRenderer();
419       vtkActorCollection *aCollection = aRenderer->GetActors();
420       aCollection->InitTraversal();
421       while(vtkActor *anAct = aCollection->GetNextActor()){
422         if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
423           if(anActor->hasIO()){
424             Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
425             if(anIO->hasEntry() && strcmp(anIO->getEntry(),theEntry) == 0){
426               return anActor;
427             }
428           }
429         }
430       }
431     }
432     return NULL;
433   }
434
435
436   SMESH_Actor* FindActorByEntry(const char* theEntry){
437     return FindActorByEntry(GetActiveWindow(),theEntry);
438   }
439
440
441   SMESH_Actor* FindActorByObject(CORBA::Object_ptr theObject){
442     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
443     if( !app )
444       return NULL;
445
446     if(!CORBA::is_nil(theObject)){
447       _PTR(Study) aStudy = GetActiveStudyDocument();
448       CORBA::String_var anIOR = app->orb()->object_to_string( theObject );
449       _PTR(SObject) aSObject = aStudy->FindObjectIOR(anIOR.in());
450       if(aSObject){
451         CORBA::String_var anEntry = aSObject->GetID().c_str();
452         return FindActorByEntry(anEntry.in());
453       }
454     }
455     return NULL;
456   }
457
458
459   SMESH_Actor* CreateActor(_PTR(Study) theStudy,
460                            const char* theEntry,
461                            int theIsClear)
462   {
463     SMESH_Actor *anActor = NULL;
464     CORBA::Long anId = theStudy->StudyId();
465     if(TVisualObjPtr aVisualObj = GetVisualObj(anId,theEntry)){
466       _PTR(SObject) aSObj = theStudy->FindObjectID(theEntry);
467       if(aSObj){
468         _PTR(GenericAttribute) anAttr;
469         if(aSObj->FindAttribute(anAttr,"AttributeName")){
470           _PTR(AttributeName) aName = anAttr;
471           std::string aNameVal = aName->Value();
472           anActor = SMESH_Actor::New(aVisualObj,theEntry,aNameVal.c_str(),theIsClear);
473         }
474       }
475     }
476     return anActor;
477   }
478
479
480   void DisplayActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){
481     if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){
482       try {
483 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
484         OCC_CATCH_SIGNALS;
485 #endif
486         vtkWnd->AddActor(theActor);
487         vtkWnd->Repaint();
488       }
489       catch (...) {
490         OnVisuException();
491 #ifdef _DEBUG_
492         cout << "Exception in SMESHGUI_VTKUtils::DisplayActor()" << endl;
493 #endif
494       }
495     }
496   }
497
498
499   void RemoveActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){
500     if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){
501       vtkWnd->RemoveActor(theActor);
502       if(theActor->hasIO()){
503         Handle(SALOME_InteractiveObject) anIO = theActor->getIO();
504         if(anIO->hasEntry()){
505           std::string anEntry = anIO->getEntry();
506           SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( vtkWnd->getViewManager()->study() );
507           int aStudyId = aStudy->id();
508           TVisualObjCont::key_type aKey(aStudyId,anEntry);
509           VISUAL_OBJ_CONT.erase(aKey);
510         }
511       }
512       theActor->Delete();
513       vtkWnd->Repaint();
514     }
515   }
516
517   void UpdateView(SUIT_ViewWindow *theWnd, EDisplaing theAction, const char* theEntry)
518   {
519     if(SVTK_ViewWindow* aViewWnd = GetVtkViewWindow(theWnd)){
520       vtkRenderer *aRenderer = aViewWnd->getRenderer();
521       vtkActorCollection *aCollection = aRenderer->GetActors();
522       aCollection->InitTraversal();
523       switch(theAction){
524       case eDisplayAll: {
525         while(vtkActor *anAct = aCollection->GetNextActor()){
526           if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
527             anActor->SetVisibility(true);
528           }
529         }
530         break;
531       }
532       case eDisplayOnly:
533       case eEraseAll: {
534         while(vtkActor *anAct = aCollection->GetNextActor()){
535           if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
536             anActor->SetVisibility(false);
537           }
538         }
539       }
540       default: {
541         if(SMESH_Actor *anActor = FindActorByEntry(theWnd,theEntry)){
542           switch(theAction) {
543             case eDisplay:
544             case eDisplayOnly:
545               anActor->SetVisibility(true);
546               if (theAction == eDisplayOnly) aRenderer->ResetCameraClippingRange();
547               break;
548             case eErase:
549               anActor->SetVisibility(false);
550               break;
551           }
552         } else {
553           switch(theAction){
554           case eDisplay:
555           case eDisplayOnly:{
556             SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( theWnd->getViewManager()->study() );
557             _PTR(Study) aDocument = aStudy->studyDS();
558             if((anActor = CreateActor(aDocument,theEntry,true))) {
559               DisplayActor(theWnd,anActor);
560               // FitAll(); - PAL16770(Display of a group performs an automatic fit all)
561             }
562             break;
563           }
564           }
565         }
566       }
567       }
568     }
569   }
570
571
572   void UpdateView(EDisplaing theAction, const char* theEntry){
573     SalomeApp_Study* aStudy = dynamic_cast< SalomeApp_Study* >( GetActiveStudy() );
574     SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( aStudy->application() );
575     SUIT_ViewWindow *aWnd = app->activeViewManager()->getActiveView();
576     UpdateView(aWnd,theAction,theEntry);
577   }
578
579   void UpdateView(){
580     if(SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView()){
581       LightApp_SelectionMgr* mgr = SMESHGUI::selectionMgr();
582       SALOME_ListIO selected; mgr->selectedObjects( selected );
583
584       if( selected.Extent() == 0){
585         vtkRenderer* aRenderer = aWnd->getRenderer();
586         vtkActorCollection *aCollection = aRenderer->GetActors();
587         aCollection->InitTraversal();
588         while(vtkActor *anAct = aCollection->GetNextActor()){
589           if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
590             if(anActor->hasIO())
591               Update(anActor->getIO(),anActor->GetVisibility());
592           }
593         }
594       }else{
595         SALOME_ListIteratorOfListIO anIter( selected );
596         for(; anIter.More(); anIter.Next()){
597           Handle(SALOME_InteractiveObject) anIO = anIter.Value();
598           Update(anIO,true);
599         }
600       }
601       RepaintCurrentView();
602     }
603   }
604
605
606   void Update(const Handle(SALOME_InteractiveObject)& theIO,
607               bool theDisplay)
608   {
609     _PTR(Study) aStudy = GetActiveStudyDocument();
610     CORBA::Long anId = aStudy->StudyId();
611     if ( TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry())) {
612       // if( aVisualObj )
613       //    aVisualObj->Update(); -> PAL16631, already done in GetVisualObj()
614       if ( theDisplay )
615         UpdateView(SMESH::eDisplay,theIO->getEntry());
616     }
617   }
618
619
620   void UpdateSelectionProp( SMESHGUI* theModule ) {
621     if( !theModule )
622       return;
623
624     SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( theModule->application() );
625     if( !app )
626     {
627       MESSAGE( "UpdateSelectionProp: Application is null" );
628       return;
629     }
630
631     SUIT_ViewManager* vm = app->activeViewManager();
632     if( !vm )
633     {
634       MESSAGE( "UpdateSelectionProp: View manager is null" );
635       return;
636     }
637
638     QPtrVector<SUIT_ViewWindow> views = vm->getViews();
639
640     SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( theModule );
641     if( !mgr )
642     {
643       MESSAGE( "UpdateSelectionProp: Resource manager is null" );
644       return;
645     }
646
647     QColor aHiColor = mgr->colorValue( "SMESH", "selection_object_color", Qt::white ),
648            aSelColor = mgr->colorValue( "SMESH", "selection_element_color", Qt::yellow ),
649            aPreColor = mgr->colorValue( "SMESH", "highlight_color", Qt::cyan );
650
651     int SW = mgr->integerValue( "SMESH", "selection_width", 5 ),
652         PW = mgr->integerValue( "SMESH", "highlight_width", 5 );
653
654     double SP1 = mgr->doubleValue( "SMESH", "selection_precision_node", 0.025 ),
655            SP2 = mgr->doubleValue( "SMESH", "selection_precision_element", 0.001 ),
656            SP3 = mgr->doubleValue( "SMESH", "selection_precision_object", 0.025 );
657
658     for ( int i=0, n=views.count(); i<n; i++ ){
659       // update VTK viewer properties
660       if(SVTK_ViewWindow* aVtkView = GetVtkViewWindow( views[i] )){
661         // mesh element selection
662         aVtkView->SetSelectionProp(aSelColor.red()/255.,
663                                    aSelColor.green()/255.,
664                                    aSelColor.blue()/255.,
665                                    SW );
666         // tolerances
667         aVtkView->SetSelectionTolerance(SP1, SP2, SP3);
668
669         // pre-selection
670         aVtkView->SetPreselectionProp(aPreColor.red()/255.,
671                                       aPreColor.green()/255.,
672                                       aPreColor.blue()/255.,
673                                       PW);
674         // update actors
675         vtkRenderer* aRenderer = aVtkView->getRenderer();
676         vtkActorCollection *aCollection = aRenderer->GetActors();
677         aCollection->InitTraversal();
678         while(vtkActor *anAct = aCollection->GetNextActor()){
679           if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
680             anActor->SetHighlightColor(aHiColor.red()/255.,
681                                        aHiColor.green()/255.,
682                                        aHiColor.blue()/255.);
683             anActor->SetPreHighlightColor(aPreColor.red()/255.,
684                                           aPreColor.green()/255.,
685                                           aPreColor.blue()/255.);
686           }
687         }
688       }
689     }
690   }
691
692
693   //----------------------------------------------------------------------------
694   SVTK_Selector*
695   GetSelector(SUIT_ViewWindow *theWindow)
696   {
697     if(SVTK_ViewWindow* aWnd = GetVtkViewWindow(theWindow))
698       return aWnd->GetSelector();
699
700     return NULL;
701   }
702
703   void SetFilter(const Handle(VTKViewer_Filter)& theFilter,
704                  SVTK_Selector* theSelector)
705   {
706     if (theSelector)
707       theSelector->SetFilter(theFilter);
708   }
709
710   Handle(VTKViewer_Filter) GetFilter(int theId, SVTK_Selector* theSelector)
711   {
712     return theSelector->GetFilter(theId);
713   }
714
715   bool IsFilterPresent(int theId, SVTK_Selector* theSelector)
716   {
717     return theSelector->IsFilterPresent(theId);
718   }
719
720   void RemoveFilter(int theId, SVTK_Selector* theSelector)
721   {
722     theSelector->RemoveFilter(theId);
723   }
724
725   void RemoveFilters(SVTK_Selector* theSelector)
726   {
727     for ( int id = SMESHGUI_NodeFilter; theSelector && id < SMESHGUI_LastFilter; id++ )
728       theSelector->RemoveFilter( id );
729   }
730
731   bool IsValid(SALOME_Actor* theActor, int theCellId,
732                SVTK_Selector* theSelector)
733   {
734     return theSelector->IsValid(theActor,theCellId);
735   }
736
737
738   //----------------------------------------------------------------------------
739   void SetPointRepresentation(bool theIsVisible){
740     if(SVTK_ViewWindow* aViewWindow = GetCurrentVtkView()){
741       vtkRenderer *aRenderer = aViewWindow->getRenderer();
742       vtkActorCollection *aCollection = aRenderer->GetActors();
743       aCollection->InitTraversal();
744       while(vtkActor *anAct = aCollection->GetNextActor()){
745         if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
746           if(anActor->GetVisibility()){
747             anActor->SetPointRepresentation(theIsVisible);
748           }
749         }
750       }
751       RepaintCurrentView();
752     }
753   }
754
755
756   void SetPickable(SMESH_Actor* theActor){
757     if(SVTK_ViewWindow* aWnd = GetCurrentVtkView()){
758       int anIsAllPickable = (theActor == NULL);
759       vtkRenderer *aRenderer = aWnd->getRenderer();
760       vtkActorCollection *aCollection = aRenderer->GetActors();
761       aCollection->InitTraversal();
762       while(vtkActor *anAct = aCollection->GetNextActor()){
763         if(SALOME_Actor *anActor = dynamic_cast<SALOME_Actor*>(anAct)){
764           if(anActor->GetVisibility()){
765             anActor->SetPickable(anIsAllPickable);
766           }
767         }
768       }
769       if(theActor)
770         theActor->SetPickable(!anIsAllPickable);
771       RepaintCurrentView();
772     }
773   }
774
775
776   //----------------------------------------------------------------------------
777   int GetNameOfSelectedNodes(SVTK_Selector* theSelector,
778                              const Handle(SALOME_InteractiveObject)& theIO,
779                              QString& theName)
780   {
781     theName = "";
782     TColStd_IndexedMapOfInteger aMapIndex;
783     theSelector->GetIndex(theIO,aMapIndex);
784
785     for(int i = 1; i <= aMapIndex.Extent(); i++)
786       theName += QString(" %1").arg(aMapIndex(i));
787
788     return aMapIndex.Extent();
789   }
790
791   int GetNameOfSelectedElements(SVTK_Selector* theSelector,
792                                 const Handle(SALOME_InteractiveObject)& theIO,
793                                 QString& theName)
794   {
795     theName = "";
796     TColStd_IndexedMapOfInteger aMapIndex;
797     theSelector->GetIndex(theIO,aMapIndex);
798
799     typedef std::set<int> TIdContainer;
800     TIdContainer anIdContainer;
801     for( int i = 1; i <= aMapIndex.Extent(); i++)
802       anIdContainer.insert(aMapIndex(i));
803
804     TIdContainer::const_iterator anIter = anIdContainer.begin();
805     for(; anIter != anIdContainer.end(); anIter++)
806       theName += QString(" %1").arg(*anIter);
807
808     return aMapIndex.Extent();
809   }
810
811
812   int GetEdgeNodes(SVTK_Selector* theSelector,
813                    const TVisualObjPtr& theVisualObject,
814                    int& theId1,
815                    int& theId2)
816   {
817     const SALOME_ListIO& selected = theSelector->StoredIObjects();
818
819     if ( selected.Extent() != 1 )
820       return -1;
821
822     Handle(SALOME_InteractiveObject) anIO = selected.First();
823     if ( anIO.IsNull() || !anIO->hasEntry() )
824       return -1;
825
826     TColStd_IndexedMapOfInteger aMapIndex;
827     theSelector->GetIndex( anIO, aMapIndex );
828     if ( aMapIndex.Extent() != 2 )
829       return -1;
830
831     int anObjId = -1, anEdgeNum = -1;
832     for ( int i = 1; i <= aMapIndex.Extent(); i++ ) {
833       int aVal = aMapIndex( i );
834       if ( aVal > 0 )
835         anObjId = aVal;
836       else
837         anEdgeNum = abs( aVal ) - 1;
838     }
839
840     if ( anObjId == -1 || anEdgeNum == -1 )
841       return -1;
842
843     return theVisualObject->GetEdgeNodes( anObjId, anEdgeNum, theId1, theId2 ) ? 1 : -1;
844   }
845
846   //----------------------------------------------------------------------------
847   int GetNameOfSelectedNodes(LightApp_SelectionMgr *theMgr,
848                              const Handle(SALOME_InteractiveObject)& theIO,
849                              QString& theName)
850   {
851     theName = "";
852     if(theIO->hasEntry()){
853       if(FindActorByEntry(theIO->getEntry())){
854         TColStd_IndexedMapOfInteger aMapIndex;
855         theMgr->GetIndexes(theIO,aMapIndex);
856         for(int i = 1; i <= aMapIndex.Extent(); i++){
857           theName += QString(" %1").arg(aMapIndex(i));
858         }
859         return aMapIndex.Extent();
860       }
861     }
862     return -1;
863   }
864
865   int GetNameOfSelectedNodes(LightApp_SelectionMgr *theMgr, QString& theName){
866     theName = "";
867     SALOME_ListIO selected; theMgr->selectedObjects( selected );
868     if(selected.Extent() == 1){
869       Handle(SALOME_InteractiveObject) anIO = selected.First();
870       return GetNameOfSelectedNodes(theMgr,anIO,theName);
871     }
872     return -1;
873   }
874
875
876   int GetNameOfSelectedElements(LightApp_SelectionMgr *theMgr,
877                                 const Handle(SALOME_InteractiveObject)& theIO,
878                                 QString& theName)
879   {
880     theName = "";
881     if(theIO->hasEntry()){
882       if(FindActorByEntry(theIO->getEntry())){
883         TColStd_IndexedMapOfInteger aMapIndex;
884         theMgr->GetIndexes(theIO,aMapIndex);
885         typedef set<int> TIdContainer;
886         TIdContainer anIdContainer;
887         for( int i = 1; i <= aMapIndex.Extent(); i++)
888           anIdContainer.insert(aMapIndex(i));
889         TIdContainer::const_iterator anIter = anIdContainer.begin();
890         for(; anIter != anIdContainer.end(); anIter++){
891           theName += QString(" %1").arg(*anIter);
892         }
893         return aMapIndex.Extent();
894       }
895     }
896     return -1;
897   }
898
899
900   int GetNameOfSelectedElements(LightApp_SelectionMgr *theMgr, QString& theName)
901   {
902     theName = "";
903     SALOME_ListIO selected; theMgr->selectedObjects( selected );
904
905     if( selected.Extent() == 1){
906       Handle(SALOME_InteractiveObject) anIO = selected.First();
907       return GetNameOfSelectedElements(theMgr,anIO,theName);
908     }
909     return -1;
910   }
911
912   int GetSelected(LightApp_SelectionMgr*       theMgr,
913                   TColStd_IndexedMapOfInteger& theMap,
914                   const bool                   theIsElement)
915   {
916     theMap.Clear();
917     SALOME_ListIO selected; theMgr->selectedObjects( selected );
918
919     if ( selected.Extent() == 1 )
920     {
921       Handle(SALOME_InteractiveObject) anIO = selected.First();
922       if ( anIO->hasEntry() ) {
923         theMgr->GetIndexes( anIO, theMap );
924       }
925     }
926     return theMap.Extent();
927   }
928
929
930   int GetEdgeNodes( LightApp_SelectionMgr* theMgr, int& theId1, int& theId2 )
931   {
932     SALOME_ListIO selected; theMgr->selectedObjects( selected );
933
934     if ( selected.Extent() != 1 )
935       return -1;
936
937     Handle(SALOME_InteractiveObject) anIO = selected.First();
938     if ( anIO.IsNull() || !anIO->hasEntry() )
939       return -1;
940
941     SMESH_Actor *anActor = SMESH::FindActorByEntry( anIO->getEntry() );
942     if ( anActor == 0 )
943       return -1;
944
945     TColStd_IndexedMapOfInteger aMapIndex;
946     theMgr->GetIndexes( anIO, aMapIndex );
947     if ( aMapIndex.Extent() != 2 )
948       return -1;
949
950     int anObjId = -1, anEdgeNum = -1;
951     for ( int i = 1; i <= aMapIndex.Extent(); i++ ) {
952       int aVal = aMapIndex( i );
953       if ( aVal > 0 )
954         anObjId = aVal;
955       else
956         anEdgeNum = abs( aVal );
957     }
958
959     if ( anObjId == -1 || anEdgeNum == -1 )
960       return -1;
961
962     return anActor->GetObject()->GetEdgeNodes( anObjId, anEdgeNum, theId1, theId2 ) ? 1 : -1;
963   }
964
965   void SetControlsPrecision( const long theVal )
966   {
967     if( SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView() )
968     {
969       vtkRenderer *aRenderer = aWnd->getRenderer();
970       vtkActorCollection *aCollection = aRenderer->GetActors();
971       aCollection->InitTraversal();
972
973       while ( vtkActor *anAct = aCollection->GetNextActor())
974       {
975         if ( SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>( anAct ) )
976         {
977           anActor->SetControlsPrecision( theVal );
978           anActor->SetControlMode( anActor->GetControlMode() );
979         }
980       }
981
982     }
983   }
984 }