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