Integration of OCCT 6.5.0 from SVN
[occt.git] / src / AIS / AIS_Selection.cxx
1 #include <AIS_Selection.ixx>
2 #include <TCollection_AsciiString.hxx>
3 #include <TColStd_SequenceOfTransient.hxx>
4
5 #define BUC60953   // SAV_050701 : the array of selected objects has always the same length
6                    // independently of number of objects selected. Thus, if there were selected
7                    // more than MaxSizeOfResult objects we have got an exception.
8                    // 
9                    // Moreover, Select method was optimized a little bit.
10                    // Now it checks the state of incoming owner. If the state is 0
11                    // there is no searching for object in <myresult> array.
12
13 #define OCC138
14
15 #define OCC189     //SAV: 18//03/02 array was replaced with list.
16
17 #define OCC1039    //SAV: 25/11/02 clearing selected objects if any on the AIS_Selection remove.
18
19 #define USE_MAP    //san : 18/04/03 USE_MAP - additional datamap is used to speed up access 
20                    //to certain owners in <myresult> list
21
22 #ifdef BUC60953
23 #include <SelectMgr_EntityOwner.hxx>
24 #endif
25
26 #ifdef OCC138      //VTN Avoding infinit loop in AddOrRemoveSelected and AddOrRemoveCurrentObject methods.
27 #include <AIS_InteractiveObject.hxx>
28 #endif
29
30 #ifndef USE_MAP
31 #define MaxSizeOfResult 10000
32 #else
33 #define MaxSizeOfResult 100000
34 #endif
35
36 // beurk mais moins qu''avant.... rob
37 static void AIS_Sel_CurrentSelection (Handle(AIS_Selection)& InputSel)     
38 {
39   static Handle(AIS_Selection) theCurrentSelection;
40   if(!InputSel.IsNull())
41     theCurrentSelection = InputSel;
42   else
43     InputSel = theCurrentSelection;
44 }
45
46 static TColStd_SequenceOfTransient&  AIS_Sel_GetSelections()
47 {
48   static TColStd_SequenceOfTransient Selections;
49   return Selections;
50 }
51
52 //=======================================================================
53 //function : AIS_Selection
54 //purpose  : 
55 //=======================================================================
56 AIS_Selection::AIS_Selection(const Standard_CString aName) :
57 myName(TCollection_AsciiString(aName)),
58 mycuri(0), 
59 #if !defined USE_MAP && !defined OCC189
60 myresult(new TColStd_HArray1OfTransient(1,MaxSizeOfResult)),
61 #endif
62 myNb(0)
63 {
64 #ifdef USE_MAP 
65   myResultMap.ReSize( MaxSizeOfResult ); // for maximum performnace on medium selections ( < 100000 objects )
66 #endif
67 }
68
69 //=======================================================================
70 //function : CreateSelection
71 //purpose  : 
72 //=======================================================================
73 Standard_Boolean AIS_Selection::CreateSelection(const Standard_CString aName)
74
75   Handle(AIS_Selection) S = AIS_Selection::Selection(aName);
76   if(!S.IsNull())
77     return Standard_False;
78   S = new AIS_Selection(aName);
79   AIS_Sel_GetSelections().Prepend(S);
80   AIS_Sel_CurrentSelection(S);
81   return Standard_True;
82 }
83
84
85 //=======================================================================
86 //function : Selection
87 //purpose  : 
88 //=======================================================================
89 Handle(AIS_Selection) AIS_Selection::Selection(const Standard_CString aName) 
90 {
91   Handle(AIS_Selection) S;
92   if(AIS_Sel_GetSelections().IsEmpty()) return S;
93   
94   Handle(Standard_Transient) curobj;
95   Handle(AIS_Selection) Sel;
96 //  Standard_Boolean found(Standard_False);
97   for(Standard_Integer I =1; I<= AIS_Sel_GetSelections().Length();I++){
98     curobj = AIS_Sel_GetSelections().Value(I);
99     Sel = *((Handle(AIS_Selection)*)&curobj);
100     if(Sel->myName.IsEqual(aName))
101       return Sel;
102   }
103   
104   return S;
105 }
106
107 //=======================================================================
108 //function : Find
109 //purpose  : 
110 //=======================================================================
111 Standard_Boolean AIS_Selection::Find(const Standard_CString aName) 
112 {
113   Handle(AIS_Selection) S = AIS_Selection::Selection(aName);
114   return !S.IsNull();
115 }
116
117 //=======================================================================
118 //function : SetCurrentSelection
119 //purpose  : 
120 //=======================================================================
121 Standard_Boolean AIS_Selection::SetCurrentSelection (const Standard_CString aName) 
122 {  
123   AIS_Selection::CreateSelection(aName); // juste pour voir... ?????????????
124
125
126   Handle(AIS_Selection) anAISSelection = AIS_Selection::Selection(aName) ;
127   AIS_Sel_CurrentSelection ( anAISSelection ) ;
128   return Standard_True;
129 }
130
131 //=======================================================================
132 //function : Select
133 //purpose  : 
134 //=======================================================================
135 void AIS_Selection::Select() 
136 {
137   Handle(AIS_Selection) S;
138   AIS_Sel_CurrentSelection (S);
139   if(!S.IsNull()){
140     S->myNb=0;
141 #if defined OCC189 || defined USE_MAP
142     S->myresult.Clear();
143 #ifdef USE_MAP
144     S->myResultMap.Clear();
145 #endif
146 #endif
147   }
148 }
149
150 //=======================================================================
151 //function : CurrentSelection
152 //purpose  : 
153 //=======================================================================
154 Handle(AIS_Selection) AIS_Selection::CurrentSelection() {
155   Handle(AIS_Selection) S;
156   AIS_Sel_CurrentSelection (S);
157   return S;
158 }
159 //=======================================================================
160 //function : Select
161 //purpose  : 
162 //=======================================================================
163 AIS_SelectStatus AIS_Selection::Select(const Handle(Standard_Transient)& anObject) 
164 {
165   Handle(AIS_Selection) S;
166   AIS_Sel_CurrentSelection (S);
167   if(S.IsNull()) return AIS_SS_NotDone;
168   Handle(AIS_InteractiveObject) anAISObj;
169   Handle(SelectMgr_EntityOwner) owner = Handle(SelectMgr_EntityOwner)::DownCast( anObject );
170   if ( owner.IsNull() )
171     anAISObj = Handle(AIS_InteractiveObject)::DownCast( anObject );
172 #ifndef OCC189
173   TColStd_Array1OfTransient& arr = S->myresult->ChangeArray1();
174   
175   Standard_Integer Found(-1);
176   Standard_Integer i ;
177
178 #ifdef BUC60953
179   
180   Standard_Boolean selected = Standard_False;
181   if ( !owner.IsNull() )
182     selected = owner->State() != 0;
183 #ifdef OCC138
184   else if(!anAISObj.IsNull())
185     selected = anAISObj->State();
186   }
187 #endif
188
189   if ( selected ) // looking up index of object
190 #endif
191
192   for( i=arr.Lower() && Found==-1;i<=S->myNb;i++){
193     if(arr(i)==anObject)
194       Found=i;
195   }
196   // Il n''est pas dedans, on le rajoute....
197
198 #ifdef BUC60953
199   if ( !selected || Found == -1 ) {
200 #else
201   if(Found==-1){
202 #endif  
203     if((S->myNb)+1>arr.Length()){
204       Handle(TColStd_HArray1OfTransient) NiouTab = new TColStd_HArray1OfTransient(1,arr.Length()+MaxSizeOfResult);
205       // oui bon, mais...
206       for(i=arr.Lower();i<=S->myNb;i++){
207         const Handle(Standard_Transient)& T = S->myresult->Value(i);
208         NiouTab->SetValue(i,T);
209       }
210 #ifdef BUC60953
211       S->myresult = NiouTab;
212 #endif
213     }
214     (S->myNb)++;
215     S->myresult->SetValue(S->myNb,anObject);
216     return AIS_SS_Added;
217   }
218   // il etait dedans on l''enleve...
219   for(i=Found;i<=S->myNb;i++)
220     arr(i)=arr(i+1);
221   S->myNb--;
222 #elif !defined USE_MAP //OCC189
223   AIS_NListTransient::Iterator anIter ( S->myresult );
224   for ( ; anIter.More(); anIter.Next() )
225     if ( anIter.Value() == anObject ) {
226       S->myresult.Remove( anIter );
227       return AIS_SS_Removed;
228     }
229       
230   S->myresult.Append( anObject );
231   return AIS_SS_Added;
232 #else //USE_MAP
233   if ( S->myResultMap.IsBound( anObject ) ){
234     AIS_NListTransient::Iterator aListIter = S->myResultMap.Find( anObject );
235 //skt-----------------------------------------------------------------
236     if( S->myIterator == aListIter )
237         if( S->myIterator.More() )
238             S->myIterator.Next();
239         else
240             S->myIterator = AIS_NListTransient::Iterator();
241 //--------------------------------------------------------------------
242 #ifdef BUC60953
243     // In the mode of advanced mesh selection only one owner is created
244     // for all selection modes. It is necessary to check the current detected
245     // entity and remove the owner from map only if the detected entity is
246     // the same as previous selected (IsForcedHilight call)
247     if( !anAISObj.IsNull() || ( !owner.IsNull() && !owner->IsForcedHilight() ) )
248     {
249 #endif  
250       S->myresult.Remove( aListIter );
251       S->myResultMap.UnBind( anObject );
252     
253       // update list iterator for next object in <myresult> list if any
254       if ( aListIter.More() ){
255         const Handle(Standard_Transient)& aNextObject = aListIter.Value();
256         if ( S->myResultMap.IsBound( aNextObject ) )
257           S->myResultMap( aNextObject ) = aListIter;
258         else
259           S->myResultMap.Bind( aNextObject, aListIter );
260       }
261       return AIS_SS_Removed;
262     }
263     else
264       return AIS_SS_Added;
265   }
266   
267   AIS_NListTransient::Iterator aListIter;
268   S->myresult.Append( anObject, aListIter );
269   S->myResultMap.Bind( anObject, aListIter );
270   return AIS_SS_Added;
271 #endif //USE_MAP
272   return AIS_SS_Removed;
273   
274 }
275
276 //=======================================================================
277 //function : AddSelect
278 //purpose  : Always add int the selection
279 //=======================================================================
280 AIS_SelectStatus AIS_Selection::AddSelect(const Handle(Standard_Transient)& anObject) 
281 {
282   Handle(AIS_Selection) S;
283   AIS_Sel_CurrentSelection (S);
284   if(S.IsNull()) return AIS_SS_NotDone;
285
286 #ifndef OCC189
287   TColStd_Array1OfTransient& arr = S->myresult->ChangeArray1();
288   Standard_Integer i;
289   if((S->myNb)+1>arr.Length()){
290       Handle(TColStd_HArray1OfTransient) NiouTab = new TColStd_HArray1OfTransient(1,arr.Length()+MaxSizeOfResult);
291       // oui bon, mais...
292       for(i=arr.Lower();i<=S->myNb;i++){
293         const Handle(Standard_Transient)& T = S->myresult->Value(i);
294         NiouTab->SetValue(i,T);
295       }
296       S->myresult = NiouTab;
297   }
298   (S->myNb)++;
299   S->myresult->SetValue(S->myNb,anObject);
300 #elif !defined USE_MAP //OCC189
301   S->myresult.Append( anObject );
302 #else //USE_MAP
303   if ( S->myResultMap.IsBound( anObject ) )
304     return AIS_SS_NotDone;
305       
306   AIS_NListTransient::Iterator aListIter;
307   S->myresult.Append( anObject, aListIter );
308   S->myResultMap.Bind( anObject, aListIter );
309 #endif
310   return AIS_SS_Added;
311 }
312
313
314 //=======================================================================
315 //function : ClearAndSelect
316 //purpose  : 
317 //=======================================================================
318
319 void AIS_Selection::ClearAndSelect(const Handle(Standard_Transient)& anObject) {
320   Handle(AIS_Selection) S;
321   AIS_Sel_CurrentSelection (S);
322   if(S.IsNull()) return;
323   
324   Select();
325   Select(anObject);
326
327 }
328
329
330 //=======================================================================
331 //function : Extent
332 //purpose  : 
333 //=======================================================================
334 Standard_Integer AIS_Selection::Extent() {
335   Handle(AIS_Selection) S;
336   AIS_Sel_CurrentSelection (S);
337 #if !defined OCC189 && !defined USE_MAP
338   return S->myNb;
339 #else
340   return S->myresult.Extent();
341 #endif
342 }
343
344 //=======================================================================
345 //function : Single
346 //purpose  : 
347 //=======================================================================
348 Handle(Standard_Transient)  AIS_Selection::Single() 
349 {
350   Handle(AIS_Selection) S;
351   AIS_Sel_CurrentSelection (S);
352   
353   S->Init();
354   return S->Value();
355 }
356 //=======================================================================
357 //function : IsSelected
358 //purpose  : 
359 //=======================================================================
360 Standard_Boolean AIS_Selection::IsSelected(const Handle(Standard_Transient)& anObject)
361 {
362   Handle(AIS_Selection) S;
363   AIS_Sel_CurrentSelection (S);
364   if(S.IsNull()) return Standard_False;
365 #ifndef USE_MAP  
366   for(S->Init();S->More();S->Next()){
367     if(S->Value()==anObject)
368       return Standard_True;
369   }
370   return Standard_False;
371 #else
372   return S->myResultMap.IsBound( anObject );
373 #endif
374 }
375
376 //=======================================================================
377 //function : Index
378 //purpose  : 
379 //=======================================================================
380
381 Standard_Integer AIS_Selection::Index(const Standard_CString aName)
382 {
383   Handle (Standard_Transient) curobj;
384   for(Standard_Integer I =1; I<= AIS_Sel_GetSelections().Length();I++){
385     curobj = AIS_Sel_GetSelections().Value(I);
386     if((*((Handle(AIS_Selection)*)&curobj))->myName.IsEqual(aName))
387       return I;
388   }
389   return 0;
390 }
391
392 //=======================================================================
393 //function : Remove
394 //purpose  : 
395 //=======================================================================
396
397 void AIS_Selection::Remove(const Standard_CString aName) 
398 {
399   Standard_Integer I = AIS_Selection::Index(aName);
400   if(I!=0) {
401 #ifdef OCC1039
402     Handle(AIS_Selection) selection = Handle(AIS_Selection)::DownCast( AIS_Sel_GetSelections().Value(I) );
403     Standard_Integer stored = selection->NbStored();
404     if ( stored )
405       selection->Select();
406 #endif
407     AIS_Sel_GetSelections().Remove(I);
408   }
409   
410 }
411