0026323: Tolerance computing unification
[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{
c5f3a425 267 Handle(SelectMgr_EntityOwner) anOwner (Handle(SelectMgr_EntityOwner)::DownCast (theEntity->OwnerId()));
7fd59977 268
f751596e 269 SelectBasics_PickResult aPickResult;
270 if (theEntity->Matches (theMgr, aPickResult))
271 {
272 if (!anOwner.IsNull())
273 {
28ee613b 274 if (HasDepthClipping (anOwner) && theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point)
f751596e 275 {
276 Standard_Boolean isClipped = theMgr.IsClipped (anOwner->Selectable()->GetClipPlanes(),
277 aPickResult.Depth());
278 if (isClipped)
279 return;
280 }
7fd59977 281
f751596e 282 Standard_Integer aPriority = anOwner->Priority();
7fd59977 283
f751596e 284 SelectMgr_SortCriterion aCriterion (aPriority, aPickResult.Depth(), aPickResult.DistToGeomCenter(), theEntity->SensitivityFactor() / 33, preferclosest);
285 if (mystored.Contains (anOwner))
4269bd1b 286 {
f751596e 287 if (theMgr.GetActiveSelectionType() != 1)
288 {
289 SelectMgr_SortCriterion& aPrevCriterion = mystored.ChangeFromKey (anOwner);
290 if (aCriterion > aPrevCriterion)
291 {
292 aPrevCriterion = aCriterion;
293 myMapOfDetected.ChangeFind (anOwner) = theEntityIdx;
7fd59977 294 }
295 }
296 }
f751596e 297 else
298 {
299 mystored.Add (anOwner, aCriterion);
300 myMapOfDetected.Bind (anOwner, theEntityIdx);
7fd59977 301 }
302 }
7fd59977 303 }
304}
305
f751596e 306//=======================================================================
307// function: traverseObject
308// purpose : Internal function that checks if there is possible overlap
309// between some entity of selectable object theObject and
310// current selecting volume
311//=======================================================================
312void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_SelectableObject)& theObject)
7fd59977 313{
f751596e 314 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
315 myMapOfObjectSensitives.ChangeFind (theObject);
7fd59977 316
f751596e 317 if (anEntitySet->Size() == 0)
318 return;
7fd59977 319
f751596e 320 const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
7fd59977 321
f751596e 322 SelectMgr_SelectingVolumeManager aMgr = theObject->HasTransformation() ?
323 mySelectingVolumeMgr.Transform (theObject->InversedTransformation()) : mySelectingVolumeMgr;
7fd59977 324
28ee613b 325 NCollection_DataMap<Handle(Standard_Type), SelectMgr_SelectingVolumeManager> aScaledTrnsfFrustums;
326
f751596e 327 Standard_Integer aNode = 0; // a root node
328 if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
329 aSensitivesTree->MaxPoint (0)))
330 {
331 return;
7fd59977 332 }
f751596e 333 Standard_Integer aStack[32];
334 Standard_Integer aHead = -1;
335 for (;;)
336 {
337 if (!aSensitivesTree->IsOuter (aNode))
338 {
339 const Standard_Integer aLeftChildIdx = aSensitivesTree->LeftChild (aNode);
340 const Standard_Integer aRightChildIdx = aSensitivesTree->RightChild (aNode);
341 const Standard_Boolean isLeftChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aLeftChildIdx),
342 aSensitivesTree->MaxPoint (aLeftChildIdx));
343 const Standard_Boolean isRightChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aRightChildIdx),
344 aSensitivesTree->MaxPoint (aRightChildIdx));
345 if (isLeftChildIn
346 && isRightChildIn)
347 {
348 aNode = aLeftChildIdx;
349 ++aHead;
350 aStack[aHead] = aRightChildIdx;
351 }
352 else if (isLeftChildIn
353 || isRightChildIn)
354 {
355 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
356 }
357 else
358 {
359 if (aHead < 0)
360 {
361 break;
362 }
7fd59977 363
f751596e 364 aNode = aStack[aHead];
365 --aHead;
366 }
367 }
368 else
369 {
370 Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode);
371 Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode);
372 for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
373 {
7ab15952 374 const Handle(SelectMgr_SensitiveEntity)& aSensitive =
f751596e 375 anEntitySet->GetSensitiveById (anIdx);
376 if (aSensitive->IsActiveForSelection())
377 {
28ee613b 378 const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
379 SelectMgr_SelectingVolumeManager aTmpMgr = aMgr;
380 if (isToScaleFrustum (anEnt))
381 {
382 if (!aScaledTrnsfFrustums.IsBound (anEnt->DynamicType()))
383 {
384 aScaledTrnsfFrustums.Bind (anEnt->DynamicType(),
385 scaleAndTransform (anEnt->SensitivityFactor(), theObject->InversedTransformation()));
386 }
387
388 aTmpMgr = aScaledTrnsfFrustums.Find (anEnt->DynamicType());
389 }
390 checkOverlap (anEnt, anIdx, aTmpMgr);
f751596e 391 }
392 }
393 if (aHead < 0)
394 {
395 break;
396 }
7fd59977 397
f751596e 398 aNode = aStack[aHead];
399 --aHead;
400 }
7fd59977 401 }
402}
403
f751596e 404//=======================================================================
405// function: TraverseSensitives
406// purpose : Traverses BVH containing all added selectable objects and
407// finds candidates for further search of overlap
408//=======================================================================
409void SelectMgr_ViewerSelector::TraverseSensitives()
7fd59977 410{
411 mystored.Clear();
f751596e 412 myMapOfDetected.Clear();
7fd59977 413
f751596e 414 if (mySelectableObjects->Size() == 0)
415 return;
7fd59977 416
f751596e 417 const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& anObjectsTree = mySelectableObjects->BVH();
7fd59977 418
f751596e 419 Standard_Integer aNode = 0;
420 if (!mySelectingVolumeMgr.Overlaps (anObjectsTree->MinPoint (0),
421 anObjectsTree->MaxPoint (0)))
7fd59977 422 {
f751596e 423 return;
424 }
425 Standard_Integer aStack[32];
426 Standard_Integer aHead = -1;
427 for (;;)
428 {
429 if (!anObjectsTree->IsOuter (aNode))
4269bd1b 430 {
f751596e 431 const Standard_Integer aLeftChildIdx = anObjectsTree->LeftChild (aNode);
432 const Standard_Integer aRightChildIdx = anObjectsTree->RightChild (aNode);
433 const Standard_Boolean isLeftChildIn =
434 mySelectingVolumeMgr.Overlaps (anObjectsTree->MinPoint (aLeftChildIdx),
435 anObjectsTree->MaxPoint (aLeftChildIdx));
436 const Standard_Boolean isRightChildIn =
437 mySelectingVolumeMgr.Overlaps (anObjectsTree->MinPoint (aRightChildIdx),
438 anObjectsTree->MaxPoint (aRightChildIdx));
439 if (isLeftChildIn
440 && isRightChildIn)
4269bd1b 441 {
f751596e 442 aNode = aLeftChildIdx;
443 ++aHead;
444 aStack[aHead] = aRightChildIdx;
445 }
446 else if (isLeftChildIn
447 || isRightChildIn)
448 {
449 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
450 }
451 else
452 {
453 if (aHead < 0)
4269bd1b 454 {
f751596e 455 break;
4269bd1b 456 }
7fd59977 457
f751596e 458 aNode = aStack[aHead];
459 --aHead;
7fd59977 460 }
461 }
f751596e 462 else
463 {
464 Standard_Integer aStartIdx = anObjectsTree->BegPrimitive (aNode);
465 Standard_Integer anEndIdx = anObjectsTree->EndPrimitive (aNode);
466 for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
467 {
468 traverseObject (mySelectableObjects->GetObjectById (anIdx));
469 }
470 if (aHead < 0)
471 {
472 break;
473 }
4269bd1b 474
f751596e 475 aNode = aStack[aHead];
476 --aHead;
477 }
7fd59977 478 }
4269bd1b 479
f751596e 480 SortResult();
7fd59977 481}
4269bd1b 482
7fd59977 483//==================================================
484// Function: Picked
485// Purpose :
486//==================================================
487Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector
488::Picked() const
489{
f751596e 490 Standard_Integer RankInMap = myIndexes->Value (myCurRank);
7fd59977 491 const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap);
c5f3a425 492 Handle(SelectMgr_EntityOwner) Ownr = Handle(SelectMgr_EntityOwner)::DownCast (toto);
7fd59977 493 return Ownr;
494}
495
496
497
498//=======================================================================
499//function : More
4269bd1b 500//purpose :
7fd59977 501//=======================================================================
4269bd1b 502Standard_Boolean SelectMgr_ViewerSelector::More()
7fd59977 503{
504 if(mystored.Extent()==0) return Standard_False;
505 if(myCurRank==0) return Standard_False;
506 return myCurRank <= myIndexes->Length();
507}
508
509//==================================================
510// Function: OnePicked
511// Purpose : only the best one is chosen
512// depend on priority and mindist...
513//==================================================
514
515Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector
516::OnePicked()
517{
518
519 Init();
520 if(More()){
f751596e 521 Standard_Integer RankInMap = myIndexes->Value (myIndexes->Lower());
7fd59977 522 const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap);
c5f3a425 523 Handle(SelectMgr_EntityOwner) Ownr = Handle(SelectMgr_EntityOwner)::DownCast (toto);
7fd59977 524 return Ownr;
525 }
526
527 Handle (SelectMgr_EntityOwner) NullObj; //returns a null Handle if there was not successfull pick...
528 return NullObj;
529}
530
531
532//=======================================================================
533//function : NbPicked
4269bd1b 534//purpose :
7fd59977 535//=======================================================================
536
537Standard_Integer SelectMgr_ViewerSelector::NbPicked() const
538{
539 return mystored.Extent();
540}
541//=======================================================================
542//function : Picked
4269bd1b 543//purpose :
7fd59977 544//=======================================================================
545Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked(const Standard_Integer aRank) const
546{
547
f751596e 548 Handle(SelectMgr_EntityOwner) anOwner;
549 if (aRank < 1 || aRank > NbPicked())
550 return anOwner;
551 Standard_Integer anOwnerIdx = myIndexes->Value (aRank);
7fd59977 552
553
f751596e 554 const Handle(SelectBasics_EntityOwner)& aStoredOwner = mystored.FindKey (anOwnerIdx);
555 anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aStoredOwner);
556 return anOwner;
7fd59977 557}
558
7fd59977 559//===================================================
560//
561// INTERNAL METHODS ....
562//
563//==================================================
564
7fd59977 565//==================================================
566// Function: Contains
4269bd1b 567// Purpose :
7fd59977 568//==================================================
f751596e 569Standard_Boolean SelectMgr_ViewerSelector::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
7fd59977 570{
f751596e 571 return mySelectableObjects->Contains (theObject);
7fd59977 572}
573
7fd59977 574//==================================================
575// Function: ActiveModes
576// Purpose : return all the modes with a given state for an object
577//==================================================
f751596e 578Standard_Boolean SelectMgr_ViewerSelector::Modes (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
579 TColStd_ListOfInteger& theModeList,
580 const SelectMgr_StateOfSelection theWantedState) const
7fd59977 581{
f751596e 582 Standard_Boolean hasActivatedStates = mySelectableObjects->Contains (theSelectableObject);
583 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
584 {
585 if (theWantedState == SelectMgr_SOS_Any)
586 {
587 theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
588 }
589 else if (theWantedState == theSelectableObject->CurrentSelection()->GetSelectionState())
590 {
591 theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
592 }
7fd59977 593 }
7fd59977 594
f751596e 595 return hasActivatedStates;
596}
7fd59977 597
f751596e 598//==================================================
599// Function: IsActive
600// Purpose :
601//==================================================
602Standard_Boolean SelectMgr_ViewerSelector::IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
603 const Standard_Integer theMode) const
7fd59977 604{
f751596e 605 if (!mySelectableObjects->Contains (theSelectableObject))
606 return Standard_False;
607
608 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
609 {
610 if (theMode == theSelectableObject->CurrentSelection()->Mode())
611 {
612 return theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated;
7fd59977 613 }
614 }
f751596e 615
7fd59977 616 return Standard_False;
617}
618
f751596e 619//==================================================
620// Function: IsInside
621// Purpose :
622//==================================================
623Standard_Boolean SelectMgr_ViewerSelector::IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
624 const Standard_Integer theMode) const
7fd59977 625{
f751596e 626 if (!mySelectableObjects->Contains (theSelectableObject))
627 return Standard_False;
7fd59977 628
f751596e 629 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
630 {
631 if (theMode == theSelectableObject->CurrentSelection()->Mode())
632 {
633 return theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown;
7fd59977 634 }
635 }
f751596e 636
7fd59977 637 return Standard_False;
638}
639
640
641//=======================================================================
642//function : Status
4269bd1b 643//purpose :
7fd59977 644//=======================================================================
645
f751596e 646SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_Selection)& theSelection) const
7fd59977 647{
f751596e 648 return theSelection->GetSelectionState();
7fd59977 649}
650
7fd59977 651//==================================================
652// Function: Status
653// Purpose : gives Information about selectors
654//==================================================
655
f751596e 656TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const
7fd59977 657{
f751596e 658 TCollection_AsciiString aStatus ("Status Object :\n\t");
659
660 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
661 {
662 if (theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown)
7fd59977 663 {
f751596e 664 aStatus = aStatus + "Mode " +
665 TCollection_AsciiString (theSelectableObject->CurrentSelection()->Mode()) +
666 " present - ";
667 if (theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated)
668 {
669 aStatus = aStatus + " Active \n\t";
670 }
7fd59977 671 else
f751596e 672 {
673 aStatus = aStatus + " Inactive \n\t";
674 }
7fd59977 675 }
676 }
677
f751596e 678 if (mySelectableObjects->Contains (theSelectableObject))
7fd59977 679 {
f751596e 680 aStatus = aStatus + "Not Present in the selector\n\n";
7fd59977 681 }
f751596e 682
683 return aStatus;
7fd59977 684}
685
686//=======================================================================
687//function : SortResult
4269bd1b 688//purpose : there is a certain number of entities ranged by criteria
81bba717 689// (depth, size, priority, mouse distance from borders or
690// CDG of the detected primitive. Parsing :
691// maximum priorities .
692// then a reasonable compromise between depth and distance...
693// finally the ranges are stored in myindexes depending on the parsing.
4269bd1b 694// so, it is possible to only read
7fd59977 695//=======================================================================
696void SelectMgr_ViewerSelector::SortResult()
697{
698 if(mystored.IsEmpty()) return;
699
700 const Standard_Integer anExtent = mystored.Extent();
701 if(myIndexes.IsNull() || anExtent != myIndexes->Length())
702 myIndexes = new TColStd_HArray1OfInteger (1, anExtent);
703
81bba717 704 // to work faster...
7fd59977 705 TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1();
706
81bba717 707 // indices from 1 to N are loaded
7fd59977 708 Standard_Integer I ;
709 for (I=1; I <= anExtent; I++)
710 thearr(I)=I;
711
e35db416 712 std::sort (thearr.begin(), thearr.end(), CompareResults (mystored));
713
f751596e 714}
715
716//=======================================================================
717//function : HasDepthClipping
718//purpose : Stub
719//=======================================================================
720Standard_Boolean SelectMgr_ViewerSelector::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& /*theOwner*/) const
721{
722 return Standard_False;
723}
724
725//=======================================================================
726// function : AddSelectableObject
727// purpose : Adds new object to the map of selectable objects
728//=======================================================================
729void SelectMgr_ViewerSelector::AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
730{
731 if (!myMapOfObjectSensitives.IsBound (theObject))
732 {
733 mySelectableObjects->Append (theObject);
734 NCollection_Handle<SelectMgr_SensitiveEntitySet> anEntitySet = new SelectMgr_SensitiveEntitySet();
735 myMapOfObjectSensitives.Bind (theObject, anEntitySet);
7fd59977 736 }
f751596e 737}
7fd59977 738
f751596e 739//=======================================================================
740// function : AddSelectionToObject
741// purpose : Adds new selection to the object and builds its BVH tree
742//=======================================================================
743void SelectMgr_ViewerSelector::AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject,
744 const Handle(SelectMgr_Selection)& theSelection)
745{
746 if (myMapOfObjectSensitives.IsBound (theObject))
747 {
748 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
749 myMapOfObjectSensitives.ChangeFind (theObject);
750 anEntitySet->Append (theSelection);
751 anEntitySet->BVH();
752 }
753 else
754 {
755 AddSelectableObject (theObject);
756 AddSelectionToObject (theObject, theSelection);
757 }
7fd59977 758}
759
f751596e 760//=======================================================================
761// function : RemoveSelectableObject
762// purpose : Removes selectable object from map of selectable ones
763//=======================================================================
764void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
765{
766 if (myMapOfObjectSensitives.IsBound (theObject))
767 {
768 myMapOfObjectSensitives.UnBind (theObject);
769 mySelectableObjects->Remove (theObject);
770 }
771}
7fd59977 772
773//=======================================================================
f751596e 774// function : RemoveSelectionOfObject
775// purpose : Removes selection of the object and marks its BVH tree
776// for rebuild
7fd59977 777//=======================================================================
f751596e 778void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject,
779 const Handle(SelectMgr_Selection)& theSelection)
7fd59977 780{
f751596e 781 if (myMapOfObjectSensitives.IsBound (theObject))
782 {
783 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
784 myMapOfObjectSensitives.ChangeFind (theObject);
785 anEntitySet->Remove (theSelection);
786 }
7fd59977 787}
788
789//=======================================================================
f751596e 790// function : RebuildObjectsTree
791// purpose : Marks BVH of selectable objects for rebuild
7fd59977 792//=======================================================================
f751596e 793void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce)
7fd59977 794{
f751596e 795 mySelectableObjects->MarkDirty();
796
797 if (theIsForce)
798 {
799 mySelectableObjects->BVH();
800 }
7fd59977 801}
4269bd1b 802
803//=======================================================================
f751596e 804// function : RebuildSensitivesTree
805// purpose : Marks BVH of sensitive entities of particular selectable
806// object for rebuild
4269bd1b 807//=======================================================================
f751596e 808void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject,
809 const Standard_Boolean theIsForce)
4269bd1b 810{
f751596e 811 if (!mySelectableObjects->Contains (theObject))
812 return;
813
814 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
815 anEntitySet->MarkDirty();
816
817 if (theIsForce)
818 {
819 anEntitySet->BVH();
820 }
4269bd1b 821}
822
823//=======================================================================
f751596e 824// function : resetSelectionActivationStatus
825// purpose : Marks all added sensitive entities of all objects as
826// non-selectable
4269bd1b 827//=======================================================================
f751596e 828void SelectMgr_ViewerSelector::resetSelectionActivationStatus()
4269bd1b 829{
f751596e 830 SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives);
831 for ( ; aSensitivesIter.More(); aSensitivesIter.Next())
832 {
833 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
834 aSensitivesIter.ChangeValue();
835 Standard_Integer anEntitiesNb = anEntitySet->Size();
836 for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
837 {
838 anEntitySet->GetSensitiveById (anIdx)->ResetSelectionActiveStatus();
839 }
840 }
4269bd1b 841}
842
843//=======================================================================
f751596e 844// function : DetectedEntity
845// purpose : Returns sensitive entity that was detected during the
846// previous run of selection algorithm
4269bd1b 847//=======================================================================
f751596e 848const Handle(SelectBasics_SensitiveEntity)& SelectMgr_ViewerSelector::DetectedEntity() const
4269bd1b 849{
f751596e 850 const Handle(SelectMgr_EntityOwner)& anOwner = myDetectedIter.Key();
851 const Handle(SelectMgr_SelectableObject)& anObject = anOwner->Selectable();
852 const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
853 myMapOfObjectSensitives.Find (anObject);
854
855 return anEntitySet->GetSensitiveById (myDetectedIter.Value())->BaseSensitive();
4269bd1b 856}
857
858//=======================================================================
f751596e 859// function : ActiveOwners
860// purpose : Returns the list of active entity owners
4269bd1b 861//=======================================================================
751955d4 862void SelectMgr_ViewerSelector::ActiveOwners (NCollection_List<Handle(SelectBasics_EntityOwner)>& theOwners) const
4269bd1b 863{
f751596e 864 for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next())
865 {
866 const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = anIter.Value();
867 Standard_Integer anEntitiesNb = anEntitySet->Size();
868 for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
869 {
870 if (anEntitySet->GetSensitiveById (anIdx)->IsActiveForSelection())
871 {
751955d4 872 theOwners.Append (anEntitySet->GetSensitiveById (anIdx)->BaseSensitive()->OwnerId());
f751596e 873 }
874 }
875 }
4269bd1b 876}