// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-// Modified by ...
-// ROB JAN/07/98 : Improve Storage of detected entities
-// AGV OCT/23/03 : Optimize the method SortResult() (OCC4201)
+#include <SelectMgr_ViewerSelector.hxx>
#include <BVH_Tree.hxx>
+#include <gp_GTrsf.hxx>
#include <gp_Pnt.hxx>
#include <OSD_Environment.hxx>
#include <Precision.hxx>
-#include <SelectMgr_ViewerSelector.hxx>
-#include <SelectMgr_CompareResults.hxx>
#include <SelectBasics_EntityOwner.hxx>
#include <SelectBasics_SensitiveEntity.hxx>
#include <SelectBasics_PickResult.hxx>
#include <SelectMgr_EntityOwner.hxx>
#include <SelectMgr_SortCriterion.hxx>
#include <SelectMgr_SensitiveEntitySet.hxx>
-#include <SortTools_QuickSortOfInteger.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <TCollection_AsciiString.hxx>
#include <TColStd_HArray1OfInteger.hxx>
#include <TColStd_ListOfInteger.hxx>
+#include <algorithm>
-//=======================================================================
-// function: SelectMgr_ToleranceMap
-// purpose : Sets tolerance values to -1.0
-//=======================================================================
-SelectMgr_ToleranceMap::SelectMgr_ToleranceMap()
-{
- myLargestKey = -1.0;
- myCustomTolerance = -1.0;
-}
+IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_ViewerSelector, Standard_Transient)
-//=======================================================================
-// function: ~SelectMgr_ToleranceMap
-// purpose :
-//=======================================================================
-SelectMgr_ToleranceMap::~SelectMgr_ToleranceMap()
-{
- myTolerances.Clear();
-}
-
-//=======================================================================
-// function: Add
-// purpose : Adds the value given to map, checks if the current tolerance value
-// should be replaced by theTolerance
-//=======================================================================
-void SelectMgr_ToleranceMap::Add (const Standard_Real& theTolerance)
-{
- if (myTolerances.IsBound (theTolerance))
+namespace {
+ // Comparison operator for sorting selection results
+ class CompareResults
{
- Standard_Integer& aFreq = myTolerances.ChangeFind (theTolerance);
- aFreq++;
+ public:
+
+ CompareResults (const SelectMgr_IndexedDataMapOfOwnerCriterion& aMapOfCriterion)
+ : myMapOfCriterion (aMapOfCriterion)
+ {
+ }
- if (aFreq == 1 && theTolerance != myLargestKey)
- myLargestKey = Max (theTolerance, myLargestKey);
- }
- else
- {
- if (myTolerances.IsEmpty())
+ Standard_Boolean operator() (Standard_Integer theLeft, Standard_Integer theRight) const
{
- myTolerances.Bind (theTolerance, 1);
- myLargestKey = theTolerance;
- return;
+ return myMapOfCriterion.FindFromIndex(theLeft) > myMapOfCriterion.FindFromIndex(theRight);
}
- myTolerances.Bind (theTolerance, 1);
- myLargestKey = Max (theTolerance, myLargestKey);
- }
+ private:
+ void operator = (const CompareResults&);
+
+ private:
+ const SelectMgr_IndexedDataMapOfOwnerCriterion& myMapOfCriterion;
+ };
+
+ static const Graphic3d_Mat4d SelectMgr_ViewerSelector_THE_IDENTITY_MAT;
}
//=======================================================================
-// function: Decrement
-// purpose : Decrements a counter of the tolerance given, checks if the current tolerance value
-// should be recalculated
+// function : updatePoint3d
+// purpose :
//=======================================================================
-void SelectMgr_ToleranceMap::Decrement (const Standard_Real& theTolerance)
+void SelectMgr_ViewerSelector::updatePoint3d (SelectMgr_SortCriterion& theCriterion,
+ const SelectBasics_PickResult& thePickResult,
+ const Handle(SelectBasics_SensitiveEntity)& theEntity,
+ const gp_GTrsf& theInversedTrsf,
+ const SelectMgr_SelectingVolumeManager& theMgr) const
{
- if (myTolerances.IsBound (theTolerance))
+ if (theMgr.GetActiveSelectionType() != SelectMgr_SelectingVolumeManager::Point)
{
- Standard_Integer& aFreq = myTolerances.ChangeFind (theTolerance);
- aFreq--;
-
- if (Abs (theTolerance - myLargestKey) < Precision::Confusion() && aFreq == 0)
- {
- myLargestKey = 0.0;
- for (NCollection_DataMap<Standard_Real, Standard_Integer>::Iterator anIter (myTolerances); anIter.More(); anIter.Next())
- {
- if (anIter.Value() != 0)
- myLargestKey = Max (myLargestKey, anIter.Key());
- }
- }
+ return;
}
-}
-//=======================================================================
-// function: Tolerance
-// purpose : Returns a current tolerance that must be applied
-//=======================================================================
-Standard_Real SelectMgr_ToleranceMap::Tolerance()
-{
- return myCustomTolerance < 0.0 ? myLargestKey : myCustomTolerance;
-}
+ if (thePickResult.HasPickedPoint())
+ {
+ theCriterion.Point = thePickResult.PickedPoint();
+ }
+ else if (!thePickResult.IsValid())
+ {
+ theCriterion.Point = thePickResult.PickedPoint();
+ return;
+ }
+ else
+ {
+ theCriterion.Point = theMgr.DetectedPoint (theCriterion.Depth);
+ }
-//=======================================================================
-// function: SetCustomTolerance
-// purpose : Sets tolerance to the given one and disables adaptive checks
-//=======================================================================
-void SelectMgr_ToleranceMap::SetCustomTolerance (const Standard_Real theTolerance)
-{
- myCustomTolerance = theTolerance;
-}
+ gp_GTrsf anInvTrsf = theInversedTrsf;
+ if (theCriterion.Entity->HasInitLocation())
+ {
+ anInvTrsf = theCriterion.Entity->InvInitLocation() * anInvTrsf;
+ }
+ if (anInvTrsf.Form() != gp_Identity)
+ {
+ anInvTrsf.Inverted().Transforms (theCriterion.Point.ChangeCoord());
+ }
-//=======================================================================
-// function: ResetDefaults
-// purpose : Unsets a custom tolerance and enables adaptive checks
-//=======================================================================
-void SelectMgr_ToleranceMap::ResetDefaults()
-{
- myCustomTolerance = -1.0;
+ if (mySelectingVolumeMgr.Camera().IsNull())
+ {
+ theCriterion.Tolerance = theEntity->SensitivityFactor() / 33.0;
+ }
+ else if (mySelectingVolumeMgr.Camera()->IsOrthographic())
+ {
+ theCriterion.Tolerance = myCameraScale * theEntity->SensitivityFactor();
+ }
+ else
+ {
+ const Standard_Real aDistFromEye = Abs ((theCriterion.Point.XYZ() - myCameraEye.XYZ()).Dot (myCameraDir.XYZ()));
+ theCriterion.Tolerance = aDistFromEye * myCameraScale * theEntity->SensitivityFactor();
+ }
}
//==================================================
//==================================================
SelectMgr_ViewerSelector::SelectMgr_ViewerSelector():
preferclosest(Standard_True),
-mytolerance(2.0),
myToUpdateTolerance (Standard_True),
+myCameraScale (1.0),
myCurRank (0),
myIsLeftChildQueuedFirst (Standard_False),
myEntityIdx (0)
{
- mySelectableObjects = new SelectMgr_SelectableObjectSet();
+ myEntitySetBuilder = new BVH_BinnedBuilder<Standard_Real, 3, 4> (BVH_Constants_LeafNodeSizeSingle, BVH_Constants_MaxTreeDepth, Standard_True);
}
-
//==================================================
// Function: Activate
// Purpose :
//==================================================
void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSelection)
{
- for (theSelection->Init(); theSelection->More(); theSelection->Next())
+ for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
{
- theSelection->Sensitive()->SetActiveForSelection();
+ aSelEntIter.Value()->SetActiveForSelection();
}
- theSelection->SetSelectionState (SelectMgr_SOS_Activated);
+ if (theSelection->GetSelectionState() != SelectMgr_SOS_Activated)
+ {
+ theSelection->SetSelectionState (SelectMgr_SOS_Activated);
- myTolerances.Add (theSelection->Sensitivity());
- mytolerance = myTolerances.Tolerance();
- myToUpdateTolerance = Standard_True;
+ myTolerances.Add (theSelection->Sensitivity());
+ myToUpdateTolerance = Standard_True;
+ }
}
-
//==================================================
// Function: Deactivate
// Purpose :
//==================================================
void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theSelection)
{
- for (theSelection->Init(); theSelection->More(); theSelection->Next())
+ for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
{
- theSelection->Sensitive()->ResetSelectionActiveStatus();
+ aSelEntIter.Value()->ResetSelectionActiveStatus();
}
- theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
+ if (theSelection->GetSelectionState() == SelectMgr_SOS_Activated)
+ {
+ theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
- myTolerances.Decrement (theSelection->Sensitivity());
- mytolerance = myTolerances.Tolerance();
- myToUpdateTolerance = Standard_True;
+ myTolerances.Decrement (theSelection->Sensitivity());
+ myToUpdateTolerance = Standard_True;
+ }
}
//==================================================
void SelectMgr_ViewerSelector::Clear()
{
mystored.Clear();
- myMapOfDetected.Clear();
}
//=======================================================================
Standard_Boolean SelectMgr_ViewerSelector::isToScaleFrustum (const Handle(SelectBasics_SensitiveEntity)& theEntity)
{
return mySelectingVolumeMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point
- && theEntity->SensitivityFactor() < myTolerances.Tolerance();
+ && sensitivity (theEntity) < myTolerances.Tolerance();
}
//=======================================================================
-// function: scaleAndTransform
-// purpose : Applies given scale and transformation matrices to the default selecting volume manager
+// function: sensitivity
+// purpose : In case if custom tolerance is set, this method will return sum of entity
+// sensitivity and custom tolerance.
//=======================================================================
-SelectMgr_SelectingVolumeManager SelectMgr_ViewerSelector::scaleAndTransform (const Standard_Real theScale,
- const gp_Trsf& theTrsf)
+Standard_Integer SelectMgr_ViewerSelector::sensitivity (const Handle(SelectBasics_SensitiveEntity)& theEntity) const
{
- SelectMgr_SelectingVolumeManager aMgr;
-
- if (theScale > Precision::Angular())
- {
- aMgr = mySelectingVolumeMgr.Scale (theScale);
- }
-
- if (theTrsf.Form() != gp_Identity)
- {
- aMgr = aMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Unknown ?
- mySelectingVolumeMgr.Transform (theTrsf) : aMgr.Transform (theTrsf);
- }
-
- return aMgr;
+ return myTolerances.IsCustomTolSet() ?
+ theEntity->SensitivityFactor() + myTolerances.CustomTolerance() : theEntity->SensitivityFactor();
}
//=======================================================================
// entity theEntity overlaps current selecting volume precisely
//=======================================================================
void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_SensitiveEntity)& theEntity,
- const Standard_Integer theEntityIdx,
+ const gp_GTrsf& theInversedTrsf,
SelectMgr_SelectingVolumeManager& theMgr)
{
- const Handle(SelectMgr_EntityOwner)& anOwner =
- Handle(SelectMgr_EntityOwner)::DownCast (theEntity->OwnerId());
-
- SelectBasics_PickResult aPickResult;
- if (theEntity->Matches (theMgr, aPickResult))
+ Handle(SelectMgr_EntityOwner) anOwner (Handle(SelectMgr_EntityOwner)::DownCast (theEntity->OwnerId()));
+ Handle(SelectMgr_SelectableObject) aSelectable;
+ Standard_Boolean toRestoresViewClipEnabled = Standard_False;
+ if (!anOwner.IsNull())
{
- if (!anOwner.IsNull())
+ aSelectable = anOwner->Selectable();
+ }
+ if (!aSelectable.IsNull())
+ {
+ if (!aSelectable->ClipPlanes().IsNull()
+ && aSelectable->ClipPlanes()->ToOverrideGlobal())
{
- if (HasDepthClipping (anOwner) && theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point)
- {
- Standard_Boolean isClipped = theMgr.IsClipped (anOwner->Selectable()->GetClipPlanes(),
- aPickResult.Depth());
- if (isClipped)
- return;
- }
-
- Standard_Integer aPriority = anOwner->Priority();
-
- SelectMgr_SortCriterion aCriterion (aPriority, aPickResult.Depth(), aPickResult.DistToGeomCenter(), theEntity->SensitivityFactor() / 33, preferclosest);
- if (mystored.Contains (anOwner))
+ theMgr.SetViewClippingEnabled (Standard_False);
+ toRestoresViewClipEnabled = Standard_True;
+ }
+ else if (!aSelectable->TransformPersistence().IsNull())
+ {
+ if (aSelectable->TransformPersistence()->IsZoomOrRotate()
+ && !theMgr.ViewClipping().IsNull())
{
- if (theMgr.GetActiveSelectionType() != 1)
+ // Zoom/rotate persistence object lives in two worlds at the same time.
+ // Global clipping planes can not be trivially applied without being converted
+ // into local space of transformation persistence object.
+ // As more simple alternative - just clip entire object by its anchor point defined in the world space.
+ const Handle(Graphic3d_SequenceOfHClipPlane)& aViewPlanes = theMgr.ViewClipping();
+
+ const gp_Pnt anAnchor = aSelectable->TransformPersistence()->AnchorPoint();
+ for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aViewPlanes); aPlaneIt.More(); aPlaneIt.Next())
{
- SelectMgr_SortCriterion& aPrevCriterion = mystored.ChangeFromKey (anOwner);
- if (aCriterion > aPrevCriterion)
+ const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
+ if (!aPlane->IsOn())
{
- aPrevCriterion = aCriterion;
- myMapOfDetected.ChangeFind (anOwner) = theEntityIdx;
+ continue;
+ }
+
+ const Graphic3d_Vec4d aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0);
+ if (aPlane->ProbePoint (aCheckPnt) == Graphic3d_ClipState_Out)
+ {
+ return;
}
}
}
- else
+
+ theMgr.SetViewClippingEnabled (Standard_False);
+ toRestoresViewClipEnabled = Standard_True;
+ }
+ }
+
+ SelectBasics_PickResult aPickResult;
+ const Standard_Boolean isMatched = theEntity->Matches(theMgr, aPickResult);
+ if (toRestoresViewClipEnabled)
+ {
+ theMgr.SetViewClippingEnabled (Standard_True);
+ }
+
+ if (!isMatched
+ || anOwner.IsNull())
+ {
+ return;
+ }
+
+ if (HasDepthClipping (anOwner)
+ && !aSelectable.IsNull()
+ && theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point)
+ {
+ Standard_Boolean isClipped = mySelectingVolumeMgr.IsClipped (*aSelectable->ClipPlanes(),
+ aPickResult.Depth());
+ if (isClipped)
+ return;
+ }
+
+ SelectMgr_SortCriterion aCriterion;
+ myZLayerOrderMap.Find (!aSelectable.IsNull() ? aSelectable->ZLayer() : Graphic3d_ZLayerId_Default, aCriterion.ZLayerPosition);
+ aCriterion.Entity = theEntity;
+ aCriterion.Priority = anOwner->Priority();
+ aCriterion.Depth = aPickResult.Depth();
+ aCriterion.MinDist = aPickResult.DistToGeomCenter();
+ aCriterion.ToPreferClosest = preferclosest;
+
+ if (SelectMgr_SortCriterion* aPrevCriterion = mystored.ChangeSeek (anOwner))
+ {
+ ++aPrevCriterion->NbOwnerMatches;
+ aCriterion.NbOwnerMatches = aPrevCriterion->NbOwnerMatches;
+ if (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Box)
+ {
+ if (aCriterion > *aPrevCriterion)
{
- mystored.Add (anOwner, aCriterion);
- myMapOfDetected.Bind (anOwner, theEntityIdx);
+ updatePoint3d (aCriterion, aPickResult, theEntity, theInversedTrsf, theMgr);
+ *aPrevCriterion = aCriterion;
}
}
}
+ else
+ {
+ aCriterion.NbOwnerMatches = 1;
+ updatePoint3d (aCriterion, aPickResult, theEntity, theInversedTrsf, theMgr);
+ mystored.Add (anOwner, aCriterion);
+ }
+}
+
+//=======================================================================
+// function: computeFrustum
+// purpose : Internal function that checks if a current selecting frustum
+// needs to be scaled and transformed for the entity and performs
+// necessary calculations
+//=======================================================================
+void SelectMgr_ViewerSelector::computeFrustum (const Handle(SelectBasics_SensitiveEntity)& theEnt,
+ const SelectMgr_SelectingVolumeManager& theMgr,
+ const gp_GTrsf& theInvTrsf,
+ SelectMgr_FrustumCache& theCachedMgrs,
+ SelectMgr_SelectingVolumeManager& theResMgr)
+{
+ Standard_Integer aScale = isToScaleFrustum (theEnt) ? sensitivity (theEnt) : 1;
+ const gp_GTrsf aTrsfMtr = theEnt->HasInitLocation() ? theEnt->InvInitLocation() * theInvTrsf : theInvTrsf;
+ const Standard_Boolean toScale = aScale != 1;
+ const Standard_Boolean toTransform = aTrsfMtr.Form() != gp_Identity;
+ if (toScale && toTransform)
+ {
+ theResMgr = theMgr.ScaleAndTransform (aScale, aTrsfMtr, NULL);
+ }
+ else if (toScale)
+ {
+ if (!theCachedMgrs.IsBound (aScale))
+ {
+ theCachedMgrs.Bind (aScale, theMgr.ScaleAndTransform (aScale, gp_Trsf(), NULL));
+ }
+ theResMgr = theCachedMgrs.Find (aScale);
+ }
+ else if (toTransform)
+ {
+ theResMgr = theMgr.ScaleAndTransform (1, aTrsfMtr, NULL);
+ }
}
//=======================================================================
// between some entity of selectable object theObject and
// current selecting volume
//=======================================================================
-void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_SelectableObject)& theObject)
+void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_SelectableObject)& theObject,
+ const SelectMgr_SelectingVolumeManager& theMgr,
+ const Handle(Graphic3d_Camera)& theCamera,
+ const Graphic3d_Mat4d& theProjectionMat,
+ const Graphic3d_Mat4d& theWorldViewMat,
+ const Standard_Integer theViewportWidth,
+ const Standard_Integer theViewportHeight)
{
- NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
- myMapOfObjectSensitives.ChangeFind (theObject);
-
+ Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
if (anEntitySet->Size() == 0)
+ {
return;
+ }
- const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
+ const opencascade::handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
+ gp_GTrsf aInversedTrsf;
+ if (theObject->HasTransformation() || !theObject->TransformPersistence().IsNull())
+ {
+ if (theObject->TransformPersistence().IsNull())
+ {
+ aInversedTrsf = theObject->InversedTransformation();
+ }
+ else
+ {
+ gp_GTrsf aTPers;
+ Graphic3d_Mat4d aMat = theObject->TransformPersistence()->Compute (theCamera, theProjectionMat, theWorldViewMat, theViewportWidth, theViewportHeight);
+
+ aTPers.SetValue (1, 1, aMat.GetValue (0, 0));
+ aTPers.SetValue (1, 2, aMat.GetValue (0, 1));
+ aTPers.SetValue (1, 3, aMat.GetValue (0, 2));
+ aTPers.SetValue (2, 1, aMat.GetValue (1, 0));
+ aTPers.SetValue (2, 2, aMat.GetValue (1, 1));
+ aTPers.SetValue (2, 3, aMat.GetValue (1, 2));
+ aTPers.SetValue (3, 1, aMat.GetValue (2, 0));
+ aTPers.SetValue (3, 2, aMat.GetValue (2, 1));
+ aTPers.SetValue (3, 3, aMat.GetValue (2, 2));
+ aTPers.SetTranslationPart (gp_XYZ (aMat.GetValue (0, 3), aMat.GetValue (1, 3), aMat.GetValue (2, 3)));
+
+ aInversedTrsf = (aTPers * gp_GTrsf (theObject->Transformation())).Inverted();
+ }
+ }
- SelectMgr_SelectingVolumeManager aMgr = theObject->HasTransformation() ?
- mySelectingVolumeMgr.Transform (theObject->InversedTransformation()) : mySelectingVolumeMgr;
+ SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity
+ ? theMgr.ScaleAndTransform (1, aInversedTrsf, NULL)
+ : theMgr;
- NCollection_DataMap<Handle(Standard_Type), SelectMgr_SelectingVolumeManager> aScaledTrnsfFrustums;
+ SelectMgr_FrustumCache aScaledTrnsfFrustums;
Standard_Integer aNode = 0; // a root node
if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
{
return;
}
- Standard_Integer aStack[32];
+
+ const Standard_Integer aFirstStored = mystored.Extent() + 1;
+
+ Standard_Integer aStack[BVH_Constants_MaxTreeDepth];
Standard_Integer aHead = -1;
for (;;)
{
if (!aSensitivesTree->IsOuter (aNode))
{
- const Standard_Integer aLeftChildIdx = aSensitivesTree->LeftChild (aNode);
- const Standard_Integer aRightChildIdx = aSensitivesTree->RightChild (aNode);
+ const Standard_Integer aLeftChildIdx = aSensitivesTree->Child<0> (aNode);
+ const Standard_Integer aRightChildIdx = aSensitivesTree->Child<1> (aNode);
const Standard_Boolean isLeftChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aLeftChildIdx),
aSensitivesTree->MaxPoint (aLeftChildIdx));
const Standard_Boolean isRightChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aRightChildIdx),
Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode);
for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
{
- const Handle(SelectMgr_SensitiveEntity)& aSensitive =
- anEntitySet->GetSensitiveById (anIdx);
+ const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx);
if (aSensitive->IsActiveForSelection())
{
const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
SelectMgr_SelectingVolumeManager aTmpMgr = aMgr;
- if (isToScaleFrustum (anEnt))
- {
- if (!aScaledTrnsfFrustums.IsBound (anEnt->DynamicType()))
- {
- aScaledTrnsfFrustums.Bind (anEnt->DynamicType(),
- scaleAndTransform (anEnt->SensitivityFactor(), theObject->InversedTransformation()));
- }
-
- aTmpMgr = aScaledTrnsfFrustums.Find (anEnt->DynamicType());
- }
- checkOverlap (anEnt, anIdx, aTmpMgr);
+ computeFrustum (anEnt, theMgr, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
+ checkOverlap (anEnt, aInversedTrsf, aTmpMgr);
}
}
if (aHead < 0)
--aHead;
}
}
+
+ // in case of Box/Polyline selection - keep only Owners having all Entities detected
+ if (mySelectingVolumeMgr.IsOverlapAllowed()
+ || (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Box
+ && theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Polyline))
+ {
+ return;
+ }
+
+ for (Standard_Integer aStoredIter = mystored.Extent(); aStoredIter >= aFirstStored; --aStoredIter)
+ {
+ const SelectMgr_SortCriterion& aCriterion = mystored.FindFromIndex (aStoredIter);
+ const Handle(SelectBasics_EntityOwner)& anOwner = aCriterion.Entity->OwnerId();
+ Standard_Integer aNbOwnerEntities = 0;
+ for (SelectMgr_IndexedMapOfHSensitive::Iterator aSensIter (anEntitySet->Sensitives()); aSensIter.More(); aSensIter.Next())
+ {
+ if (aSensIter.Value()->BaseSensitive()->OwnerId() == anOwner)
+ {
+ if (++aNbOwnerEntities > aCriterion.NbOwnerMatches)
+ {
+ // Remove from index map.
+ // Considering NCollection_IndexedDataMap implementation, the values for lower indexes will not be modified.
+ // Hence, just keep iterating in backward direction.
+ mystored.RemoveFromIndex (aStoredIter);
+ break;
+ }
+ }
+ }
+ }
}
//=======================================================================
void SelectMgr_ViewerSelector::TraverseSensitives()
{
mystored.Clear();
- myMapOfDetected.Clear();
-
- if (mySelectableObjects->Size() == 0)
- return;
- const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& anObjectsTree = mySelectableObjects->BVH();
-
- Standard_Integer aNode = 0;
- if (!mySelectingVolumeMgr.Overlaps (anObjectsTree->MinPoint (0),
- anObjectsTree->MaxPoint (0)))
+ Standard_Integer aWidth;
+ Standard_Integer aHeight;
+ mySelectingVolumeMgr.WindowSize (aWidth, aHeight);
+ mySelectableObjects.UpdateBVH (mySelectingVolumeMgr.Camera(),
+ mySelectingVolumeMgr.ProjectionMatrix(),
+ mySelectingVolumeMgr.WorldViewMatrix(),
+ mySelectingVolumeMgr.WorldViewProjState(),
+ aWidth, aHeight);
+ const Handle(Graphic3d_Camera)& aCamera = mySelectingVolumeMgr.Camera();
+ if (!aCamera.IsNull())
{
- return;
+ myCameraEye = aCamera->Eye().XYZ();
+ myCameraDir = aCamera->Direction().XYZ();
+ myCameraScale = aCamera->IsOrthographic()
+ ? aCamera->Scale()
+ : 2.0 * Tan (aCamera->FOVy() * M_PI / 360.0);
+ const double aPixelSize = Max (1.0 / aWidth, 1.0 / aHeight);
+ myCameraScale *= aPixelSize;
}
- Standard_Integer aStack[32];
- Standard_Integer aHead = -1;
- for (;;)
+
+ for (Standard_Integer aBVHSetIt = 0; aBVHSetIt < SelectMgr_SelectableObjectSet::BVHSubsetNb; ++aBVHSetIt)
{
- if (!anObjectsTree->IsOuter (aNode))
+ SelectMgr_SelectableObjectSet::BVHSubset aBVHSubset =
+ static_cast<SelectMgr_SelectableObjectSet::BVHSubset> (aBVHSetIt);
+
+ if (mySelectableObjects.IsEmpty (aBVHSubset))
{
- const Standard_Integer aLeftChildIdx = anObjectsTree->LeftChild (aNode);
- const Standard_Integer aRightChildIdx = anObjectsTree->RightChild (aNode);
- const Standard_Boolean isLeftChildIn =
- mySelectingVolumeMgr.Overlaps (anObjectsTree->MinPoint (aLeftChildIdx),
- anObjectsTree->MaxPoint (aLeftChildIdx));
- const Standard_Boolean isRightChildIn =
- mySelectingVolumeMgr.Overlaps (anObjectsTree->MinPoint (aRightChildIdx),
- anObjectsTree->MaxPoint (aRightChildIdx));
- if (isLeftChildIn
- && isRightChildIn)
- {
- aNode = aLeftChildIdx;
- ++aHead;
- aStack[aHead] = aRightChildIdx;
- }
- else if (isLeftChildIn
- || isRightChildIn)
+ continue;
+ }
+
+ gp_GTrsf aTFrustum;
+
+ SelectMgr_SelectingVolumeManager aMgr (Standard_False);
+
+ // for 2D space selection transform selecting volumes to perform overap testing
+ // directly in camera's eye space omitting the camera position, which is not
+ // needed there at all
+ if (aBVHSubset == SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent)
+ {
+ const Graphic3d_Mat4d& aMat = mySelectingVolumeMgr.WorldViewMatrix();
+ aTFrustum.SetValue (1, 1, aMat.GetValue (0, 0));
+ aTFrustum.SetValue (1, 2, aMat.GetValue (0, 1));
+ aTFrustum.SetValue (1, 3, aMat.GetValue (0, 2));
+ aTFrustum.SetValue (2, 1, aMat.GetValue (1, 0));
+ aTFrustum.SetValue (2, 2, aMat.GetValue (1, 1));
+ aTFrustum.SetValue (2, 3, aMat.GetValue (1, 2));
+ aTFrustum.SetValue (3, 1, aMat.GetValue (2, 0));
+ aTFrustum.SetValue (3, 2, aMat.GetValue (2, 1));
+ aTFrustum.SetValue (3, 3, aMat.GetValue (2, 2));
+ aTFrustum.SetTranslationPart (gp_XYZ (aMat.GetValue (0, 3), aMat.GetValue (1, 3), aMat.GetValue (2, 3)));
+
+ // define corresponding frustum builder parameters
+ Handle(SelectMgr_FrustumBuilder) aBuilder = new SelectMgr_FrustumBuilder();
+ aBuilder->SetProjectionMatrix (mySelectingVolumeMgr.ProjectionMatrix());
+ aBuilder->SetWorldViewMatrix (SelectMgr_ViewerSelector_THE_IDENTITY_MAT);
+ aBuilder->SetWindowSize (aWidth, aHeight);
+ aMgr = mySelectingVolumeMgr.ScaleAndTransform (1, aTFrustum, aBuilder);
+ }
+ else
+ {
+ aMgr = mySelectingVolumeMgr;
+ }
+
+ const Graphic3d_Mat4d& aProjectionMat = mySelectingVolumeMgr.ProjectionMatrix();
+ const Graphic3d_Mat4d& aWorldViewMat = aBVHSubset != SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent
+ ? mySelectingVolumeMgr.WorldViewMatrix()
+ : SelectMgr_ViewerSelector_THE_IDENTITY_MAT;
+
+ const opencascade::handle<BVH_Tree<Standard_Real, 3> >& aBVHTree = mySelectableObjects.BVH (aBVHSubset);
+
+ Standard_Integer aNode = 0;
+ if (!aMgr.Overlaps (aBVHTree->MinPoint (0), aBVHTree->MaxPoint (0)))
+ {
+ continue;
+ }
+
+ Standard_Integer aStack[BVH_Constants_MaxTreeDepth];
+ Standard_Integer aHead = -1;
+ for (;;)
+ {
+ if (!aBVHTree->IsOuter (aNode))
{
- aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
+ const Standard_Integer aLeftChildIdx = aBVHTree->Child<0> (aNode);
+ const Standard_Integer aRightChildIdx = aBVHTree->Child<1> (aNode);
+ const Standard_Boolean isLeftChildIn =
+ aMgr.Overlaps (aBVHTree->MinPoint (aLeftChildIdx), aBVHTree->MaxPoint (aLeftChildIdx));
+ const Standard_Boolean isRightChildIn =
+ aMgr.Overlaps (aBVHTree->MinPoint (aRightChildIdx), aBVHTree->MaxPoint (aRightChildIdx));
+ if (isLeftChildIn
+ && isRightChildIn)
+ {
+ aNode = aLeftChildIdx;
+ ++aHead;
+ aStack[aHead] = aRightChildIdx;
+ }
+ else if (isLeftChildIn
+ || isRightChildIn)
+ {
+ aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
+ }
+ else
+ {
+ if (aHead < 0)
+ {
+ break;
+ }
+
+ aNode = aStack[aHead];
+ --aHead;
+ }
}
else
{
+ Standard_Integer aStartIdx = aBVHTree->BegPrimitive (aNode);
+ Standard_Integer anEndIdx = aBVHTree->EndPrimitive (aNode);
+ for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
+ {
+ const Handle(SelectMgr_SelectableObject)& aSelectableObject =
+ mySelectableObjects.GetObjectById (aBVHSubset, anIdx);
+
+ traverseObject (aSelectableObject, aMgr, aCamera, aProjectionMat, aWorldViewMat, aWidth, aHeight);
+ }
if (aHead < 0)
{
break;
--aHead;
}
}
- else
- {
- Standard_Integer aStartIdx = anObjectsTree->BegPrimitive (aNode);
- Standard_Integer anEndIdx = anObjectsTree->EndPrimitive (aNode);
- for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
- {
- traverseObject (mySelectableObjects->GetObjectById (anIdx));
- }
- if (aHead < 0)
- {
- break;
- }
-
- aNode = aStack[aHead];
- --aHead;
- }
}
SortResult();
}
+//==================================================
+// Function: ClearPicked
+// Purpose :
+//==================================================
+void SelectMgr_ViewerSelector::ClearPicked()
+{
+ mystored.Clear();
+}
+
//==================================================
// Function: Picked
// Purpose :
{
Standard_Integer RankInMap = myIndexes->Value (myCurRank);
const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap);
- Handle(SelectMgr_EntityOwner) Ownr = *((Handle(SelectMgr_EntityOwner)*) &toto);
+ Handle(SelectMgr_EntityOwner) Ownr = Handle(SelectMgr_EntityOwner)::DownCast (toto);
return Ownr;
}
-
-
//=======================================================================
-//function : More
+//function : Picked
//purpose :
//=======================================================================
-Standard_Boolean SelectMgr_ViewerSelector::More()
-{
- if(mystored.Extent()==0) return Standard_False;
- if(myCurRank==0) return Standard_False;
- return myCurRank <= myIndexes->Length();
-}
-
-//==================================================
-// Function: OnePicked
-// Purpose : only the best one is chosen
-// depend on priority and mindist...
-//==================================================
-
-Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector
-::OnePicked()
+Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked (const Standard_Integer theRank) const
{
-
- Init();
- if(More()){
- Standard_Integer RankInMap = myIndexes->Value (myIndexes->Lower());
- const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap);
- Handle(SelectMgr_EntityOwner) Ownr = *((Handle(SelectMgr_EntityOwner)*) &toto);
- return Ownr;
+ Handle(SelectMgr_EntityOwner) anOwner;
+ if (theRank < 1 || theRank > NbPicked())
+ {
+ return anOwner;
}
- Handle (SelectMgr_EntityOwner) NullObj; //returns a null Handle if there was not successfull pick...
- return NullObj;
+ const Standard_Integer anOwnerIdx = myIndexes->Value (theRank);
+ const Handle(SelectBasics_EntityOwner)& aStoredOwner = mystored.FindKey (anOwnerIdx);
+ anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aStoredOwner);
+ return anOwner;
}
-
//=======================================================================
-//function : NbPicked
+//function : PickedData
//purpose :
//=======================================================================
-
-Standard_Integer SelectMgr_ViewerSelector::NbPicked() const
+const SelectMgr_SortCriterion& SelectMgr_ViewerSelector::PickedData(const Standard_Integer theRank) const
{
- return mystored.Extent();
-}
-//=======================================================================
-//function : Picked
-//purpose :
-//=======================================================================
-Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked(const Standard_Integer aRank) const
-{
-
- Handle(SelectMgr_EntityOwner) anOwner;
- if (aRank < 1 || aRank > NbPicked())
- return anOwner;
- Standard_Integer anOwnerIdx = myIndexes->Value (aRank);
-
-
- const Handle(SelectBasics_EntityOwner)& aStoredOwner = mystored.FindKey (anOwnerIdx);
- anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aStoredOwner);
- return anOwner;
+ Standard_OutOfRange_Raise_if (theRank < 1 || theRank > NbPicked(), "SelectMgr_ViewerSelector::PickedData() out of range index");
+ const Standard_Integer anOwnerIdx = myIndexes->Value (theRank);
+ return mystored.FindFromIndex (anOwnerIdx);
}
//===================================================
//
//==================================================
+//==================================================
+// Function: SetEntitySetBuilder
+// Purpose :
+//==================================================
+void SelectMgr_ViewerSelector::SetEntitySetBuilder (const Handle(Select3D_BVHBuilder3d)& theBuilder)
+{
+ myEntitySetBuilder = theBuilder;
+ for (SelectMgr_MapOfObjectSensitives::Iterator aSetIter (myMapOfObjectSensitives); aSetIter.More(); aSetIter.Next())
+ {
+ aSetIter.ChangeValue()->SetBuilder (myEntitySetBuilder);
+ }
+}
+
//==================================================
// Function: Contains
// Purpose :
//==================================================
Standard_Boolean SelectMgr_ViewerSelector::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
{
- return mySelectableObjects->Contains (theObject);
+ return mySelectableObjects.Contains (theObject);
}
//==================================================
TColStd_ListOfInteger& theModeList,
const SelectMgr_StateOfSelection theWantedState) const
{
- Standard_Boolean hasActivatedStates = mySelectableObjects->Contains (theSelectableObject);
- for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
+ Standard_Boolean hasActivatedStates = Contains (theSelectableObject);
+ for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theSelectableObject->Selections()); aSelIter.More(); aSelIter.Next())
{
- if (theWantedState == SelectMgr_SOS_Any)
- {
- theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
- }
- else if (theWantedState == theSelectableObject->CurrentSelection()->GetSelectionState())
- {
- theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
- }
+ if (theWantedState == SelectMgr_SOS_Any)
+ {
+ theModeList.Append (aSelIter.Value()->Mode());
+ }
+ else if (theWantedState == aSelIter.Value()->GetSelectionState())
+ {
+ theModeList.Append (aSelIter.Value()->Mode());
+ }
}
return hasActivatedStates;
Standard_Boolean SelectMgr_ViewerSelector::IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
const Standard_Integer theMode) const
{
- if (!mySelectableObjects->Contains (theSelectableObject))
+ if (!Contains (theSelectableObject))
return Standard_False;
- for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
- {
- if (theMode == theSelectableObject->CurrentSelection()->Mode())
- {
- return theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated;
- }
- }
-
- return Standard_False;
+ const Handle(SelectMgr_Selection)& aSel = theSelectableObject->Selection (theMode);
+ return !aSel.IsNull()
+ && aSel->GetSelectionState() == SelectMgr_SOS_Activated;
}
//==================================================
Standard_Boolean SelectMgr_ViewerSelector::IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
const Standard_Integer theMode) const
{
- if (!mySelectableObjects->Contains (theSelectableObject))
+ if (!Contains (theSelectableObject))
return Standard_False;
- for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
- {
- if (theMode == theSelectableObject->CurrentSelection()->Mode())
- {
- return theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown;
- }
- }
-
- return Standard_False;
+ const Handle(SelectMgr_Selection)& aSel = theSelectableObject->Selection (theMode);
+ return !aSel.IsNull()
+ && aSel->GetSelectionState() != SelectMgr_SOS_Unknown;
}
TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const
{
TCollection_AsciiString aStatus ("Status Object :\n\t");
-
- for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
+ for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theSelectableObject->Selections()); aSelIter.More(); aSelIter.Next())
{
- if (theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown)
+ if (aSelIter.Value()->GetSelectionState() != SelectMgr_SOS_Unknown)
{
- aStatus = aStatus + "Mode " +
- TCollection_AsciiString (theSelectableObject->CurrentSelection()->Mode()) +
- " present - ";
- if (theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated)
- {
- aStatus = aStatus + " Active \n\t";
- }
- else
- {
- aStatus = aStatus + " Inactive \n\t";
- }
+ aStatus = aStatus + "Mode " + TCollection_AsciiString (aSelIter.Value()->Mode()) + " present - "
+ + (aSelIter.Value()->GetSelectionState() == SelectMgr_SOS_Activated ? " Active \n\t" : " Inactive \n\t");
}
}
- if (mySelectableObjects->Contains (theSelectableObject))
+ if (!Contains (theSelectableObject))
{
aStatus = aStatus + "Not Present in the selector\n\n";
}
if(myIndexes.IsNull() || anExtent != myIndexes->Length())
myIndexes = new TColStd_HArray1OfInteger (1, anExtent);
- // to work faster...
- TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1();
-
- // indices from 1 to N are loaded
- Standard_Integer I ;
- for (I=1; I <= anExtent; I++)
- thearr(I)=I;
-
- SortTools_QuickSortOfInteger::Sort (thearr,
- SelectMgr_CompareResults(mystored));
+ TColStd_Array1OfInteger& anIndexArray = myIndexes->ChangeArray1();
+ for (Standard_Integer anIndexIter = 1; anIndexIter <= anExtent; ++anIndexIter)
+ {
+ anIndexArray.SetValue (anIndexIter, anIndexIter);
+ }
+ std::sort (anIndexArray.begin(), anIndexArray.end(), CompareResults (mystored));
}
//=======================================================================
{
if (!myMapOfObjectSensitives.IsBound (theObject))
{
- mySelectableObjects->Append (theObject);
- NCollection_Handle<SelectMgr_SensitiveEntitySet> anEntitySet = new SelectMgr_SensitiveEntitySet();
+ mySelectableObjects.Append (theObject);
+ Handle(SelectMgr_SensitiveEntitySet) anEntitySet = new SelectMgr_SensitiveEntitySet (myEntitySetBuilder);
myMapOfObjectSensitives.Bind (theObject, anEntitySet);
}
}
void SelectMgr_ViewerSelector::AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject,
const Handle(SelectMgr_Selection)& theSelection)
{
- if (myMapOfObjectSensitives.IsBound (theObject))
+ if (Handle(SelectMgr_SensitiveEntitySet)* anEntitySet = myMapOfObjectSensitives.ChangeSeek (theObject))
{
- NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
- myMapOfObjectSensitives.ChangeFind (theObject);
- anEntitySet->Append (theSelection);
- anEntitySet->BVH();
+ (*anEntitySet)->Append (theSelection);
+ (*anEntitySet)->BVH();
}
else
{
}
}
+//=======================================================================
+// function : MoveSelectableObject
+// purpose :
+//=======================================================================
+void SelectMgr_ViewerSelector::MoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
+{
+ mySelectableObjects.ChangeSubset (theObject);
+}
+
//=======================================================================
// function : RemoveSelectableObject
// purpose : Removes selectable object from map of selectable ones
//=======================================================================
void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
{
- if (myMapOfObjectSensitives.IsBound (theObject))
+ Handle(SelectMgr_SelectableObject) anObj = theObject;
+ if (myMapOfObjectSensitives.UnBind (theObject))
{
- myMapOfObjectSensitives.UnBind (theObject);
- mySelectableObjects->Remove (theObject);
+ mySelectableObjects.Remove (theObject);
}
}
void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject,
const Handle(SelectMgr_Selection)& theSelection)
{
- if (myMapOfObjectSensitives.IsBound (theObject))
+ if (Handle(SelectMgr_SensitiveEntitySet)* anEntitySet = myMapOfObjectSensitives.ChangeSeek (theObject))
{
- NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
- myMapOfObjectSensitives.ChangeFind (theObject);
- anEntitySet->Remove (theSelection);
+ (*anEntitySet)->Remove (theSelection);
}
}
//=======================================================================
void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce)
{
- mySelectableObjects->MarkDirty();
+ mySelectableObjects.MarkDirty();
if (theIsForce)
{
- mySelectableObjects->BVH();
+ Standard_Integer aViewportWidth, aViewportHeight;
+ mySelectingVolumeMgr.WindowSize (aViewportWidth, aViewportHeight);
+
+ Standard_Integer aWidth;
+ Standard_Integer aHeight;
+ mySelectingVolumeMgr.WindowSize (aWidth, aHeight);
+ mySelectableObjects.UpdateBVH (mySelectingVolumeMgr.Camera(),
+ mySelectingVolumeMgr.ProjectionMatrix(),
+ mySelectingVolumeMgr.WorldViewMatrix(),
+ mySelectingVolumeMgr.WorldViewProjState(),
+ aWidth, aHeight);
}
}
void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject,
const Standard_Boolean theIsForce)
{
- if (!mySelectableObjects->Contains (theObject))
+ if (!Contains (theObject))
return;
- NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
+ Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
anEntitySet->MarkDirty();
if (theIsForce)
// purpose : Marks all added sensitive entities of all objects as
// non-selectable
//=======================================================================
-void SelectMgr_ViewerSelector::resetSelectionActivationStatus()
+void SelectMgr_ViewerSelector::ResetSelectionActivationStatus()
{
- SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives);
- for ( ; aSensitivesIter.More(); aSensitivesIter.Next())
+ for (SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives); aSensitivesIter.More(); aSensitivesIter.Next())
{
- NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
- aSensitivesIter.ChangeValue();
- Standard_Integer anEntitiesNb = anEntitySet->Size();
+ Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = aSensitivesIter.ChangeValue();
+ const Standard_Integer anEntitiesNb = anEntitySet->Size();
for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
{
anEntitySet->GetSensitiveById (anIdx)->ResetSelectionActiveStatus();
//=======================================================================
const Handle(SelectBasics_SensitiveEntity)& SelectMgr_ViewerSelector::DetectedEntity() const
{
- const Handle(SelectMgr_EntityOwner)& anOwner = myDetectedIter.Key();
- const Handle(SelectMgr_SelectableObject)& anObject = anOwner->Selectable();
- const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
- myMapOfObjectSensitives.Find (anObject);
-
- return anEntitySet->GetSensitiveById (myDetectedIter.Value())->BaseSensitive();
+ const Standard_Integer aRankInMap = myIndexes->Value(myCurRank);
+ return mystored.FindFromIndex (aRankInMap).Entity;
}
//=======================================================================
{
for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next())
{
- const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = anIter.Value();
- Standard_Integer anEntitiesNb = anEntitySet->Size();
+ const Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = anIter.Value();
+ const Standard_Integer anEntitiesNb = anEntitySet->Size();
for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
{
- if (anEntitySet->GetSensitiveById (anIdx)->IsActiveForSelection())
+ const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx);
+ if (aSensitive->IsActiveForSelection())
{
- theOwners.Append (anEntitySet->GetSensitiveById (anIdx)->BaseSensitive()->OwnerId());
+ theOwners.Append (aSensitive->BaseSensitive()->OwnerId());
}
}
}
}
+
+//=======================================================================
+//function : AllowOverlapDetection
+//purpose : Sets the detection type: if theIsToAllow is false,
+// only fully included sensitives will be detected, otherwise
+// the algorithm will mark both included and overlapped entities
+// as matched
+//=======================================================================
+void SelectMgr_ViewerSelector::AllowOverlapDetection (const Standard_Boolean theIsToAllow)
+{
+ mySelectingVolumeMgr.AllowOverlapDetection (theIsToAllow);
+}