From 06aca3328687481ab5bc7d447062ce757c215036 Mon Sep 17 00:00:00 2001 From: mpv Date: Fri, 29 Sep 2017 10:40:43 +0300 Subject: [PATCH] Speed-up of the access from OB to complicated compsolids in the frames of issue #2256 --- src/Model/Model_ResultCompSolid.cpp | 14 +++++++++----- src/Model/Model_ResultCompSolid.h | 6 +++++- src/ModelAPI/ModelAPI_ResultCompSolid.h | 3 ++- src/ModelAPI/ModelAPI_Tools.cpp | 22 +++++++++++++++++++++- src/ModelAPI/ModelAPI_Tools.h | 5 +++++ src/XGUI/XGUI_DataModel.cpp | 7 +------ 6 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/Model/Model_ResultCompSolid.cpp b/src/Model/Model_ResultCompSolid.cpp index 231c0b6ed..c650196d9 100755 --- a/src/Model/Model_ResultCompSolid.cpp +++ b/src/Model/Model_ResultCompSolid.cpp @@ -98,12 +98,13 @@ std::shared_ptr Model_ResultCompSolid::subResult(const int return mySubs.at(theIndex); } -bool Model_ResultCompSolid::isSub(ObjectPtr theObject) const +bool Model_ResultCompSolid::isSub(ObjectPtr theObject, int& theIndex) const { - std::vector >::const_iterator aSubIter = mySubs.cbegin(); - for(; aSubIter != mySubs.cend(); aSubIter++) - if (*aSubIter == theObject) - return true; + std::map::const_iterator aFound = mySubsMap.find(theObject); + if (aFound != mySubsMap.end()) { + theIndex = aFound->second; + return true; + } return false; } @@ -213,6 +214,7 @@ void Model_ResultCompSolid::updateSubs(const std::shared_ptr& the if (mySubs.size() <= aSubIndex) { // it is needed to create a new sub-result aSub = anObjects->createBody(this->data(), aSubIndex); mySubs.push_back(aSub); + mySubsMap[aSub] = int(mySubs.size() - 1); } else { // just update shape of this result aSub = mySubs[aSubIndex]; } @@ -228,6 +230,7 @@ void Model_ResultCompSolid::updateSubs(const std::shared_ptr& the while(mySubs.size() > aSubIndex) { ResultBodyPtr anErased = *(mySubs.rbegin()); anErased->setDisabled(anErased, true); + mySubsMap.erase(anErased); mySubs.pop_back(); } if (aWasEmpty) { // erase all subs @@ -241,6 +244,7 @@ void Model_ResultCompSolid::updateSubs(const std::shared_ptr& the anErased->setDisabled(anErased, true); mySubs.pop_back(); } + mySubsMap.clear(); // redisplay this because result with and without subs are displayed differently aECreator->sendUpdated(data()->owner(), EVENT_DISP); } diff --git a/src/Model/Model_ResultCompSolid.h b/src/Model/Model_ResultCompSolid.h index 7fcf5cc59..c748aeeae 100755 --- a/src/Model/Model_ResultCompSolid.h +++ b/src/Model/Model_ResultCompSolid.h @@ -24,6 +24,7 @@ #include "Model.h" #include #include +#include /**\class Model_ResultCompSolid * \ingroup DataModel @@ -35,6 +36,8 @@ class Model_ResultCompSolid : public ModelAPI_ResultCompSolid { /// Sub-bodies if this is compsolid: zero base index to subs std::vector > mySubs; + /// Also keep map of result to index in mySubs to facilitate speed of access from OB + std::map mySubsMap; /// Flag that stores the previous state of "concealed": if it is changed, /// The event must be generated to redisplay this and all subs. bool myLastConcealed; @@ -74,7 +77,8 @@ public: bool forTree = false) const; /// Returns true if feature or reuslt belong to this composite feature as subs - MODEL_EXPORT virtual bool isSub(ObjectPtr theObject) const; + /// Returns theIndex - zero based index of sub if found + MODEL_EXPORT virtual bool isSub(ObjectPtr theObject, int& theIndex) const; /// Returns the parameters of color definition in the resources config manager MODEL_EXPORT virtual void colorConfigInfo(std::string& theSection, std::string& theName, diff --git a/src/ModelAPI/ModelAPI_ResultCompSolid.h b/src/ModelAPI/ModelAPI_ResultCompSolid.h index b2558013c..70abc72d0 100755 --- a/src/ModelAPI/ModelAPI_ResultCompSolid.h +++ b/src/ModelAPI/ModelAPI_ResultCompSolid.h @@ -45,7 +45,8 @@ public: bool forTree = false) const = 0; /// Returns true if feature or reuslt belong to this composite feature as subs - virtual bool isSub(ObjectPtr theObject) const = 0; + /// Returns theIndex - zero based index of sub if found + virtual bool isSub(ObjectPtr theObject, int& theIndex) const = 0; /// Set displayed flag to the result and all sub results /// \param theDisplay a boolean value diff --git a/src/ModelAPI/ModelAPI_Tools.cpp b/src/ModelAPI/ModelAPI_Tools.cpp index 9dd0d9d6c..3be42d1f4 100755 --- a/src/ModelAPI/ModelAPI_Tools.cpp +++ b/src/ModelAPI/ModelAPI_Tools.cpp @@ -268,6 +268,7 @@ CompositeFeaturePtr compositeOwner(const FeaturePtr& theFeature) ResultCompSolidPtr compSolidOwner(const ResultPtr& theSub) { + int anIndex; ResultBodyPtr aBody = std::dynamic_pointer_cast(theSub); if (aBody.get()) { FeaturePtr aFeatureOwner = aBody->document()->feature(aBody); @@ -276,7 +277,7 @@ ResultCompSolidPtr compSolidOwner(const ResultPtr& theSub) aFeatureOwner->results().cbegin(); for(; aResIter != aFeatureOwner->results().cend(); aResIter++) { ResultCompSolidPtr aComp = std::dynamic_pointer_cast(*aResIter); - if (aComp && aComp->isSub(aBody)) + if (aComp && aComp->isSub(aBody, anIndex)) return aComp; } } @@ -284,6 +285,25 @@ ResultCompSolidPtr compSolidOwner(const ResultPtr& theSub) return ResultCompSolidPtr(); // not found } +int compSolidIndex(const ResultPtr& theSub) +{ + int anIndex = -1; + ResultBodyPtr aBody = std::dynamic_pointer_cast(theSub); + if (aBody.get()) { + FeaturePtr aFeatureOwner = aBody->document()->feature(aBody); + if (aFeatureOwner.get()) { + std::list >::const_iterator aResIter = + aFeatureOwner->results().cbegin(); + for(; aResIter != aFeatureOwner->results().cend(); aResIter++) { + ResultCompSolidPtr aComp = std::dynamic_pointer_cast(*aResIter); + if (aComp && aComp->isSub(aBody, anIndex)) + return anIndex; + } + } + } + return anIndex; // not found +} + bool hasSubResults(const ResultPtr& theResult) { ResultCompSolidPtr aCompSolid = std::dynamic_pointer_cast(theResult); diff --git a/src/ModelAPI/ModelAPI_Tools.h b/src/ModelAPI/ModelAPI_Tools.h index ca3a1d1d8..c119924cb 100755 --- a/src/ModelAPI/ModelAPI_Tools.h +++ b/src/ModelAPI/ModelAPI_Tools.h @@ -107,6 +107,11 @@ MODELAPI_EXPORT std::shared_ptr compositeOwner( */ MODELAPI_EXPORT std::shared_ptr compSolidOwner( const std::shared_ptr& theSub); +/*! + * Returns index of this result in parent (if parent exists, returned by compSolidOwner) + * \returns zero-base index, or -1 if not found + */ +MODELAPI_EXPORT int compSolidIndex(const std::shared_ptr& theSub); /*! * Returns true if the result contains a not empty list of sub results. diff --git a/src/XGUI/XGUI_DataModel.cpp b/src/XGUI/XGUI_DataModel.cpp index 30cf4e574..758fb4f23 100644 --- a/src/XGUI/XGUI_DataModel.cpp +++ b/src/XGUI/XGUI_DataModel.cpp @@ -386,12 +386,7 @@ QModelIndex XGUI_DataModel::objectIndex(const ObjectPtr theObject) const if (aResult.get()) { ResultCompSolidPtr aCompRes = ModelAPI_Tools::compSolidOwner(aResult); if (aCompRes.get()) { - for (int i = 0; i < aCompRes->numberOfSubs(true); i++) { - if (aCompRes->subResult(i, true) == theObject) { - aRow = i; - break; - } - } + aRow = ModelAPI_Tools::compSolidIndex(aResult); } } } -- 2.39.2