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>
22 #include <gp_GTrsf.hxx>
24 #include <OSD_Environment.hxx>
25 #include <Precision.hxx>
26 #include <SelectMgr_ViewerSelector.hxx>
27 #include <SelectBasics_EntityOwner.hxx>
28 #include <SelectBasics_SensitiveEntity.hxx>
29 #include <SelectBasics_PickResult.hxx>
30 #include <SelectMgr_EntityOwner.hxx>
31 #include <SelectMgr_SortCriterion.hxx>
32 #include <SelectMgr_SensitiveEntitySet.hxx>
33 #include <TColStd_Array1OfInteger.hxx>
34 #include <TCollection_AsciiString.hxx>
35 #include <TColStd_HArray1OfInteger.hxx>
36 #include <TColStd_ListOfInteger.hxx>
40 IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_ViewerSelector,MMgt_TShared)
43 // Comparison operator for sorting selection results
48 CompareResults (const SelectMgr_IndexedDataMapOfOwnerCriterion& aMapOfCriterion)
49 : myMapOfCriterion (aMapOfCriterion)
53 Standard_Boolean operator() (Standard_Integer theLeft, Standard_Integer theRight) const
55 return myMapOfCriterion.FindFromIndex(theLeft) > myMapOfCriterion.FindFromIndex(theRight);
59 void operator = (const CompareResults&);
62 const SelectMgr_IndexedDataMapOfOwnerCriterion& myMapOfCriterion;
66 //=======================================================================
67 // function: SelectMgr_ToleranceMap
68 // purpose : Sets tolerance values to -1.0
69 //=======================================================================
70 SelectMgr_ToleranceMap::SelectMgr_ToleranceMap()
73 myCustomTolerance = -1;
76 //=======================================================================
77 // function: ~SelectMgr_ToleranceMap
79 //=======================================================================
80 SelectMgr_ToleranceMap::~SelectMgr_ToleranceMap()
85 //=======================================================================
87 // purpose : Adds the value given to map, checks if the current tolerance value
88 // should be replaced by theTolerance
89 //=======================================================================
90 void SelectMgr_ToleranceMap::Add (const Standard_Integer& theTolerance)
92 if (myTolerances.IsBound (theTolerance))
94 Standard_Integer& aFreq = myTolerances.ChangeFind (theTolerance);
97 if (aFreq == 1 && theTolerance != myLargestKey)
98 myLargestKey = Max (theTolerance, myLargestKey);
102 if (myTolerances.IsEmpty())
104 myTolerances.Bind (theTolerance, 1);
105 myLargestKey = theTolerance;
109 myTolerances.Bind (theTolerance, 1);
110 myLargestKey = Max (theTolerance, myLargestKey);
114 //=======================================================================
115 // function: Decrement
116 // purpose : Decrements a counter of the tolerance given, checks if the current tolerance value
117 // should be recalculated
118 //=======================================================================
119 void SelectMgr_ToleranceMap::Decrement (const Standard_Integer& theTolerance)
121 if (myTolerances.IsBound (theTolerance))
123 Standard_Integer& aFreq = myTolerances.ChangeFind (theTolerance);
126 if (Abs (theTolerance - myLargestKey) < Precision::Confusion() && aFreq == 0)
129 for (NCollection_DataMap<Standard_Integer, Standard_Integer>::Iterator anIter (myTolerances); anIter.More(); anIter.Next())
131 if (anIter.Value() != 0)
132 myLargestKey = Max (myLargestKey, anIter.Key());
138 //==================================================
139 // Function: Initialize
141 //==================================================
142 SelectMgr_ViewerSelector::SelectMgr_ViewerSelector():
143 preferclosest(Standard_True),
144 myToUpdateTolerance (Standard_True),
146 myIsLeftChildQueuedFirst (Standard_False),
151 //==================================================
152 // Function: Activate
154 //==================================================
155 void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSelection)
157 for (theSelection->Init(); theSelection->More(); theSelection->Next())
159 theSelection->Sensitive()->SetActiveForSelection();
162 theSelection->SetSelectionState (SelectMgr_SOS_Activated);
164 myTolerances.Add (theSelection->Sensitivity());
165 myToUpdateTolerance = Standard_True;
168 //==================================================
169 // Function: Deactivate
171 //==================================================
172 void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theSelection)
174 for (theSelection->Init(); theSelection->More(); theSelection->Next())
176 theSelection->Sensitive()->ResetSelectionActiveStatus();
179 theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
181 myTolerances.Decrement (theSelection->Sensitivity());
182 myToUpdateTolerance = Standard_True;
185 //==================================================
188 //==================================================
189 void SelectMgr_ViewerSelector::Clear()
192 myMapOfDetected.Clear();
195 //=======================================================================
196 // function: isToScaleFrustum
197 // purpose : Checks if the entity given requires to scale current selecting frustum
198 //=======================================================================
199 Standard_Boolean SelectMgr_ViewerSelector::isToScaleFrustum (const Handle(SelectBasics_SensitiveEntity)& theEntity)
201 return mySelectingVolumeMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point
202 && sensitivity (theEntity) < myTolerances.Tolerance();
205 //=======================================================================
206 // function: sensitivity
207 // purpose : In case if custom tolerance is set, this method will return sum of entity
208 // sensitivity and custom tolerance.
209 //=======================================================================
210 Standard_Integer SelectMgr_ViewerSelector::sensitivity (const Handle(SelectBasics_SensitiveEntity)& theEntity) const
212 return myTolerances.IsCustomTolSet() ?
213 theEntity->SensitivityFactor() + myTolerances.CustomTolerance() : theEntity->SensitivityFactor();
216 //=======================================================================
217 // function: checkOverlap
218 // purpose : Internal function that checks if a particular sensitive
219 // entity theEntity overlaps current selecting volume precisely
220 //=======================================================================
221 void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_SensitiveEntity)& theEntity,
222 const Standard_Integer theEntityIdx,
223 SelectMgr_SelectingVolumeManager& theMgr)
225 Handle(SelectMgr_EntityOwner) anOwner (Handle(SelectMgr_EntityOwner)::DownCast (theEntity->OwnerId()));
227 SelectBasics_PickResult aPickResult;
228 if (theEntity->Matches (theMgr, aPickResult))
230 if (!anOwner.IsNull())
232 if (HasDepthClipping (anOwner) && theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point)
234 Standard_Boolean isClipped = mySelectingVolumeMgr.IsClipped (anOwner->Selectable()->GetClipPlanes(),
235 aPickResult.Depth());
240 Standard_Integer aPriority = anOwner->Priority();
242 SelectMgr_SortCriterion aCriterion (aPriority, aPickResult.Depth(), aPickResult.DistToGeomCenter(), theEntity->SensitivityFactor() / 33.0, preferclosest);
243 if (mystored.Contains (anOwner))
245 if (theMgr.GetActiveSelectionType() != 1)
247 SelectMgr_SortCriterion& aPrevCriterion = mystored.ChangeFromKey (anOwner);
248 if (aCriterion > aPrevCriterion)
250 aPrevCriterion = aCriterion;
251 myMapOfDetected.ChangeFind (anOwner) = theEntityIdx;
257 mystored.Add (anOwner, aCriterion);
258 myMapOfDetected.Bind (anOwner, theEntityIdx);
264 //=======================================================================
265 // function: computeFrustum
266 // purpose : Internal function that checks if a current selecting frustum
267 // needs to be scaled and transformed for the entity and performs
268 // necessary calculations
269 //=======================================================================
270 void SelectMgr_ViewerSelector::computeFrustum (const Handle(SelectBasics_SensitiveEntity)& theEnt,
271 const gp_GTrsf& theInvTrsf,
272 SelectMgr_FrustumCache& theCachedMgrs,
273 SelectMgr_SelectingVolumeManager& theResMgr)
275 Standard_Integer aScale = isToScaleFrustum (theEnt) ? sensitivity (theEnt) : 1;
276 const gp_GTrsf aTrsfMtr = theEnt->HasInitLocation() ? theEnt->InvInitLocation() * theInvTrsf : theInvTrsf;
277 const Standard_Boolean toScale = aScale != 1;
278 const Standard_Boolean toTransform = aTrsfMtr.Form() != gp_Identity;
279 if (toScale && toTransform)
281 theResMgr = mySelectingVolumeMgr.ScaleAndTransform (aScale, aTrsfMtr);
285 if (!theCachedMgrs.IsBound (aScale))
287 theCachedMgrs.Bind (aScale, mySelectingVolumeMgr.ScaleAndTransform (aScale, gp_Trsf()));
289 theResMgr = theCachedMgrs.Find (aScale);
291 else if (toTransform)
293 theResMgr = mySelectingVolumeMgr.ScaleAndTransform (1, aTrsfMtr);
297 //=======================================================================
298 // function: traverseObject
299 // purpose : Internal function that checks if there is possible overlap
300 // between some entity of selectable object theObject and
301 // current selecting volume
302 //=======================================================================
303 void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_SelectableObject)& theObject)
305 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
306 myMapOfObjectSensitives.ChangeFind (theObject);
308 if (anEntitySet->Size() == 0)
311 const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
313 gp_GTrsf aInversedTrsf;
315 if (theObject->HasTransformation() || theObject->TransformPersistence().Flags)
317 if (!theObject->TransformPersistence().Flags)
319 aInversedTrsf = theObject->InversedTransformation();
323 const Graphic3d_Mat4d& aProjection = mySelectingVolumeMgr.ProjectionMatrix();
324 const Graphic3d_Mat4d& aWorldView = mySelectingVolumeMgr.WorldViewMatrix();
325 Standard_Integer aViewportWidth;
326 Standard_Integer aViewportHeight;
327 mySelectingVolumeMgr.WindowSize (aViewportWidth, aViewportHeight);
330 Graphic3d_Mat4d aMat = theObject->TransformPersistence().Compute (aProjection, aWorldView, aViewportWidth, aViewportHeight);
331 aTPers.SetValue (1, 1, aMat.GetValue (0, 0));
332 aTPers.SetValue (1, 2, aMat.GetValue (0, 1));
333 aTPers.SetValue (1, 3, aMat.GetValue (0, 2));
334 aTPers.SetValue (2, 1, aMat.GetValue (1, 0));
335 aTPers.SetValue (2, 2, aMat.GetValue (1, 1));
336 aTPers.SetValue (2, 3, aMat.GetValue (1, 2));
337 aTPers.SetValue (3, 1, aMat.GetValue (2, 0));
338 aTPers.SetValue (3, 2, aMat.GetValue (2, 1));
339 aTPers.SetValue (3, 3, aMat.GetValue (2, 2));
340 aTPers.SetTranslationPart (gp_XYZ (aMat.GetValue (0, 3), aMat.GetValue (1, 3), aMat.GetValue (2, 3)));
342 aInversedTrsf = (aTPers * gp_GTrsf (theObject->Transformation())).Inverted();
346 SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity
347 ? mySelectingVolumeMgr.ScaleAndTransform (1, aInversedTrsf)
348 : mySelectingVolumeMgr;
350 SelectMgr_FrustumCache aScaledTrnsfFrustums;
352 Standard_Integer aNode = 0; // a root node
353 if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
354 aSensitivesTree->MaxPoint (0)))
358 Standard_Integer aStack[32];
359 Standard_Integer aHead = -1;
362 if (!aSensitivesTree->IsOuter (aNode))
364 const Standard_Integer aLeftChildIdx = aSensitivesTree->Child<0> (aNode);
365 const Standard_Integer aRightChildIdx = aSensitivesTree->Child<1> (aNode);
366 const Standard_Boolean isLeftChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aLeftChildIdx),
367 aSensitivesTree->MaxPoint (aLeftChildIdx));
368 const Standard_Boolean isRightChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aRightChildIdx),
369 aSensitivesTree->MaxPoint (aRightChildIdx));
373 aNode = aLeftChildIdx;
375 aStack[aHead] = aRightChildIdx;
377 else if (isLeftChildIn
380 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
389 aNode = aStack[aHead];
395 Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode);
396 Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode);
397 for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
399 const Handle(SelectMgr_SensitiveEntity)& aSensitive =
400 anEntitySet->GetSensitiveById (anIdx);
401 if (aSensitive->IsActiveForSelection())
403 const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
404 SelectMgr_SelectingVolumeManager aTmpMgr = aMgr;
405 computeFrustum (anEnt, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
406 checkOverlap (anEnt, anIdx, aTmpMgr);
414 aNode = aStack[aHead];
420 //=======================================================================
421 // function: TraverseSensitives
422 // purpose : Traverses BVH containing all added selectable objects and
423 // finds candidates for further search of overlap
424 //=======================================================================
425 void SelectMgr_ViewerSelector::TraverseSensitives()
428 myMapOfDetected.Clear();
430 NCollection_Handle<BVH_Tree<Standard_Real, 3> > aBVHTree;
431 for (Standard_Integer aBVHTreeIdx = 0; aBVHTreeIdx < 2; ++aBVHTreeIdx)
433 const Standard_Boolean isTrsfPers = aBVHTreeIdx == 1;
436 if (mySelectableObjectsTrsfPers.Size() == 0)
440 const Graphic3d_Mat4d& aProjection = mySelectingVolumeMgr.ProjectionMatrix();
441 const Graphic3d_Mat4d& aWorldView = mySelectingVolumeMgr.WorldViewMatrix();
442 const Graphic3d_WorldViewProjState& aWVPState = mySelectingVolumeMgr.WorldViewProjState();
443 Standard_Integer aViewportWidth;
444 Standard_Integer aViewportHeight;
445 mySelectingVolumeMgr.WindowSize (aViewportWidth, aViewportHeight);
446 aBVHTree = mySelectableObjectsTrsfPers.BVH (aProjection, aWorldView, aViewportWidth, aViewportHeight, aWVPState);
450 if (mySelectableObjects.Size() == 0)
454 aBVHTree = mySelectableObjects.BVH();
457 Standard_Integer aNode = 0;
458 if (!mySelectingVolumeMgr.Overlaps (aBVHTree->MinPoint (0),
459 aBVHTree->MaxPoint (0)))
464 Standard_Integer aStack[32];
465 Standard_Integer aHead = -1;
468 if (!aBVHTree->IsOuter (aNode))
470 const Standard_Integer aLeftChildIdx = aBVHTree->Child<0> (aNode);
471 const Standard_Integer aRightChildIdx = aBVHTree->Child<1> (aNode);
472 const Standard_Boolean isLeftChildIn =
473 mySelectingVolumeMgr.Overlaps (aBVHTree->MinPoint (aLeftChildIdx),
474 aBVHTree->MaxPoint (aLeftChildIdx));
475 const Standard_Boolean isRightChildIn =
476 mySelectingVolumeMgr.Overlaps (aBVHTree->MinPoint (aRightChildIdx),
477 aBVHTree->MaxPoint (aRightChildIdx));
481 aNode = aLeftChildIdx;
483 aStack[aHead] = aRightChildIdx;
485 else if (isLeftChildIn
488 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
497 aNode = aStack[aHead];
503 Standard_Integer aStartIdx = aBVHTree->BegPrimitive (aNode);
504 Standard_Integer anEndIdx = aBVHTree->EndPrimitive (aNode);
505 for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
507 Handle(SelectMgr_SelectableObject) aSelectableObject =
508 isTrsfPers ? mySelectableObjectsTrsfPers.GetObjectById (anIdx)
509 : mySelectableObjects.GetObjectById (anIdx);
511 traverseObject (aSelectableObject);
518 aNode = aStack[aHead];
527 //==================================================
530 //==================================================
531 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector
534 Standard_Integer RankInMap = myIndexes->Value (myCurRank);
535 const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap);
536 Handle(SelectMgr_EntityOwner) Ownr = Handle(SelectMgr_EntityOwner)::DownCast (toto);
542 //=======================================================================
545 //=======================================================================
546 Standard_Boolean SelectMgr_ViewerSelector::More()
548 if(mystored.Extent()==0) return Standard_False;
549 if(myCurRank==0) return Standard_False;
550 return myCurRank <= myIndexes->Length();
553 //==================================================
554 // Function: OnePicked
555 // Purpose : only the best one is chosen
556 // depend on priority and mindist...
557 //==================================================
559 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector
565 Standard_Integer RankInMap = myIndexes->Value (myIndexes->Lower());
566 const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap);
567 Handle(SelectMgr_EntityOwner) Ownr = Handle(SelectMgr_EntityOwner)::DownCast (toto);
571 Handle (SelectMgr_EntityOwner) NullObj; //returns a null Handle if there was not successfull pick...
576 //=======================================================================
577 //function : NbPicked
579 //=======================================================================
581 Standard_Integer SelectMgr_ViewerSelector::NbPicked() const
583 return mystored.Extent();
585 //=======================================================================
588 //=======================================================================
589 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked(const Standard_Integer aRank) const
592 Handle(SelectMgr_EntityOwner) anOwner;
593 if (aRank < 1 || aRank > NbPicked())
595 Standard_Integer anOwnerIdx = myIndexes->Value (aRank);
598 const Handle(SelectBasics_EntityOwner)& aStoredOwner = mystored.FindKey (anOwnerIdx);
599 anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aStoredOwner);
603 //===================================================
605 // INTERNAL METHODS ....
607 //==================================================
609 //==================================================
610 // Function: Contains
612 //==================================================
613 Standard_Boolean SelectMgr_ViewerSelector::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
615 return mySelectableObjects.Contains (theObject)
616 || mySelectableObjectsTrsfPers.Contains (theObject);
619 //==================================================
620 // Function: ActiveModes
621 // Purpose : return all the modes with a given state for an object
622 //==================================================
623 Standard_Boolean SelectMgr_ViewerSelector::Modes (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
624 TColStd_ListOfInteger& theModeList,
625 const SelectMgr_StateOfSelection theWantedState) const
627 Standard_Boolean hasActivatedStates = Contains (theSelectableObject);
628 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
630 if (theWantedState == SelectMgr_SOS_Any)
632 theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
634 else if (theWantedState == theSelectableObject->CurrentSelection()->GetSelectionState())
636 theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
640 return hasActivatedStates;
643 //==================================================
644 // Function: IsActive
646 //==================================================
647 Standard_Boolean SelectMgr_ViewerSelector::IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
648 const Standard_Integer theMode) const
650 if (!Contains (theSelectableObject))
651 return Standard_False;
653 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
655 if (theMode == theSelectableObject->CurrentSelection()->Mode())
657 return theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated;
661 return Standard_False;
664 //==================================================
665 // Function: IsInside
667 //==================================================
668 Standard_Boolean SelectMgr_ViewerSelector::IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
669 const Standard_Integer theMode) const
671 if (!Contains (theSelectableObject))
672 return Standard_False;
674 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
676 if (theMode == theSelectableObject->CurrentSelection()->Mode())
678 return theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown;
682 return Standard_False;
686 //=======================================================================
689 //=======================================================================
691 SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_Selection)& theSelection) const
693 return theSelection->GetSelectionState();
696 //==================================================
698 // Purpose : gives Information about selectors
699 //==================================================
701 TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const
703 TCollection_AsciiString aStatus ("Status Object :\n\t");
705 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
707 if (theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown)
709 aStatus = aStatus + "Mode " +
710 TCollection_AsciiString (theSelectableObject->CurrentSelection()->Mode()) +
712 if (theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated)
714 aStatus = aStatus + " Active \n\t";
718 aStatus = aStatus + " Inactive \n\t";
723 if (!Contains (theSelectableObject))
725 aStatus = aStatus + "Not Present in the selector\n\n";
731 //=======================================================================
732 //function : SortResult
733 //purpose : there is a certain number of entities ranged by criteria
734 // (depth, size, priority, mouse distance from borders or
735 // CDG of the detected primitive. Parsing :
736 // maximum priorities .
737 // then a reasonable compromise between depth and distance...
738 // finally the ranges are stored in myindexes depending on the parsing.
739 // so, it is possible to only read
740 //=======================================================================
741 void SelectMgr_ViewerSelector::SortResult()
743 if(mystored.IsEmpty()) return;
745 const Standard_Integer anExtent = mystored.Extent();
746 if(myIndexes.IsNull() || anExtent != myIndexes->Length())
747 myIndexes = new TColStd_HArray1OfInteger (1, anExtent);
750 TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1();
752 // indices from 1 to N are loaded
754 for (I=1; I <= anExtent; I++)
757 std::sort (thearr.begin(), thearr.end(), CompareResults (mystored));
761 //=======================================================================
762 //function : HasDepthClipping
764 //=======================================================================
765 Standard_Boolean SelectMgr_ViewerSelector::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& /*theOwner*/) const
767 return Standard_False;
770 //=======================================================================
771 // function : AddSelectableObject
772 // purpose : Adds new object to the map of selectable objects
773 //=======================================================================
774 void SelectMgr_ViewerSelector::AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
776 if (!myMapOfObjectSensitives.IsBound (theObject))
778 if (!theObject->TransformPersistence().Flags)
780 mySelectableObjects.Append (theObject);
784 mySelectableObjectsTrsfPers.Append (theObject);
787 NCollection_Handle<SelectMgr_SensitiveEntitySet> anEntitySet = new SelectMgr_SensitiveEntitySet();
788 myMapOfObjectSensitives.Bind (theObject, anEntitySet);
792 //=======================================================================
793 // function : AddSelectionToObject
794 // purpose : Adds new selection to the object and builds its BVH tree
795 //=======================================================================
796 void SelectMgr_ViewerSelector::AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject,
797 const Handle(SelectMgr_Selection)& theSelection)
799 if (myMapOfObjectSensitives.IsBound (theObject))
801 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
802 myMapOfObjectSensitives.ChangeFind (theObject);
803 anEntitySet->Append (theSelection);
808 AddSelectableObject (theObject);
809 AddSelectionToObject (theObject, theSelection);
813 //=======================================================================
814 // function : RemoveSelectableObject
815 // purpose : Removes selectable object from map of selectable ones
816 //=======================================================================
817 void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
819 if (myMapOfObjectSensitives.IsBound (theObject))
821 if (!mySelectableObjects.Remove (theObject))
823 mySelectableObjectsTrsfPers.Remove (theObject);
825 myMapOfObjectSensitives.UnBind (theObject);
829 //=======================================================================
830 // function : RemoveSelectionOfObject
831 // purpose : Removes selection of the object and marks its BVH tree
833 //=======================================================================
834 void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject,
835 const Handle(SelectMgr_Selection)& theSelection)
837 if (myMapOfObjectSensitives.IsBound (theObject))
839 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
840 myMapOfObjectSensitives.ChangeFind (theObject);
841 anEntitySet->Remove (theSelection);
845 //=======================================================================
846 // function : RebuildObjectsTree
847 // purpose : Marks BVH of selectable objects for rebuild
848 //=======================================================================
849 void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce)
851 mySelectableObjects.MarkDirty();
852 mySelectableObjectsTrsfPers.MarkDirty();
856 const Graphic3d_Mat4d& aProjection = mySelectingVolumeMgr.ProjectionMatrix();
857 const Graphic3d_Mat4d& aWorldView = mySelectingVolumeMgr.WorldViewMatrix();
858 const Graphic3d_WorldViewProjState& aWVPState = mySelectingVolumeMgr.WorldViewProjState();
859 Standard_Integer aViewportWidth;
860 Standard_Integer aViewportHeight;
861 mySelectingVolumeMgr.WindowSize (aViewportWidth, aViewportHeight);
863 mySelectableObjects.BVH();
864 mySelectableObjectsTrsfPers.BVH (aProjection, aWorldView, aViewportWidth, aViewportHeight, aWVPState);
868 //=======================================================================
869 // function : RebuildSensitivesTree
870 // purpose : Marks BVH of sensitive entities of particular selectable
871 // object for rebuild
872 //=======================================================================
873 void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject,
874 const Standard_Boolean theIsForce)
876 if (!Contains (theObject))
879 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
880 anEntitySet->MarkDirty();
888 //=======================================================================
889 // function : resetSelectionActivationStatus
890 // purpose : Marks all added sensitive entities of all objects as
892 //=======================================================================
893 void SelectMgr_ViewerSelector::ResetSelectionActivationStatus()
895 SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives);
896 for ( ; aSensitivesIter.More(); aSensitivesIter.Next())
898 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
899 aSensitivesIter.ChangeValue();
900 Standard_Integer anEntitiesNb = anEntitySet->Size();
901 for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
903 anEntitySet->GetSensitiveById (anIdx)->ResetSelectionActiveStatus();
908 //=======================================================================
909 // function : DetectedEntity
910 // purpose : Returns sensitive entity that was detected during the
911 // previous run of selection algorithm
912 //=======================================================================
913 const Handle(SelectBasics_SensitiveEntity)& SelectMgr_ViewerSelector::DetectedEntity() const
915 const Handle(SelectMgr_EntityOwner)& anOwner = myDetectedIter.Key();
916 const Handle(SelectMgr_SelectableObject)& anObject = anOwner->Selectable();
917 const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
918 myMapOfObjectSensitives.Find (anObject);
920 return anEntitySet->GetSensitiveById (myDetectedIter.Value())->BaseSensitive();
923 //=======================================================================
924 // function : ActiveOwners
925 // purpose : Returns the list of active entity owners
926 //=======================================================================
927 void SelectMgr_ViewerSelector::ActiveOwners (NCollection_List<Handle(SelectBasics_EntityOwner)>& theOwners) const
929 for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next())
931 const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = anIter.Value();
932 Standard_Integer anEntitiesNb = anEntitySet->Size();
933 for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
935 if (anEntitySet->GetSensitiveById (anIdx)->IsActiveForSelection())
937 theOwners.Append (anEntitySet->GetSensitiveById (anIdx)->BaseSensitive()->OwnerId());
943 //=======================================================================
944 //function : AllowOverlapDetection
945 //purpose : Sets the detection type: if theIsToAllow is false,
946 // only fully included sensitives will be detected, otherwise
947 // the algorithm will mark both included and overlapped entities
949 //=======================================================================
950 void SelectMgr_ViewerSelector::AllowOverlapDetection (const Standard_Boolean theIsToAllow)
952 mySelectingVolumeMgr.AllowOverlapDetection (theIsToAllow);