Salome HOME
a8564b42e4f4899b1ec358f236d4316ab2217ae3
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_VTKUtils.cxx
1 // Copyright (C) 2007-2019  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // SMESH SMESHGUI : GUI for SMESH component
24 // File   : SMESHGUI_VTKUtils.cxx
25 // Author : Open CASCADE S.A.S.
26 // SMESH includes
27 //
28 #include "SMESHGUI_VTKUtils.h"
29
30 #include "SMESHGUI.h"
31 #include "SMESHGUI_Filter.h"
32 #include "SMESHGUI_Utils.h"
33 #include "SMDS_Mesh.hxx"
34 #include "SMESH_Actor.h"
35 #include "SMESH_ActorProps.h"
36 #include "SMESH_ActorUtils.h"
37 #include "SMESH_CellLabelActor.h"
38 #include "SMESH_ControlsDef.hxx"
39 #include "SMESH_NodeLabelActor.h"
40 #include "SMESH_ObjectDef.h"
41
42 // SALOME GUI includes
43 #include <SUIT_Desktop.h>
44 #include <SUIT_Session.h>
45 #include <SUIT_MessageBox.h>
46 #include <SUIT_ViewManager.h>
47 #include <SUIT_ResourceMgr.h>
48
49 #include <SALOME_ListIO.hxx>
50
51 #include <SVTK_Selector.h>
52 #include <SVTK_ViewModel.h>
53 #include <SVTK_ViewWindow.h>
54
55 #include <VTKViewer_Algorithm.h>
56
57 #include <LightApp_SelectionMgr.h>
58 #include <SalomeApp_Application.h>
59 #include <SalomeApp_Study.h>
60
61 // SALOME KERNEL includes
62 #include <utilities.h>
63
64 // IDL includes
65 #include <SALOMEconfig.h>
66 #include CORBA_CLIENT_HEADER(SMESH_Mesh)
67 #include CORBA_CLIENT_HEADER(SMESH_Group)
68
69 // VTK includes
70 #include <vtkMath.h>
71 #include <vtkRenderer.h>
72 #include <vtkActorCollection.h>
73 #include <vtkUnstructuredGrid.h>
74
75 // OCCT includes
76 #include <Standard_ErrorHandler.hxx>
77
78 namespace SMESH
79 {
80   typedef std::map<std::string,TVisualObjPtr> TVisualObjCont;
81   static TVisualObjCont VISUAL_OBJ_CONT;
82
83   //=============================================================================
84   /*!
85    * \brief Allocate some memory at construction and release it at destruction.
86    * Is used to be able to continue working after mesh generation or visualization
87    * break due to lack of memory
88    */
89   //=============================================================================
90
91   struct MemoryReserve
92   {
93     char* myBuf;
94     MemoryReserve(): myBuf( new char[1024*1024*1] ){} // 1M
95     void Free() { if (myBuf) { delete [] myBuf; myBuf = 0; }}
96     ~MemoryReserve() { Free(); }
97   };
98   static MemoryReserve* theVISU_MemoryReserve = new MemoryReserve;
99
100   //================================================================================
101   /*!
102    * \brief Remove VisualObj and its actor from all views
103    */
104   //================================================================================
105
106   void RemoveVisualObjectWithActors( const char* theEntry, bool fromAllViews )
107   {
108     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>(SUIT_Session::session()->activeApplication());
109     if(!app)
110       return;
111     SalomeApp_Study* aStudy  = dynamic_cast<SalomeApp_Study*>(app->activeStudy());
112     if(!aStudy)
113       return;
114     ViewManagerList aList;
115
116     if(fromAllViews) {
117       app->viewManagers(SVTK_Viewer::Type() , aList);
118     } else {
119       SUIT_ViewManager* aVM = app->getViewManager(SVTK_Viewer::Type(), true);
120       if(aVM)
121         aList.append(aVM);
122     }    
123     bool actorRemoved = false;
124     ViewManagerList::ConstIterator it = aList.begin();
125     SUIT_ViewManager* aViewManager = 0;
126     for( ; it!=aList.end();it++) {
127       aViewManager = *it;
128       QVector<SUIT_ViewWindow*> views = aViewManager->getViews();
129       for ( int iV = 0; iV < views.count(); ++iV ) {
130         if ( SMESH_Actor* actor = FindActorByEntry( views[iV], theEntry)) {
131           if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV])) {
132             vtkWnd->RemoveActor(actor);
133             actorRemoved = true;
134           }
135           actor->Delete();
136         }
137       }
138     }
139     
140     TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.find(theEntry);
141     if(anIter != VISUAL_OBJ_CONT.end()) {
142       // for unknown reason, object destructor is not called, so clear object manually
143       anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0);
144       anIter->second->GetUnstructuredGrid()->SetPoints(0);
145     }
146     VISUAL_OBJ_CONT.erase(theEntry);
147
148     if(actorRemoved)
149       aStudy->setVisibilityState(theEntry, Qtx::HiddenState);
150   }
151   //================================================================================
152   /*!
153    * \brief Remove all VisualObjs and their actors from all views
154    */
155   //================================================================================
156
157   void RemoveAllObjectsWithActors()
158   {
159     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
160       ( SUIT_Session::session()->activeApplication() );
161     if (!app) return;
162     ViewManagerList viewMgrs = app->viewManagers();
163     for ( int iM = 0; iM < viewMgrs.count(); ++iM ) {
164       SUIT_ViewManager* aViewManager = viewMgrs.at( iM );
165       if ( aViewManager && aViewManager->getType() == SVTK_Viewer::Type()) {
166         QVector<SUIT_ViewWindow*> views = aViewManager->getViews();
167         for ( int iV = 0; iV < views.count(); ++iV ) {
168           if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV])) {
169             vtkRenderer *aRenderer = vtkWnd->getRenderer();
170             VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
171             vtkActorCollection *actors = aCopy.GetActors();
172             for (int i = 0; i < actors->GetNumberOfItems(); ++i ) {
173               // size of actors changes inside the loop
174               if (SMESH_Actor *actor = dynamic_cast<SMESH_Actor*>(actors->GetItemAsObject(i)))
175               {
176                 vtkWnd->RemoveActor(actor);
177                 actor->Delete();
178               }
179             }
180           }
181         }
182       }
183     }
184     TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.begin();
185     for ( ; anIter != VISUAL_OBJ_CONT.end(); ++anIter ) {
186       // for unknown reason, object destructor is not called, so clear object manually
187       anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0);
188       anIter->second->GetUnstructuredGrid()->SetPoints(0);
189     }
190     VISUAL_OBJ_CONT.clear();
191   }
192
193   //================================================================================
194   /*!
195    * \brief Remove all VisualObjs of a study
196    */
197   //================================================================================
198
199   void RemoveVisuData()
200   {
201     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
202       ( SUIT_Session::session()->activeApplication() );
203     if (!app) return;
204     ViewManagerList viewMgrs = app->viewManagers();
205     for ( int iM = 0; iM < viewMgrs.count(); ++iM ) {
206       SUIT_ViewManager* aViewManager = viewMgrs.at( iM );
207       if ( aViewManager && aViewManager->getType() == SVTK_Viewer::Type() ) {
208         QVector<SUIT_ViewWindow*> views = aViewManager->getViews();
209         for ( int iV = 0; iV < views.count(); ++iV ) {
210           if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV])) {
211             vtkRenderer *aRenderer = vtkWnd->getRenderer();
212             VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
213             vtkActorCollection *actors = aCopy.GetActors();
214             for (int i = 0; i < actors->GetNumberOfItems(); ++i ) {
215               // size of actors changes inside the loop
216               if(SMESH_Actor *actor = dynamic_cast<SMESH_Actor*>(actors->GetItemAsObject(i)))
217               {
218                 vtkWnd->RemoveActor(actor);
219                 actor->Delete();
220               }
221             }
222           }
223         }
224       }
225     }
226     TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.begin();
227     for ( ; anIter != VISUAL_OBJ_CONT.end(); ) {
228       // for unknown reason, object destructor is not called, so clear object manually
229       anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0);
230       anIter->second->GetUnstructuredGrid()->SetPoints(0);
231       VISUAL_OBJ_CONT.erase( anIter++ ); // anIter++ returns a copy of self before incrementing
232     }
233   }
234
235   //================================================================================
236   /*!
237    * \brief Remove/update actors while module activation
238    *  \param [in] wnd - window
239    *
240    * At module activation, groups and sub-meshes can be removed on engine side due
241    * to modification of meshed geometry, while their actors can remain.
242    * Here we remove/update SMESH_Actor's of changed objects. State (emptiness) of objects
243    * is defined by their icons in the Object Browser
244    */
245   //================================================================================
246
247   void UpdateActorsAfterUpdateStudy( SUIT_ViewWindow* theWindow )
248   {
249     const char* emptyIcon = "ICON_SMESH_TREE_MESH_WARN";
250     _PTR(Study) aStudy = SMESH::getStudy();
251
252     if ( SVTK_ViewWindow* aViewWindow = GetVtkViewWindow( theWindow ))
253     {
254       vtkRenderer *aRenderer = aViewWindow->getRenderer();
255       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
256       vtkActorCollection *aCollection = aCopy.GetActors();
257       aCollection->InitTraversal();
258       while ( vtkActor *actor = aCollection->GetNextActor() ) {
259         if ( SMESH_Actor *smeshActor = dynamic_cast<SMESH_Actor*>( actor ))
260         {
261           if ( !smeshActor->hasIO() )
262             continue;
263           Handle(SALOME_InteractiveObject) io = smeshActor->getIO();
264           if ( !io->hasEntry() )
265             continue;
266           _PTR(SObject) so = aStudy->FindObjectID( io->getEntry() );
267           if ( !so )
268             continue; // seems impossible
269
270           CORBA::Object_var obj = SMESH::SObjectToObject( so );
271           if ( CORBA::is_nil( obj )) // removed object
272           {
273             RemoveActor( theWindow, smeshActor );
274             continue;
275           }
276
277           bool toShow = smeshActor->GetVisibility();
278           _PTR(GenericAttribute) attr;
279           if ( toShow && so->FindAttribute( attr, "AttributePixMap" )) // check emptiness
280           {
281             _PTR(AttributePixMap) pixMap = attr;
282             toShow = ( pixMap->GetPixMap() != emptyIcon );
283           }
284           //smeshActor->Update();
285           UpdateView( theWindow, toShow ? eDisplay : eErase, io->getEntry() );
286         }
287       }
288     }
289     return;
290   }
291
292   //================================================================================
293   /*!
294    * \brief Notify the user on problems during visualization
295    */
296   //================================================================================
297
298   void OnVisuException()
299   {
300     try {
301       OCC_CATCH_SIGNALS;
302       // PAL16774 (Crash after display of many groups). Salome sometimes crashes just
303       // after or at showing this message, so we do an additional check of available memory
304 //       char* buf = new char[100*1024];
305 //       delete [] buf;
306       SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"),
307                                QObject::tr("SMESH_VISU_PROBLEM"));
308     } catch (...) {
309       // no more memory at all: last resort
310       MESSAGE_BEGIN ( "SMESHGUI_VTKUtils::OnVisuException(), exception even at showing a message!!!" <<
311                       std::endl << "Try to remove all visual data..." );
312       if (theVISU_MemoryReserve) {
313         delete theVISU_MemoryReserve;
314         theVISU_MemoryReserve = 0;
315       }
316       RemoveAllObjectsWithActors();
317       SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"),
318                                QObject::tr("SMESH_VISU_PROBLEM_CLEAR"));
319       MESSAGE_END ( "...done" );
320     }
321   }
322   //================================================================================
323   /*!
324    * \brief Returns an updated visual object
325    */
326   //================================================================================
327
328   TVisualObjPtr GetVisualObj(const char* theEntry, bool nulData){
329     TVisualObjPtr aVisualObj;
330     try{
331       OCC_CATCH_SIGNALS;
332       TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.find(theEntry);
333       if(anIter != VISUAL_OBJ_CONT.end()){
334         aVisualObj = anIter->second;
335       }else{
336         SalomeApp_Application* app =
337           dynamic_cast<SalomeApp_Application*>( SMESHGUI::activeStudy()->application() );
338         _PTR(Study) aStudy = SMESH::getStudy();
339         _PTR(SObject) aSObj = aStudy->FindObjectID(theEntry);
340         if(aSObj){
341           _PTR(GenericAttribute) anAttr;
342           if(aSObj->FindAttribute(anAttr,"AttributeIOR")){
343             _PTR(AttributeIOR) anIOR = anAttr;
344             CORBA::String_var aVal = anIOR->Value().c_str();
345             CORBA::Object_var anObj = app->orb()->string_to_object( aVal.in() );
346             if(!CORBA::is_nil(anObj)){
347               //Try narrow to SMESH_Mesh interface
348               SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObj);
349               if(!aMesh->_is_nil()){
350                 aVisualObj.reset(new SMESH_MeshObj(aMesh));
351                 TVisualObjCont::value_type aValue(theEntry,aVisualObj);
352                 VISUAL_OBJ_CONT.insert(aValue);
353               }
354               //Try narrow to SMESH_Group interface
355               SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObj);
356               if(!aGroup->_is_nil()){
357                 _PTR(SObject) aFatherSObj = aSObj->GetFather();
358                 if(!aFatherSObj) return aVisualObj;
359                 aFatherSObj = aFatherSObj->GetFather();
360                 if(!aFatherSObj) return aVisualObj;
361                 CORBA::String_var anEntry = aFatherSObj->GetID().c_str();
362                 TVisualObjPtr aVisObj = GetVisualObj(anEntry.in());
363                 if(SMESH_MeshObj* aMeshObj = dynamic_cast<SMESH_MeshObj*>(aVisObj.get())){
364                   aVisualObj.reset(new SMESH_GroupObj(aGroup,aMeshObj));
365                   TVisualObjCont::value_type aValue(theEntry,aVisualObj);
366                   VISUAL_OBJ_CONT.insert(aValue);
367                 }
368               }
369               //Try narrow to SMESH_subMesh interface
370               SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(anObj);
371               if(!aSubMesh->_is_nil()){
372                 _PTR(SObject) aFatherSObj = aSObj->GetFather();
373                 if(!aFatherSObj) return aVisualObj;
374                 aFatherSObj = aFatherSObj->GetFather();
375                 if(!aFatherSObj) return aVisualObj;
376                 CORBA::String_var anEntry = aFatherSObj->GetID().c_str();
377                 TVisualObjPtr aVisObj = GetVisualObj(anEntry.in());
378                 if(SMESH_MeshObj* aMeshObj = dynamic_cast<SMESH_MeshObj*>(aVisObj.get())){
379                   aVisualObj.reset(new SMESH_subMeshObj(aSubMesh,aMeshObj));
380                   TVisualObjCont::value_type aValue(theEntry,aVisualObj);
381                   VISUAL_OBJ_CONT.insert(aValue);
382                 }
383               }
384             }
385           }
386         }
387       }
388     }catch(...){
389       INFOS("GetMeshObj - There is no SMESH_Mesh object for the SALOMEDS::Strudy and Entry!!!");
390       return TVisualObjPtr();
391     }
392     // Update object
393     bool objModified = false;
394     if ( aVisualObj ) {
395       try {
396         OCC_CATCH_SIGNALS;
397         if (nulData)
398           objModified = aVisualObj->NulData();
399         else
400           objModified = aVisualObj->Update();
401       }
402       catch (...) {
403         MESSAGE ( "Exception in SMESHGUI_VTKUtils::GetVisualObj()" );
404         RemoveVisualObjectWithActors( theEntry ); // remove this object
405         OnVisuException();
406         aVisualObj.reset();
407       }
408     }
409
410     if ( objModified ) {
411       // PAL16631. Measurements showed that to show aVisualObj in SHADING(default) mode,
412       // ~5 times more memory is used than it occupies.
413       // Warn the user if there is less free memory than 30 sizes of a grid
414       // TODO: estimate memory usage in other modes and take current mode into account
415       int freeMB = SMDS_Mesh::CheckMemory(true);
416       int usedMB = aVisualObj->GetUnstructuredGrid()->GetActualMemorySize() / 1024;
417       //MESSAGE("SMESHGUI_VTKUtils::GetVisualObj(), freeMB=" << freeMB << ", usedMB=" <<usedMB);
418       if ( freeMB > 0 && usedMB * 5 > freeMB ) {
419         bool continu = false;
420         if ( usedMB * 3 > freeMB )
421           // don't even try to show
422           SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"),
423                                    QObject::tr("SMESH_NO_MESH_VISUALIZATION"));
424         else
425           // there is a chance to succeed
426           continu = SUIT_MessageBox::warning
427             (SMESHGUI::desktop(),
428              QObject::tr("SMESH_WRN_WARNING"),
429              QObject::tr("SMESH_CONTINUE_MESH_VISUALIZATION"),
430              SUIT_MessageBox::Yes | SUIT_MessageBox::No,
431              SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes;
432         if ( !continu ) {
433           // remove the corresponding actors from all views
434           RemoveVisualObjectWithActors( theEntry );
435           aVisualObj.reset();
436         }
437       }
438     }
439
440     return aVisualObj;
441   }
442
443
444   /*! Return active view window, if it instantiates SVTK_ViewWindow class,
445    *  otherwise find or create corresponding view window, make it active and return it.
446    *  \note Active VVTK_ViewWindow can be returned, because it inherits SVTK_ViewWindow.
447    */
448   SVTK_ViewWindow* GetViewWindow (const SalomeApp_Module* theModule,
449                                   bool createIfNotFound)
450   {
451     SalomeApp_Application* anApp;
452     if (theModule)
453       anApp = theModule->getApp();
454     else
455       anApp = dynamic_cast<SalomeApp_Application*>
456         (SUIT_Session::session()->activeApplication());
457
458     if (anApp) {
459       if (SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(anApp->desktop()->activeWindow()))
460         return aView;
461
462       SUIT_ViewManager* aViewManager =
463         anApp->getViewManager(SVTK_Viewer::Type(), createIfNotFound);
464       if (aViewManager) {
465         if (SUIT_ViewWindow* aViewWindow = aViewManager->getActiveView()) {
466           if (SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(aViewWindow)) {
467             aViewWindow->raise();
468             aViewWindow->setFocus();
469             return aView;
470           }
471         }
472       }
473     }
474     return NULL;
475   }
476
477   SVTK_ViewWindow* FindVtkViewWindow (SUIT_ViewManager* theMgr,
478                                       SUIT_ViewWindow * theWindow)
479   {
480     if( !theMgr )
481       return NULL;
482
483     QVector<SUIT_ViewWindow*> views = theMgr->getViews();
484     if( views.contains( theWindow ) )
485       return GetVtkViewWindow( theWindow );
486     else
487       return NULL;
488   }
489
490   SVTK_ViewWindow* GetVtkViewWindow(SUIT_ViewWindow* theWindow){
491     return dynamic_cast<SVTK_ViewWindow*>(theWindow);
492   }
493
494 /*  SUIT_ViewWindow* GetActiveWindow()
495   {
496     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
497     if( !app )
498       return NULL;
499     SUIT_ViewManager* mgr = app->activeViewManager();
500     if( mgr )
501       return mgr->getActiveView();
502     else
503       return NULL;
504   }*/
505
506   SVTK_ViewWindow* GetCurrentVtkView(){
507     return GetVtkViewWindow( GetActiveWindow() );
508   }
509
510
511   void RepaintCurrentView()
512   {
513     if (SVTK_ViewWindow* wnd = GetCurrentVtkView())
514     {
515       try {
516         OCC_CATCH_SIGNALS;
517         wnd->getRenderer()->Render();
518         wnd->Repaint(false);
519       }
520       catch (...) {
521         MESSAGE ( "Exception in SMESHGUI_VTKUtils::RepaintCurrentView()" );
522         OnVisuException();
523       }
524     }
525   }
526
527   void RepaintViewWindow(SVTK_ViewWindow* theWindow)
528   {
529     try {
530       OCC_CATCH_SIGNALS;
531       theWindow->getRenderer()->Render();
532       theWindow->Repaint();
533     }
534     catch (...) {
535       MESSAGE ( "Exception in SMESHGUI_VTKUtils::RepaintViewWindow(SVTK_ViewWindow*)" );
536       OnVisuException();
537     }
538   }
539
540   void RenderViewWindow(SVTK_ViewWindow* theWindow)
541   {
542     try {
543       OCC_CATCH_SIGNALS;
544       theWindow->getRenderer()->Render();
545       theWindow->Repaint();
546     }
547     catch (...) {
548       MESSAGE ( "Exception in SMESHGUI_VTKUtils::RenderViewWindow(SVTK_ViewWindow*)" );
549       OnVisuException();
550     }
551   }
552
553   void FitAll(){
554     if(SVTK_ViewWindow* wnd = GetCurrentVtkView() ){
555       try {
556         OCC_CATCH_SIGNALS;
557         wnd->onFitAll();
558         wnd->Repaint();
559       }
560       catch (...) {
561         MESSAGE ( "Exception in SMESHGUI_VTKUtils::FitAll()" );
562         OnVisuException();
563       }
564     }
565   }
566
567
568   SMESH_Actor* FindActorByEntry(SUIT_ViewWindow *theWindow,
569                                 const char* theEntry)
570   {
571     if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWindow)){
572       vtkRenderer *aRenderer = aViewWindow->getRenderer();
573       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
574       vtkActorCollection *aCollection = aCopy.GetActors();
575       aCollection->InitTraversal();
576       while(vtkActor *anAct = aCollection->GetNextActor()){
577         if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
578           if(anActor->hasIO()){
579             Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
580             if(anIO->hasEntry() && strcmp(anIO->getEntry(),theEntry) == 0){
581               return anActor;
582             }
583           }
584         }
585       }
586     }
587     return NULL;
588   }
589
590
591   SMESH_Actor* FindActorByEntry(const char* theEntry){
592     return FindActorByEntry(GetActiveWindow(),theEntry);
593   }
594
595
596   SMESH_Actor* FindActorByObject(CORBA::Object_ptr theObject){
597     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
598     if( !app )
599       return NULL;
600
601     if(!CORBA::is_nil(theObject)){
602       _PTR(Study) aStudy = getStudy();
603       CORBA::String_var anIOR = app->orb()->object_to_string( theObject );
604       _PTR(SObject) aSObject = aStudy->FindObjectIOR(anIOR.in());
605       if(aSObject){
606         CORBA::String_var anEntry = aSObject->GetID().c_str();
607         return FindActorByEntry(anEntry.in());
608       }
609     }
610     return NULL;
611   }
612
613
614   SMESH_Actor* CreateActor(const char* theEntry,
615                            int theIsClear)
616   {
617     SMESH_Actor *anActor = NULL;
618     if(TVisualObjPtr aVisualObj = GetVisualObj(theEntry)){
619       _PTR(SObject) aSObj = getStudy()->FindObjectID(theEntry);
620       if(aSObj){
621         _PTR(GenericAttribute) anAttr;
622         if(aSObj->FindAttribute(anAttr,"AttributeName")){
623           _PTR(AttributeName) aName = anAttr;
624           std::string aNameVal = aName->Value();
625           anActor = SMESH_Actor::New(aVisualObj,theEntry,aNameVal.c_str(),theIsClear);
626         }
627
628         SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SMESH::SObjectToObject( aSObj ));
629         if(!CORBA::is_nil(aGroup) && anActor)
630         {
631           QColor c;
632           int deltaF, deltaV;
633           SMESH::GetColor( "SMESH", "fill_color", c, deltaF, "0,170,255|-100"  );
634           SMESH::GetColor( "SMESH", "volume_color", c, deltaV, "255,0,170|-100"  );
635           c = SMESH::GetColor( "SMESH", "default_grp_color", c );
636           SALOMEDS::Color aColor = aGroup->GetColor();
637           if( !( aColor.R > 0 || aColor.G > 0 || aColor.B > 0 ))
638           {
639             aColor.R = c.redF();
640             aColor.G = c.greenF();
641             aColor.B = c.blueF();
642             aGroup->SetColor( aColor );
643           }
644           if( aGroup->GetType() == SMESH::NODE )
645             anActor->SetNodeColor( aColor.R, aColor.G, aColor.B );
646           else if( aGroup->GetType() == SMESH::EDGE )
647             anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B );
648           else if( aGroup->GetType() == SMESH::ELEM0D )
649             anActor->Set0DColor( aColor.R, aColor.G, aColor.B );
650           else if( aGroup->GetType() == SMESH::BALL )
651             anActor->SetBallColor( aColor.R, aColor.G, aColor.B );
652           else if( aGroup->GetType() == SMESH::VOLUME )
653             anActor->SetVolumeColor( aColor.R, aColor.G, aColor.B, deltaV );
654           else
655             anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B, deltaF );
656         }
657       }
658     }
659     //MESSAGE("CreateActor " << anActor);
660     if( anActor )
661       if( SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI() )
662         aSMESHGUI->addActorAsObserver( anActor );
663     return anActor;
664   }
665
666
667   void DisplayActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){
668     if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){
669       try {
670         OCC_CATCH_SIGNALS;
671         //MESSAGE("DisplayActor " << theActor);
672         vtkWnd->AddActor(theActor);
673         vtkWnd->Repaint();
674       }
675       catch (...) {
676         MESSAGE ( "Exception in SMESHGUI_VTKUtils::DisplayActor()" );
677         OnVisuException();
678       }
679     }
680   }
681
682
683   void RemoveActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor)
684   {
685     if ( SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)) {
686       //MESSAGE("RemoveActor " << theActor);
687       vtkWnd->RemoveActor(theActor);
688       if(theActor->hasIO()){
689         Handle(SALOME_InteractiveObject) anIO = theActor->getIO();
690         if(anIO->hasEntry()){
691           std::string anEntry = anIO->getEntry();
692           VISUAL_OBJ_CONT.erase(anEntry);
693         }
694       }
695       theActor->Delete();
696       vtkWnd->Repaint();
697     }
698   }
699
700   //================================================================================
701   /*!
702    * \brief Return true if there are no SMESH actors in a view
703    */
704   //================================================================================
705
706   bool noSmeshActors(SUIT_ViewWindow *theWnd)
707   {
708     if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWnd)) {
709       vtkRenderer *aRenderer = aViewWindow->getRenderer();
710       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
711       vtkActorCollection *aCollection = aCopy.GetActors();
712       aCollection->InitTraversal();
713       while(vtkActor *anAct = aCollection->GetNextActor())
714         if(dynamic_cast<SMESH_Actor*>(anAct))
715           return false;
716     }
717     return true;
718   }
719
720   bool UpdateView(SUIT_ViewWindow *theWnd, EDisplaing theAction, const char* theEntry)
721   {
722     //MESSAGE("UpdateView");
723     bool OK = false;
724     SVTK_ViewWindow* aViewWnd = GetVtkViewWindow(theWnd);
725     if (!aViewWnd)
726       return OK;
727
728     SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd);
729     if (!vtkWnd)
730       return OK;
731
732     SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( vtkWnd->getViewManager()->study() );
733     
734     if (!aStudy)
735       return OK;
736
737     SUIT_ResourceMgr* resMgr;
738     {
739       OK = true;
740       vtkRenderer *aRenderer = aViewWnd->getRenderer();
741       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
742       vtkActorCollection *aCollection = aCopy.GetActors();
743       aCollection->InitTraversal();
744
745       switch (theAction) {
746       case eDisplayAll: {
747         while (vtkActor *anAct = aCollection->GetNextActor()) {
748           if (SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)) {
749             //MESSAGE("--- display " << anActor);
750             anActor->SetVisibility(true);
751
752             if(anActor->hasIO()){
753               Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
754               if(anIO->hasEntry()){
755                 aStudy->setVisibilityState(anIO->getEntry(), Qtx::ShownState);
756               }
757             }
758           }
759         }
760         break;
761       }
762       case eDisplayOnly:
763       case eEraseAll: {
764         //MESSAGE("---case eDisplayOnly");
765         while (vtkActor *anAct = aCollection->GetNextActor()) {
766           if (SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)) {
767             //MESSAGE("--- erase " << anActor);
768             anActor->SetVisibility(false);
769           }
770         }
771         aStudy->setVisibilityStateForAll(Qtx::HiddenState);
772       }
773       default: {
774         if (SMESH_Actor *anActor = FindActorByEntry(theWnd,theEntry)) {
775           switch (theAction) {
776             case eDisplay:
777             case eDisplayOnly:
778               //MESSAGE("--- display " << anActor);
779               anActor->Update();
780               anActor->SetVisibility(true);
781               if (theAction == eDisplayOnly) aRenderer->ResetCameraClippingRange();
782               aStudy->setVisibilityState(theEntry, Qtx::ShownState);
783               if (( theAction == eDisplayOnly ) &&
784                   ( resMgr = SMESHGUI::resourceMgr() ) &&
785                   ( resMgr->booleanValue( "SMESH", "fitall_on_displayonly", false )))
786                 FitAll(); // PAL23615
787               break;
788             case eErase:
789               //MESSAGE("--- erase " << anActor);
790               anActor->SetVisibility(false);
791               aStudy->setVisibilityState(theEntry, Qtx::HiddenState);
792               break;
793             default:;
794           }
795         } else {
796           switch (theAction) {
797           case eDisplay:
798           case eDisplayOnly:
799             {
800               //MESSAGE("---");
801               SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(theWnd->getViewManager()->study());
802               TVisualObjPtr aVisualObj;
803               if ( (aVisualObj = GetVisualObj(theEntry)) && aVisualObj->IsValid())
804               {
805                 if ((anActor = CreateActor(theEntry,true))) {
806                   bool needFitAll = noSmeshActors(theWnd); // fit for the first object only
807                   DisplayActor(theWnd,anActor);
808                   anActor->SetVisibility(true);
809                   aStudy->setVisibilityState(theEntry, Qtx::ShownState);
810                   // FitAll(); - PAL16770(Display of a group performs an automatic fit all)
811                   if (( !needFitAll ) &&
812                       ( theAction == eDisplayOnly ) &&
813                       ( resMgr = SMESHGUI::resourceMgr() ))
814                   {
815                     needFitAll = resMgr->booleanValue( "SMESH", "fitall_on_displayonly", false );
816                   }
817                   if ( needFitAll )
818                     FitAll();
819                 }
820                 else {
821                   OK = false;
822                 }
823               }
824               break;
825             }
826           default:;
827           }
828         }
829       }
830       }
831     }
832     return OK;
833   }
834
835
836   bool UpdateView(EDisplaing theAction, const char* theEntry) {
837     //MESSAGE("UpdateView");
838     SalomeApp_Study* aStudy = dynamic_cast< SalomeApp_Study* >( GetActiveStudy() );
839     SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( aStudy->application() );
840     if ( SUIT_ViewManager* vm = app->activeViewManager() )
841     {
842       SUIT_ViewWindow *aWnd = vm->getActiveView();
843       return UpdateView(aWnd,theAction,theEntry);
844     }
845     return false;
846   }
847
848   void UpdateView( bool withChildrenOfSelected )
849   {
850     if ( SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView()) {
851       LightApp_SelectionMgr* mgr = SMESHGUI::selectionMgr();
852       SALOME_ListIO selected; mgr->selectedObjects( selected );
853
854       if ( selected.Extent() == 0 ) {
855         vtkRenderer* aRenderer = aWnd->getRenderer();
856         VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
857         vtkActorCollection *aCollection = aCopy.GetActors();
858         aCollection->InitTraversal();
859         while(vtkActor *anAct = aCollection->GetNextActor()){
860           if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
861             if(anActor->hasIO())
862               if (!Update(anActor->getIO(),anActor->GetVisibility()))
863                 break; // avoid multiple warnings if visu failed
864           }
865         }
866       }
867       else
868       {
869         SALOME_ListIteratorOfListIO anIter( selected );
870         for( ; anIter.More(); anIter.Next())
871         {
872           Handle(SALOME_InteractiveObject) anIO = anIter.Value();
873           if ( !Update( anIO, true ))
874             break; // avoid multiple warnings if visu failed
875
876           if ( withChildrenOfSelected ) // update all visible children
877           {
878             QString aFatherID = anIO->getEntry();
879             vtkRenderer* aRenderer = aWnd->getRenderer();
880             VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
881             vtkActorCollection *aCollection = aCopy.GetActors();
882             aCollection->InitTraversal();
883             while ( vtkActor *anAct = aCollection->GetNextActor() ) {
884               if ( SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>( anAct )) {
885                 if ( anActor->hasIO() && anActor->GetVisibility() )
886                 {
887                   QString aChildID = anActor->getIO()->getEntry();
888                   if ( aChildID.size() > aFatherID.size() &&
889                        aChildID.startsWith( aFatherID ))
890                     if ( ! Update( anActor->getIO(), true ))
891                       break;
892                 }
893               }
894             }
895           }
896         }
897       }
898       RepaintCurrentView();
899     }
900   }
901
902
903   bool Update(const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay)
904   {
905     //MESSAGE("Update");
906     if ( TVisualObjPtr aVisualObj = SMESH::GetVisualObj(theIO->getEntry())) {
907       if ( theDisplay )
908         UpdateView(SMESH::eDisplay,theIO->getEntry());
909       return true;
910     }
911     return false;
912   }
913
914   bool UpdateNulData(const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay)
915   {
916     //MESSAGE("UpdateNulData");
917     if ( TVisualObjPtr aVisualObj = SMESH::GetVisualObj(theIO->getEntry(), true)) {
918       if ( theDisplay )
919         UpdateView(SMESH::eDisplay,theIO->getEntry());
920       return true;
921     }
922     return false;
923   }
924
925   void UpdateSelectionProp( SMESHGUI* theModule )
926   {
927     if( !theModule )
928       return;
929
930     SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( theModule->application() );
931     if( !app )
932     {
933       MESSAGE( "UpdateSelectionProp: Application is null" );
934       return;
935     }
936
937     SUIT_ViewManager* vm = app->activeViewManager();
938     if( !vm )
939     {
940       MESSAGE( "UpdateSelectionProp: View manager is null" );
941       return;
942     }
943
944     QVector<SUIT_ViewWindow*> views = vm->getViews();
945
946     SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( theModule );
947     if( !mgr )
948     {
949       MESSAGE( "UpdateSelectionProp: Resource manager is null" );
950       return;
951     }
952
953     SMESH_ActorProps::props()->reset();
954
955     QColor
956       //aHiColor = mgr->colorValue( "SMESH", "selection_object_color", Qt::white ),
957       aSelColor = mgr->colorValue( "SMESH", "selection_element_color", Qt::yellow ),
958       aPreColor = mgr->colorValue( "SMESH", "highlight_color", Qt::cyan );
959
960     int aElem0DSize = mgr->integerValue("SMESH", "elem0d_size", 5);
961     // int aBallSize   = mgr->integerValue("SMESH", "ball_elem_size", 5);
962     int aLineWidth  = mgr->integerValue("SMESH", "element_width", 1);
963     int maxSize = aElem0DSize;
964     if (aElem0DSize > maxSize) maxSize = aElem0DSize;
965     if (aLineWidth > maxSize) maxSize = aLineWidth;
966     //  if (aBallSize > maxSize) maxSize = aBallSize;
967
968     double
969       SP1 = mgr->doubleValue( "SMESH", "selection_precision_node", 0.025 ),
970       SP2 = mgr->doubleValue( "SMESH", "selection_precision_element", 0.001 ),
971       SP3 = mgr->doubleValue( "SMESH", "selection_precision_object", 0.025 );
972
973     for ( int i=0, n=views.count(); i<n; i++ )
974     {
975       // update VTK viewer properties
976       if ( SVTK_ViewWindow* aVtkView = GetVtkViewWindow( views[i] ))
977       {
978         // mesh element selection
979         aVtkView->SetSelectionProp(aSelColor.red()/255.,
980                                    aSelColor.green()/255.,
981                                    aSelColor.blue()/255.);
982         // tolerances
983         aVtkView->SetSelectionTolerance(SP1, SP2, SP3);
984
985         // pre-selection
986         aVtkView->SetPreselectionProp(aPreColor.red()/255.,
987                                       aPreColor.green()/255.,
988                                       aPreColor.blue()/255.);
989         // update actors
990         vtkRenderer* aRenderer = aVtkView->getRenderer();
991         VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
992         vtkActorCollection *aCollection = aCopy.GetActors();
993         aCollection->InitTraversal();
994         while ( vtkActor *anAct = aCollection->GetNextActor() ) {
995           if ( SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct) ) {
996             anActor->UpdateSelectionProps();
997           }
998         }
999       }
1000     }
1001   }
1002
1003
1004   void UpdateFontProp( SMESHGUI* theModule )
1005   {
1006     if ( !theModule ) return;
1007
1008     SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( theModule->application() );
1009     if ( !app ) return;
1010
1011     SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( theModule );
1012     if ( !mgr ) return;
1013     //
1014     double anRGBNd[3] = {1,1,1};
1015     SMESH::GetColor( "SMESH", "numbering_node_color", anRGBNd[0], anRGBNd[1], anRGBNd[2], QColor( 255, 255, 255 ) );
1016     int aSizeNd = 10;
1017     SMESH::LabelFont aFamilyNd = SMESH::FntTimes;
1018     bool aBoldNd    = true;
1019     bool anItalicNd = false;
1020     bool aShadowNd  = false;
1021
1022     if ( mgr->hasValue( "SMESH", "numbering_node_font" ) ) {
1023       QFont f = mgr->fontValue( "SMESH", "numbering_node_font" );
1024       if ( f.family()      == "Arial" )   aFamilyNd = SMESH::FntArial;
1025       else if ( f.family() == "Courier" ) aFamilyNd = SMESH::FntCourier;
1026       else if ( f.family() == "Times" )   aFamilyNd = SMESH::FntTimes;
1027       aBoldNd    = f.bold();
1028       anItalicNd = f.italic();
1029       aShadowNd  = f.overline();
1030       aSizeNd    = f.pointSize();
1031     }
1032     //
1033     double anRGBEl[3] = {0,1,0};
1034     SMESH::GetColor( "SMESH", "numbering_elem_color", anRGBEl[0], anRGBEl[1], anRGBEl[2], QColor( 0, 255, 0 ) );
1035     int aSizeEl = 12;
1036     SMESH::LabelFont aFamilyEl = SMESH::FntTimes;
1037     bool aBoldEl    = true;
1038     bool anItalicEl = false;
1039     bool aShadowEl  = false;
1040
1041     if ( mgr->hasValue( "SMESH", "numbering_elem_font" ) ) {
1042       QFont f = mgr->fontValue( "SMESH", "numbering_elem_font" );
1043
1044       if ( f.family()      == "Arial" )   aFamilyEl = SMESH::FntArial;
1045       else if ( f.family() == "Courier" ) aFamilyEl = SMESH::FntCourier;
1046       else if ( f.family() == "Times" )   aFamilyEl = SMESH::FntTimes;    
1047       aBoldEl    = f.bold();
1048       anItalicEl = f.italic();
1049       aShadowEl  = f.overline();
1050       aSizeEl    = f.pointSize();
1051     }
1052     //
1053     ViewManagerList vmList;
1054     app->viewManagers( SVTK_Viewer::Type(), vmList );
1055     foreach ( SUIT_ViewManager* vm, vmList ) {
1056       QVector<SUIT_ViewWindow*> views = vm->getViews();
1057       foreach ( SUIT_ViewWindow* vw, views ) {
1058         // update VTK viewer properties
1059         if ( SVTK_ViewWindow* aVtkView = GetVtkViewWindow( vw ) ) {
1060           // update actors
1061           vtkRenderer* aRenderer = aVtkView->getRenderer();
1062           VTK::ActorCollectionCopy aCopy( aRenderer->GetActors() );
1063           vtkActorCollection* aCollection = aCopy.GetActors();
1064           aCollection->InitTraversal();
1065           while ( vtkActor* anAct = aCollection->GetNextActor() ) {
1066             if ( SMESH_NodeLabelActor* anActor = dynamic_cast< SMESH_NodeLabelActor* >( anAct ) ) {
1067               anActor->SetFontProperties( aFamilyNd, aSizeNd, aBoldNd, anItalicNd, aShadowNd, anRGBNd[0], anRGBNd[1], anRGBNd[2] );
1068             }
1069             else if ( SMESH_CellLabelActor* anActor = dynamic_cast< SMESH_CellLabelActor* >( anAct ) ) {
1070               anActor->SetFontProperties( aFamilyEl, aSizeEl, aBoldEl, anItalicEl, aShadowEl, anRGBEl[0], anRGBEl[1], anRGBEl[2] );
1071             }
1072           }
1073           aVtkView->Repaint( false ); 
1074         }
1075       }
1076     }
1077   }
1078
1079   //----------------------------------------------------------------------------
1080   SVTK_Selector*
1081   GetSelector(SUIT_ViewWindow *theWindow)
1082   {
1083     if(SVTK_ViewWindow* aWnd = GetVtkViewWindow(theWindow))
1084       return aWnd->GetSelector();
1085
1086     return NULL;
1087   }
1088
1089   void SetFilter(const Handle(VTKViewer_Filter)& theFilter,
1090                  SVTK_Selector* theSelector)
1091   {
1092     if (theSelector)
1093       theSelector->SetFilter(theFilter);
1094   }
1095
1096   Handle(VTKViewer_Filter) GetFilter(int theId, SVTK_Selector* theSelector)
1097   {
1098     return theSelector->GetFilter(theId);
1099   }
1100
1101   bool IsFilterPresent(int theId, SVTK_Selector* theSelector)
1102   {
1103     return theSelector->IsFilterPresent(theId);
1104   }
1105
1106   void RemoveFilter(int theId, SVTK_Selector* theSelector)
1107   {
1108     theSelector->RemoveFilter(theId);
1109   }
1110
1111   void RemoveFilters(SVTK_Selector* theSelector)
1112   {
1113     for ( int id = SMESH::NodeFilter; theSelector && id < SMESH::LastFilter; id++ )
1114       theSelector->RemoveFilter( id );
1115   }
1116
1117   bool IsValid(SALOME_Actor* theActor, int theCellId,
1118                SVTK_Selector* theSelector)
1119   {
1120     return theSelector->IsValid(theActor,theCellId);
1121   }
1122
1123
1124   //----------------------------------------------------------------------------
1125   void SetPointRepresentation(bool theIsVisible)
1126   {
1127     if ( SVTK_ViewWindow* aViewWindow = GetCurrentVtkView() ) {
1128       vtkRenderer *aRenderer = aViewWindow->getRenderer();
1129       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
1130       vtkActorCollection *aCollection = aCopy.GetActors();
1131       aCollection->InitTraversal();
1132       while(vtkActor *anAct = aCollection->GetNextActor()){
1133         if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
1134           if(anActor->GetVisibility()){
1135             anActor->SetPointRepresentation(theIsVisible);
1136           }
1137         }
1138       }
1139       RepaintCurrentView();
1140     }
1141   }
1142
1143
1144   void SetPickable(SMESH_Actor* theActor)
1145   {
1146     if ( SVTK_ViewWindow* aWnd = GetCurrentVtkView() ) {
1147       int anIsAllPickable = (theActor == NULL);
1148       vtkRenderer *aRenderer = aWnd->getRenderer();
1149       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
1150       vtkActorCollection *aCollection = aCopy.GetActors();
1151       aCollection->InitTraversal();
1152       while(vtkActor *anAct = aCollection->GetNextActor()){
1153         if(SALOME_Actor *anActor = dynamic_cast<SALOME_Actor*>(anAct)){
1154           if(anActor->GetVisibility()){
1155             anActor->SetPickable(anIsAllPickable);
1156           }
1157         }
1158       }
1159       if(theActor)
1160         theActor->SetPickable(!anIsAllPickable);
1161       RepaintCurrentView();
1162     }
1163   }
1164
1165
1166   //----------------------------------------------------------------------------
1167   int GetNameOfSelectedNodes(SVTK_Selector*                          theSelector,
1168                              const Handle(SALOME_InteractiveObject)& theIO,
1169                              QString&                                theName)
1170   {
1171     theName = "";
1172     TColStd_IndexedMapOfInteger aMapIndex;
1173     theSelector->GetIndex(theIO,aMapIndex);
1174
1175     for(int i = 1; i <= aMapIndex.Extent(); i++)
1176       theName += QString(" %1").arg(aMapIndex(i));
1177
1178     return aMapIndex.Extent();
1179   }
1180
1181   int GetNameOfSelectedElements(SVTK_Selector* theSelector,
1182                                 const Handle(SALOME_InteractiveObject)& theIO,
1183                                 QString& theName)
1184   {
1185     theName = "";
1186     TColStd_IndexedMapOfInteger aMapIndex;
1187     theSelector->GetIndex(theIO,aMapIndex);
1188
1189     typedef std::set<int> TIdContainer;
1190     TIdContainer anIdContainer;
1191     for( int i = 1; i <= aMapIndex.Extent(); i++)
1192       anIdContainer.insert(aMapIndex(i));
1193
1194     TIdContainer::const_iterator anIter = anIdContainer.begin();
1195     for( ; anIter != anIdContainer.end(); anIter++)
1196       theName += QString(" %1").arg(*anIter);
1197
1198     return aMapIndex.Extent();
1199   }
1200
1201
1202   int GetEdgeNodes(SVTK_Selector* theSelector,
1203                    const TVisualObjPtr& theVisualObject,
1204                    int& theId1,
1205                    int& theId2)
1206   {
1207     const SALOME_ListIO& selected = theSelector->StoredIObjects();
1208
1209     if ( selected.Extent() != 1 )
1210       return -1;
1211
1212     Handle(SALOME_InteractiveObject) anIO = selected.First();
1213     if ( anIO.IsNull() || !anIO->hasEntry() )
1214       return -1;
1215
1216     TColStd_IndexedMapOfInteger aMapIndex;
1217     theSelector->GetIndex( anIO, aMapIndex );
1218     if ( aMapIndex.Extent() != 2 )
1219       return -1;
1220
1221     int anObjId = -1, anEdgeNum = -1;
1222     for ( int i = 1; i <= aMapIndex.Extent(); i++ ) {
1223       int aVal = aMapIndex( i );
1224       if ( aVal > 0 )
1225         anObjId = aVal;
1226       else
1227         anEdgeNum = abs( aVal ) - 1;
1228     }
1229
1230     if ( anObjId == -1 || anEdgeNum == -1 )
1231       return -1;
1232
1233     return theVisualObject->GetEdgeNodes( anObjId, anEdgeNum, theId1, theId2 ) ? 1 : -1;
1234   }
1235
1236   //----------------------------------------------------------------------------
1237   int GetNameOfSelectedNodes(LightApp_SelectionMgr *theMgr,
1238                              const Handle(SALOME_InteractiveObject)& theIO,
1239                              QString& theName)
1240   {
1241     theName = "";
1242     if(theIO->hasEntry()){
1243       if(FindActorByEntry(theIO->getEntry())){
1244         TColStd_IndexedMapOfInteger aMapIndex;
1245         theMgr->GetIndexes(theIO,aMapIndex);
1246         for(int i = 1; i <= aMapIndex.Extent(); i++){
1247           theName += QString(" %1").arg(aMapIndex(i));
1248         }
1249         return aMapIndex.Extent();
1250       }
1251     }
1252     return -1;
1253   }
1254
1255   int GetNameOfSelectedNodes(LightApp_SelectionMgr *theMgr, QString& theName)
1256   {
1257     theName = "";
1258     SALOME_ListIO selected; theMgr->selectedObjects( selected );
1259     if(selected.Extent() == 1){
1260       Handle(SALOME_InteractiveObject) anIO = selected.First();
1261       return GetNameOfSelectedNodes(theMgr,anIO,theName);
1262     }
1263     return -1;
1264   }
1265
1266
1267   int GetNameOfSelectedElements(LightApp_SelectionMgr *                 theMgr,
1268                                 const Handle(SALOME_InteractiveObject)& theIO,
1269                                 QString&                                theName)
1270   {
1271     theName = "";
1272     if(theIO->hasEntry()){
1273       if(FindActorByEntry(theIO->getEntry())){
1274         TColStd_IndexedMapOfInteger aMapIndex;
1275         theMgr->GetIndexes(theIO,aMapIndex);
1276         typedef std::set<int> TIdContainer;
1277         TIdContainer anIdContainer;
1278         for( int i = 1; i <= aMapIndex.Extent(); i++)
1279           anIdContainer.insert(aMapIndex(i));
1280         TIdContainer::const_iterator anIter = anIdContainer.begin();
1281         for( ; anIter != anIdContainer.end(); anIter++){
1282           theName += QString(" %1").arg(*anIter);
1283         }
1284         return aMapIndex.Extent();
1285       }
1286     }
1287     return -1;
1288   }
1289
1290
1291   int GetNameOfSelectedElements(LightApp_SelectionMgr *theMgr, QString& theName)
1292   {
1293     theName = "";
1294     SALOME_ListIO selected; theMgr->selectedObjects( selected );
1295
1296     if( selected.Extent() == 1){
1297       Handle(SALOME_InteractiveObject) anIO = selected.First();
1298       return GetNameOfSelectedElements(theMgr,anIO,theName);
1299     }
1300     return -1;
1301   }
1302
1303   int GetSelected(LightApp_SelectionMgr*       theMgr,
1304                   TColStd_IndexedMapOfInteger& theMap,
1305                   const bool                   theIsElement)
1306   {
1307     theMap.Clear();
1308     SALOME_ListIO selected; theMgr->selectedObjects( selected );
1309
1310     if ( selected.Extent() == 1 )
1311     {
1312       Handle(SALOME_InteractiveObject) anIO = selected.First();
1313       if ( anIO->hasEntry() ) {
1314         theMgr->GetIndexes( anIO, theMap );
1315       }
1316     }
1317     return theMap.Extent();
1318   }
1319
1320
1321   int GetEdgeNodes( LightApp_SelectionMgr* theMgr, int& theId1, int& theId2 )
1322   {
1323     SALOME_ListIO selected; theMgr->selectedObjects( selected );
1324
1325     if ( selected.Extent() != 1 )
1326       return -1;
1327
1328     Handle(SALOME_InteractiveObject) anIO = selected.First();
1329     if ( anIO.IsNull() || !anIO->hasEntry() )
1330       return -1;
1331
1332     SMESH_Actor *anActor = SMESH::FindActorByEntry( anIO->getEntry() );
1333     if ( anActor == 0 )
1334       return -1;
1335
1336     TColStd_IndexedMapOfInteger aMapIndex;
1337     theMgr->GetIndexes( anIO, aMapIndex );
1338     if ( aMapIndex.Extent() != 2 )
1339       return -1;
1340
1341     int anObjId = -1, anEdgeNum = -1;
1342     for ( int i = 1; i <= aMapIndex.Extent(); i++ ) {
1343       int aVal = aMapIndex( i );
1344       if ( aVal > 0 )
1345         anObjId = aVal;
1346       else
1347         anEdgeNum = abs( aVal );
1348     }
1349
1350     if ( anObjId == -1 || anEdgeNum == -1 )
1351       return -1;
1352
1353     return anActor->GetObject()->GetEdgeNodes( anObjId, anEdgeNum, theId1, theId2 ) ? 1 : -1;
1354   }
1355
1356   void SetControlsPrecision( const long theVal )
1357   {
1358     if( SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView() )
1359     {
1360       vtkRenderer *aRenderer = aWnd->getRenderer();
1361       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
1362       vtkActorCollection *aCollection = aCopy.GetActors();
1363       aCollection->InitTraversal();
1364
1365       while ( vtkActor *anAct = aCollection->GetNextActor())
1366       {
1367         if ( SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>( anAct ) )
1368         {
1369           anActor->SetControlsPrecision( theVal );
1370           anActor->SetControlMode( anActor->GetControlMode() );
1371         }
1372       }
1373
1374     }
1375   }
1376
1377   //----------------------------------------------------------------------------
1378   // internal function
1379   void ComputeBoundsParam( double theBounds[6],
1380                            double theDirection[3],
1381                            double theMinPnt[3],
1382                            double& theMaxBoundPrj,
1383                            double& theMinBoundPrj )
1384   {
1385     //Enlarge bounds in order to avoid conflicts of precision
1386     for(int i = 0; i < 6; i += 2){
1387       static double EPS = 1.0E-3;
1388       double aDelta = (theBounds[i+1] - theBounds[i])*EPS;
1389       theBounds[i] -= aDelta;
1390       theBounds[i+1] += aDelta;
1391     }
1392
1393     double aBoundPoints[8][3] = { {theBounds[0],theBounds[2],theBounds[4]},
1394                                   {theBounds[1],theBounds[2],theBounds[4]},
1395                                   {theBounds[0],theBounds[3],theBounds[4]},
1396                                   {theBounds[1],theBounds[3],theBounds[4]},
1397                                   {theBounds[0],theBounds[2],theBounds[5]},
1398                                   {theBounds[1],theBounds[2],theBounds[5]},
1399                                   {theBounds[0],theBounds[3],theBounds[5]},
1400                                   {theBounds[1],theBounds[3],theBounds[5]}};
1401
1402     int aMaxId = 0;
1403     theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]);
1404     theMinBoundPrj = theMaxBoundPrj;
1405     for(int i = 1; i < 8; i++){
1406       double aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]);
1407       if(theMaxBoundPrj < aTmp){
1408         theMaxBoundPrj = aTmp;
1409         aMaxId = i;
1410       }
1411       if(theMinBoundPrj > aTmp){
1412         theMinBoundPrj = aTmp;
1413       }
1414     }
1415     double *aMinPnt = aBoundPoints[aMaxId];
1416     theMinPnt[0] = aMinPnt[0];
1417     theMinPnt[1] = aMinPnt[1];
1418     theMinPnt[2] = aMinPnt[2];
1419   }
1420
1421   // internal function
1422   void DistanceToPosition( double theBounds[6],
1423                            double theDirection[3],
1424                            double theDist,
1425                            double thePos[3] )
1426   {
1427     double aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
1428     ComputeBoundsParam(theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
1429     double aLength = (aMaxBoundPrj-aMinBoundPrj)*theDist;
1430     thePos[0] = aMinPnt[0]-theDirection[0]*aLength;
1431     thePos[1] = aMinPnt[1]-theDirection[1]*aLength;
1432     thePos[2] = aMinPnt[2]-theDirection[2]*aLength;
1433   }
1434
1435   // internal function (currently unused, left just in case)
1436   void PositionToDistance( double theBounds[6],
1437                            double theDirection[3],
1438                            double thePos[3],
1439                            double& theDist )
1440   {
1441     double aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
1442     ComputeBoundsParam(theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
1443     double aPrj = vtkMath::Dot(theDirection,thePos);
1444     theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj);
1445   }
1446
1447   bool ComputeClippingPlaneParameters( std::list<vtkActor*> theActorList,
1448                                        double theNormal[3],
1449                                        double theDist,
1450                                        double theBounds[6],
1451                                        double theOrigin[3] )
1452   {
1453     bool anIsOk = false;
1454     anIsOk = ComputeBounds( theActorList, theBounds );
1455
1456
1457     if( !anIsOk )
1458       return false;
1459
1460     DistanceToPosition( theBounds, theNormal, theDist, theOrigin );
1461     return true;
1462   }
1463
1464   bool ComputeBounds( std::list<vtkActor*> theActorList,
1465                       double theBounds[6])
1466   {
1467     bool anIsOk = false;
1468     theBounds[0] = theBounds[2] = theBounds[4] = VTK_DOUBLE_MAX;
1469     theBounds[1] = theBounds[3] = theBounds[5] = -VTK_DOUBLE_MAX;
1470     std::list<vtkActor*>::iterator anIter = theActorList.begin();
1471     for( ; anIter != theActorList.end(); anIter++ ) {
1472       if( vtkActor* aVTKActor = *anIter ) {
1473         if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) {
1474           double aBounds[6];
1475           anActor->GetUnstructuredGrid()->GetBounds( aBounds );
1476           theBounds[0] = std::min( theBounds[0], aBounds[0] );
1477           theBounds[1] = std::max( theBounds[1], aBounds[1] );
1478           theBounds[2] = std::min( theBounds[2], aBounds[2] );
1479           theBounds[3] = std::max( theBounds[3], aBounds[3] );
1480           theBounds[4] = std::min( theBounds[4], aBounds[4] );
1481           theBounds[5] = std::max( theBounds[5], aBounds[5] );
1482           anIsOk = true;
1483         }
1484       }
1485     }
1486     return anIsOk;
1487   }
1488
1489 #ifndef DISABLE_PLOT2DVIEWER
1490   //================================================================================
1491   /*!
1492    * \brief Find all SMESH_Actor's in the View Window.
1493    * If actor contains Plot2d_Histogram object remove it from each Plot2d Viewer.
1494    */
1495   //================================================================================
1496
1497   void ClearPlot2Viewers( SUIT_ViewWindow* theWindow )
1498   {
1499     if ( SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWindow) ) {
1500       vtkRenderer *aRenderer = aViewWindow->getRenderer();
1501       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
1502       vtkActorCollection *aCollection = aCopy.GetActors();
1503       aCollection->InitTraversal();
1504       while(vtkActor *anAct = aCollection->GetNextActor()){
1505         if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
1506           if(anActor->hasIO() && anActor->GetPlot2Histogram() ){
1507             ProcessIn2DViewers(anActor,RemoveFrom2dViewer);
1508           }
1509         }
1510       }
1511     }
1512   }
1513
1514 #endif
1515
1516 } // end of namespace SMESH