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