Salome HOME
Fix for the issue #1755 : for now the sketch solver receives all modified entities...
[modules/shaper.git] / src / Model / Model_Update.cpp
index c081fbd7079b1dd1691ccb4a116d7452dad0d93e..bb00695b2f8fe2b726a2ab875535d059871d1e20 100755 (executable)
@@ -71,9 +71,19 @@ bool Model_Update::addModified(FeaturePtr theFeature, FeaturePtr theReason) {
   if (!theFeature->data()->isValid())
     return false; // delete an extrusion created on the sketch
 
-  if (theFeature->isPersistentResult()) {
-    if (!std::dynamic_pointer_cast<Model_Document>((theFeature)->document())->executeFeatures())
+  bool isNotExecuted = theFeature->isPersistentResult() &&
+    !std::dynamic_pointer_cast<Model_Document>((theFeature)->document())->executeFeatures();
+  if (isNotExecuted) {
+    if (!theReason.get()) // no reason => no construction reason
       return false;
+    if (myNotPersistentRefs.find(theFeature) == myNotPersistentRefs.end()) {
+      myNotPersistentRefs[theFeature].insert(theReason);
+    } else {
+      std::set<std::shared_ptr<ModelAPI_Feature> > aNewSet;
+      aNewSet.insert(theReason);
+      myNotPersistentRefs[theFeature] = aNewSet;
+    }
+    return false;
   }
 
   // update arguments for "apply button" state change
@@ -95,13 +105,21 @@ bool Model_Update::addModified(FeaturePtr theFeature, FeaturePtr theReason) {
     static ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators();
     aFactory->validate(theFeature); // need to be validated to update the "Apply" state if not previewed
 
+    // to redisplay split's arguments presentation, even result is not computed
+    if (!theFeature->isPreviewNeeded()) {
+      static Events_Loop* aLoop = Events_Loop::loop();
+      static const Events_ID kRedisplayEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+      ModelAPI_EventCreator::get()->sendUpdated(theFeature, kRedisplayEvent);
+      aLoop->flush(kRedisplayEvent);
+    }
+
     if (!myIsPreviewBlocked)
       return true;
   }
   if (myModified.find(theFeature) != myModified.end()) {
     if (theReason.get()) {
 #ifdef DEB_UPDATE
-      std::cout<<"*** Add already modified "<<theFeature->name()<<" reason "<<theReason->name()<<std::endl;
+      //std::cout<<"*** Add already modified "<<theFeature->name()<<" reason "<<theReason->name()<<std::endl;
 #endif
       myModified[theFeature].insert(theReason);
     }
@@ -119,12 +137,13 @@ bool Model_Update::addModified(FeaturePtr theFeature, FeaturePtr theReason) {
       if (theReason.get())
         aNewSet.insert(theReason);
     }
-    myModified[theFeature] = aNewSet;
+      myModified[theFeature] = aNewSet;
 #ifdef DEB_UPDATE
-    if (theReason.get())
-      std::cout<<"*** Add modified "<<theFeature->name()<<" reason "<<theReason->name()<<std::endl;
-    else 
-      std::cout<<"*** Add modified "<<theFeature->name()<<std::endl;
+    if (theReason.get()) {
+      //std::cout<<"*** Add modified "<<theFeature->name()<<" reason "<<theReason->name()<<std::endl;
+    } else {
+      //std::cout<<"*** Add modified "<<theFeature->name()<<std::endl;
+    }
 #endif
   } else { // will be updated during the finish of the operation, or when it becomes enabled
     if (theFeature->data()->execState() == ModelAPI_StateDone)
@@ -132,7 +151,7 @@ bool Model_Update::addModified(FeaturePtr theFeature, FeaturePtr theReason) {
     else 
       return true; // do not need iteration deeply if it is already marked as modified or so
 #ifdef DEB_UPDATE
-    std::cout<<"*** Set modified state "<<theFeature->name()<<std::endl;
+    //std::cout<<"*** Set modified state "<<theFeature->name()<<std::endl;
 #endif
   }
   // clear processed and fill modified recursively
@@ -310,7 +329,8 @@ void Model_Update::processEvent(const std::shared_ptr<Events_Message>& theMessag
   } else if (theMessage->eventID() == kReorderEvent) {
     std::shared_ptr<ModelAPI_OrderUpdatedMessage> aMsg = 
       std::dynamic_pointer_cast<ModelAPI_OrderUpdatedMessage>(theMessage);
-    addModified(aMsg->reordered(), aMsg->reordered()); // to update all attributes
+    if (aMsg->reordered().get())
+      addModified(aMsg->reordered(), aMsg->reordered()); // to update all attributes
   }
 }
 
@@ -441,6 +461,10 @@ bool Model_Update::processFeature(FeaturePtr theFeature)
       }
     }
     updateArguments(theFeature);
