Salome HOME
Tangent presentation correction
[modules/shaper.git] / src / Model / Model_Update.cpp
index ca900b86bb4cceac6174e139f23a44a866a314d6..51eba966c182977e5787340582512cc134b426e3 100644 (file)
@@ -1,3 +1,5 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
 // File:        Model_Update.cxx
 // Created:     25 Jun 2014
 // Author:      Mikhail PONIKAROV
@@ -65,8 +67,11 @@ void Model_Update::processEvent(const std::shared_ptr<Events_Message>& theMessag
   static const Events_ID kOpStartEvent = aLoop->eventByName("StartOperation");
   bool isAutomaticChanged = false;
   if (theMessage->eventID() == kChangedEvent) { // automatic and manual rebuild flag is changed
-    isAutomatic = 
-      Config_PropManager::findProp("Model update", "automatic_rebuild")->value() == "true";
+    bool aPropVal = 
+    Config_PropManager::findProp("Model update", "automatic_rebuild")->value() == "true";
+    if (aPropVal == isAutomatic)
+      return;// nothing to
+    isAutomatic = aPropVal;
   } else if (theMessage->eventID() == kRebuildEvent) { // the rebuild command
     if (isAutomatic == false) {
       isAutomaticChanged = true;
@@ -80,6 +85,8 @@ void Model_Update::processEvent(const std::shared_ptr<Events_Message>& theMessag
     std::set<ObjectPtr>::const_iterator anObjIter = anObjs.cbegin();
     for(; anObjIter != anObjs.cend(); anObjIter++) {
       myJustCreatedOrUpdated.insert(*anObjIter);
+      // TODO(mpv): check the next line. Came into dev 0.6.1 from BR_PYTHON_PLUGIN
+      // (*anObjIter)->data()->mustBeUpdated(true); // object must be updated because it was changed
     }
     if (theMessage->eventID() == kMovedEvent)
       return; // this event is for solver update, not here
@@ -115,37 +122,15 @@ void Model_Update::processEvent(const std::shared_ptr<Events_Message>& theMessag
 
   //Events_LongOp::start(this);
   isExecuted = true;
-  std::list<std::shared_ptr<ModelAPI_Document> > aDocs;
   std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aMsg =
       std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
   if (aMsg) myInitial = aMsg->objects();
   else {
     myInitial.clear();
-    // on change flag all documents must be updated
-    if (isAutomatic) {
-      aDocs = ModelAPI_Session::get()->allOpenedDocuments();
-    }
-  }
-  // collect all documents involved into the update process
-  set<std::shared_ptr<ModelAPI_Object> >::iterator aFIter = myInitial.begin();
-  for (; aFIter != myInitial.end(); aFIter++) {
-    aDocs.push_back((*aFIter)->document());
-  }
-  // iterate all features of features-documents to update them (including hidden)
-  std::set<std::shared_ptr<ModelAPI_Document> > alreadyUsed;
-  list<std::shared_ptr<ModelAPI_Document> >::iterator aDIter = aDocs.begin();
-  for (; aDIter != aDocs.end(); aDIter++) {
-    if (alreadyUsed.find(*aDIter) != alreadyUsed.end())
-      continue;
-    alreadyUsed.insert(*aDIter);
-    int aNbFeatures = (*aDIter)->size(ModelAPI_Feature::group(), true);
-    for (int aFIndex = 0; aFIndex < aNbFeatures; aFIndex++) {
-      FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(
-          (*aDIter)->object(ModelAPI_Feature::group(), aFIndex, true));
-      if (aFeature)
-        updateFeature(aFeature);
-    }
   }
+  // iterate all documents: features in Root first, then - subs
+  updateInDoc(ModelAPI_Session::get()->moduleDocument());
+
   myUpdated.clear();
   // flush to update display
   static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
@@ -160,9 +145,32 @@ void Model_Update::processEvent(const std::shared_ptr<Events_Message>& theMessag
   isExecuted = false;
 }
 
+void Model_Update::updateInDoc(std::shared_ptr<ModelAPI_Document> theDoc)
+{
+  // all features one by one
+  int aNbFeatures = theDoc->size(ModelAPI_Feature::group(), true);
+  for (int aFIndex = 0; aFIndex < aNbFeatures; aFIndex++) {
+    FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(
+        theDoc->object(ModelAPI_Feature::group(), aFIndex, true));
+    if (aFeature)
+      updateFeature(aFeature);
+  }
+  // all sub-documents one by one
+  std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(theDoc);
+  if (aDoc) {
+    const std::set<std::string> aSubs = aDoc->subDocuments(true);
+    for(std::set<std::string>::iterator aSub = aSubs.begin(); aSub != aSubs.end(); aSub++) {
+      DocumentPtr aSubDoc = theDoc->subDocument(*aSub);
+      if (aSubDoc) {
+        updateInDoc(aSubDoc);
+      }
+    }
+  }
+}
+
 void Model_Update::redisplayWithResults(FeaturePtr theFeature, const ModelAPI_ExecState theState) 
 {
-  // maske updated and redisplay all results
+  // make updated and redisplay all results
   static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
   const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = theFeature->results();
   std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
@@ -251,7 +259,8 @@ bool Model_Update::updateFeature(FeaturePtr theFeature)
                 std::shared_ptr<ModelAPI_AttributeSelection> aSel =
                   std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(*aRefsIter);
                 if (!aSel->update()) { // this must be done on execution since it may be long operation
-                  if (!aFactory->isNotObligatory(theFeature->getKind(), theFeature->data()->id(aSel)))
+                  if (!aFactory->isNotObligatory(theFeature->getKind(), theFeature->data()->id(aSel)) &&
+                      aFactory->isCase(theFeature, theFeature->data()->id(aSel)))
                     aState = ModelAPI_StateInvalidArgument;
                 }
               }
@@ -265,7 +274,8 @@ bool Model_Update::updateFeature(FeaturePtr theFeature)
                   if (aSelAttr) {
                     if (!aSelAttr->update()) {
                       if (!aFactory->isNotObligatory(
-                          theFeature->getKind(), theFeature->data()->id(aSel)))
+                            theFeature->getKind(), theFeature->data()->id(aSel)) &&
+                          aFactory->isCase(theFeature, theFeature->data()->id(aSel)))
                         aState = ModelAPI_StateInvalidArgument;
                     }
                   }
@@ -326,7 +336,9 @@ bool Model_Update::updateFeature(FeaturePtr theFeature)
       } else { // for automatically updated features (on abort, etc) it is necessary to redisplay anyway
         redisplayWithResults(theFeature, ModelAPI_StateNothing);
       }
-    } else {  // returns also true is results were updated: for sketch that refers to sub-features but results of sub-features were changed
+    } else {
+      // returns also true is results were updated: for sketch that 
+      // refers to sub-features but results of sub-features were changed
       const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = theFeature->results();
       std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
       for (; aRIter != aResults.cend(); aRIter++) {