From b34e67df02366fafb9d8ecc149f476f30e91cdd0 Mon Sep 17 00:00:00 2001 From: vsv Date: Thu, 26 Jul 2018 15:57:11 +0300 Subject: [PATCH] Implement double sided map for displayed objects in order to improve performance --- src/PartSet/PartSet_Module.cpp | 6 +- src/XGUI/XGUI_Displayer.cpp | 32 +++------ src/XGUI/XGUI_Displayer.h | 120 +++++++++++++++++++++++++++++++-- 3 files changed, 128 insertions(+), 30 deletions(-) diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index b5c1821be..2cf51fbe1 100755 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -1132,10 +1132,8 @@ void PartSet_Module::onViewTransformed(int theTrsfType) const double aCurScale = aViewer->activeView()->Camera()->Scale(); aViewer->SetScale(aViewer->activeView(), aCurScale); bool isModified = false; - QList aPrsList = aDisplayer->displayedPresentations(); - foreach (AISObjectPtr aAIS, aPrsList) { - Handle(AIS_InteractiveObject) aAisObj = aAIS->impl(); - + QList aPrsList = aDisplayer->displayedPresentations(); + foreach(Handle(AIS_InteractiveObject) aAisObj, aPrsList) { Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast(aAisObj); if (!aDim.IsNull()) { aDim->DimensionAspect()->ArrowAspect()->SetLength(aLen); diff --git a/src/XGUI/XGUI_Displayer.cpp b/src/XGUI/XGUI_Displayer.cpp index 358e2403e..9df154d64 100644 --- a/src/XGUI/XGUI_Displayer.cpp +++ b/src/XGUI/XGUI_Displayer.cpp @@ -285,7 +285,7 @@ bool XGUI_Displayer::erase(ObjectPtr theObject, const bool theUpdateViewer) if (aContext.IsNull()) return aErased; - AISObjectPtr anObject = myResult2AISObjectMap[theObject]; + AISObjectPtr anObject = myResult2AISObjectMap.value(theObject); if (anObject) { Handle(AIS_InteractiveObject) anAIS = anObject->impl(); if (!anAIS.IsNull()) { @@ -503,7 +503,7 @@ void XGUI_Displayer::setSelected(const QList& theValue ObjectPtr anObject = aPrs->object(); ResultPtr aResult = std::dynamic_pointer_cast(anObject); if (aResult.get() && isVisible(aResult)) { - AISObjectPtr anObj = myResult2AISObjectMap[aResult]; + AISObjectPtr anObj = myResult2AISObjectMap.value(aResult); Handle(AIS_InteractiveObject) anAIS = anObj->impl(); if (!anAIS.IsNull()) { // The methods are replaced in order to provide multi-selection, e.g. restore selection @@ -545,8 +545,8 @@ bool XGUI_Displayer::eraseAll(const bool theUpdateViewer) bool aErased = false; Handle(AIS_InteractiveContext) aContext = AISContext(); if (!aContext.IsNull()) { - foreach (ObjectPtr aObj, myResult2AISObjectMap.keys()) { - AISObjectPtr aAISObj = myResult2AISObjectMap[aObj]; + foreach (ObjectPtr aObj, myResult2AISObjectMap.objects()) { + AISObjectPtr aAISObj = myResult2AISObjectMap.value(aObj); // erase an object Handle(AIS_InteractiveObject) anIO = aAISObj->impl(); if (!anIO.IsNull()) { @@ -573,10 +573,7 @@ bool XGUI_Displayer::eraseAll(const bool theUpdateViewer) //************************************************************** AISObjectPtr XGUI_Displayer::getAISObject(ObjectPtr theObject) const { - AISObjectPtr anIO; - if (myResult2AISObjectMap.contains(theObject)) - anIO = myResult2AISObjectMap[theObject]; - return anIO; + return myResult2AISObjectMap.value(theObject); } //************************************************************** @@ -589,16 +586,7 @@ ObjectPtr XGUI_Displayer::getObject(const AISObjectPtr& theIO) const //************************************************************** ObjectPtr XGUI_Displayer::getObject(const Handle(AIS_InteractiveObject)& theIO) const { - ObjectPtr anObject; - ResultToAISMap::const_iterator aMapIter = myResult2AISObjectMap.cbegin(); - for (; aMapIter != myResult2AISObjectMap.cend(); aMapIter++) { - const AISObjectPtr& aAIS = aMapIter.value(); - Handle(AIS_InteractiveObject) anAIS = aAIS->impl(); - if (anAIS == theIO) - anObject = aMapIter.key(); - if (anObject.get()) - break; - } + ObjectPtr anObject = myResult2AISObjectMap.value(theIO); if (!anObject.get()) { std::shared_ptr anAISObj = AISObjectPtr(new GeomAPI_AISObject()); if (!theIO.IsNull()) { @@ -861,7 +849,7 @@ void XGUI_Displayer::removeFilters() //************************************************************** void XGUI_Displayer::showOnly(const QObjectPtrList& theList) { - QObjectPtrList aDispList = myResult2AISObjectMap.keys(); + QObjectPtrList aDispList = myResult2AISObjectMap.objects(); foreach(ObjectPtr aObj, aDispList) { if (!theList.contains(aObj)) erase(aObj, false); @@ -940,7 +928,7 @@ QColor XGUI_Displayer::setObjectColor(ObjectPtr theObject, //************************************************************** void XGUI_Displayer::appendResultObject(ObjectPtr theObject, AISObjectPtr theAIS) { - myResult2AISObjectMap[theObject] = theAIS; + myResult2AISObjectMap.add(theObject, theAIS); #ifdef DEBUG_DISPLAY std::ostringstream aPtrStr; @@ -955,8 +943,8 @@ void XGUI_Displayer::appendResultObject(ObjectPtr theObject, AISObjectPtr theAIS std::string XGUI_Displayer::getResult2AISObjectMapInfo() const { QStringList aContent; - foreach (ObjectPtr aObj, myResult2AISObjectMap.keys()) { - AISObjectPtr aAISObj = myResult2AISObjectMap[aObj]; + foreach (ObjectPtr aObj, myResult2AISObjectMap.objects()) { + AISObjectPtr aAISObj = myResult2AISObjectMap.value(aObj); std::ostringstream aPtrStr; aPtrStr << "aObj = " << aObj.get() << ":"; aPtrStr << "anAIS = " << aAISObj.get() << ":"; diff --git a/src/XGUI/XGUI_Displayer.h b/src/XGUI/XGUI_Displayer.h index 50b4a79d5..870c06af7 100644 --- a/src/XGUI/XGUI_Displayer.h +++ b/src/XGUI/XGUI_Displayer.h @@ -51,6 +51,116 @@ class XGUI_Workshop; class VInspectorAPI_CallBack; #endif + +class XGUI_TwoSidePresentationMap +{ +public: + ~XGUI_TwoSidePresentationMap() { clear(); } + + /// Add new values pair to the map + /// \param theObj an object + /// \param theAIS a corresponded presentation + bool add(const ObjectPtr& theObj, const AISObjectPtr& theAIS) + { + if (myResultToAISMap.contains(theObj)) + return false; + Handle(AIS_InteractiveObject) anAIS = theAIS->impl(); + myResultToAISMap[theObj] = anAIS; + myAIStoResultMap[anAIS] = theObj; + return true; + } + + /// Removes values by object + /// \param theObj an object + bool remove(const ObjectPtr& theObj) + { + if (!myResultToAISMap.contains(theObj)) + return false; + Handle(AIS_InteractiveObject) aAIS = myResultToAISMap[theObj]; + myResultToAISMap.remove(theObj); + myAIStoResultMap.remove(aAIS); + return true; + } + + /// Removes values by presentation + /// \param theAIS a presentation + bool remove(const AISObjectPtr& theAIS) + { + Handle(AIS_InteractiveObject) anAIS = theAIS->impl(); + if (!myAIStoResultMap.contains(anAIS)) + return false; + ObjectPtr aObj = myAIStoResultMap[anAIS]; + myResultToAISMap.remove(aObj); + myAIStoResultMap.remove(anAIS); + return true; + } + + /// Removes all values + void clear() + { + myResultToAISMap.clear(); + myAIStoResultMap.clear(); + } + + /// Returns presentation by object + /// \param theObj an object + AISObjectPtr value(const ObjectPtr& theObj) const + { + if (myResultToAISMap.contains(theObj)) { + Handle(AIS_InteractiveObject) anAIS = myResultToAISMap[theObj]; + AISObjectPtr anAISObj = AISObjectPtr(new GeomAPI_AISObject()); + anAISObj->setImpl(new Handle(AIS_InteractiveObject)(anAIS)); + return anAISObj; + } + return AISObjectPtr(); + } + + /// Returns object by presentation + /// \param theAIS a presentation + ObjectPtr value(const AISObjectPtr& theAIS) const + { + Handle(AIS_InteractiveObject) anAIS = theAIS->impl(); + if (myAIStoResultMap.contains(anAIS)) + return myAIStoResultMap[anAIS]; + return ObjectPtr(); + } + + /// Returns object by presentation + /// \param theAIS a presentation + ObjectPtr value(const Handle(AIS_InteractiveObject)& theAIS) const + { + if (myAIStoResultMap.contains(theAIS)) + return myAIStoResultMap[theAIS]; + return ObjectPtr(); + } + + /// Returns number of values + int size() const { return myResultToAISMap.size(); } + + /// Returns list of objects + QObjectPtrList objects() const { return myResultToAISMap.keys(); } + + /// returns list of presentations + QList presentations() const { return myAIStoResultMap.keys(); } + + /// Returns true if the Map contains the object + /// \param theObj an object + bool contains(const ObjectPtr& theObj) const { return myResultToAISMap.contains(theObj); } + + /// Returns true if the Map contains the presentation + /// \param theAIS a presentation + bool contains(const AISObjectPtr& theAIS) const + { + Handle(AIS_InteractiveObject) anAIS = theAIS->impl(); + return myAIStoResultMap.contains(anAIS); + } + +private: + QMap myResultToAISMap; + QMap myAIStoResultMap; +}; + + /**\class XGUI_Displayer * \ingroup GUI * \brief Displayer. Provides mechanizm of display/erase of objects in the viewer @@ -205,10 +315,13 @@ class XGUI_EXPORT XGUI_Displayer: public QObject int objectsCount() const { return myResult2AISObjectMap.size(); } /// Returns list of displayed objects - QObjectPtrList displayedObjects() const { return myResult2AISObjectMap.keys(); } + QObjectPtrList displayedObjects() const { return myResult2AISObjectMap.objects(); } /// Returns list of displayed objects - QList displayedPresentations() const { return myResult2AISObjectMap.values(); } + QList displayedPresentations() const + { + return myResult2AISObjectMap.presentations(); + } /// Returns true if the given object can be shown in shaded mode /// \param theObject object to check @@ -318,8 +431,7 @@ protected: GeomCustomPrsPtr myCustomPrs; /// Definition of a type of map which defines correspondance between objects and presentations - typedef QMap ResultToAISMap; - ResultToAISMap myResult2AISObjectMap; ///< A map of displayed objects + XGUI_TwoSidePresentationMap myResult2AISObjectMap; ///< A map of displayed objects /// Number of blocking of the viewer update. The viewer is updated only if it is zero int myViewerBlockedRecursiveCount; -- 2.39.2