b311480e |
1 | // Created on: 1995-02-15 |
2 | // Created by: Roberc Coublanc |
3 | // Copyright (c) 1995-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 ... |
18 | // ROB JAN/07/98 : Improve Storage of detected entities |
19 | // AGV OCT/23/03 : Optimize the method SortResult() (OCC4201) |
20 | |
f751596e |
21 | #include <BVH_Tree.hxx> |
7fd59977 |
22 | #include <gp_Pnt.hxx> |
f751596e |
23 | #include <OSD_Environment.hxx> |
7fd59977 |
24 | #include <Precision.hxx> |
f751596e |
25 | #include <SelectMgr_ViewerSelector.hxx> |
26 | #include <SelectMgr_CompareResults.hxx> |
4269bd1b |
27 | #include <SelectBasics_EntityOwner.hxx> |
7fd59977 |
28 | #include <SelectBasics_SensitiveEntity.hxx> |
f751596e |
29 | #include <SelectBasics_PickResult.hxx> |
30 | #include <SelectMgr_EntityOwner.hxx> |
7fd59977 |
31 | #include <SelectMgr_SortCriterion.hxx> |
f751596e |
32 | #include <SelectMgr_SensitiveEntitySet.hxx> |
7fd59977 |
33 | #include <SortTools_QuickSortOfInteger.hxx> |
f751596e |
34 | #include <TColStd_Array1OfInteger.hxx> |
35 | #include <TCollection_AsciiString.hxx> |
36 | #include <TColStd_HArray1OfInteger.hxx> |
37 | #include <TColStd_ListOfInteger.hxx> |
38 | |
39 | IMPLEMENT_STANDARD_HANDLE (SelectMgr_ViewerSelector, MMgt_TShared) |
40 | IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_ViewerSelector, MMgt_TShared) |
7fd59977 |
41 | |
28ee613b |
42 | //======================================================================= |
43 | // function: SelectMgr_ToleranceMap |
44 | // purpose : Sets tolerance values to -1.0 |
45 | //======================================================================= |
f751596e |
46 | SelectMgr_ToleranceMap::SelectMgr_ToleranceMap() |
47 | { |
28ee613b |
48 | myLargestKey = -1.0; |
49 | myCustomTolerance = -1.0; |
f751596e |
50 | } |
51 | |
28ee613b |
52 | //======================================================================= |
53 | // function: ~SelectMgr_ToleranceMap |
54 | // purpose : |
55 | //======================================================================= |
f751596e |
56 | SelectMgr_ToleranceMap::~SelectMgr_ToleranceMap() |
4269bd1b |
57 | { |
f751596e |
58 | myTolerances.Clear(); |
59 | } |
60 | |
28ee613b |
61 | //======================================================================= |
62 | // function: Add |
63 | // purpose : Adds the value given to map, checks if the current tolerance value |
64 | // should be replaced by theTolerance |
65 | //======================================================================= |
f751596e |
66 | void SelectMgr_ToleranceMap::Add (const Standard_Real& theTolerance) |
67 | { |
68 | if (myTolerances.IsBound (theTolerance)) |
69 | { |
70 | Standard_Integer& aFreq = myTolerances.ChangeFind (theTolerance); |
71 | aFreq++; |
72 | |
28ee613b |
73 | if (aFreq == 1 && theTolerance != myLargestKey) |
74 | myLargestKey = Max (theTolerance, myLargestKey); |
f751596e |
75 | } |
76 | else |
4269bd1b |
77 | { |
f751596e |
78 | if (myTolerances.IsEmpty()) |
79 | { |
80 | myTolerances.Bind (theTolerance, 1); |
81 | myLargestKey = theTolerance; |
82 | return; |
83 | } |
4269bd1b |
84 | |
f751596e |
85 | myTolerances.Bind (theTolerance, 1); |
28ee613b |
86 | myLargestKey = Max (theTolerance, myLargestKey); |
f751596e |
87 | } |
88 | } |
89 | |
28ee613b |
90 | //======================================================================= |
91 | // function: Decrement |
92 | // purpose : Decrements a counter of the tolerance given, checks if the current tolerance value |
93 | // should be recalculated |
94 | //======================================================================= |
f751596e |
95 | void SelectMgr_ToleranceMap::Decrement (const Standard_Real& theTolerance) |
96 | { |
97 | if (myTolerances.IsBound (theTolerance)) |
98 | { |
99 | Standard_Integer& aFreq = myTolerances.ChangeFind (theTolerance); |
100 | aFreq--; |
101 | |
28ee613b |
102 | if (Abs (theTolerance - myLargestKey) < Precision::Confusion() && aFreq == 0) |
f751596e |
103 | { |
28ee613b |
104 | myLargestKey = 0.0; |
f751596e |
105 | for (NCollection_DataMap<Standard_Real, Standard_Integer>::Iterator anIter (myTolerances); anIter.More(); anIter.Next()) |
4269bd1b |
106 | { |
28ee613b |
107 | if (anIter.Value() != 0) |
108 | myLargestKey = Max (myLargestKey, anIter.Key()); |
4269bd1b |
109 | } |
4269bd1b |
110 | } |
f751596e |
111 | } |
112 | } |
113 | |
28ee613b |
114 | //======================================================================= |
115 | // function: Tolerance |
116 | // purpose : Returns a current tolerance that must be applied |
117 | //======================================================================= |
118 | Standard_Real SelectMgr_ToleranceMap::Tolerance() |
f751596e |
119 | { |
28ee613b |
120 | return myCustomTolerance < 0.0 ? myLargestKey : myCustomTolerance; |
121 | } |
122 | |
123 | //======================================================================= |
124 | // function: SetCustomTolerance |
125 | // purpose : Sets tolerance to the given one and disables adaptive checks |
126 | //======================================================================= |
127 | void SelectMgr_ToleranceMap::SetCustomTolerance (const Standard_Real theTolerance) |
128 | { |
129 | myCustomTolerance = theTolerance; |
130 | } |
131 | |
132 | //======================================================================= |
133 | // function: ResetDefaults |
134 | // purpose : Unsets a custom tolerance and enables adaptive checks |
135 | //======================================================================= |
136 | void SelectMgr_ToleranceMap::ResetDefaults() |
137 | { |
138 | myCustomTolerance = -1.0; |
f751596e |
139 | } |
4269bd1b |
140 | |
7fd59977 |
141 | //================================================== |
142 | // Function: Initialize |
143 | // Purpose : |
144 | //================================================== |
145 | SelectMgr_ViewerSelector::SelectMgr_ViewerSelector(): |
7fd59977 |
146 | preferclosest(Standard_True), |
f751596e |
147 | mytolerance(2.0), |
148 | myToUpdateTolerance (Standard_True), |
149 | myCurRank (0), |
150 | myIsLeftChildQueuedFirst (Standard_False), |
151 | myEntityIdx (0) |
7fd59977 |
152 | { |
f751596e |
153 | mySelectableObjects = new SelectMgr_SelectableObjectSet(); |
7fd59977 |
154 | } |
155 | |
156 | |
157 | //================================================== |
158 | // Function: Activate |
159 | // Purpose : |
160 | //================================================== |
f751596e |
161 | void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSelection) |
7fd59977 |
162 | { |
f751596e |
163 | for (theSelection->Init(); theSelection->More(); theSelection->Next()) |
7fd59977 |
164 | { |
f751596e |
165 | theSelection->Sensitive()->SetActiveForSelection(); |
4269bd1b |
166 | } |
7fd59977 |
167 | |
f751596e |
168 | theSelection->SetSelectionState (SelectMgr_SOS_Activated); |
7fd59977 |
169 | |
f751596e |
170 | myTolerances.Add (theSelection->Sensitivity()); |
28ee613b |
171 | mytolerance = myTolerances.Tolerance(); |
f751596e |
172 | myToUpdateTolerance = Standard_True; |
7fd59977 |
173 | } |
174 | |
175 | |
7fd59977 |
176 | //================================================== |
f751596e |
177 | // Function: Deactivate |
7fd59977 |
178 | // Purpose : |
179 | //================================================== |
f751596e |
180 | void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theSelection) |
4269bd1b |
181 | { |
f751596e |
182 | for (theSelection->Init(); theSelection->More(); theSelection->Next()) |
183 | { |
184 | theSelection->Sensitive()->ResetSelectionActiveStatus(); |
7fd59977 |
185 | } |
7fd59977 |
186 | |
f751596e |
187 | theSelection->SetSelectionState (SelectMgr_SOS_Deactivated); |
7fd59977 |
188 | |
f751596e |
189 | myTolerances.Decrement (theSelection->Sensitivity()); |
28ee613b |
190 | mytolerance = myTolerances.Tolerance(); |
f751596e |
191 | myToUpdateTolerance = Standard_True; |
7fd59977 |
192 | } |
193 | |
7fd59977 |
194 | //================================================== |
195 | // Function: Clear |
196 | // Purpose : |
197 | //================================================== |
198 | void SelectMgr_ViewerSelector::Clear() |
199 | { |
7fd59977 |
200 | mystored.Clear(); |
f751596e |
201 | myMapOfDetected.Clear(); |
7fd59977 |
202 | } |
203 | |
28ee613b |
204 | //======================================================================= |
205 | // function: isToScaleFrustum |
206 | // purpose : Checks if the entity given requires to scale current selecting frustum |
207 | //======================================================================= |
208 | Standard_Boolean SelectMgr_ViewerSelector::isToScaleFrustum (const Handle(SelectBasics_SensitiveEntity)& theEntity) |
209 | { |
210 | return mySelectingVolumeMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point |
211 | && theEntity->SensitivityFactor() < myTolerances.Tolerance(); |
212 | } |
213 | |
214 | //======================================================================= |
215 | // function: scaleAndTransform |
216 | // purpose : Applies given scale and transformation matrices to the default selecting volume manager |
217 | //======================================================================= |
218 | SelectMgr_SelectingVolumeManager SelectMgr_ViewerSelector::scaleAndTransform (const Standard_Real theScale, |
219 | const gp_Trsf& theTrsf) |
220 | { |
221 | SelectMgr_SelectingVolumeManager aMgr; |
222 | |
223 | if (theScale > Precision::Angular()) |
224 | { |
225 | aMgr = mySelectingVolumeMgr.Scale (theScale); |
226 | } |
227 | |
228 | if (theTrsf.Form() != gp_Identity) |
229 | { |
230 | aMgr = aMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Unknown ? |
231 | mySelectingVolumeMgr.Transform (theTrsf) : aMgr.Transform (theTrsf); |
232 | } |
233 | |
234 | return aMgr; |
235 | } |
236 | |
f751596e |
237 | //======================================================================= |
238 | // function: checkOverlap |
239 | // purpose : Internal function that checks if a particular sensitive |
240 | // entity theEntity overlaps current selecting volume precisely |
241 | //======================================================================= |
242 | void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_SensitiveEntity)& theEntity, |
243 | const Standard_Integer theEntityIdx, |
244 | SelectMgr_SelectingVolumeManager& theMgr) |
7fd59977 |
245 | { |
f751596e |
246 | const Handle(SelectMgr_EntityOwner)& anOwner = |
247 | Handle(SelectMgr_EntityOwner)::DownCast (theEntity->OwnerId()); |
7fd59977 |
248 | |
f751596e |
249 | SelectBasics_PickResult aPickResult; |
250 | if (theEntity->Matches (theMgr, aPickResult)) |
251 | { |
252 | if (!anOwner.IsNull()) |
253 | { |
28ee613b |
254 | if (HasDepthClipping (anOwner) && theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point) |
f751596e |
255 | { |
256 | Standard_Boolean isClipped = theMgr.IsClipped (anOwner->Selectable()->GetClipPlanes(), |
257 | aPickResult.Depth()); |
258 | if (isClipped) |
259 | return; |
260 | } |
7fd59977 |
261 | |
f751596e |
262 | Standard_Integer aPriority = anOwner->Priority(); |
7fd59977 |
263 | |
f751596e |
264 | SelectMgr_SortCriterion aCriterion (aPriority, aPickResult.Depth(), aPickResult.DistToGeomCenter(), theEntity->SensitivityFactor() / 33, preferclosest); |
265 | if (mystored.Contains (anOwner)) |
4269bd1b |
266 | { |
f751596e |
267 | if (theMgr.GetActiveSelectionType() != 1) |
268 | { |
269 | SelectMgr_SortCriterion& aPrevCriterion = mystored.ChangeFromKey (anOwner); |
270 | if (aCriterion > aPrevCriterion) |
271 | { |
272 | aPrevCriterion = aCriterion; |
273 | myMapOfDetected.ChangeFind (anOwner) = theEntityIdx; |
7fd59977 |
274 | } |
275 | } |
276 | } |
f751596e |
277 | else |
278 | { |
279 | mystored.Add (anOwner, aCriterion); |
280 | myMapOfDetected.Bind (anOwner, theEntityIdx); |
7fd59977 |
281 | } |
282 | } |
7fd59977 |
283 | } |
284 | } |
285 | |
f751596e |
286 | //======================================================================= |
287 | // function: traverseObject |
288 | // purpose : Internal function that checks if there is possible overlap |
289 | // between some entity of selectable object theObject and |
290 | // current selecting volume |
291 | //======================================================================= |
292 | void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_SelectableObject)& theObject) |
7fd59977 |
293 | { |
f751596e |
294 | NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = |
295 | myMapOfObjectSensitives.ChangeFind (theObject); |
7fd59977 |
296 | |
f751596e |
297 | if (anEntitySet->Size() == 0) |
298 | return; |
7fd59977 |
299 | |
f751596e |
300 | const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH(); |
7fd59977 |
301 | |
f751596e |
302 | SelectMgr_SelectingVolumeManager aMgr = theObject->HasTransformation() ? |
303 | mySelectingVolumeMgr.Transform (theObject->InversedTransformation()) : mySelectingVolumeMgr; |
7fd59977 |
304 | |
28ee613b |
305 | NCollection_DataMap<Handle(Standard_Type), SelectMgr_SelectingVolumeManager> aScaledTrnsfFrustums; |
306 | |
f751596e |
307 | Standard_Integer aNode = 0; // a root node |
308 | if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0), |
309 | aSensitivesTree->MaxPoint (0))) |
310 | { |
311 | return; |
7fd59977 |
312 | } |
f751596e |
313 | Standard_Integer aStack[32]; |
314 | Standard_Integer aHead = -1; |
315 | for (;;) |
316 | { |
317 | if (!aSensitivesTree->IsOuter (aNode)) |
318 | { |
319 | const Standard_Integer aLeftChildIdx = aSensitivesTree->LeftChild (aNode); |
320 | const Standard_Integer aRightChildIdx = aSensitivesTree->RightChild (aNode); |
321 | const Standard_Boolean isLeftChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aLeftChildIdx), |
322 | aSensitivesTree->MaxPoint (aLeftChildIdx)); |
323 | const Standard_Boolean isRightChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aRightChildIdx), |
324 | aSensitivesTree->MaxPoint (aRightChildIdx)); |
325 | if (isLeftChildIn |
326 | && isRightChildIn) |
327 | { |
328 | aNode = aLeftChildIdx; |
329 | ++aHead; |
330 | aStack[aHead] = aRightChildIdx; |
331 | } |
332 | else if (isLeftChildIn |
333 | || isRightChildIn) |
334 | { |
335 | aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx; |
336 | } |
337 | else |
338 | { |
339 | if (aHead < 0) |
340 | { |
341 | break; |
342 | } |
7fd59977 |
343 | |
f751596e |
344 | aNode = aStack[aHead]; |
345 | --aHead; |
346 | } |
347 | } |
348 | else |
349 | { |
350 | Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode); |
351 | Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode); |
352 | for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx) |
353 | { |
7ab15952 |
354 | const Handle(SelectMgr_SensitiveEntity)& aSensitive = |
f751596e |
355 | anEntitySet->GetSensitiveById (anIdx); |
356 | if (aSensitive->IsActiveForSelection()) |
357 | { |
28ee613b |
358 | const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive(); |
359 | SelectMgr_SelectingVolumeManager aTmpMgr = aMgr; |
360 | if (isToScaleFrustum (anEnt)) |
361 | { |
362 | if (!aScaledTrnsfFrustums.IsBound (anEnt->DynamicType())) |
363 | { |
364 | aScaledTrnsfFrustums.Bind (anEnt->DynamicType(), |
365 | scaleAndTransform (anEnt->SensitivityFactor(), theObject->InversedTransformation())); |
366 | } |
367 | |
368 | aTmpMgr = aScaledTrnsfFrustums.Find (anEnt->DynamicType()); |
369 | } |
370 | checkOverlap (anEnt, anIdx, aTmpMgr); |
f751596e |
371 | } |
372 | } |
373 | if (aHead < 0) |
374 | { |
375 | break; |
376 | } |
7fd59977 |
377 | |
f751596e |
378 | aNode = aStack[aHead]; |
379 | --aHead; |
380 | } |
7fd59977 |
381 | } |
382 | } |
383 | |
f751596e |
384 | //======================================================================= |
385 | // function: TraverseSensitives |
386 | // purpose : Traverses BVH containing all added selectable objects and |
387 | // finds candidates for further search of overlap |
388 | //======================================================================= |
389 | void SelectMgr_ViewerSelector::TraverseSensitives() |
7fd59977 |
390 | { |
391 | mystored.Clear(); |
f751596e |
392 | myMapOfDetected.Clear(); |
7fd59977 |
393 | |
f751596e |
394 | if (mySelectableObjects->Size() == 0) |
395 | return; |
7fd59977 |
396 | |
f751596e |
397 | const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& anObjectsTree = mySelectableObjects->BVH(); |
7fd59977 |
398 | |
f751596e |
399 | Standard_Integer aNode = 0; |
400 | if (!mySelectingVolumeMgr.Overlaps (anObjectsTree->MinPoint (0), |
401 | anObjectsTree->MaxPoint (0))) |
7fd59977 |
402 | { |
f751596e |
403 | return; |
404 | } |
405 | Standard_Integer aStack[32]; |
406 | Standard_Integer aHead = -1; |
407 | for (;;) |
408 | { |
409 | if (!anObjectsTree->IsOuter (aNode)) |
4269bd1b |
410 | { |
f751596e |
411 | const Standard_Integer aLeftChildIdx = anObjectsTree->LeftChild (aNode); |
412 | const Standard_Integer aRightChildIdx = anObjectsTree->RightChild (aNode); |
413 | const Standard_Boolean isLeftChildIn = |
414 | mySelectingVolumeMgr.Overlaps (anObjectsTree->MinPoint (aLeftChildIdx), |
415 | anObjectsTree->MaxPoint (aLeftChildIdx)); |
416 | const Standard_Boolean isRightChildIn = |
417 | mySelectingVolumeMgr.Overlaps (anObjectsTree->MinPoint (aRightChildIdx), |
418 | anObjectsTree->MaxPoint (aRightChildIdx)); |
419 | if (isLeftChildIn |
420 | && isRightChildIn) |
4269bd1b |
421 | { |
f751596e |
422 | aNode = aLeftChildIdx; |
423 | ++aHead; |
424 | aStack[aHead] = aRightChildIdx; |
425 | } |
426 | else if (isLeftChildIn |
427 | || isRightChildIn) |
428 | { |
429 | aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx; |
430 | } |
431 | else |
432 | { |
433 | if (aHead < 0) |
4269bd1b |
434 | { |
f751596e |
435 | break; |
4269bd1b |
436 | } |
7fd59977 |
437 | |
f751596e |
438 | aNode = aStack[aHead]; |
439 | --aHead; |
7fd59977 |
440 | } |
441 | } |
f751596e |
442 | else |
443 | { |
444 | Standard_Integer aStartIdx = anObjectsTree->BegPrimitive (aNode); |
445 | Standard_Integer anEndIdx = anObjectsTree->EndPrimitive (aNode); |
446 | for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx) |
447 | { |
448 | traverseObject (mySelectableObjects->GetObjectById (anIdx)); |
449 | } |
450 | if (aHead < 0) |
451 | { |
452 | break; |
453 | } |
4269bd1b |
454 | |
f751596e |
455 | aNode = aStack[aHead]; |
456 | --aHead; |
457 | } |
7fd59977 |
458 | } |
4269bd1b |
459 | |
f751596e |
460 | SortResult(); |
7fd59977 |
461 | } |
4269bd1b |
462 | |
7fd59977 |
463 | //================================================== |
464 | // Function: Picked |
465 | // Purpose : |
466 | //================================================== |
467 | Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector |
468 | ::Picked() const |
469 | { |
f751596e |
470 | Standard_Integer RankInMap = myIndexes->Value (myCurRank); |
7fd59977 |
471 | const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap); |
472 | Handle(SelectMgr_EntityOwner) Ownr = *((Handle(SelectMgr_EntityOwner)*) &toto); |
473 | return Ownr; |
474 | } |
475 | |
476 | |
477 | |
478 | //======================================================================= |
479 | //function : More |
4269bd1b |
480 | //purpose : |
7fd59977 |
481 | //======================================================================= |
4269bd1b |
482 | Standard_Boolean SelectMgr_ViewerSelector::More() |
7fd59977 |
483 | { |
484 | if(mystored.Extent()==0) return Standard_False; |
485 | if(myCurRank==0) return Standard_False; |
486 | return myCurRank <= myIndexes->Length(); |
487 | } |
488 | |
489 | //================================================== |
490 | // Function: OnePicked |
491 | // Purpose : only the best one is chosen |
492 | // depend on priority and mindist... |
493 | //================================================== |
494 | |
495 | Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector |
496 | ::OnePicked() |
497 | { |
498 | |
499 | Init(); |
500 | if(More()){ |
f751596e |
501 | Standard_Integer RankInMap = myIndexes->Value (myIndexes->Lower()); |
7fd59977 |
502 | const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap); |
503 | Handle(SelectMgr_EntityOwner) Ownr = *((Handle(SelectMgr_EntityOwner)*) &toto); |
504 | return Ownr; |
505 | } |
506 | |
507 | Handle (SelectMgr_EntityOwner) NullObj; //returns a null Handle if there was not successfull pick... |
508 | return NullObj; |
509 | } |
510 | |
511 | |
512 | //======================================================================= |
513 | //function : NbPicked |
4269bd1b |
514 | //purpose : |
7fd59977 |
515 | //======================================================================= |
516 | |
517 | Standard_Integer SelectMgr_ViewerSelector::NbPicked() const |
518 | { |
519 | return mystored.Extent(); |
520 | } |
521 | //======================================================================= |
522 | //function : Picked |
4269bd1b |
523 | //purpose : |
7fd59977 |
524 | //======================================================================= |
525 | Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked(const Standard_Integer aRank) const |
526 | { |
527 | |
f751596e |
528 | Handle(SelectMgr_EntityOwner) anOwner; |
529 | if (aRank < 1 || aRank > NbPicked()) |
530 | return anOwner; |
531 | Standard_Integer anOwnerIdx = myIndexes->Value (aRank); |
7fd59977 |
532 | |
533 | |
f751596e |
534 | const Handle(SelectBasics_EntityOwner)& aStoredOwner = mystored.FindKey (anOwnerIdx); |
535 | anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aStoredOwner); |
536 | return anOwner; |
7fd59977 |
537 | } |
538 | |
7fd59977 |
539 | //=================================================== |
540 | // |
541 | // INTERNAL METHODS .... |
542 | // |
543 | //================================================== |
544 | |
7fd59977 |
545 | //================================================== |
546 | // Function: Contains |
4269bd1b |
547 | // Purpose : |
7fd59977 |
548 | //================================================== |
f751596e |
549 | Standard_Boolean SelectMgr_ViewerSelector::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const |
7fd59977 |
550 | { |
f751596e |
551 | return mySelectableObjects->Contains (theObject); |
7fd59977 |
552 | } |
553 | |
7fd59977 |
554 | //================================================== |
555 | // Function: ActiveModes |
556 | // Purpose : return all the modes with a given state for an object |
557 | //================================================== |
f751596e |
558 | Standard_Boolean SelectMgr_ViewerSelector::Modes (const Handle(SelectMgr_SelectableObject)& theSelectableObject, |
559 | TColStd_ListOfInteger& theModeList, |
560 | const SelectMgr_StateOfSelection theWantedState) const |
7fd59977 |
561 | { |
f751596e |
562 | Standard_Boolean hasActivatedStates = mySelectableObjects->Contains (theSelectableObject); |
563 | for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next()) |
564 | { |
565 | if (theWantedState == SelectMgr_SOS_Any) |
566 | { |
567 | theModeList.Append (theSelectableObject->CurrentSelection()->Mode()); |
568 | } |
569 | else if (theWantedState == theSelectableObject->CurrentSelection()->GetSelectionState()) |
570 | { |
571 | theModeList.Append (theSelectableObject->CurrentSelection()->Mode()); |
572 | } |
7fd59977 |
573 | } |
7fd59977 |
574 | |
f751596e |
575 | return hasActivatedStates; |
576 | } |
7fd59977 |
577 | |
f751596e |
578 | //================================================== |
579 | // Function: IsActive |
580 | // Purpose : |
581 | //================================================== |
582 | Standard_Boolean SelectMgr_ViewerSelector::IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject, |
583 | const Standard_Integer theMode) const |
7fd59977 |
584 | { |
f751596e |
585 | if (!mySelectableObjects->Contains (theSelectableObject)) |
586 | return Standard_False; |
587 | |
588 | for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next()) |
589 | { |
590 | if (theMode == theSelectableObject->CurrentSelection()->Mode()) |
591 | { |
592 | return theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated; |
7fd59977 |
593 | } |
594 | } |
f751596e |
595 | |
7fd59977 |
596 | return Standard_False; |
597 | } |
598 | |
f751596e |
599 | //================================================== |
600 | // Function: IsInside |
601 | // Purpose : |
602 | //================================================== |
603 | Standard_Boolean SelectMgr_ViewerSelector::IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject, |
604 | const Standard_Integer theMode) const |
7fd59977 |
605 | { |
f751596e |
606 | if (!mySelectableObjects->Contains (theSelectableObject)) |
607 | return Standard_False; |
7fd59977 |
608 | |
f751596e |
609 | for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next()) |
610 | { |
611 | if (theMode == theSelectableObject->CurrentSelection()->Mode()) |
612 | { |
613 | return theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown; |
7fd59977 |
614 | } |
615 | } |
f751596e |
616 | |
7fd59977 |
617 | return Standard_False; |
618 | } |
619 | |
620 | |
621 | //======================================================================= |
622 | //function : Status |
4269bd1b |
623 | //purpose : |
7fd59977 |
624 | //======================================================================= |
625 | |
f751596e |
626 | SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_Selection)& theSelection) const |
7fd59977 |
627 | { |
f751596e |
628 | return theSelection->GetSelectionState(); |
7fd59977 |
629 | } |
630 | |
7fd59977 |
631 | //================================================== |
632 | // Function: Status |
633 | // Purpose : gives Information about selectors |
634 | //================================================== |
635 | |
f751596e |
636 | TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const |
7fd59977 |
637 | { |
f751596e |
638 | TCollection_AsciiString aStatus ("Status Object :\n\t"); |
639 | |
640 | for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next()) |
641 | { |
642 | if (theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown) |
7fd59977 |
643 | { |
f751596e |
644 | aStatus = aStatus + "Mode " + |
645 | TCollection_AsciiString (theSelectableObject->CurrentSelection()->Mode()) + |
646 | " present - "; |
647 | if (theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated) |
648 | { |
649 | aStatus = aStatus + " Active \n\t"; |
650 | } |
7fd59977 |
651 | else |
f751596e |
652 | { |
653 | aStatus = aStatus + " Inactive \n\t"; |
654 | } |
7fd59977 |
655 | } |
656 | } |
657 | |
f751596e |
658 | if (mySelectableObjects->Contains (theSelectableObject)) |
7fd59977 |
659 | { |
f751596e |
660 | aStatus = aStatus + "Not Present in the selector\n\n"; |
7fd59977 |
661 | } |
f751596e |
662 | |
663 | return aStatus; |
7fd59977 |
664 | } |
665 | |
666 | //======================================================================= |
667 | //function : SortResult |
4269bd1b |
668 | //purpose : there is a certain number of entities ranged by criteria |
81bba717 |
669 | // (depth, size, priority, mouse distance from borders or |
670 | // CDG of the detected primitive. Parsing : |
671 | // maximum priorities . |
672 | // then a reasonable compromise between depth and distance... |
673 | // finally the ranges are stored in myindexes depending on the parsing. |
4269bd1b |
674 | // so, it is possible to only read |
7fd59977 |
675 | //======================================================================= |
676 | void SelectMgr_ViewerSelector::SortResult() |
677 | { |
678 | if(mystored.IsEmpty()) return; |
679 | |
680 | const Standard_Integer anExtent = mystored.Extent(); |
681 | if(myIndexes.IsNull() || anExtent != myIndexes->Length()) |
682 | myIndexes = new TColStd_HArray1OfInteger (1, anExtent); |
683 | |
81bba717 |
684 | // to work faster... |
7fd59977 |
685 | TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1(); |
686 | |
81bba717 |
687 | // indices from 1 to N are loaded |
7fd59977 |
688 | Standard_Integer I ; |
689 | for (I=1; I <= anExtent; I++) |
690 | thearr(I)=I; |
691 | |
7fd59977 |
692 | SortTools_QuickSortOfInteger::Sort (thearr, |
693 | SelectMgr_CompareResults(mystored)); |
f751596e |
694 | } |
695 | |
696 | //======================================================================= |
697 | //function : HasDepthClipping |
698 | //purpose : Stub |
699 | //======================================================================= |
700 | Standard_Boolean SelectMgr_ViewerSelector::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& /*theOwner*/) const |
701 | { |
702 | return Standard_False; |
703 | } |
704 | |
705 | //======================================================================= |
706 | // function : AddSelectableObject |
707 | // purpose : Adds new object to the map of selectable objects |
708 | //======================================================================= |
709 | void SelectMgr_ViewerSelector::AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject) |
710 | { |
711 | if (!myMapOfObjectSensitives.IsBound (theObject)) |
712 | { |
713 | mySelectableObjects->Append (theObject); |
714 | NCollection_Handle<SelectMgr_SensitiveEntitySet> anEntitySet = new SelectMgr_SensitiveEntitySet(); |
715 | myMapOfObjectSensitives.Bind (theObject, anEntitySet); |
7fd59977 |
716 | } |
f751596e |
717 | } |
7fd59977 |
718 | |
f751596e |
719 | //======================================================================= |
720 | // function : AddSelectionToObject |
721 | // purpose : Adds new selection to the object and builds its BVH tree |
722 | //======================================================================= |
723 | void SelectMgr_ViewerSelector::AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject, |
724 | const Handle(SelectMgr_Selection)& theSelection) |
725 | { |
726 | if (myMapOfObjectSensitives.IsBound (theObject)) |
727 | { |
728 | NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = |
729 | myMapOfObjectSensitives.ChangeFind (theObject); |
730 | anEntitySet->Append (theSelection); |
731 | anEntitySet->BVH(); |
732 | } |
733 | else |
734 | { |
735 | AddSelectableObject (theObject); |
736 | AddSelectionToObject (theObject, theSelection); |
737 | } |
7fd59977 |
738 | } |
739 | |
f751596e |
740 | //======================================================================= |
741 | // function : RemoveSelectableObject |
742 | // purpose : Removes selectable object from map of selectable ones |
743 | //======================================================================= |
744 | void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject) |
745 | { |
746 | if (myMapOfObjectSensitives.IsBound (theObject)) |
747 | { |
748 | myMapOfObjectSensitives.UnBind (theObject); |
749 | mySelectableObjects->Remove (theObject); |
750 | } |
751 | } |
7fd59977 |
752 | |
753 | //======================================================================= |
f751596e |
754 | // function : RemoveSelectionOfObject |
755 | // purpose : Removes selection of the object and marks its BVH tree |
756 | // for rebuild |
7fd59977 |
757 | //======================================================================= |
f751596e |
758 | void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject, |
759 | const Handle(SelectMgr_Selection)& theSelection) |
7fd59977 |
760 | { |
f751596e |
761 | if (myMapOfObjectSensitives.IsBound (theObject)) |
762 | { |
763 | NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = |
764 | myMapOfObjectSensitives.ChangeFind (theObject); |
765 | anEntitySet->Remove (theSelection); |
766 | } |
7fd59977 |
767 | } |
768 | |
769 | //======================================================================= |
f751596e |
770 | // function : RebuildObjectsTree |
771 | // purpose : Marks BVH of selectable objects for rebuild |
7fd59977 |
772 | //======================================================================= |
f751596e |
773 | void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce) |
7fd59977 |
774 | { |
f751596e |
775 | mySelectableObjects->MarkDirty(); |
776 | |
777 | if (theIsForce) |
778 | { |
779 | mySelectableObjects->BVH(); |
780 | } |
7fd59977 |
781 | } |
4269bd1b |
782 | |
783 | //======================================================================= |
f751596e |
784 | // function : RebuildSensitivesTree |
785 | // purpose : Marks BVH of sensitive entities of particular selectable |
786 | // object for rebuild |
4269bd1b |
787 | //======================================================================= |
f751596e |
788 | void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject, |
789 | const Standard_Boolean theIsForce) |
4269bd1b |
790 | { |
f751596e |
791 | if (!mySelectableObjects->Contains (theObject)) |
792 | return; |
793 | |
794 | NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject); |
795 | anEntitySet->MarkDirty(); |
796 | |
797 | if (theIsForce) |
798 | { |
799 | anEntitySet->BVH(); |
800 | } |
4269bd1b |
801 | } |
802 | |
803 | //======================================================================= |
f751596e |
804 | // function : resetSelectionActivationStatus |
805 | // purpose : Marks all added sensitive entities of all objects as |
806 | // non-selectable |
4269bd1b |
807 | //======================================================================= |
f751596e |
808 | void SelectMgr_ViewerSelector::resetSelectionActivationStatus() |
4269bd1b |
809 | { |
f751596e |
810 | SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives); |
811 | for ( ; aSensitivesIter.More(); aSensitivesIter.Next()) |
812 | { |
813 | NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = |
814 | aSensitivesIter.ChangeValue(); |
815 | Standard_Integer anEntitiesNb = anEntitySet->Size(); |
816 | for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx) |
817 | { |
818 | anEntitySet->GetSensitiveById (anIdx)->ResetSelectionActiveStatus(); |
819 | } |
820 | } |
4269bd1b |
821 | } |
822 | |
823 | //======================================================================= |
f751596e |
824 | // function : DetectedEntity |
825 | // purpose : Returns sensitive entity that was detected during the |
826 | // previous run of selection algorithm |
4269bd1b |
827 | //======================================================================= |
f751596e |
828 | const Handle(SelectBasics_SensitiveEntity)& SelectMgr_ViewerSelector::DetectedEntity() const |
4269bd1b |
829 | { |
f751596e |
830 | const Handle(SelectMgr_EntityOwner)& anOwner = myDetectedIter.Key(); |
831 | const Handle(SelectMgr_SelectableObject)& anObject = anOwner->Selectable(); |
832 | const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = |
833 | myMapOfObjectSensitives.Find (anObject); |
834 | |
835 | return anEntitySet->GetSensitiveById (myDetectedIter.Value())->BaseSensitive(); |
4269bd1b |
836 | } |
837 | |
838 | //======================================================================= |
f751596e |
839 | // function : ActiveOwners |
840 | // purpose : Returns the list of active entity owners |
4269bd1b |
841 | //======================================================================= |
f751596e |
842 | NCollection_List<Handle(SelectBasics_EntityOwner)> SelectMgr_ViewerSelector::ActiveOwners() const |
4269bd1b |
843 | { |
f751596e |
844 | NCollection_List<Handle(SelectBasics_EntityOwner)> anActiveOwners; |
845 | for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next()) |
846 | { |
847 | const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = anIter.Value(); |
848 | Standard_Integer anEntitiesNb = anEntitySet->Size(); |
849 | for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx) |
850 | { |
851 | if (anEntitySet->GetSensitiveById (anIdx)->IsActiveForSelection()) |
852 | { |
853 | anActiveOwners.Append (anEntitySet->GetSensitiveById (anIdx)->BaseSensitive()->OwnerId()); |
854 | } |
855 | } |
856 | } |
857 | |
858 | return anActiveOwners; |
4269bd1b |
859 | } |