+    // send event that sketch is prepared to be recomputed
+    static Events_ID& anID = Events_Loop::eventByName("SketchPrepared");
+    std::shared_ptr<Events_Message> aMsg(new Events_Message(anID, this));
+    Events_Loop::loop()->send(aMsg);
   }
 
   if (!aIsModified) { // no modification is needed
@@ -504,6 +528,8 @@ bool Model_Update::processFeature(FeaturePtr theFeature)
   // add this feature to the processed right now to be able remove it from this list on
   // update signal during this feature execution
   myModified.erase(theFeature);
+  if (myNotPersistentRefs.find(theFeature) != myNotPersistentRefs.end())
+    myNotPersistentRefs.erase(theFeature);
   if (theFeature->data()->execState() == ModelAPI_StateMustBeUpdated)
     theFeature->data()->execState(ModelAPI_StateDone);
 
@@ -727,18 +753,33 @@ bool Model_Update::isReason(std::shared_ptr<ModelAPI_Feature>& theFeature,
 {
   std::map<std::shared_ptr<ModelAPI_Feature>, std::set<std::shared_ptr<ModelAPI_Feature> > >
     ::iterator aReasonsIt = myModified.find(theFeature);
-  if (aReasonsIt == myModified.end())
-    return false; // this case only for not-previewed items update state, nothing is changed in args for it
-  if (aReasonsIt->second.find(theFeature) != aReasonsIt->second.end())
-    return true; // any is reason if it contains itself
-  FeaturePtr aReasFeat = std::dynamic_pointer_cast<ModelAPI_Feature>(theReason);
-  if (!aReasFeat.get()) { // try to get feature of this result
-    ResultPtr aReasRes = std::dynamic_pointer_cast<ModelAPI_Result>(theReason);
-    if (aReasRes.get())
-      aReasFeat = theReason->document()->feature(aReasRes);
-  }
-  return aReasonsIt->second.find(aReasFeat) != aReasonsIt->second.end();
+  if (aReasonsIt != myModified.end()) {
+    if (aReasonsIt->second.find(theFeature) != aReasonsIt->second.end())
+      return true; // any is reason if it contains itself
+    FeaturePtr aReasFeat = std::dynamic_pointer_cast<ModelAPI_Feature>(theReason);
+    if (!aReasFeat.get()) { // try to get feature of this result
+      ResultPtr aReasRes = std::dynamic_pointer_cast<ModelAPI_Result>(theReason);
+      if (aReasRes.get())
+        aReasFeat = theReason->document()->feature(aReasRes);
+    }
+    if (aReasonsIt->second.find(aReasFeat) != aReasonsIt->second.end())
+      return true;
+  }
+  // another try: postponed modification by not-persistences
+  std::map<std::shared_ptr<ModelAPI_Feature>, std::set<std::shared_ptr<ModelAPI_Feature> > >
+    ::iterator aNotPersist = myNotPersistentRefs.find(theFeature);
+  if (aNotPersist != myNotPersistentRefs.end()) {
+    FeaturePtr aReasFeat = std::dynamic_pointer_cast<ModelAPI_Feature>(theReason);
+    if (!aReasFeat.get()) { // try to get feature of this result
+      ResultPtr aReasRes = std::dynamic_pointer_cast<ModelAPI_Result>(theReason);
+      if (aReasRes.get())
+        aReasFeat = theReason->document()->feature(aReasRes);
+    }
+    if (aNotPersist->second.find(aReasFeat) != aNotPersist->second.end())
+      return true;
+  }
 
+  return false; // this case only for not-previewed items update state, nothing is changed in args for it
 }
 
 void Model_Update::executeFeature(FeaturePtr theFeature)