Salome HOME
Replace oe by ?
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_VTKUtils.cxx
1 //  Copyright (C) 2007-2010  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.
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_Utils.h"
32 #include "SMESHGUI_Filter.h"
33 #include "SMESH_ControlsDef.hxx"
34
35 #include <SMESH_Actor.h>
36 #include <SMESH_ActorUtils.h>
37 #include <SMESH_ObjectDef.h>
38 #include <SMDS_Mesh.hxx>
39
40 // SALOME GUI includes
41 #include <SUIT_Desktop.h>
42 #include <SUIT_Session.h>
43 #include <SUIT_MessageBox.h>
44 #include <SUIT_ViewManager.h>
45 #include <SUIT_ResourceMgr.h>
46
47 #include <SALOME_ListIO.hxx>
48 #include <SALOME_ListIteratorOfListIO.hxx>
49
50 #include <SVTK_Selector.h>
51 #include <SVTK_ViewModel.h>
52 #include <SVTK_ViewWindow.h>
53
54 #include <VTKViewer_Algorithm.h>
55
56 #include <LightApp_SelectionMgr.h>
57 #include <SalomeApp_Application.h>
58 #include <SalomeApp_Study.h>
59
60 // SALOME KERNEL includes
61 #include <utilities.h>
62
63 // IDL includes
64 #include <SALOMEconfig.h>
65 #include CORBA_CLIENT_HEADER(SMESH_Mesh)
66 #include CORBA_CLIENT_HEADER(SMESH_Group)
67
68 // VTK includes
69 #include <vtkMath.h>
70 #include <vtkRenderer.h>
71 #include <vtkActorCollection.h>
72 #include <vtkUnstructuredGrid.h>
73
74 // OCCT includes
75 #include <TColStd_IndexedMapOfInteger.hxx>
76 #include <Standard_ErrorHandler.hxx>
77
78 namespace SMESH
79 {
80   typedef std::map<TKeyOfVisualObj,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     if (aViewManager ) {
141       int aStudyId = aViewManager->study()->id();
142       TVisualObjCont::key_type aKey(aStudyId,theEntry);
143       TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.find(aKey);
144       if(anIter != VISUAL_OBJ_CONT.end()) {
145         // for unknown reason, object destructor is not called, so clear object manually
146         anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0);
147         anIter->second->GetUnstructuredGrid()->SetPoints(0);
148       }
149       VISUAL_OBJ_CONT.erase(aKey);
150     }
151
152     if(actorRemoved)
153       aStudy->setVisibilityState(theEntry, Qtx::HiddenState);
154   }
155   //================================================================================
156   /*!
157    * \brief Remove all VisualObjs and their actors from all views
158    */
159   //================================================================================
160
161   void RemoveAllObjectsWithActors()
162   {
163     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
164       ( SUIT_Session::session()->activeApplication() );
165     if (!app) return;
166     ViewManagerList viewMgrs = app->viewManagers();
167     for ( int iM = 0; iM < viewMgrs.count(); ++iM ) {
168       SUIT_ViewManager* aViewManager = viewMgrs.at( iM );
169       if ( aViewManager && aViewManager->getType() == SVTK_Viewer::Type()) {
170         QVector<SUIT_ViewWindow*> views = aViewManager->getViews();
171         for ( int iV = 0; iV < views.count(); ++iV ) {
172           if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV])) {
173             vtkRenderer *aRenderer = vtkWnd->getRenderer();
174             VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
175             vtkActorCollection *actors = aCopy.GetActors();
176             for (int i = 0; i < actors->GetNumberOfItems(); ++i ) {
177               // size of actors changes inside the loop
178               if (SMESH_Actor *actor = dynamic_cast<SMESH_Actor*>(actors->GetItemAsObject(i)))
179               {
180                 vtkWnd->RemoveActor(actor);
181                 actor->Delete();
182               }
183             }
184           }
185         }
186       }
187     }
188     TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.begin();
189     for ( ; anIter != VISUAL_OBJ_CONT.end(); ++anIter ) {
190       // for unknown reason, object destructor is not called, so clear object manually
191       anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0);
192       anIter->second->GetUnstructuredGrid()->SetPoints(0);
193     }
194     VISUAL_OBJ_CONT.clear();
195   }
196
197   //================================================================================
198   /*!
199    * \brief Remove all VisualObjs of a study
200    */
201   //================================================================================
202
203   void RemoveVisuData(int studyID)
204   {
205     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
206       ( SUIT_Session::session()->activeApplication() );
207     if (!app) return;
208     ViewManagerList viewMgrs = app->viewManagers();
209     for ( int iM = 0; iM < viewMgrs.count(); ++iM ) {
210       SUIT_ViewManager* aViewManager = viewMgrs.at( iM );
211       if ( aViewManager && aViewManager->getType() == SVTK_Viewer::Type() &&
212            aViewManager->study()->id() == studyID ) {
213         QVector<SUIT_ViewWindow*> views = aViewManager->getViews();
214         for ( int iV = 0; iV < views.count(); ++iV ) {
215           if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV])) {
216             vtkRenderer *aRenderer = vtkWnd->getRenderer();
217             VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
218             vtkActorCollection *actors = aCopy.GetActors();
219             for (int i = 0; i < actors->GetNumberOfItems(); ++i ) {
220               // size of actors changes inside the loop
221               if(SMESH_Actor *actor = dynamic_cast<SMESH_Actor*>(actors->GetItemAsObject(i)))
222               {
223                 vtkWnd->RemoveActor(actor);
224                 actor->Delete();
225               }
226             }
227           }
228         }
229       }
230     }
231     TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.begin();
232     for ( ; anIter != VISUAL_OBJ_CONT.end(); ) {
233       int curId = anIter->first.first;
234       if ( curId == studyID ) {
235         // for unknown reason, object destructor is not called, so clear object manually
236         anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0);
237         anIter->second->GetUnstructuredGrid()->SetPoints(0);
238         VISUAL_OBJ_CONT.erase( anIter++ ); // anIter++ returns a copy of self before incrementing
239       }
240       else {
241         anIter++;
242       }
243     }
244   }
245
246   //================================================================================
247   /*!
248    * \brief Notify the user on problems during visualization
249    */
250   //================================================================================
251
252   void OnVisuException()
253   {
254     try {
255 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
256       OCC_CATCH_SIGNALS;
257 #endif
258       // PAL16774 (Crash after display of many groups). Salome sometimes crashes just
259       // after or at showing this message, so we do an additional check of available memory
260 //       char* buf = new char[100*1024];
261 //       delete [] buf;
262       SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"),
263                                QObject::tr("SMESH_VISU_PROBLEM"));
264     } catch (...) {
265       // no more memory at all: last resort
266       MESSAGE_BEGIN ( "SMESHGUI_VTKUtils::OnVisuException(), exception even at showing a message!!!" <<
267                       std::endl << "Try to remove all visual data..." );
268       if (theVISU_MemoryReserve) {
269         delete theVISU_MemoryReserve;
270         theVISU_MemoryReserve = 0;
271       }
272       RemoveAllObjectsWithActors();
273       SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"),
274                                QObject::tr("SMESH_VISU_PROBLEM_CLEAR"));
275       MESSAGE_END ( "...done" );
276     }
277   }
278   //================================================================================
279   /*!
280    * \brief Returns an updated visual object
281    */
282   //================================================================================
283
284   TVisualObjPtr GetVisualObj(int theStudyId, const char* theEntry, bool nulData){
285     TVisualObjPtr aVisualObj;
286     TVisualObjCont::key_type aKey(theStudyId,theEntry);
287     try{
288 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
289       OCC_CATCH_SIGNALS;
290 #endif
291       TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.find(aKey);
292       if(anIter != VISUAL_OBJ_CONT.end()){
293         aVisualObj = anIter->second;
294       }else{
295         SalomeApp_Application* app =
296           dynamic_cast<SalomeApp_Application*>( SMESHGUI::activeStudy()->application() );
297         _PTR(Study) aStudy = SMESHGUI::activeStudy()->studyDS();
298         _PTR(SObject) aSObj = aStudy->FindObjectID(theEntry);
299         if(aSObj){
300           _PTR(GenericAttribute) anAttr;
301           if(aSObj->FindAttribute(anAttr,"AttributeIOR")){
302             _PTR(AttributeIOR) anIOR = anAttr;
303             CORBA::String_var aVal = anIOR->Value().c_str();
304             CORBA::Object_var anObj = app->orb()->string_to_object( aVal.in() );
305             if(!CORBA::is_nil(anObj)){
306               //Try narrow to SMESH_Mesh interface
307               SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObj);
308               if(!aMesh->_is_nil()){
309                 aVisualObj.reset(new SMESH_MeshObj(aMesh));
310                 TVisualObjCont::value_type aValue(aKey,aVisualObj);
311                 VISUAL_OBJ_CONT.insert(aValue);
312               }
313               //Try narrow to SMESH_Group interface
314               SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObj);
315               if(!aGroup->_is_nil()){
316                 _PTR(SObject) aFatherSObj = aSObj->GetFather();
317                 if(!aFatherSObj) return aVisualObj;
318                 aFatherSObj = aFatherSObj->GetFather();
319                 if(!aFatherSObj) return aVisualObj;
320                 CORBA::String_var anEntry = aFatherSObj->GetID().c_str();
321                 TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in());
322                 if(SMESH_MeshObj* aMeshObj = dynamic_cast<SMESH_MeshObj*>(aVisObj.get())){
323                   aVisualObj.reset(new SMESH_GroupObj(aGroup,aMeshObj));
324                   TVisualObjCont::value_type aValue(aKey,aVisualObj);
325                   VISUAL_OBJ_CONT.insert(aValue);
326                 }
327               }
328               //Try narrow to SMESH_subMesh interface
329               SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(anObj);
330               if(!aSubMesh->_is_nil()){
331                 _PTR(SObject) aFatherSObj = aSObj->GetFather();
332                 if(!aFatherSObj) return aVisualObj;
333                 aFatherSObj = aFatherSObj->GetFather();
334                 if(!aFatherSObj) return aVisualObj;
335                 CORBA::String_var anEntry = aFatherSObj->GetID().c_str();
336                 TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in());
337                 if(SMESH_MeshObj* aMeshObj = dynamic_cast<SMESH_MeshObj*>(aVisObj.get())){
338                   aVisualObj.reset(new SMESH_subMeshObj(aSubMesh,aMeshObj));
339                   TVisualObjCont::value_type aValue(aKey,aVisualObj);
340                   VISUAL_OBJ_CONT.insert(aValue);
341                 }
342               }
343             }
344           }
345         }
346       }
347     }catch(...){
348       INFOS("GetMeshObj - There is no SMESH_Mesh object for the SALOMEDS::Strudy and Entry!!!");
349       return TVisualObjPtr();
350     }
351     // Update object
352     bool objModified = false;
353     if ( aVisualObj ) {
354       try {
355 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
356         OCC_CATCH_SIGNALS;
357 #endif
358         //MESSAGE("GetVisualObj");
359         if (nulData)
360                 objModified = aVisualObj->NulData();
361         else
362           objModified = aVisualObj->Update();
363       }
364       catch (...) {
365 #ifdef _DEBUG_
366         MESSAGE ( "Exception in SMESHGUI_VTKUtils::GetVisualObj()" );
367 #endif
368         RemoveVisualObjectWithActors( theEntry ); // remove this object
369         OnVisuException();
370         aVisualObj.reset();
371       }
372     }
373
374     if ( objModified ) {
375       // PAL16631. Mesurements showed that to show aVisualObj in SHADING(default) mode,
376       // ~10 times more memory is used than it occupies.
377       // Warn the user if there is less free memory than 30 sizes of a grid
378       // TODO: estimate memory usage in other modes and take current mode into account
379       int freeMB = SMDS_Mesh::CheckMemory(true);
380       int usedMB = aVisualObj->GetUnstructuredGrid()->GetActualMemorySize() / 1024;
381       if ( freeMB > 0 && usedMB * 30 > freeMB ) {
382 #ifdef _DEBUG_
383         MESSAGE ( "SMESHGUI_VTKUtils::GetVisualObj(), freeMB=" << freeMB
384                << ", usedMB=" << usedMB );
385 #endif
386 //        bool continu = false;
387 //        if ( usedMB * 10 > freeMB )
388 //          // even dont try to show
389 //          SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"),
390 //                                   QObject::tr("SMESH_NO_MESH_VISUALIZATION"));
391 //        else
392 //          // there is a chance to succeed
393 //          continu = SUIT_MessageBox::warning
394 //            (SMESHGUI::desktop(),
395 //             QObject::tr("SMESH_WRN_WARNING"),
396 //             QObject::tr("SMESH_CONTINUE_MESH_VISUALIZATION"),
397 //             SUIT_MessageBox::Yes | SUIT_MessageBox::No,
398 //             SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes;
399 //        if ( !continu ) {
400 //          // remove the corresponding actors from all views
401 //          RemoveVisualObjectWithActors( theEntry );
402 //          aVisualObj.reset();
403 //        }
404       }
405     }
406
407     return aVisualObj;
408   }
409
410
411   /*! Return active view window, if it instantiates SVTK_ViewWindow class,
412    *  overwise find or create corresponding view window, make it active and return it.
413    *  \note Active VVTK_ViewWindow can be returned, because it inherits SVTK_ViewWindow.
414    */
415   SVTK_ViewWindow* GetViewWindow (const SalomeApp_Module* theModule,
416                                   bool createIfNotFound)
417   {
418     SalomeApp_Application* anApp;
419     if (theModule)
420       anApp = theModule->getApp();
421     else
422       anApp = dynamic_cast<SalomeApp_Application*>
423         (SUIT_Session::session()->activeApplication());
424
425     if (anApp) {
426       if (SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(anApp->desktop()->activeWindow()))
427         return aView;
428
429       SUIT_ViewManager* aViewManager =
430         anApp->getViewManager(SVTK_Viewer::Type(), createIfNotFound);
431       if (aViewManager) {
432         if (SUIT_ViewWindow* aViewWindow = aViewManager->getActiveView()) {
433           if (SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(aViewWindow)) {
434             aViewWindow->raise();
435             aViewWindow->setFocus();
436             return aView;
437           }
438         }
439       }
440     }
441     return NULL;
442   }
443
444   SVTK_ViewWindow* FindVtkViewWindow (SUIT_ViewManager* theMgr,
445                                       SUIT_ViewWindow * theWindow)
446   {
447     if( !theMgr )
448       return NULL;
449
450     QVector<SUIT_ViewWindow*> views = theMgr->getViews();
451     if( views.contains( theWindow ) )
452       return GetVtkViewWindow( theWindow );
453     else
454       return NULL;
455   }
456
457   SVTK_ViewWindow* GetVtkViewWindow(SUIT_ViewWindow* theWindow){
458     return dynamic_cast<SVTK_ViewWindow*>(theWindow);
459   }
460
461 /*  SUIT_ViewWindow* GetActiveWindow()
462   {
463     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
464     if( !app )
465       return NULL;
466     SUIT_ViewManager* mgr = app->activeViewManager();
467     if( mgr )
468       return mgr->getActiveView();
469     else
470       return NULL;
471   }*/
472
473   SVTK_ViewWindow* GetCurrentVtkView(){
474     return GetVtkViewWindow( GetActiveWindow() );
475   }
476
477
478   void RepaintCurrentView()
479   {
480     if (SVTK_ViewWindow* wnd = GetCurrentVtkView())
481     {
482       try {
483 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
484         OCC_CATCH_SIGNALS;
485 #endif
486         wnd->getRenderer()->Render();
487         wnd->Repaint(false);
488       }
489       catch (...) {
490 #ifdef _DEBUG_
491         MESSAGE ( "Exception in SMESHGUI_VTKUtils::RepaintCurrentView()" );
492 #endif
493         OnVisuException();
494       }
495     }
496   }
497
498   void RepaintViewWindow(SVTK_ViewWindow* theWindow)
499   {
500     try {
501 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
502       OCC_CATCH_SIGNALS;
503 #endif
504       theWindow->getRenderer()->Render();
505       theWindow->Repaint();
506     }
507     catch (...) {
508 #ifdef _DEBUG_
509       MESSAGE ( "Exception in SMESHGUI_VTKUtils::RepaintViewWindow(SVTK_ViewWindow*)" );
510 #endif
511       OnVisuException();
512     }
513   }
514
515   void RenderViewWindow(SVTK_ViewWindow* theWindow)
516   {
517     try {
518 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
519       OCC_CATCH_SIGNALS;
520 #endif
521       theWindow->getRenderer()->Render();
522       theWindow->Repaint();
523     }
524     catch (...) {
525 #ifdef _DEBUG_
526       MESSAGE ( "Exception in SMESHGUI_VTKUtils::RenderViewWindow(SVTK_ViewWindow*)" );
527 #endif
528       OnVisuException();
529     }
530   }
531
532   void FitAll(){
533     if(SVTK_ViewWindow* wnd = GetCurrentVtkView() ){
534       try {
535 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
536         OCC_CATCH_SIGNALS;
537 #endif
538         wnd->onFitAll();
539         wnd->Repaint();
540       }
541       catch (...) {
542 #ifdef _DEBUG_
543         MESSAGE ( "Exception in SMESHGUI_VTKUtils::FitAll()" );
544 #endif
545         OnVisuException();
546       }
547     }
548   }
549
550
551   SMESH_Actor* FindActorByEntry(SUIT_ViewWindow *theWindow,
552                                 const char* theEntry)
553   {
554     if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWindow)){
555       vtkRenderer *aRenderer = aViewWindow->getRenderer();
556       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
557       vtkActorCollection *aCollection = aCopy.GetActors();
558       aCollection->InitTraversal();
559       while(vtkActor *anAct = aCollection->GetNextActor()){
560         if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
561           if(anActor->hasIO()){
562             Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
563             if(anIO->hasEntry() && strcmp(anIO->getEntry(),theEntry) == 0){
564               return anActor;
565             }
566           }
567         }
568       }
569     }
570     return NULL;
571   }
572
573
574   SMESH_Actor* FindActorByEntry(const char* theEntry){
575     return FindActorByEntry(GetActiveWindow(),theEntry);
576   }
577
578
579   SMESH_Actor* FindActorByObject(CORBA::Object_ptr theObject){
580     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
581     if( !app )
582       return NULL;
583
584     if(!CORBA::is_nil(theObject)){
585       _PTR(Study) aStudy = GetActiveStudyDocument();
586       CORBA::String_var anIOR = app->orb()->object_to_string( theObject );
587       _PTR(SObject) aSObject = aStudy->FindObjectIOR(anIOR.in());
588       if(aSObject){
589         CORBA::String_var anEntry = aSObject->GetID().c_str();
590         return FindActorByEntry(anEntry.in());
591       }
592     }
593     return NULL;
594   }
595
596
597   SMESH_Actor* CreateActor(_PTR(Study) theStudy,
598                            const char* theEntry,
599                            int theIsClear)
600   {
601     SMESH_Actor *anActor = NULL;
602     CORBA::Long anId = theStudy->StudyId();
603     if(TVisualObjPtr aVisualObj = GetVisualObj(anId,theEntry)){
604       _PTR(SObject) aSObj = theStudy->FindObjectID(theEntry);
605       if(aSObj){
606         _PTR(GenericAttribute) anAttr;
607         if(aSObj->FindAttribute(anAttr,"AttributeName")){
608           _PTR(AttributeName) aName = anAttr;
609           std::string aNameVal = aName->Value();
610           anActor = SMESH_Actor::New(aVisualObj,theEntry,aNameVal.c_str(),theIsClear);
611         }
612
613         SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SMESH::SObjectToObject( aSObj ));
614         if(!CORBA::is_nil(aGroup) && anActor)
615         {
616           SALOMEDS::Color aColor = aGroup->GetColor();
617           if( !( aColor.R > 0 || aColor.G > 0 || aColor.B > 0 ) )
618           {
619             int r = 0, g = 0, b = 0;
620             SMESH::GetColor( "SMESH", "fill_color", r, g, b, QColor( 0, 170, 255 ) );
621             aColor.R = (float)r / 255.0;
622             aColor.G = (float)g / 255.0;
623             aColor.B = (float)b / 255.0;
624             aGroup->SetColor( aColor );
625           }
626           if( aGroup->GetType() == SMESH::NODE )
627             anActor->SetNodeColor( aColor.R, aColor.G, aColor.B );
628           else if( aGroup->GetType() == SMESH::EDGE )
629             anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B );
630           else if( aGroup->GetType() == SMESH::ELEM0D )
631             anActor->Set0DColor( aColor.R, aColor.G, aColor.B );
632           else
633             anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B );
634         }
635       }
636     }
637     MESSAGE("CreateActor " << anActor);
638     if( anActor )
639       if( SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI() )
640         aSMESHGUI->addActorAsObserver( anActor );
641     return anActor;
642   }
643
644
645   void DisplayActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){
646     if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){
647       try {
648 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
649         OCC_CATCH_SIGNALS;
650 #endif
651         MESSAGE("DisplayActor " << theActor);
652         vtkWnd->AddActor(theActor);
653         vtkWnd->Repaint();
654       }
655       catch (...) {
656 #ifdef _DEBUG_
657         MESSAGE ( "Exception in SMESHGUI_VTKUtils::DisplayActor()" );
658 #endif
659         OnVisuException();
660       }
661     }
662   }
663
664
665   void RemoveActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){
666     if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){
667         MESSAGE("RemoveActor " << theActor);
668       vtkWnd->RemoveActor(theActor);
669       if(theActor->hasIO()){
670         Handle(SALOME_InteractiveObject) anIO = theActor->getIO();
671         if(anIO->hasEntry()){
672           std::string anEntry = anIO->getEntry();
673           SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( vtkWnd->getViewManager()->study() );
674           int aStudyId = aStudy->id();
675           TVisualObjCont::key_type aKey(aStudyId,anEntry);
676           VISUAL_OBJ_CONT.erase(aKey);
677         }
678       }
679       theActor->Delete();
680       vtkWnd->Repaint();
681     }
682   }
683
684   //================================================================================
685   /*!
686    * \brief Return true if there are no SMESH actors in a view
687    */
688   //================================================================================
689
690   bool noSmeshActors(SUIT_ViewWindow *theWnd)
691   {
692     if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWnd)) {
693       vtkRenderer *aRenderer = aViewWindow->getRenderer();
694       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
695       vtkActorCollection *aCollection = aCopy.GetActors();
696       aCollection->InitTraversal();
697       while(vtkActor *anAct = aCollection->GetNextActor())
698         if(dynamic_cast<SMESH_Actor*>(anAct))
699           return false;
700     }
701     return true;
702   }
703
704   bool UpdateView(SUIT_ViewWindow *theWnd, EDisplaing theAction, const char* theEntry)
705   {
706         //MESSAGE("UpdateView");
707     bool OK = false;
708     SVTK_ViewWindow* aViewWnd = GetVtkViewWindow(theWnd);
709     if (!aViewWnd)
710       return OK;
711
712     SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd);
713     if (!vtkWnd)
714       return OK;
715
716     SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( vtkWnd->getViewManager()->study() );
717     
718     if (!aStudy)
719       return OK;
720
721     {
722       OK = true;
723       vtkRenderer *aRenderer = aViewWnd->getRenderer();
724       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
725       vtkActorCollection *aCollection = aCopy.GetActors();
726       aCollection->InitTraversal();
727
728       switch (theAction) {
729       case eDisplayAll: {
730         while (vtkActor *anAct = aCollection->GetNextActor()) {
731           if (SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)) {
732                 MESSAGE("--- display " << anActor);
733             anActor->SetVisibility(true);
734
735             if(anActor->hasIO()){
736               Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
737               if(anIO->hasEntry()){
738                 aStudy->setVisibilityState(anIO->getEntry(), Qtx::ShownState);
739               }
740             }
741           }
742         }
743         break;
744       }
745       case eDisplayOnly:
746       case eEraseAll: {
747         //MESSAGE("---case eDisplayOnly");
748         while (vtkActor *anAct = aCollection->GetNextActor()) {
749           if (SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)) {
750                 //MESSAGE("--- erase " << anActor);
751             anActor->SetVisibility(false);
752           }
753         }
754         aStudy->setVisibilityStateForAll(Qtx::HiddenState);
755       }
756       default: {
757         if (SMESH_Actor *anActor = FindActorByEntry(theWnd,theEntry)) {
758           switch (theAction) {
759             case eDisplay:
760             case eDisplayOnly:
761                 //MESSAGE("--- display " << anActor);
762               anActor->Update();
763               anActor->SetVisibility(true);
764               if (theAction == eDisplayOnly) aRenderer->ResetCameraClippingRange();
765               aStudy->setVisibilityState(theEntry, Qtx::ShownState);
766               break;
767             case eErase:
768                 //MESSAGE("--- erase " << anActor);
769               anActor->SetVisibility(false);
770               aStudy->setVisibilityState(theEntry, Qtx::HiddenState);
771               break;
772           }
773         } else {
774           switch (theAction) {
775           case eDisplay:
776           case eDisplayOnly:
777             {
778                 //MESSAGE("---");
779               SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(theWnd->getViewManager()->study());
780               _PTR(Study) aDocument = aStudy->studyDS();
781               // Pass non-visual objects (hypotheses, etc.), return true in this case
782               CORBA::Long anId = aDocument->StudyId();
783               TVisualObjPtr aVisualObj;
784               if ( (aVisualObj = GetVisualObj(anId,theEntry)) && aVisualObj->IsValid())
785               {
786                 if ((anActor = CreateActor(aDocument,theEntry,true))) {
787                   bool needFitAll = noSmeshActors(theWnd); // fit for the first object only
788                   DisplayActor(theWnd,anActor);
789                   aStudy->setVisibilityState(theEntry, Qtx::ShownState);
790                   // FitAll(); - PAL16770(Display of a group performs an automatic fit all)
791                   if (needFitAll) FitAll();
792                 } else {
793                   OK = false;
794                 }
795               }
796               break;
797             }
798           }
799         }
800       }
801       }
802     }
803     return OK;
804   }
805
806
807   bool UpdateView(EDisplaing theAction, const char* theEntry){
808         //MESSAGE("UpdateView");
809     SalomeApp_Study* aStudy = dynamic_cast< SalomeApp_Study* >( GetActiveStudy() );
810     SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( aStudy->application() );
811     SUIT_ViewWindow *aWnd = app->activeViewManager()->getActiveView();
812     return UpdateView(aWnd,theAction,theEntry);
813   }
814
815   void UpdateView(){
816     if(SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView()){
817       LightApp_SelectionMgr* mgr = SMESHGUI::selectionMgr();
818       SALOME_ListIO selected; mgr->selectedObjects( selected );
819
820       if( selected.Extent() == 0){
821         vtkRenderer* aRenderer = aWnd->getRenderer();
822         VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
823         vtkActorCollection *aCollection = aCopy.GetActors();
824         aCollection->InitTraversal();
825         while(vtkActor *anAct = aCollection->GetNextActor()){
826           if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
827             if(anActor->hasIO())
828               if (!Update(anActor->getIO(),anActor->GetVisibility()))
829                 break; // avoid multiple warinings if visu failed
830           }
831         }
832       }else{
833         SALOME_ListIteratorOfListIO anIter( selected );
834         for( ; anIter.More(); anIter.Next()){
835           Handle(SALOME_InteractiveObject) anIO = anIter.Value();
836           if ( !Update(anIO,true) )
837             break; // avoid multiple warinings if visu failed
838         }
839       }
840       RepaintCurrentView();
841     }
842   }
843
844
845   bool Update(const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay)
846   {
847         MESSAGE("Update");
848     _PTR(Study) aStudy = GetActiveStudyDocument();
849     CORBA::Long anId = aStudy->StudyId();
850     if ( TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry())) {
851       if ( theDisplay )
852         UpdateView(SMESH::eDisplay,theIO->getEntry());
853       return true;
854     }
855     return false;
856   }
857
858   bool UpdateNulData(const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay)
859   {
860         MESSAGE("UpdateNulData");
861     _PTR(Study) aStudy = GetActiveStudyDocument();
862     CORBA::Long anId = aStudy->StudyId();
863     if ( TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry(), true)) {
864       if ( theDisplay )
865         UpdateView(SMESH::eDisplay,theIO->getEntry());
866       return true;
867     }
868     return false;
869   }
870
871   void UpdateSelectionProp( SMESHGUI* theModule ) {
872     if( !theModule )
873       return;
874
875     SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( theModule->application() );
876     if( !app )
877     {
878       MESSAGE( "UpdateSelectionProp: Application is null" );
879       return;
880     }
881
882     SUIT_ViewManager* vm = app->activeViewManager();
883     if( !vm )
884     {
885       MESSAGE( "UpdateSelectionProp: View manager is null" );
886       return;
887     }
888
889     QVector<SUIT_ViewWindow*> views = vm->getViews();
890
891     SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( theModule );
892     if( !mgr )
893     {
894       MESSAGE( "UpdateSelectionProp: Resource manager is null" );
895       return;
896     }
897
898     QColor aHiColor = mgr->colorValue( "SMESH", "selection_object_color", Qt::white ),
899            aSelColor = mgr->colorValue( "SMESH", "selection_element_color", Qt::yellow ),
900            aPreColor = mgr->colorValue( "SMESH", "highlight_color", Qt::cyan );
901
902     int SW = mgr->integerValue( "SMESH", "selection_width", 5 ),
903         PW = mgr->integerValue( "SMESH", "highlight_width", 5 );
904
905     // adjust highlight_width to the width of mesh entities
906     int aElem0DSize = mgr->integerValue("SMESH", "elem0d_size", 5);
907     int aLineWidth  = mgr->integerValue("SMESH", "element_width", 1);
908     int maxSize = aElem0DSize;
909     if (aElem0DSize > maxSize) maxSize = aElem0DSize;
910     if (aLineWidth > maxSize) maxSize = aLineWidth;
911     if (PW < maxSize + 2) PW = maxSize + 2;
912
913     double SP1 = mgr->doubleValue( "SMESH", "selection_precision_node", 0.025 ),
914            SP2 = mgr->doubleValue( "SMESH", "selection_precision_element", 0.001 ),
915            SP3 = mgr->doubleValue( "SMESH", "selection_precision_object", 0.025 );
916
917     for ( int i=0, n=views.count(); i<n; i++ ){
918       // update VTK viewer properties
919       if(SVTK_ViewWindow* aVtkView = GetVtkViewWindow( views[i] )){
920         // mesh element selection
921         aVtkView->SetSelectionProp(aSelColor.red()/255.,
922                                    aSelColor.green()/255.,
923                                    aSelColor.blue()/255.,
924                                    SW );
925         // tolerances
926         aVtkView->SetSelectionTolerance(SP1, SP2, SP3);
927
928         // pre-selection
929         aVtkView->SetPreselectionProp(aPreColor.red()/255.,
930                                       aPreColor.green()/255.,
931                                       aPreColor.blue()/255.,
932                                       PW);
933         // update actors
934         vtkRenderer* aRenderer = aVtkView->getRenderer();
935         VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
936         vtkActorCollection *aCollection = aCopy.GetActors();
937         aCollection->InitTraversal();
938         while(vtkActor *anAct = aCollection->GetNextActor()){
939           if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
940             anActor->SetHighlightColor(aHiColor.red()/255.,
941                                        aHiColor.green()/255.,
942                                        aHiColor.blue()/255.);
943             anActor->SetPreHighlightColor(aPreColor.red()/255.,
944                                           aPreColor.green()/255.,
945                                           aPreColor.blue()/255.);
946           }
947         }
948       }
949     }
950   }
951
952
953   //----------------------------------------------------------------------------
954   SVTK_Selector*
955   GetSelector(SUIT_ViewWindow *theWindow)
956   {
957     if(SVTK_ViewWindow* aWnd = GetVtkViewWindow(theWindow))
958       return aWnd->GetSelector();
959
960     return NULL;
961   }
962
963   void SetFilter(const Handle(VTKViewer_Filter)& theFilter,
964                  SVTK_Selector* theSelector)
965   {
966     if (theSelector)
967       theSelector->SetFilter(theFilter);
968   }
969
970   Handle(VTKViewer_Filter) GetFilter(int theId, SVTK_Selector* theSelector)
971   {
972     return theSelector->GetFilter(theId);
973   }
974
975   bool IsFilterPresent(int theId, SVTK_Selector* theSelector)
976   {
977     return theSelector->IsFilterPresent(theId);
978   }
979
980   void RemoveFilter(int theId, SVTK_Selector* theSelector)
981   {
982     theSelector->RemoveFilter(theId);
983   }
984
985   void RemoveFilters(SVTK_Selector* theSelector)
986   {
987     for ( int id = SMESH::NodeFilter; theSelector && id < SMESH::LastFilter; id++ )
988       theSelector->RemoveFilter( id );
989   }
990
991   bool IsValid(SALOME_Actor* theActor, int theCellId,
992                SVTK_Selector* theSelector)
993   {
994     return theSelector->IsValid(theActor,theCellId);
995   }
996
997
998   //----------------------------------------------------------------------------
999   void SetPointRepresentation(bool theIsVisible){
1000     if(SVTK_ViewWindow* aViewWindow = GetCurrentVtkView()){
1001       vtkRenderer *aRenderer = aViewWindow->getRenderer();
1002       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
1003       vtkActorCollection *aCollection = aCopy.GetActors();
1004       aCollection->InitTraversal();
1005       while(vtkActor *anAct = aCollection->GetNextActor()){
1006         if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
1007           if(anActor->GetVisibility()){
1008             anActor->SetPointRepresentation(theIsVisible);
1009           }
1010         }
1011       }
1012       RepaintCurrentView();
1013     }
1014   }
1015
1016
1017   void SetPickable(SMESH_Actor* theActor){
1018     if(SVTK_ViewWindow* aWnd = GetCurrentVtkView()){
1019       int anIsAllPickable = (theActor == NULL);
1020       vtkRenderer *aRenderer = aWnd->getRenderer();
1021       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
1022       vtkActorCollection *aCollection = aCopy.GetActors();
1023       aCollection->InitTraversal();
1024       while(vtkActor *anAct = aCollection->GetNextActor()){
1025         if(SALOME_Actor *anActor = dynamic_cast<SALOME_Actor*>(anAct)){
1026           if(anActor->GetVisibility()){
1027             anActor->SetPickable(anIsAllPickable);
1028           }
1029         }
1030       }
1031       if(theActor)
1032         theActor->SetPickable(!anIsAllPickable);
1033       RepaintCurrentView();
1034     }
1035   }
1036
1037
1038   //----------------------------------------------------------------------------
1039   int GetNameOfSelectedNodes(SVTK_Selector* theSelector,
1040                              const Handle(SALOME_InteractiveObject)& theIO,
1041                              QString& theName)
1042   {
1043     theName = "";
1044     TColStd_IndexedMapOfInteger aMapIndex;
1045     theSelector->GetIndex(theIO,aMapIndex);
1046
1047     for(int i = 1; i <= aMapIndex.Extent(); i++)
1048       theName += QString(" %1").arg(aMapIndex(i));
1049
1050     return aMapIndex.Extent();
1051   }
1052
1053   int GetNameOfSelectedElements(SVTK_Selector* theSelector,
1054                                 const Handle(SALOME_InteractiveObject)& theIO,
1055                                 QString& theName)
1056   {
1057     theName = "";
1058     TColStd_IndexedMapOfInteger aMapIndex;
1059     theSelector->GetIndex(theIO,aMapIndex);
1060
1061     typedef std::set<int> TIdContainer;
1062     TIdContainer anIdContainer;
1063     for( int i = 1; i <= aMapIndex.Extent(); i++)
1064       anIdContainer.insert(aMapIndex(i));
1065
1066     TIdContainer::const_iterator anIter = anIdContainer.begin();
1067     for( ; anIter != anIdContainer.end(); anIter++)
1068       theName += QString(" %1").arg(*anIter);
1069
1070     return aMapIndex.Extent();
1071   }
1072
1073
1074   int GetEdgeNodes(SVTK_Selector* theSelector,
1075                    const TVisualObjPtr& theVisualObject,
1076                    int& theId1,
1077                    int& theId2)
1078   {
1079     const SALOME_ListIO& selected = theSelector->StoredIObjects();
1080
1081     if ( selected.Extent() != 1 )
1082       return -1;
1083
1084     Handle(SALOME_InteractiveObject) anIO = selected.First();
1085     if ( anIO.IsNull() || !anIO->hasEntry() )
1086       return -1;
1087
1088     TColStd_IndexedMapOfInteger aMapIndex;
1089     theSelector->GetIndex( anIO, aMapIndex );
1090     if ( aMapIndex.Extent() != 2 )
1091       return -1;
1092
1093     int anObjId = -1, anEdgeNum = -1;
1094     for ( int i = 1; i <= aMapIndex.Extent(); i++ ) {
1095       int aVal = aMapIndex( i );
1096       if ( aVal > 0 )
1097         anObjId = aVal;
1098       else
1099         anEdgeNum = abs( aVal ) - 1;
1100     }
1101
1102     if ( anObjId == -1 || anEdgeNum == -1 )
1103       return -1;
1104
1105     return theVisualObject->GetEdgeNodes( anObjId, anEdgeNum, theId1, theId2 ) ? 1 : -1;
1106   }
1107
1108   //----------------------------------------------------------------------------
1109   int GetNameOfSelectedNodes(LightApp_SelectionMgr *theMgr,
1110                              const Handle(SALOME_InteractiveObject)& theIO,
1111                              QString& theName)
1112   {
1113     theName = "";
1114     if(theIO->hasEntry()){
1115       if(FindActorByEntry(theIO->getEntry())){
1116         TColStd_IndexedMapOfInteger aMapIndex;
1117         theMgr->GetIndexes(theIO,aMapIndex);
1118         for(int i = 1; i <= aMapIndex.Extent(); i++){
1119           theName += QString(" %1").arg(aMapIndex(i));
1120         }
1121         return aMapIndex.Extent();
1122       }
1123     }
1124     return -1;
1125   }
1126
1127   int GetNameOfSelectedNodes(LightApp_SelectionMgr *theMgr, QString& theName){
1128     theName = "";
1129     SALOME_ListIO selected; theMgr->selectedObjects( selected );
1130     if(selected.Extent() == 1){
1131       Handle(SALOME_InteractiveObject) anIO = selected.First();
1132       return GetNameOfSelectedNodes(theMgr,anIO,theName);
1133     }
1134     return -1;
1135   }
1136
1137
1138   int GetNameOfSelectedElements(LightApp_SelectionMgr *theMgr,
1139                                 const Handle(SALOME_InteractiveObject)& theIO,
1140                                 QString& theName)
1141   {
1142     theName = "";
1143     if(theIO->hasEntry()){
1144       if(FindActorByEntry(theIO->getEntry())){
1145         TColStd_IndexedMapOfInteger aMapIndex;
1146         theMgr->GetIndexes(theIO,aMapIndex);
1147         typedef std::set<int> TIdContainer;
1148         TIdContainer anIdContainer;
1149         for( int i = 1; i <= aMapIndex.Extent(); i++)
1150           anIdContainer.insert(aMapIndex(i));
1151         TIdContainer::const_iterator anIter = anIdContainer.begin();
1152         for( ; anIter != anIdContainer.end(); anIter++){
1153           theName += QString(" %1").arg(*anIter);
1154         }
1155         return aMapIndex.Extent();
1156       }
1157     }
1158     return -1;
1159   }
1160
1161
1162   int GetNameOfSelectedElements(LightApp_SelectionMgr *theMgr, QString& theName)
1163   {
1164     theName = "";
1165     SALOME_ListIO selected; theMgr->selectedObjects( selected );
1166
1167     if( selected.Extent() == 1){
1168       Handle(SALOME_InteractiveObject) anIO = selected.First();
1169       return GetNameOfSelectedElements(theMgr,anIO,theName);
1170     }
1171     return -1;
1172   }
1173
1174   int GetSelected(LightApp_SelectionMgr*       theMgr,
1175                   TColStd_IndexedMapOfInteger& theMap,
1176                   const bool                   theIsElement)
1177   {
1178     theMap.Clear();
1179     SALOME_ListIO selected; theMgr->selectedObjects( selected );
1180
1181     if ( selected.Extent() == 1 )
1182     {
1183       Handle(SALOME_InteractiveObject) anIO = selected.First();
1184       if ( anIO->hasEntry() ) {
1185         theMgr->GetIndexes( anIO, theMap );
1186       }
1187     }
1188     return theMap.Extent();
1189   }
1190
1191
1192   int GetEdgeNodes( LightApp_SelectionMgr* theMgr, int& theId1, int& theId2 )
1193   {
1194     SALOME_ListIO selected; theMgr->selectedObjects( selected );
1195
1196     if ( selected.Extent() != 1 )
1197       return -1;
1198
1199     Handle(SALOME_InteractiveObject) anIO = selected.First();
1200     if ( anIO.IsNull() || !anIO->hasEntry() )
1201       return -1;
1202
1203     SMESH_Actor *anActor = SMESH::FindActorByEntry( anIO->getEntry() );
1204     if ( anActor == 0 )
1205       return -1;
1206
1207     TColStd_IndexedMapOfInteger aMapIndex;
1208     theMgr->GetIndexes( anIO, aMapIndex );
1209     if ( aMapIndex.Extent() != 2 )
1210       return -1;
1211
1212     int anObjId = -1, anEdgeNum = -1;
1213     for ( int i = 1; i <= aMapIndex.Extent(); i++ ) {
1214       int aVal = aMapIndex( i );
1215       if ( aVal > 0 )
1216         anObjId = aVal;
1217       else
1218         anEdgeNum = abs( aVal );
1219     }
1220
1221     if ( anObjId == -1 || anEdgeNum == -1 )
1222       return -1;
1223
1224     return anActor->GetObject()->GetEdgeNodes( anObjId, anEdgeNum, theId1, theId2 ) ? 1 : -1;
1225   }
1226
1227   void SetControlsPrecision( const long theVal )
1228   {
1229     if( SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView() )
1230     {
1231       vtkRenderer *aRenderer = aWnd->getRenderer();
1232       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
1233       vtkActorCollection *aCollection = aCopy.GetActors();
1234       aCollection->InitTraversal();
1235
1236       while ( vtkActor *anAct = aCollection->GetNextActor())
1237       {
1238         if ( SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>( anAct ) )
1239         {
1240           anActor->SetControlsPrecision( theVal );
1241           anActor->SetControlMode( anActor->GetControlMode() );
1242         }
1243       }
1244
1245     }
1246   }
1247
1248   //----------------------------------------------------------------------------
1249   // internal function
1250   void ComputeBoundsParam( vtkFloatingPointType theBounds[6],
1251                            vtkFloatingPointType theDirection[3],
1252                            vtkFloatingPointType theMinPnt[3],
1253                            vtkFloatingPointType& theMaxBoundPrj,
1254                            vtkFloatingPointType& theMinBoundPrj )
1255   {
1256     //Enlarge bounds in order to avoid conflicts of precision
1257     for(int i = 0; i < 6; i += 2){
1258       static double EPS = 1.0E-3;
1259       vtkFloatingPointType aDelta = (theBounds[i+1] - theBounds[i])*EPS;
1260       theBounds[i] -= aDelta;
1261       theBounds[i+1] += aDelta;
1262     }
1263
1264     vtkFloatingPointType aBoundPoints[8][3] = { {theBounds[0],theBounds[2],theBounds[4]},
1265                                                 {theBounds[1],theBounds[2],theBounds[4]},
1266                                                 {theBounds[0],theBounds[3],theBounds[4]},
1267                                                 {theBounds[1],theBounds[3],theBounds[4]},
1268                                                 {theBounds[0],theBounds[2],theBounds[5]},
1269                                                 {theBounds[1],theBounds[2],theBounds[5]}, 
1270                                                 {theBounds[0],theBounds[3],theBounds[5]}, 
1271                                                 {theBounds[1],theBounds[3],theBounds[5]}};
1272
1273     int aMaxId = 0, aMinId = aMaxId;
1274     theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]);
1275     theMinBoundPrj = theMaxBoundPrj;
1276     for(int i = 1; i < 8; i++){
1277       vtkFloatingPointType aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]);
1278       if(theMaxBoundPrj < aTmp){
1279         theMaxBoundPrj = aTmp;
1280         aMaxId = i;
1281       }
1282       if(theMinBoundPrj > aTmp){
1283         theMinBoundPrj = aTmp;
1284         aMinId = i;
1285       }
1286     }
1287     vtkFloatingPointType *aMinPnt = aBoundPoints[aMaxId];
1288     theMinPnt[0] = aMinPnt[0];
1289     theMinPnt[1] = aMinPnt[1];
1290     theMinPnt[2] = aMinPnt[2];
1291   }
1292
1293   // internal function
1294   void DistanceToPosition( vtkFloatingPointType theBounds[6],
1295                            vtkFloatingPointType theDirection[3],
1296                            vtkFloatingPointType theDist,
1297                            vtkFloatingPointType thePos[3] )
1298   {
1299     vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
1300     ComputeBoundsParam(theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
1301     vtkFloatingPointType aLength = (aMaxBoundPrj-aMinBoundPrj)*theDist;
1302     thePos[0] = aMinPnt[0]-theDirection[0]*aLength;
1303     thePos[1] = aMinPnt[1]-theDirection[1]*aLength;
1304     thePos[2] = aMinPnt[2]-theDirection[2]*aLength;
1305   }
1306
1307   // internal function (currently unused, left just in case)
1308   void PositionToDistance( vtkFloatingPointType theBounds[6],
1309                            vtkFloatingPointType theDirection[3],
1310                            vtkFloatingPointType thePos[3],
1311                            vtkFloatingPointType& theDist )
1312   {
1313     vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
1314     ComputeBoundsParam(theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
1315     vtkFloatingPointType aPrj = vtkMath::Dot(theDirection,thePos);
1316     theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj);
1317   }
1318
1319   bool ComputeClippingPlaneParameters( std::list<vtkActor*> theActorList,
1320                                        vtkFloatingPointType theNormal[3],
1321                                        vtkFloatingPointType theDist,
1322                                        vtkFloatingPointType theBounds[6],
1323                                        vtkFloatingPointType theOrigin[3] )
1324   {
1325     bool anIsOk = false;
1326     theBounds[0] = theBounds[2] = theBounds[4] = VTK_DOUBLE_MAX;
1327     theBounds[1] = theBounds[3] = theBounds[5] = -VTK_DOUBLE_MAX;
1328     std::list<vtkActor*>::iterator anIter = theActorList.begin();
1329     for( ; anIter != theActorList.end(); anIter++ ) {
1330       if( vtkActor* aVTKActor = *anIter ) {
1331         if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) {
1332           vtkFloatingPointType aBounds[6];
1333           anActor->GetUnstructuredGrid()->GetBounds( aBounds );
1334           theBounds[0] = std::min( theBounds[0], aBounds[0] );
1335           theBounds[1] = std::max( theBounds[1], aBounds[1] );
1336           theBounds[2] = std::min( theBounds[2], aBounds[2] );
1337           theBounds[3] = std::max( theBounds[3], aBounds[3] );
1338           theBounds[4] = std::min( theBounds[4], aBounds[4] );
1339           theBounds[5] = std::max( theBounds[5], aBounds[5] );
1340           anIsOk = true;
1341         }
1342       }
1343     }
1344
1345     if( !anIsOk )
1346       return false;
1347
1348     DistanceToPosition( theBounds, theNormal, theDist, theOrigin );
1349     return true;
1350   }
1351
1352 #ifndef DISABLE_PLOT2DVIEWER
1353   //================================================================================
1354   /*!
1355    * \brief Find all SMESH_Actor's in the View Window.
1356    * If actor constains Plot2d_Histogram object remove it from each Plot2d Viewer.
1357    */
1358   //================================================================================
1359
1360   void ClearPlot2Viewers( SUIT_ViewWindow* theWindow ) {
1361     if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWindow)){
1362       vtkRenderer *aRenderer = aViewWindow->getRenderer();
1363       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
1364       vtkActorCollection *aCollection = aCopy.GetActors();
1365       aCollection->InitTraversal();
1366       while(vtkActor *anAct = aCollection->GetNextActor()){
1367         if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
1368           if(anActor->hasIO() && anActor->GetPlot2Histogram() ){
1369             ProcessIn2DViewers(anActor,RemoveFrom2dViewer);
1370           }
1371         }
1372       }
1373     }
1374   }
1375   
1376 #endif
1377
1378 } // end of namespace SMESH