From 47d2f208d2e883f502090608fb86c9a4b2505f00 Mon Sep 17 00:00:00 2001 From: dpasukhi Date: Wed, 6 May 2026 19:42:08 +0100 Subject: [PATCH] Visualization - Refactor selection management and presentation handling - Added new test file `AIS_InteractiveContext_Test.cxx` to GTests. - Replaced `NCollection_List` with `NCollection_LinearVector` in `PrsMgr_PresentationManager` for improved performance and memory management. - Updated methods in `PrsMgr_PresentationManager` to use index-based access instead of iterator-based loops. - Refactored `SelectMgr_SelectableObject` to utilize `NCollection_LinearVector` for selections, enhancing efficiency in selection handling. - Simplified selection iteration in `SelectMgr_SelectionManager`, `SelectMgr_ViewerSelector`, and `SelectMgr_SelectionImageFiller` by using index-based loops. - Changed `NCollection_Map` to `NCollection_FlatMap` in `V3d_Viewer` for better performance in layer ID management. --- .../D3DHost/D3DHost_GraphicDriver.cxx | 6 +- .../TKOpenGl/OpenGl/OpenGl_FrameStats.cxx | 14 +- .../TKOpenGl/OpenGl/OpenGl_GraphicDriver.cxx | 6 +- .../TKOpenGl/OpenGl/OpenGl_LayerList.cxx | 209 ++++---- .../TKOpenGl/OpenGl/OpenGl_LayerList.hxx | 35 +- .../TKOpenGl/OpenGl/OpenGl_ShaderManager.cxx | 28 +- .../TKOpenGl/OpenGl/OpenGl_ShaderManager.hxx | 11 +- .../TKOpenGl/OpenGl/OpenGl_ShaderProgram.cxx | 126 ++--- .../TKOpenGl/OpenGl/OpenGl_ShaderProgram.hxx | 25 +- .../TKOpenGl/OpenGl/OpenGl_View.cxx | 23 +- .../TKOpenGl/OpenGl/OpenGl_View.hxx | 3 +- .../TKOpenGl/OpenGl/OpenGl_View_Raytrace.cxx | 6 +- .../GTests/Graphic3d_Aspects_Test.cxx | 56 +++ .../TKService/Graphic3d/Graphic3d_CView.cxx | 18 +- .../TKService/Graphic3d/Graphic3d_CView.hxx | 6 +- .../Graphic3d/Graphic3d_GraphicDriver.cxx | 114 ++--- .../Graphic3d/Graphic3d_GraphicDriver.hxx | 11 +- .../Graphic3d/Graphic3d_ShaderProgram.cxx | 30 +- .../Graphic3d/Graphic3d_ShaderProgram.hxx | 35 +- .../TKV3d/AIS/AIS_GlobalStatus.hxx | 22 +- .../TKV3d/AIS/AIS_InteractiveContext.cxx | 194 ++++---- .../TKV3d/AIS/AIS_InteractiveContext.hxx | 8 +- .../TKV3d/AIS/AIS_PointCloud.cxx | 10 +- src/Visualization/TKV3d/AIS/AIS_Selection.cxx | 64 +-- src/Visualization/TKV3d/AIS/AIS_Selection.hxx | 30 +- .../TKV3d/AIS/AIS_SelectionModes.hxx | 121 +++++ src/Visualization/TKV3d/AIS/FILES.cmake | 1 + .../GTests/AIS_InteractiveContext_Test.cxx | 448 ++++++++++++++++++ src/Visualization/TKV3d/GTests/FILES.cmake | 1 + .../PrsMgr/PrsMgr_PresentationManager.cxx | 51 +- .../PrsMgr/PrsMgr_PresentationManager.hxx | 10 +- .../SelectMgr/SelectMgr_SelectableObject.cxx | 179 +++---- .../SelectMgr/SelectMgr_SelectableObject.hxx | 19 +- .../SelectMgr_SelectionImageFiller.cxx | 28 +- .../SelectMgr/SelectMgr_SelectionManager.cxx | 61 +-- .../SelectMgr/SelectMgr_ViewerSelector.cxx | 37 +- src/Visualization/TKV3d/V3d/V3d_Viewer.hxx | 4 +- 37 files changed, 1272 insertions(+), 778 deletions(-) create mode 100644 src/Visualization/TKV3d/AIS/AIS_SelectionModes.hxx create mode 100644 src/Visualization/TKV3d/GTests/AIS_InteractiveContext_Test.cxx diff --git a/src/Visualization/TKD3DHost/D3DHost/D3DHost_GraphicDriver.cxx b/src/Visualization/TKD3DHost/D3DHost/D3DHost_GraphicDriver.cxx index edca2cd351b..12dd4f3b351 100644 --- a/src/Visualization/TKD3DHost/D3DHost/D3DHost_GraphicDriver.cxx +++ b/src/Visualization/TKD3DHost/D3DHost/D3DHost_GraphicDriver.cxx @@ -42,11 +42,9 @@ occ::handle D3DHost_GraphicDriver::CreateView( { occ::handle aView = new D3DHost_View(theMgr, this, myCaps, &myStateCounter); myMapOfView.Add(aView); - for (NCollection_List>::Iterator aLayerIter(myLayers); - aLayerIter.More(); - aLayerIter.Next()) + for (size_t i = 0; i < myLayers.Size(); ++i) { - const occ::handle& aLayer = aLayerIter.Value(); + const occ::handle& aLayer = myLayers.Value(i); aView->InsertLayerAfter(aLayer->LayerId(), aLayer->LayerSettings(), Graphic3d_ZLayerId_UNKNOWN); } return aView; diff --git a/src/Visualization/TKOpenGl/OpenGl/OpenGl_FrameStats.cxx b/src/Visualization/TKOpenGl/OpenGl/OpenGl_FrameStats.cxx index 01da8899c31..0ea8b1cb16d 100644 --- a/src/Visualization/TKOpenGl/OpenGl/OpenGl_FrameStats.cxx +++ b/src/Visualization/TKOpenGl/OpenGl/OpenGl_FrameStats.cxx @@ -99,16 +99,16 @@ void OpenGl_FrameStats::updateStatistics(const occ::handle& the || (aBits & Graphic3d_RenderingParams::PerfCounters_Layers) != 0 || toCountGroups; - myCountersTmp[Graphic3d_FrameStatsCounter_NbLayers] = aView->LayerList().Layers().Size(); + myCountersTmp[Graphic3d_FrameStatsCounter_NbLayers] = + static_cast(aView->LayerList().Layers().Size()); if (toCountStructs || (aBits & Graphic3d_RenderingParams::PerfCounters_Layers) != 0) { - const int aViewId = aView->Identification(); - for (NCollection_List>::Iterator aLayerIter( - aView->LayerList().Layers()); - aLayerIter.More(); - aLayerIter.Next()) + const int aViewId = aView->Identification(); + const NCollection_LinearVector>& aLayers_ = + aView->LayerList().Layers(); + for (size_t aLayerIdx_ = 0; aLayerIdx_ < aLayers_.Size(); ++aLayerIdx_) { - const occ::handle& aLayer = aLayerIter.Value(); + const occ::handle& aLayer = aLayers_.Value(aLayerIdx_); myCountersTmp[Graphic3d_FrameStatsCounter_NbStructs] += aLayer->NbStructures(); if (theIsImmediateOnly && !aLayer->LayerSettings().IsImmediate()) { diff --git a/src/Visualization/TKOpenGl/OpenGl/OpenGl_GraphicDriver.cxx b/src/Visualization/TKOpenGl/OpenGl/OpenGl_GraphicDriver.cxx index 32f4f2284d9..844bf248235 100644 --- a/src/Visualization/TKOpenGl/OpenGl/OpenGl_GraphicDriver.cxx +++ b/src/Visualization/TKOpenGl/OpenGl/OpenGl_GraphicDriver.cxx @@ -788,11 +788,9 @@ occ::handle OpenGl_GraphicDriver::CreateView( { occ::handle aView = new OpenGl_View(theMgr, this, myCaps, &myStateCounter); myMapOfView.Add(aView); - for (NCollection_List>::Iterator aLayerIter(myLayers); - aLayerIter.More(); - aLayerIter.Next()) + for (size_t i = 0; i < myLayers.Size(); ++i) { - const occ::handle& aLayer = aLayerIter.Value(); + const occ::handle& aLayer = myLayers.Value(i); aView->InsertLayerAfter(aLayer->LayerId(), aLayer->LayerSettings(), Graphic3d_ZLayerId_UNKNOWN); } return aView; diff --git a/src/Visualization/TKOpenGl/OpenGl/OpenGl_LayerList.cxx b/src/Visualization/TKOpenGl/OpenGl/OpenGl_LayerList.cxx index e604fe515b6..2e2c309da53 100644 --- a/src/Visualization/TKOpenGl/OpenGl/OpenGl_LayerList.cxx +++ b/src/Visualization/TKOpenGl/OpenGl/OpenGl_LayerList.cxx @@ -28,29 +28,46 @@ namespace { -//! Auxiliary class extending sequence iterator with index. -class OpenGl_IndexedLayerIterator : public NCollection_List>::Iterator +//! Linear-scan index iterator over the layer vector. +class OpenGl_IndexedLayerIterator { public: //! Main constructor. - OpenGl_IndexedLayerIterator(const NCollection_List>& theSeq) - : NCollection_List>::Iterator(theSeq), + OpenGl_IndexedLayerIterator( + const NCollection_LinearVector>& theLayers) + : myLayers(&theLayers), + myPos(0), myIndex(1) { } - //! Return index of current position. + //! Return TRUE if iterator points at a valid layer. + bool More() const { return myPos < myLayers->Size(); } + + //! Return current layer handle (matches map iterator's Value() shape). + const occ::handle& Value() const { return myLayers->Value(myPos); } + + //! Return current layer handle (mutable). + occ::handle& ChangeValue() const + { + return const_cast>*>(myLayers) + ->ChangeValue(myPos); + } + + //! Return index of current position (1-based for backward compatibility). int Index() const { return myIndex; } //! Move to the next position. void Next() { - NCollection_List>::Iterator::Next(); + ++myPos; ++myIndex; } private: - int myIndex; + const NCollection_LinearVector>* myLayers; + size_t myPos; + int myIndex; }; //! Iterator through layers with filter. @@ -58,11 +75,12 @@ class OpenGl_FilteredIndexedLayerIterator { public: //! Main constructor. - OpenGl_FilteredIndexedLayerIterator(const NCollection_List>& theSeq, - bool theToDrawImmediate, - OpenGl_LayerFilter theFilterMode, - Graphic3d_ZLayerId theLayersToProcess) - : myIter(theSeq), + OpenGl_FilteredIndexedLayerIterator( + const NCollection_LinearVector>& theLayers, + bool theToDrawImmediate, + OpenGl_LayerFilter theFilterMode, + Graphic3d_ZLayerId theLayersToProcess) + : myIter(theLayers), myFilterMode(theFilterMode), myToDrawImmediate(theToDrawImmediate), myLayersToProcess(theLayersToProcess) @@ -182,13 +200,31 @@ OpenGl_LayerList::~OpenGl_LayerList() = default; void OpenGl_LayerList::SetFrustumCullingBVHBuilder(const occ::handle& theBuilder) { myBVHBuilder = theBuilder; - for (NCollection_List>::Iterator aLayerIter(myLayers); - aLayerIter.More(); - aLayerIter.Next()) + for (size_t i = 0; i < myLayers.Size(); ++i) + { + myLayers.ChangeValue(i)->SetFrustumCullingBVHBuilder(theBuilder); + } +} + +namespace +{ +//! Linear-scan index lookup of a layer by ID. +constexpr size_t THE_NPOS = static_cast(-1); + +static size_t findLayerIndex( + const NCollection_LinearVector>& theLayers, + const Graphic3d_ZLayerId theLayerId) +{ + for (size_t i = 0; i < theLayers.Size(); ++i) { - aLayerIter.ChangeValue()->SetFrustumCullingBVHBuilder(theBuilder); + if (theLayers.Value(i)->LayerId() == theLayerId) + { + return i; + } } + return THE_NPOS; } +} // namespace //================================================================================================= @@ -196,7 +232,7 @@ void OpenGl_LayerList::InsertLayerBefore(const Graphic3d_ZLayerId theNewL const Graphic3d_ZLayerSettings& theSettings, const Graphic3d_ZLayerId theLayerAfter) { - if (myLayerIds.IsBound(theNewLayerId)) + if (findLayerIndex(myLayers, theNewLayerId) != THE_NPOS) { return; } @@ -204,27 +240,18 @@ void OpenGl_LayerList::InsertLayerBefore(const Graphic3d_ZLayerId theNewL occ::handle aNewLayer = new Graphic3d_Layer(theNewLayerId, myBVHBuilder); aNewLayer->SetLayerSettings(theSettings); - occ::handle anOtherLayer; - if (theLayerAfter != Graphic3d_ZLayerId_UNKNOWN && myLayerIds.Find(theLayerAfter, anOtherLayer)) + const size_t anAnchor = theLayerAfter != Graphic3d_ZLayerId_UNKNOWN + ? findLayerIndex(myLayers, theLayerAfter) + : THE_NPOS; + if (anAnchor == THE_NPOS) { - for (NCollection_List>::Iterator aLayerIter(myLayers); - aLayerIter.More(); - aLayerIter.Next()) - { - if (aLayerIter.Value() == anOtherLayer) - { - myLayers.InsertBefore(aNewLayer, aLayerIter); - break; - } - } + myLayers.InsertBefore(0, aNewLayer); } else { - myLayers.Prepend(aNewLayer); + myLayers.InsertBefore(anAnchor, aNewLayer); } - - myLayerIds.Bind(theNewLayerId, aNewLayer); - myTransparentToProcess.Allocate(myLayers.Length()); + myTransparentToProcess.Allocate(static_cast(myLayers.Size())); } //================================================================================================= @@ -233,7 +260,7 @@ void OpenGl_LayerList::InsertLayerAfter(const Graphic3d_ZLayerId theNewLa const Graphic3d_ZLayerSettings& theSettings, const Graphic3d_ZLayerId theLayerBefore) { - if (myLayerIds.IsBound(theNewLayerId)) + if (findLayerIndex(myLayers, theNewLayerId) != THE_NPOS) { return; } @@ -241,47 +268,44 @@ void OpenGl_LayerList::InsertLayerAfter(const Graphic3d_ZLayerId theNewLa occ::handle aNewLayer = new Graphic3d_Layer(theNewLayerId, myBVHBuilder); aNewLayer->SetLayerSettings(theSettings); - occ::handle anOtherLayer; - if (theLayerBefore != Graphic3d_ZLayerId_UNKNOWN && myLayerIds.Find(theLayerBefore, anOtherLayer)) + const size_t anAnchor = theLayerBefore != Graphic3d_ZLayerId_UNKNOWN + ? findLayerIndex(myLayers, theLayerBefore) + : THE_NPOS; + if (anAnchor == THE_NPOS) { - for (NCollection_List>::Iterator aLayerIter(myLayers); - aLayerIter.More(); - aLayerIter.Next()) - { - if (aLayerIter.Value() == anOtherLayer) - { - myLayers.InsertAfter(aNewLayer, aLayerIter); - break; - } - } + myLayers.Append(aNewLayer); } else { - myLayers.Append(aNewLayer); + myLayers.InsertAfter(anAnchor, aNewLayer); } - - myLayerIds.Bind(theNewLayerId, aNewLayer); - myTransparentToProcess.Allocate(myLayers.Length()); + myTransparentToProcess.Allocate(static_cast(myLayers.Size())); } //================================================================================================= void OpenGl_LayerList::RemoveLayer(const Graphic3d_ZLayerId theLayerId) { - occ::handle aLayerToRemove; - if (theLayerId <= 0 || !myLayerIds.Find(theLayerId, aLayerToRemove)) + if (theLayerId <= 0) { return; } + const size_t anIndex = findLayerIndex(myLayers, theLayerId); + if (anIndex == THE_NPOS) + { + return; + } + const occ::handle aLayerToRemove = myLayers.Value(anIndex); - // move all displayed structures to first layer - myLayerIds.Find(Graphic3d_ZLayerId_Default)->Append(*aLayerToRemove); - - // remove layer - myLayers.Remove(aLayerToRemove); - myLayerIds.UnBind(theLayerId); + // move all displayed structures to default layer + const size_t aDefaultIndex = findLayerIndex(myLayers, Graphic3d_ZLayerId_Default); + if (aDefaultIndex != THE_NPOS) + { + myLayers.Value(aDefaultIndex)->Append(*aLayerToRemove); + } - myTransparentToProcess.Allocate(myLayers.Length()); + myLayers.Erase(anIndex); + myTransparentToProcess.Allocate(static_cast(myLayers.Size())); } //================================================================================================= @@ -293,9 +317,10 @@ void OpenGl_LayerList::AddStructure(const OpenGl_Structure* theStruct, { // add structure to associated layer, // if layer doesn't exists, display structure in default layer - const occ::handle* aLayerPtr = myLayerIds.Seek(theLayerId); - const occ::handle& aLayer = - aLayerPtr != nullptr ? *aLayerPtr : myLayerIds.Find(Graphic3d_ZLayerId_Default); + const size_t aLayerIdx = findLayerIndex(myLayers, theLayerId); + const size_t aLayerActualIdx = + aLayerIdx != THE_NPOS ? aLayerIdx : findLayerIndex(myLayers, Graphic3d_ZLayerId_Default); + const occ::handle& aLayer = myLayers.Value(aLayerActualIdx); aLayer->Add(theStruct, thePriority, isForChangePriority); ++myNbStructures; if (aLayer->IsImmediate()) @@ -312,10 +337,11 @@ void OpenGl_LayerList::AddStructure(const OpenGl_Structure* theStruct, void OpenGl_LayerList::RemoveStructure(const OpenGl_Structure* theStructure) { - const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer(); - const occ::handle* aLayerPtr = myLayerIds.Seek(aLayerId); - const occ::handle& aLayer = - aLayerPtr != nullptr ? *aLayerPtr : myLayerIds.Find(Graphic3d_ZLayerId_Default); + const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer(); + const size_t aLayerIdx = findLayerIndex(myLayers, aLayerId); + const size_t aLayerActualIdx = + aLayerIdx != THE_NPOS ? aLayerIdx : findLayerIndex(myLayers, Graphic3d_ZLayerId_Default); + const occ::handle& aLayer = myLayers.Value(aLayerActualIdx); Graphic3d_DisplayPriority aPriority = Graphic3d_DisplayPriority_INVALID; @@ -339,11 +365,9 @@ void OpenGl_LayerList::RemoveStructure(const OpenGl_Structure* theStructure) } // scan through layers and remove it - for (NCollection_List>::Iterator aLayerIter(myLayers); - aLayerIter.More(); - aLayerIter.Next()) + for (size_t aLayerIdx_ = 0; aLayerIdx_ < myLayers.Size(); ++aLayerIdx_) { - const occ::handle& aLayerEx = aLayerIter.ChangeValue(); + const occ::handle& aLayerEx = myLayers.ChangeValue(aLayerIdx_); if (aLayerEx == aLayer) { continue; @@ -370,9 +394,10 @@ void OpenGl_LayerList::RemoveStructure(const OpenGl_Structure* theStructure) void OpenGl_LayerList::InvalidateBVHData(const Graphic3d_ZLayerId theLayerId) { - const occ::handle* aLayerPtr = myLayerIds.Seek(theLayerId); - const occ::handle& aLayer = - aLayerPtr != nullptr ? *aLayerPtr : myLayerIds.Find(Graphic3d_ZLayerId_Default); + const size_t aLayerIdx = findLayerIndex(myLayers, theLayerId); + const size_t aLayerActualIdx = + aLayerIdx != THE_NPOS ? aLayerIdx : findLayerIndex(myLayers, Graphic3d_ZLayerId_Default); + const occ::handle& aLayer = myLayers.Value(aLayerActualIdx); aLayer->InvalidateBVHData(); } @@ -382,9 +407,10 @@ void OpenGl_LayerList::ChangeLayer(const OpenGl_Structure* theStructure, const Graphic3d_ZLayerId theOldLayerId, const Graphic3d_ZLayerId theNewLayerId) { - const occ::handle* aLayerPtr = myLayerIds.Seek(theOldLayerId); - const occ::handle& aLayer = - aLayerPtr != nullptr ? *aLayerPtr : myLayerIds.Find(Graphic3d_ZLayerId_Default); + const size_t aLayerIdx = findLayerIndex(myLayers, theOldLayerId); + const size_t aLayerActualIdx = + aLayerIdx != THE_NPOS ? aLayerIdx : findLayerIndex(myLayers, Graphic3d_ZLayerId_Default); + const occ::handle& aLayer = myLayers.Value(aLayerActualIdx); Graphic3d_DisplayPriority aPriority = Graphic3d_DisplayPriority_INVALID; @@ -411,11 +437,9 @@ void OpenGl_LayerList::ChangeLayer(const OpenGl_Structure* theStructure, } // scan through layers and remove it - for (NCollection_List>::Iterator aLayerIter(myLayers); - aLayerIter.More(); - aLayerIter.Next()) + for (size_t aLayerIdx_ = 0; aLayerIdx_ < myLayers.Size(); ++aLayerIdx_) { - const occ::handle& aLayerEx = aLayerIter.ChangeValue(); + const occ::handle& aLayerEx = myLayers.ChangeValue(aLayerIdx_); if (aLayerEx == aLayer) { continue; @@ -450,9 +474,10 @@ void OpenGl_LayerList::ChangePriority(const OpenGl_Structure* theStructu const Graphic3d_ZLayerId theLayerId, const Graphic3d_DisplayPriority theNewPriority) { - const occ::handle* aLayerPtr = myLayerIds.Seek(theLayerId); - const occ::handle& aLayer = - aLayerPtr != nullptr ? *aLayerPtr : myLayerIds.Find(Graphic3d_ZLayerId_Default); + const size_t aLayerIdx = findLayerIndex(myLayers, theLayerId); + const size_t aLayerActualIdx = + aLayerIdx != THE_NPOS ? aLayerIdx : findLayerIndex(myLayers, Graphic3d_ZLayerId_Default); + const occ::handle& aLayer = myLayers.Value(aLayerActualIdx); Graphic3d_DisplayPriority anOldPriority = Graphic3d_DisplayPriority_INVALID; if (aLayer->Remove(theStructure, anOldPriority, true)) @@ -467,11 +492,9 @@ void OpenGl_LayerList::ChangePriority(const OpenGl_Structure* theStructu return; } - for (NCollection_List>::Iterator aLayerIter(myLayers); - aLayerIter.More(); - aLayerIter.Next()) + for (size_t aLayerIdx_ = 0; aLayerIdx_ < myLayers.Size(); ++aLayerIdx_) { - const occ::handle& aLayerEx = aLayerIter.ChangeValue(); + const occ::handle& aLayerEx = myLayers.ChangeValue(aLayerIdx_); if (aLayerEx == aLayer) { continue; @@ -527,11 +550,9 @@ void OpenGl_LayerList::UpdateCulling(const occ::handle& theWor const int aViewId = theWorkspace->View()->Identification(); const Graphic3d_CullingTool& aSelector = theWorkspace->View()->BVHTreeSelector(); - for (NCollection_List>::Iterator aLayerIter(myLayers); - aLayerIter.More(); - aLayerIter.Next()) + for (size_t aLayerIdx_ = 0; aLayerIdx_ < myLayers.Size(); ++aLayerIdx_) { - const occ::handle& aLayer = aLayerIter.ChangeValue(); + const occ::handle& aLayer = myLayers.ChangeValue(aLayerIdx_); if (aLayer->IsImmediate() != theToDrawImmediate) { continue; @@ -1284,11 +1305,9 @@ void OpenGl_LayerList::DumpJson(Standard_OStream& theOStream, int theDepth) cons { OCCT_DUMP_CLASS_BEGIN(theOStream, OpenGl_LayerList) - for (NCollection_List>::Iterator aLayersIt(myLayers); - aLayersIt.More(); - aLayersIt.Next()) + for (size_t aLayerIdx_ = 0; aLayerIdx_ < myLayers.Size(); ++aLayerIdx_) { - const occ::handle& aLayerId = aLayersIt.Value(); + const occ::handle& aLayerId = myLayers.Value(aLayerIdx_); OCCT_DUMP_FIELD_VALUES_DUMPED(theOStream, theDepth, aLayerId.get()) } diff --git a/src/Visualization/TKOpenGl/OpenGl/OpenGl_LayerList.hxx b/src/Visualization/TKOpenGl/OpenGl/OpenGl_LayerList.hxx index b6cf163b7c6..54c1f9bf019 100644 --- a/src/Visualization/TKOpenGl/OpenGl/OpenGl_LayerList.hxx +++ b/src/Visualization/TKOpenGl/OpenGl/OpenGl_LayerList.hxx @@ -22,7 +22,7 @@ #include #include #include -#include +#include class OpenGl_FrameBuffer; class OpenGl_Structure; @@ -85,12 +85,12 @@ public: const Graphic3d_DisplayPriority theNewPriority); //! Returns reference to the layer with given ID. - OpenGl_Layer& Layer(const Graphic3d_ZLayerId theLayerId) { return *myLayerIds.Find(theLayerId); } + OpenGl_Layer& Layer(const Graphic3d_ZLayerId theLayerId) { return *findLayer(theLayerId); } //! Returns reference to the layer with given ID. const OpenGl_Layer& Layer(const Graphic3d_ZLayerId theLayerId) const { - return *myLayerIds.Find(theLayerId); + return *findLayer(theLayerId); } //! Assign new settings to the layer. @@ -109,14 +109,8 @@ public: OpenGl_FrameBuffer* theReadDrawFbo, OpenGl_FrameBuffer* theOitAccumFbo) const; - //! Returns the set of OpenGL Z-layers. - const NCollection_List>& Layers() const { return myLayers; } - - //! Returns the map of Z-layer IDs to indexes. - const NCollection_DataMap>& LayerIDs() const - { - return myLayerIds; - } + //! Returns the list of Z-layers in render order. + const NCollection_LinearVector>& Layers() const { return myLayers; } //! Marks BVH tree for given priority list as dirty and //! marks primitive set for rebuild. @@ -211,8 +205,23 @@ protected: const Graphic3d_Layer& theLayer) const; protected: - NCollection_List> myLayers; - NCollection_DataMap> myLayerIds; + //! Linear-scan lookup of a layer by id; returns null when not found. + //! Defined inline so the const/non-const Layer() accessors stay header-resident. + Graphic3d_Layer* findLayer(const Graphic3d_ZLayerId theLayerId) const + { + for (size_t i = 0; i < myLayers.Size(); ++i) + { + const occ::handle& aLayer = myLayers.Value(i); + if (aLayer->LayerId() == theLayerId) + { + return aLayer.get(); + } + } + return nullptr; + } + +protected: + NCollection_LinearVector> myLayers; //!< layers in render order occ::handle myBVHBuilder; //!< BVH tree builder for frustum culling int myNbStructures; diff --git a/src/Visualization/TKOpenGl/OpenGl/OpenGl_ShaderManager.cxx b/src/Visualization/TKOpenGl/OpenGl/OpenGl_ShaderManager.cxx index 4ee733255d8..c5d88cb0b45 100644 --- a/src/Visualization/TKOpenGl/OpenGl/OpenGl_ShaderManager.cxx +++ b/src/Visualization/TKOpenGl/OpenGl/OpenGl_ShaderManager.cxx @@ -199,7 +199,7 @@ bool OpenGl_ShaderManager::Create(const occ::handle& th { if (theProgram->Share()) { - myProgramList.Append(theProgram); + myProgramList.Add(theProgram); } return true; } @@ -213,7 +213,7 @@ bool OpenGl_ShaderManager::Create(const occ::handle& th return false; } - myProgramList.Append(theProgram); + myProgramList.Add(theProgram); myContext->ShareResource(theShareKey, theProgram); return true; } @@ -225,24 +225,20 @@ bool OpenGl_ShaderManager::Create(const occ::handle& th void OpenGl_ShaderManager::Unregister(TCollection_AsciiString& theShareKey, occ::handle& theProgram) { - for (NCollection_Sequence>::Iterator anIt(myProgramList); - anIt.More(); - anIt.Next()) + if (!myProgramList.Contains(theProgram)) { - if (anIt.Value() == theProgram) - { - if (!theProgram->UnShare()) - { - theShareKey.Clear(); - theProgram.Nullify(); - return; - } + return; + } - myProgramList.Remove(anIt); - break; - } + if (!theProgram->UnShare()) + { + theShareKey.Clear(); + theProgram.Nullify(); + return; } + myProgramList.Remove(theProgram); + const TCollection_AsciiString anID = theProgram->myProxy->GetId(); if (anID.IsEmpty()) { diff --git a/src/Visualization/TKOpenGl/OpenGl/OpenGl_ShaderManager.hxx b/src/Visualization/TKOpenGl/OpenGl/OpenGl_ShaderManager.hxx index c7c7cb1f6c2..edd65e9de65 100644 --- a/src/Visualization/TKOpenGl/OpenGl/OpenGl_ShaderManager.hxx +++ b/src/Visualization/TKOpenGl/OpenGl/OpenGl_ShaderManager.hxx @@ -27,9 +27,9 @@ #include #include -class OpenGl_VertexBuffer; +#include -//! List of shader programs. +class OpenGl_VertexBuffer; //! This class is responsible for managing shader programs. class OpenGl_ShaderManager : public Graphic3d_ShaderManager @@ -86,7 +86,7 @@ public: occ::handle& theProgram); //! Returns list of registered shader programs. - const NCollection_Sequence>& ShaderPrograms() const + const NCollection_OrderedMap>& ShaderPrograms() const { return myProgramList; } @@ -788,9 +788,8 @@ protected: occ::handle myFfpProgram; Graphic3d_TypeOfShadingModel myShadingModel; //!< lighting shading model - NCollection_Sequence> - myProgramList; //!< The list of shader programs - // clang-format off + NCollection_OrderedMap> myProgramList; //!< Shader programs + // clang-format off occ::handle myLightPrograms; //!< pointer to active lighting programs matrix occ::handle myUnlitPrograms; //!< programs matrix without lighting occ::handle myOutlinePrograms; //!< programs matrix without lighting for outline presentation diff --git a/src/Visualization/TKOpenGl/OpenGl/OpenGl_ShaderProgram.cxx b/src/Visualization/TKOpenGl/OpenGl/OpenGl_ShaderProgram.cxx index 9db6023d4bc..e3ac1036cdb 100644 --- a/src/Visualization/TKOpenGl/OpenGl/OpenGl_ShaderProgram.cxx +++ b/src/Visualization/TKOpenGl/OpenGl/OpenGl_ShaderProgram.cxx @@ -165,13 +165,15 @@ OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector() // ======================================================================= void OpenGl_VariableSetterSelector::Set(const occ::handle& theCtx, const occ::handle& theVariable, - OpenGl_ShaderProgram* theProgram) const + OpenGl_ShaderProgram* theProgram, + GLint theLocation) const { Standard_ASSERT_RETURN(mySetterList.IsBound(theVariable->Value()->TypeID()), "The type of user-defined uniform variable is not supported...", Standard_VOID_RETURN); - mySetterList.Find(theVariable->Value()->TypeID())->Set(theCtx, theVariable, theProgram); + mySetterList.Find(theVariable->Value()->TypeID()) + ->Set(theCtx, theVariable, theProgram, theLocation); } // ======================================================================= @@ -201,8 +203,8 @@ OpenGl_ShaderProgram::OpenGl_ShaderProgram(const occ::handle& theCtx, - const NCollection_Sequence>& theShaders) + const occ::handle& theCtx, + const NCollection_LinearVector>& theShaders) { myHasTessShader = false; if (theCtx.IsNull() || !Create(theCtx)) @@ -213,11 +215,9 @@ bool OpenGl_ShaderProgram::Initialize( TCollection_AsciiString aHeaderVer = !myProxy.IsNull() ? myProxy->Header() : TCollection_AsciiString(); int aShaderMask = 0; - for (NCollection_Sequence>::Iterator anIter(theShaders); - anIter.More(); - anIter.Next()) + for (size_t i = 0; i < theShaders.Size(); ++i) { - aShaderMask |= anIter.Value()->Type(); + aShaderMask |= theShaders.Value(i)->Type(); } myHasTessShader = (aShaderMask & (Graphic3d_TOS_TESS_CONTROL | Graphic3d_TOS_TESS_EVALUATION)) != 0; @@ -351,11 +351,10 @@ bool OpenGl_ShaderProgram::Initialize( } } - for (NCollection_Sequence>::Iterator anIter(theShaders); - anIter.More(); - anIter.Next()) + for (size_t aShaderIdx_ = 0; aShaderIdx_ < theShaders.Size(); ++aShaderIdx_) { - if (!anIter.Value()->IsDone()) + const occ::handle& aSrcShader = theShaders.Value(aShaderIdx_); + if (!aSrcShader->IsDone()) { const TCollection_ExtendedString aMsg = "Error! Failed to get shader source"; theCtx->PushMessage(GL_DEBUG_SOURCE_APPLICATION, @@ -366,7 +365,7 @@ bool OpenGl_ShaderProgram::Initialize( return false; } - const GLenum aShaderType = shaderTypeToGl(anIter.Value()->Type()); + const GLenum aShaderType = shaderTypeToGl(aSrcShader->Type()); if (aShaderType == 0) { return false; @@ -447,7 +446,7 @@ bool OpenGl_ShaderProgram::Initialize( } TCollection_AsciiString aPrecisionHeader; - if (anIter.Value()->Type() == Graphic3d_TOS_FRAGMENT + if (aSrcShader->Type() == Graphic3d_TOS_FRAGMENT && theCtx->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGLES) { aPrecisionHeader = theCtx->hasHighp ? "precision highp float;\n" @@ -457,7 +456,7 @@ bool OpenGl_ShaderProgram::Initialize( } TCollection_AsciiString aHeaderType; - switch (anIter.Value()->Type()) + switch (aSrcShader->Type()) { case Graphic3d_TOS_COMPUTE: { aHeaderType = "#define COMPUTE_SHADER\n"; @@ -545,7 +544,7 @@ bool OpenGl_ShaderProgram::Initialize( + Shaders_Declarations_glsl // common declarations (global constants and Vertex Shader inputs) + Shaders_DeclarationsImpl_glsl // clang-format off - + anIter.Value()->Source(); // the source code itself (defining main() function) + + aSrcShader->Source(); // the source code itself (defining main() function) // clang-format on if (!aShader->LoadAndCompile(theCtx, myResourceId, aSource)) { @@ -559,8 +558,7 @@ bool OpenGl_ShaderProgram::Initialize( if (theCtx->caps->glslDumpLevel == OpenGl_ShaderProgramDumpLevel_Short) { anOutputSource = aHeaderVer + (!aHeaderVer.IsEmpty() ? "\n" : "") + anExtensions - + aPrecisionHeader + aHeaderType + aHeaderConstants - + anIter.Value()->Source(); + + aPrecisionHeader + aHeaderType + aHeaderConstants + aSrcShader->Source(); } aShader->DumpSourceCode(theCtx, myResourceId, anOutputSource); } @@ -581,14 +579,12 @@ bool OpenGl_ShaderProgram::Initialize( // bind custom Vertex Attributes if (!myProxy.IsNull()) { - for (NCollection_Sequence>::Iterator anAttribIter( - myProxy->VertexAttributes()); - anAttribIter.More(); - anAttribIter.Next()) + const NCollection_LinearVector>& anAttribs = + myProxy->VertexAttributes(); + for (size_t i = 0; i < anAttribs.Size(); ++i) { - SetAttributeName(theCtx, - anAttribIter.Value()->Location(), - anAttribIter.Value()->Name().ToCString()); + const occ::handle& anAttr = anAttribs.Value(i); + SetAttributeName(theCtx, anAttr->Location(), anAttr->Name().ToCString()); } } @@ -723,17 +719,15 @@ bool OpenGl_ShaderProgram::AttachShader(const occ::handle& return false; } - for (NCollection_Sequence>::Iterator anIter(myShaderObjects); - anIter.More(); - anIter.Next()) + for (size_t i = 0; i < myShaderObjects.Size(); ++i) { - if (theShader == anIter.Value()) + if (myShaderObjects.Value(i) == theShader) { return false; } } - myShaderObjects.Append(theShader); + theCtx->core20fwd->glAttachShader(myProgramID, theShader->myShaderID); return true; } @@ -750,19 +744,17 @@ bool OpenGl_ShaderProgram::DetachShader(const occ::handle& return false; } - NCollection_Sequence>::Iterator anIter(myShaderObjects); - while (anIter.More()) + bool isFound = false; + for (size_t i = 0; i < myShaderObjects.Size(); ++i) { - if (theShader == anIter.Value()) + if (myShaderObjects.Value(i) == theShader) { - myShaderObjects.Remove(anIter); + myShaderObjects.Erase(i); + isFound = true; break; } - - anIter.Next(); } - - if (!anIter.More()) + if (!isFound) { return false; } @@ -775,6 +767,7 @@ bool OpenGl_ShaderProgram::DetachShader(const occ::handle& bool OpenGl_ShaderProgram::link(const occ::handle& theCtx) { + myUniformLocations.Clear(); if (myProgramID == NO_PROGRAM) { return false; @@ -873,12 +866,15 @@ bool OpenGl_ShaderProgram::ApplyVariables(const occ::handle& the return false; } - for (NCollection_Sequence>::Iterator anIter( - myProxy->Variables()); + for (NCollection_OrderedDataMap>::Iterator + anIter(myProxy->Variables()); anIter.More(); anIter.Next()) { - mySetterSelector.Set(theCtx, anIter.Value(), this); + const OpenGl_ShaderUniformLocation aLocation = + GetUniformLocation(theCtx, anIter.Key().ToCString()); + mySetterSelector.Set(theCtx, anIter.Value(), this, aLocation); } myProxy->ClearVariables(); @@ -893,9 +889,23 @@ OpenGl_ShaderUniformLocation OpenGl_ShaderProgram::GetUniformLocation( const occ::handle& theCtx, const GLchar* theName) const { - return OpenGl_ShaderUniformLocation( - myProgramID != NO_PROGRAM ? theCtx->core20fwd->glGetUniformLocation(myProgramID, theName) - : INVALID_LOCATION); + if (myProgramID == NO_PROGRAM || theCtx.IsNull() || theCtx->core20fwd == nullptr + || theName == nullptr) + { + return OpenGl_ShaderUniformLocation(INVALID_LOCATION); + } + + const TCollection_AsciiString aName(theName); + OpenGl_ShaderUniformLocation aLocation; + if (myUniformLocations.Find(aName, aLocation)) + { + return aLocation; + } + + aLocation = + OpenGl_ShaderUniformLocation(theCtx->core20fwd->glGetUniformLocation(myProgramID, theName)); + myUniformLocations.Bind(aName, aLocation); + return aLocation; } // ======================================================================= @@ -1508,6 +1518,7 @@ bool OpenGl_ShaderProgram::Create(const occ::handle& theCtx) void OpenGl_ShaderProgram::Release(OpenGl_Context* theCtx) { + myUniformLocations.Clear(); if (myProgramID == NO_PROGRAM) { return; @@ -1518,16 +1529,15 @@ void OpenGl_ShaderProgram::Release(OpenGl_Context* theCtx) "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...", Standard_VOID_RETURN); - for (NCollection_Sequence>::Iterator anIter(myShaderObjects); - anIter.More(); - anIter.Next()) + for (size_t i = 0; i < myShaderObjects.Size(); ++i) { - if (!anIter.Value().IsNull()) + const occ::handle& aShader = myShaderObjects.Value(i); + if (!aShader.IsNull()) { - anIter.ChangeValue()->Release(theCtx); - anIter.ChangeValue().Nullify(); + aShader->Release(theCtx); } } + myShaderObjects.Clear(); if (theCtx->core20fwd != nullptr && theCtx->IsValid()) { @@ -1561,20 +1571,16 @@ bool OpenGl_ShaderProgram::UpdateDebugDump(const occ::handle& th } bool hasUpdates = false; - for (NCollection_Sequence>::Iterator anIter(myShaderObjects); - anIter.More(); - anIter.Next()) + for (size_t i = 0; i < myShaderObjects.Size(); ++i) { - if (!anIter.Value().IsNull()) + const occ::handle& aShader = myShaderObjects.Value(i); + if (!aShader.IsNull()) { // desktop OpenGL (but not OpenGL ES) allows multiple shaders of the same stage to be // attached, but here we expect only single source per stage - hasUpdates = anIter.ChangeValue()->updateDebugDump(theCtx, - myResourceId, - aFolder, - theToBeautify, - theToReset) - || hasUpdates; + hasUpdates = + aShader->updateDebugDump(theCtx, myResourceId, aFolder, theToBeautify, theToReset) + || hasUpdates; } } if (hasUpdates) diff --git a/src/Visualization/TKOpenGl/OpenGl/OpenGl_ShaderProgram.hxx b/src/Visualization/TKOpenGl/OpenGl/OpenGl_ShaderProgram.hxx index a61e6f20e92..e43e6f3da81 100644 --- a/src/Visualization/TKOpenGl/OpenGl/OpenGl_ShaderProgram.hxx +++ b/src/Visualization/TKOpenGl/OpenGl/OpenGl_ShaderProgram.hxx @@ -17,7 +17,7 @@ #define OpenGl_ShaderProgram_HeaderFile #include -#include +#include #include #include @@ -100,7 +100,8 @@ struct OpenGl_SetterInterface //! Sets user-defined uniform variable to specified program. virtual void Set(const occ::handle& theCtx, const occ::handle& theVariable, - OpenGl_ShaderProgram* theProgram) = 0; + OpenGl_ShaderProgram* theProgram, + GLint theLocation) = 0; //! Destructor virtual ~OpenGl_SetterInterface() = default; @@ -123,7 +124,8 @@ public: //! Sets user-defined uniform variable to specified program. void Set(const occ::handle& theCtx, const occ::handle& theVariable, - OpenGl_ShaderProgram* theProgram) const; + OpenGl_ShaderProgram* theProgram, + GLint theLocation) const; private: //! List of variable setters. @@ -245,8 +247,8 @@ public: //! Initializes program object with the list of shader objects. Standard_EXPORT bool Initialize( - const occ::handle& theCtx, - const NCollection_Sequence>& theShaders); + const occ::handle& theCtx, + const NCollection_LinearVector>& theShaders); //! Links the program object. //! @param theCtx bound OpenGL context @@ -640,8 +642,8 @@ protected: protected: GLuint myProgramID; //!< Handle of OpenGL shader program - NCollection_Sequence> - myShaderObjects; //!< List of attached shader objects + NCollection_LinearVector> + myShaderObjects; //!< attached shader objects in attachment order // clang-format off occ::handle myProxy; //!< Proxy shader program (from application layer) int myShareCount; //!< program users count, initialized with 1 (already shared by one user) @@ -661,6 +663,10 @@ protected: //! Stores locations of OCCT state uniform variables. OpenGl_ShaderUniformLocation myStateLocations[OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES]; + + //! Cached locations of GLSL uniform variables by name. + mutable NCollection_DataMap + myUniformLocations; }; template @@ -668,9 +674,10 @@ struct OpenGl_VariableSetter : public OpenGl_SetterInterface { void Set(const occ::handle& theCtx, const occ::handle& theVariable, - OpenGl_ShaderProgram* theProgram) override + OpenGl_ShaderProgram* theProgram, + GLint theLocation) override { - theProgram->SetUniform(theCtx, theVariable->Name().ToCString(), theVariable->Value()->As()); + theProgram->SetUniform(theCtx, theLocation, theVariable->Value()->As()); } }; diff --git a/src/Visualization/TKOpenGl/OpenGl/OpenGl_View.cxx b/src/Visualization/TKOpenGl/OpenGl/OpenGl_View.cxx index 99c789adbd1..d24c00d04bd 100644 --- a/src/Visualization/TKOpenGl/OpenGl/OpenGl_View.cxx +++ b/src/Visualization/TKOpenGl/OpenGl/OpenGl_View.cxx @@ -907,18 +907,16 @@ void OpenGl_View::SetZLayerSettings(const Graphic3d_ZLayerId theLayerId, int OpenGl_View::ZLayerMax() const { int aLayerMax = Graphic3d_ZLayerId_Default; - for (NCollection_List>::Iterator aLayerIter(myZLayers.Layers()); - aLayerIter.More(); - aLayerIter.Next()) + for (size_t i = 0; i < myZLayers.Layers().Size(); ++i) { - aLayerMax = std::max(aLayerMax, aLayerIter.Value()->LayerId()); + aLayerMax = std::max(aLayerMax, myZLayers.Layers().Value(i)->LayerId()); } return aLayerMax; } //================================================================================================= -const NCollection_List>& OpenGl_View::Layers() const +const NCollection_LinearVector>& OpenGl_View::Layers() const { return myZLayers.Layers(); } @@ -927,12 +925,19 @@ const NCollection_List>& OpenGl_View::Layers() cons occ::handle OpenGl_View::Layer(const Graphic3d_ZLayerId theLayerId) const { - occ::handle aLayer; - if (theLayerId != Graphic3d_ZLayerId_UNKNOWN) + if (theLayerId == Graphic3d_ZLayerId_UNKNOWN) { - myZLayers.LayerIDs().Find(theLayerId, aLayer); + return occ::handle(); } - return aLayer; + for (size_t i = 0; i < myZLayers.Layers().Size(); ++i) + { + const occ::handle& aLayer = myZLayers.Layers().Value(i); + if (aLayer->LayerId() == theLayerId) + { + return aLayer; + } + } + return occ::handle(); } //================================================================================================= diff --git a/src/Visualization/TKOpenGl/OpenGl/OpenGl_View.hxx b/src/Visualization/TKOpenGl/OpenGl/OpenGl_View.hxx index e806a2f4961..72e1f9b0a25 100644 --- a/src/Visualization/TKOpenGl/OpenGl/OpenGl_View.hxx +++ b/src/Visualization/TKOpenGl/OpenGl/OpenGl_View.hxx @@ -148,7 +148,8 @@ public: Standard_EXPORT int ZLayerMax() const override; //! Returns the list of layers. - Standard_EXPORT const NCollection_List>& Layers() const override; + Standard_EXPORT const NCollection_LinearVector>& Layers() + const override; //! Returns layer with given ID or NULL if undefined. Standard_EXPORT occ::handle Layer( diff --git a/src/Visualization/TKOpenGl/OpenGl/OpenGl_View_Raytrace.cxx b/src/Visualization/TKOpenGl/OpenGl/OpenGl_View_Raytrace.cxx index d2f39537a08..90925e67a96 100644 --- a/src/Visualization/TKOpenGl/OpenGl/OpenGl_View_Raytrace.cxx +++ b/src/Visualization/TKOpenGl/OpenGl/OpenGl_View_Raytrace.cxx @@ -108,11 +108,9 @@ bool OpenGl_View::updateRaytraceGeometry(const RaytraceUpdateMode theM // of changes in OpenGL scene (only for path tracing) NCollection_Map aNonRaytraceIDs; - for (NCollection_List>::Iterator aLayerIter(myZLayers.Layers()); - aLayerIter.More(); - aLayerIter.Next()) + for (size_t aLayerIdx_ = 0; aLayerIdx_ < myZLayers.Layers().Size(); ++aLayerIdx_) { - const occ::handle& aLayer = aLayerIter.Value(); + const occ::handle& aLayer = myZLayers.Layers().Value(aLayerIdx_); if (aLayer->NbStructures() == 0 || !aLayer->LayerSettings().IsRaytracable() || aLayer->LayerSettings().IsImmediate()) { diff --git a/src/Visualization/TKService/GTests/Graphic3d_Aspects_Test.cxx b/src/Visualization/TKService/GTests/Graphic3d_Aspects_Test.cxx index 3c99d0a6531..4c62b46d352 100644 --- a/src/Visualization/TKService/GTests/Graphic3d_Aspects_Test.cxx +++ b/src/Visualization/TKService/GTests/Graphic3d_Aspects_Test.cxx @@ -16,6 +16,62 @@ #include #include #include +#include +#include +#include + +TEST(Graphic3d_ShaderProgramTest, PushVariable_OverwritesByNamePreservesOrder) +{ + occ::handle aProgram = new Graphic3d_ShaderProgram(); + + EXPECT_TRUE(aProgram->PushVariableFloat("uFirst", 1.0f)); + EXPECT_TRUE(aProgram->PushVariableInt("uSecond", 2)); + EXPECT_TRUE(aProgram->PushVariableFloat("uFirst", 3.0f)); + + const NCollection_OrderedDataMap>& + aVariables = aProgram->Variables(); + ASSERT_EQ(2, aVariables.Extent()); + + NCollection_OrderedDataMap>::Iterator + aVariableIter(aVariables); + ASSERT_TRUE(aVariableIter.More()); + EXPECT_EQ(TCollection_AsciiString("uFirst"), aVariableIter.Key()); + EXPECT_FLOAT_EQ(3.0f, aVariableIter.Value()->Value()->As()); + + aVariableIter.Next(); + ASSERT_TRUE(aVariableIter.More()); + EXPECT_EQ(TCollection_AsciiString("uSecond"), aVariableIter.Key()); + EXPECT_EQ(2, aVariableIter.Value()->Value()->As()); + + aProgram->ClearVariables(); + EXPECT_TRUE(aProgram->Variables().IsEmpty()); +} + +TEST(Graphic3d_ShaderProgramTest, AttachShader_DeduplicatesAndPreservesOrder) +{ + occ::handle aProgram = new Graphic3d_ShaderProgram(); + occ::handle aVertexShader = + Graphic3d_ShaderObject::CreateFromSource(Graphic3d_TOS_VERTEX, "void main() {}\n"); + occ::handle aFragmentShader = + Graphic3d_ShaderObject::CreateFromSource(Graphic3d_TOS_FRAGMENT, "void main() {}\n"); + + ASSERT_FALSE(aVertexShader.IsNull()); + ASSERT_FALSE(aFragmentShader.IsNull()); + EXPECT_TRUE(aProgram->AttachShader(aVertexShader)); + EXPECT_FALSE(aProgram->AttachShader(aVertexShader)); + EXPECT_TRUE(aProgram->AttachShader(aFragmentShader)); + ASSERT_EQ(size_t(2), aProgram->ShaderObjects().Size()); + + EXPECT_EQ(aVertexShader, aProgram->ShaderObjects().Value(0)); + EXPECT_EQ(aFragmentShader, aProgram->ShaderObjects().Value(1)); + + EXPECT_TRUE(aProgram->DetachShader(aVertexShader)); + EXPECT_FALSE(aProgram->DetachShader(aVertexShader)); + ASSERT_EQ(size_t(1), aProgram->ShaderObjects().Size()); + + EXPECT_EQ(aFragmentShader, aProgram->ShaderObjects().Value(0)); +} // Test: default shading model is DEFAULT. TEST(Graphic3d_AspectsTest, ShadingModel_Default) diff --git a/src/Visualization/TKService/Graphic3d/Graphic3d_CView.cxx b/src/Visualization/TKService/Graphic3d/Graphic3d_CView.cxx index 2db4ff07100..c5491a080dd 100644 --- a/src/Visualization/TKService/Graphic3d/Graphic3d_CView.cxx +++ b/src/Visualization/TKService/Graphic3d/Graphic3d_CView.cxx @@ -515,11 +515,9 @@ void Graphic3d_CView::InvalidateZLayerBoundingBox(const Graphic3d_ZLayerId theLa return; } - for (NCollection_List>::Iterator aLayerIter(Layers()); - aLayerIter.More(); - aLayerIter.Next()) + for (size_t i = 0; i < Layers().Size(); ++i) { - const occ::handle& aLayer = aLayerIter.Value(); + const occ::handle& aLayer = Layers().Value(i); if (aLayer->NbOfTransformPersistenceObjects() > 0) { aLayer->InvalidateBoundingBox(); @@ -554,11 +552,9 @@ Bnd_Box Graphic3d_CView::MinMaxValues(const bool theToIncludeAuxiliary) const Window()->Size(aWinSize.x(), aWinSize.y()); Bnd_Box aResult; - for (NCollection_List>::Iterator aLayerIter(Layers()); - aLayerIter.More(); - aLayerIter.Next()) + for (size_t i = 0; i < Layers().Size(); ++i) { - const occ::handle& aLayer = aLayerIter.Value(); + const occ::handle& aLayer = Layers().Value(i); Bnd_Box aBox = aLayer->BoundingBox(Identification(), aCamera, aWinSize.x(), @@ -583,11 +579,9 @@ double Graphic3d_CView::ConsiderZoomPersistenceObjects() Window()->Size(aWinSize.x(), aWinSize.y()); double aMaxCoef = 1.0; - for (NCollection_List>::Iterator aLayerIter(Layers()); - aLayerIter.More(); - aLayerIter.Next()) + for (size_t i = 0; i < Layers().Size(); ++i) { - const occ::handle& aLayer = aLayerIter.Value(); + const occ::handle& aLayer = Layers().Value(i); aMaxCoef = std::max(aMaxCoef, aLayer->considerZoomPersistenceObjects(Identification(), aCamera, diff --git a/src/Visualization/TKService/Graphic3d/Graphic3d_CView.hxx b/src/Visualization/TKService/Graphic3d/Graphic3d_CView.hxx index 285d4360f9b..5eb20de5f7c 100644 --- a/src/Visualization/TKService/Graphic3d/Graphic3d_CView.hxx +++ b/src/Visualization/TKService/Graphic3d/Graphic3d_CView.hxx @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -324,8 +326,8 @@ public: //! First layer ID is Graphic3d_ZLayerId_Default, last ID is ZLayerMax(). virtual int ZLayerMax() const = 0; - //! Returns the list of layers. - virtual const NCollection_List>& Layers() const = 0; + //! Returns the list of layers in render order. + virtual const NCollection_LinearVector>& Layers() const = 0; //! Returns layer with given ID or NULL if undefined. virtual occ::handle Layer(const Graphic3d_ZLayerId theLayerId) const = 0; diff --git a/src/Visualization/TKService/Graphic3d/Graphic3d_GraphicDriver.cxx b/src/Visualization/TKService/Graphic3d/Graphic3d_GraphicDriver.cxx index c0a9c308288..e51f48689d2 100644 --- a/src/Visualization/TKService/Graphic3d/Graphic3d_GraphicDriver.cxx +++ b/src/Visualization/TKService/Graphic3d/Graphic3d_GraphicDriver.cxx @@ -20,6 +20,25 @@ IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_GraphicDriver, Standard_Transient) +namespace +{ +constexpr size_t THE_NPOS = static_cast(-1); + +static size_t findLayerIndex( + const NCollection_LinearVector>& theLayers, + const Graphic3d_ZLayerId theLayerId) +{ + for (size_t i = 0; i < theLayers.Size(); ++i) + { + if (theLayers.Value(i)->LayerId() == theLayerId) + { + return i; + } + } + return THE_NPOS; +} +} // namespace + //================================================================================================= Graphic3d_GraphicDriver::Graphic3d_GraphicDriver( @@ -41,7 +60,6 @@ Graphic3d_GraphicDriver::Graphic3d_GraphicDriver( new Graphic3d_Layer(Graphic3d_ZLayerId_BotOSD, occ::handle()); aLayer->SetLayerSettings(aSettings); myLayers.Append(aLayer); - myLayerIds.Bind(aLayer->LayerId(), aLayer); } { @@ -58,7 +76,6 @@ Graphic3d_GraphicDriver::Graphic3d_GraphicDriver( new Graphic3d_Layer(Graphic3d_ZLayerId_Default, occ::handle()); aLayer->SetLayerSettings(aSettings); myLayers.Append(aLayer); - myLayerIds.Bind(aLayer->LayerId(), aLayer); } { @@ -75,7 +92,6 @@ Graphic3d_GraphicDriver::Graphic3d_GraphicDriver( new Graphic3d_Layer(Graphic3d_ZLayerId_Top, occ::handle()); aLayer->SetLayerSettings(aSettings); myLayers.Append(aLayer); - myLayerIds.Bind(aLayer->LayerId(), aLayer); } { @@ -92,7 +108,6 @@ Graphic3d_GraphicDriver::Graphic3d_GraphicDriver( new Graphic3d_Layer(Graphic3d_ZLayerId_Topmost, occ::handle()); aLayer->SetLayerSettings(aSettings); myLayers.Append(aLayer); - myLayerIds.Bind(aLayer->LayerId(), aLayer); } { @@ -109,7 +124,6 @@ Graphic3d_GraphicDriver::Graphic3d_GraphicDriver( new Graphic3d_Layer(Graphic3d_ZLayerId_TopOSD, occ::handle()); aLayer->SetLayerSettings(aSettings); myLayers.Append(aLayer); - myLayerIds.Bind(aLayer->LayerId(), aLayer); } } @@ -139,13 +153,13 @@ void Graphic3d_GraphicDriver::RemoveIdentification(const int theId) const Graphic3d_ZLayerSettings& Graphic3d_GraphicDriver::ZLayerSettings( const Graphic3d_ZLayerId theLayerId) const { - const occ::handle* aLayer = myLayerIds.Seek(theLayerId); - if (aLayer == nullptr) + const size_t anIndex = findLayerIndex(myLayers, theLayerId); + if (anIndex == THE_NPOS) { throw Standard_OutOfRange( "Graphic3d_GraphicDriver::ZLayerSettings, Layer with theLayerId does not exist"); } - return (*aLayer)->LayerSettings(); + return myLayers.Value(anIndex)->LayerSettings(); } //================================================================================================= @@ -155,11 +169,9 @@ void Graphic3d_GraphicDriver::ZLayers(NCollection_Sequence& theLayerSeq) co theLayerSeq.Clear(); // append normal layers - for (NCollection_List>::Iterator aLayerIter(myLayers); - aLayerIter.More(); - aLayerIter.Next()) + for (size_t i = 0; i < myLayers.Size(); ++i) { - const occ::handle& aLayer = aLayerIter.Value(); + const occ::handle& aLayer = myLayers.Value(i); if (!aLayer->IsImmediate()) { theLayerSeq.Append(aLayer->LayerId()); @@ -167,11 +179,9 @@ void Graphic3d_GraphicDriver::ZLayers(NCollection_Sequence& theLayerSeq) co } // append immediate layers - for (NCollection_List>::Iterator aLayerIter(myLayers); - aLayerIter.More(); - aLayerIter.Next()) + for (size_t i = 0; i < myLayers.Size(); ++i) { - const occ::handle& aLayer = aLayerIter.Value(); + const occ::handle& aLayer = myLayers.Value(i); if (aLayer->IsImmediate()) { theLayerSeq.Append(aLayer->LayerId()); @@ -189,32 +199,23 @@ void Graphic3d_GraphicDriver::InsertLayerBefore(const Graphic3d_ZLayerId theNewLayerId > 0, "Graphic3d_GraphicDriver::InsertLayerBefore, negative and zero IDs are reserved"); Standard_ASSERT_RAISE( - !myLayerIds.IsBound(theNewLayerId), + findLayerIndex(myLayers, theNewLayerId) == THE_NPOS, "Graphic3d_GraphicDriver::InsertLayerBefore, Layer with theLayerId already exists"); occ::handle aNewLayer = new Graphic3d_Layer(theNewLayerId, occ::handle()); aNewLayer->SetLayerSettings(theSettings); - occ::handle anOtherLayer; - if (theLayerAfter != Graphic3d_ZLayerId_UNKNOWN && myLayerIds.Find(theLayerAfter, anOtherLayer)) + const size_t anAnchor = theLayerAfter != Graphic3d_ZLayerId_UNKNOWN + ? findLayerIndex(myLayers, theLayerAfter) + : THE_NPOS; + if (anAnchor == THE_NPOS) { - for (NCollection_List>::Iterator aLayerIter(myLayers); - aLayerIter.More(); - aLayerIter.Next()) - { - if (aLayerIter.Value() == anOtherLayer) - { - myLayers.InsertBefore(aNewLayer, aLayerIter); - break; - } - } - } - else - { - myLayers.Prepend(aNewLayer); + // anchor not found - prepend + myLayers.InsertBefore(0, aNewLayer); + return; } - myLayerIds.Bind(theNewLayerId, aNewLayer); + myLayers.InsertBefore(anAnchor, aNewLayer); } //================================================================================================= @@ -227,32 +228,23 @@ void Graphic3d_GraphicDriver::InsertLayerAfter(const Graphic3d_ZLayerId t theNewLayerId > 0, "Graphic3d_GraphicDriver::InsertLayerAfter, negative and zero IDs are reserved"); Standard_ASSERT_RAISE( - !myLayerIds.IsBound(theNewLayerId), + findLayerIndex(myLayers, theNewLayerId) == THE_NPOS, "Graphic3d_GraphicDriver::InsertLayerAfter, Layer with theLayerId already exists"); occ::handle aNewLayer = new Graphic3d_Layer(theNewLayerId, occ::handle()); aNewLayer->SetLayerSettings(theSettings); - occ::handle anOtherLayer; - if (theLayerBefore != Graphic3d_ZLayerId_UNKNOWN && myLayerIds.Find(theLayerBefore, anOtherLayer)) - { - for (NCollection_List>::Iterator aLayerIter(myLayers); - aLayerIter.More(); - aLayerIter.Next()) - { - if (aLayerIter.Value() == anOtherLayer) - { - myLayers.InsertAfter(aNewLayer, aLayerIter); - break; - } - } - } - else + const size_t anAnchor = theLayerBefore != Graphic3d_ZLayerId_UNKNOWN + ? findLayerIndex(myLayers, theLayerBefore) + : THE_NPOS; + if (anAnchor == THE_NPOS) { + // anchor not found - append myLayers.Append(aNewLayer); + return; } - myLayerIds.Bind(theNewLayerId, aNewLayer); + myLayers.InsertAfter(anAnchor, aNewLayer); } //================================================================================================= @@ -263,13 +255,11 @@ void Graphic3d_GraphicDriver::RemoveZLayer(const Graphic3d_ZLayerId theLayerId) "Graphic3d_GraphicDriver::RemoveZLayer, negative and zero IDs are reserved " "and cannot be removed"); - occ::handle aLayerDef; - myLayerIds.Find(theLayerId, aLayerDef); + const size_t anIndex = findLayerIndex(myLayers, theLayerId); Standard_ASSERT_RAISE( - !aLayerDef.IsNull(), + anIndex != THE_NPOS, "Graphic3d_GraphicDriver::RemoveZLayer, Layer with theLayerId does not exist"); - myLayers.Remove(aLayerDef); - myLayerIds.UnBind(theLayerId); + myLayers.Erase(anIndex); } //================================================================================================= @@ -277,12 +267,11 @@ void Graphic3d_GraphicDriver::RemoveZLayer(const Graphic3d_ZLayerId theLayerId) void Graphic3d_GraphicDriver::SetZLayerSettings(const Graphic3d_ZLayerId theLayerId, const Graphic3d_ZLayerSettings& theSettings) { - occ::handle aLayerDef; - myLayerIds.Find(theLayerId, aLayerDef); + const size_t anIndex = findLayerIndex(myLayers, theLayerId); Standard_ASSERT_RAISE( - !aLayerDef.IsNull(), + anIndex != THE_NPOS, "Graphic3d_GraphicDriver::SetZLayerSettings, Layer with theLayerId does not exist"); - aLayerDef->SetLayerSettings(theSettings); + myLayers.Value(anIndex)->SetLayerSettings(theSettings); } //================================================================================================= @@ -293,10 +282,9 @@ void Graphic3d_GraphicDriver::DumpJson(Standard_OStream& theOStream, int theDept OCCT_DUMP_FIELD_VALUES_DUMPED(theOStream, theDepth, &myStructGenId) - for (NCollection_List>::Iterator anIter(myLayers); anIter.More(); - anIter.Next()) + for (size_t i = 0; i < myLayers.Size(); ++i) { - const occ::handle& aLayer = anIter.Value(); + const occ::handle& aLayer = myLayers.Value(i); OCCT_DUMP_FIELD_VALUES_DUMPED(theOStream, theDepth, aLayer.get()) } } diff --git a/src/Visualization/TKService/Graphic3d/Graphic3d_GraphicDriver.hxx b/src/Visualization/TKService/Graphic3d/Graphic3d_GraphicDriver.hxx index 0b4c566ad3e..0c69dd9748b 100644 --- a/src/Visualization/TKService/Graphic3d/Graphic3d_GraphicDriver.hxx +++ b/src/Visualization/TKService/Graphic3d/Graphic3d_GraphicDriver.hxx @@ -19,11 +19,13 @@ #include #include +#include #include #include #include -#include +#include #include +#include class Aspect_DisplayConnection; class Aspect_Window; @@ -147,10 +149,9 @@ protected: Standard_EXPORT Graphic3d_GraphicDriver(const occ::handle& theDisp); protected: - occ::handle myDisplayConnection; - Aspect_GenId myStructGenId; - NCollection_List> myLayers; - NCollection_DataMap> myLayerIds; + occ::handle myDisplayConnection; + Aspect_GenId myStructGenId; + NCollection_LinearVector> myLayers; //!< layers in render order }; #endif // _Graphic3d_GraphicDriver_HeaderFile diff --git a/src/Visualization/TKService/Graphic3d/Graphic3d_ShaderProgram.cxx b/src/Visualization/TKService/Graphic3d/Graphic3d_ShaderProgram.cxx index cd4510c674d..8e2b1bdc6aa 100644 --- a/src/Visualization/TKService/Graphic3d/Graphic3d_ShaderProgram.cxx +++ b/src/Visualization/TKService/Graphic3d/Graphic3d_ShaderProgram.cxx @@ -108,11 +108,9 @@ bool Graphic3d_ShaderProgram::IsDone() const return false; } - for (NCollection_Sequence>::Iterator anIt(myShaderObjects); - anIt.More(); - anIt.Next()) + for (size_t i = 0; i < myShaderObjects.Size(); ++i) { - if (!anIt.Value()->IsDone()) + if (!myShaderObjects.Value(i)->IsDone()) { return false; } @@ -132,16 +130,13 @@ bool Graphic3d_ShaderProgram::AttachShader(const occ::handle>::Iterator anIt(myShaderObjects); - anIt.More(); - anIt.Next()) + for (size_t i = 0; i < myShaderObjects.Size(); ++i) { - if (anIt.Value() == theShader) + if (myShaderObjects.Value(i) == theShader) { return false; } } - myShaderObjects.Append(theShader); return true; } @@ -157,17 +152,14 @@ bool Graphic3d_ShaderProgram::DetachShader(const occ::handle>::Iterator anIt(myShaderObjects); - anIt.More(); - anIt.Next()) + for (size_t i = 0; i < myShaderObjects.Size(); ++i) { - if (anIt.Value() == theShader) + if (myShaderObjects.Value(i) == theShader) { - myShaderObjects.Remove(anIt); + myShaderObjects.Erase(i); return true; } } - return false; } @@ -183,7 +175,11 @@ void Graphic3d_ShaderProgram::ClearVariables() //================================================================================================= void Graphic3d_ShaderProgram::SetVertexAttributes( - const NCollection_Sequence>& theAttributes) + const NCollection_LinearVector>& theAttributes) { - myAttributes = theAttributes; + myAttributes.Clear(); + for (size_t i = 0; i < theAttributes.Size(); ++i) + { + myAttributes.Append(theAttributes.Value(i)); + } } diff --git a/src/Visualization/TKService/Graphic3d/Graphic3d_ShaderProgram.hxx b/src/Visualization/TKService/Graphic3d/Graphic3d_ShaderProgram.hxx index 36d653d5116..3d13537ab6b 100644 --- a/src/Visualization/TKService/Graphic3d/Graphic3d_ShaderProgram.hxx +++ b/src/Visualization/TKService/Graphic3d/Graphic3d_ShaderProgram.hxx @@ -21,13 +21,8 @@ #include #include #include -#include - -//! List of shader objects. - -//! List of custom uniform shader variables. - -//! List of custom vertex shader attributes +#include +#include //! This class is responsible for managing shader programs. class Graphic3d_ShaderProgram : public Standard_Transient @@ -112,21 +107,23 @@ public: //! Detaches shader object from the program object. Standard_EXPORT bool DetachShader(const occ::handle& theShader); - //! Returns list of attached shader objects. - const NCollection_Sequence>& ShaderObjects() const + //! Returns list of attached shader objects in attachment order. + const NCollection_LinearVector>& ShaderObjects() const { return myShaderObjects; } //! The list of currently pushed but not applied custom uniform variables. - //! This list is automatically cleared after applying to GLSL program. - const NCollection_Sequence>& Variables() const + //! Keyed by variable name; pushing a same-name variable replaces the previous entry while + //! preserving the original insertion position. Cleared after applying to GLSL program. + const NCollection_OrderedDataMap>& + Variables() const { return myVariables; } //! Return the list of custom vertex attributes. - const NCollection_Sequence>& VertexAttributes() const + const NCollection_LinearVector>& VertexAttributes() const { return myAttributes; } @@ -134,7 +131,7 @@ public: //! Assign the list of custom vertex attributes. //! Should be done before GLSL program initialization. Standard_EXPORT void SetVertexAttributes( - const NCollection_Sequence>& theAttributes); + const NCollection_LinearVector>& theAttributes); //! Returns the number (1+) of Fragment Shader outputs to be written to //! (more than 1 can be in case of multiple draw buffers); 1 by default. @@ -266,11 +263,11 @@ public: private: TCollection_AsciiString myID; //!< the unique identifier of program object - NCollection_Sequence> - myShaderObjects; //!< the list of attached shader objects - NCollection_Sequence> - myVariables; //!< the list of custom uniform variables - NCollection_Sequence> + NCollection_LinearVector> + myShaderObjects; //!< attached shader objects in attachment order + NCollection_OrderedDataMap> + myVariables; //!< pushed uniform variables keyed by name (replace-by-name semantics) + NCollection_LinearVector> myAttributes; //!< the list of custom vertex attributes // clang-format off TCollection_AsciiString myHeader; //!< GLSL header with version code and used extensions @@ -301,7 +298,7 @@ inline bool Graphic3d_ShaderProgram::PushVariable(const TCollection_AsciiString& return false; } - myVariables.Append(aVariable); + myVariables.Bind(theName, aVariable); return true; } diff --git a/src/Visualization/TKV3d/AIS/AIS_GlobalStatus.hxx b/src/Visualization/TKV3d/AIS/AIS_GlobalStatus.hxx index d615a389454..cbec5923df6 100644 --- a/src/Visualization/TKV3d/AIS/AIS_GlobalStatus.hxx +++ b/src/Visualization/TKV3d/AIS/AIS_GlobalStatus.hxx @@ -19,9 +19,9 @@ #include +#include #include #include -#include #include //! Stores information about objects in graphic context: @@ -51,21 +51,19 @@ public: const occ::handle& HilightStyle() const { return myHiStyle; } //! Returns active selection modes of the object. - const NCollection_List& SelectionModes() const { return mySelModes; } + const AIS_SelectionModes& SelectionModes() const { return mySelModes; } + + //! Returns number of active selection modes. + size_t NbSelectionModes() const { return mySelModes.Size(); } + + //! Return TRUE when the only registered selection mode matches the given one. + bool HasOnlySelectionMode(const int theMode) const { return mySelModes.HasOnly(theMode); } //! Return TRUE if selection mode was registered. bool IsSModeIn(int theMode) const { return mySelModes.Contains(theMode); } //! Add selection mode. - bool AddSelectionMode(const int theMode) - { - if (!mySelModes.Contains(theMode)) - { - mySelModes.Append(theMode); - return true; - } - return false; - } + bool AddSelectionMode(const int theMode) { return mySelModes.Add(theMode); } //! Remove selection mode. bool RemoveSelectionMode(const int theMode) { return mySelModes.Remove(theMode); } @@ -78,7 +76,7 @@ public: void SetSubIntensity(bool theIsOn) { mySubInt = theIsOn; } private: - NCollection_List mySelModes; + AIS_SelectionModes mySelModes; occ::handle myHiStyle; int myDispMode; bool myIsHilit; diff --git a/src/Visualization/TKV3d/AIS/AIS_InteractiveContext.cxx b/src/Visualization/TKV3d/AIS/AIS_InteractiveContext.cxx index 1c0496d8487..8f7e46f12d9 100644 --- a/src/Visualization/TKV3d/AIS/AIS_InteractiveContext.cxx +++ b/src/Visualization/TKV3d/AIS/AIS_InteractiveContext.cxx @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -187,12 +188,9 @@ AIS_InteractiveContext::~AIS_InteractiveContext() { const occ::handle& anObj = anObjIter.Key(); anObj->SetContext(aNullContext); - for (NCollection_Sequence>::Iterator aSelIter( - anObj->Selections()); - aSelIter.More(); - aSelIter.Next()) + for (size_t aSelIdx = 0; aSelIdx < anObj->Selections().Size(); ++aSelIdx) { - aSelIter.Value()->UpdateBVHStatus(SelectMgr_TBU_Renew); + anObj->Selections().Value(aSelIdx)->UpdateBVHStatus(SelectMgr_TBU_Renew); } } } @@ -606,7 +604,7 @@ void AIS_InteractiveContext::DisplayAll(const bool theToUpdateViewer) void AIS_InteractiveContext::DisplaySelected(const bool theToUpdateViewer) { - for (NCollection_List>::Iterator aSelIter( + for (NCollection_OrderedMap>::Iterator aSelIter( mySelection->Objects()); aSelIter.More(); aSelIter.Next()) @@ -627,10 +625,10 @@ void AIS_InteractiveContext::DisplaySelected(const bool theToUpdateViewer) void AIS_InteractiveContext::EraseSelected(const bool theToUpdateViewer) { bool isFound = false; - for (NCollection_List>::Iterator aSelIter( + for (NCollection_OrderedMap>::Iterator aSelIter( mySelection->Objects()); aSelIter.More(); - aSelIter.Init(mySelection->Objects())) + aSelIter.Initialize(mySelection->Objects())) { occ::handle anObj = occ::down_cast(aSelIter.Value()->Selectable()); @@ -1601,7 +1599,7 @@ void AIS_InteractiveContext::SetSelectedAspect(const occ::handle>::Iterator aSelIter( + for (NCollection_OrderedMap>::Iterator aSelIter( mySelection->Objects()); aSelIter.More(); aSelIter.Next()) @@ -1689,7 +1687,7 @@ void AIS_InteractiveContext::Status(const occ::handle& th } theStatus += "\t| Active Selection Modes in the MainViewer :\n"; - for (NCollection_List::Iterator aSelModeIter(aStatus->SelectionModes()); aSelModeIter.More(); + for (AIS_SelectionModes::Iterator aSelModeIter(aStatus->SelectionModes()); aSelModeIter.More(); aSelModeIter.Next()) { theStatus += "\t\t Mode "; @@ -1749,7 +1747,7 @@ void AIS_InteractiveContext::EraseGlobal(const occ::handleSetVisibility(theIObj, aDispMode, false); } - for (NCollection_List::Iterator aSelModeIter(aStatus->SelectionModes()); aSelModeIter.More(); + for (AIS_SelectionModes::Iterator aSelModeIter(aStatus->SelectionModes()); aSelModeIter.More(); aSelModeIter.Next()) { mgrSelector->Deactivate(theIObj, aSelModeIter.Value()); @@ -1767,22 +1765,20 @@ void AIS_InteractiveContext::EraseGlobal(const occ::handle& theObject) { - NCollection_Sequence> aSeq; - for (NCollection_List>::Iterator aSelIter( + NCollection_LinearVector> anOwnersToUnselect; + for (NCollection_OrderedMap>::Iterator aSelIter( mySelection->Objects()); aSelIter.More(); aSelIter.Next()) { if (aSelIter.Value()->IsSameSelectable(theObject)) { - aSeq.Append(aSelIter.Value()); + anOwnersToUnselect.Append(aSelIter.Value()); } } - for (NCollection_Sequence>::Iterator aDelIter(aSeq); - aDelIter.More(); - aDelIter.Next()) + for (const occ::handle& anOwner : anOwnersToUnselect) { - AddOrRemoveSelected(aDelIter.Value(), false); + AddOrRemoveSelected(anOwner, false); } } @@ -2129,7 +2125,7 @@ Bnd_Box AIS_InteractiveContext::BoundingBoxOfSelection(const occ::handleView()->Identification() : -1; - for (NCollection_List>::Iterator aSelIter( + for (NCollection_OrderedMap>::Iterator aSelIter( mySelection->Objects()); aSelIter.More(); aSelIter.Next()) @@ -2321,8 +2317,8 @@ void AIS_InteractiveContext::highlightWithColor(const occ::handle& theOwner) { - NCollection_List> anOwners; - const occ::handle anObj = + NCollection_OrderedMap> anOwners; + const occ::handle anObj = occ::down_cast(theOwner->Selectable()); if (anObj.IsNull()) { @@ -2331,21 +2327,20 @@ void AIS_InteractiveContext::highlightSelected(const occ::handleIsAutoHilight()) { - NCollection_Sequence> aSeq; - for (NCollection_List>::Iterator aSelIter( + for (NCollection_OrderedMap>::Iterator aSelIter( mySelection->Objects()); aSelIter.More(); aSelIter.Next()) { if (aSelIter.Value()->IsSameSelectable(anObj)) { - anOwners.Append(aSelIter.Value()); + anOwners.Add(aSelIter.Value()); } } } else { - anOwners.Append(theOwner); + anOwners.Add(theOwner); } highlightOwners(anOwners, occ::handle()); } @@ -2370,24 +2365,23 @@ void AIS_InteractiveContext::highlightGlobal(const occ::handle> anOwners; + NCollection_OrderedMap> anOwners; if (!aGlobOwner->IsAutoHilight()) { - NCollection_Sequence> aSeq; - for (NCollection_List>::Iterator aSelIter( + for (NCollection_OrderedMap>::Iterator aSelIter( mySelection->Objects()); aSelIter.More(); aSelIter.Next()) { if (aSelIter.Value()->IsSameSelectable(theObj)) { - anOwners.Append(aSelIter.Value()); + anOwners.Add(aSelIter.Value()); } } } else { - anOwners.Append(aGlobOwner); + anOwners.Add(aGlobOwner); } highlightOwners(anOwners, theStyle); } @@ -2402,11 +2396,11 @@ void AIS_InteractiveContext::unhighlightSelected(const bool theIsToHilightSubInt //================================================================================================= void AIS_InteractiveContext::unhighlightOwners( - const NCollection_List>& theOwners, - const bool theIsToHilightSubIntensity) + const NCollection_OrderedMap>& theOwners, + const bool theIsToHilightSubIntensity) { NCollection_IndexedMap> anObjToClear; - for (NCollection_List>::Iterator aSelIter(theOwners); + for (NCollection_OrderedMap>::Iterator aSelIter(theOwners); aSelIter.More(); aSelIter.Next()) { @@ -2469,8 +2463,8 @@ void AIS_InteractiveContext::unhighlightGlobal(const occ::handle> anOwners; - anOwners.Append(aGlobOwner); + NCollection_OrderedMap> anOwners; + anOwners.Add(aGlobOwner); unhighlightOwners(anOwners); } @@ -2484,26 +2478,7 @@ void AIS_InteractiveContext::turnOnSubintensity(const occ::handle& aSubStyle = myStyles[Prs3d_TypeOfHighlight_SubIntensity]; aSubStyle->SetTransparency(myStyles[Prs3d_TypeOfHighlight_Selected]->Transparency()); - if (theObject.IsNull()) - { - for (NCollection_DataMap, - occ::handle>::Iterator anObjsIter(myObjects); - anObjsIter.More(); - anObjsIter.Next()) - { - const occ::handle& aStatus = anObjsIter.Value(); - if (theObject->DisplayStatus() != PrsMgr_DisplayStatus_Displayed && theIsDisplayedOnly) - { - continue; - } - - aStatus->SetSubIntensity(true); - myMainPM->Color(anObjsIter.Key(), - aSubStyle, - theDispMode != -1 ? theDispMode : aStatus->DisplayMode()); - } - } - else + if (!theObject.IsNull()) { occ::handle aStatus; if (!myObjects.Find(theObject, aStatus)) @@ -2511,13 +2486,30 @@ void AIS_InteractiveContext::turnOnSubintensity(const occ::handleDisplayStatus() != PrsMgr_DisplayStatus_Displayed && theIsDisplayedOnly) + if (theIsDisplayedOnly && theObject->DisplayStatus() != PrsMgr_DisplayStatus_Displayed) { return; } aStatus->SetSubIntensity(true); myMainPM->Color(theObject, aSubStyle, theDispMode != -1 ? theDispMode : aStatus->DisplayMode()); + return; + } + + for (NCollection_DataMap, + occ::handle>::Iterator anObjIter(myObjects); + anObjIter.More(); + anObjIter.Next()) + { + const occ::handle& anObject = anObjIter.Key(); + if (theIsDisplayedOnly && anObject->DisplayStatus() != PrsMgr_DisplayStatus_Displayed) + { + continue; + } + + const occ::handle& aStatus = anObjIter.Value(); + aStatus->SetSubIntensity(true); + myMainPM->Color(anObject, aSubStyle, theDispMode != -1 ? theDispMode : aStatus->DisplayMode()); } } @@ -2949,13 +2941,13 @@ AIS_StatusOfPick AIS_InteractiveContext::Select( const AIS_SelectionScheme theSelScheme) { NCollection_IndexedMap> aSelOwnerMap( - myAutoHilight ? mySelection->Objects().Length() : 0); + myAutoHilight ? mySelection->Extent() : 0); if (myAutoHilight) { clearDynamicHighlight(); // collect currently selected owners - for (NCollection_List>::Iterator anOwnerIter( + for (NCollection_OrderedMap>::Iterator anOwnerIter( mySelection->Objects()); anOwnerIter.More(); anOwnerIter.Next()) @@ -2972,8 +2964,9 @@ AIS_StatusOfPick AIS_InteractiveContext::Select( if (myAutoHilight) { // collect lists of owners to unhighlight (unselected) and to highlight (selected) - NCollection_List> anOwnersToUnhighlight, anOwnersToHighlight; - for (NCollection_List>::Iterator anOwnerIter( + NCollection_OrderedMap> anOwnersToUnhighlight, + anOwnersToHighlight; + for (NCollection_OrderedMap>::Iterator anOwnerIter( mySelection->Objects()); anOwnerIter.More(); anOwnerIter.Next()) @@ -2983,7 +2976,7 @@ AIS_StatusOfPick AIS_InteractiveContext::Select( if (!aSelOwnerMap.RemoveKey(anOwner)) { // newly selected owner - anOwnersToHighlight.Append(anOwner); + anOwnersToHighlight.Add(anOwner); } else { @@ -2992,12 +2985,12 @@ AIS_StatusOfPick AIS_InteractiveContext::Select( && theSelScheme != AIS_SelectionScheme_Add) { // hack to perform AIS_InteractiveObject::ClearSelected() before highlighting - anOwnersToUnhighlight.Append(anOwner); - anOwnersToHighlight.Append(anOwner); + anOwnersToUnhighlight.Add(anOwner); + anOwnersToHighlight.Add(anOwner); } else if (anOwner->IsForcedHilight() || !anOwner->IsAutoHilight()) { - anOwnersToHighlight.Append(anOwner); + anOwnersToHighlight.Add(anOwner); } } } @@ -3009,7 +3002,7 @@ AIS_StatusOfPick AIS_InteractiveContext::Select( { // owners removed from selection const occ::handle& anOwner = anOwnerIter.Value(); - anOwnersToUnhighlight.Append(anOwner); + anOwnersToUnhighlight.Add(anOwner); } unhighlightOwners(anOwnersToUnhighlight); @@ -3040,13 +3033,13 @@ void AIS_InteractiveContext::HilightSelected(const bool theToUpdateViewer) //================================================================================================= void AIS_InteractiveContext::highlightOwners( - const NCollection_List>& theOwners, - const occ::handle& theStyle) + const NCollection_OrderedMap>& theOwners, + const occ::handle& theStyle) { NCollection_DataMap, - NCollection_Handle>>> + NCollection_Sequence>> anObjOwnerMap; - for (NCollection_List>::Iterator aSelIter(theOwners); + for (NCollection_OrderedMap>::Iterator aSelIter(theOwners); aSelIter.More(); aSelIter.Next()) { @@ -3072,17 +3065,9 @@ void AIS_InteractiveContext::highlightOwners( } if (!anOwner->IsAutoHilight()) { - NCollection_Handle>> aSeq; - if (anObjOwnerMap.Find(anObj, aSeq)) - { - aSeq->Append(anOwner); - } - else - { - aSeq = new NCollection_Sequence>(); - aSeq->Append(anOwner); - anObjOwnerMap.Bind(anObj, aSeq); - } + NCollection_Sequence>& aSeq = + anObjOwnerMap.TryBound(anObj, NCollection_Sequence>()); + aSeq.Append(anOwner); } else { @@ -3093,14 +3078,13 @@ void AIS_InteractiveContext::highlightOwners( if (!anObjOwnerMap.IsEmpty()) { - for (NCollection_DataMap< - occ::handle, - NCollection_Handle>>>::Iterator + for (NCollection_DataMap, + NCollection_Sequence>>::Iterator anIter(anObjOwnerMap); anIter.More(); anIter.Next()) { - anIter.Key()->HilightSelected(myMainPM, *anIter.Value()); + anIter.Key()->HilightSelected(myMainPM, anIter.Value()); } anObjOwnerMap.Clear(); } @@ -3203,7 +3187,7 @@ void AIS_InteractiveContext::SetSelected(const occ::handle>::Iterator aSelIter( + for (NCollection_OrderedMap>::Iterator aSelIter( mySelection->Objects()); aSelIter.More(); aSelIter.Next()) @@ -3368,8 +3352,8 @@ void AIS_InteractiveContext::AddOrRemoveSelected(const occ::handle> anOwners; - anOwners.Append(theOwner); + NCollection_OrderedMap> anOwners; + anOwners.Add(theOwner); unhighlightOwners(anOwners); (*aStatusPtr)->SetHilightStyle(occ::handle()); @@ -3436,19 +3420,14 @@ bool AIS_InteractiveContext::IsSelected(const occ::handle return false; } - const int aGlobalSelMode = theObj->GlobalSelectionMode(); - const NCollection_List& anActivatedModes = (*aStatus)->SelectionModes(); - for (NCollection_List::Iterator aModeIter(anActivatedModes); aModeIter.More(); - aModeIter.Next()) + if (!(*aStatus)->IsSModeIn(theObj->GlobalSelectionMode())) { - if (aModeIter.Value() == aGlobalSelMode) - { - if (occ::handle aGlobOwner = theObj->GlobalSelOwner()) - { - return aGlobOwner->IsSelected(); - } - return false; - } + return false; + } + + if (occ::handle aGlobOwner = theObj->GlobalSelOwner()) + { + return aGlobOwner->IsSelected(); } return false; } @@ -3689,8 +3668,7 @@ void AIS_InteractiveContext::SetSelectionModeActive( { if (theMode == -1) { - for (NCollection_List::Iterator aModeIter((*aStat)->SelectionModes()); - aModeIter.More(); + for (AIS_SelectionModes::Iterator aModeIter((*aStat)->SelectionModes()); aModeIter.More(); aModeIter.Next()) { mgrSelector->Deactivate(theObj, aModeIter.Value()); @@ -3717,7 +3695,7 @@ void AIS_InteractiveContext::SetSelectionModeActive( return; } - if ((*aStat)->SelectionModes().Size() == 1 && (*aStat)->SelectionModes().First() == theMode) + if ((*aStat)->HasOnlySelectionMode(theMode)) { return; } @@ -3727,8 +3705,7 @@ void AIS_InteractiveContext::SetSelectionModeActive( switch (theActiveFilter) { case AIS_SelectionModesConcurrency_Single: { - for (NCollection_List::Iterator aModeIter((*aStat)->SelectionModes()); - aModeIter.More(); + for (AIS_SelectionModes::Iterator aModeIter((*aStat)->SelectionModes()); aModeIter.More(); aModeIter.Next()) { mgrSelector->Deactivate(theObj, aModeIter.Value()); @@ -3739,8 +3716,7 @@ void AIS_InteractiveContext::SetSelectionModeActive( case AIS_SelectionModesConcurrency_GlobalOrLocal: { const int aGlobSelMode = theObj->GlobalSelectionMode(); NCollection_List aRemovedModes; - for (NCollection_List::Iterator aModeIter((*aStat)->SelectionModes()); - aModeIter.More(); + for (AIS_SelectionModes::Iterator aModeIter((*aStat)->SelectionModes()); aModeIter.More(); aModeIter.Next()) { if ((theMode == aGlobSelMode && aModeIter.Value() != aGlobSelMode) @@ -3750,7 +3726,7 @@ void AIS_InteractiveContext::SetSelectionModeActive( aRemovedModes.Append(aModeIter.Value()); } } - if (aRemovedModes.Size() == (*aStat)->SelectionModes().Size()) + if (aRemovedModes.Size() == (*aStat)->NbSelectionModes()) { (*aStat)->ClearSelectionModes(); } @@ -3825,7 +3801,7 @@ void AIS_InteractiveContext::ActivatedModes(const occ::handle* aStatus = myObjects.Seek(theObj); if (aStatus != nullptr) { - for (NCollection_List::Iterator aModeIter((*aStatus)->SelectionModes()); aModeIter.More(); + for (AIS_SelectionModes::Iterator aModeIter((*aStatus)->SelectionModes()); aModeIter.More(); aModeIter.Next()) { theList.Append(aModeIter.Value()); @@ -3894,7 +3870,7 @@ void AIS_InteractiveContext::DisplayActiveSensitive( return; } - for (NCollection_List::Iterator aModeIter((*aStatus)->SelectionModes()); aModeIter.More(); + for (AIS_SelectionModes::Iterator aModeIter((*aStatus)->SelectionModes()); aModeIter.More(); aModeIter.Next()) { const occ::handle& aSel = theObj->Selection(aModeIter.Value()); diff --git a/src/Visualization/TKV3d/AIS/AIS_InteractiveContext.hxx b/src/Visualization/TKV3d/AIS/AIS_InteractiveContext.hxx index 4c957bd4400..4a045684d45 100644 --- a/src/Visualization/TKV3d/AIS/AIS_InteractiveContext.hxx +++ b/src/Visualization/TKV3d/AIS/AIS_InteractiveContext.hxx @@ -1516,8 +1516,8 @@ protected: //! @name internal methods //! @param[in] theOwners list of owners to highlight //! @param[in] theStyle highlight style to apply or NULL to apply selection style Standard_EXPORT void highlightOwners( - const NCollection_List>& theOwners, - const occ::handle& theStyle); + const NCollection_OrderedMap>& theOwners, + const occ::handle& theStyle); //! Helper function that highlights global owner of the object given with with check //! for AutoHighlight, e.g. is used for selection. @@ -1536,8 +1536,8 @@ protected: //! @name internal methods //! Helper function that unhighlights the owners with check //! for AutoHighlight, e.g. is used for selection. Standard_EXPORT void unhighlightOwners( - const NCollection_List>& theOwners, - const bool theIsToHilightSubIntensity = false); + const NCollection_OrderedMap>& theOwners, + const bool theIsToHilightSubIntensity = false); //! Helper function that unhighlights global selection owner of given interactive. //! The function does not perform any updates of global or owner status diff --git a/src/Visualization/TKV3d/AIS/AIS_PointCloud.cxx b/src/Visualization/TKV3d/AIS/AIS_PointCloud.cxx index 1ca945206d2..aa48a2585c0 100644 --- a/src/Visualization/TKV3d/AIS/AIS_PointCloud.cxx +++ b/src/Visualization/TKV3d/AIS/AIS_PointCloud.cxx @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -73,12 +74,11 @@ void AIS_PointCloudOwner::HilightWithColor(const occ::handleZLayer() : (thePrsMgr->IsImmediateModeOn() ? Graphic3d_ZLayerId_Top : anObj->ZLayer()); aMap->ChangeMap().Clear(); - for (NCollection_Sequence>::Iterator aSelIter( - anObj->Selections()); - aSelIter.More(); - aSelIter.Next()) + const NCollection_LinearVector>& aSelections = + anObj->Selections(); + for (size_t aSelIdx = 0; aSelIdx < aSelections.Size(); ++aSelIdx) { - const occ::handle& aSel = aSelIter.Value(); + const occ::handle& aSel = aSelections.Value(aSelIdx); for (NCollection_DynamicArray>::Iterator aSelEntIter( aSel->Entities()); aSelEntIter.More(); diff --git a/src/Visualization/TKV3d/AIS/AIS_Selection.cxx b/src/Visualization/TKV3d/AIS/AIS_Selection.cxx index def1e0753a8..d768f9e1c94 100644 --- a/src/Visualization/TKV3d/AIS/AIS_Selection.cxx +++ b/src/Visualization/TKV3d/AIS/AIS_Selection.cxx @@ -20,33 +20,23 @@ IMPLEMENT_STANDARD_RTTIEXT(AIS_Selection, Standard_Transient) -namespace -{ -constexpr int THE_MaxSizeOfResult = 100000; -} - //================================================================================================= -AIS_Selection::AIS_Selection() -{ - // for maximum performance on medium selections (< 100000 objects) - myResultMap.ReSize(THE_MaxSizeOfResult); -} +AIS_Selection::AIS_Selection() {} //================================================================================================= void AIS_Selection::Clear() { - for (NCollection_List>::Iterator aSelIter(Objects()); + for (NCollection_OrderedMap>::Iterator aSelIter(Objects()); aSelIter.More(); aSelIter.Next()) { const occ::handle anObject = aSelIter.Value(); anObject->SetSelected(false); } - myresult.Clear(); - myResultMap.Clear(); - myIterator = NCollection_List>::Iterator(); + myOwners.Clear(); + myIterator = NCollection_OrderedMap>::Iterator(); } //================================================================================================= @@ -66,32 +56,21 @@ AIS_SelectStatus AIS_Selection::Select(const occ::handle& const bool wasSelected = theOwner->IsSelected(); const bool toSelect = theOwner->Select(theSelScheme, isDetected); - if (!wasSelected || !myResultMap.IsBound(theOwner)) + if (!wasSelected || !myOwners.Contains(theOwner)) { if (!toSelect) { return AIS_SS_NotDone; } - NCollection_List>::Iterator aListIter; - myresult.Append(theOwner, aListIter); - myResultMap.Bind(theOwner, aListIter); + myOwners.Add(theOwner); theOwner->SetSelected(true); return AIS_SS_Added; } - NCollection_List>::Iterator aListIter = - myResultMap.Find(theOwner); - if (myIterator == aListIter) + if (myIterator.More() && myIterator.Value() == theOwner) { - if (myIterator.More()) - { - myIterator.Next(); - } - else - { - myIterator = NCollection_List>::Iterator(); - } + myIterator.Next(); } // In the mode of advanced mesh selection only one owner is created for all selection modes. @@ -103,23 +82,8 @@ AIS_SelectStatus AIS_Selection::Select(const occ::handle& return AIS_SS_Added; } - myresult.Remove(aListIter); - myResultMap.UnBind(theOwner); + myOwners.Remove(theOwner); theOwner->SetSelected(false); - - // update list iterator for next object in list if any - if (aListIter.More()) - { - const occ::handle& aNextObject = aListIter.Value(); - if (myResultMap.IsBound(aNextObject)) - { - myResultMap(aNextObject) = aListIter; - } - else - { - myResultMap.Bind(aNextObject, aListIter); - } - } return AIS_SS_Removed; } @@ -127,14 +91,12 @@ AIS_SelectStatus AIS_Selection::Select(const occ::handle& AIS_SelectStatus AIS_Selection::AddSelect(const occ::handle& theObject) { - if (theObject.IsNull() || !theObject->HasSelectable() || myResultMap.IsBound(theObject)) + if (theObject.IsNull() || !theObject->HasSelectable() || myOwners.Contains(theObject)) { return AIS_SS_NotDone; } - NCollection_List>::Iterator aListIter; - myresult.Append(theObject, aListIter); - myResultMap.Bind(theObject, aListIter); + myOwners.Add(theObject); theObject->SetSelected(true); return AIS_SS_Added; } @@ -149,7 +111,7 @@ void AIS_Selection::SelectOwners( { (void)theToAllowSelOverlap; - if (theSelScheme == AIS_SelectionScheme_ReplaceExtra && thePickedOwners.Size() == myresult.Size()) + if (theSelScheme == AIS_SelectionScheme_ReplaceExtra && thePickedOwners.Size() == myOwners.Size()) { // If picked owners is equivalent to the selected then just clear selected. bool isTheSame = true; @@ -158,7 +120,7 @@ void AIS_Selection::SelectOwners( aPickedIter.More(); aPickedIter.Next()) { - if (!myResultMap.IsBound(aPickedIter.Value())) + if (!myOwners.Contains(aPickedIter.Value())) { isTheSame = false; break; diff --git a/src/Visualization/TKV3d/AIS/AIS_Selection.hxx b/src/Visualization/TKV3d/AIS/AIS_Selection.hxx index 652ddf912a4..df109efde80 100644 --- a/src/Visualization/TKV3d/AIS/AIS_Selection.hxx +++ b/src/Visualization/TKV3d/AIS/AIS_Selection.hxx @@ -17,17 +17,17 @@ #ifndef _AIS_Selection_HeaderFile #define _AIS_Selection_HeaderFile -#include -#include -#include #include #include +#include +#include +#include #include #include class SelectMgr_Filter; -//! Class holding the list of selected owners. +//! Class holding the ordered set of selected owners. class AIS_Selection : public Standard_Transient { DEFINE_STANDARD_RTTIEXT(AIS_Selection, Standard_Transient) @@ -71,23 +71,26 @@ public: //! checks if the object is in the selection. bool IsSelected(const occ::handle& theObject) const { - return myResultMap.IsBound(theObject); + return myOwners.Contains(theObject); } - //! Return the list of selected objects. - const NCollection_List>& Objects() const { return myresult; } + //! Return the ordered set of selected objects. + const NCollection_OrderedMap>& Objects() const + { + return myOwners; + } //! Return the number of selected objects. - int Extent() const { return myresult.Length(); } + int Extent() const { return myOwners.Extent(); } //! Return true if list of selected objects is empty. - bool IsEmpty() const { return myresult.IsEmpty(); } + bool IsEmpty() const { return myOwners.IsEmpty(); } public: //! Start iteration through selected objects. void Init() { - myIterator = NCollection_List>::Iterator(myresult); + myIterator = NCollection_OrderedMap>::Iterator(myOwners); } //! Return true if iterator points to selected object. @@ -120,11 +123,8 @@ protected: const occ::handle& theFilter); protected: - NCollection_List> myresult; - NCollection_List>::Iterator myIterator; - NCollection_DataMap, - NCollection_List>::Iterator> - myResultMap; + NCollection_OrderedMap> myOwners; + NCollection_OrderedMap>::Iterator myIterator; }; #endif // _AIS_Selection_HeaderFile diff --git a/src/Visualization/TKV3d/AIS/AIS_SelectionModes.hxx b/src/Visualization/TKV3d/AIS/AIS_SelectionModes.hxx new file mode 100644 index 00000000000..a0c692b9902 --- /dev/null +++ b/src/Visualization/TKV3d/AIS/AIS_SelectionModes.hxx @@ -0,0 +1,121 @@ +// Copyright (c) 2026 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 _AIS_SelectionModes_HeaderFile +#define _AIS_SelectionModes_HeaderFile + +#include +#include +#include + +//! Stores active AIS selection modes with stable iteration order. +//! Backed by a contiguous vector - the typical population is 1-5 modes, +//! so linear scans dominate hashed lookup on cache locality. +class AIS_SelectionModes +{ +public: + //! Iterator over active selection modes in insertion order. + class Iterator + { + public: + //! Constructor from selection modes container. + Iterator(const AIS_SelectionModes& theModes) + : myModes(&theModes.myModes), + myIndex(0) + { + } + + //! Return TRUE if iterator points to a valid mode. + bool More() const { return myIndex < myModes->Size(); } + + //! Advance iterator. + void Next() { ++myIndex; } + + //! Return current selection mode. + int Value() const { return myModes->Value(myIndex); } + + private: + const NCollection_LinearVector* myModes; + size_t myIndex; + }; + +public: + //! Empty constructor. + AIS_SelectionModes() {} + + //! Returns number of active modes. + size_t Size() const { return myModes.Size(); } + + //! Return TRUE when no modes are stored. + bool IsEmpty() const { return myModes.IsEmpty(); } + + //! Return TRUE when the only registered mode matches the given one. + bool HasOnly(const int theMode) const + { + return myModes.Size() == 1 && myModes.Value(0) == theMode; + } + + //! Return TRUE when the mode is stored. + bool Contains(const int theMode) const + { + for (size_t i = 0; i < myModes.Size(); ++i) + { + if (myModes.Value(i) == theMode) + { + return true; + } + } + return false; + } + + //! Return mode by zero-based ordered index. + int Mode(const int theIndex) const + { + Standard_OutOfRange_Raise_if(theIndex < 0 || static_cast(theIndex) >= myModes.Size(), + "AIS_SelectionModes::Mode"); + return myModes.Value(static_cast(theIndex)); + } + + //! Add selection mode if it is not stored yet. + bool Add(const int theMode) + { + if (Contains(theMode)) + { + return false; + } + myModes.Append(theMode); + return true; + } + + //! Remove selection mode. + bool Remove(const int theMode) + { + for (size_t i = 0; i < myModes.Size(); ++i) + { + if (myModes.Value(i) == theMode) + { + myModes.Erase(i); + return true; + } + } + return false; + } + + //! Remove all selection modes. + void Clear() { myModes.Clear(); } + +private: + NCollection_LinearVector myModes; +}; + +#endif // _AIS_SelectionModes_HeaderFile diff --git a/src/Visualization/TKV3d/AIS/FILES.cmake b/src/Visualization/TKV3d/AIS/FILES.cmake index 7fbb4df200a..9d209463522 100644 --- a/src/Visualization/TKV3d/AIS/FILES.cmake +++ b/src/Visualization/TKV3d/AIS/FILES.cmake @@ -79,6 +79,7 @@ set(OCCT_AIS_FILES AIS_RubberBand.cxx AIS_Selection.cxx AIS_Selection.hxx + AIS_SelectionModes.hxx AIS_SelectStatus.hxx AIS_SelectionModesConcurrency.hxx AIS_SelectionScheme.hxx diff --git a/src/Visualization/TKV3d/GTests/AIS_InteractiveContext_Test.cxx b/src/Visualization/TKV3d/GTests/AIS_InteractiveContext_Test.cxx new file mode 100644 index 00000000000..6f696736855 --- /dev/null +++ b/src/Visualization/TKV3d/GTests/AIS_InteractiveContext_Test.cxx @@ -0,0 +1,448 @@ +// Copyright (c) 2026 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace +{ + +class AIS_TestCStructure : public Graphic3d_CStructure +{ +public: + AIS_TestCStructure(const occ::handle& theManager) + : Graphic3d_CStructure(theManager) + { + } + + void OnVisibilityChanged() override {} + + void Clear() override { myGroups.Clear(); } + + void Connect(Graphic3d_CStructure&) override {} + + void Disconnect(Graphic3d_CStructure&) override {} + + void GraphicHighlight(const occ::handle& theStyle) override + { + myHighlightStyle = theStyle; + highlight = 1; + } + + void GraphicUnhighlight() override + { + myHighlightStyle.Nullify(); + highlight = 0; + } + + occ::handle ShadowLink( + const occ::handle& theManager) const override + { + return new AIS_TestCStructure(theManager); + } + + occ::handle NewGroup(const occ::handle&) override + { + return occ::handle(); + } + + void RemoveGroup(const occ::handle&) override {} + + DEFINE_STANDARD_RTTI_INLINE(AIS_TestCStructure, Graphic3d_CStructure) +}; + +class AIS_TestGraphicDriver : public Graphic3d_GraphicDriver +{ +public: + AIS_TestGraphicDriver() + : Graphic3d_GraphicDriver(occ::handle()) + { + } + + int InquireLimit(const Graphic3d_TypeOfLimit theType) const override + { + switch (theType) + { + case Graphic3d_TypeOfLimit_MaxNbLights: + return 8; + case Graphic3d_TypeOfLimit_MaxNbClipPlanes: + return 6; + case Graphic3d_TypeOfLimit_MaxNbViews: + return 32; + case Graphic3d_TypeOfLimit_MaxTextureSize: + case Graphic3d_TypeOfLimit_MaxViewDumpSizeX: + case Graphic3d_TypeOfLimit_MaxViewDumpSizeY: + return 4096; + default: + return 0; + } + } + + occ::handle CreateStructure( + const occ::handle& theManager) override + { + return new AIS_TestCStructure(theManager); + } + + void RemoveStructure(occ::handle& theCStructure) override + { + theCStructure.Nullify(); + } + + occ::handle CreateView(const occ::handle&) override + { + return occ::handle(); + } + + void RemoveView(const occ::handle&) override {} + + void EnableVBO(const bool) override {} + + bool IsVerticalSync() const override { return false; } + + void SetVerticalSync(bool) override {} + + bool MemoryInfo(size_t& theFreeBytes, TCollection_AsciiString& theInfo) const override + { + theFreeBytes = 0; + theInfo.Clear(); + return false; + } + + float DefaultTextHeight() const override { return 12.0f; } + + void TextSize(const occ::handle&, + const char* const, + const float, + float& theWidth, + float& theAscent, + float& theDescent) const override + { + theWidth = 0.0f; + theAscent = 0.0f; + theDescent = 0.0f; + } + + void InsertLayerBefore(const Graphic3d_ZLayerId, + const Graphic3d_ZLayerSettings&, + const Graphic3d_ZLayerId) override + { + } + + void InsertLayerAfter(const Graphic3d_ZLayerId, + const Graphic3d_ZLayerSettings&, + const Graphic3d_ZLayerId) override + { + } + + void RemoveZLayer(const Graphic3d_ZLayerId) override {} + + void SetZLayerSettings(const Graphic3d_ZLayerId, const Graphic3d_ZLayerSettings&) override {} + + bool ViewExists(const occ::handle&, occ::handle& theView) override + { + theView.Nullify(); + return false; + } + + DEFINE_STANDARD_RTTI_INLINE(AIS_TestGraphicDriver, Graphic3d_GraphicDriver) +}; + +class Graphic3d_TestLayerDriver : public AIS_TestGraphicDriver +{ +public: + void InsertLayerBefore(const Graphic3d_ZLayerId theLayerId, + const Graphic3d_ZLayerSettings& theSettings, + const Graphic3d_ZLayerId theLayerAfter) override + { + Graphic3d_GraphicDriver::InsertLayerBefore(theLayerId, theSettings, theLayerAfter); + } + + void InsertLayerAfter(const Graphic3d_ZLayerId theLayerId, + const Graphic3d_ZLayerSettings& theSettings, + const Graphic3d_ZLayerId theLayerBefore) override + { + Graphic3d_GraphicDriver::InsertLayerAfter(theLayerId, theSettings, theLayerBefore); + } + + void RemoveZLayer(const Graphic3d_ZLayerId theLayerId) override + { + Graphic3d_GraphicDriver::RemoveZLayer(theLayerId); + } + + void SetZLayerSettings(const Graphic3d_ZLayerId theLayerId, + const Graphic3d_ZLayerSettings& theSettings) override + { + Graphic3d_GraphicDriver::SetZLayerSettings(theLayerId, theSettings); + } + + DEFINE_STANDARD_RTTI_INLINE(Graphic3d_TestLayerDriver, AIS_TestGraphicDriver) +}; + +class AIS_InteractiveContextTestAccessor : public AIS_InteractiveContext +{ +public: + AIS_InteractiveContextTestAccessor(const occ::handle& theViewer) + : AIS_InteractiveContext(theViewer) + { + } + + void AddErasedObject(const occ::handle& theObject) + { + setContextToObject(theObject); + setObjectStatus(theObject, PrsMgr_DisplayStatus_Erased, 0, -1); + } + + bool IsSubIntensityOn(const occ::handle& theObject) const + { + occ::handle aStatus; + return myObjects.Find(theObject, aStatus) && aStatus->IsSubIntensityOn(); + } + + DEFINE_STANDARD_RTTI_INLINE(AIS_InteractiveContextTestAccessor, AIS_InteractiveContext) +}; + +class PrsMgr_PresentationManagerTestAccessor : public PrsMgr_PresentationManager +{ +public: + PrsMgr_PresentationManagerTestAccessor( + const occ::handle& theStructureManager) + : PrsMgr_PresentationManager(theStructureManager) + { + } + + size_t ImmediateListSize() const { return myImmediateList.Size(); } + + DEFINE_STANDARD_RTTI_INLINE(PrsMgr_PresentationManagerTestAccessor, PrsMgr_PresentationManager) +}; + +} // namespace + +class AIS_InteractiveContextTest : public testing::Test +{ +protected: + void SetUp() override + { + myDriver = new AIS_TestGraphicDriver(); + myViewer = new V3d_Viewer(myDriver); + myContext = new AIS_InteractiveContextTestAccessor(myViewer); + } + + occ::handle MakeBoxObject() const + { + return new AIS_Shape(BRepPrimAPI_MakeBox(1.0, 1.0, 1.0).Shape()); + } + + occ::handle myDriver; + occ::handle myViewer; + occ::handle myContext; +}; + +TEST_F(AIS_InteractiveContextTest, SubIntensityOn_NullObject_SkipsErasedObjects) +{ + occ::handle aShape = MakeBoxObject(); + myContext->AddErasedObject(aShape); + + EXPECT_NO_THROW(myContext->SubIntensityOn(occ::handle(), false)); + EXPECT_FALSE(myContext->IsSubIntensityOn(aShape)); +} + +TEST_F(AIS_InteractiveContextTest, SubIntensityOn_ErasedObject_DoesNotSetSubIntensity) +{ + occ::handle aShape = MakeBoxObject(); + myContext->AddErasedObject(aShape); + + EXPECT_NO_THROW(myContext->SubIntensityOn(aShape, false)); + EXPECT_FALSE(myContext->IsSubIntensityOn(aShape)); +} + +TEST(AIS_GlobalStatusTest, SelectionModes_PreserveOrderAfterRemove) +{ + occ::handle aStatus = new AIS_GlobalStatus(); + + EXPECT_TRUE(aStatus->AddSelectionMode(0)); + EXPECT_TRUE(aStatus->AddSelectionMode(2)); + EXPECT_TRUE(aStatus->AddSelectionMode(4)); + EXPECT_FALSE(aStatus->AddSelectionMode(2)); + EXPECT_EQ(size_t(3), aStatus->NbSelectionModes()); + EXPECT_FALSE(aStatus->HasOnlySelectionMode(0)); + + EXPECT_TRUE(aStatus->RemoveSelectionMode(0)); + EXPECT_FALSE(aStatus->RemoveSelectionMode(0)); + ASSERT_EQ(size_t(2), aStatus->SelectionModes().Size()); + EXPECT_EQ(2, aStatus->SelectionModes().Mode(0)); + EXPECT_EQ(4, aStatus->SelectionModes().Mode(1)); + EXPECT_TRUE(aStatus->IsSModeIn(2)); + EXPECT_FALSE(aStatus->IsSModeIn(0)); +} + +TEST(Graphic3d_GraphicDriverTest, ZLayers_InsertRemoveAndImmediateOrdering) +{ + occ::handle aDriver = new Graphic3d_TestLayerDriver(); + + constexpr int THE_BEFORE_DEFAULT_LAYER = 1001; + constexpr int THE_AFTER_DEFAULT_LAYER = 1002; + + Graphic3d_ZLayerSettings aSettings; + aSettings.SetImmediate(false); + aDriver->InsertLayerBefore(THE_BEFORE_DEFAULT_LAYER, aSettings, Graphic3d_ZLayerId_Default); + aDriver->InsertLayerAfter(THE_AFTER_DEFAULT_LAYER, aSettings, Graphic3d_ZLayerId_Default); + + NCollection_Sequence aLayers; + aDriver->ZLayers(aLayers); + + ASSERT_EQ(aLayers.Length(), 7); + EXPECT_EQ(aLayers.Value(1), Graphic3d_ZLayerId_BotOSD); + EXPECT_EQ(aLayers.Value(2), THE_BEFORE_DEFAULT_LAYER); + EXPECT_EQ(aLayers.Value(3), Graphic3d_ZLayerId_Default); + EXPECT_EQ(aLayers.Value(4), THE_AFTER_DEFAULT_LAYER); + EXPECT_EQ(aLayers.Value(5), Graphic3d_ZLayerId_Top); + EXPECT_EQ(aLayers.Value(6), Graphic3d_ZLayerId_Topmost); + EXPECT_EQ(aLayers.Value(7), Graphic3d_ZLayerId_TopOSD); + + aDriver->RemoveZLayer(THE_BEFORE_DEFAULT_LAYER); + EXPECT_THROW(aDriver->ZLayerSettings(THE_BEFORE_DEFAULT_LAYER), Standard_OutOfRange); + + Graphic3d_ZLayerSettings anImmediateSettings; + anImmediateSettings.SetImmediate(true); + aDriver->SetZLayerSettings(THE_AFTER_DEFAULT_LAYER, anImmediateSettings); + + aDriver->ZLayers(aLayers); + + ASSERT_EQ(aLayers.Length(), 6); + EXPECT_EQ(aLayers.Value(1), Graphic3d_ZLayerId_BotOSD); + EXPECT_EQ(aLayers.Value(2), Graphic3d_ZLayerId_Default); + EXPECT_EQ(aLayers.Value(3), THE_AFTER_DEFAULT_LAYER); + EXPECT_EQ(aLayers.Value(4), Graphic3d_ZLayerId_Top); + EXPECT_EQ(aLayers.Value(5), Graphic3d_ZLayerId_Topmost); + EXPECT_EQ(aLayers.Value(6), Graphic3d_ZLayerId_TopOSD); +} + +TEST(V3d_ViewerTest, ZLayerIds_RemoveRejectsMissingLayer) +{ + occ::handle aDriver = new AIS_TestGraphicDriver(); + occ::handle aViewer = new V3d_Viewer(aDriver); + + Graphic3d_ZLayerSettings aSettings; + Graphic3d_ZLayerId aLayerId = Graphic3d_ZLayerId_UNKNOWN; + ASSERT_TRUE(aViewer->InsertLayerAfter(aLayerId, aSettings, Graphic3d_ZLayerId_Default)); + EXPECT_TRUE(aViewer->RemoveZLayer(aLayerId)); + EXPECT_FALSE(aViewer->RemoveZLayer(aLayerId)); + EXPECT_FALSE(aViewer->RemoveZLayer(Graphic3d_ZLayerId_Default)); +} + +TEST(AIS_SelectionTest, AddRemoveAndClear_KeepOrderAndSelectionState) +{ + occ::handle aFirstShape = new AIS_Shape(BRepPrimAPI_MakeBox(1.0, 1.0, 1.0).Shape()); + occ::handle aSecondShape = new AIS_Shape(BRepPrimAPI_MakeBox(2.0, 2.0, 2.0).Shape()); + occ::handle aFirstOwner = new SelectMgr_EntityOwner(aFirstShape); + occ::handle aSecondOwner = new SelectMgr_EntityOwner(aSecondShape); + + occ::handle aSelection = new AIS_Selection(); + EXPECT_EQ(AIS_SS_Added, aSelection->AddSelect(aFirstOwner)); + EXPECT_EQ(AIS_SS_Added, aSelection->AddSelect(aSecondOwner)); + EXPECT_EQ(AIS_SS_NotDone, aSelection->AddSelect(aFirstOwner)); + EXPECT_EQ(2, aSelection->Extent()); + EXPECT_TRUE(aSelection->IsSelected(aFirstOwner)); + EXPECT_TRUE(aSelection->IsSelected(aSecondOwner)); + + NCollection_OrderedMap>::Iterator anOwnerIter( + aSelection->Objects()); + ASSERT_TRUE(anOwnerIter.More()); + EXPECT_EQ(aFirstOwner, anOwnerIter.Value()); + anOwnerIter.Next(); + ASSERT_TRUE(anOwnerIter.More()); + EXPECT_EQ(aSecondOwner, anOwnerIter.Value()); + + EXPECT_EQ(AIS_SS_Removed, + aSelection->Select(aFirstOwner, + occ::handle(), + AIS_SelectionScheme_Remove, + false)); + EXPECT_FALSE(aFirstOwner->IsSelected()); + EXPECT_TRUE(aSecondOwner->IsSelected()); + ASSERT_EQ(1, aSelection->Extent()); + EXPECT_EQ(aSecondOwner, aSelection->Objects().First()); + + aSelection->Clear(); + EXPECT_TRUE(aSelection->IsEmpty()); + EXPECT_FALSE(aSecondOwner->IsSelected()); +} + +TEST(SelectMgr_SelectableObjectTest, Selections_AreKeyedByModeAndPreserveOrder) +{ + occ::handle aShape = new AIS_Shape(BRepPrimAPI_MakeBox(1.0, 1.0, 1.0).Shape()); + occ::handle aMode0 = new SelectMgr_Selection(0); + occ::handle aMode2 = new SelectMgr_Selection(2); + + aShape->AddSelection(aMode0, 0); + aShape->AddSelection(aMode2, 2); + + EXPECT_EQ(aMode0, aShape->Selection(0)); + EXPECT_EQ(aMode2, aShape->Selection(2)); + ASSERT_EQ(size_t(2), aShape->Selections().Size()); + + EXPECT_EQ(0, aShape->Selections().Value(0)->Mode()); + EXPECT_EQ(aMode0, aShape->Selections().Value(0)); + EXPECT_EQ(2, aShape->Selections().Value(1)->Mode()); + EXPECT_EQ(aMode2, aShape->Selections().Value(1)); + + occ::handle aMode0Replacement = new SelectMgr_Selection(0); + aShape->AddSelection(aMode0Replacement, 0); + + EXPECT_EQ(aMode0Replacement, aShape->Selection(0)); + ASSERT_EQ(size_t(2), aShape->Selections().Size()); + + // Replacement appends after existing entries - mode 2 is now first, the new mode-0 last. + EXPECT_EQ(2, aShape->Selections().Value(0)->Mode()); + EXPECT_EQ(aMode2, aShape->Selections().Value(0)); + EXPECT_EQ(0, aShape->Selections().Value(1)->Mode()); + EXPECT_EQ(aMode0Replacement, aShape->Selections().Value(1)); +} + +TEST(PrsMgr_PresentationManagerTest, AddToImmediateList_Deduplicates) +{ + occ::handle aDriver = new AIS_TestGraphicDriver(); + occ::handle aStructureManager = + new Graphic3d_StructureManager(aDriver); + occ::handle aPresentationManager = + new PrsMgr_PresentationManagerTestAccessor(aStructureManager); + occ::handle aPresentation = new Prs3d_Presentation(aStructureManager); + + aPresentationManager->AddToImmediateList(aPresentation); + EXPECT_EQ(size_t(0), aPresentationManager->ImmediateListSize()); + + aPresentationManager->BeginImmediateDraw(); + aPresentationManager->AddToImmediateList(aPresentation); + aPresentationManager->AddToImmediateList(aPresentation); + EXPECT_EQ(size_t(1), aPresentationManager->ImmediateListSize()); + + aPresentationManager->ClearImmediateDraw(); + EXPECT_EQ(size_t(0), aPresentationManager->ImmediateListSize()); +} diff --git a/src/Visualization/TKV3d/GTests/FILES.cmake b/src/Visualization/TKV3d/GTests/FILES.cmake index 47a5151dd4a..26abcfcb1fa 100644 --- a/src/Visualization/TKV3d/GTests/FILES.cmake +++ b/src/Visualization/TKV3d/GTests/FILES.cmake @@ -3,5 +3,6 @@ set(OCCT_TKV3d_GTests_FILES_LOCATION "${CMAKE_CURRENT_LIST_DIR}") set(OCCT_TKV3d_GTests_FILES AIS_ColoredShape_Test.cxx + AIS_InteractiveContext_Test.cxx Select3D_SensitivePrimitiveArray_Test.cxx ) diff --git a/src/Visualization/TKV3d/PrsMgr/PrsMgr_PresentationManager.cxx b/src/Visualization/TKV3d/PrsMgr/PrsMgr_PresentationManager.cxx index b3ab8fb607b..24a0f448040 100644 --- a/src/Visualization/TKV3d/PrsMgr/PrsMgr_PresentationManager.cxx +++ b/src/Visualization/TKV3d/PrsMgr/PrsMgr_PresentationManager.cxx @@ -344,19 +344,14 @@ void PrsMgr_PresentationManager::BeginImmediateDraw() void PrsMgr_PresentationManager::ClearImmediateDraw() { - for (NCollection_List>::Iterator anIter(myImmediateList); - anIter.More(); - anIter.Next()) + for (size_t i = 0; i < myImmediateList.Size(); ++i) { - anIter.Value()->Erase(); + myImmediateList.Value(i)->Erase(); } - for (NCollection_List>::Iterator anIter( - myViewDependentImmediateList); - anIter.More(); - anIter.Next()) + for (size_t i = 0; i < myViewDependentImmediateList.Size(); ++i) { - anIter.Value()->Erase(); + myViewDependentImmediateList.Value(i)->Erase(); } myImmediateList.Clear(); @@ -376,11 +371,9 @@ void PrsMgr_PresentationManager::displayImmediate(const occ::handle& anActiveViewIter.Next()) { const occ::handle& aView = anActiveViewIter.Value()->View(); - for (NCollection_List>::Iterator anIter(myImmediateList); - anIter.More(); - anIter.Next()) + for (size_t aPrsIdx_ = 0; aPrsIdx_ < myImmediateList.Size(); ++aPrsIdx_) { - const occ::handle& aPrs = anIter.Value(); + const occ::handle& aPrs = myImmediateList.Value(aPrsIdx_); if (aPrs.IsNull()) { continue; @@ -451,18 +444,13 @@ void PrsMgr_PresentationManager::RedrawImmediate(const occ::handle& } // Clear previously displayed structures - for (NCollection_List>::Iterator anIter(myImmediateList); - anIter.More(); - anIter.Next()) + for (size_t i = 0; i < myImmediateList.Size(); ++i) { - anIter.Value()->Erase(); + myImmediateList.Value(i)->Erase(); } - for (NCollection_List>::Iterator anIter( - myViewDependentImmediateList); - anIter.More(); - anIter.Next()) + for (size_t i = 0; i < myViewDependentImmediateList.Size(); ++i) { - anIter.Value()->Erase(); + myViewDependentImmediateList.Value(i)->Erase(); } myViewDependentImmediateList.Clear(); @@ -478,16 +466,13 @@ void PrsMgr_PresentationManager::AddToImmediateList(const occ::handle>::Iterator anIter(myImmediateList); - anIter.More(); - anIter.Next()) + for (size_t i = 0; i < myImmediateList.Size(); ++i) { - if (anIter.Value() == thePrs) + if (myImmediateList.Value(i) == thePrs) { return; } } - myImmediateList.Append(thePrs); } @@ -688,15 +673,13 @@ namespace //! and applies transformation theTrsf to them in case if parent ID //! of shadow presentation is equal to theRefId static void updatePrsTransformation( - const NCollection_List>& thePrsList, - const int theRefId, - const occ::handle& theTrsf) + const NCollection_LinearVector>& thePrsList, + const int theRefId, + const occ::handle& theTrsf) { - for (NCollection_List>::Iterator anIter(thePrsList); - anIter.More(); - anIter.Next()) + for (size_t i = 0; i < thePrsList.Size(); ++i) { - const occ::handle& aPrs = anIter.Value(); + const occ::handle& aPrs = thePrsList.Value(i); if (aPrs.IsNull()) { continue; diff --git a/src/Visualization/TKV3d/PrsMgr/PrsMgr_PresentationManager.hxx b/src/Visualization/TKV3d/PrsMgr/PrsMgr_PresentationManager.hxx index ae2e219697f..5bdb4462d6f 100644 --- a/src/Visualization/TKV3d/PrsMgr/PrsMgr_PresentationManager.hxx +++ b/src/Visualization/TKV3d/PrsMgr/PrsMgr_PresentationManager.hxx @@ -19,7 +19,7 @@ #include #include -#include +#include #include class Graphic3d_Structure; @@ -195,10 +195,10 @@ private: void displayImmediate(const occ::handle& theViewer); protected: - occ::handle myStructureManager; - int myImmediateModeOn; - NCollection_List> myImmediateList; - NCollection_List> myViewDependentImmediateList; + occ::handle myStructureManager; + int myImmediateModeOn; + NCollection_LinearVector> myImmediateList; + NCollection_LinearVector> myViewDependentImmediateList; }; #endif // _PrsMgr_PresentationManager_HeaderFile diff --git a/src/Visualization/TKV3d/SelectMgr/SelectMgr_SelectableObject.cxx b/src/Visualization/TKV3d/SelectMgr/SelectMgr_SelectableObject.cxx index 7d0488a2227..7c3828d8a3d 100644 --- a/src/Visualization/TKV3d/SelectMgr/SelectMgr_SelectableObject.cxx +++ b/src/Visualization/TKV3d/SelectMgr/SelectMgr_SelectableObject.cxx @@ -34,6 +34,24 @@ namespace { static const occ::handle THE_NULL_SELECTION; static const occ::handle THE_NULL_ENTITYOWNER; + +//! Linear scan for the selection of the given mode. +//! Returns its index or NPOS when not found. +constexpr size_t THE_NPOS = static_cast(-1); + +static size_t findSelectionIndex( + const NCollection_LinearVector>& theSelections, + const int theMode) +{ + for (size_t i = 0; i < theSelections.Size(); ++i) + { + if (theSelections.Value(i)->Mode() == theMode) + { + return i; + } + } + return THE_NPOS; +} } // namespace //================================================================================================= @@ -52,11 +70,9 @@ SelectMgr_SelectableObject::SelectMgr_SelectableObject( //================================================== SelectMgr_SelectableObject::~SelectMgr_SelectableObject() { - for (NCollection_Sequence>::Iterator aSelIter(myselections); - aSelIter.More(); - aSelIter.Next()) + for (size_t i = 0; i < myselections.Size(); ++i) { - aSelIter.Value()->Clear(); + myselections.Value(i)->Clear(); } } @@ -72,11 +88,16 @@ SelectMgr_SelectableObject::~SelectMgr_SelectableObject() //================================================== void SelectMgr_SelectableObject::RecomputePrimitives() { - for (NCollection_Sequence>::Iterator aSelIter(myselections); - aSelIter.More(); - aSelIter.Next()) + // Snapshot modes upfront - RecomputePrimitives(mode) may grow the vector and invalidate + // references. + NCollection_LinearVector aModes(myselections.Size()); + for (size_t i = 0; i < myselections.Size(); ++i) { - RecomputePrimitives(aSelIter.Value()->Mode()); + aModes.Append(myselections.Value(i)->Mode()); + } + for (size_t i = 0; i < aModes.Size(); ++i) + { + RecomputePrimitives(aModes.Value(i)); } } @@ -93,26 +114,22 @@ void SelectMgr_SelectableObject::RecomputePrimitives() void SelectMgr_SelectableObject::RecomputePrimitives(const int theMode) { SelectMgr_SelectableObject* aSelParent = dynamic_cast(Parent()); - for (NCollection_Sequence>::Iterator aSelIter(myselections); - aSelIter.More(); - aSelIter.Next()) + const size_t anIndex = findSelectionIndex(myselections, theMode); + if (anIndex != THE_NPOS) { - const occ::handle& aSel = aSelIter.Value(); - if (aSel->Mode() == theMode) + occ::handle& aSel = myselections.ChangeValue(anIndex); + aSel->Clear(); + ComputeSelection(aSel, theMode); + aSel->UpdateStatus(SelectMgr_TOU_Partial); + aSel->UpdateBVHStatus(SelectMgr_TBU_Renew); + if (theMode == 0 && aSelParent != nullptr) { - aSel->Clear(); - ComputeSelection(aSel, theMode); - aSel->UpdateStatus(SelectMgr_TOU_Partial); - aSel->UpdateBVHStatus(SelectMgr_TBU_Renew); - if (theMode == 0 && aSelParent != nullptr) + if (const occ::handle& anAsmOwner = aSelParent->GetAssemblyOwner()) { - if (const occ::handle& anAsmOwner = aSelParent->GetAssemblyOwner()) - { - SetAssemblyOwner(anAsmOwner, theMode); - } + SetAssemblyOwner(anAsmOwner, theMode); } - return; } + return; } occ::handle aNewSel = new SelectMgr_Selection(theMode); @@ -136,11 +153,9 @@ void SelectMgr_SelectableObject::RecomputePrimitives(const int theMode) void SelectMgr_SelectableObject::ClearSelections(const bool theToUpdate) { - for (NCollection_Sequence>::Iterator aSelIter(myselections); - aSelIter.More(); - aSelIter.Next()) + for (size_t i = 0; i < myselections.Size(); ++i) { - const occ::handle& aSel = aSelIter.Value(); + const occ::handle& aSel = myselections.Value(i); aSel->Clear(); aSel->UpdateBVHStatus(SelectMgr_TBU_Remove); if (theToUpdate) @@ -160,17 +175,8 @@ const occ::handle& SelectMgr_SelectableObject::Selection( return THE_NULL_SELECTION; } - for (NCollection_Sequence>::Iterator aSelIter(myselections); - aSelIter.More(); - aSelIter.Next()) - { - const occ::handle& aSel = aSelIter.Value(); - if (aSel->Mode() == theMode) - { - return aSel; - } - } - return THE_NULL_SELECTION; + const size_t anIndex = findSelectionIndex(myselections, theMode); + return anIndex != THE_NPOS ? myselections.Value(anIndex) : THE_NULL_SELECTION; } //================================================================================================= @@ -185,23 +191,16 @@ void SelectMgr_SelectableObject::AddSelection(const occ::handleUpdateBVHStatus(SelectMgr_TBU_Add); } - bool isReplaced = false; - for (NCollection_Sequence>::Iterator aSelIter(myselections); - aSelIter.More(); - aSelIter.Next()) + const size_t anExistingIndex = findSelectionIndex(myselections, theMode); + const bool isReplaced = anExistingIndex != THE_NPOS; + if (isReplaced) { - if (aSelIter.Value()->Mode() == theMode) - { - isReplaced = true; - myselections.Remove(aSelIter); - break; - } + myselections.Erase(anExistingIndex); } - myselections.Append(theSel); if (isReplaced) { - myselections.Last()->UpdateBVHStatus(SelectMgr_TBU_Renew); + theSel->UpdateBVHStatus(SelectMgr_TBU_Renew); } if (theMode == 0) @@ -221,11 +220,9 @@ void SelectMgr_SelectableObject::AddSelection(const occ::handle>::Iterator aSelIter(myselections); - aSelIter.More(); - aSelIter.Next()) + for (size_t i = 0; i < myselections.Size(); ++i) { - const occ::handle& aSel = aSelIter.Value(); + const occ::handle& aSel = myselections.Value(i); aSel->UpdateStatus(SelectMgr_TOU_Partial); aSel->UpdateBVHStatus(SelectMgr_TBU_None); } @@ -237,11 +234,9 @@ void SelectMgr_SelectableObject::ResetTransformation() void SelectMgr_SelectableObject::UpdateTransformation() { - for (NCollection_Sequence>::Iterator aSelIter(myselections); - aSelIter.More(); - aSelIter.Next()) + for (size_t i = 0; i < myselections.Size(); ++i) { - aSelIter.Value()->UpdateStatus(SelectMgr_TOU_Partial); + myselections.Value(i)->UpdateStatus(SelectMgr_TOU_Partial); } PrsMgr_PresentableObject::UpdateTransformation(); @@ -389,11 +384,9 @@ void SelectMgr_SelectableObject::SetZLayer(const Graphic3d_ZLayerId theLayerId) } // update all entity owner presentations - for (NCollection_Sequence>::Iterator aSelIter(myselections); - aSelIter.More(); - aSelIter.Next()) + for (size_t i = 0; i < myselections.Size(); ++i) { - const occ::handle& aSel = aSelIter.Value(); + const occ::handle& aSel = myselections.Value(i); for (NCollection_DynamicArray>::Iterator aSelEntIter( aSel->Entities()); aSelEntIter.More(); @@ -436,26 +429,17 @@ void SelectMgr_SelectableObject::updateSelection(const int theMode) { if (theMode == -1) { - for (NCollection_Sequence>::Iterator aSelIter(myselections); - aSelIter.More(); - aSelIter.Next()) + for (size_t i = 0; i < myselections.Size(); ++i) { - const occ::handle& aSel = aSelIter.Value(); - aSel->UpdateStatus(SelectMgr_TOU_Full); + myselections.Value(i)->UpdateStatus(SelectMgr_TOU_Full); } return; } - for (NCollection_Sequence>::Iterator aSelIter(myselections); - aSelIter.More(); - aSelIter.Next()) + const size_t anIndex = findSelectionIndex(myselections, theMode); + if (anIndex != THE_NPOS) { - const occ::handle& aSel = aSelIter.Value(); - if (aSel->Mode() == theMode) - { - aSel->UpdateStatus(SelectMgr_TOU_Full); - return; - } + myselections.Value(anIndex)->UpdateStatus(SelectMgr_TOU_Full); } } @@ -469,11 +453,9 @@ void SelectMgr_SelectableObject::SetAssemblyOwner( { if (theMode == -1) { - for (NCollection_Sequence>::Iterator aSelIter(myselections); - aSelIter.More(); - aSelIter.Next()) + for (size_t i = 0; i < myselections.Size(); ++i) { - const occ::handle& aSel = aSelIter.Value(); + const occ::handle& aSel = myselections.Value(i); for (NCollection_DynamicArray>::Iterator aSelEntIter( aSel->Entities()); aSelEntIter.More(); @@ -485,22 +467,17 @@ void SelectMgr_SelectableObject::SetAssemblyOwner( return; } - for (NCollection_Sequence>::Iterator aSelIter(myselections); - aSelIter.More(); - aSelIter.Next()) + const size_t anIndex = findSelectionIndex(myselections, theMode); + if (anIndex == THE_NPOS) { - const occ::handle& aSel = aSelIter.Value(); - if (aSel->Mode() == theMode) - { - for (NCollection_DynamicArray>::Iterator aSelEntIter( - aSel->Entities()); - aSelEntIter.More(); - aSelEntIter.Next()) - { - aSelEntIter.Value()->BaseSensitive()->Set(theOwner); - } - return; - } + return; + } + for (NCollection_DynamicArray>::Iterator aSelEntIter( + myselections.Value(anIndex)->Entities()); + aSelEntIter.More(); + aSelEntIter.Next()) + { + aSelEntIter.Value()->BaseSensitive()->Set(theOwner); } } @@ -516,11 +493,9 @@ Bnd_Box SelectMgr_SelectableObject::BndBoxOfSelected( } Bnd_Box aBnd; - for (NCollection_Sequence>::Iterator aSelIter(myselections); - aSelIter.More(); - aSelIter.Next()) + for (size_t i = 0; i < myselections.Size(); ++i) { - const occ::handle& aSel = aSelIter.Value(); + const occ::handle& aSel = myselections.Value(i); if (aSel->GetSelectionState() != SelectMgr_SOS_Activated) { continue; @@ -586,11 +561,9 @@ void SelectMgr_SelectableObject::DumpJson(Standard_OStream& theOStream, int theD OCCT_DUMP_FIELD_VALUES_DUMPED(theOStream, theDepth, mySelectionPrs.get()) OCCT_DUMP_FIELD_VALUES_DUMPED(theOStream, theDepth, myHilightPrs.get()) - for (NCollection_Sequence>::Iterator anIterator(myselections); - anIterator.More(); - anIterator.Next()) + for (size_t i = 0; i < myselections.Size(); ++i) { - const occ::handle& aSelection = anIterator.Value(); + const occ::handle& aSelection = myselections.Value(i); OCCT_DUMP_FIELD_VALUES_DUMPED(theOStream, theDepth, aSelection.get()) } diff --git a/src/Visualization/TKV3d/SelectMgr/SelectMgr_SelectableObject.hxx b/src/Visualization/TKV3d/SelectMgr/SelectMgr_SelectableObject.hxx index c920fa53ef2..546df1f9d62 100644 --- a/src/Visualization/TKV3d/SelectMgr/SelectMgr_SelectableObject.hxx +++ b/src/Visualization/TKV3d/SelectMgr/SelectMgr_SelectableObject.hxx @@ -19,8 +19,9 @@ #include #include -#include +#include #include +#include #include class SelectMgr_EntityOwner; @@ -95,8 +96,9 @@ public: //! object. bool HasSelection(const int theMode) const { return !Selection(theMode).IsNull(); } - //! Return the sequence of selections. - const NCollection_Sequence>& Selections() const + //! Return the contiguous list of selections in insertion order. + //! Each entry carries its own mode via SelectMgr_Selection::Mode(). + const NCollection_LinearVector>& Selections() const { return myselections; } @@ -206,13 +208,14 @@ protected: Standard_EXPORT virtual void updateSelection(const int theMode); protected: - NCollection_Sequence> myselections; //!< list of selections - // clang-format off + NCollection_LinearVector> + myselections; //!< selections in insertion order; mode lives on each entry + // clang-format off occ::handle mySelectionPrs; //!< optional presentation for highlighting selected object occ::handle myHilightPrs; //!< optional presentation for highlighting detected object - // clang-format on - int myGlobalSelMode; //!< global selection mode - bool myAutoHilight; //!< auto-highlighting flag defining + // clang-format on + int myGlobalSelMode; //!< global selection mode + bool myAutoHilight; //!< auto-highlighting flag defining }; #endif // _SelectMgr_SelectableObject_HeaderFile diff --git a/src/Visualization/TKV3d/SelectMgr/SelectMgr_SelectionImageFiller.cxx b/src/Visualization/TKV3d/SelectMgr/SelectMgr_SelectionImageFiller.cxx index 93833339962..e33d5b7589a 100644 --- a/src/Visualization/TKV3d/SelectMgr/SelectMgr_SelectionImageFiller.cxx +++ b/src/Visualization/TKV3d/SelectMgr/SelectMgr_SelectionImageFiller.cxx @@ -30,12 +30,9 @@ class GeneratedEntityColorFiller : public SelectMgr_SelectionImageFiller anObjIter.Next()) { const occ::handle& anObj = anObjIter.Value(); - for (NCollection_Sequence>::Iterator aSelIter( - anObj->Selections()); - aSelIter.More(); - aSelIter.Next()) + for (size_t aSelIdx = 0; aSelIdx < anObj->Selections().Size(); ++aSelIdx) { - const occ::handle& aSel = aSelIter.Value(); + const occ::handle& aSel = anObj->Selections().Value(aSelIdx); for (NCollection_DynamicArray>::Iterator aSelEntIter( aSel->Entities()); aSelEntIter.More(); @@ -84,12 +81,9 @@ class GeneratedEntityTypeColorFiller : public SelectMgr_SelectionImageFiller anObjIter.Next()) { const occ::handle& anObj = anObjIter.Value(); - for (NCollection_Sequence>::Iterator aSelIter( - anObj->Selections()); - aSelIter.More(); - aSelIter.Next()) + for (size_t aSelIdx = 0; aSelIdx < anObj->Selections().Size(); ++aSelIdx) { - const occ::handle& aSel = aSelIter.Value(); + const occ::handle& aSel = anObj->Selections().Value(aSelIdx); for (NCollection_DynamicArray>::Iterator aSelEntIter( aSel->Entities()); aSelEntIter.More(); @@ -245,12 +239,9 @@ class GeneratedOwnerColorFiller : public SelectMgr_SelectionImageFiller anObjIter.Next()) { const occ::handle& anObj = anObjIter.Value(); - for (NCollection_Sequence>::Iterator aSelIter( - anObj->Selections()); - aSelIter.More(); - aSelIter.Next()) + for (size_t aSelIdx = 0; aSelIdx < anObj->Selections().Size(); ++aSelIdx) { - const occ::handle& aSel = aSelIter.Value(); + const occ::handle& aSel = anObj->Selections().Value(aSelIdx); for (NCollection_DynamicArray>::Iterator aSelEntIter( aSel->Entities()); aSelEntIter.More(); @@ -324,12 +315,9 @@ class GeneratedSelModeColorFiller : public SelectMgr_SelectionImageFiller const occ::handle& aSelectable = myMainSel->Picked(thePicked)->Selectable(); const occ::handle& anEntity = myMainSel->PickedEntity(thePicked); - for (NCollection_Sequence>::Iterator aSelIter( - aSelectable->Selections()); - aSelIter.More(); - aSelIter.Next()) + for (size_t aSelIdx = 0; aSelIdx < aSelectable->Selections().Size(); ++aSelIdx) { - const occ::handle& aSelection = aSelIter.Value(); + const occ::handle& aSelection = aSelectable->Selections().Value(aSelIdx); for (NCollection_DynamicArray>::Iterator aSelEntIter( aSelection->Entities()); aSelEntIter.More(); diff --git a/src/Visualization/TKV3d/SelectMgr/SelectMgr_SelectionManager.cxx b/src/Visualization/TKV3d/SelectMgr/SelectMgr_SelectionManager.cxx index 9314ad69ef0..61a4da82699 100644 --- a/src/Visualization/TKV3d/SelectMgr/SelectMgr_SelectionManager.cxx +++ b/src/Visualization/TKV3d/SelectMgr/SelectMgr_SelectionManager.cxx @@ -95,14 +95,12 @@ void SelectMgr_SelectionManager::Remove(const occ::handleContains(theObject)) { - for (NCollection_Sequence>::Iterator aSelIter( - theObject->Selections()); - aSelIter.More(); - aSelIter.Next()) + for (size_t aSelIdx = 0; aSelIdx < theObject->Selections().Size(); ++aSelIdx) { - mySelector->RemoveSelectionOfObject(theObject, aSelIter.Value()); - aSelIter.Value()->UpdateBVHStatus(SelectMgr_TBU_Remove); - mySelector->Deactivate(aSelIter.Value()); + const occ::handle& aSel = theObject->Selections().Value(aSelIdx); + mySelector->RemoveSelectionOfObject(theObject, aSel); + aSel->UpdateBVHStatus(SelectMgr_TBU_Remove); + mySelector->Deactivate(aSel); } mySelector->RemoveSelectableObject(theObject); } @@ -221,12 +219,9 @@ void SelectMgr_SelectionManager::Deactivate( const occ::handle& aSel = theObject->Selection(theMode); if (theMode == -1) { - for (NCollection_Sequence>::Iterator aSelIter( - theObject->Selections()); - aSelIter.More(); - aSelIter.Next()) + for (size_t aSelIdx = 0; aSelIdx < theObject->Selections().Size(); ++aSelIdx) { - mySelector->Deactivate(aSelIter.Value()); + mySelector->Deactivate(theObject->Selections().Value(aSelIdx)); } } else if (!aSel.IsNull()) @@ -262,12 +257,9 @@ bool SelectMgr_SelectionManager::IsActivated( if (theMode == -1) { - for (NCollection_Sequence>::Iterator aSelIter( - theObject->Selections()); - aSelIter.More(); - aSelIter.Next()) + for (size_t aSelIdx = 0; aSelIdx < theObject->Selections().Size(); ++aSelIdx) { - if (mySelector->Status(aSelIter.Value()) == SelectMgr_SOS_Activated) + if (mySelector->Status(theObject->Selections().Value(aSelIdx)) == SelectMgr_SOS_Activated) { return true; } @@ -321,12 +313,9 @@ void SelectMgr_SelectionManager::ClearSelectionStructures( } else { - for (NCollection_Sequence>::Iterator aSelIter( - theObj->Selections()); - aSelIter.More(); - aSelIter.Next()) + for (size_t aSelIdx = 0; aSelIdx < theObj->Selections().Size(); ++aSelIdx) { - const occ::handle& aSelection = aSelIter.Value(); + const occ::handle& aSelection = theObj->Selections().Value(aSelIdx); mySelector->RemoveSelectionOfObject(theObj, aSelection); aSelection->UpdateBVHStatus(SelectMgr_TBU_Add); } @@ -370,12 +359,9 @@ void SelectMgr_SelectionManager::RestoreSelectionStructures( } else { - for (NCollection_Sequence>::Iterator aSelIter( - theObj->Selections()); - aSelIter.More(); - aSelIter.Next()) + for (size_t aSelIdx = 0; aSelIdx < theObj->Selections().Size(); ++aSelIdx) { - const occ::handle& aSelection = aSelIter.Value(); + const occ::handle& aSelection = theObj->Selections().Value(aSelIdx); mySelector->AddSelectionToObject(theObj, aSelection); aSelection->UpdateBVHStatus(SelectMgr_TBU_None); } @@ -445,12 +431,9 @@ void SelectMgr_SelectionManager::RecomputeSelection( if (theMode == -1) { - for (NCollection_Sequence>::Iterator aSelIter( - theObject->Selections()); - aSelIter.More(); - aSelIter.Next()) + for (size_t aSelIdx = 0; aSelIdx < theObject->Selections().Size(); ++aSelIdx) { - const occ::handle& aSelection = aSelIter.Value(); + const occ::handle& aSelection = theObject->Selections().Value(aSelIdx); const int aSelMode = aSelection->Mode(); recomputeSelectionMode(theObject, aSelection, aSelMode); } @@ -486,12 +469,9 @@ void SelectMgr_SelectionManager::Update(const occ::handle>::Iterator aSelIter( - theObject->Selections()); - aSelIter.More(); - aSelIter.Next()) + for (size_t aSelIdx = 0; aSelIdx < theObject->Selections().Size(); ++aSelIdx) { - const occ::handle& aSelection = aSelIter.Value(); + const occ::handle& aSelection = theObject->Selections().Value(aSelIdx); if (theIsForce || mySelector->Status(aSelection) == SelectMgr_SOS_Activated) { switch (aSelection->UpdateStatus()) @@ -595,12 +575,9 @@ void SelectMgr_SelectionManager::SetUpdateMode( const occ::handle& theObject, const SelectMgr_TypeOfUpdate theType) { - for (NCollection_Sequence>::Iterator aSelIter( - theObject->Selections()); - aSelIter.More(); - aSelIter.Next()) + for (size_t aSelIdx = 0; aSelIdx < theObject->Selections().Size(); ++aSelIdx) { - aSelIter.Value()->UpdateStatus(theType); + theObject->Selections().Value(aSelIdx)->UpdateStatus(theType); } } diff --git a/src/Visualization/TKV3d/SelectMgr/SelectMgr_ViewerSelector.cxx b/src/Visualization/TKV3d/SelectMgr/SelectMgr_ViewerSelector.cxx index 1dbb495eb4e..a6b44094b0e 100644 --- a/src/Visualization/TKV3d/SelectMgr/SelectMgr_ViewerSelector.cxx +++ b/src/Visualization/TKV3d/SelectMgr/SelectMgr_ViewerSelector.cxx @@ -973,18 +973,16 @@ bool SelectMgr_ViewerSelector::Modes( const SelectMgr_StateOfSelection theWantedState) const { bool hasActivatedStates = Contains(theSelectableObject); - for (NCollection_Sequence>::Iterator aSelIter( - theSelectableObject->Selections()); - aSelIter.More(); - aSelIter.Next()) + for (size_t aSelIdx = 0; aSelIdx < theSelectableObject->Selections().Size(); ++aSelIdx) { + const occ::handle& aSel = theSelectableObject->Selections().Value(aSelIdx); if (theWantedState == SelectMgr_SOS_Any) { - theModeList.Append(aSelIter.Value()->Mode()); + theModeList.Append(aSel->Mode()); } - else if (theWantedState == aSelIter.Value()->GetSelectionState()) + else if (theWantedState == aSel->GetSelectionState()) { - theModeList.Append(aSelIter.Value()->Mode()); + theModeList.Append(aSel->Mode()); } } @@ -1038,17 +1036,14 @@ TCollection_AsciiString SelectMgr_ViewerSelector::Status( const occ::handle& theSelectableObject) const { TCollection_AsciiString aStatus("Status Object :\n\t"); - for (NCollection_Sequence>::Iterator aSelIter( - theSelectableObject->Selections()); - aSelIter.More(); - aSelIter.Next()) + for (size_t aSelIdx = 0; aSelIdx < theSelectableObject->Selections().Size(); ++aSelIdx) { - if (aSelIter.Value()->GetSelectionState() != SelectMgr_SOS_Unknown) + const occ::handle& aSel = theSelectableObject->Selections().Value(aSelIdx); + if (aSel->GetSelectionState() != SelectMgr_SOS_Unknown) { - aStatus = - aStatus + "Mode " + TCollection_AsciiString(aSelIter.Value()->Mode()) + " present - " - + (aSelIter.Value()->GetSelectionState() == SelectMgr_SOS_Activated ? " Active \n\t" - : " Inactive \n\t"); + aStatus = aStatus + "Mode " + TCollection_AsciiString(aSel->Mode()) + " present - " + + (aSel->GetSelectionState() == SelectMgr_SOS_Activated ? " Active \n\t" + : " Inactive \n\t"); } } @@ -1391,15 +1386,13 @@ void SelectMgr_ViewerSelector::DisplaySensitive(const occ::handle& the occ::handle aStruct = new Graphic3d_Structure(theView->Viewer()->StructureManager()); const occ::handle& anObj = aSelectableIt.Value(); - for (NCollection_Sequence>::Iterator aSelIter( - anObj->Selections()); - aSelIter.More(); - aSelIter.Next()) + for (size_t aSelIdx = 0; aSelIdx < anObj->Selections().Size(); ++aSelIdx) { - if (aSelIter.Value()->GetSelectionState() == SelectMgr_SOS_Activated) + const occ::handle& aSel = anObj->Selections().Value(aSelIdx); + if (aSel->GetSelectionState() == SelectMgr_SOS_Activated) { SelectMgr::ComputeSensitivePrs(aStruct, - aSelIter.Value(), + aSel, anObj->Transformation(), anObj->TransformPersistence()); } diff --git a/src/Visualization/TKV3d/V3d/V3d_Viewer.hxx b/src/Visualization/TKV3d/V3d/V3d_Viewer.hxx index 59bb006cd87..22549480f0e 100644 --- a/src/Visualization/TKV3d/V3d/V3d_Viewer.hxx +++ b/src/Visualization/TKV3d/V3d/V3d_Viewer.hxx @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include @@ -573,7 +573,7 @@ private: private: occ::handle myDriver; occ::handle myStructureManager; - NCollection_Map myLayerIds; + NCollection_FlatMap myLayerIds; Aspect_GenId myZLayerGenId; NCollection_List> myDefinedViews;