// Created on: 1995-02-15
// Created by: Roberc Coublanc
// Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
//
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
//
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
-
-// Modified by ...
-// ROB JAN/07/98 : Improve Storage of detected entities
-// AGV OCT/23/03 : Optimize the method SortResult() (OCC4201)
-
-#include <SelectMgr_ViewerSelector.ixx>
-#include <SelectMgr_CompareResults.hxx>
-#include <gp_Pnt2d.hxx>
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <SelectMgr_ViewerSelector.hxx>
+
+#include <BVH_Tree.hxx>
+#include <gp_GTrsf.hxx>
#include <gp_Pnt.hxx>
-#include <gp_Lin.hxx>
-#include <Bnd_HArray1OfBox2d.hxx>
-#include <Bnd_Array1OfBox2d.hxx>
+#include <OSD_Environment.hxx>
#include <Precision.hxx>
+#include <Select3D_SensitiveEntity.hxx>
+#include <SelectBasics_PickResult.hxx>
+#include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_SortCriterion.hxx>
+#include <SelectMgr_SensitiveEntitySet.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <TCollection_AsciiString.hxx>
-#include <NCollection_DataMap.hxx>
-#include <SelectBasics_EntityOwner.hxx>
-#include <SelectBasics_ListIteratorOfListOfBox2d.hxx>
-#include <SelectBasics_SensitiveEntity.hxx>
-#include <SelectBasics_ListOfBox2d.hxx>
-#include <SelectBasics_PickArgs.hxx>
-#include <SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive.hxx>
-#include <SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation.hxx>
-#include <SelectMgr_SortCriterion.hxx>
-#include <SortTools_QuickSortOfInteger.hxx>
-#include <OSD_Environment.hxx>
+#include <TColStd_HArray1OfInteger.hxx>
+#include <TColStd_ListOfInteger.hxx>
-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 );
-}
+#include <algorithm>
+
+IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_ViewerSelector, Standard_Transient)
namespace
{
- // container to store depth limits in collection map
- struct SelectMgr_DepthRange
+ //! Comparison operator for sorting selection results
+ class CompareResults
{
- Standard_Real DepthMin;
- Standard_Real DepthMax;
- Standard_Boolean IsEmpty() const { return (DepthMin == DepthMax); }
+ public:
- void Common (const SelectMgr_DepthRange& theOther)
+ CompareResults (const SelectMgr_IndexedDataMapOfOwnerCriterion& theMapOfCriterion)
+ : myMapOfCriterion (&theMapOfCriterion)
{
- if (theOther.DepthMin > DepthMax || theOther.DepthMax < DepthMin)
- {
- DepthMin = RealFirst();
- DepthMax = RealLast();
- return;
- }
+ }
- DepthMin = Max (DepthMin, theOther.DepthMin);
- DepthMax = Min (DepthMax, theOther.DepthMax);
+ Standard_Boolean operator() (Standard_Integer theLeft, Standard_Integer theRight) const
+ {
+ return myMapOfCriterion->FindFromIndex (theLeft) > myMapOfCriterion->FindFromIndex (theRight);
}
+
+ private:
+ const SelectMgr_IndexedDataMapOfOwnerCriterion* myMapOfCriterion;
};
-};
+
+ static const Graphic3d_Mat4d SelectMgr_ViewerSelector_THE_IDENTITY_MAT;
+}
+
+//=======================================================================
+// function : updatePoint3d
+// purpose :
+//=======================================================================
+void SelectMgr_ViewerSelector::updatePoint3d (SelectMgr_SortCriterion& theCriterion,
+ const SelectBasics_PickResult& thePickResult,
+ const Handle(Select3D_SensitiveEntity)& theEntity,
+ const gp_GTrsf& theInversedTrsf,
+ const SelectMgr_SelectingVolumeManager& theMgr) const
+{
+ if (theMgr.GetActiveSelectionType() != SelectMgr_SelectingVolumeManager::Point)
+ {
+ return;
+ }
+
+ bool hasNormal = false;
+ if (thePickResult.HasPickedPoint())
+ {
+ theCriterion.Point = thePickResult.PickedPoint();
+ theCriterion.Normal = thePickResult.SurfaceNormal();
+ const float aNormLen2 = theCriterion.Normal.SquareModulus();
+ if (aNormLen2 > ShortRealEpsilon())
+ {
+ hasNormal = true;
+ theCriterion.Normal *= 1.0f / sqrtf (aNormLen2);
+ }
+ }
+ else if (!thePickResult.IsValid())
+ {
+ theCriterion.Point = thePickResult.PickedPoint();
+ return;
+ }
+ else
+ {
+ theCriterion.Point = theMgr.DetectedPoint (theCriterion.Depth);
+ }
+
+ gp_GTrsf anInvTrsf = theInversedTrsf;
+ if (theCriterion.Entity->HasInitLocation())
+ {
+ anInvTrsf = theCriterion.Entity->InvInitLocation() * anInvTrsf;
+ }
+ if (anInvTrsf.Form() != gp_Identity)
+ {
+ const gp_GTrsf anInvInvTrsd = anInvTrsf.Inverted();
+ anInvInvTrsd.Transforms (theCriterion.Point.ChangeCoord());
+ if (hasNormal)
+ {
+ Graphic3d_Mat4d aMat4;
+ anInvInvTrsd.GetMat4 (aMat4);
+ const Graphic3d_Vec4d aNormRes = aMat4 * Graphic3d_Vec4d (Graphic3d_Vec3d (theCriterion.Normal), 0.0);
+ theCriterion.Normal = Graphic3d_Vec3 (aNormRes.xyz());
+ }
+ }
+
+ 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();
+ }
+}
//==================================================
// Function: Initialize
// Purpose :
//==================================================
SelectMgr_ViewerSelector::SelectMgr_ViewerSelector():
-toupdate(Standard_True),
-tosort(Standard_True),
preferclosest(Standard_True),
-mytolerance(0.),
-myCurRank(0),
-lastx (Precision::Infinite()),
-lasty (Precision::Infinite()),
-myUpdateSortPossible( Standard_True )
+myToUpdateTolerance (Standard_True),
+myCameraScale (1.0),
+myCurRank (0),
+myIsLeftChildQueuedFirst (Standard_False),
+myEntityIdx (0)
{
+ myEntitySetBuilder = new BVH_BinnedBuilder<Standard_Real, 3, 4> (BVH_Constants_LeafNodeSizeSingle, BVH_Constants_MaxTreeDepth, Standard_True);
}
-
-//==================================================
-// Function: Activate
+//=======================================================================
+// Function: SetPixelTolerance
// Purpose :
-//==================================================
-void SelectMgr_ViewerSelector::
-Activate (const Handle(SelectMgr_Selection)& aSelection,
- const Standard_Boolean AutomaticProj)
+//=======================================================================
+void SelectMgr_ViewerSelector::SetPixelTolerance (const Standard_Integer theTolerance)
{
- tosort = Standard_True;
+ if (myTolerances.Tolerance() == theTolerance)
+ {
+ return;
+ }
- if (!myselections.IsBound(aSelection))
+ myToUpdateTolerance = Standard_True;
+ if (theTolerance < 0)
{
- myselections.Bind(aSelection,0);
+ myTolerances.ResetDefaults();
}
- else if (myselections(aSelection)!=0)
+ else
{
- myselections(aSelection)= 0;
+ myTolerances.SetCustomTolerance (theTolerance);
}
- if(AutomaticProj)
- Convert(aSelection);
}
-
//==================================================
-// Function: Deactivate
+// Function: Activate
// Purpose :
//==================================================
-void SelectMgr_ViewerSelector::
-Deactivate (const Handle(SelectMgr_Selection)& aSel)
+void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSelection)
{
- if(myselections.IsBound(aSel))
- {myselections(aSel)=1;
- tosort = Standard_True;}
-}
-
-
-
-
-
-//==================================================
-// Function: Sleep
-// Purpose :
-//==================================================
-void SelectMgr_ViewerSelector::Sleep()
-{ SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections);
-for (;It.More();It.Next()){
- if(It.Value()==0) myselections(It.Key())= 2;
-}
-UpdateSort();
-}
-//=======================================================================
-//function : Sleep
-//purpose :
-//=======================================================================
+ for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
+ {
+ aSelEntIter.Value()->SetActiveForSelection();
+ }
-void SelectMgr_ViewerSelector::Sleep(const Handle(SelectMgr_SelectableObject)& SO)
-{
+ if (theSelection->GetSelectionState() != SelectMgr_SOS_Activated)
+ {
+ theSelection->SetSelectionState (SelectMgr_SOS_Activated);
- for(SO->Init();SO->More();SO->Next()){
- if(myselections.IsBound(SO->CurrentSelection())){
- myselections(SO->CurrentSelection()) = 2;
- }
+ myTolerances.Add (theSelection->Sensitivity());
+ myToUpdateTolerance = Standard_True;
}
- UpdateSort();
}
-
//==================================================
-// Function: Awake
+// Function: Deactivate
// Purpose :
//==================================================
-void SelectMgr_ViewerSelector::Awake(const Standard_Boolean AutomaticProj)
+void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theSelection)
{
- SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections);
- for (;It.More();It.Next()){
- if(It.Value()==2)
- myselections(It.Key())=0;
- if(AutomaticProj)
- UpdateConversion();
- UpdateSort();
+ for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
+ {
+ aSelEntIter.Value()->ResetSelectionActiveStatus();
}
-}
-void SelectMgr_ViewerSelector::Awake(const Handle(SelectMgr_SelectableObject)& SO,
- const Standard_Boolean AutomaticProj)
-{
- for(SO->Init();SO->More();SO->Next()){
- if(myselections.IsBound(SO->CurrentSelection())){
- myselections(SO->CurrentSelection()) =0;
- if(AutomaticProj)
- Convert(SO->CurrentSelection());
- }
- }
+ if (theSelection->GetSelectionState() == SelectMgr_SOS_Activated)
+ {
+ theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
+ myTolerances.Decrement (theSelection->Sensitivity());
+ myToUpdateTolerance = Standard_True;
+ }
}
+
//==================================================
// Function: Clear
// Purpose :
//==================================================
void SelectMgr_ViewerSelector::Clear()
{
- myentities.Clear();
- myselections.Clear();
- toupdate = Standard_True;
- tosort = Standard_True;
mystored.Clear();
- lastx = Precision::Infinite();
- lasty = Precision::Infinite();
-
}
-//==================================================
-// Function: UpdateConversion
-// Purpose :
-//==================================================
-void SelectMgr_ViewerSelector::UpdateConversion()
+//=======================================================================
+// function: isToScaleFrustum
+// purpose : Checks if the entity given requires to scale current selecting frustum
+//=======================================================================
+Standard_Boolean SelectMgr_ViewerSelector::isToScaleFrustum (const Handle(Select3D_SensitiveEntity)& theEntity)
{
- if( SelectDebugModeOnVS() )
- cout<<"\t\t\t\t\t SelectMgr_VS::UpdateConversion"<<endl;
-
- SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections);
- for(;It.More();It.Next()){
- //Convert only if active...
- if(It.Value()==0)
- Convert(It.Key());
- }
- toupdate = Standard_False;
- tosort = Standard_True;
+ 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(Select3D_SensitiveEntity)& theEntity) const
+{
+ return myTolerances.IsCustomTolSet() ?
+ theEntity->SensitivityFactor() + myTolerances.CustomTolerance() : theEntity->SensitivityFactor();
+}
-//==================================================
-// Function: Convert
-// Purpose :
-//==================================================
-void SelectMgr_ViewerSelector::
-Convert (const Handle(SelectMgr_Selection)& /*aSel*/) {tosort=Standard_True;}
-
-
-//==================================================
-// Function: UpdateSort
-// Purpose :
-//==================================================
-void SelectMgr_ViewerSelector::UpdateSort()
+//=======================================================================
+// function: checkOverlap
+// purpose : Internal function that checks if a particular sensitive
+// entity theEntity overlaps current selecting volume precisely
+//=======================================================================
+void SelectMgr_ViewerSelector::checkOverlap (const Handle(Select3D_SensitiveEntity)& theEntity,
+ const gp_GTrsf& theInversedTrsf,
+ SelectMgr_SelectingVolumeManager& theMgr)
{
- if( !myUpdateSortPossible )
+ const Handle(SelectMgr_EntityOwner)& anOwner = theEntity->OwnerId();
+ Handle(SelectMgr_SelectableObject) aSelectable = !anOwner.IsNull() ? anOwner->Selectable() : Handle(SelectMgr_SelectableObject)();
+ SelectBasics_PickResult aPickResult;
+ const Standard_Boolean isMatched = theEntity->Matches(theMgr, aPickResult);
+ if (!isMatched
+ || anOwner.IsNull())
+ {
return;
+ }
- if( SelectDebugModeOnVS() )
- cout<<"\t\t\t\t\t SelectMgr_ViewerSelector::UpdateSort()"<<endl;
- mystored.Clear();
- myentities.Clear();
- myactivenb = NbBoxes();
-
- if(myactivenb > 0) {
- Standard_Boolean NoClip = myclip.IsVoid();
- Handle(Bnd_HArray1OfBox2d) refToTab = new Bnd_HArray1OfBox2d(1,myactivenb);
- Bnd_Array1OfBox2d & tab = refToTab->ChangeArray1();
- Standard_Real xmin=Precision::Infinite(),ymin=Precision::Infinite(),xmax=-Precision::Infinite(),ymax=-Precision::Infinite();
- Standard_Real curxmin,curymin,curxmax,curymax;
- // Standard_Integer boxindex=0,indexsel=0,indexprim=0;
- Standard_Integer boxindex=0;
-
- SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It;
- SelectBasics_ListIteratorOfListOfBox2d LIt;
- Handle(SelectMgr_Selection) curEntity;
- Standard_Real ScaleFactor;
- for(It.Initialize(myselections);It.More();It.Next()){
- if(It.Value()== 0)
- { curEntity = It.Key();
- for(curEntity->Init();curEntity->More();curEntity->Next())
+ 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)
{
- static SelectBasics_ListOfBox2d BoxList;
- BoxList.Clear();
- curEntity->Sensitive()->Areas(BoxList);
- ScaleFactor = curEntity->Sensitive()->SensitivityFactor();
-
-
- for(LIt.Initialize(BoxList);LIt.More();LIt.Next()){
- boxindex++;
-
- tab.SetValue(boxindex,LIt.Value());
-
- tab(boxindex).SetGap(mytolerance*ScaleFactor);
- myentities.Bind(boxindex,curEntity->Sensitive());
- if(NoClip){
- if (!tab(boxindex).IsVoid()) {
- tab(boxindex).Get(curxmin,curymin,curxmax,curymax);
- if(curxmin<xmin) xmin=curxmin;
- if(curxmax>xmax) xmax=curxmax;
- if(curymin<ymin) ymin=curymin;
- if(curymax>ymax) ymax=curymax;
- }
- }
- }
- }
+ updatePoint3d (aCriterion, aPickResult, theEntity, theInversedTrsf, theMgr);
+ *aPrevCriterion = aCriterion;
}
}
-
-
- if(NoClip) {myclip.SetVoid();myclip.Update(xmin,ymin,xmax,ymax);}
- myselector.Initialize(myclip, mytolerance,refToTab);
- tosort = Standard_False;
- if(NoClip) myclip.SetVoid();
+ }
+ else
+ {
+ aCriterion.NbOwnerMatches = 1;
+ updatePoint3d (aCriterion, aPickResult, theEntity, theInversedTrsf, theMgr);
+ mystored.Add (anOwner, aCriterion);
}
}
-
-//==================================================
-// Function: Remove
-// Purpose :
-//==================================================
-void SelectMgr_ViewerSelector::
-Remove(const Handle(SelectMgr_Selection)& aSel)
+//=======================================================================
+// function: computeFrustum
+// purpose :
+//=======================================================================
+void SelectMgr_ViewerSelector::computeFrustum (const Handle(Select3D_SensitiveEntity)& theEnt,
+ const SelectMgr_SelectingVolumeManager& theMgrGlobal,
+ const SelectMgr_SelectingVolumeManager& theMgrObject,
+ const gp_GTrsf& theInvTrsf,
+ SelectMgr_FrustumCache& theCachedMgrs,
+ SelectMgr_SelectingVolumeManager& theResMgr)
{
- if (myselections.IsBound(aSel))
- { myselections.UnBind(aSel);
- tosort = Standard_True;
+ 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 = theMgrGlobal.ScaleAndTransform (aScale, aTrsfMtr, NULL);
+ theResMgr.SetViewClipping (theMgrObject);
+ }
+ else if (toScale)
+ {
+ if (!theCachedMgrs.Find (aScale, theResMgr))
+ {
+ theResMgr = theMgrGlobal.ScaleAndTransform (aScale, gp_Trsf(), NULL);
+ theCachedMgrs.Bind (aScale, theResMgr);
+ }
+ theResMgr.SetViewClipping (theMgrObject);
+ }
+ else if (toTransform)
+ {
+ theResMgr = theMgrGlobal.ScaleAndTransform (1, aTrsfMtr, NULL);
+ theResMgr.SetViewClipping (theMgrObject);
+ }
+ else
+ {
+ theResMgr = theMgrObject;
}
}
-//==================================================
-// Function: SetSensitivity
-// Purpose :
-//==================================================
-void SelectMgr_ViewerSelector::SetSensitivity(const Standard_Real aVal)
-{mytolerance = aVal;
-tosort=Standard_True;}
-
-//==================================================
-// Function: SetClipping
-// Purpose :
-//==================================================
-void SelectMgr_ViewerSelector::SetClipping(const Standard_Real Xc,
- const Standard_Real Yc,
- const Standard_Real Height,
- const Standard_Real Width)
+//=======================================================================
+// function: traverseObject
+// purpose : Internal function that checks if there is possible overlap
+// between some entity of selectable object theObject and
+// current selecting volume
+//=======================================================================
+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)
{
- Bnd_Box2d aClip;
- aClip.Set(gp_Pnt2d(Xc-Width/2, Yc-Height/2));
- aClip.Add(gp_Pnt2d(Xc+Width/2, Yc+Height/2));
- myclip = aClip;
- tosort = Standard_True;
-}
-
+ Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
+ if (anEntitySet->Size() == 0)
+ {
+ return;
+ }
-//==================================================
-// Function: SetClipping
-// Purpose :
-//==================================================
-void SelectMgr_ViewerSelector::SetClipping (const Bnd_Box2d& abox)
-{myclip = abox;
-tosort = Standard_True;
-}
+ 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();
+ }
+ }
-//==================================================
-// Function: InitSelect
-// Purpose :
-//==================================================
-void SelectMgr_ViewerSelector::InitSelect(const Standard_Real Xr,
- const Standard_Real Yr)
-{
- Standard_OutOfRange_Raise_if(Abs(Xr-Precision::Infinite())<=Precision::Confusion() ||
- Abs(Yr-Precision::Infinite())<=Precision::Confusion(),
- " Infinite values in IniSelect");
- mystored.Clear();
- myprim.Clear();
- if (toupdate) UpdateConversion();
- if (tosort) UpdateSort();
- if(myactivenb!=0){
- myselector.InitSelect(Xr,Yr);
- if(myselector.More()) {lastx = Xr;lasty=Yr;}
- LoadResult();
+ SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity
+ ? theMgr.ScaleAndTransform (1, aInversedTrsf, NULL)
+ : theMgr;
+ if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
+ aSensitivesTree->MaxPoint (0)))
+ {
+ return;
}
-}
-//==================================================
-// Function: InitSelect
-// Purpose :
-//==================================================
-void SelectMgr_ViewerSelector::InitSelect(const Bnd_Box2d& aBox)
-{
- mystored.Clear();
- if(toupdate) UpdateConversion();
- if (tosort) UpdateSort();
- if (myactivenb!=0){
- myselector.InitSelect(aBox);
- LoadResult(aBox);
+ if (!theObject->ClipPlanes().IsNull()
+ && theObject->ClipPlanes()->ToOverrideGlobal())
+ {
+ aMgr.SetViewClipping (Handle(Graphic3d_SequenceOfHClipPlane)(), theObject->ClipPlanes(), &theMgr);
}
-}
+ else if (!theObject->TransformPersistence().IsNull())
+ {
+ if (theObject->TransformPersistence()->IsZoomOrRotate()
+ && !theMgr.ViewClipping().IsNull())
+ {
+ // 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 gp_Pnt anAnchor = theObject->TransformPersistence()->AnchorPoint();
+ for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*theMgr.ViewClipping()); aPlaneIt.More(); aPlaneIt.Next())
+ {
+ const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
+ if (!aPlane->IsOn())
+ {
+ continue;
+ }
-//==================================================
-// Function: InitSelect
-// Purpose :
-//==================================================
-void SelectMgr_ViewerSelector::InitSelect(const Standard_Real Xmin,
- const Standard_Real Ymin,
- const Standard_Real Xmax,
- const Standard_Real Ymax)
-{
- mystored.Clear();
+ const Graphic3d_Vec4d aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0);
+ if (aPlane->ProbePoint (aCheckPnt) == Graphic3d_ClipState_Out)
+ {
+ return;
+ }
+ }
+ }
- if (toupdate) UpdateConversion();
- if (tosort) UpdateSort();
- if (myactivenb!=0){
- Bnd_Box2d aBox;
- aBox.Update(Xmin,Ymin,Xmax,Ymax);
- myselector.InitSelect(aBox);
- LoadResult(aBox);
+ aMgr.SetViewClipping (Handle(Graphic3d_SequenceOfHClipPlane)(), theObject->ClipPlanes(), &theMgr);
+ }
+ else if (!theObject->ClipPlanes().IsNull()
+ && !theObject->ClipPlanes()->IsEmpty())
+ {
+ aMgr.SetViewClipping (theMgr.ViewClipping(), theObject->ClipPlanes(), &theMgr);
}
-}
-//==================================================
-// Function: InitSelect
-// Purpose : Polyline Selection
-//==================================================
-void SelectMgr_ViewerSelector::InitSelect(const TColgp_Array1OfPnt2d& aPoly)
-{
- mystored.Clear();
+ if (!theMgr.ViewClipping().IsNull() &&
+ theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Box)
+ {
+ Graphic3d_BndBox3d aBBox (aSensitivesTree->MinPoint (0), aSensitivesTree->MaxPoint (0));
+ // If box selection is active, and the whole sensitive tree is out of the clip planes
+ // selection is empty for this object
+ const Handle(Graphic3d_SequenceOfHClipPlane)& aViewPlanes = theMgr.ViewClipping();
- if (toupdate) UpdateConversion();
- if (tosort) UpdateSort();
- if (myactivenb!=0){
- // the Bnd boxes are used for the first time
- Bnd_Box2d aBox;
- Standard_Integer NbPnt = aPoly.Length();
- Standard_Integer i;
- for(i=1;i<=NbPnt;i++) {
- aBox.Update(aPoly(i).X(),aPoly(i).Y());
+ for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aViewPlanes); aPlaneIt.More(); aPlaneIt.Next())
+ {
+ const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
+ if (!aPlane->IsOn())
+ {
+ continue;
+ }
+
+ Graphic3d_ClipState aState = aPlane->ProbeBox (aBBox);
+ if (aState == Graphic3d_ClipState_Out) // do not process only whole trees, next check on the tree node
+ {
+ return;
+ }
}
- myselector.InitSelect(aBox);
- LoadResult(aPoly);
- // LoadResult(aBox);
}
-}
+ const Standard_Integer aFirstStored = mystored.Extent() + 1;
-//==================================================
-// Function: LoadResult
-// Purpose : for the moment the size of the primitive
-// is not taken into account in the search criteriai...
-// The priority, the depth and the min. distance to CDG or Borders is taken...
-//==================================================
-void SelectMgr_ViewerSelector::LoadResult()
-{
- if (myselector.More())
+ Standard_Integer aStack[BVH_Constants_MaxTreeDepth];
+ Standard_Integer aHead = -1;
+ Standard_Integer aNode = 0; // a root node
+ SelectMgr_FrustumCache aScaledTrnsfFrustums;
+ SelectMgr_SelectingVolumeManager aTmpMgr (false);
+ for (;;)
{
- NCollection_DataMap<Handle(SelectMgr_EntityOwner), SelectMgr_DepthRange> aMapOfOwnerRanges;
-
- // collect information on depth clipping from implementations
- gp_Lin aPickLine = PickingLine (lastx, lasty);
- SelectMgr_DepthRange aViewDRange;
- DepthClipping (lastx, lasty, aViewDRange.DepthMin, aViewDRange.DepthMax);
-
- Standard_Real aDMin;
- Standard_Real aDepthMin;
- Standard_Integer aNument;
-
- if (!aViewDRange.IsEmpty())
+ if (!aSensitivesTree->IsOuter (aNode))
{
- for (; myselector.More(); myselector.Next())
+ 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),
+ aSensitivesTree->MaxPoint (aRightChildIdx));
+ if (isLeftChildIn
+ && isRightChildIn)
{
- aNument = myselector.Value();
-
- const Handle(SelectBasics_SensitiveEntity)& SE = myentities (aNument);
- const Handle(SelectMgr_EntityOwner)& anOwner =
- Handle(SelectMgr_EntityOwner)::DownCast (SE->OwnerId());
-
- // compute depth range for sensitives of entity owner
- SelectMgr_DepthRange anEntityDRange (aViewDRange);
- if (!anOwner.IsNull() && HasDepthClipping (anOwner) && !aMapOfOwnerRanges.Find (anOwner, anEntityDRange))
+ aNode = aLeftChildIdx;
+ ++aHead;
+ aStack[aHead] = aRightChildIdx;
+ }
+ else if (isLeftChildIn
+ || isRightChildIn)
+ {
+ aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
+ }
+ else
+ {
+ if (aHead < 0)
{
- // get depth range from implementation
- SelectMgr_DepthRange aGetRange;
- DepthClipping (lastx, lasty, anOwner, aGetRange.DepthMin, aGetRange.DepthMax);
-
- // concatenate and remember depth range for pefromance increase
- anEntityDRange.Common (aGetRange);
- aMapOfOwnerRanges.Bind (anOwner, anEntityDRange);
+ break;
}
- if (anEntityDRange.IsEmpty())
+ aNode = aStack[aHead];
+ --aHead;
+ }
+ }
+ else
+ {
+ bool aClipped = false;
+ if (!theMgr.ViewClipping().IsNull() &&
+ theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Box)
+ {
+ Graphic3d_BndBox3d aBBox (aSensitivesTree->MinPoint (aNode), aSensitivesTree->MaxPoint (aNode));
+ // If box selection is active, and the whole sensitive tree is out of the clip planes
+ // selection is empty for this object
+ const Handle(Graphic3d_SequenceOfHClipPlane)& aViewPlanes = theMgr.ViewClipping();
+
+ for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aViewPlanes); aPlaneIt.More(); aPlaneIt.Next())
{
- continue;
+ const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
+ if (!aPlane->IsOn())
+ {
+ continue;
+ }
+ Graphic3d_ClipState aState = aPlane->ProbeBox (aBBox);
+ if (aState == Graphic3d_ClipState_Out)
+ {
+ aClipped = true;
+ break;
+ }
+ if (aState == Graphic3d_ClipState_On && !mySelectingVolumeMgr.IsOverlapAllowed()) // partially clipped
+ {
+ if (aPlane->ProbeBoxTouch (aBBox))
+ continue;
+ aClipped = true;
+ break;
+ }
}
-
- SelectBasics_PickArgs aPickArgs (lastx, lasty, mytolerance,
- anEntityDRange.DepthMin,
- anEntityDRange.DepthMax,
- aPickLine);
-
- if (SE->Matches (aPickArgs, aDMin, aDepthMin))
+ }
+ if (!aClipped)
+ {
+ Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode);
+ Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode);
+ for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
{
- if (!anOwner.IsNull())
+ const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx);
+ if (aSensitive->IsActiveForSelection())
{
- Standard_Integer aPrior = anOwner->Priority();
-
- SelectMgr_SortCriterion SC (aPrior, aDepthMin, aDMin, mytolerance, preferclosest);
- if (mystored.Contains (anOwner))
- {
- SelectMgr_SortCriterion& Crit = mystored.ChangeFromKey (anOwner);
- if (SC > Crit)
- {
- Crit = SC;
-
- // update previously recorded entity for this owner
- for (int i = 1; i <= myprim.Length(); i++)
- {
- if (myentities (myprim(i))->OwnerId() == anOwner)
- {
- myprim.SetValue (i, aNument);
- break;
- }
- }
- }
- }
- else
- {
- mystored.Add (anOwner, SC);
-
- // record entity
- myprim.Append (aNument);
- }
+ const Handle(Select3D_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
+ computeFrustum (anEnt, theMgr, aMgr, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
+ checkOverlap (anEnt, aInversedTrsf, aTmpMgr);
}
}
}
- }
+ if (aHead < 0)
+ {
+ break;
+ }
- SortResult();
+ aNode = aStack[aHead];
+ --aHead;
+ }
}
- if (SelectDebugModeOnVS())
+ // 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))
{
- cout<<"\tSelectMgr_VS:: Resultat du move"<<endl;
- cout<<"\tNb Detectes :"<<mystored.Extent()<<endl;
+ return;
+ }
- for(Standard_Integer i=1; i<=mystored.Extent(); i++)
+ for (Standard_Integer aStoredIter = mystored.Extent(); aStoredIter >= aFirstStored; --aStoredIter)
+ {
+ const SelectMgr_SortCriterion& aCriterion = mystored.FindFromIndex (aStoredIter);
+ const Handle(SelectMgr_EntityOwner)& anOwner = aCriterion.Entity->OwnerId();
+ Standard_Integer aNbOwnerEntities = 0;
+ for (SelectMgr_IndexedMapOfHSensitive::Iterator aSensIter (anEntitySet->Sensitives()); aSensIter.More(); aSensIter.Next())
{
- const SelectMgr_SortCriterion& Crit = mystored (myIndexes->Value(i));
- cout << "\t" << i << " - Prior" << Crit.Priority()
- << " - prof :" << Crit.Depth()
- << " - Dist. :" << Crit.MinDist() << endl;
+ 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;
+ }
+ }
}
}
}
-//==================================================
-// Function: LoadResult
-// Purpose :
-//==================================================
-void SelectMgr_ViewerSelector::LoadResult(const Bnd_Box2d& abox)
+//=======================================================================
+// function: TraverseSensitives
+// purpose : Traverses BVH containing all added selectable objects and
+// finds candidates for further search of overlap
+//=======================================================================
+void SelectMgr_ViewerSelector::TraverseSensitives()
{
mystored.Clear();
- // Handle(SelectMgr_EntityOwner) OWNR;
- if(myselector.More())
- { Standard_Real xmin,ymin,xmax,ymax;
- abox.Get(xmin,ymin,xmax,ymax);
- // Standard_Boolean Found(Standard_False);
- // Standard_Real DMin=0.;
- Standard_Integer nument;
- for(;myselector.More();myselector.Next()){
- nument = myselector.Value();
- const Handle(SelectBasics_SensitiveEntity)& SE = myentities(nument);
- if (SE->Matches(xmin,ymin,xmax,ymax,0.0)){
- const Handle(SelectBasics_EntityOwner)& OWNR = SE->OwnerId();
- if(!OWNR.IsNull()){
- if(!mystored.Contains(OWNR)){
- SelectMgr_SortCriterion SC(OWNR->Priority(),Precision::Infinite(),
- Precision::Infinite(),mytolerance,preferclosest);
- mystored.Add(OWNR,SC);
- myprim.Append(nument);
- }
- }
- }
+ 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())
+ {
+ 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;
}
- // do not parse in case of selection by elastic rectangle (BUG ANALYST)
- if(mystored.IsEmpty()) return;
- if(myIndexes.IsNull())
- myIndexes = new TColStd_HArray1OfInteger(1,mystored.Extent());
- else if(mystored.Extent() !=myIndexes->Length())
- myIndexes = new TColStd_HArray1OfInteger (1,mystored.Extent());
-
- // to work faster...
- TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1();
- for(Standard_Integer I=1;I<=mystored.Extent();I++)
- thearr(I)=I;
- }
-}
-//==================================================
-// Function: LoadResult
-// Purpose :
-//==================================================
-void SelectMgr_ViewerSelector::LoadResult(const TColgp_Array1OfPnt2d& aPoly)
-{
- mystored.Clear();
- Bnd_Box2d aBox;
- Standard_Integer NbPnt = aPoly.Length();
- Standard_Integer i;
- for(i=1;i<=NbPnt;i++) {
- aBox.Update(aPoly(i).X(),aPoly(i).Y());
- }
- Standard_Integer NB=0;
- // Handle(SelectMgr_EntityOwner) OWNR;
- if(myselector.More())
+ for (Standard_Integer aBVHSetIt = 0; aBVHSetIt < SelectMgr_SelectableObjectSet::BVHSubsetNb; ++aBVHSetIt)
{
- Standard_Integer nument;
-
- for(;myselector.More();myselector.Next()){
- NB++;
- nument = myselector.Value();
- const Handle(SelectBasics_SensitiveEntity)& SE = myentities(nument);
- if (SE->Matches(aPoly,aBox,0.0)){
- const Handle(SelectBasics_EntityOwner)& OWNR = SE->OwnerId();
- if(!OWNR.IsNull()){
- if(!mystored.Contains(OWNR)){
- SelectMgr_SortCriterion SC(OWNR->Priority(),Precision::Infinite(),
- Precision::Infinite(),mytolerance,preferclosest);
- mystored.Add(OWNR,SC);
- myprim.Append(nument);
+ SelectMgr_SelectableObjectSet::BVHSubset aBVHSubset =
+ static_cast<SelectMgr_SelectableObjectSet::BVHSubset> (aBVHSetIt);
+
+ if (mySelectableObjects.IsEmpty (aBVHSubset))
+ {
+ 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))
+ {
+ 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);
- if(mystored.IsEmpty()) return;
- if(myIndexes.IsNull())
- myIndexes = new TColStd_HArray1OfInteger(1,mystored.Extent());
- else if(mystored.Extent() !=myIndexes->Length())
- myIndexes = new TColStd_HArray1OfInteger (1,mystored.Extent());
+ traverseObject (aSelectableObject, aMgr, aCamera, aProjectionMat, aWorldViewMat, aWidth, aHeight);
+ }
+ if (aHead < 0)
+ {
+ break;
+ }
- // to work faster...
- TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1();
- for(Standard_Integer I=1;I<=mystored.Extent();I++)
- thearr(I)=I;
+ aNode = aStack[aHead];
+ --aHead;
+ }
+ }
}
-}
+ SortResult();
+}
//==================================================
-// Function: HasStored
+// Function: ClearPicked
// Purpose :
//==================================================
-Standard_Boolean SelectMgr_ViewerSelector::
-HasStored ()
+void SelectMgr_ViewerSelector::ClearPicked()
{
- if(Abs(lastx-Precision::Infinite())<=Precision::Confusion()) return Standard_False;
- if(Abs(lasty-Precision::Infinite())<=Precision::Confusion()) return Standard_False;
- InitSelect(lastx,lasty);
- Init();
- return More();
+ mystored.Clear();
}
-
-
-
//==================================================
// Function: Picked
// Purpose :
//==================================================
-Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector
-::Picked() const
+Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked() const
{
- Standard_Integer RankInMap = myIndexes->Value(myCurRank);
- const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap);
- Handle(SelectMgr_EntityOwner) Ownr = *((Handle(SelectMgr_EntityOwner)*) &toto);
- return Ownr;
+ const Standard_Integer aRankInMap = myIndexes->Value (myCurRank);
+ const Handle(SelectMgr_EntityOwner)& anOwner = mystored.FindKey (aRankInMap);
+ return anOwner;
}
-
-
//=======================================================================
-//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(1);
- const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap);
- Handle(SelectMgr_EntityOwner) Ownr = *((Handle(SelectMgr_EntityOwner)*) &toto);
- return Ownr;
+ if (theRank < 1 || theRank > NbPicked())
+ {
+ return Handle(SelectMgr_EntityOwner)();
}
- Handle (SelectMgr_EntityOwner) NullObj; //returns a null Handle if there was not successfull pick...
- return NullObj;
-}
-
-
-//=======================================================================
-//function : NbPicked
-//purpose :
-//=======================================================================
-
-Standard_Integer SelectMgr_ViewerSelector::NbPicked() const
-{
- return mystored.Extent();
+ const Standard_Integer anOwnerIdx = myIndexes->Value (theRank);
+ const Handle(SelectMgr_EntityOwner)& aStoredOwner = mystored.FindKey (anOwnerIdx);
+ return aStoredOwner;
}
-//=======================================================================
-//function : Picked
-//purpose :
-//=======================================================================
-Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked(const Standard_Integer aRank) const
-{
-
- Handle(SelectMgr_EntityOwner) Own;
- if (aRank<1 || aRank>NbPicked())
- return Own;
- Standard_Integer Indx = myIndexes->Value(aRank);
-
- const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(Indx);
- Own = *((Handle(SelectMgr_EntityOwner)*) &toto);
- return Own;
-}
//=======================================================================
-//function : Primitive
+//function : PickedData
//purpose :
//=======================================================================
-Handle(SelectBasics_SensitiveEntity) SelectMgr_ViewerSelector::Primitive
-(const Standard_Integer /*Index*/) const
+const SelectMgr_SortCriterion& SelectMgr_ViewerSelector::PickedData(const Standard_Integer theRank) const
{
- return myentities(myprim(myCurRank));
+ 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: LastPosition
-// Purpose :
-//==================================================
-void SelectMgr_ViewerSelector::LastPosition(Standard_Real& Xlast,
- Standard_Real& YLast) const
-{ Xlast = lastx;YLast = lasty;}
-
-
-
//===================================================
//
// INTERNAL METHODS ....
//
//==================================================
-
-
-
//==================================================
-// Function: NbBoxes
+// Function: SetEntitySetBuilder
// Purpose :
//==================================================
-Standard_Integer SelectMgr_ViewerSelector::NbBoxes()
+void SelectMgr_ViewerSelector::SetEntitySetBuilder (const Handle(Select3D_BVHBuilder3d)& theBuilder)
{
- SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections);
- // Standard_Integer Nbb=0, first,last;
- Standard_Integer Nbb=0;
-
- for(;It.More();It.Next()){
- if(It.Value()==0){
- for(It.Key()->Init();It.Key()->More();It.Key()->Next())
- {Nbb+= It.Key()->Sensitive()->MaxBoxes();}
- }
+ myEntitySetBuilder = theBuilder;
+ for (SelectMgr_MapOfObjectSensitives::Iterator aSetIter (myMapOfObjectSensitives); aSetIter.More(); aSetIter.Next())
+ {
+ aSetIter.ChangeValue()->SetBuilder (myEntitySetBuilder);
}
- return Nbb;
}
-
-
-
//==================================================
// Function: Contains
// Purpose :
//==================================================
-Standard_Boolean SelectMgr_ViewerSelector::
-Contains(const Handle(SelectMgr_SelectableObject)& anObject) const
+Standard_Boolean SelectMgr_ViewerSelector::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
{
- for (anObject->Init();anObject->More();anObject->Next()){
- if(myselections.IsBound(anObject->CurrentSelection()))
- return Standard_True;
- }
- return Standard_False;
+ return mySelectableObjects.Contains (theObject);
}
-
-
//==================================================
// Function: ActiveModes
// Purpose : return all the modes with a given state for an object
//==================================================
-
-
-Standard_Boolean SelectMgr_ViewerSelector::
-Modes(const Handle(SelectMgr_SelectableObject)& SO,
- TColStd_ListOfInteger& TheActiveList,
- const SelectMgr_StateOfSelection WantedState) const
+Standard_Boolean SelectMgr_ViewerSelector::Modes (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
+ TColStd_ListOfInteger& theModeList,
+ const SelectMgr_StateOfSelection theWantedState) const
{
- Standard_Boolean Found= Standard_False;
- for(SO->Init();SO->More();SO->Next()){
- if(myselections.IsBound(SO->CurrentSelection())){
- if(WantedState==SelectMgr_SOS_Any)
- TheActiveList.Append(SO->CurrentSelection()->Mode());
- else if( myselections(SO->CurrentSelection())==WantedState)
- TheActiveList.Append(SO->CurrentSelection()->Mode());
-
- if(!Found) Found=Standard_True;
+ Standard_Boolean hasActivatedStates = Contains (theSelectableObject);
+ for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theSelectableObject->Selections()); aSelIter.More(); aSelIter.Next())
+ {
+ if (theWantedState == SelectMgr_SOS_Any)
+ {
+ theModeList.Append (aSelIter.Value()->Mode());
}
- }
- return Found;
-}
-
-
-Standard_Boolean SelectMgr_ViewerSelector::
-IsActive(const Handle(SelectMgr_SelectableObject)& SO,
- const Standard_Integer aMode) const
-{
- for(SO->Init();SO->More();SO->Next()){
- if(aMode==SO->CurrentSelection()->Mode()){
- if(myselections.IsBound(SO->CurrentSelection()) &&
- myselections(SO->CurrentSelection())==SelectMgr_SOS_Activated)
- return Standard_True;
- else return Standard_False;
+ else if (theWantedState == aSelIter.Value()->GetSelectionState())
+ {
+ theModeList.Append (aSelIter.Value()->Mode());
}
}
- return Standard_False;
-}
+ return hasActivatedStates;
+}
-Standard_Boolean SelectMgr_ViewerSelector::
-IsInside(const Handle(SelectMgr_SelectableObject)& SO,
- const Standard_Integer aMode) const
+//==================================================
+// Function: IsActive
+// Purpose :
+//==================================================
+Standard_Boolean SelectMgr_ViewerSelector::IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
+ const Standard_Integer theMode) const
{
- for(SO->Init();SO->More();SO->Next()){
- if(aMode==SO->CurrentSelection()->Mode()){
- if(myselections.IsBound(SO->CurrentSelection())) return Standard_True;
- else return Standard_False;
+ if (!Contains (theSelectableObject))
+ return Standard_False;
- }
- }
- return Standard_False;
+ const Handle(SelectMgr_Selection)& aSel = theSelectableObject->Selection (theMode);
+ return !aSel.IsNull()
+ && aSel->GetSelectionState() == SelectMgr_SOS_Activated;
}
-
-//=======================================================================
-//function : Status
-//purpose :
-//=======================================================================
-
-SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status(const Handle(SelectMgr_Selection)& aSel) const
+//==================================================
+// Function: IsInside
+// Purpose :
+//==================================================
+Standard_Boolean SelectMgr_ViewerSelector::IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
+ const Standard_Integer theMode) const
{
- if(!myselections.IsBound(aSel)) return SelectMgr_SOS_Unknown;
- //JR/Hp
- Standard_Integer ie = myselections(aSel) ;
- return SelectMgr_StateOfSelection( ie );
- // return SelectMgr_StateOfSelection(myselections(aSel));
+ if (!Contains (theSelectableObject))
+ return Standard_False;
+ const Handle(SelectMgr_Selection)& aSel = theSelectableObject->Selection (theMode);
+ return !aSel.IsNull()
+ && aSel->GetSelectionState() != SelectMgr_SOS_Unknown;
}
-
//=======================================================================
-//function : Dump
+//function : Status
//purpose :
//=======================================================================
-void SelectMgr_ViewerSelector::Dump(Standard_OStream& S) const
+SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_Selection)& theSelection) const
{
- S<<"=========================="<<endl;
- S<<" SelectMgr_ViewerSelector "<<endl;
- S<<"=========================="<<endl;
- S<<" "<<endl;
+ return theSelection->GetSelectionState();
}
-
-
//==================================================
// Function: Status
// Purpose : gives Information about selectors
//==================================================
-TCollection_AsciiString SelectMgr_ViewerSelector::
-Status(const Handle(SelectMgr_SelectableObject)& SO) const
+TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const
{
- TCollection_AsciiString Status("Status Object :\n\t");
- Standard_Boolean Found= Standard_False;
- for(SO->Init();SO->More();SO->Next()){
- if(myselections.IsBound(SO->CurrentSelection()))
+ TCollection_AsciiString aStatus ("Status Object :\n\t");
+ for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theSelectableObject->Selections()); aSelIter.More(); aSelIter.Next())
+ {
+ if (aSelIter.Value()->GetSelectionState() != SelectMgr_SOS_Unknown)
{
- Found = Standard_True;
- Status = Status + "Mode " +
- TCollection_AsciiString(SO->CurrentSelection()->Mode()) +
- " present - " ;
- if(myselections(SO->CurrentSelection()))
- Status = Status + " Active \n\t";
- else
- Status = Status + " 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(!Found) Status = Status + "Not Present in the selector\n\n";
- return Status;
-}
-
-
-TCollection_AsciiString SelectMgr_ViewerSelector::
-Status () const
-{
- // sevsitive primitives present
- //-----------------------------
- TCollection_AsciiString Status("\t\tSelector Status :\n\t");
- // selections
- //-----------
- Standard_Integer NbActive =0,NbPrim=0;
- Status = Status + "Number of already computed selections : " +
- TCollection_AsciiString(myselections.Extent());
-
- SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections);
- for(;It.More();It.Next())
+ if (!Contains (theSelectableObject))
{
- if(It.Value()==0) {NbActive++;
- for(It.Key()->Init();It.Key()->More();It.Key()->Next()){NbPrim++;}
- }
- }
- Status = Status + " - " + TCollection_AsciiString(NbActive) + " activated ones\n\t";
- Status = Status + "Number of active sensitive primitives : " +
- TCollection_AsciiString(NbPrim)+"\n\t";
- Status = Status + "Real stored Pick Tolerance : " + TCollection_AsciiString(mytolerance) +"\n\t";
- if(toupdate) {
- Status = Status + "\nWARNING : those informations will be obsolete for the next Pick\n"
- +"to get the real status of the selector - make One pick and call Status again\n";
+ aStatus = aStatus + "Not Present in the selector\n\n";
}
- return Status;
+
+ return aStatus;
}
//=======================================================================
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;
-
- // OCC4201 (AGV): This loop is inefficient on large arrays, so I replace it
- // with a standard sort algo
- // // on trie suivant les criteres (i) (Owner) (SortCriterion)
- // Standard_Boolean OKSort;
- // Standard_Integer temp,indx,indx1;
- // Standard_Integer tmprim;
- // // merci lbr...
- // do{
- // OKSort =Standard_True;
- // for(I=1;I<thearr.Length();I++){
- // indx = thearr(I);
- // indx1 = thearr(I+1);
- // if(mystored(indx) < mystored(indx1)){
- // OKSort = Standard_False;
- //
- // temp = thearr(I+1);
- // thearr(I+1) = thearr (I);
- // thearr(I) = temp;
- //
- // tmprim = myprim(I+1);
- // myprim(I+1) = myprim(I);
- // myprim(I) = tmprim;
- //
- // }
- // }
- // } while (OKSort==Standard_False);
- //
- // OCC4201 (AGV): debut
-
- SortTools_QuickSortOfInteger::Sort (thearr,
- SelectMgr_CompareResults(mystored));
- TColStd_Array1OfInteger myPrimArr (1, myprim.Length());
- for (I = 1; I <= myPrimArr.Length(); I++)
- myPrimArr (I) = myprim (I);
- for (I = 1; I <= thearr.Length(); I++) {
- const Standard_Integer ind = thearr(I);
- if (ind > 0 && ind <= myPrimArr.Upper())
- myprim (I) = myPrimArr (ind);
+ TColStd_Array1OfInteger& anIndexArray = myIndexes->ChangeArray1();
+ for (Standard_Integer anIndexIter = 1; anIndexIter <= anExtent; ++anIndexIter)
+ {
+ anIndexArray.SetValue (anIndexIter, anIndexIter);
}
- // OCC4201 (AGV): fin
- // it is enough to return owners corresponding to parced indices...
+ std::sort (anIndexArray.begin(), anIndexArray.end(), CompareResults (mystored));
+}
+//=======================================================================
+// function : AddSelectableObject
+// purpose : Adds new object to the map of selectable objects
+//=======================================================================
+void SelectMgr_ViewerSelector::AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
+{
+ if (!myMapOfObjectSensitives.IsBound (theObject))
+ {
+ mySelectableObjects.Append (theObject);
+ Handle(SelectMgr_SensitiveEntitySet) anEntitySet = new SelectMgr_SensitiveEntitySet (myEntitySetBuilder);
+ myMapOfObjectSensitives.Bind (theObject, anEntitySet);
+ }
}
+//=======================================================================
+// function : AddSelectionToObject
+// purpose : Adds new selection to the object and builds its BVH tree
+//=======================================================================
+void SelectMgr_ViewerSelector::AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject,
+ const Handle(SelectMgr_Selection)& theSelection)
+{
+ if (Handle(SelectMgr_SensitiveEntitySet)* anEntitySet = myMapOfObjectSensitives.ChangeSeek (theObject))
+ {
+ (*anEntitySet)->Append (theSelection);
+ (*anEntitySet)->BVH();
+ }
+ else
+ {
+ AddSelectableObject (theObject);
+ AddSelectionToObject (theObject, theSelection);
+ }
+}
//=======================================================================
-//function :
-//purpose :
+// function : MoveSelectableObject
+// purpose :
//=======================================================================
-Standard_Boolean SelectMgr_ViewerSelector::IsUpdateSortPossible() const
+void SelectMgr_ViewerSelector::MoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
{
- return myUpdateSortPossible;
+ mySelectableObjects.ChangeSubset (theObject);
}
//=======================================================================
-//function :
-//purpose :
+// function : RemoveSelectableObject
+// purpose : Removes selectable object from map of selectable ones
//=======================================================================
-void SelectMgr_ViewerSelector::SetUpdateSortPossible( const Standard_Boolean possible )
+void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
{
- myUpdateSortPossible = possible;
+ Handle(SelectMgr_SelectableObject) anObj = theObject;
+ if (myMapOfObjectSensitives.UnBind (theObject))
+ {
+ mySelectableObjects.Remove (theObject);
+ }
}
//=======================================================================
-//function : PickingLine
-//purpose : Stub
+// function : RemoveSelectionOfObject
+// purpose : Removes selection of the object and marks its BVH tree
+// for rebuild
//=======================================================================
-gp_Lin SelectMgr_ViewerSelector::PickingLine (const Standard_Real /*theX*/,
- const Standard_Real /*theY*/) const
+void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject,
+ const Handle(SelectMgr_Selection)& theSelection)
{
- return gp_Lin();
+ if (Handle(SelectMgr_SensitiveEntitySet)* anEntitySet = myMapOfObjectSensitives.ChangeSeek (theObject))
+ {
+ (*anEntitySet)->Remove (theSelection);
+ }
}
//=======================================================================
-//function : DepthClipping
-//purpose : Stub
+// function : RebuildObjectsTree
+// purpose : Marks BVH of selectable objects for rebuild
//=======================================================================
-void SelectMgr_ViewerSelector::DepthClipping (const Standard_Real /*theX*/,
- const Standard_Real /*theY*/,
- Standard_Real& theMin,
- Standard_Real& theMax) const
+void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce)
{
- theMin = RealFirst();
- theMax = RealLast();
+ mySelectableObjects.MarkDirty();
+
+ if (theIsForce)
+ {
+ 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);
+ }
}
//=======================================================================
-//function : DepthClipping
-//purpose : Stub
+// function : RebuildSensitivesTree
+// purpose : Marks BVH of sensitive entities of particular selectable
+// object for rebuild
//=======================================================================
-void SelectMgr_ViewerSelector::DepthClipping (const Standard_Real /*theX*/,
- const Standard_Real /*theY*/,
- const Handle(SelectMgr_EntityOwner)& /*theOwner*/,
- Standard_Real& theMin,
- Standard_Real& theMax) const
+void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject,
+ const Standard_Boolean theIsForce)
{
- theMin = RealFirst();
- theMax = RealLast();
+ if (!Contains (theObject))
+ return;
+
+ Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
+ anEntitySet->MarkDirty();
+
+ if (theIsForce)
+ {
+ anEntitySet->BVH();
+ }
+}
+
+//=======================================================================
+// function : resetSelectionActivationStatus
+// purpose : Marks all added sensitive entities of all objects as
+// non-selectable
+//=======================================================================
+void SelectMgr_ViewerSelector::ResetSelectionActivationStatus()
+{
+ for (SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives); aSensitivesIter.More(); aSensitivesIter.Next())
+ {
+ Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = aSensitivesIter.ChangeValue();
+ const Standard_Integer anEntitiesNb = anEntitySet->Size();
+ for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
+ {
+ anEntitySet->GetSensitiveById (anIdx)->ResetSelectionActiveStatus();
+ }
+ }
}
//=======================================================================
-//function : HasDepthClipping
-//purpose : Stub
+// function : DetectedEntity
+// purpose : Returns sensitive entity that was detected during the
+// previous run of selection algorithm
//=======================================================================
-Standard_Boolean SelectMgr_ViewerSelector::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& /*theOwner*/) const
+const Handle(Select3D_SensitiveEntity)& SelectMgr_ViewerSelector::DetectedEntity() const
{
- return Standard_False;
+ const Standard_Integer aRankInMap = myIndexes->Value(myCurRank);
+ return mystored.FindFromIndex (aRankInMap).Entity;
+}
+
+//=======================================================================
+// function : ActiveOwners
+// purpose : Returns the list of active entity owners
+//=======================================================================
+void SelectMgr_ViewerSelector::ActiveOwners (NCollection_List<Handle(SelectMgr_EntityOwner)>& theOwners) const
+{
+ for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next())
+ {
+ const Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = anIter.Value();
+ const Standard_Integer anEntitiesNb = anEntitySet->Size();
+ for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
+ {
+ const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx);
+ if (aSensitive->IsActiveForSelection())
+ {
+ 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);
+}
+
+//=======================================================================
+//function : DumpJson
+//purpose :
+//=======================================================================
+void SelectMgr_ViewerSelector::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
+{
+ OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
+
+ OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, preferclosest)
+ OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myToUpdateTolerance)
+ OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, mystored.Extent())
+
+ OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, &mySelectingVolumeMgr)
+ OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, &mySelectableObjects)
+
+ Standard_Integer aNbOfSelectableObjects = 0;
+ for (SelectMgr_SelectableObjectSet::Iterator aSelectableIt (mySelectableObjects); aSelectableIt.More(); aSelectableIt.Next())
+ {
+ aNbOfSelectableObjects++;
+ }
+ OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, aNbOfSelectableObjects)
+
+ OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myTolerances.Tolerance())
+ OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myTolerances.CustomTolerance())
+ OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myZLayerOrderMap.Extent())
+
+ OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myEntitySetBuilder.get())
+ OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myCameraEye)
+ OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myCameraDir)
+ OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myCameraScale)
+
+ if (!myIndexes.IsNull())
+ OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIndexes->Size())
+
+ OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myCurRank)
+ OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsLeftChildQueuedFirst)
+ OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myEntityIdx)
+ OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMapOfObjectSensitives.Extent())
}