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