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