]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Speed up undo-redo and document loading: do not recompute persistence-based features .
authormpv <mpv@opencascade.com>
Wed, 29 Nov 2017 07:26:33 +0000 (10:26 +0300)
committermpv <mpv@opencascade.com>
Wed, 29 Nov 2017 07:26:33 +0000 (10:26 +0300)
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/Model/Model_Objects.cpp
src/Model/Model_Update.cpp
src/Model/Model_Update.h

index bb82a340e7190215deda3d9b8459ad96cb9236de..e11f26faa5ebb62378031c1a75745267a7512f9d 100755 (executable)
@@ -1817,3 +1817,15 @@ void Model_Document::eraseAllFeatures()
   if (myObjs)
     myObjs->eraseAllFeatures();
 }
+
+void Model_Document::setExecuteFeatures(const bool theFlag)
+{
+  myExecuteFeatures = theFlag;
+  const std::set<int> aSubs = subDocuments();
+  std::set<int>::iterator aSubIter = aSubs.begin();
+  for (; aSubIter != aSubs.end(); aSubIter++) {
+    if (!subDoc(*aSubIter)->myObjs)
+      continue;
+    subDoc(*aSubIter)->setExecuteFeatures(theFlag);
+  }
+}
index 4b33be6af7044e11e3edd715c35eb1dfc82f692f..b6358eb4f18f44a03bd781f75483020d3e404a25 100644 (file)
@@ -201,7 +201,10 @@ class Model_Document : public ModelAPI_Document
 
   ///! Returns true if parametric updater need to execute feature on recomputartion
   ///! On abort, undo or redo it is not necessary: results in document are updated automatically
-  bool& executeFeatures() {return myExecuteFeatures;}
+  bool executeFeatures() {return myExecuteFeatures;}
+
+  ///! On abort, undo or redo it is not necessary: results in document are updated automatically
+  void setExecuteFeatures(const bool theFlag);
 
   //! Registers the name of the shape for the topological naming needs
   void addNamingName(const TDF_Label theLabel, std::string theName);
index 85460450ce703b410da807ee6836e5cd974a2f19..17c62335760b13c2b0b1f26e037b2ef1a1b9f565 100644 (file)
@@ -69,7 +69,7 @@ void Model_Objects::setOwner(DocumentPtr theDoc)
   myDoc = theDoc;
   // update all fields and recreate features and result objects if needed
   TDF_LabelList aNoUpdated;
-  synchronizeFeatures(aNoUpdated, true, true, true, true);
+  synchronizeFeatures(aNoUpdated, true, false, true, true);
   myHistory.clear();
 }
 
@@ -783,8 +783,8 @@ void Model_Objects::synchronizeFeatures(
     myHistory.clear();
   }
 
-  if (theExecuteFeatures)
-    anOwner->executeFeatures() = false;
+  if (!theExecuteFeatures)
+    anOwner->setExecuteFeatures(false);
   aLoop->activateFlushes(isActive);
 
   if (theFlush) {
@@ -797,8 +797,8 @@ void Model_Objects::synchronizeFeatures(
     aLoop->flush(aRedispEvent);
     aLoop->flush(aToHideEvent);
   }
-  if (theExecuteFeatures)
-    anOwner->executeFeatures() = true;
+  if (!theExecuteFeatures)
+    anOwner->setExecuteFeatures(true);
 }
 
 /// synchronises back references for the given object basing on the collected data
