1 // Created on: 1995-02-15
2 // Created by: Roberc Coublanc
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 // ROB JAN/07/98 : Improve Storage of detected entities
19 // AGV OCT/23/03 : Optimize the method SortResult() (OCC4201)
21 #include <BVH_Tree.hxx>
23 #include <OSD_Environment.hxx>
24 #include <Precision.hxx>
25 #include <SelectMgr_ViewerSelector.hxx>
26 #include <SelectBasics_EntityOwner.hxx>
27 #include <SelectBasics_SensitiveEntity.hxx>
28 #include <SelectBasics_PickResult.hxx>
29 #include <SelectMgr_EntityOwner.hxx>
30 #include <SelectMgr_SortCriterion.hxx>
31 #include <SelectMgr_SensitiveEntitySet.hxx>
32 #include <TColStd_Array1OfInteger.hxx>
33 #include <TCollection_AsciiString.hxx>
34 #include <TColStd_HArray1OfInteger.hxx>
35 #include <TColStd_ListOfInteger.hxx>
40 // Comparison operator for sorting selection results
45 CompareResults (const SelectMgr_IndexedDataMapOfOwnerCriterion& aMapOfCriterion)
46 : myMapOfCriterion (aMapOfCriterion)
50 Standard_Boolean operator() (Standard_Integer theLeft, Standard_Integer theRight) const
52 return myMapOfCriterion.FindFromIndex(theLeft) > myMapOfCriterion.FindFromIndex(theRight);
56 void operator = (const CompareResults&);
59 const SelectMgr_IndexedDataMapOfOwnerCriterion& myMapOfCriterion;
63 //=======================================================================
64 // function: SelectMgr_ToleranceMap
65 // purpose : Sets tolerance values to -1.0
66 //=======================================================================
67 SelectMgr_ToleranceMap::SelectMgr_ToleranceMap()
70 myCustomTolerance = -1.0;
73 //=======================================================================
74 // function: ~SelectMgr_ToleranceMap
76 //=======================================================================
77 SelectMgr_ToleranceMap::~SelectMgr_ToleranceMap()
82 //=======================================================================
84 // purpose : Adds the value given to map, checks if the current tolerance value
85 // should be replaced by theTolerance
86 //=======================================================================
87 void SelectMgr_ToleranceMap::Add (const Standard_Real& theTolerance)
89 if (myTolerances.IsBound (theTolerance))
91 Standard_Integer& aFreq = myTolerances.ChangeFind (theTolerance);
94 if (aFreq == 1 && theTolerance != myLargestKey)
95 myLargestKey = Max (theTolerance, myLargestKey);
99 if (myTolerances.IsEmpty())
101 myTolerances.Bind (theTolerance, 1);
102 myLargestKey = theTolerance;
106 myTolerances.Bind (theTolerance, 1);
107 myLargestKey = Max (theTolerance, myLargestKey);
111 //=======================================================================
112 // function: Decrement
113 // purpose : Decrements a counter of the tolerance given, checks if the current tolerance value
114 // should be recalculated
115 //=======================================================================
116 void SelectMgr_ToleranceMap::Decrement (const Standard_Real& theTolerance)
118 if (myTolerances.IsBound (theTolerance))
120 Standard_Integer& aFreq = myTolerances.ChangeFind (theTolerance);
123 if (Abs (theTolerance - myLargestKey) < Precision::Confusion() && aFreq == 0)
126 for (NCollection_DataMap<Standard_Real, Standard_Integer>::Iterator anIter (myTolerances); anIter.More(); anIter.Next())
128 if (anIter.Value() != 0)
129 myLargestKey = Max (myLargestKey, anIter.Key());
135 //==================================================
136 // Function: Initialize
138 //==================================================
139 SelectMgr_ViewerSelector::SelectMgr_ViewerSelector():
140 preferclosest(Standard_True),
141 myToUpdateTolerance (Standard_True),
143 myIsLeftChildQueuedFirst (Standard_False),
148 //==================================================
149 // Function: Activate
151 //==================================================
152 void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSelection)
154 for (theSelection->Init(); theSelection->More(); theSelection->Next())
156 theSelection->Sensitive()->SetActiveForSelection();
159 theSelection->SetSelectionState (SelectMgr_SOS_Activated);
161 myTolerances.Add (theSelection->Sensitivity());
162 myToUpdateTolerance = Standard_True;
165 //==================================================
166 // Function: Deactivate
168 //==================================================
169 void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theSelection)
171 for (theSelection->Init(); theSelection->More(); theSelection->Next())
173 theSelection->Sensitive()->ResetSelectionActiveStatus();
176 theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
178 myTolerances.Decrement (theSelection->Sensitivity());
179 myToUpdateTolerance = Standard_True;
182 //==================================================
185 //==================================================
186 void SelectMgr_ViewerSelector::Clear()
189 myMapOfDetected.Clear();
192 //=======================================================================
193 // function: isToScaleFrustum
194 // purpose : Checks if the entity given requires to scale current selecting frustum
195 //=======================================================================
196 Standard_Boolean SelectMgr_ViewerSelector::isToScaleFrustum (const Handle(SelectBasics_SensitiveEntity)& theEntity)
198 return mySelectingVolumeMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point
199 && sensitivity (theEntity) < myTolerances.Tolerance();
202 //=======================================================================
203 // function: scaleAndTransform
204 // purpose : Applies given scale and transformation matrices to the default selecting volume manager
205 //=======================================================================
206 SelectMgr_SelectingVolumeManager SelectMgr_ViewerSelector::scaleAndTransform (const Standard_Real theScale,
207 const gp_Trsf& theTrsf)
209 SelectMgr_SelectingVolumeManager aMgr;
211 if (theScale > Precision::Angular())
213 aMgr = mySelectingVolumeMgr.Scale (theScale);
216 if (theTrsf.Form() != gp_Identity)
218 aMgr = aMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Unknown ?
219 mySelectingVolumeMgr.Transform (theTrsf) : aMgr.Transform (theTrsf);
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 //=======================================================================
230 Standard_Real SelectMgr_ViewerSelector::sensitivity (const Handle(SelectBasics_SensitiveEntity)& theEntity) const
232 return myTolerances.IsCustomTolSet() ?
233 theEntity->SensitivityFactor() + myTolerances.CustomTolerance() : theEntity->SensitivityFactor();
236 //=======================================================================
237 // function: checkOverlap
238 // purpose : Internal function that checks if a particular sensitive
239 // entity theEntity overlaps current selecting volume precisely
240 //=======================================================================
241 void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_SensitiveEntity)& theEntity,
242 const Standard_Integer theEntityIdx,
243 SelectMgr_SelectingVolumeManager& theMgr)
245 Handle(SelectMgr_EntityOwner) anOwner (Handle(SelectMgr_EntityOwner)::DownCast (theEntity->OwnerId()));
247 SelectBasics_PickResult aPickResult;
248 if (theEntity->Matches (theMgr, aPickResult))
250 if (!anOwner.IsNull())
252 if (HasDepthClipping (anOwner) && theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point)
254 Standard_Boolean isClipped = theMgr.IsClipped (anOwner->Selectable()->GetClipPlanes(),
255 aPickResult.Depth());
260 Standard_Integer aPriority = anOwner->Priority();
262 SelectMgr_SortCriterion aCriterion (aPriority, aPickResult.Depth(), aPickResult.DistToGeomCenter(), theEntity->SensitivityFactor() / 33, preferclosest);
263 if (mystored.Contains (anOwner))
265 if (theMgr.GetActiveSelectionType() != 1)
267 SelectMgr_SortCriterion& aPrevCriterion = mystored.ChangeFromKey (anOwner);
268 if (aCriterion > aPrevCriterion)
270 aPrevCriterion = aCriterion;
271 myMapOfDetected.ChangeFind (anOwner) = theEntityIdx;
277 mystored.Add (anOwner, aCriterion);
278 myMapOfDetected.Bind (anOwner, theEntityIdx);
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 //=======================================================================
290 void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_SelectableObject)& theObject)
292 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
293 myMapOfObjectSensitives.ChangeFind (theObject);
295 if (anEntitySet->Size() == 0)
298 const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
300 gp_Trsf aInversedTrsf;
302 if (theObject->HasTransformation() || theObject->TransformPersistence().Flags)
304 if (!theObject->TransformPersistence().Flags)
306 aInversedTrsf = theObject->InversedTransformation();
310 const Graphic3d_Mat4d& aProjection = mySelectingVolumeMgr.ProjectionMatrix();
311 const Graphic3d_Mat4d& aWorldView = mySelectingVolumeMgr.WorldViewMatrix();
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));
319 aInversedTrsf = (aTPers * theObject->Transformation()).Inverted();
323 SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity
324 ? mySelectingVolumeMgr.Transform (aInversedTrsf)
325 : mySelectingVolumeMgr;
327 NCollection_DataMap<Handle(Standard_Type), SelectMgr_SelectingVolumeManager> aScaledTrnsfFrustums;
329 Standard_Integer aNode = 0; // a root node
330 if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
331 aSensitivesTree->MaxPoint (0)))
335 Standard_Integer aStack[32];
336 Standard_Integer aHead = -1;
339 if (!aSensitivesTree->IsOuter (aNode))
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));
350 aNode = aLeftChildIdx;
352 aStack[aHead] = aRightChildIdx;
354 else if (isLeftChildIn
357 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
366 aNode = aStack[aHead];
372 Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode);
373 Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode);
374 for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
376 const Handle(SelectMgr_SensitiveEntity)& aSensitive =
377 anEntitySet->GetSensitiveById (anIdx);
378 if (aSensitive->IsActiveForSelection())
380 const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
381 SelectMgr_SelectingVolumeManager aTmpMgr = aMgr;
382 if (isToScaleFrustum (anEnt))
384 if (!aScaledTrnsfFrustums.IsBound (anEnt->DynamicType()))
386 aScaledTrnsfFrustums.Bind (anEnt->DynamicType(),
387 scaleAndTransform (sensitivity (anEnt), aInversedTrsf));
390 aTmpMgr = aScaledTrnsfFrustums.Find (anEnt->DynamicType());
392 checkOverlap (anEnt, anIdx, aTmpMgr);
400 aNode = aStack[aHead];
406 //=======================================================================
407 // function: TraverseSensitives
408 // purpose : Traverses BVH containing all added selectable objects and
409 // finds candidates for further search of overlap
410 //=======================================================================
411 void SelectMgr_ViewerSelector::TraverseSensitives()
414 myMapOfDetected.Clear();
416 NCollection_Handle<BVH_Tree<Standard_Real, 3> > aBVHTree;
417 for (Standard_Integer aBVHTreeIdx = 0; aBVHTreeIdx < 2; ++aBVHTreeIdx)
419 const Standard_Boolean isTrsfPers = aBVHTreeIdx == 1;
422 if (mySelectableObjectsTrsfPers.Size() == 0)
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);
433 if (mySelectableObjects.Size() == 0)
437 aBVHTree = mySelectableObjects.BVH();
440 Standard_Integer aNode = 0;
441 if (!mySelectingVolumeMgr.Overlaps (aBVHTree->MinPoint (0),
442 aBVHTree->MaxPoint (0)))
447 Standard_Integer aStack[32];
448 Standard_Integer aHead = -1;
451 if (!aBVHTree->IsOuter (aNode))
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));
464 aNode = aLeftChildIdx;
466 aStack[aHead] = aRightChildIdx;
468 else if (isLeftChildIn
471 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
480 aNode = aStack[aHead];
486 Standard_Integer aStartIdx = aBVHTree->BegPrimitive (aNode);
487 Standard_Integer anEndIdx = aBVHTree->EndPrimitive (aNode);
488 for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
490 Handle(SelectMgr_SelectableObject) aSelectableObject =
491 isTrsfPers ? mySelectableObjectsTrsfPers.GetObjectById (anIdx)
492 : mySelectableObjects.GetObjectById (anIdx);
494 traverseObject (aSelectableObject);
501 aNode = aStack[aHead];
510 //==================================================
513 //==================================================
514 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector
517 Standard_Integer RankInMap = myIndexes->Value (myCurRank);
518 const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap);
519 Handle(SelectMgr_EntityOwner) Ownr = Handle(SelectMgr_EntityOwner)::DownCast (toto);
525 //=======================================================================
528 //=======================================================================
529 Standard_Boolean SelectMgr_ViewerSelector::More()
531 if(mystored.Extent()==0) return Standard_False;
532 if(myCurRank==0) return Standard_False;
533 return myCurRank <= myIndexes->Length();
536 //==================================================
537 // Function: OnePicked
538 // Purpose : only the best one is chosen
539 // depend on priority and mindist...
540 //==================================================
542 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector
548 Standard_Integer RankInMap = myIndexes->Value (myIndexes->Lower());
549 const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap);
550 Handle(SelectMgr_EntityOwner) Ownr = Handle(SelectMgr_EntityOwner)::DownCast (toto);
554 Handle (SelectMgr_EntityOwner) NullObj; //returns a null Handle if there was not successfull pick...
559 //=======================================================================
560 //function : NbPicked
562 //=======================================================================
564 Standard_Integer SelectMgr_ViewerSelector::NbPicked() const
566 return mystored.Extent();
568 //=======================================================================
571 //=======================================================================
572 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked(const Standard_Integer aRank) const
575 Handle(SelectMgr_EntityOwner) anOwner;
576 if (aRank < 1 || aRank > NbPicked())
578 Standard_Integer anOwnerIdx = myIndexes->Value (aRank);
581 const Handle(SelectBasics_EntityOwner)& aStoredOwner = mystored.FindKey (anOwnerIdx);
582 anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aStoredOwner);
586 //===================================================
588 // INTERNAL METHODS ....
590 //==================================================
592 //==================================================
593 // Function: Contains
595 //==================================================
596 Standard_Boolean SelectMgr_ViewerSelector::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
598 return mySelectableObjects.Contains (theObject)
599 || mySelectableObjectsTrsfPers.Contains (theObject);
602 //==================================================
603 // Function: ActiveModes
604 // Purpose : return all the modes with a given state for an object
605 //==================================================
606 Standard_Boolean SelectMgr_ViewerSelector::Modes (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
607 TColStd_ListOfInteger& theModeList,
608 const SelectMgr_StateOfSelection theWantedState) const
610 Standard_Boolean hasActivatedStates = Contains (theSelectableObject);
611 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
613 if (theWantedState == SelectMgr_SOS_Any)
615 theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
617 else if (theWantedState == theSelectableObject->CurrentSelection()->GetSelectionState())
619 theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
623 return hasActivatedStates;
626 //==================================================
627 // Function: IsActive
629 //==================================================
630 Standard_Boolean SelectMgr_ViewerSelector::IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
631 const Standard_Integer theMode) const
633 if (!Contains (theSelectableObject))
634 return Standard_False;
636 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
638 if (theMode == theSelectableObject->CurrentSelection()->Mode())
640 return theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated;
644 return Standard_False;
647 //==================================================
648 // Function: IsInside
650 //==================================================
651 Standard_Boolean SelectMgr_ViewerSelector::IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
652 const Standard_Integer theMode) const
654 if (!Contains (theSelectableObject))
655 return Standard_False;
657 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
659 if (theMode == theSelectableObject->CurrentSelection()->Mode())
661 return theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown;
665 return Standard_False;
669 //=======================================================================
672 //=======================================================================
674 SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_Selection)& theSelection) const
676 return theSelection->GetSelectionState();
679 //==================================================
681 // Purpose : gives Information about selectors
682 //==================================================
684 TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const
686 TCollection_AsciiString aStatus ("Status Object :\n\t");
688 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
690 if (theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown)
692 aStatus = aStatus + "Mode " +
693 TCollection_AsciiString (theSelectableObject->CurrentSelection()->Mode()) +
695 if (theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated)
697 aStatus = aStatus + " Active \n\t";
701 aStatus = aStatus + " Inactive \n\t";
706 if (!Contains (theSelectableObject))
708 aStatus = aStatus + "Not Present in the selector\n\n";
714 //=======================================================================
715 //function : SortResult
716 //purpose : there is a certain number of entities ranged by criteria
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.
722 // so, it is possible to only read
723 //=======================================================================
724 void SelectMgr_ViewerSelector::SortResult()
726 if(mystored.IsEmpty()) return;
728 const Standard_Integer anExtent = mystored.Extent();
729 if(myIndexes.IsNull() || anExtent != myIndexes->Length())
730 myIndexes = new TColStd_HArray1OfInteger (1, anExtent);
733 TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1();
735 // indices from 1 to N are loaded
737 for (I=1; I <= anExtent; I++)
740 std::sort (thearr.begin(), thearr.end(), CompareResults (mystored));
744 //=======================================================================
745 //function : HasDepthClipping
747 //=======================================================================
748 Standard_Boolean SelectMgr_ViewerSelector::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& /*theOwner*/) const
750 return Standard_False;
753 //=======================================================================
754 // function : AddSelectableObject
755 // purpose : Adds new object to the map of selectable objects
756 //=======================================================================
757 void SelectMgr_ViewerSelector::AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
759 if (!myMapOfObjectSensitives.IsBound (theObject))
761 if (!theObject->TransformPersistence().Flags)
763 mySelectableObjects.Append (theObject);
767 mySelectableObjectsTrsfPers.Append (theObject);
770 NCollection_Handle<SelectMgr_SensitiveEntitySet> anEntitySet = new SelectMgr_SensitiveEntitySet();
771 myMapOfObjectSensitives.Bind (theObject, anEntitySet);
775 //=======================================================================
776 // function : AddSelectionToObject
777 // purpose : Adds new selection to the object and builds its BVH tree
778 //=======================================================================
779 void SelectMgr_ViewerSelector::AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject,
780 const Handle(SelectMgr_Selection)& theSelection)
782 if (myMapOfObjectSensitives.IsBound (theObject))
784 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
785 myMapOfObjectSensitives.ChangeFind (theObject);
786 anEntitySet->Append (theSelection);
791 AddSelectableObject (theObject);
792 AddSelectionToObject (theObject, theSelection);
796 //=======================================================================
797 // function : RemoveSelectableObject
798 // purpose : Removes selectable object from map of selectable ones
799 //=======================================================================
800 void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
802 if (myMapOfObjectSensitives.IsBound (theObject))
804 if (!mySelectableObjects.Remove (theObject))
806 mySelectableObjectsTrsfPers.Remove (theObject);
808 myMapOfObjectSensitives.UnBind (theObject);
812 //=======================================================================
813 // function : RemoveSelectionOfObject
814 // purpose : Removes selection of the object and marks its BVH tree
816 //=======================================================================
817 void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject,
818 const Handle(SelectMgr_Selection)& theSelection)
820 if (myMapOfObjectSensitives.IsBound (theObject))
822 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
823 myMapOfObjectSensitives.ChangeFind (theObject);
824 anEntitySet->Remove (theSelection);
828 //=======================================================================
829 // function : RebuildObjectsTree
830 // purpose : Marks BVH of selectable objects for rebuild
831 //=======================================================================
832 void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce)
834 mySelectableObjects.MarkDirty();
835 mySelectableObjectsTrsfPers.MarkDirty();
839 const Graphic3d_Mat4d& aProjection = mySelectingVolumeMgr.ProjectionMatrix();
840 const Graphic3d_Mat4d& aWorldView = mySelectingVolumeMgr.WorldViewMatrix();
841 const Graphic3d_WorldViewProjState& aWVPState = mySelectingVolumeMgr.WorldViewProjState();
843 mySelectableObjects.BVH();
844 mySelectableObjectsTrsfPers.BVH (aProjection, aWorldView, aWVPState);
848 //=======================================================================
849 // function : RebuildSensitivesTree
850 // purpose : Marks BVH of sensitive entities of particular selectable
851 // object for rebuild
852 //=======================================================================
853 void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject,
854 const Standard_Boolean theIsForce)
856 if (!Contains (theObject))
859 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
860 anEntitySet->MarkDirty();
868 //=======================================================================
869 // function : resetSelectionActivationStatus
870 // purpose : Marks all added sensitive entities of all objects as
872 //=======================================================================
873 void SelectMgr_ViewerSelector::ResetSelectionActivationStatus()
875 SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives);
876 for ( ; aSensitivesIter.More(); aSensitivesIter.Next())
878 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
879 aSensitivesIter.ChangeValue();
880 Standard_Integer anEntitiesNb = anEntitySet->Size();
881 for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
883 anEntitySet->GetSensitiveById (anIdx)->ResetSelectionActiveStatus();
888 //=======================================================================
889 // function : DetectedEntity
890 // purpose : Returns sensitive entity that was detected during the
891 // previous run of selection algorithm
892 //=======================================================================
893 const Handle(SelectBasics_SensitiveEntity)& SelectMgr_ViewerSelector::DetectedEntity() const
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);
900 return anEntitySet->GetSensitiveById (myDetectedIter.Value())->BaseSensitive();
903 //=======================================================================
904 // function : ActiveOwners
905 // purpose : Returns the list of active entity owners
906 //=======================================================================
907 void SelectMgr_ViewerSelector::ActiveOwners (NCollection_List<Handle(SelectBasics_EntityOwner)>& theOwners) const
909 for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next())
911 const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = anIter.Value();
912 Standard_Integer anEntitiesNb = anEntitySet->Size();
913 for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
915 if (anEntitySet->GetSensitiveById (anIdx)->IsActiveForSelection())
917 theOwners.Append (anEntitySet->GetSensitiveById (anIdx)->BaseSensitive()->OwnerId());
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
929 //=======================================================================
930 void SelectMgr_ViewerSelector::AllowOverlapDetection (const Standard_Boolean theIsToAllow)
932 mySelectingVolumeMgr.AllowOverlapDetection (theIsToAllow);