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