1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
16 #include <AIS_InteractiveObject.hxx>
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>
27 IMPLEMENT_STANDARD_RTTIEXT(AIS_Selection,MMgt_TShared)
29 #define MaxSizeOfResult 100000
31 //current selection (handle)
32 static Handle(AIS_Selection) theCurrentSelection;
33 static void AIS_Sel_CurrentSelection (Handle(AIS_Selection)& InputSel)
35 if(!InputSel.IsNull())
36 theCurrentSelection = InputSel;
38 InputSel = theCurrentSelection;
41 static TColStd_SequenceOfTransient& AIS_Sel_GetSelections()
43 static TColStd_SequenceOfTransient Selections;
47 //=======================================================================
48 //function : AIS_Selection
50 //=======================================================================
51 AIS_Selection::AIS_Selection(const Standard_CString aName) :
52 myName(TCollection_AsciiString(aName)),
55 myResultMap.ReSize( MaxSizeOfResult ); // for maximum performnace on medium selections ( < 100000 objects )
58 //=======================================================================
59 //function : CreateSelection
61 //=======================================================================
62 Standard_Boolean AIS_Selection::CreateSelection(const Standard_CString aName)
64 Handle(AIS_Selection) S = AIS_Selection::Selection(aName);
66 return Standard_False;
67 S = new AIS_Selection(aName);
68 AIS_Sel_GetSelections().Prepend(S);
69 AIS_Sel_CurrentSelection(S);
74 //=======================================================================
75 //function : Selection
77 //=======================================================================
78 Handle(AIS_Selection) AIS_Selection::Selection(const Standard_CString aName)
80 Handle(AIS_Selection) S;
81 if(AIS_Sel_GetSelections().IsEmpty()) return S;
83 Handle(Standard_Transient) curobj;
84 Handle(AIS_Selection) Sel;
85 // Standard_Boolean found(Standard_False);
86 for(Standard_Integer I =1; I<= AIS_Sel_GetSelections().Length();I++){
87 curobj = AIS_Sel_GetSelections().Value(I);
88 Sel = Handle(AIS_Selection)::DownCast (curobj);
89 if(Sel->myName.IsEqual(aName))
96 //=======================================================================
99 //=======================================================================
100 Standard_Boolean AIS_Selection::Find(const Standard_CString aName)
102 Handle(AIS_Selection) S = AIS_Selection::Selection(aName);
106 //=======================================================================
107 //function : SetCurrentSelection
109 //=======================================================================
110 Standard_Boolean AIS_Selection::SetCurrentSelection (const Standard_CString aName)
112 AIS_Selection::CreateSelection(aName);
115 Handle(AIS_Selection) anAISSelection = AIS_Selection::Selection(aName) ;
116 AIS_Sel_CurrentSelection ( anAISSelection ) ;
117 return Standard_True;
120 //=======================================================================
123 //=======================================================================
124 void AIS_Selection::Select()
126 Handle(AIS_Selection) S;
127 AIS_Sel_CurrentSelection (S);
131 S->myResultMap.Clear();
135 //=======================================================================
136 //function : CurrentSelection
138 //=======================================================================
139 Handle(AIS_Selection) AIS_Selection::CurrentSelection() {
140 Handle(AIS_Selection) S;
141 AIS_Sel_CurrentSelection (S);
144 //=======================================================================
147 //=======================================================================
148 AIS_SelectStatus AIS_Selection::Select(const Handle(Standard_Transient)& anObject)
150 Handle(AIS_Selection) S;
151 AIS_Sel_CurrentSelection (S);
152 if(S.IsNull()) return AIS_SS_NotDone;
153 Handle(AIS_InteractiveObject) anAISObj;
154 Handle(SelectMgr_EntityOwner) owner = Handle(SelectMgr_EntityOwner)::DownCast( anObject );
155 if ( owner.IsNull() )
156 anAISObj = Handle(AIS_InteractiveObject)::DownCast( anObject );
157 if ( S->myResultMap.IsBound( anObject ) ){
158 AIS_NListTransient::Iterator aListIter = S->myResultMap.Find( anObject );
159 //skt-----------------------------------------------------------------
160 if( S->myIterator == aListIter ) {
161 if( S->myIterator.More() )
162 S->myIterator.Next();
164 S->myIterator = AIS_NListTransient::Iterator();
166 //--------------------------------------------------------------------
167 // In the mode of advanced mesh selection only one owner is created
168 // for all selection modes. It is necessary to check the current detected
169 // entity and remove the owner from map only if the detected entity is
170 // the same as previous selected (IsForcedHilight call)
171 if( !anAISObj.IsNull() || ( !owner.IsNull() && !owner->IsForcedHilight() ) )
173 S->myresult.Remove( aListIter );
174 S->myResultMap.UnBind( anObject );
176 // update list iterator for next object in <myresult> list if any
177 if ( aListIter.More() ){
178 const Handle(Standard_Transient)& aNextObject = aListIter.Value();
179 if ( S->myResultMap.IsBound( aNextObject ) )
180 S->myResultMap( aNextObject ) = aListIter;
182 S->myResultMap.Bind( aNextObject, aListIter );
184 return AIS_SS_Removed;
190 AIS_NListTransient::Iterator aListIter;
191 S->myresult.Append( anObject, aListIter );
192 S->myResultMap.Bind( anObject, aListIter );
196 //=======================================================================
197 //function : AddSelect
198 //purpose : Always add int the selection
199 //=======================================================================
200 AIS_SelectStatus AIS_Selection::AddSelect(const Handle(Standard_Transient)& anObject)
202 Handle(AIS_Selection) S;
203 AIS_Sel_CurrentSelection (S);
204 if(S.IsNull()) return AIS_SS_NotDone;
206 if ( S->myResultMap.IsBound( anObject ) )
207 return AIS_SS_NotDone;
209 AIS_NListTransient::Iterator aListIter;
210 S->myresult.Append( anObject, aListIter );
211 S->myResultMap.Bind( anObject, aListIter );
216 //=======================================================================
217 //function : ClearAndSelect
219 //=======================================================================
221 void AIS_Selection::ClearAndSelect(const Handle(Standard_Transient)& anObject) {
222 Handle(AIS_Selection) S;
223 AIS_Sel_CurrentSelection (S);
224 if(S.IsNull()) return;
232 //=======================================================================
235 //=======================================================================
236 Standard_Integer AIS_Selection::Extent() {
237 Handle(AIS_Selection) S;
238 AIS_Sel_CurrentSelection (S);
243 return S->myresult.Extent();
246 //=======================================================================
249 //=======================================================================
250 Handle(Standard_Transient) AIS_Selection::Single()
252 Handle(AIS_Selection) S;
253 AIS_Sel_CurrentSelection (S);
256 return Handle(Standard_Transient)();
261 //=======================================================================
262 //function : IsSelected
264 //=======================================================================
265 Standard_Boolean AIS_Selection::IsSelected(const Handle(Standard_Transient)& anObject)
267 Handle(AIS_Selection) S;
268 AIS_Sel_CurrentSelection (S);
269 if(S.IsNull()) return Standard_False;
270 return S->myResultMap.IsBound( anObject );
273 //=======================================================================
276 //=======================================================================
278 Standard_Integer AIS_Selection::Index(const Standard_CString aName)
280 Handle (Standard_Transient) curobj;
281 for(Standard_Integer I =1; I<= AIS_Sel_GetSelections().Length();I++){
282 curobj = AIS_Sel_GetSelections().Value(I);
283 if(Handle(AIS_Selection)::DownCast (curobj)->myName.IsEqual(aName))
289 //=======================================================================
292 //=======================================================================
294 void AIS_Selection::Remove(const Standard_CString aName)
296 Standard_Integer I = AIS_Selection::Index(aName);
298 Handle(AIS_Selection) selection = Handle(AIS_Selection)::DownCast( AIS_Sel_GetSelections().Value(I) );
299 Standard_Integer stored = selection->NbStored();
302 AIS_Sel_GetSelections().Remove(I);
306 // clean the static current selection handle
307 void AIS_Selection::ClearCurrentSelection()
309 theCurrentSelection.Nullify();