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