0024023: Revamp the OCCT Handle - gcc and clang
[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//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 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
7fd59977 16#include <AIS_InteractiveObject.hxx>
42cf5bc1 17#include <AIS_Selection.hxx>
18#include <SelectMgr_EntityOwner.hxx>
19#include <Standard_MultiplyDefined.hxx>
20#include <Standard_NoSuchObject.hxx>
21#include <Standard_Transient.hxx>
22#include <Standard_Type.hxx>
23#include <Standard_TypeMismatch.hxx>
24#include <TCollection_AsciiString.hxx>
25#include <TColStd_SequenceOfTransient.hxx>
7fd59977 26
7fd59977 27#define MaxSizeOfResult 100000
7fd59977 28
30bf45dc 29//current selection (handle)
30static Handle(AIS_Selection) theCurrentSelection;
7fd59977 31static void AIS_Sel_CurrentSelection (Handle(AIS_Selection)& InputSel)
32{
7fd59977 33 if(!InputSel.IsNull())
34 theCurrentSelection = InputSel;
35 else
36 InputSel = theCurrentSelection;
37}
38
39static TColStd_SequenceOfTransient& AIS_Sel_GetSelections()
40{
41 static TColStd_SequenceOfTransient Selections;
42 return Selections;
43}
44
45//=======================================================================
46//function : AIS_Selection
47//purpose :
48//=======================================================================
49AIS_Selection::AIS_Selection(const Standard_CString aName) :
50myName(TCollection_AsciiString(aName)),
7fd59977 51myNb(0)
52{
7fd59977 53 myResultMap.ReSize( MaxSizeOfResult ); // for maximum performnace on medium selections ( < 100000 objects )
7fd59977 54}
55
56//=======================================================================
57//function : CreateSelection
58//purpose :
59//=======================================================================
60Standard_Boolean AIS_Selection::CreateSelection(const Standard_CString aName)
61{
62 Handle(AIS_Selection) S = AIS_Selection::Selection(aName);
63 if(!S.IsNull())
64 return Standard_False;
65 S = new AIS_Selection(aName);
66 AIS_Sel_GetSelections().Prepend(S);
67 AIS_Sel_CurrentSelection(S);
68 return Standard_True;
69}
70
71
72//=======================================================================
73//function : Selection
74//purpose :
75//=======================================================================
76Handle(AIS_Selection) AIS_Selection::Selection(const Standard_CString aName)
77{
78 Handle(AIS_Selection) S;
79 if(AIS_Sel_GetSelections().IsEmpty()) return S;
80
81 Handle(Standard_Transient) curobj;
82 Handle(AIS_Selection) Sel;
83// Standard_Boolean found(Standard_False);
84 for(Standard_Integer I =1; I<= AIS_Sel_GetSelections().Length();I++){
85 curobj = AIS_Sel_GetSelections().Value(I);
c5f3a425 86 Sel = Handle(AIS_Selection)::DownCast (curobj);
7fd59977 87 if(Sel->myName.IsEqual(aName))
88 return Sel;
89 }
90
91 return S;
92}
93
94//=======================================================================
95//function : Find
96//purpose :
97//=======================================================================
98Standard_Boolean AIS_Selection::Find(const Standard_CString aName)
99{
100 Handle(AIS_Selection) S = AIS_Selection::Selection(aName);
101 return !S.IsNull();
102}
103
104//=======================================================================
105//function : SetCurrentSelection
106//purpose :
107//=======================================================================
108Standard_Boolean AIS_Selection::SetCurrentSelection (const Standard_CString aName)
109{
81bba717 110 AIS_Selection::CreateSelection(aName);
7fd59977 111
112
113 Handle(AIS_Selection) anAISSelection = AIS_Selection::Selection(aName) ;
114 AIS_Sel_CurrentSelection ( anAISSelection ) ;
115 return Standard_True;
116}
117
118//=======================================================================
119//function : Select
120//purpose :
121//=======================================================================
122void AIS_Selection::Select()
123{
124 Handle(AIS_Selection) S;
125 AIS_Sel_CurrentSelection (S);
126 if(!S.IsNull()){
127 S->myNb=0;
7fd59977 128 S->myresult.Clear();
7fd59977 129 S->myResultMap.Clear();
7fd59977 130 }
131}
132
133//=======================================================================
134//function : CurrentSelection
135//purpose :
136//=======================================================================
137Handle(AIS_Selection) AIS_Selection::CurrentSelection() {
138 Handle(AIS_Selection) S;
139 AIS_Sel_CurrentSelection (S);
140 return S;
141}
142//=======================================================================
143//function : Select
144//purpose :
145//=======================================================================
146AIS_SelectStatus AIS_Selection::Select(const Handle(Standard_Transient)& anObject)
147{
148 Handle(AIS_Selection) S;
149 AIS_Sel_CurrentSelection (S);
150 if(S.IsNull()) return AIS_SS_NotDone;
151 Handle(AIS_InteractiveObject) anAISObj;
152 Handle(SelectMgr_EntityOwner) owner = Handle(SelectMgr_EntityOwner)::DownCast( anObject );
153 if ( owner.IsNull() )
154 anAISObj = Handle(AIS_InteractiveObject)::DownCast( anObject );
7fd59977 155 if ( S->myResultMap.IsBound( anObject ) ){
156 AIS_NListTransient::Iterator aListIter = S->myResultMap.Find( anObject );
157//skt-----------------------------------------------------------------
eafb234b 158 if( S->myIterator == aListIter ) {
159 if( S->myIterator.More() )
160 S->myIterator.Next();
161 else
162 S->myIterator = AIS_NListTransient::Iterator();
163 }
7fd59977 164//--------------------------------------------------------------------
7fd59977 165 // In the mode of advanced mesh selection only one owner is created
166 // for all selection modes. It is necessary to check the current detected
167 // entity and remove the owner from map only if the detected entity is
168 // the same as previous selected (IsForcedHilight call)
169 if( !anAISObj.IsNull() || ( !owner.IsNull() && !owner->IsForcedHilight() ) )
170 {
7fd59977 171 S->myresult.Remove( aListIter );
172 S->myResultMap.UnBind( anObject );
173
174 // update list iterator for next object in <myresult> list if any
175 if ( aListIter.More() ){
176 const Handle(Standard_Transient)& aNextObject = aListIter.Value();
177 if ( S->myResultMap.IsBound( aNextObject ) )
178 S->myResultMap( aNextObject ) = aListIter;
179 else
180 S->myResultMap.Bind( aNextObject, aListIter );
181 }
182 return AIS_SS_Removed;
183 }
184 else
185 return AIS_SS_Added;
186 }
187
188 AIS_NListTransient::Iterator aListIter;
189 S->myresult.Append( anObject, aListIter );
190 S->myResultMap.Bind( anObject, aListIter );
191 return AIS_SS_Added;
7fd59977 192}
193
194//=======================================================================
195//function : AddSelect
196//purpose : Always add int the selection
197//=======================================================================
198AIS_SelectStatus AIS_Selection::AddSelect(const Handle(Standard_Transient)& anObject)
199{
200 Handle(AIS_Selection) S;
201 AIS_Sel_CurrentSelection (S);
202 if(S.IsNull()) return AIS_SS_NotDone;
203
7fd59977 204 if ( S->myResultMap.IsBound( anObject ) )
205 return AIS_SS_NotDone;
206
207 AIS_NListTransient::Iterator aListIter;
208 S->myresult.Append( anObject, aListIter );
209 S->myResultMap.Bind( anObject, aListIter );
7fd59977 210 return AIS_SS_Added;
211}
212
213
214//=======================================================================
215//function : ClearAndSelect
216//purpose :
217//=======================================================================
218
219void AIS_Selection::ClearAndSelect(const Handle(Standard_Transient)& anObject) {
220 Handle(AIS_Selection) S;
221 AIS_Sel_CurrentSelection (S);
222 if(S.IsNull()) return;
223
224 Select();
225 Select(anObject);
226
227}
228
229
230//=======================================================================
231//function : Extent
232//purpose :
233//=======================================================================
234Standard_Integer AIS_Selection::Extent() {
235 Handle(AIS_Selection) S;
236 AIS_Sel_CurrentSelection (S);
8d64c0cc 237
238 if (S.IsNull())
239 return 0;
240
7fd59977 241 return S->myresult.Extent();
7fd59977 242}
243
244//=======================================================================
245//function : Single
246//purpose :
247//=======================================================================
248Handle(Standard_Transient) AIS_Selection::Single()
249{
250 Handle(AIS_Selection) S;
251 AIS_Sel_CurrentSelection (S);
8d64c0cc 252
253 if (S.IsNull())
254 return Handle(Standard_Transient)();
255
7fd59977 256 S->Init();
257 return S->Value();
258}
259//=======================================================================
260//function : IsSelected
261//purpose :
262//=======================================================================
263Standard_Boolean AIS_Selection::IsSelected(const Handle(Standard_Transient)& anObject)
264{
265 Handle(AIS_Selection) S;
266 AIS_Sel_CurrentSelection (S);
267 if(S.IsNull()) return Standard_False;
7fd59977 268 return S->myResultMap.IsBound( anObject );
7fd59977 269}
270
271//=======================================================================
272//function : Index
273//purpose :
274//=======================================================================
275
276Standard_Integer AIS_Selection::Index(const Standard_CString aName)
277{
278 Handle (Standard_Transient) curobj;
279 for(Standard_Integer I =1; I<= AIS_Sel_GetSelections().Length();I++){
280 curobj = AIS_Sel_GetSelections().Value(I);
c5f3a425 281 if(Handle(AIS_Selection)::DownCast (curobj)->myName.IsEqual(aName))
7fd59977 282 return I;
283 }
284 return 0;
285}
286
287//=======================================================================
288//function : Remove
289//purpose :
290//=======================================================================
291
292void AIS_Selection::Remove(const Standard_CString aName)
293{
294 Standard_Integer I = AIS_Selection::Index(aName);
295 if(I!=0) {
7fd59977 296 Handle(AIS_Selection) selection = Handle(AIS_Selection)::DownCast( AIS_Sel_GetSelections().Value(I) );
297 Standard_Integer stored = selection->NbStored();
298 if ( stored )
299 selection->Select();
7fd59977 300 AIS_Sel_GetSelections().Remove(I);
301 }
30bf45dc 302}
303
304// clean the static current selection handle
305void AIS_Selection::ClearCurrentSelection()
306{
307 theCurrentSelection.Nullify();
7fd59977 308}
309