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.
17 #include <SelectMgr_ViewerSelector.hxx>
19 #include <BVH_Tree.hxx>
20 #include <gp_GTrsf.hxx>
22 #include <OSD_Environment.hxx>
23 #include <Precision.hxx>
24 #include <SelectBasics_EntityOwner.hxx>
25 #include <SelectBasics_SensitiveEntity.hxx>
26 #include <SelectBasics_PickResult.hxx>
27 #include <SelectMgr_EntityOwner.hxx>
28 #include <SelectMgr_SortCriterion.hxx>
29 #include <SelectMgr_SensitiveEntitySet.hxx>
30 #include <TColStd_Array1OfInteger.hxx>
31 #include <TCollection_AsciiString.hxx>
32 #include <TColStd_HArray1OfInteger.hxx>
33 #include <TColStd_ListOfInteger.hxx>
37 IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_ViewerSelector,MMgt_TShared)
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;
62 //! Compute 3d position for detected entity.
63 inline void updatePoint3d (SelectMgr_SortCriterion& theCriterion,
64 const gp_GTrsf& theInversedTrsf,
65 SelectMgr_SelectingVolumeManager& theMgr)
67 if (theMgr.GetActiveSelectionType() != SelectMgr_SelectingVolumeManager::Point)
72 theCriterion.Point = theMgr.DetectedPoint (theCriterion.Depth);
73 gp_GTrsf anInvTrsf = theInversedTrsf;
74 if (theCriterion.Entity->HasInitLocation())
76 anInvTrsf = theCriterion.Entity->InvInitLocation() * anInvTrsf;
78 if (anInvTrsf.Form() != gp_Identity)
80 anInvTrsf.Inverted().Transforms (theCriterion.Point.ChangeCoord());
84 static const Graphic3d_Mat4d THE_IDENTITY_MAT;
87 //==================================================
88 // Function: Initialize
90 //==================================================
91 SelectMgr_ViewerSelector::SelectMgr_ViewerSelector():
92 preferclosest(Standard_True),
93 myToUpdateTolerance (Standard_True),
95 myIsLeftChildQueuedFirst (Standard_False),
100 //==================================================
101 // Function: Activate
103 //==================================================
104 void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSelection)
106 for (theSelection->Init(); theSelection->More(); theSelection->Next())
108 theSelection->Sensitive()->SetActiveForSelection();
111 theSelection->SetSelectionState (SelectMgr_SOS_Activated);
113 myTolerances.Add (theSelection->Sensitivity());
114 myToUpdateTolerance = Standard_True;
117 //==================================================
118 // Function: Deactivate
120 //==================================================
121 void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theSelection)
123 for (theSelection->Init(); theSelection->More(); theSelection->Next())
125 theSelection->Sensitive()->ResetSelectionActiveStatus();
128 theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
130 myTolerances.Decrement (theSelection->Sensitivity());
131 myToUpdateTolerance = Standard_True;
134 //==================================================
137 //==================================================
138 void SelectMgr_ViewerSelector::Clear()
143 //=======================================================================
144 // function: isToScaleFrustum
145 // purpose : Checks if the entity given requires to scale current selecting frustum
146 //=======================================================================
147 Standard_Boolean SelectMgr_ViewerSelector::isToScaleFrustum (const Handle(SelectBasics_SensitiveEntity)& theEntity)
149 return mySelectingVolumeMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point
150 && sensitivity (theEntity) < myTolerances.Tolerance();
153 //=======================================================================
154 // function: sensitivity
155 // purpose : In case if custom tolerance is set, this method will return sum of entity
156 // sensitivity and custom tolerance.
157 //=======================================================================
158 Standard_Integer SelectMgr_ViewerSelector::sensitivity (const Handle(SelectBasics_SensitiveEntity)& theEntity) const
160 return myTolerances.IsCustomTolSet() ?
161 theEntity->SensitivityFactor() + myTolerances.CustomTolerance() : theEntity->SensitivityFactor();
164 //=======================================================================
165 // function: checkOverlap
166 // purpose : Internal function that checks if a particular sensitive
167 // entity theEntity overlaps current selecting volume precisely
168 //=======================================================================
169 void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_SensitiveEntity)& theEntity,
170 const gp_GTrsf& theInversedTrsf,
171 SelectMgr_SelectingVolumeManager& theMgr)
173 Handle(SelectMgr_EntityOwner) anOwner (Handle(SelectMgr_EntityOwner)::DownCast (theEntity->OwnerId()));
174 Handle(SelectMgr_SelectableObject) aSelectable;
175 Standard_Boolean toRestoresViewClipEnabled = Standard_False;
176 if (!anOwner.IsNull())
178 aSelectable = anOwner->Selectable();
179 if ((!aSelectable->TransformPersistence().IsNull() && aSelectable->TransformPersistence()->IsTrihedronOr2d())
180 || (!aSelectable->ClipPlanes().IsNull() && aSelectable->ClipPlanes()->ToOverrideGlobal()))
182 theMgr.SetViewClippingEnabled (Standard_False);
183 toRestoresViewClipEnabled = Standard_True;
187 SelectBasics_PickResult aPickResult;
188 const Standard_Boolean isMatched = theEntity->Matches(theMgr, aPickResult);
189 if (toRestoresViewClipEnabled)
191 theMgr.SetViewClippingEnabled (Standard_True);
200 if (HasDepthClipping (anOwner)
201 && theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point)
203 Standard_Boolean isClipped = mySelectingVolumeMgr.IsClipped (*aSelectable->ClipPlanes(),
204 aPickResult.Depth());
209 SelectMgr_SortCriterion aCriterion;
210 myZLayerOrderMap.Find (aSelectable->ZLayer(), aCriterion.ZLayerPosition);
211 aCriterion.Entity = theEntity;
212 aCriterion.Priority = anOwner->Priority();
213 aCriterion.Depth = aPickResult.Depth();
214 aCriterion.MinDist = aPickResult.DistToGeomCenter();
215 aCriterion.Tolerance = theEntity->SensitivityFactor() / 33.0;
216 aCriterion.ToPreferClosest = preferclosest;
218 const Standard_Integer aPrevStoredIndex = mystored.FindIndex (anOwner);
219 if (aPrevStoredIndex != 0)
221 if (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Box)
223 SelectMgr_SortCriterion& aPrevCriterion = mystored.ChangeFromIndex (aPrevStoredIndex);
224 if (aCriterion > aPrevCriterion)
226 updatePoint3d (aCriterion, theInversedTrsf, theMgr);
227 aPrevCriterion = aCriterion;
233 updatePoint3d (aCriterion, theInversedTrsf, theMgr);
234 mystored.Add (anOwner, aCriterion);
238 //=======================================================================
239 // function: computeFrustum
240 // purpose : Internal function that checks if a current selecting frustum
241 // needs to be scaled and transformed for the entity and performs
242 // necessary calculations
243 //=======================================================================
244 void SelectMgr_ViewerSelector::computeFrustum (const Handle(SelectBasics_SensitiveEntity)& theEnt,
245 const SelectMgr_SelectingVolumeManager& theMgr,
246 const gp_GTrsf& theInvTrsf,
247 SelectMgr_FrustumCache& theCachedMgrs,
248 SelectMgr_SelectingVolumeManager& theResMgr)
250 Standard_Integer aScale = isToScaleFrustum (theEnt) ? sensitivity (theEnt) : 1;
251 const gp_GTrsf aTrsfMtr = theEnt->HasInitLocation() ? theEnt->InvInitLocation() * theInvTrsf : theInvTrsf;
252 const Standard_Boolean toScale = aScale != 1;
253 const Standard_Boolean toTransform = aTrsfMtr.Form() != gp_Identity;
254 if (toScale && toTransform)
256 theResMgr = theMgr.ScaleAndTransform (aScale, aTrsfMtr, NULL);
260 if (!theCachedMgrs.IsBound (aScale))
262 theCachedMgrs.Bind (aScale, theMgr.ScaleAndTransform (aScale, gp_Trsf(), NULL));
264 theResMgr = theCachedMgrs.Find (aScale);
266 else if (toTransform)
268 theResMgr = theMgr.ScaleAndTransform (1, aTrsfMtr, NULL);
272 //=======================================================================
273 // function: traverseObject
274 // purpose : Internal function that checks if there is possible overlap
275 // between some entity of selectable object theObject and
276 // current selecting volume
277 //=======================================================================
278 void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_SelectableObject)& theObject,
279 const SelectMgr_SelectingVolumeManager& theMgr,
280 const Handle(Graphic3d_Camera)& theCamera,
281 const Graphic3d_Mat4d& theProjectionMat,
282 const Graphic3d_Mat4d& theWorldViewMat,
283 const Standard_Integer theViewportWidth,
284 const Standard_Integer theViewportHeight)
286 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
287 myMapOfObjectSensitives.ChangeFind (theObject);
289 if (anEntitySet->Size() == 0)
292 const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
294 gp_GTrsf aInversedTrsf;
296 if (theObject->HasTransformation() || !theObject->TransformPersistence().IsNull())
298 if (theObject->TransformPersistence().IsNull())
300 aInversedTrsf = theObject->InversedTransformation();
305 Graphic3d_Mat4d aMat = theObject->TransformPersistence()->Compute (theCamera, theProjectionMat, theWorldViewMat, theViewportWidth, theViewportHeight);
307 aTPers.SetValue (1, 1, aMat.GetValue (0, 0));
308 aTPers.SetValue (1, 2, aMat.GetValue (0, 1));
309 aTPers.SetValue (1, 3, aMat.GetValue (0, 2));
310 aTPers.SetValue (2, 1, aMat.GetValue (1, 0));
311 aTPers.SetValue (2, 2, aMat.GetValue (1, 1));
312 aTPers.SetValue (2, 3, aMat.GetValue (1, 2));
313 aTPers.SetValue (3, 1, aMat.GetValue (2, 0));
314 aTPers.SetValue (3, 2, aMat.GetValue (2, 1));
315 aTPers.SetValue (3, 3, aMat.GetValue (2, 2));
316 aTPers.SetTranslationPart (gp_XYZ (aMat.GetValue (0, 3), aMat.GetValue (1, 3), aMat.GetValue (2, 3)));
318 aInversedTrsf = (aTPers * gp_GTrsf (theObject->Transformation())).Inverted();
322 SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity
323 ? theMgr.ScaleAndTransform (1, aInversedTrsf, NULL)
326 SelectMgr_FrustumCache aScaledTrnsfFrustums;
328 Standard_Integer aNode = 0; // a root node
329 if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
330 aSensitivesTree->MaxPoint (0)))
334 Standard_Integer aStack[32];
335 Standard_Integer aHead = -1;
338 if (!aSensitivesTree->IsOuter (aNode))
340 const Standard_Integer aLeftChildIdx = aSensitivesTree->Child<0> (aNode);
341 const Standard_Integer aRightChildIdx = aSensitivesTree->Child<1> (aNode);
342 const Standard_Boolean isLeftChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aLeftChildIdx),
343 aSensitivesTree->MaxPoint (aLeftChildIdx));
344 const Standard_Boolean isRightChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aRightChildIdx),
345 aSensitivesTree->MaxPoint (aRightChildIdx));
349 aNode = aLeftChildIdx;
351 aStack[aHead] = aRightChildIdx;
353 else if (isLeftChildIn
356 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
365 aNode = aStack[aHead];
371 Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode);
372 Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode);
373 for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
375 const Handle(SelectMgr_SensitiveEntity)& aSensitive =
376 anEntitySet->GetSensitiveById (anIdx);
377 if (aSensitive->IsActiveForSelection())
379 const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
380 SelectMgr_SelectingVolumeManager aTmpMgr = aMgr;
381 computeFrustum (anEnt, theMgr, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
382 checkOverlap (anEnt, aInversedTrsf, aTmpMgr);
390 aNode = aStack[aHead];
396 //=======================================================================
397 // function: TraverseSensitives
398 // purpose : Traverses BVH containing all added selectable objects and
399 // finds candidates for further search of overlap
400 //=======================================================================
401 void SelectMgr_ViewerSelector::TraverseSensitives()
405 Standard_Integer aWidth;
406 Standard_Integer aHeight;
407 mySelectingVolumeMgr.WindowSize (aWidth, aHeight);
408 mySelectableObjects.UpdateBVH (mySelectingVolumeMgr.Camera(),
409 mySelectingVolumeMgr.ProjectionMatrix(),
410 mySelectingVolumeMgr.WorldViewMatrix(),
411 mySelectingVolumeMgr.WorldViewProjState(),
414 for (Standard_Integer aBVHSetIt = 0; aBVHSetIt < SelectMgr_SelectableObjectSet::BVHSubsetNb; ++aBVHSetIt)
416 SelectMgr_SelectableObjectSet::BVHSubset aBVHSubset =
417 static_cast<SelectMgr_SelectableObjectSet::BVHSubset> (aBVHSetIt);
419 if (mySelectableObjects.IsEmpty (aBVHSubset))
426 SelectMgr_SelectingVolumeManager aMgr (Standard_False);
428 // for 2D space selection transform selecting volumes to perform overap testing
429 // directly in camera's eye space omitting the camera position, which is not
430 // needed there at all
431 if (aBVHSubset == SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent)
433 const Graphic3d_Mat4d& aMat = mySelectingVolumeMgr.WorldViewMatrix();
434 aTFrustum.SetValue (1, 1, aMat.GetValue (0, 0));
435 aTFrustum.SetValue (1, 2, aMat.GetValue (0, 1));
436 aTFrustum.SetValue (1, 3, aMat.GetValue (0, 2));
437 aTFrustum.SetValue (2, 1, aMat.GetValue (1, 0));
438 aTFrustum.SetValue (2, 2, aMat.GetValue (1, 1));
439 aTFrustum.SetValue (2, 3, aMat.GetValue (1, 2));
440 aTFrustum.SetValue (3, 1, aMat.GetValue (2, 0));
441 aTFrustum.SetValue (3, 2, aMat.GetValue (2, 1));
442 aTFrustum.SetValue (3, 3, aMat.GetValue (2, 2));
443 aTFrustum.SetTranslationPart (gp_XYZ (aMat.GetValue (0, 3), aMat.GetValue (1, 3), aMat.GetValue (2, 3)));
445 // define corresponding frustum builder parameters
446 Handle(SelectMgr_FrustumBuilder) aBuilder = new SelectMgr_FrustumBuilder();
447 aBuilder->SetProjectionMatrix (mySelectingVolumeMgr.ProjectionMatrix());
448 aBuilder->SetWorldViewMatrix (THE_IDENTITY_MAT);
449 aBuilder->SetWindowSize (aWidth, aHeight);
450 aMgr = mySelectingVolumeMgr.ScaleAndTransform (1, aTFrustum, aBuilder);
454 aMgr = mySelectingVolumeMgr;
457 const Handle(Graphic3d_Camera)& aCamera = mySelectingVolumeMgr.Camera();
458 const Graphic3d_Mat4d& aProjectionMat = mySelectingVolumeMgr.ProjectionMatrix();
459 const Graphic3d_Mat4d& aWorldViewMat = aBVHSubset != SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent
460 ? mySelectingVolumeMgr.WorldViewMatrix()
463 const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aBVHTree = mySelectableObjects.BVH (aBVHSubset);
465 Standard_Integer aNode = 0;
466 if (!aMgr.Overlaps (aBVHTree->MinPoint (0), aBVHTree->MaxPoint (0)))
471 Standard_Integer aStack[32];
472 Standard_Integer aHead = -1;
475 if (!aBVHTree->IsOuter (aNode))
477 const Standard_Integer aLeftChildIdx = aBVHTree->Child<0> (aNode);
478 const Standard_Integer aRightChildIdx = aBVHTree->Child<1> (aNode);
479 const Standard_Boolean isLeftChildIn =
480 aMgr.Overlaps (aBVHTree->MinPoint (aLeftChildIdx), aBVHTree->MaxPoint (aLeftChildIdx));
481 const Standard_Boolean isRightChildIn =
482 aMgr.Overlaps (aBVHTree->MinPoint (aRightChildIdx), aBVHTree->MaxPoint (aRightChildIdx));
486 aNode = aLeftChildIdx;
488 aStack[aHead] = aRightChildIdx;
490 else if (isLeftChildIn
493 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
502 aNode = aStack[aHead];
508 Standard_Integer aStartIdx = aBVHTree->BegPrimitive (aNode);
509 Standard_Integer anEndIdx = aBVHTree->EndPrimitive (aNode);
510 for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
512 const Handle(SelectMgr_SelectableObject)& aSelectableObject =
513 mySelectableObjects.GetObjectById (aBVHSubset, anIdx);
515 traverseObject (aSelectableObject, aMgr, aCamera, aProjectionMat, aWorldViewMat, aWidth, aHeight);
522 aNode = aStack[aHead];
531 //==================================================
534 //==================================================
535 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector
538 Standard_Integer RankInMap = myIndexes->Value (myCurRank);
539 const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap);
540 Handle(SelectMgr_EntityOwner) Ownr = Handle(SelectMgr_EntityOwner)::DownCast (toto);
544 //=======================================================================
547 //=======================================================================
548 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked (const Standard_Integer theRank) const
550 Handle(SelectMgr_EntityOwner) anOwner;
551 if (theRank < 1 || theRank > NbPicked())
556 const Standard_Integer anOwnerIdx = myIndexes->Value (theRank);
557 const Handle(SelectBasics_EntityOwner)& aStoredOwner = mystored.FindKey (anOwnerIdx);
558 anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aStoredOwner);
562 //=======================================================================
563 //function : PickedData
565 //=======================================================================
566 const SelectMgr_SortCriterion& SelectMgr_ViewerSelector::PickedData(const Standard_Integer theRank) const
568 Standard_OutOfRange_Raise_if (theRank < 1 || theRank > NbPicked(), "SelectMgr_ViewerSelector::PickedData() out of range index");
569 const Standard_Integer anOwnerIdx = myIndexes->Value (theRank);
570 return mystored.FindFromIndex (anOwnerIdx);
573 //===================================================
575 // INTERNAL METHODS ....
577 //==================================================
579 //==================================================
580 // Function: Contains
582 //==================================================
583 Standard_Boolean SelectMgr_ViewerSelector::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
585 return mySelectableObjects.Contains (theObject);
588 //==================================================
589 // Function: ActiveModes
590 // Purpose : return all the modes with a given state for an object
591 //==================================================
592 Standard_Boolean SelectMgr_ViewerSelector::Modes (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
593 TColStd_ListOfInteger& theModeList,
594 const SelectMgr_StateOfSelection theWantedState) const
596 Standard_Boolean hasActivatedStates = Contains (theSelectableObject);
597 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
599 if (theWantedState == SelectMgr_SOS_Any)
601 theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
603 else if (theWantedState == theSelectableObject->CurrentSelection()->GetSelectionState())
605 theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
609 return hasActivatedStates;
612 //==================================================
613 // Function: IsActive
615 //==================================================
616 Standard_Boolean SelectMgr_ViewerSelector::IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
617 const Standard_Integer theMode) const
619 if (!Contains (theSelectableObject))
620 return Standard_False;
622 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
624 if (theMode == theSelectableObject->CurrentSelection()->Mode())
626 return theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated;
630 return Standard_False;
633 //==================================================
634 // Function: IsInside
636 //==================================================
637 Standard_Boolean SelectMgr_ViewerSelector::IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
638 const Standard_Integer theMode) const
640 if (!Contains (theSelectableObject))
641 return Standard_False;
643 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
645 if (theMode == theSelectableObject->CurrentSelection()->Mode())
647 return theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown;
651 return Standard_False;
655 //=======================================================================
658 //=======================================================================
660 SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_Selection)& theSelection) const
662 return theSelection->GetSelectionState();
665 //==================================================
667 // Purpose : gives Information about selectors
668 //==================================================
670 TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const
672 TCollection_AsciiString aStatus ("Status Object :\n\t");
674 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
676 if (theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown)
678 aStatus = aStatus + "Mode " +
679 TCollection_AsciiString (theSelectableObject->CurrentSelection()->Mode()) +
681 if (theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated)
683 aStatus = aStatus + " Active \n\t";
687 aStatus = aStatus + " Inactive \n\t";
692 if (!Contains (theSelectableObject))
694 aStatus = aStatus + "Not Present in the selector\n\n";
700 //=======================================================================
701 //function : SortResult
702 //purpose : there is a certain number of entities ranged by criteria
703 // (depth, size, priority, mouse distance from borders or
704 // CDG of the detected primitive. Parsing :
705 // maximum priorities .
706 // then a reasonable compromise between depth and distance...
707 // finally the ranges are stored in myindexes depending on the parsing.
708 // so, it is possible to only read
709 //=======================================================================
710 void SelectMgr_ViewerSelector::SortResult()
712 if(mystored.IsEmpty()) return;
714 const Standard_Integer anExtent = mystored.Extent();
715 if(myIndexes.IsNull() || anExtent != myIndexes->Length())
716 myIndexes = new TColStd_HArray1OfInteger (1, anExtent);
719 TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1();
721 // indices from 1 to N are loaded
723 for (I=1; I <= anExtent; I++)
726 std::sort (thearr.begin(), thearr.end(), CompareResults (mystored));
730 //=======================================================================
731 //function : HasDepthClipping
733 //=======================================================================
734 Standard_Boolean SelectMgr_ViewerSelector::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& /*theOwner*/) const
736 return Standard_False;
739 //=======================================================================
740 // function : AddSelectableObject
741 // purpose : Adds new object to the map of selectable objects
742 //=======================================================================
743 void SelectMgr_ViewerSelector::AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
745 if (!myMapOfObjectSensitives.IsBound (theObject))
747 mySelectableObjects.Append (theObject);
748 NCollection_Handle<SelectMgr_SensitiveEntitySet> anEntitySet = new SelectMgr_SensitiveEntitySet();
749 myMapOfObjectSensitives.Bind (theObject, anEntitySet);
753 //=======================================================================
754 // function : AddSelectionToObject
755 // purpose : Adds new selection to the object and builds its BVH tree
756 //=======================================================================
757 void SelectMgr_ViewerSelector::AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject,
758 const Handle(SelectMgr_Selection)& theSelection)
760 if (myMapOfObjectSensitives.IsBound (theObject))
762 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
763 myMapOfObjectSensitives.ChangeFind (theObject);
764 anEntitySet->Append (theSelection);
769 AddSelectableObject (theObject);
770 AddSelectionToObject (theObject, theSelection);
774 //=======================================================================
775 // function : MoveSelectableObject
777 //=======================================================================
778 void SelectMgr_ViewerSelector::MoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
780 mySelectableObjects.ChangeSubset (theObject);
783 //=======================================================================
784 // function : RemoveSelectableObject
785 // purpose : Removes selectable object from map of selectable ones
786 //=======================================================================
787 void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
789 if (myMapOfObjectSensitives.IsBound (theObject))
791 mySelectableObjects.Remove (theObject);
792 myMapOfObjectSensitives.UnBind (theObject);
796 //=======================================================================
797 // function : RemoveSelectionOfObject
798 // purpose : Removes selection of the object and marks its BVH tree
800 //=======================================================================
801 void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject,
802 const Handle(SelectMgr_Selection)& theSelection)
804 if (myMapOfObjectSensitives.IsBound (theObject))
806 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
807 myMapOfObjectSensitives.ChangeFind (theObject);
808 anEntitySet->Remove (theSelection);
812 //=======================================================================
813 // function : RebuildObjectsTree
814 // purpose : Marks BVH of selectable objects for rebuild
815 //=======================================================================
816 void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce)
818 mySelectableObjects.MarkDirty();
822 Standard_Integer aViewportWidth, aViewportHeight;
823 mySelectingVolumeMgr.WindowSize (aViewportWidth, aViewportHeight);
825 Standard_Integer aWidth;
826 Standard_Integer aHeight;
827 mySelectingVolumeMgr.WindowSize (aWidth, aHeight);
828 mySelectableObjects.UpdateBVH (mySelectingVolumeMgr.Camera(),
829 mySelectingVolumeMgr.ProjectionMatrix(),
830 mySelectingVolumeMgr.WorldViewMatrix(),
831 mySelectingVolumeMgr.WorldViewProjState(),
836 //=======================================================================
837 // function : RebuildSensitivesTree
838 // purpose : Marks BVH of sensitive entities of particular selectable
839 // object for rebuild
840 //=======================================================================
841 void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject,
842 const Standard_Boolean theIsForce)
844 if (!Contains (theObject))
847 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
848 anEntitySet->MarkDirty();
856 //=======================================================================
857 // function : resetSelectionActivationStatus
858 // purpose : Marks all added sensitive entities of all objects as
860 //=======================================================================
861 void SelectMgr_ViewerSelector::ResetSelectionActivationStatus()
863 SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives);
864 for ( ; aSensitivesIter.More(); aSensitivesIter.Next())
866 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
867 aSensitivesIter.ChangeValue();
868 Standard_Integer anEntitiesNb = anEntitySet->Size();
869 for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
871 anEntitySet->GetSensitiveById (anIdx)->ResetSelectionActiveStatus();
876 //=======================================================================
877 // function : DetectedEntity
878 // purpose : Returns sensitive entity that was detected during the
879 // previous run of selection algorithm
880 //=======================================================================
881 const Handle(SelectBasics_SensitiveEntity)& SelectMgr_ViewerSelector::DetectedEntity() const
883 const Standard_Integer aRankInMap = myIndexes->Value(myCurRank);
884 return mystored.FindFromIndex (aRankInMap).Entity;
887 //=======================================================================
888 // function : ActiveOwners
889 // purpose : Returns the list of active entity owners
890 //=======================================================================
891 void SelectMgr_ViewerSelector::ActiveOwners (NCollection_List<Handle(SelectBasics_EntityOwner)>& theOwners) const
893 for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next())
895 const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = anIter.Value();
896 Standard_Integer anEntitiesNb = anEntitySet->Size();
897 for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
899 if (anEntitySet->GetSensitiveById (anIdx)->IsActiveForSelection())
901 theOwners.Append (anEntitySet->GetSensitiveById (anIdx)->BaseSensitive()->OwnerId());
907 //=======================================================================
908 //function : AllowOverlapDetection
909 //purpose : Sets the detection type: if theIsToAllow is false,
910 // only fully included sensitives will be detected, otherwise
911 // the algorithm will mark both included and overlapped entities
913 //=======================================================================
914 void SelectMgr_ViewerSelector::AllowOverlapDetection (const Standard_Boolean theIsToAllow)
916 mySelectingVolumeMgr.AllowOverlapDetection (theIsToAllow);