Salome HOME
Join modifications from branch BR_DEBUG_3_2_0b1
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_VTKUtils.cxx
1 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 //
4 //  This library is free software; you can redistribute it and/or
5 //  modify it under the terms of the GNU Lesser General Public
6 //  License as published by the Free Software Foundation; either
7 //  version 2.1 of the License.
8 //
9 //  This library is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 //  Lesser General Public License for more details.
13 //
14 //  You should have received a copy of the GNU Lesser General Public
15 //  License along with this library; if not, write to the Free Software
16 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19
20
21 #include "SMESHGUI_VTKUtils.h"
22 #include "SMESHGUI_Utils.h"
23 #include "SMESHGUI_Filter.h"
24
25 #include <vtkRenderer.h>
26 #include <vtkActorCollection.h>
27
28 #include <TColStd_IndexedMapOfInteger.hxx>
29
30 #include <SUIT_Desktop.h>
31 #include <SUIT_Session.h>
32 #include <SUIT_Study.h>
33
34 #include "LightApp_SelectionMgr.h"
35
36 #include "SVTK_Selector.h"
37 #include "SVTK_ViewModel.h"
38 #include "SVTK_ViewWindow.h"
39
40 #include "utilities.h"
41
42 #include "SALOMEconfig.h"
43 #include CORBA_CLIENT_HEADER(SMESH_Gen)
44 #include CORBA_CLIENT_HEADER(SMESH_Mesh)
45 #include CORBA_CLIENT_HEADER(SMESH_Group)
46 #include CORBA_CLIENT_HEADER(SMESH_Hypothesis)
47
48 #include "SMESHGUI.h"
49 #include "SMESH_Actor.h"
50 #include "SMESH_ObjectDef.h"
51
52 #include <SalomeApp_Application.h>
53 #include <LightApp_SelectionMgr.h>
54 #include <SalomeApp_Study.h>
55
56 #include <SALOMEDSClient_Study.hxx>
57 #include <SALOMEDSClient_SObject.hxx>
58
59 #include <SALOME_ListIO.hxx>
60 #include <SALOME_ListIteratorOfListIO.hxx>
61
62 #include <set>
63 using namespace std;
64
65 namespace SMESH{
66
67   typedef map<TKeyOfVisualObj,TVisualObjPtr> TVisualObjCont;
68   static TVisualObjCont VISUAL_OBJ_CONT;
69
70   TVisualObjPtr GetVisualObj(int theStudyId, const char* theEntry){
71     TVisualObjPtr aVisualObj;
72     try{
73       TVisualObjCont::key_type aKey(theStudyId,theEntry);
74       TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.find(aKey);
75       if(anIter != VISUAL_OBJ_CONT.end()){
76         aVisualObj = anIter->second;
77       }else{
78         SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SMESHGUI::activeStudy()->application() );
79         _PTR(Study) aStudy = SMESHGUI::activeStudy()->studyDS();
80         _PTR(SObject) aSObj = aStudy->FindObjectID(theEntry);
81         if(aSObj){
82           _PTR(GenericAttribute) anAttr;
83           if(aSObj->FindAttribute(anAttr,"AttributeIOR")){
84             _PTR(AttributeIOR) anIOR = anAttr;
85             CORBA::String_var aVal = anIOR->Value().c_str();
86             CORBA::Object_var anObj = app->orb()->string_to_object( aVal.in() );
87             if(!CORBA::is_nil(anObj)){
88               //Try narrow to SMESH_Mesh interafce
89               SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObj);
90               if(!aMesh->_is_nil()){
91                 aVisualObj.reset(new SMESH_MeshObj(aMesh));
92                 aVisualObj->Update();
93                 TVisualObjCont::value_type aValue(aKey,aVisualObj);
94                 VISUAL_OBJ_CONT.insert(aValue);
95                 return aVisualObj;
96               }
97               //Try narrow to SMESH_Group interafce
98               SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObj);
99               if(!aGroup->_is_nil()){
100                 _PTR(SObject) aFatherSObj = aSObj->GetFather();
101                 if(!aFatherSObj) return aVisualObj;
102                 aFatherSObj = aFatherSObj->GetFather();
103                 if(!aFatherSObj) return aVisualObj;
104                 CORBA::String_var anEntry = aFatherSObj->GetID().c_str();
105                 TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in());
106                 if(SMESH_MeshObj* aMeshObj = dynamic_cast<SMESH_MeshObj*>(aVisObj.get())){
107                   aVisualObj.reset(new SMESH_GroupObj(aGroup,aMeshObj));
108                   aVisualObj->Update();
109                   TVisualObjCont::value_type aValue(aKey,aVisualObj);
110                   VISUAL_OBJ_CONT.insert(aValue);
111                   return aVisualObj;
112                 }
113               }
114               //Try narrow to SMESH_subMesh interafce
115               SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(anObj);
116               if(!aSubMesh->_is_nil()){
117                 _PTR(SObject) aFatherSObj = aSObj->GetFather();
118                 if(!aFatherSObj) return aVisualObj;
119                 aFatherSObj = aFatherSObj->GetFather();
120                 if(!aFatherSObj) return aVisualObj;
121                 CORBA::String_var anEntry = aFatherSObj->GetID().c_str();
122                 TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in());
123                 if(SMESH_MeshObj* aMeshObj = dynamic_cast<SMESH_MeshObj*>(aVisObj.get())){
124                   aVisualObj.reset(new SMESH_subMeshObj(aSubMesh,aMeshObj));
125                   aVisualObj->Update();
126                   TVisualObjCont::value_type aValue(aKey,aVisualObj);
127                   VISUAL_OBJ_CONT.insert(aValue);
128                   return aVisualObj;
129                 }
130               }
131             }
132           }
133         }
134       }
135     }catch(...){
136       INFOS("GetMeshObj - There is no SMESH_Mesh object for the SALOMEDS::Strudy and Entry!!!");
137     }
138     return aVisualObj;
139   }
140
141
142   SVTK_ViewWindow*
143   GetViewWindow(const SalomeApp_Module* theModule)
144   {
145     if (SalomeApp_Application* anApp = theModule->getApp())
146       return dynamic_cast<SVTK_ViewWindow*>(anApp->desktop()->activeWindow());
147     return NULL;
148   }
149
150   SVTK_ViewWindow* FindVtkViewWindow( SUIT_ViewManager* theMgr,
151                                            SUIT_ViewWindow* theWindow )
152   {
153     if( !theMgr )
154       return NULL;
155
156     QPtrVector<SUIT_ViewWindow> views = theMgr->getViews();
157     if( views.containsRef( theWindow ) )
158       return GetVtkViewWindow( theWindow );
159     else
160       return NULL;
161   }
162
163
164   SVTK_ViewWindow* GetVtkViewWindow(SUIT_ViewWindow* theWindow){
165     return dynamic_cast<SVTK_ViewWindow*>(theWindow);
166   }
167
168
169 /*  SUIT_ViewWindow* GetActiveWindow()
170   {
171     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
172     if( !app )
173       return NULL;
174     SUIT_ViewManager* mgr = app->activeViewManager();
175     if( mgr )
176       return mgr->getActiveView();
177     else
178       return NULL;
179   }*/
180
181   SVTK_ViewWindow* GetCurrentVtkView(){
182     return GetVtkViewWindow( GetActiveWindow() );
183   }
184
185   void RepaintViewWindow(SVTK_ViewWindow* theWindow)
186   {
187     theWindow->Repaint();
188   }
189
190   void RenderViewWindow(SVTK_ViewWindow* theWindow)
191   {
192     theWindow->getRenderer()->Render();
193     theWindow->Repaint();
194   }
195
196   SMESH_Actor* FindActorByEntry(SUIT_ViewWindow *theWindow,
197                                 const char* theEntry)
198   {
199     if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWindow)){
200       vtkRenderer *aRenderer = aViewWindow->getRenderer();
201       vtkActorCollection *aCollection = aRenderer->GetActors();
202       aCollection->InitTraversal();
203       while(vtkActor *anAct = aCollection->GetNextActor()){
204         if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
205           if(anActor->hasIO()){
206             Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
207             if(anIO->hasEntry() && strcmp(anIO->getEntry(),theEntry) == 0){
208               return anActor;
209             }
210           }
211         }
212       }
213     }
214     return NULL;
215   }
216
217
218   SMESH_Actor* FindActorByEntry(const char* theEntry){
219     return FindActorByEntry(GetActiveWindow(),theEntry);
220   }
221
222
223   SMESH_Actor* FindActorByObject(CORBA::Object_ptr theObject){
224     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
225     if( !app )
226       return NULL;
227
228     if(!CORBA::is_nil(theObject)){
229       _PTR(Study) aStudy = GetActiveStudyDocument();
230       CORBA::String_var anIOR = app->orb()->object_to_string( theObject );
231       _PTR(SObject) aSObject = aStudy->FindObjectIOR(anIOR.in());
232       if(aSObject){
233         CORBA::String_var anEntry = aSObject->GetID().c_str();
234         return FindActorByEntry(anEntry.in());
235       }
236     }
237     return NULL;
238   }
239
240
241   SMESH_Actor* CreateActor(_PTR(Study) theStudy,
242                            const char* theEntry,
243                            int theIsClear)
244   {
245     SMESH_Actor *anActor = NULL;
246     CORBA::Long anId = theStudy->StudyId();
247     if(TVisualObjPtr aVisualObj = GetVisualObj(anId,theEntry)){
248       _PTR(SObject) aSObj = theStudy->FindObjectID(theEntry);
249       if(aSObj){
250         _PTR(GenericAttribute) anAttr;
251         if(aSObj->FindAttribute(anAttr,"AttributeName")){
252           _PTR(AttributeName) aName = anAttr;
253           std::string aNameVal = aName->Value();
254           anActor = SMESH_Actor::New(aVisualObj,theEntry,aNameVal.c_str(),theIsClear);
255         }
256       }
257     }
258     return anActor;
259   }
260
261
262   void DisplayActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){
263     if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){
264       vtkWnd->AddActor(theActor);
265       vtkWnd->Repaint();
266     }
267   }
268
269
270   void RemoveActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){
271     if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){
272       vtkWnd->RemoveActor(theActor);
273       if(theActor->hasIO()){
274         Handle(SALOME_InteractiveObject) anIO = theActor->getIO();
275         if(anIO->hasEntry()){
276           std::string anEntry = anIO->getEntry();
277           SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( vtkWnd->getViewManager()->study() );
278           int aStudyId = aStudy->id();
279           TVisualObjCont::key_type aKey(aStudyId,anEntry);
280           VISUAL_OBJ_CONT.erase(aKey);
281         }
282       }
283       theActor->Delete();
284       vtkWnd->Repaint();
285     }
286   }
287
288
289   void FitAll(){
290     if(SVTK_ViewWindow* wnd = GetCurrentVtkView() ){
291       wnd->onFitAll();
292       wnd->Repaint();
293     }
294   }
295
296   vtkRenderer* GetCurrentRenderer(){
297     if(SVTK_ViewWindow* wnd = GetCurrentVtkView() )
298       return wnd->getRenderer();
299     return NULL;
300   }
301
302   void RepaintCurrentView(){
303     if(SVTK_ViewWindow* wnd = GetCurrentVtkView() )
304       {
305         wnd->getRenderer()->Render();
306         wnd->Repaint(false);
307       }
308   }
309
310   void UpdateView(SUIT_ViewWindow *theWnd, EDisplaing theAction, const char* theEntry)
311   {
312     if(SVTK_ViewWindow* aViewWnd = GetVtkViewWindow(theWnd)){
313       vtkRenderer *aRenderer = aViewWnd->getRenderer();
314       vtkActorCollection *aCollection = aRenderer->GetActors();
315       aCollection->InitTraversal();
316       switch(theAction){
317       case eDisplayAll: {
318         while(vtkActor *anAct = aCollection->GetNextActor()){
319           if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
320             anActor->SetVisibility(true);
321           }
322         }
323         break;
324       }
325       case eDisplayOnly:
326       case eEraseAll: {
327         while(vtkActor *anAct = aCollection->GetNextActor()){
328           if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
329             anActor->SetVisibility(false);
330           }
331         }
332       }
333       default: {
334         if(SMESH_Actor *anActor = FindActorByEntry(theWnd,theEntry)){
335           switch(theAction) {
336             case eDisplay:
337             case eDisplayOnly:
338               anActor->SetVisibility(true);
339               break;
340             case eErase:
341               anActor->SetVisibility(false);
342               break;
343           }
344         } else {
345           switch(theAction){
346           case eDisplay:
347           case eDisplayOnly:{
348             SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( theWnd->getViewManager()->study() );
349             _PTR(Study) aDocument = aStudy->studyDS();
350             if((anActor = CreateActor(aDocument,theEntry,true))) {
351               DisplayActor(theWnd,anActor);
352               FitAll();
353             }
354             break;
355           }
356           }
357         }
358       }
359       }
360     }
361   }
362
363
364   void UpdateView(EDisplaing theAction, const char* theEntry){
365     SalomeApp_Study* aStudy = dynamic_cast< SalomeApp_Study* >( GetActiveStudy() );
366     SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( aStudy->application() );
367     SUIT_ViewWindow *aWnd = app->activeViewManager()->getActiveView();
368     UpdateView(aWnd,theAction,theEntry);
369   }
370
371   void UpdateView(){
372     if(SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView()){
373       LightApp_SelectionMgr* mgr = SMESHGUI::selectionMgr();
374       SALOME_ListIO selected; mgr->selectedObjects( selected );
375
376       if( selected.Extent() == 0){
377         vtkRenderer* aRenderer = aWnd->getRenderer();
378         vtkActorCollection *aCollection = aRenderer->GetActors();
379         aCollection->InitTraversal();
380         while(vtkActor *anAct = aCollection->GetNextActor()){
381           if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
382             if(anActor->hasIO())
383               Update(anActor->getIO(),anActor->GetVisibility());
384           }
385         }
386       }else{
387         SALOME_ListIteratorOfListIO anIter( selected );
388         for(; anIter.More(); anIter.Next()){
389           Handle(SALOME_InteractiveObject) anIO = anIter.Value();
390           Update(anIO,true);
391         }
392       }
393       RepaintCurrentView();
394     }
395   }
396
397
398   void Update(const Handle(SALOME_InteractiveObject)& theIO,
399               bool theDisplay)
400   {
401     _PTR(Study) aStudy = GetActiveStudyDocument();
402     CORBA::Long anId = aStudy->StudyId();
403     TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry());
404     if( aVisualObj )
405       aVisualObj->Update();
406     if ( theDisplay )
407       UpdateView(SMESH::eDisplay,theIO->getEntry());
408   }
409
410
411   void UpdateSelectionProp( SMESHGUI* theModule ) {
412     if( !theModule )
413       return;
414
415     SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( theModule->application() );
416     if( !app )
417     {
418       MESSAGE( "UpdateSelectionProp: Application is null" );
419       return;
420     }
421
422     SUIT_ViewManager* vm = app->activeViewManager();
423     if( !vm )
424     {
425       MESSAGE( "UpdateSelectionProp: View manager is null" );
426       return;
427     }
428
429     QPtrVector<SUIT_ViewWindow> views = vm->getViews();
430
431     SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( theModule );
432     if( !mgr )
433     {
434       MESSAGE( "UpdateSelectionProp: Resource manager is null" );
435       return;
436     }
437
438     QColor aHiColor = mgr->colorValue( "SMESH", "selection_object_color", Qt::white ),
439            aSelColor = mgr->colorValue( "SMESH", "selection_element_color", Qt::yellow ),
440            aPreColor = mgr->colorValue( "SMESH", "highlight_color", Qt::cyan );
441
442     int SW = mgr->integerValue( "SMESH", "selection_width", 5 ),
443         PW = mgr->integerValue( "SMESH", "highlight_width", 5 );
444
445     double SP1 = mgr->doubleValue( "SMESH", "selection_precision_node", 0.025 ),
446            SP2 = mgr->doubleValue( "SMESH", "selection_precision_element", 0.001 );
447
448     for ( int i=0, n=views.count(); i<n; i++ ){
449       // update VTK viewer properties
450       if(SVTK_ViewWindow* aVtkView = GetVtkViewWindow( views[i] )){
451         // mesh element selection
452         aVtkView->SetSelectionProp(aSelColor.red()/255., 
453                                    aSelColor.green()/255.,
454                                    aSelColor.blue()/255., 
455                                    SW );
456         // tolerances
457         aVtkView->SetSelectionTolerance(SP1, SP2);
458
459         // pre-selection
460         aVtkView->SetPreselectionProp(aPreColor.red()/255., 
461                                       aPreColor.green()/255.,
462                                       aPreColor.blue()/255., 
463                                       PW);
464         // update actors
465         vtkRenderer* aRenderer = aVtkView->getRenderer();
466         vtkActorCollection *aCollection = aRenderer->GetActors();
467         aCollection->InitTraversal();
468         while(vtkActor *anAct = aCollection->GetNextActor()){
469           if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
470             anActor->SetHighlightColor(aHiColor.red()/255., 
471                                        aHiColor.green()/255.,
472                                        aHiColor.blue()/255.);
473             anActor->SetPreHighlightColor(aPreColor.red()/255., 
474                                           aPreColor.green()/255.,
475                                           aPreColor.blue()/255.);
476           }
477         }
478       }
479     }
480   }
481
482
483   //----------------------------------------------------------------------------
484   SVTK_Selector* 
485   GetSelector(SUIT_ViewWindow *theWindow)
486   {
487     if(SVTK_ViewWindow* aWnd = GetVtkViewWindow(theWindow))
488       return aWnd->GetSelector();
489
490     return NULL;
491   }
492
493   void SetFilter(const Handle(VTKViewer_Filter)& theFilter,
494                  SVTK_Selector* theSelector)
495   {
496     if (theSelector)
497       theSelector->SetFilter(theFilter);
498   }
499
500   Handle(VTKViewer_Filter) GetFilter(int theId, SVTK_Selector* theSelector)
501   {
502     return theSelector->GetFilter(theId);
503   }
504
505   bool IsFilterPresent(int theId, SVTK_Selector* theSelector)
506   {
507     return theSelector->IsFilterPresent(theId);
508   }
509
510   void RemoveFilter(int theId, SVTK_Selector* theSelector)
511   {
512     theSelector->RemoveFilter(theId);
513   }
514
515   void RemoveFilters(SVTK_Selector* theSelector)
516   {
517     for ( int id = SMESHGUI_NodeFilter; theSelector && id < SMESHGUI_LastFilter; id++ )
518       theSelector->RemoveFilter( id );
519   }
520
521   bool IsValid(SALOME_Actor* theActor, int theCellId,
522                SVTK_Selector* theSelector)
523   {
524     return theSelector->IsValid(theActor,theCellId);
525   }
526
527
528   //----------------------------------------------------------------------------
529   void SetPointRepresentation(bool theIsVisible){
530     if(SVTK_ViewWindow* aViewWindow = GetCurrentVtkView()){
531       vtkRenderer *aRenderer = aViewWindow->getRenderer();
532       vtkActorCollection *aCollection = aRenderer->GetActors();
533       aCollection->InitTraversal();
534       while(vtkActor *anAct = aCollection->GetNextActor()){
535         if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
536           if(anActor->GetVisibility()){
537             anActor->SetPointRepresentation(theIsVisible);
538           }
539         }
540       }
541       RepaintCurrentView();
542     }
543   }
544
545
546   void SetPickable(SMESH_Actor* theActor){
547     if(SVTK_ViewWindow* aWnd = GetCurrentVtkView()){
548       int anIsAllPickable = (theActor == NULL);
549       vtkRenderer *aRenderer = aWnd->getRenderer();
550       vtkActorCollection *aCollection = aRenderer->GetActors();
551       aCollection->InitTraversal();
552       while(vtkActor *anAct = aCollection->GetNextActor()){
553         if(SALOME_Actor *anActor = dynamic_cast<SALOME_Actor*>(anAct)){
554           if(anActor->GetVisibility()){
555             anActor->SetPickable(anIsAllPickable);
556           }
557         }
558       }
559       if(theActor)
560         theActor->SetPickable(!anIsAllPickable);
561       RepaintCurrentView();
562     }
563   }
564
565
566   //----------------------------------------------------------------------------
567   int GetNameOfSelectedNodes(SVTK_Selector* theSelector,
568                              const Handle(SALOME_InteractiveObject)& theIO,
569                              QString& theName)
570   {
571     theName = "";
572     TColStd_IndexedMapOfInteger aMapIndex;
573     theSelector->GetIndex(theIO,aMapIndex);
574
575     for(int i = 1; i <= aMapIndex.Extent(); i++)
576       theName += QString(" %1").arg(aMapIndex(i));
577
578     return aMapIndex.Extent();
579   }
580
581   int GetNameOfSelectedElements(SVTK_Selector* theSelector,
582                                 const Handle(SALOME_InteractiveObject)& theIO,
583                                 QString& theName)
584   {
585     theName = "";
586     TColStd_IndexedMapOfInteger aMapIndex;
587     theSelector->GetIndex(theIO,aMapIndex);
588
589     typedef std::set<int> TIdContainer;
590     TIdContainer anIdContainer;
591     for( int i = 1; i <= aMapIndex.Extent(); i++)
592       anIdContainer.insert(aMapIndex(i));
593
594     TIdContainer::const_iterator anIter = anIdContainer.begin();
595     for(; anIter != anIdContainer.end(); anIter++)
596       theName += QString(" %1").arg(*anIter);
597
598     return aMapIndex.Extent();
599   }
600
601
602   int GetEdgeNodes(SVTK_Selector* theSelector,
603                    const TVisualObjPtr& theVisualObject,
604                    int& theId1,
605                    int& theId2)
606   {
607     const SALOME_ListIO& selected = theSelector->StoredIObjects();
608
609     if ( selected.Extent() != 1 )
610       return -1;
611
612     Handle(SALOME_InteractiveObject) anIO = selected.First();
613     if ( anIO.IsNull() || !anIO->hasEntry() )
614       return -1;
615
616     TColStd_IndexedMapOfInteger aMapIndex;
617     theSelector->GetIndex( anIO, aMapIndex );
618     if ( aMapIndex.Extent() != 2 )
619       return -1;
620
621     int anObjId = -1, anEdgeNum = -1;
622     for ( int i = 1; i <= aMapIndex.Extent(); i++ ) {
623       int aVal = aMapIndex( i );
624       if ( aVal > 0 )
625         anObjId = aVal;
626       else
627         anEdgeNum = abs( aVal ) - 1;
628     }
629
630     if ( anObjId == -1 || anEdgeNum == -1 )
631       return -1;
632
633     return theVisualObject->GetEdgeNodes( anObjId, anEdgeNum, theId1, theId2 ) ? 1 : -1;
634   }
635
636   //----------------------------------------------------------------------------
637   int GetNameOfSelectedNodes(LightApp_SelectionMgr *theMgr,
638                              const Handle(SALOME_InteractiveObject)& theIO,
639                              QString& theName)
640   {
641     theName = "";
642     if(theIO->hasEntry()){
643       if(FindActorByEntry(theIO->getEntry())){
644         TColStd_IndexedMapOfInteger aMapIndex;
645         theMgr->GetIndexes(theIO,aMapIndex);
646         for(int i = 1; i <= aMapIndex.Extent(); i++){
647           theName += QString(" %1").arg(aMapIndex(i));
648         }
649         return aMapIndex.Extent();
650       }
651     }
652     return -1;
653   }
654
655   int GetNameOfSelectedNodes(LightApp_SelectionMgr *theMgr, QString& theName){
656     theName = "";
657     SALOME_ListIO selected; theMgr->selectedObjects( selected );
658     if(selected.Extent() == 1){
659       Handle(SALOME_InteractiveObject) anIO = selected.First();
660       return GetNameOfSelectedNodes(theMgr,anIO,theName);
661     }
662     return -1;
663   }
664
665
666   int GetNameOfSelectedElements(LightApp_SelectionMgr *theMgr,
667                                 const Handle(SALOME_InteractiveObject)& theIO,
668                                 QString& theName)
669   {
670     theName = "";
671     if(theIO->hasEntry()){
672       if(FindActorByEntry(theIO->getEntry())){
673         TColStd_IndexedMapOfInteger aMapIndex;
674         theMgr->GetIndexes(theIO,aMapIndex);
675         typedef set<int> TIdContainer;
676         TIdContainer anIdContainer;
677         for( int i = 1; i <= aMapIndex.Extent(); i++)
678           anIdContainer.insert(aMapIndex(i));
679         TIdContainer::const_iterator anIter = anIdContainer.begin();
680         for(; anIter != anIdContainer.end(); anIter++){
681           theName += QString(" %1").arg(*anIter);
682         }
683         return aMapIndex.Extent();
684       }
685     }
686     return -1;
687   }
688
689
690   int GetNameOfSelectedElements(LightApp_SelectionMgr *theMgr, QString& theName)
691   {
692     theName = "";
693     SALOME_ListIO selected; theMgr->selectedObjects( selected );
694
695     if( selected.Extent() == 1){
696       Handle(SALOME_InteractiveObject) anIO = selected.First();
697       return GetNameOfSelectedElements(theMgr,anIO,theName);
698     }
699     return -1;
700   }
701
702   int GetSelected(LightApp_SelectionMgr*       theMgr,
703                   TColStd_IndexedMapOfInteger& theMap,
704                   const bool                   theIsElement)
705   {
706     theMap.Clear();
707     SALOME_ListIO selected; theMgr->selectedObjects( selected );
708
709     if ( selected.Extent() == 1 )
710     {
711       Handle(SALOME_InteractiveObject) anIO = selected.First();
712       if ( anIO->hasEntry() ) {
713         theMgr->GetIndexes( anIO, theMap );
714       }
715     }
716     return theMap.Extent();
717   }
718
719
720   int GetEdgeNodes( LightApp_SelectionMgr* theMgr, int& theId1, int& theId2 )
721   {
722     SALOME_ListIO selected; theMgr->selectedObjects( selected );
723
724     if ( selected.Extent() != 1 )
725       return -1;
726
727     Handle(SALOME_InteractiveObject) anIO = selected.First();
728     if ( anIO.IsNull() || !anIO->hasEntry() )
729       return -1;
730
731     SMESH_Actor *anActor = SMESH::FindActorByEntry( anIO->getEntry() );
732     if ( anActor == 0 )
733       return -1;
734
735     TColStd_IndexedMapOfInteger aMapIndex;
736     theMgr->GetIndexes( anIO, aMapIndex );
737     if ( aMapIndex.Extent() != 2 )
738       return -1;
739
740     int anObjId = -1, anEdgeNum = -1;
741     for ( int i = 1; i <= aMapIndex.Extent(); i++ ) {
742       int aVal = aMapIndex( i );
743       if ( aVal > 0 )
744         anObjId = aVal;
745       else
746         anEdgeNum = abs( aVal );
747     }
748
749     if ( anObjId == -1 || anEdgeNum == -1 )
750       return -1;
751
752     return anActor->GetObject()->GetEdgeNodes( anObjId, anEdgeNum, theId1, theId2 ) ? 1 : -1;
753   }
754
755   void SetControlsPrecision( const long theVal )
756   {
757     if( SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView() )
758     {
759       vtkRenderer *aRenderer = aWnd->getRenderer();
760       vtkActorCollection *aCollection = aRenderer->GetActors();
761       aCollection->InitTraversal();
762
763       while ( vtkActor *anAct = aCollection->GetNextActor())
764       {
765         if ( SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>( anAct ) )
766         {
767           anActor->SetControlsPrecision( theVal );
768           anActor->SetControlMode( anActor->GetControlMode() );
769         }
770       }
771
772     }
773   }
774 }