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