From 5273a29f18f5e57e5c8c107ef912b64ce2676a96 Mon Sep 17 00:00:00 2001 From: mpv Date: Thu, 27 Aug 2015 12:10:26 +0300 Subject: [PATCH] Fix for the problem that selection of sub-elements of compsolids for concealment operation not erased the other sub-solids in the viewer. --- src/Model/Model_Update.cpp | 73 +++++++++++++++++++++++--------------- src/Model/Model_Update.h | 19 ++++++++++ 2 files changed, 64 insertions(+), 28 deletions(-) diff --git a/src/Model/Model_Update.cpp b/src/Model/Model_Update.cpp index d0b06ce0b..6c0dfc950 100644 --- a/src/Model/Model_Update.cpp +++ b/src/Model/Model_Update.cpp @@ -168,6 +168,47 @@ void Model_Update::processEvent(const std::shared_ptr& theMessag } } +bool Model_Update::iterateUpdate(std::shared_ptr theFeature) +{ + myProcessIterator.push_back(IterationItem()); + IterationItem& aCurrent = *myProcessIterator.rbegin(); + if (theFeature.get()) { + aCurrent.myMain = theFeature; + // two cycles: parameters must be processed first + for(int a = 0; a < theFeature->numberOfSubs(); a++) { + FeaturePtr aSub = theFeature->subFeature(a); + aCurrent.mySub = aSub; + if (aSub->getKind() == "Parameter") + updateFeature(aSub); + } + // number of subs can be changed in execution: like fillet + for(int a = 0; a < theFeature->numberOfSubs(); a++) { + FeaturePtr aSub = theFeature->subFeature(a); + aCurrent.mySub = aSub; + if (aSub->getKind() != "Parameter") + updateFeature(aSub); + } + } else { + DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument(); + Model_Objects* anObjs = std::dynamic_pointer_cast(aRootDoc)->objects(); + if (!anObjs) + return false; + aCurrent.mySub = anObjs->firstFeature(); + for (; aCurrent.mySub.get(); aCurrent.mySub = anObjs->nextFeature(aCurrent.mySub)) { + if (aCurrent.mySub->getKind() == "Parameter") + updateFeature(aCurrent.mySub); + } + aCurrent.mySub = anObjs->firstFeature(); + for (; aCurrent.mySub.get(); aCurrent.mySub = anObjs->nextFeature(aCurrent.mySub)) { + if (aCurrent.mySub->getKind() != "Parameter") + updateFeature(aCurrent.mySub); + } + } + // processing is finished, so, remove the iterated + myProcessIterator.pop_back(); + return true; // iteration is finished correctly +} + void Model_Update::processOperation(const bool theTotalUpdate, const bool theFinish) { if (theFinish) { @@ -202,23 +243,9 @@ void Model_Update::processOperation(const bool theTotalUpdate, const bool theFin isAutomaticChanged = true; myIsAutomatic = true; } - - // iterate all features in the root document to update each - DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument(); - Model_Objects* anObjs = std::dynamic_pointer_cast(aRootDoc)->objects(); - if (!anObjs) return; - // two cycles: parameters are first to process - FeaturePtr aFeatureIter = anObjs->firstFeature(); + // init iteration from the root document myProcessed.clear(); // to avoid processing twice - for (; aFeatureIter.get(); aFeatureIter = anObjs->nextFeature(aFeatureIter)) { - if (aFeatureIter->getKind() == "Parameter") - updateFeature(aFeatureIter); - } - aFeatureIter = anObjs->firstFeature(); - for (; aFeatureIter.get(); aFeatureIter = anObjs->nextFeature(aFeatureIter)) { - if (aFeatureIter->getKind() != "Parameter") - updateFeature(aFeatureIter); - } + iterateUpdate(CompositeFeaturePtr()); if (isAutomaticChanged) myIsAutomatic = false; myProcessed.clear(); // to avoid keeping features in memory @@ -264,18 +291,8 @@ void Model_Update::updateFeature(FeaturePtr theFeature) // composite feature must be executed after sub-features execution if (aCompos) { - // two cycles: parameters must be processed first - for(int a = 0; a < aCompos->numberOfSubs(); a++) { - FeaturePtr aSub = aCompos->subFeature(a); - if (aSub->getKind() == "Parameter") - updateFeature(aSub); - } - // number of subs can be changed in execution: like fillet - for(int a = 0; a < aCompos->numberOfSubs(); a++) { - FeaturePtr aSub = aCompos->subFeature(a); - if (aSub->getKind() != "Parameter") - updateFeature(aSub); - } + if (!iterateUpdate(aCompos)) + return; // iteration was interrupted, so, interrupt the update of this feature (it will be done later) // reupdate arguments of composite feature: it may be changed during subs execution if (theFeature->data()->execState() != ModelAPI_StateMustBeUpdated) updateArguments(theFeature); diff --git a/src/Model/Model_Update.h b/src/Model/Model_Update.h index aed04adae..845118c88 100644 --- a/src/Model/Model_Update.h +++ b/src/Model/Model_Update.h @@ -16,6 +16,7 @@ class ModelAPI_Object; class ModelAPI_Feature; +class ModelAPI_CompositeFeature; /**\class Model_Update * \ingroup DataModel @@ -38,6 +39,18 @@ class Model_Update : public Events_Listener /// Set of already processed features in the "processOperation" method std::set > myProcessed; + /// internal structure that contains the updating iteration information: + /// which object and subobject is iterated, t ocontinue iteration + struct IterationItem { + /// the main object, subs of it are iterated + std::shared_ptr myMain; + /// the currently iterated sub-object + std::shared_ptr mySub; + }; + /// List of iterated features: composite feature to the currently iterated sub. + /// The first element in the list has no "main": the root document is not feature. + std::list myProcessIterator; + public: /// Is called only once, on startup of the application Model_Update(); @@ -65,6 +78,12 @@ protected: /// Performs the feature execution /// \returns the status of execution void executeFeature(std::shared_ptr theFeature); + + /// Iterates and updates features from theFeature by managing myProcessIterator. + /// Returns only after the iteration is finished. + /// \param theFeature is null for iteration of root document (which is not composite) + /// \returns false if this feature should not be updated: iteration was moved much upper + bool iterateUpdate(std::shared_ptr theFeature); }; #endif -- 2.39.2