b311480e |
1 | // Created on: 1996-10-30 |
2 | // Created by: Robert COUBLANC |
3 | // Copyright (c) 1996-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
12 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
b311480e |
16 | |
7fd59977 |
17 | // Modified by rob Thu Apr 02 1998 |
18 | // - use of optimisation in SelectMgr_ViewerSelector |
19 | // -> Best management in detected entities... |
20 | |
42cf5bc1 |
21 | #include <AIS_InteractiveContext.hxx> |
22 | #include <AIS_InteractiveObject.hxx> |
23 | #include <AIS_LocalContext.hxx> |
7fd59977 |
24 | #include <AIS_LocalStatus.hxx> |
42cf5bc1 |
25 | #include <AIS_Selection.hxx> |
26 | #include <AIS_Shape.hxx> |
27 | #include <Aspect_Grid.hxx> |
28 | #include <Geom_Transformation.hxx> |
b8ddfc2f |
29 | #include <Graphic3d_ArrayOfTriangles.hxx> |
7fd59977 |
30 | #include <Graphic3d_Group.hxx> |
42cf5bc1 |
31 | #include <NCollection_Map.hxx> |
32 | #include <OSD_Environment.hxx> |
33 | #include <Prs3d_Drawer.hxx> |
34 | #include <Prs3d_Presentation.hxx> |
35 | #include <Prs3d_ShadingAspect.hxx> |
7fd59977 |
36 | #include <Select3D_SensitiveTriangulation.hxx> |
37 | #include <SelectBasics_SensitiveEntity.hxx> |
42cf5bc1 |
38 | #include <SelectMgr_EntityOwner.hxx> |
39 | #include <SelectMgr_Filter.hxx> |
40 | #include <SelectMgr_OrFilter.hxx> |
41 | #include <SelectMgr_SelectableObject.hxx> |
7fd59977 |
42 | #include <SelectMgr_Selection.hxx> |
42cf5bc1 |
43 | #include <SelectMgr_SelectionManager.hxx> |
e3a6386d |
44 | #include <SelectMgr_SequenceOfOwner.hxx> |
42cf5bc1 |
45 | #include <Standard_Transient.hxx> |
46 | #include <StdSelect_BRepOwner.hxx> |
47 | #include <StdSelect_ViewerSelector3d.hxx> |
48 | #include <TCollection_AsciiString.hxx> |
49 | #include <TColStd_ListIteratorOfListOfInteger.hxx> |
50 | #include <TColStd_ListOfInteger.hxx> |
51 | #include <TColStd_MapIteratorOfMapOfTransient.hxx> |
52 | #include <TColStd_MapOfTransient.hxx> |
42cf5bc1 |
53 | #include <V3d_View.hxx> |
7fd59977 |
54 | |
016e5959 |
55 | namespace |
56 | { |
896faa72 |
57 | TopoDS_Shape AIS_LocalContext_myDummyShape; |
016e5959 |
58 | } |
59 | |
7fd59977 |
60 | //================================================== |
679ecdee |
61 | // Function: MoveTo |
7fd59977 |
62 | // Purpose : |
63 | //================================================== |
679ecdee |
64 | AIS_StatusOfDetection AIS_LocalContext::MoveTo (const Standard_Integer theXpix, |
65 | const Standard_Integer theYpix, |
66 | const Handle(V3d_View)& theView, |
67 | const Standard_Boolean theToRedrawImmediate) |
7fd59977 |
68 | { |
679ecdee |
69 | // check that ViewerSelector gives |
70 | if (theView->Viewer() != myCTX->CurrentViewer()) |
71 | { |
72 | return AIS_SOD_Error; |
73 | } |
74 | |
75 | myAISCurDetected = 0; |
679ecdee |
76 | |
77 | myCurDetected = 0; |
78 | myDetectedSeq.Clear(); |
a272ed94 |
79 | myFilters->SetDisabledObjects (theView->View()->HiddenObjects()); |
679ecdee |
80 | myMainVS->Pick (theXpix, theYpix, theView); |
81 | |
82 | const Standard_Integer aDetectedNb = myMainVS->NbPicked(); |
83 | for (Standard_Integer aDetIter = 1; aDetIter <= aDetectedNb; ++aDetIter) |
84 | { |
85 | Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (aDetIter); |
d21ddc4f |
86 | if (!anOwner.IsNull() |
87 | && myFilters->IsOk (anOwner)) |
679ecdee |
88 | { |
d21ddc4f |
89 | myDetectedSeq.Append (aDetIter); // normally they are already arranged in correct order... |
7fd59977 |
90 | } |
679ecdee |
91 | } |
7fd59977 |
92 | |
679ecdee |
93 | // result of courses.. |
94 | if (aDetectedNb == 0 || myDetectedSeq.IsEmpty()) |
95 | { |
b586500b |
96 | if (mylastindex != 0 && mylastindex <= myMapOfOwner->Extent()) |
679ecdee |
97 | { |
63d907e7 |
98 | myMainPM->ClearImmediateDraw(); |
b586500b |
99 | Unhilight (myMapOfOwner->FindKey (mylastindex), theView); |
679ecdee |
100 | if (theToRedrawImmediate) |
101 | { |
102 | theView->RedrawImmediate(); |
7fd59977 |
103 | } |
7fd59977 |
104 | } |
679ecdee |
105 | |
106 | mylastindex = 0; |
107 | return aDetectedNb == 0 |
108 | ? AIS_SOD_Nothing |
109 | : AIS_SOD_AllBad; |
110 | } |
111 | |
112 | // all owners detected by the selector are passed to the |
113 | // filters and correct ones are preserved... |
114 | myCurDetected = 1; |
115 | Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected)); |
116 | manageDetected (anOwner, theView, theToRedrawImmediate); |
117 | if (myDetectedSeq.Length() == 1) |
118 | { |
119 | return aDetectedNb == 1 |
120 | ? AIS_SOD_OnlyOneDetected |
121 | : AIS_SOD_OnlyOneGood; |
122 | } |
123 | else |
124 | { |
125 | return AIS_SOD_SeveralGood; |
7fd59977 |
126 | } |
7fd59977 |
127 | } |
128 | |
016e5959 |
129 | //======================================================================= |
130 | //function : AddSelect |
131 | //purpose : |
132 | //======================================================================= |
02974a19 |
133 | AIS_StatusOfPick AIS_LocalContext::AddSelect (const Handle(SelectMgr_EntityOwner)& theObject) |
016e5959 |
134 | { |
135 | mySelection->AddSelect (theObject); |
136 | |
137 | Standard_Integer aSelNum = mySelection->Extent(); |
138 | return (aSelNum == 1) ? AIS_SOP_OneSelected |
139 | : (aSelNum > 1) ? AIS_SOP_SeveralSelected |
140 | : AIS_SOP_Error; |
141 | } |
142 | |
c398b00e |
143 | //======================================================================= |
144 | //function : Select |
145 | //purpose : |
146 | //======================================================================= |
147 | AIS_StatusOfPick AIS_LocalContext::Select (const Standard_Boolean toUpdateViewer) |
7fd59977 |
148 | { |
c398b00e |
149 | if (myAutoHilight) |
150 | { |
151 | UnhilightPicked (Standard_False); |
152 | } |
7fd59977 |
153 | |
c398b00e |
154 | Standard_Integer aDetIndex = DetectedIndex(); |
155 | if (aDetIndex <= 0) |
156 | { |
157 | ClearSelected (toUpdateViewer); |
02974a19 |
158 | return mySelection->IsEmpty() ? AIS_SOP_NothingSelected : AIS_SOP_Removed; |
7fd59977 |
159 | } |
160 | |
b586500b |
161 | const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (aDetIndex); |
7fd59977 |
162 | |
c398b00e |
163 | ClearSelected (Standard_False); |
164 | |
165 | if (!anOwner->IsSelected()) // anOwner is not selected |
166 | { |
167 | anOwner->SetSelected (Standard_True); |
016e5959 |
168 | mySelection->Select (anOwner); |
7fd59977 |
169 | } |
c398b00e |
170 | |
679ecdee |
171 | if (myAutoHilight) |
172 | { |
7fd59977 |
173 | const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer(); |
6a24c6de |
174 | for (V3d_ListOfViewIterator anActiveViewIter (aViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next()) |
679ecdee |
175 | { |
6a24c6de |
176 | Unhilight (anOwner, anActiveViewIter.Value()); |
7fd59977 |
177 | } |
178 | |
679ecdee |
179 | // advanced selection highlighting mechanism |
c398b00e |
180 | if (!anOwner->IsAutoHilight() && anOwner->HasSelectable()) |
679ecdee |
181 | { |
c398b00e |
182 | Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable()); |
679ecdee |
183 | UpdateSelected (anIO, Standard_False); |
184 | } |
185 | |
c398b00e |
186 | if (toUpdateViewer) |
679ecdee |
187 | { |
188 | myCTX->CurrentViewer()->Update(); |
189 | } |
7fd59977 |
190 | } |
c398b00e |
191 | |
016e5959 |
192 | return (mySelection->Extent() == 1) ? AIS_SOP_OneSelected : AIS_SOP_SeveralSelected; |
7fd59977 |
193 | } |
c398b00e |
194 | |
195 | //======================================================================= |
196 | //function : Select |
197 | //purpose : |
198 | //======================================================================= |
199 | AIS_StatusOfPick AIS_LocalContext::Select (const Standard_Integer theXPMin, |
200 | const Standard_Integer theYPMin, |
201 | const Standard_Integer theXPMax, |
202 | const Standard_Integer theYPMax, |
203 | const Handle(V3d_View)& theView, |
204 | const Standard_Boolean toUpdateViewer) |
7fd59977 |
205 | { |
c398b00e |
206 | if (theView->Viewer() == myCTX->CurrentViewer()) |
207 | { |
208 | myMainVS->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView); |
209 | if (myAutoHilight) |
210 | { |
211 | UnhilightPicked (Standard_False); |
212 | } |
213 | |
016e5959 |
214 | Standard_Integer aSelNum = mySelection->Extent(); |
aa75c0cf |
215 | if (myMainVS->NbPicked() == 0) |
c398b00e |
216 | { |
217 | ClearSelected (toUpdateViewer); |
218 | mylastindex = 0; |
219 | return aSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed; |
7fd59977 |
220 | } |
221 | |
c398b00e |
222 | ClearSelected (Standard_False); |
223 | |
aa75c0cf |
224 | for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter) |
c398b00e |
225 | { |
aa75c0cf |
226 | const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter); |
c398b00e |
227 | if (myFilters->IsOk (anOwner)) |
228 | { |
229 | // it can be helpful to classify this owner immediately... |
230 | if (!anOwner->IsSelected()) |
231 | { |
232 | anOwner->SetSelected (Standard_True); |
016e5959 |
233 | mySelection->Select (anOwner); |
c398b00e |
234 | } |
7fd59977 |
235 | } |
236 | } |
c398b00e |
237 | |
238 | if (myAutoHilight) |
239 | { |
240 | HilightPicked (toUpdateViewer); |
241 | } |
7fd59977 |
242 | } |
7fd59977 |
243 | |
016e5959 |
244 | Standard_Integer aSelNum = mySelection->Extent(); |
7fd59977 |
245 | |
c398b00e |
246 | return (aSelNum == 1) ? AIS_SOP_OneSelected |
247 | : (aSelNum > 1) ? AIS_SOP_SeveralSelected |
248 | : AIS_SOP_Error; |
249 | } |
7fd59977 |
250 | |
251 | //================================================== |
c398b00e |
252 | // Function: Select |
253 | // Purpose : Selection by polyline |
7fd59977 |
254 | //================================================== |
c398b00e |
255 | AIS_StatusOfPick AIS_LocalContext::Select (const TColgp_Array1OfPnt2d& thePolyline, |
256 | const Handle(V3d_View)& theView, |
257 | const Standard_Boolean toUpdateViewer) |
7fd59977 |
258 | { |
c398b00e |
259 | if (theView->Viewer() == myCTX->CurrentViewer()) |
260 | { |
261 | myMainVS->Pick (thePolyline, theView); |
7fd59977 |
262 | |
016e5959 |
263 | Standard_Integer aLastSelNum = mySelection->Extent(); |
aa75c0cf |
264 | if (myMainVS->NbPicked() == 0) |
c398b00e |
265 | { |
266 | // Nothing is selected clear selection. |
267 | ClearSelected (toUpdateViewer); |
268 | mylastindex = 0; |
269 | |
270 | // Return state to know if something was unselected |
271 | return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed; |
272 | } |
273 | |
274 | if (myAutoHilight) |
275 | { |
276 | UnhilightPicked (Standard_False); |
277 | } |
278 | |
279 | // Clear previous selection without update to process this selection |
280 | ClearSelected (Standard_False); |
281 | |
aa75c0cf |
282 | for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter) |
c398b00e |
283 | { |
aa75c0cf |
284 | const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter); |
c398b00e |
285 | if (myFilters->IsOk (anOwner)) |
286 | { |
287 | // it can be helpful to classify this owner immediately... |
288 | if (!anOwner->IsSelected()) |
289 | { |
016e5959 |
290 | mySelection->AddSelect (anOwner); |
c398b00e |
291 | anOwner->SetSelected (Standard_True); |
292 | } |
293 | } |
294 | } |
295 | |
296 | if (myAutoHilight) |
297 | { |
298 | HilightPicked (toUpdateViewer); |
299 | } |
300 | } |
301 | |
016e5959 |
302 | Standard_Integer aSelNum = mySelection->Extent(); |
c398b00e |
303 | return (aSelNum == 1) ? AIS_SOP_OneSelected |
304 | : (aSelNum > 1) ? AIS_SOP_SeveralSelected |
305 | : AIS_SOP_Error; |
306 | } |
307 | |
308 | //======================================================================= |
309 | //function : ShiftSelect |
310 | //purpose : |
311 | //======================================================================= |
312 | AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const Standard_Boolean toUpdateViewer) |
313 | { |
314 | Standard_Integer aDetIndex = DetectedIndex(); |
c398b00e |
315 | |
316 | if(aDetIndex > 0) |
317 | { |
016e5959 |
318 | Standard_Integer aSelNum = mySelection->Extent(); |
b586500b |
319 | const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (aDetIndex); |
c398b00e |
320 | Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True; |
016e5959 |
321 | mySelection->Select (anOwner); |
c398b00e |
322 | anOwner->SetSelected (toSelect); |
7fd59977 |
323 | |
679ecdee |
324 | if(myAutoHilight) |
325 | { |
63d907e7 |
326 | myMainPM->ClearImmediateDraw(); |
7fd59977 |
327 | const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer(); |
6a24c6de |
328 | for (V3d_ListOfViewIterator anActiveViewIter (aViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next()) |
679ecdee |
329 | { |
6a24c6de |
330 | Unhilight (anOwner, anActiveViewIter.Value()); |
679ecdee |
331 | } |
332 | |
333 | // advanced selection highlighting mechanism |
c398b00e |
334 | if (!anOwner->IsAutoHilight() && anOwner->HasSelectable()) |
679ecdee |
335 | { |
c398b00e |
336 | Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable()); |
679ecdee |
337 | UpdateSelected (anIO, Standard_False); |
7fd59977 |
338 | } |
339 | |
c398b00e |
340 | if (toUpdateViewer) |
679ecdee |
341 | { |
7fd59977 |
342 | myCTX->CurrentViewer()->Update(); |
679ecdee |
343 | } |
7fd59977 |
344 | } |
c398b00e |
345 | |
016e5959 |
346 | Standard_Integer NS = mySelection->Extent(); |
7fd59977 |
347 | if( NS == 1 ) return AIS_SOP_OneSelected; |
348 | else if( NS > 1 ) return AIS_SOP_SeveralSelected; |
c398b00e |
349 | return aSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed; |
7fd59977 |
350 | } |
351 | return AIS_SOP_Error; |
352 | } |
c398b00e |
353 | |
354 | //======================================================================= |
355 | //function : ShiftSelect |
356 | //purpose : |
357 | //======================================================================= |
358 | AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const Standard_Integer theXPMin, |
359 | const Standard_Integer theYPMin, |
360 | const Standard_Integer theXPMax, |
361 | const Standard_Integer theYPMax, |
362 | const Handle(V3d_View)& theView, |
363 | const Standard_Boolean toUpdateViewer) |
7fd59977 |
364 | { |
679ecdee |
365 | myMainPM->ClearImmediateDraw(); |
366 | |
c398b00e |
367 | if (theView->Viewer() == myCTX->CurrentViewer()) |
368 | { |
369 | myMainVS->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView); |
370 | |
016e5959 |
371 | Standard_Integer aLastSelNum = mySelection->Extent(); |
aa75c0cf |
372 | if (myMainVS->NbPicked() == 0) |
c398b00e |
373 | { |
374 | // Nothing is selected clear selection, but don't clear the selection |
375 | // as it is shift selection and previous selection matters. |
376 | // Return state to know if something was unselected |
377 | return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed; |
378 | } |
7fd59977 |
379 | |
c398b00e |
380 | if (myAutoHilight) |
381 | { |
382 | UnhilightPicked (Standard_False); |
383 | } |
7fd59977 |
384 | |
aa75c0cf |
385 | for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter) |
c398b00e |
386 | { |
aa75c0cf |
387 | const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter); |
c398b00e |
388 | if(myFilters->IsOk (anOwner)) |
389 | { |
390 | Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True; |
016e5959 |
391 | mySelection->Select (anOwner); |
c398b00e |
392 | anOwner->SetSelected (toSelect); |
7fd59977 |
393 | } |
394 | } |
c398b00e |
395 | |
396 | if (myAutoHilight) |
397 | { |
398 | HilightPicked (toUpdateViewer); |
399 | } |
7fd59977 |
400 | } |
c398b00e |
401 | |
016e5959 |
402 | Standard_Integer aSelNum = mySelection->Extent(); |
c398b00e |
403 | |
404 | return (aSelNum == 1) ? AIS_SOP_OneSelected |
405 | : (aSelNum > 1) ? AIS_SOP_SeveralSelected |
406 | : AIS_SOP_Error; |
7fd59977 |
407 | } |
408 | |
409 | //================================================== |
410 | // Function: Select |
411 | // Purpose : Selection by polyline |
412 | //================================================== |
c398b00e |
413 | AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const TColgp_Array1OfPnt2d& thePolyline, |
414 | const Handle(V3d_View)& theView, |
415 | const Standard_Boolean toUpdateViewer) |
7fd59977 |
416 | { |
c398b00e |
417 | if (theView->Viewer() == myCTX->CurrentViewer()) |
418 | { |
419 | myMainVS->Pick (thePolyline, theView); |
420 | |
016e5959 |
421 | Standard_Integer aLastSelNum = mySelection->Extent(); |
aa75c0cf |
422 | if (myMainVS->NbPicked() == 0) |
c398b00e |
423 | { |
424 | // Nothing is selected clear selection, but don't clear the selection |
425 | // as it is shift selection and previous selection matters. |
426 | // Return state to know if something was unselected |
427 | return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed; |
7fd59977 |
428 | } |
429 | |
c398b00e |
430 | if (myAutoHilight) |
431 | { |
432 | UnhilightPicked (Standard_False); |
7fd59977 |
433 | } |
434 | |
aa75c0cf |
435 | for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter) |
c398b00e |
436 | { |
aa75c0cf |
437 | const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter); |
c398b00e |
438 | if (myFilters->IsOk (anOwner)) |
439 | { |
440 | Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True; |
016e5959 |
441 | mySelection->Select (anOwner); |
c398b00e |
442 | anOwner->SetSelected (toSelect); |
443 | } |
444 | } |
445 | if (myAutoHilight) |
446 | { |
447 | HilightPicked (toUpdateViewer); |
448 | } |
7fd59977 |
449 | } |
7fd59977 |
450 | |
016e5959 |
451 | Standard_Integer aSelNum = mySelection->Extent(); |
c398b00e |
452 | |
453 | return (aSelNum == 1) ? AIS_SOP_OneSelected |
454 | : (aSelNum > 1) ? AIS_SOP_SeveralSelected |
455 | : AIS_SOP_Error; |
7fd59977 |
456 | } |
457 | |
458 | //================================================== |
679ecdee |
459 | // Function: Hilight |
7fd59977 |
460 | // Purpose : |
461 | //================================================== |
679ecdee |
462 | void AIS_LocalContext::Hilight (const Handle(SelectMgr_EntityOwner)& theOwner, |
463 | const Handle(V3d_View)& theView) |
7fd59977 |
464 | { |
679ecdee |
465 | if (theView.IsNull()) |
466 | { |
467 | return; |
468 | } |
7fd59977 |
469 | |
f838dac4 |
470 | const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast(theOwner->Selectable()); |
471 | const Handle(Prs3d_Drawer)& aHiStyle = myCTX->getHiStyle (anObj, theOwner); |
472 | const Standard_Integer aHiMode = myCTX->getHilightMode (anObj, aHiStyle, -1); |
679ecdee |
473 | myMainPM->BeginImmediateDraw(); |
f838dac4 |
474 | theOwner->HilightWithColor (myMainPM, aHiStyle, aHiMode); |
c3282ec1 |
475 | myMainPM->EndImmediateDraw (theView->Viewer()); |
7fd59977 |
476 | } |
477 | |
478 | //================================================== |
679ecdee |
479 | // Function: Unhilight |
7fd59977 |
480 | // Purpose : |
481 | //================================================== |
679ecdee |
482 | void AIS_LocalContext::Unhilight (const Handle(SelectMgr_EntityOwner)& theOwner, |
483 | const Handle(V3d_View)& theView) |
7fd59977 |
484 | { |
679ecdee |
485 | if (theView.IsNull()) |
486 | { |
487 | return; |
488 | } |
7fd59977 |
489 | |
f838dac4 |
490 | const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable()); |
679ecdee |
491 | if (IsSelected (theOwner)) |
7fd59977 |
492 | { |
679ecdee |
493 | if (theOwner->IsAutoHilight()) |
494 | { |
f838dac4 |
495 | const Handle(Prs3d_Drawer)& aSelStyle = myCTX->getSelStyle (anObj, theOwner); |
496 | const Standard_Integer aHiMode = myCTX->getHilightMode (anObj, aSelStyle, -1); |
497 | theOwner->HilightWithColor (myMainPM, aSelStyle, aHiMode); |
679ecdee |
498 | } |
499 | } |
500 | else |
501 | { |
f838dac4 |
502 | theOwner->Unhilight (myMainPM); |
7fd59977 |
503 | } |
7fd59977 |
504 | } |
505 | |
506 | //======================================================================= |
507 | //function : HilightPicked |
02974a19 |
508 | //purpose : |
7fd59977 |
509 | //======================================================================= |
02974a19 |
510 | void AIS_LocalContext::HilightPicked (const Standard_Boolean theToUpdateviewer) |
7fd59977 |
511 | { |
02974a19 |
512 | if (mySelection.IsNull()) |
513 | { |
514 | return; |
515 | } |
016e5959 |
516 | |
02974a19 |
517 | typedef NCollection_Shared<SelectMgr_SequenceOfOwner> SelectMgr_HSequenceOfOwner; |
518 | typedef NCollection_DataMap <Handle(SelectMgr_SelectableObject), Handle(SelectMgr_HSequenceOfOwner) > SelectMgr_DataMapOfObjectOwners; |
7fd59977 |
519 | SelectMgr_DataMapOfObjectOwners aMap; |
e3a6386d |
520 | |
81bba717 |
521 | // to avoid problems when there is a loop searching for selected objects... |
02974a19 |
522 | for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next()) |
7fd59977 |
523 | { |
02974a19 |
524 | const Handle(SelectMgr_EntityOwner)& anOwner = aSelIter.Value(); |
525 | Handle(SelectMgr_SelectableObject) aSelObj = anOwner->Selectable(); |
526 | if (anOwner->IsAutoHilight()) |
527 | { |
528 | Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast(aSelObj); |
f838dac4 |
529 | const Handle(Prs3d_Drawer)& aSelStyle = myCTX->getSelStyle (anIO, anOwner); |
530 | const Standard_Integer aHiMode = myCTX->getHilightMode (anIO, aSelStyle, -1); |
531 | anOwner->HilightWithColor (myMainPM, aSelStyle, aHiMode); |
02974a19 |
532 | continue; |
533 | } |
534 | |
535 | Handle(SelectMgr_HSequenceOfOwner) aSeq; |
536 | if (aMap.Find (aSelObj, aSeq)) |
537 | { |
538 | aSeq->Append (anOwner); |
539 | } |
540 | else |
541 | { |
542 | aSeq = new SelectMgr_HSequenceOfOwner(); |
543 | aSeq->Append (anOwner); |
544 | aMap.Bind (aSelObj, aSeq); |
7fd59977 |
545 | } |
546 | } |
547 | |
02974a19 |
548 | for (SelectMgr_DataMapOfObjectOwners::Iterator aMapIter (aMap); aMapIter.More(); aMapIter.Next()) |
e3a6386d |
549 | { |
550 | aMapIter.Key()->HilightSelected (myMainPM, *aMapIter.Value()); |
551 | } |
7fd59977 |
552 | |
02974a19 |
553 | if (theToUpdateviewer) |
679ecdee |
554 | { |
555 | myCTX->CurrentViewer()->Update(); |
7fd59977 |
556 | } |
557 | } |
558 | |
559 | //================================================== |
02974a19 |
560 | // Function: UnhilightPicked |
7fd59977 |
561 | // Purpose : |
562 | //================================================== |
02974a19 |
563 | void AIS_LocalContext::UnhilightPicked (const Standard_Boolean theToUpdateViewer) |
7fd59977 |
564 | { |
679ecdee |
565 | myMainPM->ClearImmediateDraw(); |
02974a19 |
566 | if (mySelection.IsNull()) |
567 | { |
568 | return; |
569 | } |
679ecdee |
570 | |
e3a6386d |
571 | NCollection_Map<Handle(SelectMgr_SelectableObject)> anObjMap; |
02974a19 |
572 | for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next()) |
573 | { |
574 | const Handle(SelectMgr_EntityOwner)& anOwner = aSelIter.Value(); |
575 | Handle(SelectMgr_SelectableObject) aSelObj = anOwner->Selectable(); |
576 | Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (aSelObj); |
577 | anObjMap.Add (aSelObj); |
f838dac4 |
578 | anOwner->Unhilight (myMainPM); |
7fd59977 |
579 | } |
02974a19 |
580 | |
581 | for (NCollection_Map<Handle(SelectMgr_SelectableObject)>::Iterator aMapIter (anObjMap); |
582 | aMapIter.More(); aMapIter.Next()) |
e3a6386d |
583 | { |
02974a19 |
584 | if (!aMapIter.Key()->IsAutoHilight()) |
585 | { |
586 | aMapIter.Key()->ClearSelected(); |
587 | } |
e3a6386d |
588 | } |
7fd59977 |
589 | |
02974a19 |
590 | if (theToUpdateViewer) |
591 | { |
7fd59977 |
592 | myCTX->CurrentViewer()->Update(); |
02974a19 |
593 | } |
7fd59977 |
594 | } |
595 | |
596 | //======================================================================= |
597 | //function : IsSelected |
598 | //purpose : |
599 | //======================================================================= |
600 | Standard_Boolean AIS_LocalContext::IsSelected(const Handle(AIS_InteractiveObject)& anIObj) const |
601 | { |
602 | return (!FindSelectedOwnerFromIO(anIObj).IsNull()); |
603 | } |
604 | |
605 | //======================================================================= |
606 | //function : IsSelected |
607 | //purpose : |
608 | //======================================================================= |
609 | |
c398b00e |
610 | Standard_Boolean AIS_LocalContext::IsSelected (const Handle(SelectMgr_EntityOwner)& theOwner) const |
7fd59977 |
611 | { |
c398b00e |
612 | return !theOwner.IsNull() && theOwner->IsSelected(); |
7fd59977 |
613 | } |
614 | |
615 | //================================================== |
616 | // Function: |
617 | // Purpose : |
618 | //================================================== |
619 | void AIS_LocalContext:: |
620 | InitSelected() |
621 | { |
016e5959 |
622 | mySelection->Init(); |
7fd59977 |
623 | } |
624 | |
625 | //================================================== |
626 | // Function: |
627 | // Purpose : |
628 | //================================================== |
629 | Standard_Boolean AIS_LocalContext:: |
630 | MoreSelected() const |
631 | { |
016e5959 |
632 | return mySelection->More(); |
7fd59977 |
633 | } |
634 | |
635 | //================================================== |
636 | // Function: |
637 | // Purpose : |
638 | //================================================== |
639 | void AIS_LocalContext:: |
640 | NextSelected() |
641 | { |
016e5959 |
642 | mySelection->Next(); |
7fd59977 |
643 | } |
644 | |
645 | //================================================== |
02974a19 |
646 | // Function: HasShape |
7fd59977 |
647 | // Purpose : |
648 | //================================================== |
02974a19 |
649 | Standard_Boolean AIS_LocalContext::HasShape() const |
7fd59977 |
650 | { |
02974a19 |
651 | if (!mySelection->More()) |
652 | { |
653 | return Standard_False; |
654 | } |
655 | |
656 | Handle(StdSelect_BRepOwner) aBROwner = Handle(StdSelect_BRepOwner)::DownCast(mySelection->Value()); |
657 | return !aBROwner.IsNull() |
658 | && aBROwner->HasShape() |
659 | && aBROwner->ComesFromDecomposition(); |
7fd59977 |
660 | } |
661 | |
51023771 |
662 | //================================================================ |
663 | // Function : HasSelectedShape |
664 | // Purpose : Checks if there is a selected shape regardless of its decomposition status |
665 | //================================================================ |
666 | Standard_Boolean AIS_LocalContext::HasSelectedShape() const |
667 | { |
02974a19 |
668 | if (!mySelection->More()) |
51023771 |
669 | { |
670 | return Standard_False; |
671 | } |
02974a19 |
672 | |
673 | Handle(StdSelect_BRepOwner) aBrepOwner = Handle(StdSelect_BRepOwner)::DownCast (mySelection->Value()); |
674 | return !aBrepOwner.IsNull() |
675 | && aBrepOwner->HasShape(); |
51023771 |
676 | } |
677 | |
7fd59977 |
678 | //================================================== |
02974a19 |
679 | // Function: SelectedShape |
7fd59977 |
680 | // Purpose : |
681 | //================================================== |
0717ddc1 |
682 | TopoDS_Shape AIS_LocalContext::SelectedShape() const |
7fd59977 |
683 | { |
02974a19 |
684 | if (!mySelection->More()) |
685 | { |
686 | return TopoDS_Shape(); |
687 | } |
688 | |
689 | Handle(StdSelect_BRepOwner) aBRO = Handle(StdSelect_BRepOwner)::DownCast(mySelection->Value()); |
690 | if (aBRO.IsNull()) |
7fd59977 |
691 | { |
d8110103 |
692 | return TopoDS_Shape(); |
7fd59977 |
693 | } |
51023771 |
694 | |
d8110103 |
695 | return aBRO->Shape().Located (aBRO->Location() * aBRO->Shape().Location()); |
7fd59977 |
696 | } |
697 | |
698 | //================================================== |
02974a19 |
699 | // Function: SelectedInteractive |
7fd59977 |
700 | // Purpose : |
701 | //================================================== |
02974a19 |
702 | Handle(AIS_InteractiveObject) AIS_LocalContext::SelectedInteractive() const |
7fd59977 |
703 | { |
02974a19 |
704 | return !mySelection->More() |
705 | ? Handle(AIS_InteractiveObject)() |
706 | : Handle(AIS_InteractiveObject)::DownCast (mySelection->Value()->Selectable()); |
7fd59977 |
707 | } |
02974a19 |
708 | |
7fd59977 |
709 | //================================================== |
02974a19 |
710 | // Function: SelectedOwner |
7fd59977 |
711 | // Purpose : |
712 | //================================================== |
02974a19 |
713 | Handle(SelectMgr_EntityOwner) AIS_LocalContext::SelectedOwner() const |
7fd59977 |
714 | { |
02974a19 |
715 | return !mySelection->More() |
716 | ? Handle(SelectMgr_EntityOwner)() |
717 | : mySelection->Value(); |
7fd59977 |
718 | } |
719 | |
720 | //================================================== |
721 | // Function: |
722 | // Purpose : |
723 | //================================================== |
02974a19 |
724 | Standard_Boolean AIS_LocalContext::HasApplicative() const |
7fd59977 |
725 | { |
02974a19 |
726 | Handle(AIS_InteractiveObject) anIO = SelectedInteractive(); |
727 | return !anIO.IsNull() |
728 | && anIO->HasOwner(); |
7fd59977 |
729 | } |
730 | |
731 | //================================================== |
732 | // Function: |
733 | // Purpose : |
734 | //================================================== |
735 | const Handle(Standard_Transient)& AIS_LocalContext:: |
736 | SelectedApplicative() const |
737 | { |
738 | return SelectedInteractive()->GetOwner(); |
739 | } |
740 | |
741 | |
742 | |
743 | //======================================================================= |
744 | //function : UpdateSelection |
81bba717 |
745 | //purpose : should disappear... |
7fd59977 |
746 | //======================================================================= |
747 | void AIS_LocalContext::UpdateSelected(const Standard_Boolean updateviewer) |
748 | { |
749 | UnhilightPicked(Standard_False); |
750 | HilightPicked(updateviewer); |
751 | } |
752 | |
753 | //================================================================ |
754 | // Function : UpdateSelected |
755 | // Purpose : Part of advanced selection mechanism. |
756 | // Highlightes or clears selection presentation for the given IO |
757 | //================================================================ |
758 | void AIS_LocalContext::UpdateSelected(const Handle(AIS_InteractiveObject)& anobj, |
759 | const Standard_Boolean updateviewer) |
760 | { |
761 | if (anobj.IsNull() || anobj->IsAutoHilight()) |
762 | return; |
763 | |
7fd59977 |
764 | SelectMgr_SequenceOfOwner aSeq; |
02974a19 |
765 | for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next()) |
766 | { |
8e5fb5ea |
767 | if (aSelIter.Value()->IsSameSelectable (anobj)) |
02974a19 |
768 | { |
769 | aSeq.Append (aSelIter.Value()); |
770 | } |
7fd59977 |
771 | } |
772 | |
773 | if ( aSeq.Length() ) |
774 | anobj->HilightSelected( myMainPM, aSeq ); |
775 | else |
776 | anobj->ClearSelected(); |
777 | |
778 | if(updateviewer){ |
779 | myCTX->CurrentViewer()->Update(); |
780 | } |
781 | } |
782 | |
783 | //================================================== |
784 | // Function: ClearSelected |
785 | // Purpose : |
786 | //================================================== |
c398b00e |
787 | void AIS_LocalContext::ClearSelected (const Standard_Boolean updateviewer) |
7fd59977 |
788 | { |
789 | UnhilightPicked(updateviewer); |
02974a19 |
790 | for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next()) |
791 | { |
792 | aSelIter.Value()->SetSelected (Standard_False); |
7fd59977 |
793 | } |
02974a19 |
794 | mySelection->Clear(); |
7fd59977 |
795 | mylastindex = 0; |
796 | } |
797 | |
fb4b684a |
798 | //================================================== |
bc677575 |
799 | // Function: ClearOutdatedSelection |
fb4b684a |
800 | // Purpose : |
801 | //================================================== |
bc677575 |
802 | void AIS_LocalContext::ClearOutdatedSelection (const Handle(AIS_InteractiveObject)& theIO, |
803 | const Standard_Boolean toClearDeactivated) |
fb4b684a |
804 | { |
bc677575 |
805 | // 1. Collect selectable entities |
806 | SelectMgr_IndexedMapOfOwner aValidOwners; |
bc677575 |
807 | const TColStd_ListOfInteger& aModes = SelectionModes (theIO); |
b5cce1ab |
808 | for (TColStd_ListIteratorOfListOfInteger aModeIter (aModes); aModeIter.More(); aModeIter.Next()) |
bc677575 |
809 | { |
b5cce1ab |
810 | const int aMode = aModeIter.Value(); |
bc677575 |
811 | if (!theIO->HasSelection(aMode)) |
812 | { |
813 | continue; |
814 | } |
815 | |
f751596e |
816 | if (toClearDeactivated && !mySM->IsActivated(theIO, aMode, myMainVS)) |
bc677575 |
817 | { |
818 | continue; |
819 | } |
820 | |
b5cce1ab |
821 | const Handle(SelectMgr_Selection)& aSelection = theIO->Selection (aMode); |
822 | for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next()) |
bc677575 |
823 | { |
b5cce1ab |
824 | if (Handle(SelectBasics_SensitiveEntity) anEntity = aSelEntIter.Value()->BaseSensitive()) |
bc677575 |
825 | { |
b5cce1ab |
826 | if (Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast (anEntity->OwnerId())) |
827 | { |
828 | aValidOwners.Add (anOwner); |
829 | } |
bc677575 |
830 | } |
bc677575 |
831 | } |
832 | } |
833 | |
badc9305 |
834 | // 2. Refresh context's detection and selection and keep only active owners. |
fb4b684a |
835 | // Keep last detected object for lastindex initialization. |
badc9305 |
836 | Handle(SelectMgr_EntityOwner) aLastPicked; |
837 | if (IsValidIndex (mylastindex)) |
838 | { |
839 | aLastPicked = myMapOfOwner->FindKey (mylastindex); |
840 | } |
fb4b684a |
841 | |
bc677575 |
842 | // Remove entity owners from detected sequences |
843 | for (Standard_Integer anIdx = 1; anIdx <= myDetectedSeq.Length(); ++anIdx) |
fb4b684a |
844 | { |
bc677575 |
845 | Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (anIdx)); |
8e5fb5ea |
846 | if (anOwner.IsNull() || !anOwner->IsSameSelectable (theIO) || aValidOwners.Contains (anOwner)) |
fb4b684a |
847 | { |
bc677575 |
848 | continue; |
849 | } |
850 | |
851 | myDetectedSeq.Remove (anIdx--); |
d21ddc4f |
852 | if (myCurDetected > anIdx) |
853 | { |
854 | --myCurDetected; |
855 | } |
856 | if (myAISCurDetected > anIdx) |
bc677575 |
857 | { |
d21ddc4f |
858 | --myAISCurDetected; |
fb4b684a |
859 | } |
860 | } |
d21ddc4f |
861 | myCurDetected = Max (myCurDetected, 1); |
862 | myAISCurDetected = Max (myAISCurDetected, 1); |
fb4b684a |
863 | |
c070aa39 |
864 | // 3. AIS_Selection : remove entity owners from AIS_Selection |
bc677575 |
865 | const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer(); |
02974a19 |
866 | NCollection_List<Handle(SelectMgr_EntityOwner)> aRemoveEntites; |
867 | for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next()) |
fb4b684a |
868 | { |
02974a19 |
869 | Handle(SelectMgr_EntityOwner) anOwner = aSelIter.Value(); |
8e5fb5ea |
870 | if (!anOwner->IsSameSelectable (theIO)) |
fb4b684a |
871 | { |
872 | continue; |
873 | } |
874 | |
d21ddc4f |
875 | if (!aValidOwners.Contains (anOwner)) |
fb4b684a |
876 | { |
c070aa39 |
877 | aRemoveEntites.Append (anOwner); |
878 | anOwner->SetSelected (Standard_False); |
6a24c6de |
879 | for (V3d_ListOfViewIterator anActiveViewIter (aViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next()) |
c070aa39 |
880 | { |
6a24c6de |
881 | Unhilight (anOwner, anActiveViewIter.Value()); |
c070aa39 |
882 | } |
fb4b684a |
883 | } |
884 | } |
02974a19 |
885 | |
886 | for (NCollection_List<Handle(SelectMgr_EntityOwner)>::Iterator anIterRemove (aRemoveEntites); |
887 | anIterRemove.More(); anIterRemove.Next()) |
fb4b684a |
888 | { |
016e5959 |
889 | mySelection->Select (anIterRemove.Value()); |
fb4b684a |
890 | } |
891 | |
c070aa39 |
892 | // 4. AIS_LocalContext - myMapOfOwner : remove entity owners from myMapOfOwner |
fb4b684a |
893 | SelectMgr_IndexedMapOfOwner anOwnersToKeep; |
b586500b |
894 | for (Standard_Integer anIdx = 1; anIdx <= myMapOfOwner->Extent(); anIdx++) |
fb4b684a |
895 | { |
b586500b |
896 | Handle(SelectMgr_EntityOwner) anOwner = myMapOfOwner->FindKey (anIdx); |
fb4b684a |
897 | if (anOwner.IsNull()) |
898 | { |
899 | continue; |
900 | } |
901 | |
8e5fb5ea |
902 | if (!anOwner->IsSameSelectable (theIO) || aValidOwners.Contains (anOwner)) |
fb4b684a |
903 | { |
904 | anOwnersToKeep.Add (anOwner); |
905 | } |
906 | else |
907 | { |
6a24c6de |
908 | for (V3d_ListOfViewIterator anActiveViewIter (aViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next()) |
fb4b684a |
909 | { |
6a24c6de |
910 | Unhilight (anOwner, anActiveViewIter.Value()); |
fb4b684a |
911 | } |
912 | } |
913 | } |
b586500b |
914 | myMapOfOwner->Clear(); |
915 | myMapOfOwner->Assign (anOwnersToKeep); |
badc9305 |
916 | |
917 | if (myDetectedSeq.IsEmpty() && !aLastPicked.IsNull()) |
63d907e7 |
918 | { |
919 | myMainPM->ClearImmediateDraw(); |
badc9305 |
920 | mylastindex = 0; |
921 | } |
922 | else if (!aLastPicked.IsNull()) |
923 | { |
924 | // For a case when the last detected owner was unhilighted and removed as outdated we |
925 | // need to check if there were other detected owners with less priority. If yes then |
926 | // one from the remaining should be treated. |
927 | Standard_Integer anIndex = 1, aDetectedSeqLength = myDetectedSeq.Length(); |
928 | for (; anIndex <= aDetectedSeqLength; anIndex++) |
929 | { |
930 | if (aLastPicked == myMainVS->Picked (myDetectedSeq.Value(anIndex))) |
931 | { |
932 | break; // detected owner was not removed |
933 | } |
934 | } |
935 | if (anIndex <= aDetectedSeqLength) |
936 | { |
937 | // Last detected owner was not removed, update mylastindex variable |
938 | mylastindex = myMapOfOwner->FindIndex (aLastPicked); |
939 | } |
940 | else |
941 | { |
942 | // Last detected owner was removed. First object from sequence become detected. |
943 | // Pass any active view because in current implementation the highlighting is |
944 | // synchronized in all view. |
badc9305 |
945 | manageDetected (myMainVS->Picked (myDetectedSeq.First()), |
6a24c6de |
946 | aViewer->ActiveViewIterator().Value(), |
badc9305 |
947 | Standard_False); |
948 | } |
63d907e7 |
949 | } |
fb4b684a |
950 | } |
7fd59977 |
951 | |
952 | //======================================================================= |
953 | //function : SetSelected |
954 | //purpose : |
955 | //======================================================================= |
956 | void AIS_LocalContext::SetSelected(const Handle(AIS_InteractiveObject)& anIObj, |
957 | const Standard_Boolean updateviewer) |
958 | { |
959 | if(!IsValidForSelection(anIObj)) return; |
960 | UnhilightPicked(Standard_False); |
961 | |
81bba717 |
962 | //1st case, owner already <anIObj> as owner |
963 | // and not separated is found... |
7fd59977 |
964 | |
7fd59977 |
965 | Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromIO(anIObj); |
966 | if(EO.IsNull()){ |
0d5880e1 |
967 | //check if global selection there is an owner that can be triturated... |
968 | if (anIObj->HasSelection (anIObj->GlobalSelectionMode())) |
969 | { |
970 | EO = anIObj->GlobalSelOwner(); |
7fd59977 |
971 | } |
972 | if(EO.IsNull()) |
543a9964 |
973 | EO = new SelectMgr_EntityOwner((const Handle(SelectMgr_SelectableObject)&)anIObj); |
7fd59977 |
974 | } |
975 | |
976 | ClearSelected(Standard_False); |
c398b00e |
977 | |
016e5959 |
978 | mySelection->Select(EO); |
c398b00e |
979 | EO->SetSelected (Standard_True); |
980 | |
7fd59977 |
981 | HilightPicked(updateviewer); |
982 | } |
983 | |
984 | //======================================================================= |
985 | //function : AddOrRemoveSelected |
986 | //purpose : |
987 | //======================================================================= |
988 | |
989 | void AIS_LocalContext::AddOrRemoveSelected(const Handle(AIS_InteractiveObject)& anIObj, |
990 | const Standard_Boolean updateviewer) |
991 | { |
992 | if(!IsValidForSelection(anIObj)) return; |
993 | UnhilightPicked(Standard_False); |
81bba717 |
994 | // first check if it is selected... |
7fd59977 |
995 | Handle(SelectMgr_EntityOwner) EO; |
996 | |
997 | EO = FindSelectedOwnerFromIO(anIObj); |
c398b00e |
998 | |
999 | if (EO.IsNull()) |
1000 | { |
0d5880e1 |
1001 | if(anIObj->HasSelection (anIObj->GlobalSelectionMode())) |
c398b00e |
1002 | { |
0d5880e1 |
1003 | EO = anIObj->GlobalSelOwner(); |
7fd59977 |
1004 | } |
c398b00e |
1005 | if(EO.IsNull()) |
1006 | { |
543a9964 |
1007 | EO = new SelectMgr_EntityOwner((const Handle(SelectMgr_SelectableObject)&)anIObj); |
c398b00e |
1008 | } |
7fd59977 |
1009 | } |
016e5959 |
1010 | |
1011 | if (!mySelection.IsNull()) |
c398b00e |
1012 | { |
016e5959 |
1013 | AIS_SelectStatus aStatus = mySelection->Select(EO); |
c398b00e |
1014 | EO->SetSelected (aStatus == AIS_SS_Added); |
7fd59977 |
1015 | } |
c398b00e |
1016 | |
7fd59977 |
1017 | HilightPicked(updateviewer); |
1018 | } |
1019 | |
1020 | //======================================================================= |
1021 | //function : AddOrRemoveSelected |
81bba717 |
1022 | //purpose : To check... |
7fd59977 |
1023 | //======================================================================= |
1024 | void AIS_LocalContext::AddOrRemoveSelected(const TopoDS_Shape& Sh, |
1025 | const Standard_Boolean updateviewer) |
1026 | { |
c398b00e |
1027 | UnhilightPicked (Standard_False); |
7fd59977 |
1028 | Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromShape(Sh); |
c398b00e |
1029 | if (!EO.IsNull()) |
1030 | { |
016e5959 |
1031 | mySelection->Select(EO); |
c398b00e |
1032 | EO->SetSelected (Standard_True); |
7fd59977 |
1033 | } |
c398b00e |
1034 | HilightPicked (updateviewer); |
7fd59977 |
1035 | } |
1036 | |
c398b00e |
1037 | void AIS_LocalContext::AddOrRemoveSelected (const Handle(SelectMgr_EntityOwner)& theOwner, |
1038 | const Standard_Boolean toUpdateViewer) |
1039 | { |
7fd59977 |
1040 | if(myAutoHilight) |
c398b00e |
1041 | { |
1042 | UnhilightPicked (Standard_False); |
1043 | } |
7fd59977 |
1044 | |
c398b00e |
1045 | Standard_Boolean toSelect = theOwner->IsSelected() ? Standard_False : Standard_True; |
1046 | |
016e5959 |
1047 | mySelection->Select(theOwner); |
c398b00e |
1048 | theOwner->SetSelected (toSelect); |
7fd59977 |
1049 | |
7fd59977 |
1050 | if(myAutoHilight) |
c398b00e |
1051 | { |
1052 | HilightPicked (toUpdateViewer); |
1053 | } |
7fd59977 |
1054 | } |
1055 | |
1056 | //================================================== |
679ecdee |
1057 | // Function: manageDetected |
7fd59977 |
1058 | // Purpose : |
1059 | //================================================== |
679ecdee |
1060 | void AIS_LocalContext::manageDetected (const Handle(SelectMgr_EntityOwner)& thePickOwner, |
1061 | const Handle(V3d_View)& theView, |
1062 | const Standard_Boolean theToRedrawImmediate) |
7fd59977 |
1063 | { |
679ecdee |
1064 | if (thePickOwner.IsNull()) |
1065 | { |
63d907e7 |
1066 | myMainPM->ClearImmediateDraw(); |
679ecdee |
1067 | if (theToRedrawImmediate) |
1068 | { |
1069 | theView->RedrawImmediate(); |
1070 | } |
1071 | return; |
1072 | } |
7fd59977 |
1073 | |
679ecdee |
1074 | if (!myFilters->IsOk (thePickOwner)) |
1075 | { |
1076 | if (mylastindex != 0) |
1077 | { |
1078 | mylastgood = mylastindex; |
1079 | } |
1080 | if (theToRedrawImmediate) |
1081 | { |
1082 | theView->RedrawImmediate(); |
1083 | } |
1084 | return; |
1085 | } |
7fd59977 |
1086 | |
679ecdee |
1087 | //======================================================================================================= |
1088 | // 2 cases : a- object is in the map of picks: |
1089 | // 1. this is the same index as the last detected: -> Do nothing |
1090 | // 2. otherwise : |
1091 | // - if lastindex = 0 (no object was detected at the last step) |
1092 | // the object presentation is highlighted and lastindex = index(objet) |
1093 | // - othrwise : |
1094 | // the presentation of the object corresponding to lastindex is "unhighlighted" |
1095 | // it is removed if the object is not visualized but only active |
1096 | // then the presentation of the detected object is highlighted and lastindex = index(objet) |
1097 | // b- the object is not in the map of picked objects |
1098 | // - if lastindex != 0 (object detected at the last step) it is unhighlighted ... |
1099 | // if the object was decomposed, presentation is created for the detected shape and the couple |
1100 | // (Proprietaire,Prs)is added in the map. |
1101 | // otherwise the couple(proprietaire, NullPrs) is placed in the map and the interactive object |
1102 | // itself is highlighted. |
1103 | // |
1104 | //======================================================================================================= |
1105 | |
b586500b |
1106 | const Standard_Integer aNewIndex = myMapOfOwner->Contains (thePickOwner) |
1107 | ? myMapOfOwner->FindIndex (thePickOwner) |
1108 | : myMapOfOwner->Add (thePickOwner); |
679ecdee |
1109 | |
1110 | // For the advanced mesh selection mode the owner indices comparison |
1111 | // is not effective because in that case only one owner manage the |
1112 | // selection in current selection mode. It is necessary to check the current detected |
1113 | // entity and hilight it only if the detected entity is not the same as |
1114 | // previous detected (IsForcedHilight call) |
1115 | if (aNewIndex != mylastindex |
1116 | || thePickOwner->IsForcedHilight()) |
1117 | { |
63d907e7 |
1118 | myMainPM->ClearImmediateDraw(); |
679ecdee |
1119 | if (mylastindex != 0 |
b586500b |
1120 | && mylastindex <= myMapOfOwner->Extent()) |
679ecdee |
1121 | { |
b586500b |
1122 | const Handle(SelectMgr_EntityOwner)& aLastOwner = myMapOfOwner->FindKey (mylastindex); |
679ecdee |
1123 | Unhilight (aLastOwner, theView); |
1124 | } |
7fd59977 |
1125 | |
679ecdee |
1126 | if (myAutoHilight) |
1127 | { |
c398b00e |
1128 | if (!thePickOwner->IsSelected() || myCTX->ToHilightSelected()) |
679ecdee |
1129 | { |
1130 | Hilight (thePickOwner, theView); |
7fd59977 |
1131 | } |
679ecdee |
1132 | if (theToRedrawImmediate) |
1133 | { |
1134 | theView->RedrawImmediate(); |
7fd59977 |
1135 | } |
7fd59977 |
1136 | } |
679ecdee |
1137 | |
1138 | mylastindex = aNewIndex; |
7fd59977 |
1139 | } |
1140 | |
63d907e7 |
1141 | if (mylastindex != 0) |
679ecdee |
1142 | { |
1143 | mylastgood = mylastindex; |
1144 | } |
7fd59977 |
1145 | } |
1146 | |
7fd59977 |
1147 | //======================================================================= |
1148 | //function : HasDetectedShape |
1149 | //purpose : |
1150 | //======================================================================= |
1151 | |
1152 | Standard_Boolean AIS_LocalContext::HasDetectedShape() const |
1153 | { |
1154 | if(mylastindex==0) return Standard_False; |
1155 | return IsShape(mylastindex); |
1156 | } |
1157 | |
1158 | //======================================================================= |
1159 | //function : DetectedShape |
1160 | //purpose : |
1161 | //======================================================================= |
1162 | |
1163 | const TopoDS_Shape& |
1164 | AIS_LocalContext::DetectedShape() const |
1165 | { |
7fd59977 |
1166 | if(mylastindex != 0) |
1167 | { |
b586500b |
1168 | Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(myMapOfOwner->FindKey (mylastindex)); |
896faa72 |
1169 | if(BROwnr.IsNull()) return AIS_LocalContext_myDummyShape; |
7fd59977 |
1170 | return BROwnr->Shape(); |
1171 | } |
896faa72 |
1172 | return AIS_LocalContext_myDummyShape; |
7fd59977 |
1173 | } |
1174 | |
1175 | //======================================================================= |
1176 | //function : DetectedInteractive |
1177 | //purpose : |
1178 | //======================================================================= |
1179 | |
1180 | Handle(AIS_InteractiveObject) |
1181 | AIS_LocalContext::DetectedInteractive() const |
1182 | { |
1183 | Handle(AIS_InteractiveObject) Iobj; |
1184 | if(IsValidIndex(mylastindex)){ |
b586500b |
1185 | Handle(SelectMgr_SelectableObject) SO = myMapOfOwner->FindKey(mylastindex)->Selectable(); |
c5f3a425 |
1186 | Iobj = Handle(AIS_InteractiveObject)::DownCast (SO); |
7fd59977 |
1187 | } |
1188 | return Iobj; |
1189 | } |
1190 | //======================================================================= |
1191 | //function : DetectedInteractive |
1192 | //purpose : |
1193 | //======================================================================= |
1194 | Handle(SelectMgr_EntityOwner) AIS_LocalContext::DetectedOwner() const |
1195 | { |
1196 | Handle(SelectMgr_EntityOwner) bid; |
1197 | if(!IsValidIndex(mylastindex)) return bid; |
b586500b |
1198 | return myMapOfOwner->FindKey(mylastindex); |
7fd59977 |
1199 | } |
1200 | |
1201 | |
1202 | //======================================================================= |
1203 | //function : ComesFromDecomposition |
1204 | //purpose : |
1205 | //======================================================================= |
1206 | |
1207 | Standard_Boolean AIS_LocalContext::ComesFromDecomposition(const Standard_Integer PickedIndex) const |
1208 | { |
b586500b |
1209 | const Handle(SelectMgr_EntityOwner)& OWN = myMapOfOwner->FindKey(PickedIndex); |
7fd59977 |
1210 | Handle(SelectMgr_SelectableObject) aSel = OWN->Selectable(); |
81bba717 |
1211 | if (myActiveObjects.IsBound (aSel)) { // debug of jmi |
7fd59977 |
1212 | const Handle(AIS_LocalStatus)& Stat = myActiveObjects(aSel); |
1213 | return Stat->Decomposed(); |
1214 | } |
1215 | return Standard_False; |
1216 | } |
1217 | |
7fd59977 |
1218 | //======================================================================= |
1219 | //function : DisplaySensitive |
1220 | //purpose : |
1221 | //======================================================================= |
1222 | |
1223 | void AIS_LocalContext::DisplaySensitive(const Handle(V3d_View)& aviou) |
1224 | { |
1225 | myMainVS->DisplaySensitive(aviou); |
1226 | } |
1227 | |
1228 | //======================================================================= |
1229 | //function : ClearSensitive |
1230 | //purpose : |
1231 | //======================================================================= |
1232 | |
1233 | void AIS_LocalContext::ClearSensitive(const Handle(V3d_View)& aviou) |
1234 | { |
1235 | myMainVS->ClearSensitive(aviou); |
1236 | } |
1237 | |
1238 | |
1239 | //======================================================================= |
1240 | //function : IsShape |
1241 | //purpose : |
1242 | //======================================================================= |
1243 | Standard_Boolean AIS_LocalContext::IsShape(const Standard_Integer Index) const |
1244 | { |
5b111128 |
1245 | Handle(SelectMgr_EntityOwner) aEO (myMapOfOwner->FindKey(Index)); |
1246 | if (aEO.IsNull() || ! aEO->IsKind(STANDARD_TYPE(StdSelect_BRepOwner))) |
7fd59977 |
1247 | return Standard_False; |
1248 | return |
1249 | ComesFromDecomposition(Index); |
1250 | } |
1251 | |
1252 | Standard_Boolean AIS_LocalContext::IsValidForSelection(const Handle(AIS_InteractiveObject)& anIObj) const |
1253 | { |
4796758e |
1254 | const Handle(SelectMgr_SelectableObject)& aSelObj = anIObj; // to avoid ambiguity |
7fd59977 |
1255 | // Shape was not transfered from AIS_Shape to EntityOwner |
1256 | Handle(AIS_Shape) shape = Handle(AIS_Shape)::DownCast(anIObj); |
1257 | if( !shape.IsNull() ) |
4796758e |
1258 | return myFilters->IsOk(new StdSelect_BRepOwner(shape->Shape(), aSelObj)); |
1259 | return myFilters->IsOk(new SelectMgr_EntityOwner(aSelObj)); |
7fd59977 |
1260 | } |
1261 | |
1262 | |
1263 | //======================================================================= |
1264 | //function : HilightNextDetected |
679ecdee |
1265 | //purpose : |
7fd59977 |
1266 | //======================================================================= |
679ecdee |
1267 | Standard_Integer AIS_LocalContext::HilightNextDetected (const Handle(V3d_View)& theView, |
1268 | const Standard_Boolean theToRedrawImmediate) |
7fd59977 |
1269 | { |
81bba717 |
1270 | // go to the next owner |
679ecdee |
1271 | if (myDetectedSeq.IsEmpty()) |
1272 | { |
1273 | return 0; |
1274 | } |
7fd59977 |
1275 | |
679ecdee |
1276 | const Standard_Integer aLen = myDetectedSeq.Length(); |
1277 | if (++myCurDetected > aLen) |
1278 | { |
7fd59977 |
1279 | myCurDetected = 1; |
7fd59977 |
1280 | } |
bc677575 |
1281 | Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected)); |
679ecdee |
1282 | if (anOwner.IsNull()) |
1283 | { |
1284 | return 0; |
1285 | } |
1286 | manageDetected (anOwner, theView, theToRedrawImmediate); |
7fd59977 |
1287 | return myCurDetected; |
1288 | } |
1289 | |
1290 | //======================================================================= |
1291 | //function : HilightPreviousDetected |
679ecdee |
1292 | //purpose : |
7fd59977 |
1293 | //======================================================================= |
679ecdee |
1294 | Standard_Integer AIS_LocalContext::HilightPreviousDetected (const Handle(V3d_View)& theView, |
1295 | const Standard_Boolean theToRedrawImmediate) |
7fd59977 |
1296 | { |
679ecdee |
1297 | if (myDetectedSeq.IsEmpty()) |
1298 | { |
1299 | return 0; |
1300 | } |
7fd59977 |
1301 | |
4ca4bbe8 |
1302 | const Standard_Integer aLen = myDetectedSeq.Length(); |
679ecdee |
1303 | if (--myCurDetected < 1) |
1304 | { |
4ca4bbe8 |
1305 | myCurDetected = aLen; |
679ecdee |
1306 | } |
bc677575 |
1307 | Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected)); |
679ecdee |
1308 | if (anOwner.IsNull()) |
1309 | { |
1310 | return 0; |
7fd59977 |
1311 | } |
1312 | |
679ecdee |
1313 | manageDetected (anOwner, theView, theToRedrawImmediate); |
7fd59977 |
1314 | return myCurDetected; |
1315 | } |
1316 | |
1317 | //======================================================================= |
1318 | //function : UnhilightLastDetected |
679ecdee |
1319 | //purpose : |
7fd59977 |
1320 | //======================================================================= |
679ecdee |
1321 | Standard_Boolean AIS_LocalContext::UnhilightLastDetected (const Handle(V3d_View)& theView) |
4679d975 |
1322 | { |
1323 | return UnhilightLastDetected (theView->Viewer()); |
1324 | } |
1325 | |
1326 | //======================================================================= |
1327 | //function : UnhilightLastDetected |
1328 | //purpose : |
1329 | //======================================================================= |
1330 | Standard_Boolean AIS_LocalContext::UnhilightLastDetected (const Handle(V3d_Viewer)& theViewer) |
7fd59977 |
1331 | { |
679ecdee |
1332 | if (!IsValidIndex (mylastindex)) |
1333 | { |
1334 | return Standard_False; |
7fd59977 |
1335 | } |
7fd59977 |
1336 | |
679ecdee |
1337 | myMainPM->BeginImmediateDraw(); |
b586500b |
1338 | const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (mylastindex); |
f838dac4 |
1339 | anOwner->Unhilight (myMainPM); |
4679d975 |
1340 | myMainPM->EndImmediateDraw (theViewer); |
679ecdee |
1341 | mylastindex = 0; |
1342 | return Standard_True; |
7fd59977 |
1343 | } |
1344 | |
1345 | //======================================================================= |
1346 | //function : FindSelectedOwnerFromIO |
81bba717 |
1347 | //purpose : it is checked if one of the selected owners really presents IObj |
7fd59977 |
1348 | //======================================================================= |
02974a19 |
1349 | Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromIO (const Handle(AIS_InteractiveObject)& theObj) const |
7fd59977 |
1350 | { |
1351 | Handle(SelectMgr_EntityOwner) EO,bid; |
02974a19 |
1352 | if (theObj.IsNull() |
1353 | || mySelection.IsNull()) |
1354 | { |
1355 | return Handle(SelectMgr_EntityOwner)(); |
1356 | } |
1357 | |
1358 | for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next()) |
1359 | { |
8e5fb5ea |
1360 | if (!aSelIter.Value()->IsSameSelectable (theObj)) |
02974a19 |
1361 | { |
1362 | continue; |
1363 | } |
1364 | |
1365 | Handle(StdSelect_BRepOwner) aBROwner = Handle(StdSelect_BRepOwner)::DownCast(aSelIter.Value()); |
1366 | if (aBROwner.IsNull() |
1367 | || !aBROwner->ComesFromDecomposition()) |
1368 | { |
1369 | return aSelIter.Value(); |
7fd59977 |
1370 | } |
1371 | } |
02974a19 |
1372 | return Handle(SelectMgr_EntityOwner)(); |
7fd59977 |
1373 | } |
1374 | |
1375 | //======================================================================= |
1376 | //function : FindSelectedOwnerFromShape |
81bba717 |
1377 | //purpose : it is checked if one of the selected owners really presents IObj |
7fd59977 |
1378 | //======================================================================= |
1379 | Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromShape(const TopoDS_Shape& sh) const |
1380 | { |
7fd59977 |
1381 | Handle(SelectMgr_EntityOwner) EO, bid; |
7fd59977 |
1382 | if (sh.IsNull()) return EO; |
1383 | |
016e5959 |
1384 | if(mySelection.IsNull()) { |
7fd59977 |
1385 | return EO; |
1386 | } |
1387 | |
1388 | Standard_Boolean found(Standard_False); |
1389 | |
7fd59977 |
1390 | if (!found) { |
751955d4 |
1391 | NCollection_List<Handle(SelectBasics_EntityOwner)> anActiveOwners; |
1392 | myMainVS->ActiveOwners (anActiveOwners); |
1393 | for (NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt (anActiveOwners); anOwnersIt.More(); anOwnersIt.Next()) |
1394 | { |
f751596e |
1395 | EO = Handle(SelectMgr_EntityOwner)::DownCast (anOwnersIt.Value()); |
7fd59977 |
1396 | Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(EO); |
1397 | if (!BROwnr.IsNull() && BROwnr->HasShape() && BROwnr->Shape() == sh) { |
1398 | found = Standard_True; |
1399 | break; |
1400 | } |
1401 | } |
1402 | } |
7fd59977 |
1403 | |
1404 | if(found) return EO; |
1405 | return bid; |
1406 | } |
1407 | |
7fd59977 |
1408 | //======================================================================= |
1409 | //function : AIS_LocalContext::InitDetected |
1410 | //purpose : |
1411 | //======================================================================= |
7fd59977 |
1412 | void AIS_LocalContext::InitDetected() |
1413 | { |
d21ddc4f |
1414 | myAISCurDetected = !myDetectedSeq.IsEmpty() ? myDetectedSeq.Lower() : 0; |
7fd59977 |
1415 | } |
1416 | |
1417 | //======================================================================= |
1418 | //function : AIS_LocalContext::MoreDetected |
1419 | //purpose : |
1420 | //======================================================================= |
7fd59977 |
1421 | Standard_Boolean AIS_LocalContext::MoreDetected() const |
1422 | { |
d21ddc4f |
1423 | return myAISCurDetected >= myDetectedSeq.Lower() |
1424 | && myAISCurDetected <= myDetectedSeq.Upper(); |
7fd59977 |
1425 | } |
1426 | |
7fd59977 |
1427 | //======================================================================= |
1428 | //function : AIS_LocalContext::NextDetected |
1429 | //purpose : |
1430 | //======================================================================= |
7fd59977 |
1431 | void AIS_LocalContext::NextDetected() |
1432 | { |
57ad5cbd |
1433 | myAISCurDetected++; |
7fd59977 |
1434 | } |
1435 | |
1436 | //======================================================================= |
1437 | //function : DetectedCurrentShape |
1438 | //purpose : |
1439 | //======================================================================= |
7fd59977 |
1440 | const TopoDS_Shape& AIS_LocalContext::DetectedCurrentShape() const |
1441 | { |
57ad5cbd |
1442 | Handle(AIS_Shape) aCurrentShape = Handle(AIS_Shape)::DownCast (DetectedCurrentObject()); |
1443 | |
1444 | if (aCurrentShape.IsNull()) |
1445 | { |
896faa72 |
1446 | return AIS_LocalContext_myDummyShape; |
57ad5cbd |
1447 | } |
1448 | |
1449 | return aCurrentShape->Shape(); |
1450 | } |
d21ddc4f |
1451 | |
1452 | //======================================================================= |
1453 | //function : DetectedCurrentOwner |
1454 | //purpose : |
1455 | //======================================================================= |
1456 | Handle(SelectMgr_EntityOwner) AIS_LocalContext::DetectedCurrentOwner() const |
1457 | { |
1458 | return MoreDetected() |
1459 | ? myMainVS->Picked (myDetectedSeq (myAISCurDetected)) |
1460 | : Handle(SelectMgr_EntityOwner)(); |
1461 | } |
1462 | |
7fd59977 |
1463 | //======================================================================= |
1464 | //function : DetectedCurrentObject |
1465 | //purpose : |
1466 | //======================================================================= |
7fd59977 |
1467 | Handle(AIS_InteractiveObject) AIS_LocalContext::DetectedCurrentObject() const |
1468 | { |
d21ddc4f |
1469 | if (!MoreDetected()) |
1470 | { |
1471 | return Handle(AIS_InteractiveObject)(); |
1472 | } |
1473 | return Handle(AIS_InteractiveObject)::DownCast (myMainVS->Picked (myDetectedSeq (myAISCurDetected))->Selectable()); |
7fd59977 |
1474 | } |
325e442b |
1475 | |
1476 | //======================================================================= |
1477 | //function : RestoreActivatedModes |
1478 | //purpose : |
1479 | //======================================================================= |
1480 | void AIS_LocalContext::RestoreActivatedModes() const |
1481 | { |
1482 | for (AIS_DataMapOfSelStat::Iterator anIter (myActiveObjects); anIter.More(); anIter.Next()) |
1483 | { |
1484 | const TColStd_ListOfInteger& anActivatedModes = anIter.Value()->SelectionModes(); |
1485 | for (TColStd_ListIteratorOfListOfInteger aModesIter (anActivatedModes); aModesIter.More(); aModesIter.Next()) |
1486 | { |
1487 | mySM->Activate (anIter.Key(), aModesIter.Value(), myMainVS); |
1488 | } |
1489 | } |
1490 | } |