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;
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_Integer& 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_Integer& 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_Integer, 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: sensitivity
204 // purpose : In case if custom tolerance is set, this method will return sum of entity
205 // sensitivity and custom tolerance.
206 //=======================================================================
207 Standard_Integer SelectMgr_ViewerSelector::sensitivity (const Handle(SelectBasics_SensitiveEntity)& theEntity) const
209 return myTolerances.IsCustomTolSet() ?
210 theEntity->SensitivityFactor() + myTolerances.CustomTolerance() : theEntity->SensitivityFactor();
213 //=======================================================================
214 // function: checkOverlap
215 // purpose : Internal function that checks if a particular sensitive
216 // entity theEntity overlaps current selecting volume precisely
217 //=======================================================================
218 void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_SensitiveEntity)& theEntity,
219 const Standard_Integer theEntityIdx,
220 SelectMgr_SelectingVolumeManager& theMgr)
222 Handle(SelectMgr_EntityOwner) anOwner (Handle(SelectMgr_EntityOwner)::DownCast (theEntity->OwnerId()));
224 SelectBasics_PickResult aPickResult;
225 if (theEntity->Matches (theMgr, aPickResult))
227 if (!anOwner.IsNull())
229 if (HasDepthClipping (anOwner) && theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point)
231 Standard_Boolean isClipped = theMgr.IsClipped (anOwner->Selectable()->GetClipPlanes(),
232 aPickResult.Depth());
237 Standard_Integer aPriority = anOwner->Priority();
239 SelectMgr_SortCriterion aCriterion (aPriority, aPickResult.Depth(), aPickResult.DistToGeomCenter(), theEntity->SensitivityFactor() / 33.0, preferclosest);
240 if (mystored.Contains (anOwner))
242 if (theMgr.GetActiveSelectionType() != 1)
244 SelectMgr_SortCriterion& aPrevCriterion = mystored.ChangeFromKey (anOwner);
245 if (aCriterion > aPrevCriterion)
247 aPrevCriterion = aCriterion;
248 myMapOfDetected.ChangeFind (anOwner) = theEntityIdx;
254 mystored.Add (anOwner, aCriterion);
255 myMapOfDetected.Bind (anOwner, theEntityIdx);
261 //=======================================================================
262 // function: computeFrustum
263 // purpose : Internal function that checks if a current selecting frustum
264 // needs to be scaled and transformed for the entity and performs
265 // necessary calculations
266 //=======================================================================
267 void SelectMgr_ViewerSelector::computeFrustum (const Handle(SelectBasics_SensitiveEntity)& theEnt,
268 const gp_Trsf& theInvTrsf,
269 SelectMgr_FrustumCache& theCachedMgrs,
270 SelectMgr_SelectingVolumeManager& theResMgr)
272 Standard_Integer aScale = 1;
273 const Standard_Boolean toScale = isToScaleFrustum (theEnt);
276 aScale = sensitivity (theEnt);
278 if (theEnt->HasInitLocation())
281 mySelectingVolumeMgr.ScaleAndTransform (aScale, theEnt->InvInitLocation() * theInvTrsf);
285 if (!theCachedMgrs.IsBound (aScale))
287 theCachedMgrs.Bind (aScale,
288 mySelectingVolumeMgr.ScaleAndTransform(aScale, theInvTrsf));
291 theResMgr = theCachedMgrs.Find (aScale);
295 //=======================================================================
296 // function: traverseObject
297 // purpose : Internal function that checks if there is possible overlap
298 // between some entity of selectable object theObject and
299 // current selecting volume
300 //=======================================================================
301 void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_SelectableObject)& theObject)
303 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
304 myMapOfObjectSensitives.ChangeFind (theObject);
306 if (anEntitySet->Size() == 0)
309 const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
311 gp_Trsf aInversedTrsf;
313 if (theObject->HasTransformation() || theObject->TransformPersistence().Flags)
315 if (!theObject->TransformPersistence().Flags)
317 aInversedTrsf = theObject->InversedTransformation();
321 const Graphic3d_Mat4d& aProjection = mySelectingVolumeMgr.ProjectionMatrix();
322 const Graphic3d_Mat4d& aWorldView = mySelectingVolumeMgr.WorldViewMatrix();
325 Graphic3d_Mat4d aMat = theObject->TransformPersistence().Compute (aProjection, aWorldView, 0, 0);
326 aTPers.SetValues (aMat.GetValue (0, 0), aMat.GetValue (0, 1), aMat.GetValue (0, 2), aMat.GetValue (0, 3),
327 aMat.GetValue (1, 0), aMat.GetValue (1, 1), aMat.GetValue (1, 2), aMat.GetValue (1, 3),
328 aMat.GetValue (2, 0), aMat.GetValue (2, 1), aMat.GetValue (2, 2), aMat.GetValue (2, 3));
330 aInversedTrsf = (aTPers * theObject->Transformation()).Inverted();
334 SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity
335 ? mySelectingVolumeMgr.ScaleAndTransform (1, aInversedTrsf)
336 : mySelectingVolumeMgr;
338 SelectMgr_FrustumCache aScaledTrnsfFrustums;
340 Standard_Integer aNode = 0; // a root node
341 if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
342 aSensitivesTree->MaxPoint (0)))
346 Standard_Integer aStack[32];
347 Standard_Integer aHead = -1;
350 if (!aSensitivesTree->IsOuter (aNode))
352 const Standard_Integer aLeftChildIdx = aSensitivesTree->LeftChild (aNode);
353 const Standard_Integer aRightChildIdx = aSensitivesTree->RightChild (aNode);
354 const Standard_Boolean isLeftChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aLeftChildIdx),
355 aSensitivesTree->MaxPoint (aLeftChildIdx));
356 const Standard_Boolean isRightChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aRightChildIdx),
357 aSensitivesTree->MaxPoint (aRightChildIdx));
361 aNode = aLeftChildIdx;
363 aStack[aHead] = aRightChildIdx;
365 else if (isLeftChildIn
368 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
377 aNode = aStack[aHead];
383 Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode);
384 Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode);
385 for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
387 const Handle(SelectMgr_SensitiveEntity)& aSensitive =
388 anEntitySet->GetSensitiveById (anIdx);
389 if (aSensitive->IsActiveForSelection())
391 const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
392 SelectMgr_SelectingVolumeManager aTmpMgr = aMgr;
393 computeFrustum (anEnt, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
394 checkOverlap (anEnt, anIdx, aTmpMgr);
402 aNode = aStack[aHead];
408 //=======================================================================
409 // function: TraverseSensitives
410 // purpose : Traverses BVH containing all added selectable objects and
411 // finds candidates for further search of overlap
412 //=======================================================================
413 void SelectMgr_ViewerSelector::TraverseSensitives()
416 myMapOfDetected.Clear();
418 NCollection_Handle<BVH_Tree<Standard_Real, 3> > aBVHTree;
419 for (Standard_Integer aBVHTreeIdx = 0; aBVHTreeIdx < 2; ++aBVHTreeIdx)
421 const Standard_Boolean isTrsfPers = aBVHTreeIdx == 1;
424 if (mySelectableObjectsTrsfPers.Size() == 0)
428 const Graphic3d_Mat4d& aProjection = mySelectingVolumeMgr.ProjectionMatrix();
429 const Graphic3d_Mat4d& aWorldView = mySelectingVolumeMgr.WorldViewMatrix();
430 const Graphic3d_WorldViewProjState& aWVPState = mySelectingVolumeMgr.WorldViewProjState();
431 aBVHTree = mySelectableObjectsTrsfPers.BVH (aProjection, aWorldView, aWVPState);
435 if (mySelectableObjects.Size() == 0)
439 aBVHTree = mySelectableObjects.BVH();
442 Standard_Integer aNode = 0;
443 if (!mySelectingVolumeMgr.Overlaps (aBVHTree->MinPoint (0),
444 aBVHTree->MaxPoint (0)))
449 Standard_Integer aStack[32];
450 Standard_Integer aHead = -1;
453 if (!aBVHTree->IsOuter (aNode))
455 const Standard_Integer aLeftChildIdx = aBVHTree->LeftChild (aNode);
456 const Standard_Integer aRightChildIdx = aBVHTree->RightChild (aNode);
457 const Standard_Boolean isLeftChildIn =
458 mySelectingVolumeMgr.Overlaps (aBVHTree->MinPoint (aLeftChildIdx),
459 aBVHTree->MaxPoint (aLeftChildIdx));
460 const Standard_Boolean isRightChildIn =
461 mySelectingVolumeMgr.Overlaps (aBVHTree->MinPoint (aRightChildIdx),
462 aBVHTree->MaxPoint (aRightChildIdx));
466 aNode = aLeftChildIdx;
468 aStack[aHead] = aRightChildIdx;
470 else if (isLeftChildIn
473 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
482 aNode = aStack[aHead];
488 Standard_Integer aStartIdx = aBVHTree->BegPrimitive (aNode);
489 Standard_Integer anEndIdx = aBVHTree->EndPrimitive (aNode);
490 for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
492 Handle(SelectMgr_SelectableObject) aSelectableObject =
493 isTrsfPers ? mySelectableObjectsTrsfPers.GetObjectById (anIdx)
494 : mySelectableObjects.GetObjectById (anIdx);
496 traverseObject (aSelectableObject);
503 aNode = aStack[aHead];
512 //==================================================
515 //==================================================
516 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector
519 Standard_Integer RankInMap = myIndexes->Value (myCurRank);
520 const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap);
521 Handle(SelectMgr_EntityOwner) Ownr = Handle(SelectMgr_EntityOwner)::DownCast (toto);
527 //=======================================================================
530 //=======================================================================
531 Standard_Boolean SelectMgr_ViewerSelector::More()
533 if(mystored.Extent()==0) return Standard_False;
534 if(myCurRank==0) return Standard_False;
535 return myCurRank <= myIndexes->Length();
538 //==================================================
539 // Function: OnePicked
540 // Purpose : only the best one is chosen
541 // depend on priority and mindist...
542 //==================================================
544 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector
550 Standard_Integer RankInMap = myIndexes->Value (myIndexes->Lower());
551 const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap);
552 Handle(SelectMgr_EntityOwner) Ownr = Handle(SelectMgr_EntityOwner)::DownCast (toto);
556 Handle (SelectMgr_EntityOwner) NullObj; //returns a null Handle if there was not successfull pick...
561 //=======================================================================
562 //function : NbPicked
564 //=======================================================================
566 Standard_Integer SelectMgr_ViewerSelector::NbPicked() const
568 return mystored.Extent();
570 //=======================================================================
573 //=======================================================================
574 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked(const Standard_Integer aRank) const
577 Handle(SelectMgr_EntityOwner) anOwner;
578 if (aRank < 1 || aRank > NbPicked())
580 Standard_Integer anOwnerIdx = myIndexes->Value (aRank);
583 const Handle(SelectBasics_EntityOwner)& aStoredOwner = mystored.FindKey (anOwnerIdx);
584 anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aStoredOwner);
588 //===================================================
590 // INTERNAL METHODS ....
592 //==================================================
594 //==================================================
595 // Function: Contains
597 //==================================================
598 Standard_Boolean SelectMgr_ViewerSelector::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
600 return mySelectableObjects.Contains (theObject)
601 || mySelectableObjectsTrsfPers.Contains (theObject);
604 //==================================================
605 // Function: ActiveModes
606 // Purpose : return all the modes with a given state for an object
607 //==================================================
608 Standard_Boolean SelectMgr_ViewerSelector::Modes (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
609 TColStd_ListOfInteger& theModeList,
610 const SelectMgr_StateOfSelection theWantedState) const
612 Standard_Boolean hasActivatedStates = Contains (theSelectableObject);
613 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
615 if (theWantedState == SelectMgr_SOS_Any)
617 theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
619 else if (theWantedState == theSelectableObject->CurrentSelection()->GetSelectionState())
621 theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
625 return hasActivatedStates;
628 //==================================================
629 // Function: IsActive
631 //==================================================
632 Standard_Boolean SelectMgr_ViewerSelector::IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
633 const Standard_Integer theMode) const
635 if (!Contains (theSelectableObject))
636 return Standard_False;
638 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
640 if (theMode == theSelectableObject->CurrentSelection()->Mode())
642 return theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated;
646 return Standard_False;
649 //==================================================
650 // Function: IsInside
652 //==================================================
653 Standard_Boolean SelectMgr_ViewerSelector::IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
654 const Standard_Integer theMode) const
656 if (!Contains (theSelectableObject))
657 return Standard_False;
659 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
661 if (theMode == theSelectableObject->CurrentSelection()->Mode())
663 return theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown;
667 return Standard_False;
671 //=======================================================================
674 //=======================================================================
676 SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_Selection)& theSelection) const
678 return theSelection->GetSelectionState();
681 //==================================================
683 // Purpose : gives Information about selectors
684 //==================================================
686 TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const
688 TCollection_AsciiString aStatus ("Status Object :\n\t");
690 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
692 if (theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown)
694 aStatus = aStatus + "Mode " +
695 TCollection_AsciiString (theSelectableObject->CurrentSelection()->Mode()) +
697 if (theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated)
699 aStatus = aStatus + " Active \n\t";
703 aStatus = aStatus + " Inactive \n\t";
708 if (!Contains (theSelectableObject))
710 aStatus = aStatus + "Not Present in the selector\n\n";
716 //=======================================================================
717 //function : SortResult
718 //purpose : there is a certain number of entities ranged by criteria
719 // (depth, size, priority, mouse distance from borders or
720 // CDG of the detected primitive. Parsing :
721 // maximum priorities .
722 // then a reasonable compromise between depth and distance...
723 // finally the ranges are stored in myindexes depending on the parsing.
724 // so, it is possible to only read
725 //=======================================================================
726 void SelectMgr_ViewerSelector::SortResult()
728 if(mystored.IsEmpty()) return;
730 const Standard_Integer anExtent = mystored.Extent();
731 if(myIndexes.IsNull() || anExtent != myIndexes->Length())
732 myIndexes = new TColStd_HArray1OfInteger (1, anExtent);
735 TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1();
737 // indices from 1 to N are loaded
739 for (I=1; I <= anExtent; I++)
742 std::sort (thearr.begin(), thearr.end(), CompareResults (mystored));
746 //=======================================================================
747 //function : HasDepthClipping
749 //=======================================================================
750 Standard_Boolean SelectMgr_ViewerSelector::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& /*theOwner*/) const
752 return Standard_False;
755 //=======================================================================
756 // function : AddSelectableObject
757 // purpose : Adds new object to the map of selectable objects
758 //=======================================================================
759 void SelectMgr_ViewerSelector::AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
761 if (!myMapOfObjectSensitives.IsBound (theObject))
763 if (!theObject->TransformPersistence().Flags)
765 mySelectableObjects.Append (theObject);
769 mySelectableObjectsTrsfPers.Append (theObject);
772 NCollection_Handle<SelectMgr_SensitiveEntitySet> anEntitySet = new SelectMgr_SensitiveEntitySet();
773 myMapOfObjectSensitives.Bind (theObject, anEntitySet);
777 //=======================================================================
778 // function : AddSelectionToObject
779 // purpose : Adds new selection to the object and builds its BVH tree
780 //=======================================================================
781 void SelectMgr_ViewerSelector::AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject,
782 const Handle(SelectMgr_Selection)& theSelection)
784 if (myMapOfObjectSensitives.IsBound (theObject))
786 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
787 myMapOfObjectSensitives.ChangeFind (theObject);
788 anEntitySet->Append (theSelection);
793 AddSelectableObject (theObject);
794 AddSelectionToObject (theObject, theSelection);
798 //=======================================================================
799 // function : RemoveSelectableObject
800 // purpose : Removes selectable object from map of selectable ones
801 //=======================================================================
802 void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
804 if (myMapOfObjectSensitives.IsBound (theObject))
806 if (!mySelectableObjects.Remove (theObject))
808 mySelectableObjectsTrsfPers.Remove (theObject);
810 myMapOfObjectSensitives.UnBind (theObject);
814 //=======================================================================
815 // function : RemoveSelectionOfObject
816 // purpose : Removes selection of the object and marks its BVH tree
818 //=======================================================================
819 void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject,
820 const Handle(SelectMgr_Selection)& theSelection)
822 if (myMapOfObjectSensitives.IsBound (theObject))
824 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
825 myMapOfObjectSensitives.ChangeFind (theObject);
826 anEntitySet->Remove (theSelection);
830 //=======================================================================
831 // function : RebuildObjectsTree
832 // purpose : Marks BVH of selectable objects for rebuild
833 //=======================================================================
834 void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce)
836 mySelectableObjects.MarkDirty();
837 mySelectableObjectsTrsfPers.MarkDirty();
841 const Graphic3d_Mat4d& aProjection = mySelectingVolumeMgr.ProjectionMatrix();
842 const Graphic3d_Mat4d& aWorldView = mySelectingVolumeMgr.WorldViewMatrix();
843 const Graphic3d_WorldViewProjState& aWVPState = mySelectingVolumeMgr.WorldViewProjState();
845 mySelectableObjects.BVH();
846 mySelectableObjectsTrsfPers.BVH (aProjection, aWorldView, aWVPState);
850 //=======================================================================
851 // function : RebuildSensitivesTree
852 // purpose : Marks BVH of sensitive entities of particular selectable
853 // object for rebuild
854 //=======================================================================
855 void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject,
856 const Standard_Boolean theIsForce)
858 if (!Contains (theObject))
861 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
862 anEntitySet->MarkDirty();
870 //=======================================================================
871 // function : resetSelectionActivationStatus
872 // purpose : Marks all added sensitive entities of all objects as
874 //=======================================================================
875 void SelectMgr_ViewerSelector::ResetSelectionActivationStatus()
877 SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives);
878 for ( ; aSensitivesIter.More(); aSensitivesIter.Next())
880 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
881 aSensitivesIter.ChangeValue();
882 Standard_Integer anEntitiesNb = anEntitySet->Size();
883 for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
885 anEntitySet->GetSensitiveById (anIdx)->ResetSelectionActiveStatus();
890 //=======================================================================
891 // function : DetectedEntity
892 // purpose : Returns sensitive entity that was detected during the
893 // previous run of selection algorithm
894 //=======================================================================
895 const Handle(SelectBasics_SensitiveEntity)& SelectMgr_ViewerSelector::DetectedEntity() const
897 const Handle(SelectMgr_EntityOwner)& anOwner = myDetectedIter.Key();
898 const Handle(SelectMgr_SelectableObject)& anObject = anOwner->Selectable();
899 const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
900 myMapOfObjectSensitives.Find (anObject);
902 return anEntitySet->GetSensitiveById (myDetectedIter.Value())->BaseSensitive();
905 //=======================================================================
906 // function : ActiveOwners
907 // purpose : Returns the list of active entity owners
908 //=======================================================================
909 void SelectMgr_ViewerSelector::ActiveOwners (NCollection_List<Handle(SelectBasics_EntityOwner)>& theOwners) const
911 for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next())
913 const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = anIter.Value();
914 Standard_Integer anEntitiesNb = anEntitySet->Size();
915 for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
917 if (anEntitySet->GetSensitiveById (anIdx)->IsActiveForSelection())
919 theOwners.Append (anEntitySet->GetSensitiveById (anIdx)->BaseSensitive()->OwnerId());
925 //=======================================================================
926 //function : AllowOverlapDetection
927 //purpose : Sets the detection type: if theIsToAllow is false,
928 // only fully included sensitives will be detected, otherwise
929 // the algorithm will mark both included and overlapped entities
931 //=======================================================================
932 void SelectMgr_ViewerSelector::AllowOverlapDetection (const Standard_Boolean theIsToAllow)
934 mySelectingVolumeMgr.AllowOverlapDetection (theIsToAllow);