index 4274d9c5e037da15b727e7a340718375f23c942b..8e2ac8137228b26224f0245b17bd2d08095d3399 100755 (executable)
@@ -90,6 +90,7 @@ bool Model_Update::addModified(FeaturePtr theFeature, FeaturePtr theReason) {
   bool isNotExecuted = theFeature->isPersistentResult() &&
     !std::dynamic_pointer_cast<Model_Document>((theFeature)->document())->executeFeatures();
   if (isNotExecuted) {
+    redisplayWithResults(theFeature, ModelAPI_StateNothing, false); // redisplay even not executed
     if (!theReason.get()) // no reason => no construction reason
       return false;
     if (myNotPersistentRefs.find(theFeature) == myNotPersistentRefs.end()) {
@@ -104,7 +105,10 @@ bool Model_Update::addModified(FeaturePtr theFeature, FeaturePtr theReason) {
 
   // update arguments for "apply button" state change
   if ((!theFeature->isPreviewNeeded() && !myIsFinish) || myIsPreviewBlocked) {
-    myProcessOnFinish.insert(theFeature);
+    if (theReason.get())
+      myProcessOnFinish[theFeature].insert(theReason);
+    else if (myProcessOnFinish.find(theFeature) == myProcessOnFinish.end())
+      myProcessOnFinish[theFeature] = std::set<std::shared_ptr<ModelAPI_Feature> >();
 #ifdef DEB_UPDATE
       std::cout<<"*** Add process on finish "<<theFeature->name()<<std::endl;
 #endif
@@ -319,10 +323,20 @@ void Model_Update::processEvent(const std::shared_ptr<Events_Message>& theMessag
     if (theMessage->eventID() == kOpFinishEvent) {
       myIsFinish = true;
       // add features that wait for finish as modified
-      std::set<std::shared_ptr<ModelAPI_Feature> >::iterator aFeature = myProcessOnFinish.begin();
-      for(; aFeature != myProcessOnFinish.end(); aFeature++)
-        if ((*aFeature)->data()->isValid()) // there may be already removed wait for features
-          addModified(*aFeature, FeaturePtr());
+      std::map<std::shared_ptr<ModelAPI_Feature>, std::set<std::shared_ptr<ModelAPI_Feature> > >::
+        iterator aFeature = myProcessOnFinish.begin();
+      for(; aFeature != myProcessOnFinish.end(); aFeature++) {
+        if (aFeature->first->data()->isValid()) {// there may be already removed while wait
+          if (aFeature->second.empty()) {
+            addModified(aFeature->first, FeaturePtr());
+            continue;
+          }
+          std::set<std::shared_ptr<ModelAPI_Feature> >::iterator aReasons;
+          for(aReasons = aFeature->second.begin(); aReasons != aFeature->second.end(); aReasons++) {
+            addModified(aFeature->first, *aReasons);
+          }
+        }
+      }
       myIsFinish = false;
     }
     // processed features must be only on finish, so clear anyway (to avoid reimport on load)
@@ -628,7 +642,8 @@ bool Model_Update::processFeature(FeaturePtr theFeature)
   return true;
 }
 
-void Model_Update::redisplayWithResults(FeaturePtr theFeature, const ModelAPI_ExecState theState)
+void Model_Update::redisplayWithResults(
+  FeaturePtr theFeature, const ModelAPI_ExecState theState, bool theUpdateState)
 {
   // make updated and redisplay all results
   static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
@@ -641,7 +656,8 @@ void Model_Update::redisplayWithResults(FeaturePtr theFeature, const ModelAPI_Ex
     if (!aRes->isDisabled()) {
       // update state only for enabled results
       // (Placement Result Part may make the original Part Result as invalid)
-      aRes->data()->execState(theState);
+      if (theUpdateState)
+        aRes->data()->execState(theState);
     }
     if (theFeature->data()->updateID() > aRes->data()->updateID()) {
       aRes->data()->setUpdateID(theFeature->data()->updateID());
@@ -650,7 +666,8 @@ void Model_Update::redisplayWithResults(FeaturePtr theFeature, const ModelAPI_Ex
   }
   // to redisplay "presentable" feature (for ex. distance constraint)
   ModelAPI_EventCreator::get()->sendUpdated(theFeature, EVENT_DISP);
-  theFeature->data()->execState(theState);
+  if (theUpdateState)
+    theFeature->data()->execState(theState);
 }
 
 /// Updates the state by the referenced object: if something bad with it, set state for this one
index cef7c0b49c4484241fb791aa0b132bee4b7dacbc..9a6ecc711bb27da78d47103aaec41dab8d9a67e9 100644 (file)
@@ -56,8 +56,10 @@ class Model_Update : public Events_Listener
   bool myIsFinish;
   /// try if processing is currently performed
   bool myIsProcessed;
-  /// set that contains features that must be executed only on finish of the operation
-  std::set<std::shared_ptr<ModelAPI_Feature> > myProcessOnFinish;
+  /// map that contains features that must be executed only on finish of the operation
+  /// the value in map is the set of reasons
+  std::map<std::shared_ptr<ModelAPI_Feature>, std::set<std::shared_ptr<ModelAPI_Feature> > >
+    myProcessOnFinish;
   /// to avoid infinitive cycling: feature -> count of the processing periods during this update
   std::map<std::shared_ptr<ModelAPI_Feature>, int > myProcessed;
   /// if preview in hte property panel is blocked and
@@ -89,7 +91,7 @@ protected:
 
   /// Sends the redisplay events for feature and results, updates the updated status
   void redisplayWithResults(std::shared_ptr<ModelAPI_Feature> theFeature,
-    const ModelAPI_ExecState theState);
+    const ModelAPI_ExecState theState, bool theUpdateState = true);
 
   /// On operation start/end/abort the "Just" fileds must be cleared and processed in the right way
   //! \param theFlushRedisplay a boolean value if the redisplay signal should be flushed