0024859: Replace SortTools by STL equivalents
[occt.git] / src / SelectMgr / SelectMgr_ViewerSelector.cxx
CommitLineData
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
39namespace {
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 67SelectMgr_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 77SelectMgr_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 87void 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 116void 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//=======================================================================
139Standard_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//=======================================================================
148void 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//=======================================================================
157void SelectMgr_ToleranceMap::ResetDefaults()
158{
159 myCustomTolerance = -1.0;
f751596e 160}
4269bd1b 161
7fd59977 162//==================================================
163// Function: Initialize
164// Purpose :
165//==================================================
166SelectMgr_ViewerSelector::SelectMgr_ViewerSelector():
7fd59977 167preferclosest(Standard_True),
f751596e 168mytolerance(2.0),
169myToUpdateTolerance (Standard_True),
170myCurRank (0),
171myIsLeftChildQueuedFirst (Standard_False),
172myEntityIdx (0)
7fd59977 173{
f751596e 174 mySelectableObjects = new SelectMgr_SelectableObjectSet();
7fd59977 175}
176
177
178//==================================================
179// Function: Activate
180// Purpose :
181//==================================================
f751596e 182void 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 201void 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//==================================================
219void 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//=======================================================================
229Standard_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//=======================================================================
239SelectMgr_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//=======================================================================
263void 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//=======================================================================
313void 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//=======================================================================
410void 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//==================================================
488Handle(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 503Standard_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
516Handle(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
538Standard_Integer SelectMgr_ViewerSelector::NbPicked() const
539{
540 return mystored.Extent();
541}
542//=======================================================================
543//function : Picked
4269bd1b 544//purpose :
7fd59977 545//=======================================================================
546Handle(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 570Standard_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 579Standard_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//==================================================
603Standard_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//==================================================
624Standard_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 647SelectMgr_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 657TCollection_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//=======================================================================
697void 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//=======================================================================
721Standard_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//=======================================================================
730void 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//=======================================================================
744void 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//=======================================================================
765void 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 779void 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 794void 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 809void 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 829void 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 849const 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 863void 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}