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