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 = isToScaleFrustum (theEnt) ? sensitivity (theEnt) : 1;
273 const gp_Trsf aTrsfMtr = theEnt->HasInitLocation() ? theEnt->InvInitLocation() * theInvTrsf : theInvTrsf;
274 const Standard_Boolean toScale = aScale != 1;
275 const Standard_Boolean toTransform = aTrsfMtr.Form() != gp_Identity;
276 if (toScale && toTransform)
278 theResMgr = mySelectingVolumeMgr.ScaleAndTransform (aScale, aTrsfMtr);
282 if (!theCachedMgrs.IsBound (aScale))
284 theCachedMgrs.Bind (aScale, mySelectingVolumeMgr.ScaleAndTransform (aScale, gp_Trsf()));
286 theResMgr = theCachedMgrs.Find (aScale);
288 else if (toTransform)
290 theResMgr = mySelectingVolumeMgr.ScaleAndTransform (1, aTrsfMtr);
294 //=======================================================================
295 // function: traverseObject
296 // purpose : Internal function that checks if there is possible overlap
297 // between some entity of selectable object theObject and
298 // current selecting volume
299 //=======================================================================
300 void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_SelectableObject)& theObject)
302 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
303 myMapOfObjectSensitives.ChangeFind (theObject);
305 if (anEntitySet->Size() == 0)
308 const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
310 gp_Trsf aInversedTrsf;
312 if (theObject->HasTransformation() || theObject->TransformPersistence().Flags)
314 if (!theObject->TransformPersistence().Flags)
316 aInversedTrsf = theObject->InversedTransformation();
320 const Graphic3d_Mat4d& aProjection = mySelectingVolumeMgr.ProjectionMatrix();
321 const Graphic3d_Mat4d& aWorldView = mySelectingVolumeMgr.WorldViewMatrix();
324 Graphic3d_Mat4d aMat = theObject->TransformPersistence().Compute (aProjection, aWorldView, 0, 0);
325 aTPers.SetValues (aMat.GetValue (0, 0), aMat.GetValue (0, 1), aMat.GetValue (0, 2), aMat.GetValue (0, 3),
326 aMat.GetValue (1, 0), aMat.GetValue (1, 1), aMat.GetValue (1, 2), aMat.GetValue (1, 3),
327 aMat.GetValue (2, 0), aMat.GetValue (2, 1), aMat.GetValue (2, 2), aMat.GetValue (2, 3));
329 aInversedTrsf = (aTPers * theObject->Transformation()).Inverted();
333 SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity
334 ? mySelectingVolumeMgr.ScaleAndTransform (1, aInversedTrsf)
335 : mySelectingVolumeMgr;
337 SelectMgr_FrustumCache aScaledTrnsfFrustums;
339 Standard_Integer aNode = 0; // a root node
340 if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
341 aSensitivesTree->MaxPoint (0)))
345 Standard_Integer aStack[32];
346 Standard_Integer aHead = -1;
349 if (!aSensitivesTree->IsOuter (aNode))
351 const Standard_Integer aLeftChildIdx = aSensitivesTree->LeftChild (aNode);
352 const Standard_Integer aRightChildIdx = aSensitivesTree->RightChild (aNode);
353 const Standard_Boolean isLeftChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aLeftChildIdx),
354 aSensitivesTree->MaxPoint (aLeftChildIdx));
355 const Standard_Boolean isRightChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aRightChildIdx),
356 aSensitivesTree->MaxPoint (aRightChildIdx));
360 aNode = aLeftChildIdx;
362 aStack[aHead] = aRightChildIdx;
364 else if (isLeftChildIn
367 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
376 aNode = aStack[aHead];
382 Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode);
383 Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode);
384 for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
386 const Handle(SelectMgr_SensitiveEntity)& aSensitive =
387 anEntitySet->GetSensitiveById (anIdx);
388 if (aSensitive->IsActiveForSelection())
390 const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
391 SelectMgr_SelectingVolumeManager aTmpMgr = aMgr;
392 computeFrustum (anEnt, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
393 checkOverlap (anEnt, anIdx, aTmpMgr);
401 aNode = aStack[aHead];
407 //=======================================================================
408 // function: TraverseSensitives
409 // purpose : Traverses BVH containing all added selectable objects and
410 // finds candidates for further search of overlap
411 //=======================================================================
412 void SelectMgr_ViewerSelector::TraverseSensitives()
415 myMapOfDetected.Clear();
417 NCollection_Handle<BVH_Tree<Standard_Real, 3> > aBVHTree;
418 for (Standard_Integer aBVHTreeIdx = 0; aBVHTreeIdx < 2; ++aBVHTreeIdx)
420 const Standard_Boolean isTrsfPers = aBVHTreeIdx == 1;
423 if (mySelectableObjectsTrsfPers.Size() == 0)
427 const Graphic3d_Mat4d& aProjection = mySelectingVolumeMgr.ProjectionMatrix();
428 const Graphic3d_Mat4d& aWorldView = mySelectingVolumeMgr.WorldViewMatrix();
429 const Graphic3d_WorldViewProjState& aWVPState = mySelectingVolumeMgr.WorldViewProjState();
430 aBVHTree = mySelectableObjectsTrsfPers.BVH (aProjection, aWorldView, aWVPState);
434 if (mySelectableObjects.Size() == 0)
438 aBVHTree = mySelectableObjects.BVH();
441 Standard_Integer aNode = 0;
442 if (!mySelectingVolumeMgr.Overlaps (aBVHTree->MinPoint (0),
443 aBVHTree->MaxPoint (0)))
448 Standard_Integer aStack[32];
449 Standard_Integer aHead = -1;
452 if (!aBVHTree->IsOuter (aNode))
454 const Standard_Integer aLeftChildIdx = aBVHTree->LeftChild (aNode);
455 const Standard_Integer aRightChildIdx = aBVHTree->RightChild (aNode);
456 const Standard_Boolean isLeftChildIn =
457 mySelectingVolumeMgr.Overlaps (aBVHTree->MinPoint (aLeftChildIdx),
458 aBVHTree->MaxPoint (aLeftChildIdx));
459 const Standard_Boolean isRightChildIn =
460 mySelectingVolumeMgr.Overlaps (aBVHTree->MinPoint (aRightChildIdx),
461 aBVHTree->MaxPoint (aRightChildIdx));
465 aNode = aLeftChildIdx;
467 aStack[aHead] = aRightChildIdx;
469 else if (isLeftChildIn
472 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
481 aNode = aStack[aHead];
487 Standard_Integer aStartIdx = aBVHTree->BegPrimitive (aNode);
488 Standard_Integer anEndIdx = aBVHTree->EndPrimitive (aNode);
489 for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
491 Handle(SelectMgr_SelectableObject) aSelectableObject =
492 isTrsfPers ? mySelectableObjectsTrsfPers.GetObjectById (anIdx)
493 : mySelectableObjects.GetObjectById (anIdx);
495 traverseObject (aSelectableObject);
502 aNode = aStack[aHead];
511 //==================================================
514 //==================================================
515 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector
518 Standard_Integer RankInMap = myIndexes->Value (myCurRank);
519 const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap);
520 Handle(SelectMgr_EntityOwner) Ownr = Handle(SelectMgr_EntityOwner)::DownCast (toto);
526 //=======================================================================
529 //=======================================================================
530 Standard_Boolean SelectMgr_ViewerSelector::More()
532 if(mystored.Extent()==0) return Standard_False;
533 if(myCurRank==0) return Standard_False;
534 return myCurRank <= myIndexes->Length();
537 //==================================================
538 // Function: OnePicked
539 // Purpose : only the best one is chosen
540 // depend on priority and mindist...
541 //==================================================
543 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector
549 Standard_Integer RankInMap = myIndexes->Value (myIndexes->Lower());
550 const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap);
551 Handle(SelectMgr_EntityOwner) Ownr = Handle(SelectMgr_EntityOwner)::DownCast (toto);
555 Handle (SelectMgr_EntityOwner) NullObj; //returns a null Handle if there was not successfull pick...
560 //=======================================================================
561 //function : NbPicked
563 //=======================================================================
565 Standard_Integer SelectMgr_ViewerSelector::NbPicked() const
567 return mystored.Extent();
569 //=======================================================================
572 //=======================================================================
573 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked(const Standard_Integer aRank) const
576 Handle(SelectMgr_EntityOwner) anOwner;
577 if (aRank < 1 || aRank > NbPicked())
579 Standard_Integer anOwnerIdx = myIndexes->Value (aRank);
582 const Handle(SelectBasics_EntityOwner)& aStoredOwner = mystored.FindKey (anOwnerIdx);
583 anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aStoredOwner);
587 //===================================================
589 // INTERNAL METHODS ....
591 //==================================================
593 //==================================================
594 // Function: Contains
596 //==================================================
597 Standard_Boolean SelectMgr_ViewerSelector::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
599 return mySelectableObjects.Contains (theObject)
600 || mySelectableObjectsTrsfPers.Contains (theObject);
603 //==================================================
604 // Function: ActiveModes
605 // Purpose : return all the modes with a given state for an object
606 //==================================================
607 Standard_Boolean SelectMgr_ViewerSelector::Modes (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
608 TColStd_ListOfInteger& theModeList,
609 const SelectMgr_StateOfSelection theWantedState) const
611 Standard_Boolean hasActivatedStates = Contains (theSelectableObject);
612 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
614 if (theWantedState == SelectMgr_SOS_Any)
616 theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
618 else if (theWantedState == theSelectableObject->CurrentSelection()->GetSelectionState())
620 theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
624 return hasActivatedStates;
627 //==================================================
628 // Function: IsActive
630 //==================================================
631 Standard_Boolean SelectMgr_ViewerSelector::IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
632 const Standard_Integer theMode) const
634 if (!Contains (theSelectableObject))
635 return Standard_False;
637 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
639 if (theMode == theSelectableObject->CurrentSelection()->Mode())
641 return theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated;
645 return Standard_False;
648 //==================================================
649 // Function: IsInside
651 //==================================================
652 Standard_Boolean SelectMgr_ViewerSelector::IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
653 const Standard_Integer theMode) const
655 if (!Contains (theSelectableObject))
656 return Standard_False;
658 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
660 if (theMode == theSelectableObject->CurrentSelection()->Mode())
662 return theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown;
666 return Standard_False;
670 //=======================================================================
673 //=======================================================================
675 SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_Selection)& theSelection) const
677 return theSelection->GetSelectionState();
680 //==================================================
682 // Purpose : gives Information about selectors
683 //==================================================
685 TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const
687 TCollection_AsciiString aStatus ("Status Object :\n\t");
689 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
691 if (theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown)
693 aStatus = aStatus + "Mode " +
694 TCollection_AsciiString (theSelectableObject->CurrentSelection()->Mode()) +
696 if (theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated)
698 aStatus = aStatus + " Active \n\t";
702 aStatus = aStatus + " Inactive \n\t";
707 if (!Contains (theSelectableObject))
709 aStatus = aStatus + "Not Present in the selector\n\n";
715 //=======================================================================
716 //function : SortResult
717 //purpose : there is a certain number of entities ranged by criteria
718 // (depth, size, priority, mouse distance from borders or
719 // CDG of the detected primitive. Parsing :
720 // maximum priorities .
721 // then a reasonable compromise between depth and distance...
722 // finally the ranges are stored in myindexes depending on the parsing.
723 // so, it is possible to only read
724 //=======================================================================
725 void SelectMgr_ViewerSelector::SortResult()
727 if(mystored.IsEmpty()) return;
729 const Standard_Integer anExtent = mystored.Extent();
730 if(myIndexes.IsNull() || anExtent != myIndexes->Length())
731 myIndexes = new TColStd_HArray1OfInteger (1, anExtent);
734 TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1();
736 // indices from 1 to N are loaded
738 for (I=1; I <= anExtent; I++)
741 std::sort (thearr.begin(), thearr.end(), CompareResults (mystored));
745 //=======================================================================
746 //function : HasDepthClipping
748 //=======================================================================
749 Standard_Boolean SelectMgr_ViewerSelector::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& /*theOwner*/) const
751 return Standard_False;
754 //=======================================================================
755 // function : AddSelectableObject
756 // purpose : Adds new object to the map of selectable objects
757 //=======================================================================
758 void SelectMgr_ViewerSelector::AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
760 if (!myMapOfObjectSensitives.IsBound (theObject))
762 if (!theObject->TransformPersistence().Flags)
764 mySelectableObjects.Append (theObject);
768 mySelectableObjectsTrsfPers.Append (theObject);
771 NCollection_Handle<SelectMgr_SensitiveEntitySet> anEntitySet = new SelectMgr_SensitiveEntitySet();
772 myMapOfObjectSensitives.Bind (theObject, anEntitySet);
776 //=======================================================================
777 // function : AddSelectionToObject
778 // purpose : Adds new selection to the object and builds its BVH tree
779 //=======================================================================
780 void SelectMgr_ViewerSelector::AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject,
781 const Handle(SelectMgr_Selection)& theSelection)
783 if (myMapOfObjectSensitives.IsBound (theObject))
785 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
786 myMapOfObjectSensitives.ChangeFind (theObject);
787 anEntitySet->Append (theSelection);
792 AddSelectableObject (theObject);
793 AddSelectionToObject (theObject, theSelection);
797 //=======================================================================
798 // function : RemoveSelectableObject
799 // purpose : Removes selectable object from map of selectable ones
800 //=======================================================================
801 void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
803 if (myMapOfObjectSensitives.IsBound (theObject))
805 if (!mySelectableObjects.Remove (theObject))
807 mySelectableObjectsTrsfPers.Remove (theObject);
809 myMapOfObjectSensitives.UnBind (theObject);
813 //=======================================================================
814 // function : RemoveSelectionOfObject
815 // purpose : Removes selection of the object and marks its BVH tree
817 //=======================================================================
818 void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject,
819 const Handle(SelectMgr_Selection)& theSelection)
821 if (myMapOfObjectSensitives.IsBound (theObject))
823 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
824 myMapOfObjectSensitives.ChangeFind (theObject);
825 anEntitySet->Remove (theSelection);
829 //=======================================================================
830 // function : RebuildObjectsTree
831 // purpose : Marks BVH of selectable objects for rebuild
832 //=======================================================================
833 void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce)
835 mySelectableObjects.MarkDirty();
836 mySelectableObjectsTrsfPers.MarkDirty();
840 const Graphic3d_Mat4d& aProjection = mySelectingVolumeMgr.ProjectionMatrix();
841 const Graphic3d_Mat4d& aWorldView = mySelectingVolumeMgr.WorldViewMatrix();
842 const Graphic3d_WorldViewProjState& aWVPState = mySelectingVolumeMgr.WorldViewProjState();
844 mySelectableObjects.BVH();
845 mySelectableObjectsTrsfPers.BVH (aProjection, aWorldView, aWVPState);
849 //=======================================================================
850 // function : RebuildSensitivesTree
851 // purpose : Marks BVH of sensitive entities of particular selectable
852 // object for rebuild
853 //=======================================================================
854 void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject,
855 const Standard_Boolean theIsForce)
857 if (!Contains (theObject))
860 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
861 anEntitySet->MarkDirty();
869 //=======================================================================
870 // function : resetSelectionActivationStatus
871 // purpose : Marks all added sensitive entities of all objects as
873 //=======================================================================
874 void SelectMgr_ViewerSelector::ResetSelectionActivationStatus()
876 SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives);
877 for ( ; aSensitivesIter.More(); aSensitivesIter.Next())
879 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
880 aSensitivesIter.ChangeValue();
881 Standard_Integer anEntitiesNb = anEntitySet->Size();
882 for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
884 anEntitySet->GetSensitiveById (anIdx)->ResetSelectionActiveStatus();
889 //=======================================================================
890 // function : DetectedEntity
891 // purpose : Returns sensitive entity that was detected during the
892 // previous run of selection algorithm
893 //=======================================================================
894 const Handle(SelectBasics_SensitiveEntity)& SelectMgr_ViewerSelector::DetectedEntity() const
896 const Handle(SelectMgr_EntityOwner)& anOwner = myDetectedIter.Key();
897 const Handle(SelectMgr_SelectableObject)& anObject = anOwner->Selectable();
898 const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
899 myMapOfObjectSensitives.Find (anObject);
901 return anEntitySet->GetSensitiveById (myDetectedIter.Value())->BaseSensitive();
904 //=======================================================================
905 // function : ActiveOwners
906 // purpose : Returns the list of active entity owners
907 //=======================================================================
908 void SelectMgr_ViewerSelector::ActiveOwners (NCollection_List<Handle(SelectBasics_EntityOwner)>& theOwners) const
910 for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next())
912 const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = anIter.Value();
913 Standard_Integer anEntitiesNb = anEntitySet->Size();
914 for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
916 if (anEntitySet->GetSensitiveById (anIdx)->IsActiveForSelection())
918 theOwners.Append (anEntitySet->GetSensitiveById (anIdx)->BaseSensitive()->OwnerId());
924 //=======================================================================
925 //function : AllowOverlapDetection
926 //purpose : Sets the detection type: if theIsToAllow is false,
927 // only fully included sensitives will be detected, otherwise
928 // the algorithm will mark both included and overlapped entities
930 //=======================================================================
931 void SelectMgr_ViewerSelector::AllowOverlapDetection (const Standard_Boolean theIsToAllow)
933 mySelectingVolumeMgr.AllowOverlapDetection (theIsToAllow);