From: mpv Date: Wed, 1 Jul 2015 17:06:23 +0000 (+0300) Subject: Fix for the issue #587 and general optimization and debug of parametric update. X-Git-Tag: V_1.3.0~128 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=7180ff8200cdfcbdcf28b31e6b8729824b3f1599;p=modules%2Fshaper.git Fix for the issue #587 and general optimization and debug of parametric update. --- diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 62e27bdd0..cc37e8bef 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -902,3 +902,13 @@ bool Model_Document::isOpened() { return myObjs && !myDoc.IsNull(); } + +int Model_Document::numInternalFeatures() +{ + return myObjs->numInternalFeatures(); +} + +std::shared_ptr Model_Document::internalFeature(const int theIndex) +{ + return myObjs->internalFeature(theIndex); +} diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index 586d50a28..ba7ecb7af 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -136,6 +136,11 @@ class Model_Document : public ModelAPI_Document //! Makes the current feature one feature upper MODEL_EXPORT virtual void setCurrentFeatureUp(); + //! Returns the number of all features: in the history or not + MODEL_EXPORT virtual int numInternalFeatures(); + //! Returns the feature by zero-based index: features in the history or not + MODEL_EXPORT virtual std::shared_ptr internalFeature(const int theIndex); + /// Creates a construction cresults MODEL_EXPORT virtual std::shared_ptr createConstruction( const std::shared_ptr& theFeatureData, const int theIndex = 0); diff --git a/src/Model/Model_Objects.cpp b/src/Model/Model_Objects.cpp index 1361a931a..224d9d9db 100644 --- a/src/Model/Model_Objects.cpp +++ b/src/Model/Model_Objects.cpp @@ -913,6 +913,24 @@ std::list > Model_Objects::allFeatures() return aResult; } +int Model_Objects::numInternalFeatures() +{ + Handle(TDataStd_ReferenceArray) aRefs; + if (featuresLabel().FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs)) { + return aRefs->Upper() - aRefs->Lower() + 1; + } + return 0; // invalid +} + +std::shared_ptr Model_Objects::internalFeature(const int theIndex) +{ + Handle(TDataStd_ReferenceArray) aRefs; + if (featuresLabel().FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs)) { + return feature(aRefs->Value(aRefs->Lower() + theIndex)); + } + return FeaturePtr(); // invalid +} + Standard_Integer HashCode(const TDF_Label& theLab, const Standard_Integer theUpper) { return TDF_LabelMapHasher::HashCode(theLab, theUpper); diff --git a/src/Model/Model_Objects.h b/src/Model/Model_Objects.h index cd7f440e7..9bab83b67 100644 --- a/src/Model/Model_Objects.h +++ b/src/Model/Model_Objects.h @@ -86,6 +86,11 @@ class Model_Objects ///! Returns all (and disabled) results of the given type. Not fast method (iterates all features). void allResults(const std::string& theGroupID, std::list& theResults); + //! Returns the number of all features: in the history or not + int numInternalFeatures(); + //! Returns the feature by zero-based index: features in the history or not + std::shared_ptr internalFeature(const int theIndex); + /// Creates a construction cresults std::shared_ptr createConstruction( const std::shared_ptr& theFeatureData, const int theIndex = 0); diff --git a/src/Model/Model_Update.cpp b/src/Model/Model_Update.cpp index d87e87ed8..1e5bb3fed 100644 --- a/src/Model/Model_Update.cpp +++ b/src/Model/Model_Update.cpp @@ -59,6 +59,7 @@ Model_Update::Model_Update() myIsAutomatic = Config_PropManager::findProp("Model update", "automatic_rebuild")->value() == "true"; myIsParamUpdated = false; + myIsFinish = false; } void Model_Update::processEvent(const std::shared_ptr& theMessage) @@ -72,7 +73,6 @@ void Model_Update::processEvent(const std::shared_ptr& theMessag static const Events_ID kOpFinishEvent = aLoop->eventByName("FinishOperation"); static const Events_ID kOpAbortEvent = aLoop->eventByName("AbortOperation"); static const Events_ID kOpStartEvent = aLoop->eventByName("StartOperation"); - bool isOperationChanged = false; if (theMessage->eventID() == kChangedEvent) { // automatic and manual rebuild flag is changed bool aPropVal = Config_PropManager::findProp("Model update", "automatic_rebuild")->value() == "true"; @@ -104,34 +104,28 @@ void Model_Update::processEvent(const std::shared_ptr& theMessag // this event is for solver update, not here, do not react immideately if (!isOnlyResults && !(theMessage->eventID() == kMovedEvent)) processOperation(false); - } else if (theMessage->eventID() == kOpStartEvent) { - // we don't need the update only on operation start (caused problems in PartSet_Listener::processEvent) - isOperationChanged = true; - } else if (theMessage->eventID() == kOpFinishEvent || theMessage->eventID() == kOpAbortEvent) { - processOperation(true, theMessage->eventID() == kOpFinishEvent); - isOperationChanged = true; - } - if (isOperationChanged) { - // remove all macros before clearing all created and execute all not-previewed - std::set::iterator anUpdatedIter = myJustUpdated.begin(); - while(anUpdatedIter != myJustUpdated.end()) { + } else if (theMessage->eventID() == kOpFinishEvent || theMessage->eventID() == kOpAbortEvent || + theMessage->eventID() == kOpStartEvent) { + myIsParamUpdated = false; + + if (!(theMessage->eventID() == kOpStartEvent)) { + myIsFinish = true; + processOperation(true, theMessage->eventID() == kOpFinishEvent); + myIsFinish = false; + } + // remove all macros before clearing all created + std::set::iterator anUpdatedIter = myWaitForFinish.begin(); + while(anUpdatedIter != myWaitForFinish.end()) { FeaturePtr aFeature = std::dynamic_pointer_cast(*anUpdatedIter); if (aFeature.get()) { - // execute not-previewed feature on "apply" - if (!aFeature->isPreviewNeeded()) { - static ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators(); - if (aFactory->validate(aFeature)) { - executeFeature(aFeature); - } - } - // remove macro on apply + // remove macro on finish if (aFeature->isMacro()) { aFeature->document()->removeFeature(aFeature); - myJustUpdated.erase(aFeature); + myWaitForFinish.erase(aFeature); } // to avoid the map update problems on "remove" - if (myJustUpdated.find(aFeature) == myJustUpdated.end()) { - anUpdatedIter = myJustUpdated.begin(); + if (myWaitForFinish.find(aFeature) == myWaitForFinish.end()) { + anUpdatedIter = myWaitForFinish.begin(); } else { anUpdatedIter++; } @@ -139,7 +133,10 @@ void Model_Update::processEvent(const std::shared_ptr& theMessag anUpdatedIter++; } } - myIsParamUpdated = false; + // in the end of transaction everything is updated, so clear the old objects (the only one + // place where results are cleared) + myJustUpdated.clear(); + myWaitForFinish.clear(); } } @@ -163,7 +160,6 @@ void Model_Update::processOperation(const bool theTotalUpdate, const bool theFin } } } - myWaitForFinish.clear(); } // perform update of everything if needed if (!myIsExecuted) { @@ -243,8 +239,8 @@ void Model_Update::updateFeature(FeaturePtr theFeature, std::set& th aJustUpdated = true; // execute feature if it must be updated - if (theFeature->isPreviewNeeded()) { - if ((myIsAutomatic || aJustUpdated) && + if (theFeature->isPreviewNeeded() || myIsFinish) { + if (aJustUpdated && std::dynamic_pointer_cast(theFeature->document())->executeFeatures()) { ModelAPI_ExecState aState = theFeature->data()->execState(); if (aFactory->validate(theFeature)) { @@ -257,6 +253,8 @@ void Model_Update::updateFeature(FeaturePtr theFeature, std::set& th } else { // preview is not needed => make state Done if (theFeature->data()->execState() == ModelAPI_StateMustBeUpdated) { theFeature->data()->execState(ModelAPI_StateDone); + if (aJustUpdated) // store that it must be updated on finish + myJustUpdated.insert(theFeature); } } } @@ -431,6 +429,21 @@ void Model_Update::updateArguments(FeaturePtr theFeature) { aState = stateByReference(*aRefObj, aState); } } + // composites sub-elements + CompositeFeaturePtr aCompos = std::dynamic_pointer_cast(theFeature); + // composite feature must be executed after sub-features execution + if (aCompos) { + // number of subs can be changed in execution: like fillet + for(int a = 0; a < aCompos->numberOfSubs(); a++) { + FeaturePtr aSub = aCompos->subFeature(a); + if (myJustUpdated.find(aSub) != myJustUpdated.end() || + (aSub.get() && aSub->data()->updateID() > theFeature->data()->updateID())) { + if (aState == ModelAPI_StateDone) + aState = ModelAPI_StateMustBeUpdated; + } + } + } + if (aState != ModelAPI_StateDone) theFeature->data()->execState(aState); diff --git a/src/Model/Model_Update.h b/src/Model/Model_Update.h index 1ae12eb09..d8d590497 100644 --- a/src/Model/Model_Update.h +++ b/src/Model/Model_Update.h @@ -33,6 +33,8 @@ class Model_Update : public Events_Listener bool myIsAutomatic; /// to know that some parameter was changed during this operation bool myIsParamUpdated; + /// to execute features of finish if perview is not needed + bool myIsFinish; public: /// Is called only once, on startup of the application diff --git a/src/ModelAPI/ModelAPI_Document.h b/src/ModelAPI/ModelAPI_Document.h index 2a97982b0..6d778360f 100644 --- a/src/ModelAPI/ModelAPI_Document.h +++ b/src/ModelAPI/ModelAPI_Document.h @@ -102,6 +102,12 @@ public: //! Makes the current feature one feature upper virtual void setCurrentFeatureUp() = 0; + //! Returns the number of all features: in the history or not + virtual int numInternalFeatures() = 0; + //! Returns the feature by zero-based index: features in the history or not + virtual std::shared_ptr internalFeature(const int theIndex) = 0; + + //! To virtually destroy the fields of successors MODELAPI_EXPORT virtual ~ModelAPI_Document(); diff --git a/src/PartSetPlugin/PartSetPlugin_Part.cpp b/src/PartSetPlugin/PartSetPlugin_Part.cpp index 04b6ddd6e..3ef0eb192 100644 --- a/src/PartSetPlugin/PartSetPlugin_Part.cpp +++ b/src/PartSetPlugin/PartSetPlugin_Part.cpp @@ -67,7 +67,7 @@ int PartSetPlugin_Part::numberOfSubs() const if (aResult.get()) { DocumentPtr aDoc = aResult->partDoc(); if (aDoc.get()) - return aDoc->size(ModelAPI_Feature::group()); + return aDoc->numInternalFeatures(); } return 0; } @@ -78,8 +78,7 @@ std::shared_ptr PartSetPlugin_Part::subFeature(const int theIn if (aResult.get()) { DocumentPtr aDoc = aResult->partDoc(); if (aDoc.get()) { - return std::dynamic_pointer_cast( - aDoc->object(ModelAPI_Feature::group(), theIndex)); + return aDoc->internalFeature(theIndex); } } return FeaturePtr();