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 theCriterion.Point = theMgr.DetectedPoint (theCriterion.Depth);
68 gp_GTrsf anInvTrsf = theInversedTrsf;
69 if (theCriterion.Entity->HasInitLocation())
71 anInvTrsf = theCriterion.Entity->InvInitLocation() * anInvTrsf;
73 if (anInvTrsf.Form() != gp_Identity)
75 anInvTrsf.Inverted().Transforms (theCriterion.Point.ChangeCoord());
79 static const Graphic3d_Mat4d THE_IDENTITY_MAT;
82 //==================================================
83 // Function: Initialize
85 //==================================================
86 SelectMgr_ViewerSelector::SelectMgr_ViewerSelector():
87 preferclosest(Standard_True),
88 myToUpdateTolerance (Standard_True),
90 myIsLeftChildQueuedFirst (Standard_False),
95 //==================================================
98 //==================================================
99 void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSelection)
101 for (theSelection->Init(); theSelection->More(); theSelection->Next())
103 theSelection->Sensitive()->SetActiveForSelection();
106 theSelection->SetSelectionState (SelectMgr_SOS_Activated);
108 myTolerances.Add (theSelection->Sensitivity());
109 myToUpdateTolerance = Standard_True;
112 //==================================================
113 // Function: Deactivate
115 //==================================================
116 void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theSelection)
118 for (theSelection->Init(); theSelection->More(); theSelection->Next())
120 theSelection->Sensitive()->ResetSelectionActiveStatus();
123 theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
125 myTolerances.Decrement (theSelection->Sensitivity());
126 myToUpdateTolerance = Standard_True;
129 //==================================================
132 //==================================================
133 void SelectMgr_ViewerSelector::Clear()
138 //=======================================================================
139 // function: isToScaleFrustum
140 // purpose : Checks if the entity given requires to scale current selecting frustum
141 //=======================================================================
142 Standard_Boolean SelectMgr_ViewerSelector::isToScaleFrustum (const Handle(SelectBasics_SensitiveEntity)& theEntity)
144 return mySelectingVolumeMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point
145 && sensitivity (theEntity) < myTolerances.Tolerance();
148 //=======================================================================
149 // function: sensitivity
150 // purpose : In case if custom tolerance is set, this method will return sum of entity
151 // sensitivity and custom tolerance.
152 //=======================================================================
153 Standard_Integer SelectMgr_ViewerSelector::sensitivity (const Handle(SelectBasics_SensitiveEntity)& theEntity) const
155 return myTolerances.IsCustomTolSet() ?
156 theEntity->SensitivityFactor() + myTolerances.CustomTolerance() : theEntity->SensitivityFactor();
159 //=======================================================================
160 // function: checkOverlap
161 // purpose : Internal function that checks if a particular sensitive
162 // entity theEntity overlaps current selecting volume precisely
163 //=======================================================================
164 void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_SensitiveEntity)& theEntity,
165 const gp_GTrsf& theInversedTrsf,
166 SelectMgr_SelectingVolumeManager& theMgr)
168 Handle(SelectMgr_EntityOwner) anOwner (Handle(SelectMgr_EntityOwner)::DownCast (theEntity->OwnerId()));
169 Handle(SelectMgr_SelectableObject) aSelectable;
170 Standard_Boolean toRestoresViewClipEnabled = Standard_False;
171 if (!anOwner.IsNull())
173 aSelectable = anOwner->Selectable();
174 if (aSelectable->TransformPersistence().Flags == Graphic3d_TMF_TriedronPers
175 || aSelectable->TransformPersistence().Flags == Graphic3d_TMF_2d
176 || (!aSelectable->ClipPlanes().IsNull() && aSelectable->ClipPlanes()->ToOverrideGlobal()))
178 theMgr.SetViewClippingEnabled (Standard_False);
179 toRestoresViewClipEnabled = Standard_True;
183 SelectBasics_PickResult aPickResult;
184 const Standard_Boolean isMatched = theEntity->Matches(theMgr, aPickResult);
185 if (toRestoresViewClipEnabled)
187 theMgr.SetViewClippingEnabled (Standard_True);
196 if (HasDepthClipping (anOwner)
197 && theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point)
199 Standard_Boolean isClipped = mySelectingVolumeMgr.IsClipped (*aSelectable->ClipPlanes(),
200 aPickResult.Depth());
205 SelectMgr_SortCriterion aCriterion;
206 myZLayerOrderMap.Find (aSelectable->ZLayer(), aCriterion.ZLayerPosition);
207 aCriterion.Entity = theEntity;
208 aCriterion.Priority = anOwner->Priority();
209 aCriterion.Depth = aPickResult.Depth();
210 aCriterion.MinDist = aPickResult.DistToGeomCenter();
211 aCriterion.Tolerance = theEntity->SensitivityFactor() / 33.0;
212 aCriterion.ToPreferClosest = preferclosest;
214 const Standard_Integer aPrevStoredIndex = mystored.FindIndex (anOwner);
215 if (aPrevStoredIndex != 0)
217 if (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Box)
219 SelectMgr_SortCriterion& aPrevCriterion = mystored.ChangeFromIndex (aPrevStoredIndex);
220 if (aCriterion > aPrevCriterion)
222 updatePoint3d (aCriterion, theInversedTrsf, theMgr);
223 aPrevCriterion = aCriterion;
229 updatePoint3d (aCriterion, theInversedTrsf, theMgr);
230 mystored.Add (anOwner, aCriterion);
234 //=======================================================================
235 // function: computeFrustum
236 // purpose : Internal function that checks if a current selecting frustum
237 // needs to be scaled and transformed for the entity and performs
238 // necessary calculations
239 //=======================================================================
240 void SelectMgr_ViewerSelector::computeFrustum (const Handle(SelectBasics_SensitiveEntity)& theEnt,
241 const SelectMgr_SelectingVolumeManager& theMgr,
242 const gp_GTrsf& theInvTrsf,
243 SelectMgr_FrustumCache& theCachedMgrs,
244 SelectMgr_SelectingVolumeManager& theResMgr)
246 Standard_Integer aScale = isToScaleFrustum (theEnt) ? sensitivity (theEnt) : 1;
247 const gp_GTrsf aTrsfMtr = theEnt->HasInitLocation() ? theEnt->InvInitLocation() * theInvTrsf : theInvTrsf;
248 const Standard_Boolean toScale = aScale != 1;
249 const Standard_Boolean toTransform = aTrsfMtr.Form() != gp_Identity;
250 if (toScale && toTransform)
252 theResMgr = theMgr.ScaleAndTransform (aScale, aTrsfMtr, NULL);
256 if (!theCachedMgrs.IsBound (aScale))
258 theCachedMgrs.Bind (aScale, theMgr.ScaleAndTransform (aScale, gp_Trsf(), NULL));
260 theResMgr = theCachedMgrs.Find (aScale);
262 else if (toTransform)
264 theResMgr = theMgr.ScaleAndTransform (1, aTrsfMtr, NULL);
268 //=======================================================================
269 // function: traverseObject
270 // purpose : Internal function that checks if there is possible overlap
271 // between some entity of selectable object theObject and
272 // current selecting volume
273 //=======================================================================
274 void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_SelectableObject)& theObject,
275 const SelectMgr_SelectingVolumeManager& theMgr,
276 const Handle(Graphic3d_Camera)& theCamera,
277 const Graphic3d_Mat4d& theProjectionMat,
278 const Graphic3d_Mat4d& theWorldViewMat,
279 const Standard_Integer theViewportWidth,
280 const Standard_Integer theViewportHeight)
282 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
283 myMapOfObjectSensitives.ChangeFind (theObject);
285 if (anEntitySet->Size() == 0)
288 const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
290 gp_GTrsf aInversedTrsf;
292 if (theObject->HasTransformation() || theObject->TransformPersistence().Flags)
294 if (!theObject->TransformPersistence().Flags)
296 aInversedTrsf = theObject->InversedTransformation();
301 Graphic3d_Mat4d aMat = theObject->TransformPersistence().Compute (
302 theCamera, theProjectionMat, theWorldViewMat, theViewportWidth, theViewportHeight);
304 aTPers.SetValue (1, 1, aMat.GetValue (0, 0));
305 aTPers.SetValue (1, 2, aMat.GetValue (0, 1));
306 aTPers.SetValue (1, 3, aMat.GetValue (0, 2));
307 aTPers.SetValue (2, 1, aMat.GetValue (1, 0));
308 aTPers.SetValue (2, 2, aMat.GetValue (1, 1));
309 aTPers.SetValue (2, 3, aMat.GetValue (1, 2));
310 aTPers.SetValue (3, 1, aMat.GetValue (2, 0));
311 aTPers.SetValue (3, 2, aMat.GetValue (2, 1));
312 aTPers.SetValue (3, 3, aMat.GetValue (2, 2));
313 aTPers.SetTranslationPart (gp_XYZ (aMat.GetValue (0, 3), aMat.GetValue (1, 3), aMat.GetValue (2, 3)));
315 aInversedTrsf = (aTPers * gp_GTrsf (theObject->Transformation())).Inverted();
319 SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity
320 ? theMgr.ScaleAndTransform (1, aInversedTrsf, NULL)
323 SelectMgr_FrustumCache aScaledTrnsfFrustums;
325 Standard_Integer aNode = 0; // a root node
326 if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
327 aSensitivesTree->MaxPoint (0)))
331 Standard_Integer aStack[32];
332 Standard_Integer aHead = -1;
335 if (!aSensitivesTree->IsOuter (aNode))
337 const Standard_Integer aLeftChildIdx = aSensitivesTree->Child<0> (aNode);
338 const Standard_Integer aRightChildIdx = aSensitivesTree->Child<1> (aNode);
339 const Standard_Boolean isLeftChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aLeftChildIdx),
340 aSensitivesTree->MaxPoint (aLeftChildIdx));
341 const Standard_Boolean isRightChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aRightChildIdx),
342 aSensitivesTree->MaxPoint (aRightChildIdx));
346 aNode = aLeftChildIdx;
348 aStack[aHead] = aRightChildIdx;
350 else if (isLeftChildIn
353 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
362 aNode = aStack[aHead];
368 Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode);
369 Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode);
370 for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
372 const Handle(SelectMgr_SensitiveEntity)& aSensitive =
373 anEntitySet->GetSensitiveById (anIdx);
374 if (aSensitive->IsActiveForSelection())
376 const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
377 SelectMgr_SelectingVolumeManager aTmpMgr = aMgr;
378 computeFrustum (anEnt, theMgr, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
379 checkOverlap (anEnt, aInversedTrsf, aTmpMgr);
387 aNode = aStack[aHead];
393 //=======================================================================
394 // function: TraverseSensitives
395 // purpose : Traverses BVH containing all added selectable objects and
396 // finds candidates for further search of overlap
397 //=======================================================================
398 void SelectMgr_ViewerSelector::TraverseSensitives()
402 Standard_Integer aWidth;
403 Standard_Integer aHeight;
404 mySelectingVolumeMgr.WindowSize (aWidth, aHeight);
405 mySelectableObjects.UpdateBVH (mySelectingVolumeMgr.Camera(),
406 mySelectingVolumeMgr.ProjectionMatrix(),
407 mySelectingVolumeMgr.WorldViewMatrix(),
408 mySelectingVolumeMgr.WorldViewProjState(),
411 for (Standard_Integer aBVHSetIt = 0; aBVHSetIt < SelectMgr_SelectableObjectSet::BVHSubsetNb; ++aBVHSetIt)
413 SelectMgr_SelectableObjectSet::BVHSubset aBVHSubset =
414 static_cast<SelectMgr_SelectableObjectSet::BVHSubset> (aBVHSetIt);
416 if (mySelectableObjects.IsEmpty (aBVHSubset))
423 SelectMgr_SelectingVolumeManager aMgr (Standard_False);
425 // for 2D space selection transform selecting volumes to perform overap testing
426 // directly in camera's eye space omitting the camera position, which is not
427 // needed there at all
428 if (aBVHSubset == SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent)
430 const Graphic3d_Mat4d& aMat = mySelectingVolumeMgr.WorldViewMatrix();
431 aTFrustum.SetValue (1, 1, aMat.GetValue (0, 0));
432 aTFrustum.SetValue (1, 2, aMat.GetValue (0, 1));
433 aTFrustum.SetValue (1, 3, aMat.GetValue (0, 2));
434 aTFrustum.SetValue (2, 1, aMat.GetValue (1, 0));
435 aTFrustum.SetValue (2, 2, aMat.GetValue (1, 1));
436 aTFrustum.SetValue (2, 3, aMat.GetValue (1, 2));
437 aTFrustum.SetValue (3, 1, aMat.GetValue (2, 0));
438 aTFrustum.SetValue (3, 2, aMat.GetValue (2, 1));
439 aTFrustum.SetValue (3, 3, aMat.GetValue (2, 2));
440 aTFrustum.SetTranslationPart (gp_XYZ (aMat.GetValue (0, 3), aMat.GetValue (1, 3), aMat.GetValue (2, 3)));
442 // define corresponding frustum builder parameters
443 Handle(SelectMgr_FrustumBuilder) aBuilder = new SelectMgr_FrustumBuilder();
444 aBuilder->SetProjectionMatrix (mySelectingVolumeMgr.ProjectionMatrix());
445 aBuilder->SetWorldViewMatrix (THE_IDENTITY_MAT);
446 aBuilder->SetWindowSize (aWidth, aHeight);
447 aMgr = mySelectingVolumeMgr.ScaleAndTransform (1, aTFrustum, aBuilder);
451 aMgr = mySelectingVolumeMgr;
454 const Handle(Graphic3d_Camera)& aCamera = mySelectingVolumeMgr.Camera();
455 const Graphic3d_Mat4d& aProjectionMat = mySelectingVolumeMgr.ProjectionMatrix();
456 const Graphic3d_Mat4d& aWorldViewMat = aBVHSubset != SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent
457 ? mySelectingVolumeMgr.WorldViewMatrix()
460 const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aBVHTree = mySelectableObjects.BVH (aBVHSubset);
462 Standard_Integer aNode = 0;
463 if (!aMgr.Overlaps (aBVHTree->MinPoint (0), aBVHTree->MaxPoint (0)))
468 Standard_Integer aStack[32];
469 Standard_Integer aHead = -1;
472 if (!aBVHTree->IsOuter (aNode))
474 const Standard_Integer aLeftChildIdx = aBVHTree->Child<0> (aNode);
475 const Standard_Integer aRightChildIdx = aBVHTree->Child<1> (aNode);
476 const Standard_Boolean isLeftChildIn =
477 aMgr.Overlaps (aBVHTree->MinPoint (aLeftChildIdx), aBVHTree->MaxPoint (aLeftChildIdx));
478 const Standard_Boolean isRightChildIn =
479 aMgr.Overlaps (aBVHTree->MinPoint (aRightChildIdx), aBVHTree->MaxPoint (aRightChildIdx));
483 aNode = aLeftChildIdx;
485 aStack[aHead] = aRightChildIdx;
487 else if (isLeftChildIn
490 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
499 aNode = aStack[aHead];
505 Standard_Integer aStartIdx = aBVHTree->BegPrimitive (aNode);
506 Standard_Integer anEndIdx = aBVHTree->EndPrimitive (aNode);
507 for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
509 const Handle(SelectMgr_SelectableObject)& aSelectableObject =
510 mySelectableObjects.GetObjectById (aBVHSubset, anIdx);
512 traverseObject (aSelectableObject, aMgr, aCamera, aProjectionMat, aWorldViewMat, aWidth, aHeight);
519 aNode = aStack[aHead];
528 //==================================================
531 //==================================================
532 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector
535 Standard_Integer RankInMap = myIndexes->Value (myCurRank);
536 const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap);
537 Handle(SelectMgr_EntityOwner) Ownr = Handle(SelectMgr_EntityOwner)::DownCast (toto);
541 //=======================================================================
544 //=======================================================================
545 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked (const Standard_Integer theRank) const
547 Handle(SelectMgr_EntityOwner) anOwner;
548 if (theRank < 1 || theRank > NbPicked())
553 const Standard_Integer anOwnerIdx = myIndexes->Value (theRank);
554 const Handle(SelectBasics_EntityOwner)& aStoredOwner = mystored.FindKey (anOwnerIdx);
555 anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aStoredOwner);
559 //=======================================================================
560 //function : PickedData
562 //=======================================================================
563 const SelectMgr_SortCriterion& SelectMgr_ViewerSelector::PickedData(const Standard_Integer theRank) const
565 Standard_OutOfRange_Raise_if (theRank < 1 || theRank > NbPicked(), "SelectMgr_ViewerSelector::PickedData() out of range index");
566 const Standard_Integer anOwnerIdx = myIndexes->Value (theRank);
567 return mystored.FindFromIndex (anOwnerIdx);
570 //===================================================
572 // INTERNAL METHODS ....
574 //==================================================
576 //==================================================
577 // Function: Contains
579 //==================================================
580 Standard_Boolean SelectMgr_ViewerSelector::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
582 return mySelectableObjects.Contains (theObject);
585 //==================================================
586 // Function: ActiveModes
587 // Purpose : return all the modes with a given state for an object
588 //==================================================
589 Standard_Boolean SelectMgr_ViewerSelector::Modes (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
590 TColStd_ListOfInteger& theModeList,
591 const SelectMgr_StateOfSelection theWantedState) const
593 Standard_Boolean hasActivatedStates = Contains (theSelectableObject);
594 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
596 if (theWantedState == SelectMgr_SOS_Any)
598 theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
600 else if (theWantedState == theSelectableObject->CurrentSelection()->GetSelectionState())
602 theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
606 return hasActivatedStates;
609 //==================================================
610 // Function: IsActive
612 //==================================================
613 Standard_Boolean SelectMgr_ViewerSelector::IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
614 const Standard_Integer theMode) const
616 if (!Contains (theSelectableObject))
617 return Standard_False;
619 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
621 if (theMode == theSelectableObject->CurrentSelection()->Mode())
623 return theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated;
627 return Standard_False;
630 //==================================================
631 // Function: IsInside
633 //==================================================
634 Standard_Boolean SelectMgr_ViewerSelector::IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
635 const Standard_Integer theMode) const
637 if (!Contains (theSelectableObject))
638 return Standard_False;
640 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
642 if (theMode == theSelectableObject->CurrentSelection()->Mode())
644 return theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown;
648 return Standard_False;
652 //=======================================================================
655 //=======================================================================
657 SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_Selection)& theSelection) const
659 return theSelection->GetSelectionState();
662 //==================================================
664 // Purpose : gives Information about selectors
665 //==================================================
667 TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const
669 TCollection_AsciiString aStatus ("Status Object :\n\t");
671 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
673 if (theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown)
675 aStatus = aStatus + "Mode " +
676 TCollection_AsciiString (theSelectableObject->CurrentSelection()->Mode()) +
678 if (theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated)
680 aStatus = aStatus + " Active \n\t";
684 aStatus = aStatus + " Inactive \n\t";
689 if (!Contains (theSelectableObject))
691 aStatus = aStatus + "Not Present in the selector\n\n";
697 //=======================================================================
698 //function : SortResult
699 //purpose : there is a certain number of entities ranged by criteria
700 // (depth, size, priority, mouse distance from borders or
701 // CDG of the detected primitive. Parsing :
702 // maximum priorities .
703 // then a reasonable compromise between depth and distance...
704 // finally the ranges are stored in myindexes depending on the parsing.
705 // so, it is possible to only read
706 //=======================================================================
707 void SelectMgr_ViewerSelector::SortResult()
709 if(mystored.IsEmpty()) return;
711 const Standard_Integer anExtent = mystored.Extent();
712 if(myIndexes.IsNull() || anExtent != myIndexes->Length())
713 myIndexes = new TColStd_HArray1OfInteger (1, anExtent);
716 TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1();
718 // indices from 1 to N are loaded
720 for (I=1; I <= anExtent; I++)
723 std::sort (thearr.begin(), thearr.end(), CompareResults (mystored));
727 //=======================================================================
728 //function : HasDepthClipping
730 //=======================================================================
731 Standard_Boolean SelectMgr_ViewerSelector::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& /*theOwner*/) const
733 return Standard_False;
736 //=======================================================================
737 // function : AddSelectableObject
738 // purpose : Adds new object to the map of selectable objects
739 //=======================================================================
740 void SelectMgr_ViewerSelector::AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
742 if (!myMapOfObjectSensitives.IsBound (theObject))
744 mySelectableObjects.Append (theObject);
745 NCollection_Handle<SelectMgr_SensitiveEntitySet> anEntitySet = new SelectMgr_SensitiveEntitySet();
746 myMapOfObjectSensitives.Bind (theObject, anEntitySet);
750 //=======================================================================
751 // function : AddSelectionToObject
752 // purpose : Adds new selection to the object and builds its BVH tree
753 //=======================================================================
754 void SelectMgr_ViewerSelector::AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject,
755 const Handle(SelectMgr_Selection)& theSelection)
757 if (myMapOfObjectSensitives.IsBound (theObject))
759 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
760 myMapOfObjectSensitives.ChangeFind (theObject);
761 anEntitySet->Append (theSelection);
766 AddSelectableObject (theObject);
767 AddSelectionToObject (theObject, theSelection);
771 //=======================================================================
772 // function : MoveSelectableObject
774 //=======================================================================
775 void SelectMgr_ViewerSelector::MoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
777 mySelectableObjects.ChangeSubset (theObject);
780 //=======================================================================
781 // function : RemoveSelectableObject
782 // purpose : Removes selectable object from map of selectable ones
783 //=======================================================================
784 void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
786 if (myMapOfObjectSensitives.IsBound (theObject))
788 mySelectableObjects.Remove (theObject);
789 myMapOfObjectSensitives.UnBind (theObject);
793 //=======================================================================
794 // function : RemoveSelectionOfObject
795 // purpose : Removes selection of the object and marks its BVH tree
797 //=======================================================================
798 void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject,
799 const Handle(SelectMgr_Selection)& theSelection)
801 if (myMapOfObjectSensitives.IsBound (theObject))
803 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
804 myMapOfObjectSensitives.ChangeFind (theObject);
805 anEntitySet->Remove (theSelection);
809 //=======================================================================
810 // function : RebuildObjectsTree
811 // purpose : Marks BVH of selectable objects for rebuild
812 //=======================================================================
813 void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce)
815 mySelectableObjects.MarkDirty();
819 Standard_Integer aViewportWidth, aViewportHeight;
820 mySelectingVolumeMgr.WindowSize (aViewportWidth, aViewportHeight);
822 Standard_Integer aWidth;
823 Standard_Integer aHeight;
824 mySelectingVolumeMgr.WindowSize (aWidth, aHeight);
825 mySelectableObjects.UpdateBVH (mySelectingVolumeMgr.Camera(),
826 mySelectingVolumeMgr.ProjectionMatrix(),
827 mySelectingVolumeMgr.WorldViewMatrix(),
828 mySelectingVolumeMgr.WorldViewProjState(),
833 //=======================================================================
834 // function : RebuildSensitivesTree
835 // purpose : Marks BVH of sensitive entities of particular selectable
836 // object for rebuild
837 //=======================================================================
838 void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject,
839 const Standard_Boolean theIsForce)
841 if (!Contains (theObject))
844 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
845 anEntitySet->MarkDirty();
853 //=======================================================================
854 // function : resetSelectionActivationStatus
855 // purpose : Marks all added sensitive entities of all objects as
857 //=======================================================================
858 void SelectMgr_ViewerSelector::ResetSelectionActivationStatus()
860 SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives);
861 for ( ; aSensitivesIter.More(); aSensitivesIter.Next())
863 NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
864 aSensitivesIter.ChangeValue();
865 Standard_Integer anEntitiesNb = anEntitySet->Size();
866 for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
868 anEntitySet->GetSensitiveById (anIdx)->ResetSelectionActiveStatus();
873 //=======================================================================
874 // function : DetectedEntity
875 // purpose : Returns sensitive entity that was detected during the
876 // previous run of selection algorithm
877 //=======================================================================
878 const Handle(SelectBasics_SensitiveEntity)& SelectMgr_ViewerSelector::DetectedEntity() const
880 const Standard_Integer aRankInMap = myIndexes->Value(myCurRank);
881 return mystored.FindFromIndex (aRankInMap).Entity;
884 //=======================================================================
885 // function : ActiveOwners
886 // purpose : Returns the list of active entity owners
887 //=======================================================================
888 void SelectMgr_ViewerSelector::ActiveOwners (NCollection_List<Handle(SelectBasics_EntityOwner)>& theOwners) const
890 for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next())
892 const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = anIter.Value();
893 Standard_Integer anEntitiesNb = anEntitySet->Size();
894 for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
896 if (anEntitySet->GetSensitiveById (anIdx)->IsActiveForSelection())
898 theOwners.Append (anEntitySet->GetSensitiveById (anIdx)->BaseSensitive()->OwnerId());
904 //=======================================================================
905 //function : AllowOverlapDetection
906 //purpose : Sets the detection type: if theIsToAllow is false,
907 // only fully included sensitives will be detected, otherwise
908 // the algorithm will mark both included and overlapped entities
910 //=======================================================================
911 void SelectMgr_ViewerSelector::AllowOverlapDetection (const Standard_Boolean theIsToAllow)
913 mySelectingVolumeMgr.AllowOverlapDetection (theIsToAllow);