Salome HOME
ENV: Windows porting.
[modules/geom.git] / src / GEOMGUI / GEOMGUI_OCCSelector.cxx
1 #include "GEOMGUI_OCCSelector.h"
2
3 #include <SalomeApp_DataSubOwner.h>
4
5 #include <OCCViewer_ViewModel.h>
6
7 #include <SALOME_InteractiveObject.hxx>
8
9 #include <AIS_ListOfInteractive.hxx>
10 #include <AIS_ListIteratorOfListOfInteractive.hxx>
11 #include <SelectMgr_EntityOwner.hxx>
12 #include <AIS_Shape.hxx>
13 #include <TopTools_IndexedMapOfShape.hxx>
14 #include <TopExp.hxx>
15 #include <SelectMgr_IndexedMapOfOwner.hxx>
16 #include <TColStd_ListIteratorOfListOfInteger.hxx>
17 #include <SelectMgr_Selection.hxx>
18 #include <SelectBasics_SensitiveEntity.hxx>
19 #include <TColStd_IndexedMapOfInteger.hxx>
20 #include <SelectMgr_IndexedMapOfOwner.hxx>
21 #include <NCollection_DataMap.hxx>
22
23
24 //================================================================
25 // Function : GEOMGUI_OCCSelector
26 // Purpose  : 
27 //================================================================
28 GEOMGUI_OCCSelector::GEOMGUI_OCCSelector( OCCViewer_Viewer* viewer, SUIT_SelectionMgr* mgr )
29 : SalomeApp_OCCSelector( viewer, mgr )
30 {
31 }
32
33 //================================================================
34 // Function : ~GEOMGUI_OCCSelector
35 // Purpose  : 
36 //================================================================
37 GEOMGUI_OCCSelector::~GEOMGUI_OCCSelector()
38 {
39 }
40
41 //================================================================
42 // Function : getSelection
43 // Purpose  : 
44 //================================================================
45 void GEOMGUI_OCCSelector::getSelection( SUIT_DataOwnerPtrList& aList ) const
46 {
47   OCCViewer_Viewer* vw = viewer();
48   if ( !vw )
49     return;
50
51   Handle(AIS_InteractiveContext) ic = vw->getAISContext();
52   
53   if ( ic->HasOpenedContext() )
54     {
55       for ( ic->InitSelected(); ic->MoreSelected(); ic->NextSelected() )
56         {
57           Handle(SelectMgr_EntityOwner) anOwner = ic->SelectedOwner();
58           if ( anOwner.IsNull() )
59             continue;
60           
61           Handle(AIS_InteractiveObject) io = Handle(AIS_InteractiveObject)::DownCast( anOwner->Selectable() );
62           
63           QString entryStr = entry( io );
64           int index = -1; 
65           
66           if ( anOwner->ComesFromDecomposition() ) // == Local Selection
67             {
68               TopoDS_Shape subShape = anOwner->Shape();
69               Handle(AIS_Shape) aisShape = Handle(AIS_Shape)::DownCast( io );
70               if ( !aisShape.IsNull() )
71                 {
72                   TopoDS_Shape bigShape = aisShape->Shape();
73                   
74                   TopTools_IndexedMapOfShape subShapes;
75                   TopExp::MapShapes( bigShape, subShapes );
76                   index = subShapes.FindIndex( subShape );
77                 }
78             }
79           
80           if ( !entryStr.isEmpty() )
81             {
82               SalomeApp_DataOwner* owner;
83               if ( index > -1 ) // Local Selection
84                 owner = new SalomeApp_DataSubOwner( entryStr, index );
85               else // Global Selection
86                 owner = new SalomeApp_DataOwner( entryStr );
87
88               aList.append( SUIT_DataOwnerPtr( owner ) );
89             }
90         }
91     }
92   else
93     {
94       for ( ic->InitCurrent(); ic->MoreCurrent(); ic->NextCurrent() )
95         {
96           Handle(AIS_InteractiveObject) io = ic->Current();
97           
98           QString entryStr = entry( io );
99           
100           if ( !entryStr.isEmpty() )
101             {
102               SalomeApp_DataOwner* owner = new SalomeApp_DataOwner( entryStr );
103               aList.append( SUIT_DataOwnerPtr( owner ) );
104             }
105         }
106     }
107 }
108
109 //================================================================
110 // Function : getEntityOwners
111 // Purpose  : 
112 //================================================================
113 static void getEntityOwners( const Handle(AIS_InteractiveObject)& theObj,
114                              const Handle(AIS_InteractiveContext)& theIC,
115                              SelectMgr_IndexedMapOfOwner& theMap )
116 {
117   if ( theObj.IsNull() || theIC.IsNull() )
118     return;
119
120   TColStd_ListOfInteger modes;
121   theIC->ActivatedModes( theObj, modes );
122
123   TColStd_ListIteratorOfListOfInteger itr( modes );
124   for (; itr.More(); itr.Next() ) {
125     int m = itr.Value();
126     if ( !theObj->HasSelection( m ) )
127       continue;
128
129     Handle(SelectMgr_Selection) sel = theObj->Selection( m );
130
131     for ( sel->Init(); sel->More(); sel->Next() ) {
132       Handle(SelectBasics_SensitiveEntity) entity = sel->Sensitive();
133       if ( entity.IsNull() )
134         continue;
135
136       Handle(SelectMgr_EntityOwner) owner =
137         Handle(SelectMgr_EntityOwner)::DownCast(entity->OwnerId());
138       if ( !owner.IsNull() )
139         theMap.Add( owner );
140     }
141   }
142 }
143
144 //================================================================
145 // Function : setSelection
146 // Purpose  : 
147 //================================================================
148 void GEOMGUI_OCCSelector::setSelection( const SUIT_DataOwnerPtrList& aList )
149 {
150   OCCViewer_Viewer* vw = viewer();
151   if ( !vw )
152     return;
153
154   Handle(AIS_InteractiveContext) ic = vw->getAISContext();
155
156 #ifndef WNT
157   NCollection_DataMap<TCollection_AsciiString, TColStd_IndexedMapOfInteger> indexesMap; // "entry - list_of_int" map for LOCAL selection
158 #else
159   NCollection_DataMap<Standard_CString, TColStd_IndexedMapOfInteger> indexesMap; // "entry - list_of_int" map for LOCAL selection
160 #endif
161   QMap<QString,int> globalSelMap; // only Key=entry from this map is used.  value(int) is NOT used at all.
162   SelectMgr_IndexedMapOfOwner ownersmap; // map of owners to be selected
163   
164   AIS_ListOfInteractive aDispList;
165   ic->DisplayedObjects( aDispList );
166
167   // build a map of data owner indexes to be selected.
168   // "entry - to - list_of_ids" map
169   for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr )
170   {
171     const SalomeApp_DataSubOwner* subOwner = dynamic_cast<const SalomeApp_DataSubOwner*>( (*itr).operator->() );
172     if ( subOwner )
173     {
174       QString entry = subOwner->entry();
175 #ifndef WNT
176       if ( indexesMap.IsBound( TCollection_AsciiString((char*)entry.latin1())))
177 #else
178           if ( indexesMap.IsBound( (char*)entry.latin1()))
179 #endif
180       {
181         TColStd_IndexedMapOfInteger& subIndexes = indexesMap.ChangeFind((char*)entry.latin1());
182         subIndexes.Add( subOwner->index() );
183         //indexesMap.replace( entry, subIndexes );
184       }
185       else
186       {
187         TColStd_IndexedMapOfInteger subIndexes;
188         subIndexes.Add( subOwner->index() );
189         indexesMap.Bind((char*)entry.latin1(), subIndexes);
190       }
191     } 
192     else // the owner is NOT a sub owner, maybe it is a DataOwner == GLOBAL selection
193     {
194       const SalomeApp_DataOwner* owner = dynamic_cast<const SalomeApp_DataOwner*>( (*itr).operator->() );
195       if ( owner )
196       {
197         globalSelMap[owner->entry()] = 1;
198       }
199     }
200   }
201
202   // get all owners.  Fill "entry - list_of_owners" map.
203   for ( AIS_ListIteratorOfListOfInteractive it( aDispList ); it.More(); it.Next() )
204   {
205     Handle(AIS_InteractiveObject) io = it.Value();
206     QString entryStr = entry( io );
207     if ( !entryStr.isEmpty() )
208     {
209       //EntryToListOfOwnerMap entryOwnersMap; // "entry - list_of_owners" map.  temporary use.
210       SelectMgr_IndexedMapOfOwner owners;
211       getEntityOwners( io, ic, owners ); // get all owners
212
213       for  ( int i = 1, n = owners.Extent(); i <= n; i++ ) 
214       {
215         Handle(SelectMgr_EntityOwner) anOwner = owners( i );
216         if ( anOwner.IsNull() || !anOwner->HasShape() )
217           continue;
218
219         // GLOBAL selection
220         if ( !anOwner->ComesFromDecomposition() && globalSelMap.contains( entryStr ) ) 
221         {
222           ownersmap.Add( anOwner );
223         }
224         // LOCAL selection
225         else
226         {
227           Handle(AIS_Shape) aisShape = Handle(AIS_Shape)::DownCast( io );
228
229           if ( !aisShape.IsNull() && indexesMap.IsBound( (char*)entryStr.latin1() ) )
230           {
231             TopoDS_Shape shape = aisShape->Shape();
232             TopTools_IndexedMapOfShape aMapOfShapes;
233             TopExp::MapShapes( shape, aMapOfShapes );
234             const TColStd_IndexedMapOfInteger& subIndexes = indexesMap.ChangeFind((char*)entryStr.latin1());
235
236             const TopoDS_Shape& aSubShape = anOwner->Shape();
237             int  aSubShapeId = aMapOfShapes.FindIndex( aSubShape );
238
239             // check if the "sub_shape_index" is found in the "map of indexes for this entry",
240             // which was passes in the parameter
241             if ( subIndexes.Contains( aSubShapeId ) )
242             {
243               ownersmap.Add( anOwner );
244             }
245           }
246         } // end of local selection
247       } // end of for(owners)
248     }// end of if(entry)
249   }// end of for(AIS_all_ios)
250
251   vw->unHighlightAll( false );
252
253   // DO the selection
254   for  ( int i = 1, n = ownersmap.Extent(); i <= n; i++ ) 
255   {
256     Handle(SelectMgr_EntityOwner) owner = ownersmap( i );
257     if ( owner->State() )
258       continue;
259
260     if ( ic->HasOpenedContext() )
261       ic->AddOrRemoveSelected( owner, false );
262     else
263       ic->AddOrRemoveSelected( Handle(AIS_InteractiveObject)::DownCast(owner->Selectable()), false );
264   }
265
266   vw->update();
267 }