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, Standard_Transient)
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 SelectMgr_ViewerSelector_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),
98 myEntitySetBuilder = new BVH_BinnedBuilder<Standard_Real, 3, 4> (BVH_Constants_LeafNodeSizeSingle, BVH_Constants_MaxTreeDepth, Standard_True);
101 //==================================================
102 // Function: Activate
104 //==================================================
105 void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSelection)
107 for (theSelection->Init(); theSelection->More(); theSelection->Next())
109 theSelection->Sensitive()->SetActiveForSelection();
112 theSelection->SetSelectionState (SelectMgr_SOS_Activated);
114 myTolerances.Add (theSelection->Sensitivity());
115 myToUpdateTolerance = Standard_True;
118 //==================================================
119 // Function: Deactivate
121 //==================================================
122 void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theSelection)
124 for (theSelection->Init(); theSelection->More(); theSelection->Next())
126 theSelection->Sensitive()->ResetSelectionActiveStatus();
129 theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
131 myTolerances.Decrement (theSelection->Sensitivity());
132 myToUpdateTolerance = Standard_True;
135 //==================================================
138 //==================================================
139 void SelectMgr_ViewerSelector::Clear()
144 //=======================================================================
145 // function: isToScaleFrustum
146 // purpose : Checks if the entity given requires to scale current selecting frustum
147 //=======================================================================
148 Standard_Boolean SelectMgr_ViewerSelector::isToScaleFrustum (const Handle(SelectBasics_SensitiveEntity)& theEntity)
150 return mySelectingVolumeMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point
151 && sensitivity (theEntity) < myTolerances.Tolerance();
154 //=======================================================================
155 // function: sensitivity
156 // purpose : In case if custom tolerance is set, this method will return sum of entity
157 // sensitivity and custom tolerance.
158 //=======================================================================
159 Standard_Integer SelectMgr_ViewerSelector::sensitivity (const Handle(SelectBasics_SensitiveEntity)& theEntity) const
161 return myTolerances.IsCustomTolSet() ?
162 theEntity->SensitivityFactor() + myTolerances.CustomTolerance() : theEntity->SensitivityFactor();
165 //=======================================================================
166 // function: checkOverlap
167 // purpose : Internal function that checks if a particular sensitive
168 // entity theEntity overlaps current selecting volume precisely
169 //=======================================================================
170 void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_SensitiveEntity)& theEntity,
171 const gp_GTrsf& theInversedTrsf,
172 SelectMgr_SelectingVolumeManager& theMgr)
174 Handle(SelectMgr_EntityOwner) anOwner (Handle(SelectMgr_EntityOwner)::DownCast (theEntity->OwnerId()));
175 Handle(SelectMgr_SelectableObject) aSelectable;
176 Standard_Boolean toRestoresViewClipEnabled = Standard_False;
177 if (!anOwner.IsNull())
179 aSelectable = anOwner->Selectable();
180 if (!aSelectable->ClipPlanes().IsNull()
181 && aSelectable->ClipPlanes()->ToOverrideGlobal())
183 theMgr.SetViewClippingEnabled (Standard_False);
184 toRestoresViewClipEnabled = Standard_True;
186 else if (!aSelectable->TransformPersistence().IsNull())
188 if (aSelectable->TransformPersistence()->IsZoomOrRotate()
189 && !theMgr.ViewClipping().IsNull())
191 // Zoom/rotate persistence object lives in two worlds at the same time.
192 // Global clipping planes can not be trivially applied without being converted
193 // into local space of transformation persistence object.
194 // As more simple alternative - just clip entire object by its anchor point defined in the world space.
195 const Handle(Graphic3d_SequenceOfHClipPlane)& aViewPlanes = theMgr.ViewClipping();
197 const gp_Pnt anAnchor = aSelectable->TransformPersistence()->AnchorPoint();
198 for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aViewPlanes); aPlaneIt.More(); aPlaneIt.Next())
200 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
206 const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation();
207 const Graphic3d_Vec4d aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0);
208 if (aPlaneEquation.Dot (aCheckPnt) < 0.0) // vertex is outside the half-space
215 theMgr.SetViewClippingEnabled (Standard_False);
216 toRestoresViewClipEnabled = Standard_True;
220 SelectBasics_PickResult aPickResult;
221 const Standard_Boolean isMatched = theEntity->Matches(theMgr, aPickResult);
222 if (toRestoresViewClipEnabled)
224 theMgr.SetViewClippingEnabled (Standard_True);
233 if (HasDepthClipping (anOwner)
234 && theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point)
236 Standard_Boolean isClipped = mySelectingVolumeMgr.IsClipped (*aSelectable->ClipPlanes(),
237 aPickResult.Depth());
242 SelectMgr_SortCriterion aCriterion;
243 myZLayerOrderMap.Find (aSelectable->ZLayer(), aCriterion.ZLayerPosition);
244 aCriterion.Entity = theEntity;
245 aCriterion.Priority = anOwner->Priority();
246 aCriterion.Depth = aPickResult.Depth();
247 aCriterion.MinDist = aPickResult.DistToGeomCenter();
248 aCriterion.Tolerance = theEntity->SensitivityFactor() / 33.0;
249 aCriterion.ToPreferClosest = preferclosest;
251 const Standard_Integer aPrevStoredIndex = mystored.FindIndex (anOwner);
252 if (aPrevStoredIndex != 0)
254 if (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Box)
256 SelectMgr_SortCriterion& aPrevCriterion = mystored.ChangeFromIndex (aPrevStoredIndex);
257 if (aCriterion > aPrevCriterion)
259 updatePoint3d (aCriterion, theInversedTrsf, theMgr);
260 aPrevCriterion = aCriterion;
266 updatePoint3d (aCriterion, theInversedTrsf, theMgr);
267 mystored.Add (anOwner, aCriterion);
271 //=======================================================================
272 // function: computeFrustum
273 // purpose : Internal function that checks if a current selecting frustum
274 // needs to be scaled and transformed for the entity and performs
275 // necessary calculations
276 //=======================================================================
277 void SelectMgr_ViewerSelector::computeFrustum (const Handle(SelectBasics_SensitiveEntity)& theEnt,
278 const SelectMgr_SelectingVolumeManager& theMgr,
279 const gp_GTrsf& theInvTrsf,
280 SelectMgr_FrustumCache& theCachedMgrs,
281 SelectMgr_SelectingVolumeManager& theResMgr)
283 Standard_Integer aScale = isToScaleFrustum (theEnt) ? sensitivity (theEnt) : 1;
284 const gp_GTrsf aTrsfMtr = theEnt->HasInitLocation() ? theEnt->InvInitLocation() * theInvTrsf : theInvTrsf;
285 const Standard_Boolean toScale = aScale != 1;
286 const Standard_Boolean toTransform = aTrsfMtr.Form() != gp_Identity;
287 if (toScale && toTransform)
289 theResMgr = theMgr.ScaleAndTransform (aScale, aTrsfMtr, NULL);
293 if (!theCachedMgrs.IsBound (aScale))
295 theCachedMgrs.Bind (aScale, theMgr.ScaleAndTransform (aScale, gp_Trsf(), NULL));
297 theResMgr = theCachedMgrs.Find (aScale);
299 else if (toTransform)
301 theResMgr = theMgr.ScaleAndTransform (1, aTrsfMtr, NULL);
305 //=======================================================================
306 // function: traverseObject
307 // purpose : Internal function that checks if there is possible overlap
308 // between some entity of selectable object theObject and
309 // current selecting volume
310 //=======================================================================
311 void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_SelectableObject)& theObject,
312 const SelectMgr_SelectingVolumeManager& theMgr,
313 const Handle(Graphic3d_Camera)& theCamera,
314 const Graphic3d_Mat4d& theProjectionMat,
315 const Graphic3d_Mat4d& theWorldViewMat,
316 const Standard_Integer theViewportWidth,
317 const Standard_Integer theViewportHeight)
319 Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
320 if (anEntitySet->Size() == 0)
325 const opencascade::handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
326 gp_GTrsf aInversedTrsf;
327 if (theObject->HasTransformation() || !theObject->TransformPersistence().IsNull())
329 if (theObject->TransformPersistence().IsNull())
331 aInversedTrsf = theObject->InversedTransformation();
336 Graphic3d_Mat4d aMat = theObject->TransformPersistence()->Compute (theCamera, theProjectionMat, theWorldViewMat, theViewportWidth, theViewportHeight);
338 aTPers.SetValue (1, 1, aMat.GetValue (0, 0));
339 aTPers.SetValue (1, 2, aMat.GetValue (0, 1));
340 aTPers.SetValue (1, 3, aMat.GetValue (0, 2));
341 aTPers.SetValue (2, 1, aMat.GetValue (1, 0));
342 aTPers.SetValue (2, 2, aMat.GetValue (1, 1));
343 aTPers.SetValue (2, 3, aMat.GetValue (1, 2));
344 aTPers.SetValue (3, 1, aMat.GetValue (2, 0));
345 aTPers.SetValue (3, 2, aMat.GetValue (2, 1));
346 aTPers.SetValue (3, 3, aMat.GetValue (2, 2));
347 aTPers.SetTranslationPart (gp_XYZ (aMat.GetValue (0, 3), aMat.GetValue (1, 3), aMat.GetValue (2, 3)));
349 aInversedTrsf = (aTPers * gp_GTrsf (theObject->Transformation())).Inverted();
353 SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity
354 ? theMgr.ScaleAndTransform (1, aInversedTrsf, NULL)
357 SelectMgr_FrustumCache aScaledTrnsfFrustums;
359 Standard_Integer aNode = 0; // a root node
360 if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
361 aSensitivesTree->MaxPoint (0)))
365 Standard_Integer aStack[BVH_Constants_MaxTreeDepth];
366 Standard_Integer aHead = -1;
369 if (!aSensitivesTree->IsOuter (aNode))
371 const Standard_Integer aLeftChildIdx = aSensitivesTree->Child<0> (aNode);
372 const Standard_Integer aRightChildIdx = aSensitivesTree->Child<1> (aNode);
373 const Standard_Boolean isLeftChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aLeftChildIdx),
374 aSensitivesTree->MaxPoint (aLeftChildIdx));
375 const Standard_Boolean isRightChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aRightChildIdx),
376 aSensitivesTree->MaxPoint (aRightChildIdx));
380 aNode = aLeftChildIdx;
382 aStack[aHead] = aRightChildIdx;
384 else if (isLeftChildIn
387 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
396 aNode = aStack[aHead];
402 Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode);
403 Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode);
404 for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
406 const Handle(SelectMgr_SensitiveEntity)& aSensitive =
407 anEntitySet->GetSensitiveById (anIdx);
408 if (aSensitive->IsActiveForSelection())
410 const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
411 SelectMgr_SelectingVolumeManager aTmpMgr = aMgr;
412 computeFrustum (anEnt, theMgr, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
413 checkOverlap (anEnt, aInversedTrsf, aTmpMgr);
421 aNode = aStack[aHead];
427 //=======================================================================
428 // function: TraverseSensitives
429 // purpose : Traverses BVH containing all added selectable objects and
430 // finds candidates for further search of overlap
431 //=======================================================================
432 void SelectMgr_ViewerSelector::TraverseSensitives()
436 Standard_Integer aWidth;
437 Standard_Integer aHeight;
438 mySelectingVolumeMgr.WindowSize (aWidth, aHeight);
439 mySelectableObjects.UpdateBVH (mySelectingVolumeMgr.Camera(),
440 mySelectingVolumeMgr.ProjectionMatrix(),
441 mySelectingVolumeMgr.WorldViewMatrix(),
442 mySelectingVolumeMgr.WorldViewProjState(),
445 for (Standard_Integer aBVHSetIt = 0; aBVHSetIt < SelectMgr_SelectableObjectSet::BVHSubsetNb; ++aBVHSetIt)
447 SelectMgr_SelectableObjectSet::BVHSubset aBVHSubset =
448 static_cast<SelectMgr_SelectableObjectSet::BVHSubset> (aBVHSetIt);
450 if (mySelectableObjects.IsEmpty (aBVHSubset))
457 SelectMgr_SelectingVolumeManager aMgr (Standard_False);
459 // for 2D space selection transform selecting volumes to perform overap testing
460 // directly in camera's eye space omitting the camera position, which is not
461 // needed there at all
462 if (aBVHSubset == SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent)
464 const Graphic3d_Mat4d& aMat = mySelectingVolumeMgr.WorldViewMatrix();
465 aTFrustum.SetValue (1, 1, aMat.GetValue (0, 0));
466 aTFrustum.SetValue (1, 2, aMat.GetValue (0, 1));
467 aTFrustum.SetValue (1, 3, aMat.GetValue (0, 2));
468 aTFrustum.SetValue (2, 1, aMat.GetValue (1, 0));
469 aTFrustum.SetValue (2, 2, aMat.GetValue (1, 1));
470 aTFrustum.SetValue (2, 3, aMat.GetValue (1, 2));
471 aTFrustum.SetValue (3, 1, aMat.GetValue (2, 0));
472 aTFrustum.SetValue (3, 2, aMat.GetValue (2, 1));
473 aTFrustum.SetValue (3, 3, aMat.GetValue (2, 2));
474 aTFrustum.SetTranslationPart (gp_XYZ (aMat.GetValue (0, 3), aMat.GetValue (1, 3), aMat.GetValue (2, 3)));
476 // define corresponding frustum builder parameters
477 Handle(SelectMgr_FrustumBuilder) aBuilder = new SelectMgr_FrustumBuilder();
478 aBuilder->SetProjectionMatrix (mySelectingVolumeMgr.ProjectionMatrix());
479 aBuilder->SetWorldViewMatrix (SelectMgr_ViewerSelector_THE_IDENTITY_MAT);
480 aBuilder->SetWindowSize (aWidth, aHeight);
481 aMgr = mySelectingVolumeMgr.ScaleAndTransform (1, aTFrustum, aBuilder);
485 aMgr = mySelectingVolumeMgr;
488 const Handle(Graphic3d_Camera)& aCamera = mySelectingVolumeMgr.Camera();
489 const Graphic3d_Mat4d& aProjectionMat = mySelectingVolumeMgr.ProjectionMatrix();
490 const Graphic3d_Mat4d& aWorldViewMat = aBVHSubset != SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent
491 ? mySelectingVolumeMgr.WorldViewMatrix()
492 : SelectMgr_ViewerSelector_THE_IDENTITY_MAT;
494 const opencascade::handle<BVH_Tree<Standard_Real, 3> >& aBVHTree = mySelectableObjects.BVH (aBVHSubset);
496 Standard_Integer aNode = 0;
497 if (!aMgr.Overlaps (aBVHTree->MinPoint (0), aBVHTree->MaxPoint (0)))
502 Standard_Integer aStack[BVH_Constants_MaxTreeDepth];
503 Standard_Integer aHead = -1;
506 if (!aBVHTree->IsOuter (aNode))
508 const Standard_Integer aLeftChildIdx = aBVHTree->Child<0> (aNode);
509 const Standard_Integer aRightChildIdx = aBVHTree->Child<1> (aNode);
510 const Standard_Boolean isLeftChildIn =
511 aMgr.Overlaps (aBVHTree->MinPoint (aLeftChildIdx), aBVHTree->MaxPoint (aLeftChildIdx));
512 const Standard_Boolean isRightChildIn =
513 aMgr.Overlaps (aBVHTree->MinPoint (aRightChildIdx), aBVHTree->MaxPoint (aRightChildIdx));
517 aNode = aLeftChildIdx;
519 aStack[aHead] = aRightChildIdx;
521 else if (isLeftChildIn
524 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
533 aNode = aStack[aHead];
539 Standard_Integer aStartIdx = aBVHTree->BegPrimitive (aNode);
540 Standard_Integer anEndIdx = aBVHTree->EndPrimitive (aNode);
541 for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
543 const Handle(SelectMgr_SelectableObject)& aSelectableObject =
544 mySelectableObjects.GetObjectById (aBVHSubset, anIdx);
546 traverseObject (aSelectableObject, aMgr, aCamera, aProjectionMat, aWorldViewMat, aWidth, aHeight);
553 aNode = aStack[aHead];
562 //==================================================
565 //==================================================
566 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector
569 Standard_Integer RankInMap = myIndexes->Value (myCurRank);
570 const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap);
571 Handle(SelectMgr_EntityOwner) Ownr = Handle(SelectMgr_EntityOwner)::DownCast (toto);
575 //=======================================================================
578 //=======================================================================
579 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked (const Standard_Integer theRank) const
581 Handle(SelectMgr_EntityOwner) anOwner;
582 if (theRank < 1 || theRank > NbPicked())
587 const Standard_Integer anOwnerIdx = myIndexes->Value (theRank);
588 const Handle(SelectBasics_EntityOwner)& aStoredOwner = mystored.FindKey (anOwnerIdx);
589 anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aStoredOwner);
593 //=======================================================================
594 //function : PickedData
596 //=======================================================================
597 const SelectMgr_SortCriterion& SelectMgr_ViewerSelector::PickedData(const Standard_Integer theRank) const
599 Standard_OutOfRange_Raise_if (theRank < 1 || theRank > NbPicked(), "SelectMgr_ViewerSelector::PickedData() out of range index");
600 const Standard_Integer anOwnerIdx = myIndexes->Value (theRank);
601 return mystored.FindFromIndex (anOwnerIdx);
604 //===================================================
606 // INTERNAL METHODS ....
608 //==================================================
610 //==================================================
611 // Function: SetEntitySetBuilder
613 //==================================================
614 void SelectMgr_ViewerSelector::SetEntitySetBuilder (const Handle(Select3D_BVHBuilder3d)& theBuilder)
616 myEntitySetBuilder = theBuilder;
617 for (SelectMgr_MapOfObjectSensitives::Iterator aSetIter (myMapOfObjectSensitives); aSetIter.More(); aSetIter.Next())
619 aSetIter.ChangeValue()->SetBuilder (myEntitySetBuilder);
623 //==================================================
624 // Function: Contains
626 //==================================================
627 Standard_Boolean SelectMgr_ViewerSelector::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
629 return mySelectableObjects.Contains (theObject);
632 //==================================================
633 // Function: ActiveModes
634 // Purpose : return all the modes with a given state for an object
635 //==================================================
636 Standard_Boolean SelectMgr_ViewerSelector::Modes (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
637 TColStd_ListOfInteger& theModeList,
638 const SelectMgr_StateOfSelection theWantedState) const
640 Standard_Boolean hasActivatedStates = Contains (theSelectableObject);
641 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
643 if (theWantedState == SelectMgr_SOS_Any)
645 theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
647 else if (theWantedState == theSelectableObject->CurrentSelection()->GetSelectionState())
649 theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
653 return hasActivatedStates;
656 //==================================================
657 // Function: IsActive
659 //==================================================
660 Standard_Boolean SelectMgr_ViewerSelector::IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
661 const Standard_Integer theMode) const
663 if (!Contains (theSelectableObject))
664 return Standard_False;
666 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
668 if (theMode == theSelectableObject->CurrentSelection()->Mode())
670 return theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated;
674 return Standard_False;
677 //==================================================
678 // Function: IsInside
680 //==================================================
681 Standard_Boolean SelectMgr_ViewerSelector::IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
682 const Standard_Integer theMode) const
684 if (!Contains (theSelectableObject))
685 return Standard_False;
687 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
689 if (theMode == theSelectableObject->CurrentSelection()->Mode())
691 return theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown;
695 return Standard_False;
699 //=======================================================================
702 //=======================================================================
704 SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_Selection)& theSelection) const
706 return theSelection->GetSelectionState();
709 //==================================================
711 // Purpose : gives Information about selectors
712 //==================================================
714 TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const
716 TCollection_AsciiString aStatus ("Status Object :\n\t");
718 for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
720 if (theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown)
722 aStatus = aStatus + "Mode " +
723 TCollection_AsciiString (theSelectableObject->CurrentSelection()->Mode()) +
725 if (theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated)
727 aStatus = aStatus + " Active \n\t";
731 aStatus = aStatus + " Inactive \n\t";
736 if (!Contains (theSelectableObject))
738 aStatus = aStatus + "Not Present in the selector\n\n";
744 //=======================================================================
745 //function : SortResult
746 //purpose : there is a certain number of entities ranged by criteria
747 // (depth, size, priority, mouse distance from borders or
748 // CDG of the detected primitive. Parsing :
749 // maximum priorities .
750 // then a reasonable compromise between depth and distance...
751 // finally the ranges are stored in myindexes depending on the parsing.
752 // so, it is possible to only read
753 //=======================================================================
754 void SelectMgr_ViewerSelector::SortResult()
756 if(mystored.IsEmpty()) return;
758 const Standard_Integer anExtent = mystored.Extent();
759 if(myIndexes.IsNull() || anExtent != myIndexes->Length())
760 myIndexes = new TColStd_HArray1OfInteger (1, anExtent);
762 TColStd_Array1OfInteger& anIndexArray = myIndexes->ChangeArray1();
763 for (Standard_Integer anIndexIter = 1; anIndexIter <= anExtent; ++anIndexIter)
765 anIndexArray.SetValue (anIndexIter, anIndexIter);
767 std::sort (anIndexArray.begin(), anIndexArray.end(), CompareResults (mystored));
770 //=======================================================================
771 //function : HasDepthClipping
773 //=======================================================================
774 Standard_Boolean SelectMgr_ViewerSelector::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& /*theOwner*/) const
776 return Standard_False;
779 //=======================================================================
780 // function : AddSelectableObject
781 // purpose : Adds new object to the map of selectable objects
782 //=======================================================================
783 void SelectMgr_ViewerSelector::AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
785 if (!myMapOfObjectSensitives.IsBound (theObject))
787 mySelectableObjects.Append (theObject);
788 Handle(SelectMgr_SensitiveEntitySet) anEntitySet = new SelectMgr_SensitiveEntitySet (myEntitySetBuilder);
789 myMapOfObjectSensitives.Bind (theObject, anEntitySet);
793 //=======================================================================
794 // function : AddSelectionToObject
795 // purpose : Adds new selection to the object and builds its BVH tree
796 //=======================================================================
797 void SelectMgr_ViewerSelector::AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject,
798 const Handle(SelectMgr_Selection)& theSelection)
800 if (Handle(SelectMgr_SensitiveEntitySet)* anEntitySet = myMapOfObjectSensitives.ChangeSeek (theObject))
802 (*anEntitySet)->Append (theSelection);
803 (*anEntitySet)->BVH();
807 AddSelectableObject (theObject);
808 AddSelectionToObject (theObject, theSelection);
812 //=======================================================================
813 // function : MoveSelectableObject
815 //=======================================================================
816 void SelectMgr_ViewerSelector::MoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
818 mySelectableObjects.ChangeSubset (theObject);
821 //=======================================================================
822 // function : RemoveSelectableObject
823 // purpose : Removes selectable object from map of selectable ones
824 //=======================================================================
825 void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
827 Handle(SelectMgr_SelectableObject) anObj = theObject;
828 if (myMapOfObjectSensitives.UnBind (theObject))
830 mySelectableObjects.Remove (theObject);
834 //=======================================================================
835 // function : RemoveSelectionOfObject
836 // purpose : Removes selection of the object and marks its BVH tree
838 //=======================================================================
839 void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject,
840 const Handle(SelectMgr_Selection)& theSelection)
842 if (Handle(SelectMgr_SensitiveEntitySet)* anEntitySet = myMapOfObjectSensitives.ChangeSeek (theObject))
844 (*anEntitySet)->Remove (theSelection);
848 //=======================================================================
849 // function : RebuildObjectsTree
850 // purpose : Marks BVH of selectable objects for rebuild
851 //=======================================================================
852 void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce)
854 mySelectableObjects.MarkDirty();
858 Standard_Integer aViewportWidth, aViewportHeight;
859 mySelectingVolumeMgr.WindowSize (aViewportWidth, aViewportHeight);
861 Standard_Integer aWidth;
862 Standard_Integer aHeight;
863 mySelectingVolumeMgr.WindowSize (aWidth, aHeight);
864 mySelectableObjects.UpdateBVH (mySelectingVolumeMgr.Camera(),
865 mySelectingVolumeMgr.ProjectionMatrix(),
866 mySelectingVolumeMgr.WorldViewMatrix(),
867 mySelectingVolumeMgr.WorldViewProjState(),
872 //=======================================================================
873 // function : RebuildSensitivesTree
874 // purpose : Marks BVH of sensitive entities of particular selectable
875 // object for rebuild
876 //=======================================================================
877 void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject,
878 const Standard_Boolean theIsForce)
880 if (!Contains (theObject))
883 Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
884 anEntitySet->MarkDirty();
892 //=======================================================================
893 // function : resetSelectionActivationStatus
894 // purpose : Marks all added sensitive entities of all objects as
896 //=======================================================================
897 void SelectMgr_ViewerSelector::ResetSelectionActivationStatus()
899 for (SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives); aSensitivesIter.More(); aSensitivesIter.Next())
901 Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = aSensitivesIter.ChangeValue();
902 const Standard_Integer anEntitiesNb = anEntitySet->Size();
903 for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
905 anEntitySet->GetSensitiveById (anIdx)->ResetSelectionActiveStatus();
910 //=======================================================================
911 // function : DetectedEntity
912 // purpose : Returns sensitive entity that was detected during the
913 // previous run of selection algorithm
914 //=======================================================================
915 const Handle(SelectBasics_SensitiveEntity)& SelectMgr_ViewerSelector::DetectedEntity() const
917 const Standard_Integer aRankInMap = myIndexes->Value(myCurRank);
918 return mystored.FindFromIndex (aRankInMap).Entity;
921 //=======================================================================
922 // function : ActiveOwners
923 // purpose : Returns the list of active entity owners
924 //=======================================================================
925 void SelectMgr_ViewerSelector::ActiveOwners (NCollection_List<Handle(SelectBasics_EntityOwner)>& theOwners) const
927 for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next())
929 const Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = anIter.Value();
930 const Standard_Integer anEntitiesNb = anEntitySet->Size();
931 for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
933 const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx);
934 if (aSensitive->IsActiveForSelection())
936 theOwners.Append (aSensitive->BaseSensitive()->OwnerId());
942 //=======================================================================
943 //function : AllowOverlapDetection
944 //purpose : Sets the detection type: if theIsToAllow is false,
945 // only fully included sensitives will be detected, otherwise
946 // the algorithm will mark both included and overlapped entities
948 //=======================================================================
949 void SelectMgr_ViewerSelector::AllowOverlapDetection (const Standard_Boolean theIsToAllow)
951 mySelectingVolumeMgr.AllowOverlapDetection (theIsToAllow);