From: kgv Date: Fri, 2 Sep 2016 16:11:23 +0000 (+0300) Subject: 0027834: Visualization, SelectMgr_ViewerSelector - iteration through detected Entitie... X-Git-Tag: V7_1_0_beta~164 X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=commitdiff_plain;h=aa75c0cf9db7bad98176fc0e8f8d6525d932233c 0027834: Visualization, SelectMgr_ViewerSelector - iteration through detected Entities should be sorted SelectMgr_SortCriterion now stores detected SensitiveEntity and 3D point. SelectMgr_ToleranceMap class definition has been moved out to dedicated file (from SelectMgr_ViewerSelector). SelectMgr_ViewerSelector - the methods implementing class-as-iterator Init(), More(), Next(), Picked() and InitDetected(), MoreDetected(), NextDetected(), DetectedEntity() have been deprecated. User should access detection results by using index. New methods PickedData(), PickedEntity(), PickedPoint() have been added for accessing auxiliary information about picked object in sorted order. --- diff --git a/src/AIS/AIS_InteractiveContext_1.cxx b/src/AIS/AIS_InteractiveContext_1.cxx index 9b07d867d0..7a1ce9ae75 100644 --- a/src/AIS/AIS_InteractiveContext_1.cxx +++ b/src/AIS/AIS_InteractiveContext_1.cxx @@ -359,10 +359,9 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Integer theXPMi } aSelector->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView); - - for (aSelector->Init(); aSelector->More(); aSelector->Next()) + for (Standard_Integer aPickIter = 1; aPickIter <= aSelector->NbPicked(); ++aPickIter) { - const Handle(SelectMgr_EntityOwner)& aCurOwner = aSelector->Picked(); + const Handle(SelectMgr_EntityOwner)& aCurOwner = aSelector->Picked (aPickIter); if (aCurOwner.IsNull() || !aCurOwner->HasSelectable() || !myFilters->IsOk (aCurOwner)) continue; @@ -407,10 +406,9 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const TColgp_Array1OfPnt2d& the } aSelector->Pick (thePolyline, theView); - - for (aSelector->Init(); aSelector->More(); aSelector->Next()) + for (Standard_Integer aPickIter = 1; aPickIter <= aSelector->NbPicked(); ++aPickIter) { - const Handle(SelectMgr_EntityOwner) anOwner = aSelector->Picked(); + const Handle(SelectMgr_EntityOwner) anOwner = aSelector->Picked (aPickIter); if (anOwner.IsNull() || !anOwner->HasSelectable() || !myFilters->IsOk (anOwner)) continue; @@ -544,9 +542,9 @@ AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Integer the } aSelector->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView); - for (aSelector->Init(); aSelector->More(); aSelector->Next()) + for (Standard_Integer aPickIter = 1; aPickIter <= aSelector->NbPicked(); ++aPickIter) { - const Handle(SelectMgr_EntityOwner) anOwner = aSelector->Picked(); + const Handle(SelectMgr_EntityOwner) anOwner = aSelector->Picked (aPickIter); if (anOwner.IsNull() || !anOwner->HasSelectable() || !myFilters->IsOk (anOwner)) continue; @@ -593,10 +591,9 @@ AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const TColgp_Array1OfPnt2d } aSelector->Pick (thePolyline, theView); - - for (aSelector->Init(); aSelector->More(); aSelector->Next()) + for (Standard_Integer aPickIter = 1; aPickIter <= aSelector->NbPicked(); ++aPickIter) { - const Handle(SelectMgr_EntityOwner) anOwner = aSelector->Picked(); + const Handle(SelectMgr_EntityOwner) anOwner = aSelector->Picked (aPickIter); if (anOwner.IsNull() || !anOwner->HasSelectable() || !myFilters->IsOk (anOwner)) continue; diff --git a/src/AIS/AIS_LocalContext_1.cxx b/src/AIS/AIS_LocalContext_1.cxx index e098549c6e..c1b3765dfb 100644 --- a/src/AIS/AIS_LocalContext_1.cxx +++ b/src/AIS/AIS_LocalContext_1.cxx @@ -225,9 +225,7 @@ AIS_StatusOfPick AIS_LocalContext::Select (const Standard_Integer theXPMin, } Standard_Integer aSelNum = mySelection->Extent(); - - myMainVS->Init(); - if (!myMainVS->More()) + if (myMainVS->NbPicked() == 0) { ClearSelected (toUpdateViewer); mylastindex = 0; @@ -236,9 +234,9 @@ AIS_StatusOfPick AIS_LocalContext::Select (const Standard_Integer theXPMin, ClearSelected (Standard_False); - for (myMainVS->Init(); myMainVS->More(); myMainVS->Next()) + for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter) { - const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked(); + const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter); if (myFilters->IsOk (anOwner)) { // it can be helpful to classify this owner immediately... @@ -276,8 +274,7 @@ AIS_StatusOfPick AIS_LocalContext::Select (const TColgp_Array1OfPnt2d& thePolyli myMainVS->Pick (thePolyline, theView); Standard_Integer aLastSelNum = mySelection->Extent(); - myMainVS->Init(); - if (!myMainVS->More()) + if (myMainVS->NbPicked() == 0) { // Nothing is selected clear selection. ClearSelected (toUpdateViewer); @@ -295,9 +292,9 @@ AIS_StatusOfPick AIS_LocalContext::Select (const TColgp_Array1OfPnt2d& thePolyli // Clear previous selection without update to process this selection ClearSelected (Standard_False); - for (myMainVS->Init(); myMainVS->More(); myMainVS->Next()) + for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter) { - const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked(); + const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter); if (myFilters->IsOk (anOwner)) { // it can be helpful to classify this owner immediately... @@ -385,9 +382,7 @@ AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const Standard_Integer theXPMin myMainVS->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView); Standard_Integer aLastSelNum = mySelection->Extent(); - - myMainVS->Init(); - if (!myMainVS->More()) + if (myMainVS->NbPicked() == 0) { // Nothing is selected clear selection, but don't clear the selection // as it is shift selection and previous selection matters. @@ -400,9 +395,9 @@ AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const Standard_Integer theXPMin UnhilightPicked (Standard_False); } - for (myMainVS->Init(); myMainVS->More(); myMainVS->Next()) + for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter) { - const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked(); + const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter); if(myFilters->IsOk (anOwner)) { Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True; @@ -437,8 +432,7 @@ AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const TColgp_Array1OfPnt2d& theP myMainVS->Pick (thePolyline, theView); Standard_Integer aLastSelNum = mySelection->Extent(); - myMainVS->Init(); - if(!myMainVS->More()) + if (myMainVS->NbPicked() == 0) { // Nothing is selected clear selection, but don't clear the selection // as it is shift selection and previous selection matters. @@ -451,9 +445,9 @@ AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const TColgp_Array1OfPnt2d& theP UnhilightPicked (Standard_False); } - for (myMainVS->Init(); myMainVS->More(); myMainVS->Next()) + for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter) { - const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked(); + const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter); if (myFilters->IsOk (anOwner)) { Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True; diff --git a/src/SelectMgr/FILES b/src/SelectMgr/FILES index a251e20cc0..bf2eb89118 100755 --- a/src/SelectMgr/FILES +++ b/src/SelectMgr/FILES @@ -48,6 +48,8 @@ SelectMgr_SequenceOfSelector.hxx SelectMgr_SOPtr.hxx SelectMgr_SortCriterion.hxx SelectMgr_StateOfSelection.hxx +SelectMgr_ToleranceMap.hxx +SelectMgr_ToleranceMap.cxx SelectMgr_TriangularFrustum.cxx SelectMgr_TriangularFrustum.hxx SelectMgr_TriangularFrustumSet.cxx @@ -58,4 +60,3 @@ SelectMgr_VectorTypes.hxx SelectMgr_ViewClipRange.hxx SelectMgr_ViewerSelector.cxx SelectMgr_ViewerSelector.hxx -SelectMgr_ViewerSelector.lxx diff --git a/src/SelectMgr/SelectMgr_SortCriterion.hxx b/src/SelectMgr/SelectMgr_SortCriterion.hxx index 70a924a7e9..81f731d304 100644 --- a/src/SelectMgr/SelectMgr_SortCriterion.hxx +++ b/src/SelectMgr/SelectMgr_SortCriterion.hxx @@ -19,12 +19,7 @@ #include #include -#include -#include -#include -#include -#include -#include +#include //! This class provides data and criterion for sorting candidate //! entities in the process of interactive selection by mouse click @@ -32,6 +27,8 @@ class SelectMgr_SortCriterion { public: + Handle(SelectBasics_SensitiveEntity) Entity; //!< detected entity + gp_Pnt Point; //!< 3D point Standard_Real Depth; //!< distance from the view plane to the entity Standard_Real MinDist; //!< distance from the clicked point to the entity on the view plane Standard_Real Tolerance; //!< tolerance used for selecting candidates diff --git a/src/SelectMgr/SelectMgr_ToleranceMap.cxx b/src/SelectMgr/SelectMgr_ToleranceMap.cxx new file mode 100644 index 0000000000..acc0810f59 --- /dev/null +++ b/src/SelectMgr/SelectMgr_ToleranceMap.cxx @@ -0,0 +1,84 @@ +// Copyright (c) 2016 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// 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. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +//======================================================================= +// function: SelectMgr_ToleranceMap +// purpose : +//======================================================================= +SelectMgr_ToleranceMap::SelectMgr_ToleranceMap() +{ + myLargestKey = -1; + myCustomTolerance = -1; +} + +//======================================================================= +// function: ~SelectMgr_ToleranceMap +// purpose : +//======================================================================= +SelectMgr_ToleranceMap::~SelectMgr_ToleranceMap() +{ + myTolerances.Clear(); +} + +//======================================================================= +// function: Add +// purpose : +//======================================================================= +void SelectMgr_ToleranceMap::Add (const Standard_Integer& theTolerance) +{ + if (myTolerances.IsBound (theTolerance)) + { + Standard_Integer& aFreq = myTolerances.ChangeFind (theTolerance); + aFreq++; + + if (aFreq == 1 && theTolerance != myLargestKey) + myLargestKey = Max (theTolerance, myLargestKey); + } + else + { + if (myTolerances.IsEmpty()) + { + myTolerances.Bind (theTolerance, 1); + myLargestKey = theTolerance; + return; + } + + myTolerances.Bind (theTolerance, 1); + myLargestKey = Max (theTolerance, myLargestKey); + } +} + +//======================================================================= +// function: Decrement +// purpose : +//======================================================================= +void SelectMgr_ToleranceMap::Decrement (const Standard_Integer& theTolerance) +{ + if (myTolerances.IsBound (theTolerance)) + { + Standard_Integer& aFreq = myTolerances.ChangeFind (theTolerance); + aFreq--; + + if (Abs (theTolerance - myLargestKey) < Precision::Confusion() && aFreq == 0) + { + myLargestKey = 0; + for (NCollection_DataMap::Iterator anIter (myTolerances); anIter.More(); anIter.Next()) + { + if (anIter.Value() != 0) + myLargestKey = Max (myLargestKey, anIter.Key()); + } + } + } +} diff --git a/src/SelectMgr/SelectMgr_ToleranceMap.hxx b/src/SelectMgr/SelectMgr_ToleranceMap.hxx new file mode 100644 index 0000000000..098cef202e --- /dev/null +++ b/src/SelectMgr/SelectMgr_ToleranceMap.hxx @@ -0,0 +1,70 @@ +// Copyright (c) 2016 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// 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. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _SelectMgr_ToleranceMap_HeaderFile +#define _SelectMgr_ToleranceMap_HeaderFile + +#include +#include + +//! An internal class for calculation of current largest tolerance value which will be applied for creation of selecting frustum by default. +//! Each time the selection set is deactivated, maximum tolerance value will be recalculated. +//! If a user enables custom precision using StdSelect_ViewerSelector3d::SetPixelTolerance, it will be applied to all sensitive entities without any checks. +class SelectMgr_ToleranceMap +{ +public: + + //! Sets tolerance values to -1.0 + Standard_EXPORT SelectMgr_ToleranceMap(); + + Standard_EXPORT ~SelectMgr_ToleranceMap(); + + //! Adds the value given to map, checks if the current tolerance value + //! should be replaced by theTolerance + Standard_EXPORT void Add (const Standard_Integer& theTolerance); + + //! Decrements a counter of the tolerance given, checks if the current tolerance value + //! should be recalculated + Standard_EXPORT void Decrement (const Standard_Integer& theTolerance); + + //! Returns a current tolerance that must be applied + Standard_Integer Tolerance() const + { + if (myLargestKey < Precision::Confusion()) + { + return 2; // default tolerance value + } + return myCustomTolerance < 0 + ? myLargestKey + : myLargestKey + myCustomTolerance; + } + + //! Sets tolerance to the given one and disables adaptive checks + void SetCustomTolerance (const Standard_Integer theTolerance) { myCustomTolerance = theTolerance; } + + //! Unsets a custom tolerance and enables adaptive checks + void ResetDefaults() { myCustomTolerance = -1; } + + //! Returns the value of custom tolerance regardless of it validity + Standard_Integer CustomTolerance() const { return myCustomTolerance; } + + //! Returns true if custom tolerance value is greater than zero + Standard_Boolean IsCustomTolSet() const { return myCustomTolerance > 0; } + +private: + NCollection_DataMap myTolerances; + Standard_Integer myLargestKey; + Standard_Integer myCustomTolerance; +}; + +#endif // _SelectMgr_ToleranceMap_HeaderFile diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.cxx b/src/SelectMgr/SelectMgr_ViewerSelector.cxx index 3243627944..428bfe0cb7 100644 --- a/src/SelectMgr/SelectMgr_ViewerSelector.cxx +++ b/src/SelectMgr/SelectMgr_ViewerSelector.cxx @@ -14,16 +14,13 @@ // 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 #include #include #include #include #include -#include #include #include #include @@ -61,78 +58,24 @@ namespace { 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(); -} - -//======================================================================= -// 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 (aFreq == 1 && theTolerance != myLargestKey) - myLargestKey = Max (theTolerance, myLargestKey); - } - else + //! Compute 3d position for detected entity. + inline void updatePoint3d (SelectMgr_SortCriterion& theCriterion, + const gp_GTrsf& theInversedTrsf, + SelectMgr_SelectingVolumeManager& theMgr) { - if (myTolerances.IsEmpty()) + theCriterion.Point = theMgr.DetectedPoint (theCriterion.Depth); + gp_GTrsf anInvTrsf = theInversedTrsf; + if (theCriterion.Entity->HasInitLocation()) { - myTolerances.Bind (theTolerance, 1); - myLargestKey = theTolerance; - return; + anInvTrsf = theCriterion.Entity->InvInitLocation() * anInvTrsf; } - - myTolerances.Bind (theTolerance, 1); - myLargestKey = Max (theTolerance, myLargestKey); - } -} - -//======================================================================= -// 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 (Abs (theTolerance - myLargestKey) < Precision::Confusion() && aFreq == 0) + if (anInvTrsf.Form() != gp_Identity) { - myLargestKey = 0; - for (NCollection_DataMap::Iterator anIter (myTolerances); anIter.More(); anIter.Next()) - { - if (anIter.Value() != 0) - myLargestKey = Max (myLargestKey, anIter.Key()); - } + anInvTrsf.Inverted().Transforms (theCriterion.Point.ChangeCoord()); } } + } //================================================== @@ -189,7 +132,6 @@ void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& th void SelectMgr_ViewerSelector::Clear() { mystored.Clear(); - myMapOfDetected.Clear(); } //======================================================================= @@ -219,7 +161,7 @@ Standard_Integer SelectMgr_ViewerSelector::sensitivity (const Handle(SelectBasic // 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) { Handle(SelectMgr_EntityOwner) anOwner (Handle(SelectMgr_EntityOwner)::DownCast (theEntity->OwnerId())); @@ -240,27 +182,30 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive SelectMgr_SortCriterion aCriterion; myZLayerOrderMap.Find (aSelectable->ZLayer(), aCriterion.ZLayerPosition); + aCriterion.Entity = theEntity; aCriterion.Priority = anOwner->Priority(); aCriterion.Depth = aPickResult.Depth(); aCriterion.MinDist = aPickResult.DistToGeomCenter(); aCriterion.Tolerance = theEntity->SensitivityFactor() / 33.0; aCriterion.ToPreferClosest = preferclosest; - if (mystored.Contains (anOwner)) + + const Standard_Integer aPrevStoredIndex = mystored.FindIndex (anOwner); + if (aPrevStoredIndex != 0) { - if (theMgr.GetActiveSelectionType() != 1) + if (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Box) { - SelectMgr_SortCriterion& aPrevCriterion = mystored.ChangeFromKey (anOwner); + SelectMgr_SortCriterion& aPrevCriterion = mystored.ChangeFromIndex (aPrevStoredIndex); if (aCriterion > aPrevCriterion) { + updatePoint3d (aCriterion, theInversedTrsf, theMgr); aPrevCriterion = aCriterion; - myMapOfDetected.ChangeFind (anOwner) = theEntityIdx; } } } else { + updatePoint3d (aCriterion, theInversedTrsf, theMgr); mystored.Add (anOwner, aCriterion); - myMapOfDetected.Bind (anOwner, theEntityIdx); } } } @@ -409,7 +354,7 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive(); SelectMgr_SelectingVolumeManager aTmpMgr = aMgr; computeFrustum (anEnt, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr); - checkOverlap (anEnt, anIdx, aTmpMgr); + checkOverlap (anEnt, aInversedTrsf, aTmpMgr); } } if (aHead < 0) @@ -431,7 +376,6 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable void SelectMgr_ViewerSelector::TraverseSensitives() { mystored.Clear(); - myMapOfDetected.Clear(); NCollection_Handle > aBVHTree; for (Standard_Integer aBVHTreeIdx = 0; aBVHTreeIdx < 2; ++aBVHTreeIdx) @@ -543,67 +487,33 @@ Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector 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)::DownCast (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 -{ - return mystored.Extent(); -} -//======================================================================= -//function : Picked -//purpose : -//======================================================================= -Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked(const Standard_Integer aRank) const +const SelectMgr_SortCriterion& SelectMgr_ViewerSelector::PickedData(const Standard_Integer theRank) 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); } //=================================================== @@ -939,12 +849,8 @@ void SelectMgr_ViewerSelector::ResetSelectionActivationStatus() //======================================================================= 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& anEntitySet = - myMapOfObjectSensitives.Find (anObject); - - return anEntitySet->GetSensitiveById (myDetectedIter.Value())->BaseSensitive(); + const Standard_Integer aRankInMap = myIndexes->Value(myCurRank); + return mystored.FindFromIndex (aRankInMap).Entity; } //======================================================================= diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.hxx b/src/SelectMgr/SelectMgr_ViewerSelector.hxx index cdb1064eee..30f033fd76 100644 --- a/src/SelectMgr/SelectMgr_ViewerSelector.hxx +++ b/src/SelectMgr/SelectMgr_ViewerSelector.hxx @@ -14,10 +14,6 @@ // 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) - #ifndef _SelectMgr_ViewerSelector_HeaderFile #define _SelectMgr_ViewerSelector_HeaderFile @@ -27,10 +23,6 @@ #include #include #include - -#include -#include - #include #include #include @@ -38,67 +30,19 @@ #include #include #include +#include #include class SelectMgr_SelectionManager; -class SelectMgr_Selection; class SelectMgr_SensitiveEntitySet; class SelectMgr_EntityOwner; -class TCollection_AsciiString; class SelectBasics_SensitiveEntity; -class SelectMgr_SelectableObjectSet; typedef NCollection_DataMap > SelectMgr_MapOfObjectSensitives; typedef NCollection_DataMap >::Iterator SelectMgr_MapOfObjectSensitivesIterator; -typedef NCollection_DataMap SelectMgr_MapOfOwnerDetectedEntities; -typedef NCollection_DataMap::Iterator SelectMgr_MapOfOwnerDetectedEntitiesIterator; - typedef NCollection_DataMap SelectMgr_FrustumCache; -//! An internal class for calculation of current largest tolerance value which will be applied -//! for creation of selecting frustum by default. Each time the selection set is deactivated, -//! maximum tolerance value will be recalculated. If a user enables custom precision using -//! StdSelect_ViewerSelector3d::SetPixelTolerance, it will be applied to all sensitive entities -//! without any checks. -class SelectMgr_ToleranceMap -{ -public: - - //! Sets tolerance values to -1.0 - Standard_EXPORT SelectMgr_ToleranceMap(); - - Standard_EXPORT ~SelectMgr_ToleranceMap(); - - //! Adds the value given to map, checks if the current tolerance value - //! should be replaced by theTolerance - Standard_EXPORT void Add (const Standard_Integer& theTolerance); - - //! Decrements a counter of the tolerance given, checks if the current tolerance value - //! should be recalculated - Standard_EXPORT void Decrement (const Standard_Integer& theTolerance); - - //! Returns a current tolerance that must be applied - inline Standard_Integer Tolerance() const; - - //! Sets tolerance to the given one and disables adaptive checks - inline void SetCustomTolerance (const Standard_Integer theTolerance); - - //! Unsets a custom tolerance and enables adaptive checks - inline void ResetDefaults(); - - //! Returns the value of custom tolerance regardless of it validity - inline Standard_Integer CustomTolerance() const; - - //! Returns true if custom tolerance value is greater than zero - inline Standard_Boolean IsCustomTolSet() const; - -private: - NCollection_DataMap myTolerances; - Standard_Integer myLargestKey; - Standard_Integer myCustomTolerance; -}; - //! A framework to define finding, sorting the sensitive //! primitives in a view. Services are also provided to //! define the return of the owners of those primitives @@ -131,37 +75,28 @@ private: //! intersection detection will be resized according to its sensitivity. class SelectMgr_ViewerSelector : public MMgt_TShared { + DEFINE_STANDARD_RTTIEXT(SelectMgr_ViewerSelector, MMgt_TShared) + friend class SelectMgr_SelectionManager; public: //! Empties all the tables, removes all selections... Standard_EXPORT void Clear(); //! returns the Sensitivity of picking - Standard_Real Sensitivity() const; + Standard_Real Sensitivity() const { return myTolerances.Tolerance(); } //! Sorts the detected entites by priority and distance. //! to be redefined if other criterion are used... Standard_EXPORT void SortResult(); - //! Begins an iteration scanning for the owners detected at a position in the view. - void Init(); - - //! Continues the interation scanning for the owners - //! detected at a position in the view, or - //! - continues the iteration scanning for the owner - //! closest to the position in the view. - Standard_EXPORT Standard_Boolean More(); - - //! Returns the next owner found in the iteration. This is - //! a scan for the owners detected at a position in the view. - void Next(); - - //! Returns the current selected entity detected by the selector; - Standard_EXPORT Handle(SelectMgr_EntityOwner) Picked() const; - //! Returns the picked element with the highest priority, //! and which is the closest to the last successful mouse position. - Standard_EXPORT Handle(SelectMgr_EntityOwner) OnePicked(); + Handle(SelectMgr_EntityOwner) OnePicked() const + { + return mystored.IsEmpty() + ? Handle(SelectMgr_EntityOwner)() + : Picked (1); + } //! Set preference of selecting one object for OnePicked() method: //! - If True, objects with less depth (distance fron the view plane) are @@ -169,15 +104,27 @@ public: //! objects with similar depth), //! - If False, objects with higher priority are preferred regardless of the //! depth which is used to choose among objects of the same priority. - void SetPickClosest (const Standard_Boolean preferClosest); + void SetPickClosest (const Standard_Boolean theToPreferClosest) { preferclosest = theToPreferClosest; } + + //! Returns the number of detected owners. + Standard_Integer NbPicked() const { return mystored.Extent(); } + + //! Returns the entity Owner for the object picked at specified position. + //! @param theRank rank of detected object within range 1...NbPicked() + Standard_EXPORT Handle(SelectMgr_EntityOwner) Picked (const Standard_Integer theRank) const; + + //! Returns the Entity for the object picked at specified position. + //! @param theRank rank of detected object within range 1...NbPicked() + Standard_EXPORT const SelectMgr_SortCriterion& PickedData (const Standard_Integer theRank) const; - //! Returns the number of owners found at a position in - //! the view by the Init - More - Next - Picked iteration. - Standard_EXPORT Standard_Integer NbPicked() const; + //! Returns the Entity for the object picked at specified position. + //! @param theRank rank of detected object within range 1...NbPicked() + const Handle(SelectBasics_SensitiveEntity)& PickedEntity (const Standard_Integer theRank) const { return PickedData (theRank).Entity; } - //! Returns the entity which is at rank - //! in the list of stored ones. - Standard_EXPORT Handle(SelectMgr_EntityOwner) Picked (const Standard_Integer aRank) const; + //! Returns the 3D point (intersection of picking axis with the object nearest to eye) + //! for the object picked at specified position. + //! @param theRank rank of detected object within range 1...NbPicked() + gp_Pnt PickedPoint (const Standard_Integer theRank) const { return PickedData (theRank).Point; } Standard_EXPORT Standard_Boolean Contains (const Handle(SelectMgr_SelectableObject)& theObject) const; @@ -238,22 +185,8 @@ public: Standard_EXPORT void RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject, const Standard_Boolean theIsForce = Standard_False); - //! Initializes internal iterator for stored detected sensitive entities - void InitDetected(); - - //! Makes a step along the map of detected sensitive entities and their owners - void NextDetected(); - - //! Returns true if iterator of map of detected sensitive entities has reached - //! its end - Standard_Boolean MoreDetected(); - - //! Returns sensitive entity that was detected during the previous run of - //! selection algorithm - Standard_EXPORT const Handle(SelectBasics_SensitiveEntity)& DetectedEntity() const; - //! Returns instance of selecting volume manager of the viewer selector - SelectMgr_SelectingVolumeManager& GetManager(); + SelectMgr_SelectingVolumeManager& GetManager() { return mySelectingVolumeMgr; } //! Marks all added sensitive entities of all objects as non-selectable Standard_EXPORT void ResetSelectionActivationStatus(); @@ -263,9 +196,41 @@ public: //! mark both included and overlapped entities as matched Standard_EXPORT void AllowOverlapDetection (const Standard_Boolean theIsToAllow); - friend class SelectMgr_SelectionManager; +public: + + //! Begins an iteration scanning for the owners detected at a position in the view. + Standard_DEPRECATED("Deprecated method Init()") + void Init() { initPicked(); } + + //! Continues the interation scanning for the owners detected at a position in the view, + //! or continues the iteration scanning for the owner closest to the position in the view. + Standard_DEPRECATED("Deprecated method More()") + Standard_EXPORT Standard_Boolean More() { return morePicked(); } + + //! Returns the next owner found in the iteration. This is + //! a scan for the owners detected at a position in the view. + Standard_DEPRECATED("Deprecated method Next()") + void Next() { nextPicked(); } + + //! Returns the current selected entity detected by the selector; + Standard_DEPRECATED("Deprecated method Picked()") + Standard_EXPORT Handle(SelectMgr_EntityOwner) Picked() const; + + //! Initializes internal iterator for stored detected sensitive entities + Standard_DEPRECATED("Deprecated method InitDetected()") + void InitDetected() { initPicked(); } - DEFINE_STANDARD_RTTIEXT(SelectMgr_ViewerSelector,MMgt_TShared) + //! Makes a step along the map of detected sensitive entities and their owners + Standard_DEPRECATED("Deprecated method NextDetected()") + void NextDetected() { nextPicked(); } + + //! Returns true if iterator of map of detected sensitive entities has reached its end + Standard_DEPRECATED("Deprecated method MoreDetected()") + Standard_Boolean MoreDetected() { return morePicked(); } + + //! Returns sensitive entity that was detected during the previous run of selection algorithm + Standard_DEPRECATED("Deprecated method DetectedEntity() should be replaced by DetectedEntity(int)") + Standard_EXPORT const Handle(SelectBasics_SensitiveEntity)& DetectedEntity() const; protected: @@ -291,7 +256,7 @@ protected: //! Internal function that checks if a particular sensitive //! entity theEntity overlaps current selecting volume precisely Standard_EXPORT void checkOverlap (const Handle(SelectBasics_SensitiveEntity)& theEntity, - const Standard_Integer theEntityIdx, + const gp_GTrsf& theInversedTrsf, SelectMgr_SelectingVolumeManager& theMgr); private: @@ -319,6 +284,22 @@ private: SelectMgr_SelectingVolumeManager& theResMgr); +private: // implementation of deprecated methods + + //! Initializes internal iterator for stored detected sensitive entities + void initPicked() { myCurRank = 1; } + + //! Makes a step along the map of detected sensitive entities and their owners + void nextPicked() { ++myCurRank; } + + //! Returns true if iterator of map of detected sensitive entities has reached its end + Standard_Boolean morePicked() const + { + if (mystored.Extent() == 0) return Standard_False; + if (myCurRank == 0) return Standard_False; + return myCurRank <= myIndexes->Length(); + } + protected: Standard_Boolean preferclosest; @@ -337,12 +318,9 @@ private: Standard_Boolean myIsLeftChildQueuedFirst; Standard_Integer myEntityIdx; SelectMgr_MapOfObjectSensitives myMapOfObjectSensitives; - SelectMgr_MapOfOwnerDetectedEntities myMapOfDetected; - SelectMgr_MapOfOwnerDetectedEntitiesIterator myDetectedIter; + }; DEFINE_STANDARD_HANDLE(SelectMgr_ViewerSelector, MMgt_TShared) -#include - #endif diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.lxx b/src/SelectMgr/SelectMgr_ViewerSelector.lxx deleted file mode 100644 index f26b33dab1..0000000000 --- a/src/SelectMgr/SelectMgr_ViewerSelector.lxx +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) 1998-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// 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. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -//======================================================================= -// function: Tolerance -// purpose : Returns a current tolerance that must be applied -//======================================================================= -inline Standard_Integer SelectMgr_ToleranceMap::Tolerance() const -{ - if (myLargestKey < Precision::Confusion()) - return 2; // default tolerance value - - return myCustomTolerance < 0 ? myLargestKey : myLargestKey + myCustomTolerance; -} - -//======================================================================= -// function: SetCustomTolerance -// purpose : Sets tolerance to the given one and disables adaptive checks -//======================================================================= -inline void SelectMgr_ToleranceMap::SetCustomTolerance (const Standard_Integer theTolerance) -{ - myCustomTolerance = theTolerance; -} - -//======================================================================= -// function: CustomTolerance -// purpose : Returns current value of custom tolerance regardless of it is set or not -//======================================================================= -inline Standard_Integer SelectMgr_ToleranceMap::CustomTolerance() const -{ - return myCustomTolerance; -} - -//======================================================================= -// function: IsCustomTolSet -// purpose : Checks if custom tolerance value is greater than zero -//======================================================================= -inline Standard_Boolean SelectMgr_ToleranceMap::IsCustomTolSet() const -{ - return myCustomTolerance > 0; -} - -//======================================================================= -// function: ResetDefaults -// purpose : Unsets a custom tolerance and enables adaptive checks -//======================================================================= -inline void SelectMgr_ToleranceMap::ResetDefaults() -{ - myCustomTolerance = -1; -} - -inline Standard_Real SelectMgr_ViewerSelector::Sensitivity() const -{ - return myTolerances.Tolerance(); -} - -inline void SelectMgr_ViewerSelector::Init() -{ - myCurRank = 1; -} - -inline void SelectMgr_ViewerSelector::Next() -{ - myCurRank++; -} - -inline void SelectMgr_ViewerSelector::SetPickClosest (const Standard_Boolean preferClosest) -{ - preferclosest = preferClosest; -} - -inline void SelectMgr_ViewerSelector::InitDetected() -{ - myDetectedIter.Initialize (myMapOfDetected); -} - -inline void SelectMgr_ViewerSelector::NextDetected() -{ - myDetectedIter.Next(); -} - -inline Standard_Boolean SelectMgr_ViewerSelector::MoreDetected() -{ - return myDetectedIter.More(); -} - -inline SelectMgr_SelectingVolumeManager& SelectMgr_ViewerSelector::GetManager() -{ - return mySelectingVolumeMgr; -} diff --git a/src/ViewerTest/ViewerTest.cxx b/src/ViewerTest/ViewerTest.cxx index 0b1e63a022..a342d1ab95 100644 --- a/src/ViewerTest/ViewerTest.cxx +++ b/src/ViewerTest/ViewerTest.cxx @@ -76,13 +76,6 @@ #include #include -// avoid warnings on 'extern "C"' functions returning C++ classes -#ifdef _MSC_VER -#define _CRT_SECURE_NO_DEPRECATE -#pragma warning(4:4190) -#pragma warning (disable:4996) -#endif - extern int ViewerMainLoop(Standard_Integer argc, const char** argv); #include @@ -4467,67 +4460,20 @@ static Standard_Integer VState (Draw_Interpretor& theDI, theDI << "Detected entities:\n"; Handle(StdSelect_ViewerSelector3d) aSelector = aCtx->HasOpenedContext() ? aCtx->LocalSelector() : aCtx->MainSelector(); SelectMgr_SelectingVolumeManager aMgr = aSelector->GetManager(); - for (aSelector->InitDetected(); aSelector->MoreDetected(); aSelector->NextDetected()) + for (Standard_Integer aPickIter = 1; aPickIter <= aSelector->NbPicked(); ++aPickIter) { - const Handle(SelectBasics_SensitiveEntity)& anEntity = aSelector->DetectedEntity(); + const SelectMgr_SortCriterion& aPickData = aSelector->PickedData (aPickIter); + const Handle(SelectBasics_SensitiveEntity)& anEntity = aSelector->PickedEntity (aPickIter); Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast (anEntity->OwnerId()); Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable()); - gp_GTrsf anInvTrsf; - if (anObj->TransformPersistence().Flags) - { - const Graphic3d_Mat4d& aProjection = aMgr.ProjectionMatrix(); - const Graphic3d_Mat4d& aWorldView = aMgr.WorldViewMatrix(); - - Standard_Integer aViewportWidth = 0; - Standard_Integer aViewportHeight = 0; - aMgr.WindowSize (aViewportWidth, aViewportHeight); - - Graphic3d_Mat4d aMat = anObj->TransformPersistence().Compute (aMgr.Camera(), aProjection, aWorldView, aViewportWidth, aViewportHeight); - - anInvTrsf.SetValue (1, 1, aMat.GetValue (0, 0)); - anInvTrsf.SetValue (1, 2, aMat.GetValue (0, 1)); - anInvTrsf.SetValue (1, 3, aMat.GetValue (0, 2)); - anInvTrsf.SetValue (2, 1, aMat.GetValue (1, 0)); - anInvTrsf.SetValue (2, 2, aMat.GetValue (1, 1)); - anInvTrsf.SetValue (2, 3, aMat.GetValue (1, 2)); - anInvTrsf.SetValue (3, 1, aMat.GetValue (2, 0)); - anInvTrsf.SetValue (3, 2, aMat.GetValue (2, 1)); - anInvTrsf.SetValue (3, 3, aMat.GetValue (2, 2)); - anInvTrsf.SetTranslationPart (gp_XYZ(aMat.GetValue (0, 3), aMat.GetValue (1, 3), aMat.GetValue (2, 3))); - anInvTrsf.Invert(); - } - if (anObj->HasTransformation()) - { - anInvTrsf = anObj->InversedTransformation() * anInvTrsf; - } - if (anEntity->HasInitLocation()) - { - anInvTrsf = anEntity->InvInitLocation() * anInvTrsf; - } - const Standard_Integer aScale = anEntity->SensitivityFactor() < aSelector->PixelTolerance() - ? anEntity->SensitivityFactor() : 1; - const Standard_Boolean isToScaleAndTransform = anInvTrsf.Form() != gp_Identity || aScale != 1; - SelectMgr_SelectingVolumeManager anEntMgr = - isToScaleAndTransform ? aMgr.ScaleAndTransform (aScale, anInvTrsf) - : aMgr; - SelectBasics_PickResult aResult; - anEntity->Matches (anEntMgr, aResult); - - gp_Pnt aDetectedPnt = anEntMgr.DetectedPoint (aResult.Depth()); - - if (anInvTrsf.Form() != gp_Identity) - { - anInvTrsf.Inverted().Transforms (aDetectedPnt.ChangeCoord()); - } - TCollection_AsciiString aName = GetMapOfAIS().Find1 (anObj); aName.LeftJustify (20, ' '); char anInfoStr[512]; Sprintf (anInfoStr, " Depth: %+.3f Distance: %+.3f Point: %+.3f %+.3f %+.3f", - aResult.Depth(), - aResult.DistToGeomCenter(), - aDetectedPnt.X(), aDetectedPnt.Y(), aDetectedPnt.Z()); + aPickData.Depth, + aPickData.MinDist, + aPickData.Point.X(), aPickData.Point.Y(), aPickData.Point.Z()); theDI << " " << aName << anInfoStr << " (" << anEntity->DynamicType()->Name() << ")"