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