// AGV OCT/23/03 : Optimize the method SortResult() (OCC4201)
#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>
-IMPLEMENT_STANDARD_HANDLE (SelectMgr_ViewerSelector, MMgt_TShared)
-IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_ViewerSelector, MMgt_TShared)
+#include <algorithm>
-static Standard_Boolean SelectDebugModeOnVS()
-{
- static Standard_Integer isDebugMode( -1 );
- if ( isDebugMode < 0 ) {
- isDebugMode = 1;
- OSD_Environment selectdb("SELDEBUGMODE");
- if ( selectdb.Value().IsEmpty() )
- isDebugMode = 0;
- }
- return ( isDebugMode != 0 );
+IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_ViewerSelector,MMgt_TShared)
+
+namespace {
+ // Comparison operator for sorting selection results
+ class CompareResults
+ {
+ public:
+
+ CompareResults (const SelectMgr_IndexedDataMapOfOwnerCriterion& aMapOfCriterion)
+ : myMapOfCriterion (aMapOfCriterion)
+ {
+ }
+
+ Standard_Boolean operator() (Standard_Integer theLeft, Standard_Integer theRight) const
+ {
+ return myMapOfCriterion.FindFromIndex(theLeft) > myMapOfCriterion.FindFromIndex(theRight);
+ }
+
+ private:
+ void operator = (const CompareResults&);
+
+ private:
+ const SelectMgr_IndexedDataMapOfOwnerCriterion& myMapOfCriterion;
+ };
}
+//=======================================================================
+// function: SelectMgr_ToleranceMap
+// purpose : Sets tolerance values to -1.0
+//=======================================================================
SelectMgr_ToleranceMap::SelectMgr_ToleranceMap()
{
myLargestKey = -1;
+ myCustomTolerance = -1;
}
+//=======================================================================
+// function: ~SelectMgr_ToleranceMap
+// purpose :
+//=======================================================================
SelectMgr_ToleranceMap::~SelectMgr_ToleranceMap()
{
myTolerances.Clear();
}
-void SelectMgr_ToleranceMap::Add (const Standard_Real& theTolerance)
+//=======================================================================
+// 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_Integer& theTolerance)
{
if (myTolerances.IsBound (theTolerance))
{
Standard_Integer& aFreq = myTolerances.ChangeFind (theTolerance);
aFreq++;
- if (theTolerance == myLargestKey)
- return;
-
- Standard_Integer aMaxFreq = myTolerances.Find (myLargestKey);
- if (aFreq >= aMaxFreq)
- {
- myLargestKey = aFreq == aMaxFreq ? Max (myLargestKey, theTolerance) : theTolerance;
- }
+ if (aFreq == 1 && theTolerance != myLargestKey)
+ myLargestKey = Max (theTolerance, myLargestKey);
}
else
{
}
myTolerances.Bind (theTolerance, 1);
- Standard_Integer aMaxFreq = myTolerances.Find (myLargestKey);
- if (aMaxFreq <= 1)
- {
- myLargestKey = aMaxFreq == 1 ? Max (myLargestKey, theTolerance) : theTolerance;
- }
+ myLargestKey = Max (theTolerance, myLargestKey);
}
}
-void SelectMgr_ToleranceMap::Decrement (const Standard_Real& theTolerance)
+//=======================================================================
+// function: Decrement
+// purpose : Decrements a counter of the tolerance given, checks if the current tolerance value
+// should be recalculated
+//=======================================================================
+void SelectMgr_ToleranceMap::Decrement (const Standard_Integer& theTolerance)
{
if (myTolerances.IsBound (theTolerance))
{
Standard_Integer& aFreq = myTolerances.ChangeFind (theTolerance);
aFreq--;
- if (theTolerance == myLargestKey)
+ if (Abs (theTolerance - myLargestKey) < Precision::Confusion() && aFreq == 0)
{
- Standard_Integer aMaxFreq = aFreq;
- for (NCollection_DataMap<Standard_Real, Standard_Integer>::Iterator anIter (myTolerances); anIter.More(); anIter.Next())
+ myLargestKey = 0;
+ for (NCollection_DataMap<Standard_Integer, Standard_Integer>::Iterator anIter (myTolerances); anIter.More(); anIter.Next())
{
- if (aMaxFreq <= anIter.Value() && myLargestKey != anIter.Key())
- {
- aMaxFreq = anIter.Value();
- myLargestKey = anIter.Key();
- }
+ if (anIter.Value() != 0)
+ myLargestKey = Max (myLargestKey, anIter.Key());
}
}
}
}
-const Standard_Real SelectMgr_ToleranceMap::Largest()
-{
- return myLargestKey;
-}
-
//==================================================
// Function: Initialize
// Purpose :
//==================================================
SelectMgr_ViewerSelector::SelectMgr_ViewerSelector():
preferclosest(Standard_True),
-mytolerance(2.0),
myToUpdateTolerance (Standard_True),
myCurRank (0),
myIsLeftChildQueuedFirst (Standard_False),
myEntityIdx (0)
{
- mySelectableObjects = new SelectMgr_SelectableObjectSet();
}
-
//==================================================
// Function: Activate
// Purpose :
theSelection->SetSelectionState (SelectMgr_SOS_Activated);
myTolerances.Add (theSelection->Sensitivity());
- mytolerance = myTolerances.Largest();
myToUpdateTolerance = Standard_True;
}
-
//==================================================
// Function: Deactivate
// Purpose :
theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
myTolerances.Decrement (theSelection->Sensitivity());
- mytolerance = myTolerances.Largest();
myToUpdateTolerance = Standard_True;
}
myMapOfDetected.Clear();
}
+//=======================================================================
+// function: isToScaleFrustum
+// purpose : Checks if the entity given requires to scale current selecting frustum
+//=======================================================================
+Standard_Boolean SelectMgr_ViewerSelector::isToScaleFrustum (const Handle(SelectBasics_SensitiveEntity)& theEntity)
+{
+ return mySelectingVolumeMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point
+ && sensitivity (theEntity) < myTolerances.Tolerance();
+}
+
+//=======================================================================
+// function: sensitivity
+// purpose : In case if custom tolerance is set, this method will return sum of entity
+// sensitivity and custom tolerance.
+//=======================================================================
+Standard_Integer SelectMgr_ViewerSelector::sensitivity (const Handle(SelectBasics_SensitiveEntity)& theEntity) const
+{
+ return myTolerances.IsCustomTolSet() ?
+ theEntity->SensitivityFactor() + myTolerances.CustomTolerance() : theEntity->SensitivityFactor();
+}
+
//=======================================================================
// function: checkOverlap
// purpose : Internal function that checks if a particular sensitive
const Standard_Integer theEntityIdx,
SelectMgr_SelectingVolumeManager& theMgr)
{
- const Handle(SelectMgr_EntityOwner)& anOwner =
- Handle(SelectMgr_EntityOwner)::DownCast (theEntity->OwnerId());
+ Handle(SelectMgr_EntityOwner) anOwner (Handle(SelectMgr_EntityOwner)::DownCast (theEntity->OwnerId()));
SelectBasics_PickResult aPickResult;
if (theEntity->Matches (theMgr, aPickResult))
{
if (!anOwner.IsNull())
{
- Standard_Boolean isPointSelection =
- theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point;
- if (HasDepthClipping (anOwner) && isPointSelection)
+ if (HasDepthClipping (anOwner) && theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point)
{
- Standard_Boolean isClipped = theMgr.IsClipped (anOwner->Selectable()->GetClipPlanes(),
- aPickResult.Depth());
+ Standard_Boolean isClipped = mySelectingVolumeMgr.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);
+ SelectMgr_SortCriterion aCriterion (aPriority, aPickResult.Depth(), aPickResult.DistToGeomCenter(), theEntity->SensitivityFactor() / 33.0, preferclosest);
if (mystored.Contains (anOwner))
{
if (theMgr.GetActiveSelectionType() != 1)
}
}
+//=======================================================================
+// 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 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 = mySelectingVolumeMgr.ScaleAndTransform (aScale, aTrsfMtr);
+ }
+ else if (toScale)
+ {
+ if (!theCachedMgrs.IsBound (aScale))
+ {
+ theCachedMgrs.Bind (aScale, mySelectingVolumeMgr.ScaleAndTransform (aScale, gp_Trsf()));
+ }
+ theResMgr = theCachedMgrs.Find (aScale);
+ }
+ else if (toTransform)
+ {
+ theResMgr = mySelectingVolumeMgr.ScaleAndTransform (1, aTrsfMtr);
+ }
+}
+
//=======================================================================
// function: traverseObject
// purpose : Internal function that checks if there is possible overlap
const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
- SelectMgr_SelectingVolumeManager aMgr = theObject->HasTransformation() ?
- mySelectingVolumeMgr.Transform (theObject->InversedTransformation()) : mySelectingVolumeMgr;
+ gp_GTrsf aInversedTrsf;
+
+ if (theObject->HasTransformation() || theObject->TransformPersistence().Flags)
+ {
+ if (!theObject->TransformPersistence().Flags)
+ {
+ aInversedTrsf = theObject->InversedTransformation();
+ }
+ else
+ {
+ const Graphic3d_Mat4d& aProjection = mySelectingVolumeMgr.ProjectionMatrix();
+ const Graphic3d_Mat4d& aWorldView = mySelectingVolumeMgr.WorldViewMatrix();
+
+ Standard_Integer aViewportWidth;
+ Standard_Integer aViewportHeight;
+ mySelectingVolumeMgr.WindowSize (aViewportWidth, aViewportHeight);
+
+ gp_GTrsf aTPers;
+ Graphic3d_Mat4d aMat = theObject->TransformPersistence().Compute (aProjection, aWorldView, aViewportWidth, aViewportHeight);
+ 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 = aInversedTrsf.Form() != gp_Identity
+ ? mySelectingVolumeMgr.ScaleAndTransform (1, aInversedTrsf)
+ : mySelectingVolumeMgr;
+
+ SelectMgr_FrustumCache aScaledTrnsfFrustums;
Standard_Integer aNode = 0; // a root node
if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
{
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 SelectMgr_HSensitiveEntity& aSensitive =
+ const Handle(SelectMgr_SensitiveEntity)& aSensitive =
anEntitySet->GetSensitiveById (anIdx);
if (aSensitive->IsActiveForSelection())
{
- checkOverlap (aSensitive->BaseSensitive(), anIdx, aMgr);
+ const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
+ SelectMgr_SelectingVolumeManager aTmpMgr = aMgr;
+ computeFrustum (anEnt, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
+ checkOverlap (anEnt, anIdx, aTmpMgr);
}
}
if (aHead < 0)
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)))
+ NCollection_Handle<BVH_Tree<Standard_Real, 3> > aBVHTree;
+ for (Standard_Integer aBVHTreeIdx = 0; aBVHTreeIdx < 2; ++aBVHTreeIdx)
{
- return;
- }
- Standard_Integer aStack[32];
- Standard_Integer aHead = -1;
- for (;;)
- {
- if (!anObjectsTree->IsOuter (aNode))
+ const Standard_Boolean isTrsfPers = aBVHTreeIdx == 1;
+ if (isTrsfPers)
{
- 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)
+ if (mySelectableObjectsTrsfPers.Size() == 0)
{
- aNode = aLeftChildIdx;
- ++aHead;
- aStack[aHead] = aRightChildIdx;
+ continue;
}
- else if (isLeftChildIn
- || isRightChildIn)
+ const Graphic3d_Mat4d& aProjection = mySelectingVolumeMgr.ProjectionMatrix();
+ const Graphic3d_Mat4d& aWorldView = mySelectingVolumeMgr.WorldViewMatrix();
+ const Graphic3d_WorldViewProjState& aWVPState = mySelectingVolumeMgr.WorldViewProjState();
+ Standard_Integer aViewportWidth;
+ Standard_Integer aViewportHeight;
+ mySelectingVolumeMgr.WindowSize (aViewportWidth, aViewportHeight);
+ aBVHTree = mySelectableObjectsTrsfPers.BVH (aProjection, aWorldView, aViewportWidth, aViewportHeight, aWVPState);
+ }
+ else
+ {
+ if (mySelectableObjects.Size() == 0)
{
- aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
+ continue;
+ }
+ aBVHTree = mySelectableObjects.BVH();
+ }
+
+ Standard_Integer aNode = 0;
+ if (!mySelectingVolumeMgr.Overlaps (aBVHTree->MinPoint (0),
+ aBVHTree->MaxPoint (0)))
+ {
+ continue;
+ }
+
+ Standard_Integer aStack[32];
+ Standard_Integer aHead = -1;
+ for (;;)
+ {
+ if (!aBVHTree->IsOuter (aNode))
+ {
+ const Standard_Integer aLeftChildIdx = aBVHTree->Child<0> (aNode);
+ const Standard_Integer aRightChildIdx = aBVHTree->Child<1> (aNode);
+ const Standard_Boolean isLeftChildIn =
+ mySelectingVolumeMgr.Overlaps (aBVHTree->MinPoint (aLeftChildIdx),
+ aBVHTree->MaxPoint (aLeftChildIdx));
+ const Standard_Boolean isRightChildIn =
+ mySelectingVolumeMgr.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)
+ {
+ Handle(SelectMgr_SelectableObject) aSelectableObject =
+ isTrsfPers ? mySelectableObjectsTrsfPers.GetObjectById (anIdx)
+ : mySelectableObjects.GetObjectById (anIdx);
+
+ traverseObject (aSelectableObject);
+ }
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();
-
- if (SelectDebugModeOnVS())
- {
- cout<<"\tSelectMgr_VS:: Resultat du move"<<endl;
- cout<<"\tNb Detectes :"<<mystored.Extent()<<endl;
-
- for(Standard_Integer i=1; i<=mystored.Extent(); i++)
- {
- const SelectMgr_SortCriterion& Crit = mystored (myIndexes->Value(i));
- cout << "\t" << i << " - Prior" << Crit.Priority()
- << " - prof :" << Crit.Depth()
- << " - Dist. :" << Crit.MinDist() << endl;
- }
- }
}
//==================================================
{
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;
}
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);
+ Handle(SelectMgr_EntityOwner) Ownr = Handle(SelectMgr_EntityOwner)::DownCast (toto);
return Ownr;
}
//==================================================
Standard_Boolean SelectMgr_ViewerSelector::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
{
- return mySelectableObjects->Contains (theObject);
+ return mySelectableObjects.Contains (theObject)
+ || mySelectableObjectsTrsfPers.Contains (theObject);
}
//==================================================
TColStd_ListOfInteger& theModeList,
const SelectMgr_StateOfSelection theWantedState) const
{
- Standard_Boolean hasActivatedStates = mySelectableObjects->Contains (theSelectableObject);
+ Standard_Boolean hasActivatedStates = Contains (theSelectableObject);
for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
{
if (theWantedState == SelectMgr_SOS_Any)
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())
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 (mySelectableObjects->Contains (theSelectableObject))
+ if (!Contains (theSelectableObject))
{
aStatus = aStatus + "Not Present in the selector\n\n";
}
for (I=1; I <= anExtent; I++)
thearr(I)=I;
- SortTools_QuickSortOfInteger::Sort (thearr,
- SelectMgr_CompareResults(mystored));
+ std::sort (thearr.begin(), thearr.end(), CompareResults (mystored));
+
}
//=======================================================================
{
if (!myMapOfObjectSensitives.IsBound (theObject))
{
- mySelectableObjects->Append (theObject);
+ if (!theObject->TransformPersistence().Flags)
+ {
+ mySelectableObjects.Append (theObject);
+ }
+ else
+ {
+ mySelectableObjectsTrsfPers.Append (theObject);
+ }
+
NCollection_Handle<SelectMgr_SensitiveEntitySet> anEntitySet = new SelectMgr_SensitiveEntitySet();
myMapOfObjectSensitives.Bind (theObject, anEntitySet);
}
}
}
+//=======================================================================
+// function : MoveSelectableObject
+// purpose :
+//=======================================================================
+void SelectMgr_ViewerSelector::MoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
+{
+ if (!mySelectableObjects.Remove (theObject))
+ {
+ mySelectableObjectsTrsfPers.Remove (theObject);
+ }
+
+ if (!theObject->TransformPersistence().Flags)
+ {
+ mySelectableObjects.Append (theObject);
+ }
+ else
+ {
+ mySelectableObjectsTrsfPers.Append (theObject);
+ }
+}
+
//=======================================================================
// function : RemoveSelectableObject
// purpose : Removes selectable object from map of selectable ones
{
if (myMapOfObjectSensitives.IsBound (theObject))
{
+ if (!mySelectableObjects.Remove (theObject))
+ {
+ mySelectableObjectsTrsfPers.Remove (theObject);
+ }
myMapOfObjectSensitives.UnBind (theObject);
- mySelectableObjects->Remove (theObject);
}
}
//=======================================================================
void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce)
{
- mySelectableObjects->MarkDirty();
+ mySelectableObjects.MarkDirty();
+ mySelectableObjectsTrsfPers.MarkDirty();
if (theIsForce)
{
- mySelectableObjects->BVH();
+ const Graphic3d_Mat4d& aProjection = mySelectingVolumeMgr.ProjectionMatrix();
+ const Graphic3d_Mat4d& aWorldView = mySelectingVolumeMgr.WorldViewMatrix();
+ const Graphic3d_WorldViewProjState& aWVPState = mySelectingVolumeMgr.WorldViewProjState();
+ Standard_Integer aViewportWidth;
+ Standard_Integer aViewportHeight;
+ mySelectingVolumeMgr.WindowSize (aViewportWidth, aViewportHeight);
+
+ mySelectableObjects.BVH();
+ mySelectableObjectsTrsfPers.BVH (aProjection, aWorldView, aViewportWidth, aViewportHeight, aWVPState);
}
}
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);
// 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())
// function : ActiveOwners
// purpose : Returns the list of active entity owners
//=======================================================================
-NCollection_List<Handle(SelectBasics_EntityOwner)> SelectMgr_ViewerSelector::ActiveOwners() const
+void SelectMgr_ViewerSelector::ActiveOwners (NCollection_List<Handle(SelectBasics_EntityOwner)>& theOwners) const
{
- NCollection_List<Handle(SelectBasics_EntityOwner)> anActiveOwners;
for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next())
{
const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = anIter.Value();
{
if (anEntitySet->GetSensitiveById (anIdx)->IsActiveForSelection())
{
- anActiveOwners.Append (anEntitySet->GetSensitiveById (anIdx)->BaseSensitive()->OwnerId());
+ theOwners.Append (anEntitySet->GetSensitiveById (anIdx)->BaseSensitive()->OwnerId());
}
}
}
+}
- return anActiveOwners;
+//=======================================================================
+//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);
}