Salome HOME
updated copyright message
[modules/shaper.git] / src / Model / Model_Update.cpp
index a2bcdfacbcbb937ed1e2792b68c20157071532f5..2100f48b902b1210a53f7565de78ca08cac6a770 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2020  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2023  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 Model_Update MY_UPDATER_INSTANCE;  /// the only one instance initialized on load of the library
 //#define DEB_UPDATE
 
+#ifdef DEB_UPDATE
+#include <Locale_Convert.h>
+#endif
+
 Model_Update::Model_Update()
 {
   Events_Loop* aLoop = Events_Loop::loop();
@@ -116,7 +120,7 @@ bool Model_Update::addModified(FeaturePtr theFeature, FeaturePtr 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;
+      std::wcout<<L"*** Add process on finish "<<theFeature->name()<<std::endl;
 #endif
     // keeps the currently updated features to avoid infinitive cycling here: where feature on
     // "updateArguments" sends "updated" (in selection attribute) and goes here again
@@ -186,13 +190,14 @@ bool Model_Update::addModified(FeaturePtr theFeature, FeaturePtr theReason) {
 #endif
   }
   // clear processed and fill modified recursively
+  std::set<FeaturePtr> aRefSet;
   const std::set<std::shared_ptr<ModelAPI_Attribute> >& aRefs = theFeature->data()->refsToMe();
   std::set<std::shared_ptr<ModelAPI_Attribute> >::const_iterator aRefIter = aRefs.cbegin();
   for(; aRefIter != aRefs.cend(); aRefIter++) {
     if ((*aRefIter)->isArgument()) {
       FeaturePtr aReferenced = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRefIter)->owner());
       if (aReferenced.get()) {
-        addModified(aReferenced, theFeature);
+        aRefSet.insert(aReferenced);
       }
     }
   }
@@ -207,19 +212,21 @@ bool Model_Update::addModified(FeaturePtr theFeature, FeaturePtr theReason) {
       if ((*aRIter)->isArgument()) {
         FeaturePtr aReferenced = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRIter)->owner());
         if (aReferenced.get()) {
-          addModified(aReferenced, theFeature);
+          aRefSet.insert(aReferenced);
         }
       }
     }
   }
-
   // also add part feature that contains this feature to the modified
   if (theFeature->document()->kind() != "PartSet") {
     FeaturePtr aPart = ModelAPI_Tools::findPartFeature(
       ModelAPI_Session::get()->moduleDocument(), theFeature->document());
     if (aPart.get())
-      addModified(aPart, theFeature);
+      aRefSet.insert(aPart);
   }
+  for(std::set<FeaturePtr>::iterator aRef = aRefSet.begin(); aRef != aRefSet.end(); aRef++)
+    addModified(*aRef, theFeature);
+
   return true;
 }
 
@@ -328,8 +335,8 @@ void Model_Update::processEvent(const std::shared_ptr<Events_Message>& theMessag
       if (!(*anObjIter)->data()->isValid())
         continue;
 #ifdef DEB_UPDATE
-      std::cout<<">>> in event updated "<<(*anObjIter)->groupName()<<
-        " "<<(*anObjIter)->data()->name()<<std::endl;
+      std::wcout<<L">>> in event updated "<<Locale::Convert::toWString((*anObjIter)->groupName())
+                <<L" "<<(*anObjIter)->data()->name()<<std::endl;
 #endif
       if ((*anObjIter)->groupName() == ModelAPI_ResultParameter::group()) {
         myIsParamUpdated = true;
@@ -339,18 +346,6 @@ void Model_Update::processEvent(const std::shared_ptr<Events_Message>& theMessag
       if (anUpdated.get()) {
         if (addModified(anUpdated, FeaturePtr()))
           aSomeModified = true;
-        if (myUpdateBlocked) { // execute this feature anyway to show the current result
-          /*if (!anUpdated->isStable() && anUpdated->results().size() && (
-              anUpdated->firstResult()->groupName() == ModelAPI_ResultBody::group() ||
-              anUpdated->firstResult()->groupName() == ModelAPI_ResultPart::group())) {
-            if (aFactory->validate(anUpdated)) {
-              executeFeature(anUpdated);
-              redisplayWithResults(anUpdated, ModelAPI_StateNothing, false);
-              static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
-              aLoop->flush(EVENT_DISP);
-            }
-          }*/
-        }
       } else {
         // process the updated result as update of features that refers to this result
         const std::set<std::shared_ptr<ModelAPI_Attribute> >&
@@ -566,14 +561,14 @@ bool Model_Update::processFeature(FeaturePtr theFeature)
   }
 
 #ifdef DEB_UPDATE
-    std::cout<<"* Process feature "<<theFeature->name()<<std::endl;
+    std::wcout<<L"* Process feature "<<theFeature->name()<<std::endl;
 #endif
 
   // update the sketch plane before the sketch sub-elements are recomputed
   // (otherwise sketch will update plane, modify subs, after executed, but with old subs edges)
     if (aIsModified && theFeature->getKind() == "Sketch") {
 #ifdef DEB_UPDATE
-      std::cout << "****** Update sketch args " << theFeature->name() << std::endl;
+      std::wcout << L"****** Update sketch args " << theFeature->name() << std::endl;
 #endif
       AttributeSelectionPtr anExtSel = theFeature->selection("External");
       if (anExtSel.get()) {
@@ -692,7 +687,7 @@ bool Model_Update::processFeature(FeaturePtr theFeature)
   }
 
 #ifdef DEB_UPDATE
-  std::cout<<"Update args "<<theFeature->name()<<std::endl;
+  std::wcout<<L"Update args "<<theFeature->name()<<std::endl;
 #endif
   // TestImport.py : after arguments are updated, theFeature may be removed
   if (!theFeature->data()->isValid())
@@ -715,7 +710,7 @@ bool Model_Update::processFeature(FeaturePtr theFeature)
       // don't disable Part because it will make disabled all the features
       // (performance and problems with the current feature)
   #ifdef DEB_UPDATE
-    std::cout<<"Invalid args "<<theFeature->name()<<std::endl;
+    std::wcout<<L"Invalid args "<<theFeature->name()<<std::endl;
   #endif
     theFeature->eraseResults(false);
     redisplayWithResults(theFeature, ModelAPI_StateInvalidArgument); // result also must be updated
@@ -728,7 +723,8 @@ bool Model_Update::processFeature(FeaturePtr theFeature)
     if (!isPostponedMain) {
       bool aDoExecute = true;
       if (myUpdateBlocked) {
-        if (!theFeature->isStable()) {
+        if (!theFeature->isStable() || (theFeature->getKind().size() > 6 &&
+            theFeature->getKind().substr(0, 6) == "Sketch")) { // automatic update sketch elements
           aDoExecute = true;
         } else if (theFeature->results().size()) { // execute only not persistent results features
           aDoExecute = !theFeature->isPersistentResult();
@@ -745,7 +741,7 @@ bool Model_Update::processFeature(FeaturePtr theFeature)
     }
   } else {
     #ifdef DEB_UPDATE
-      std::cout<<"Feature is not valid, erase results "<<theFeature->name()<<std::endl;
+      std::wcout<<L"Feature is not valid, erase results "<<theFeature->name()<<std::endl;
     #endif
     theFeature->eraseResults(false);
     redisplayWithResults(theFeature, ModelAPI_StateInvalidArgument); // result also must be updated
@@ -898,7 +894,9 @@ void Model_Update::updateArguments(FeaturePtr theFeature) {
           bool isObligatory = !aFactory->isNotObligatory(
             theFeature->getKind(), theFeature->data()->id(aSel)) &&
             aFactory->isCase(theFeature, theFeature->data()->id(aSel));
-          if (isObligatory)
+          if (isObligatory ||
+            // #24260 : sketch plane was selected, but selection becomes wrong, make it invalid
+            (theFeature->getKind() == "Sketch" && aSel->id() == "External"))
             aState = ModelAPI_StateInvalidArgument;
         }
       }
@@ -907,8 +905,7 @@ void Model_Update::updateArguments(FeaturePtr theFeature) {
       bool isObligatory = aFactory->isCase(theFeature, theFeature->data()->id(aSel));
       if (isObligatory)
         aState = ModelAPI_StateInvalidArgument;
-    } else if (theFeature->getKind() == "Sketch" && aSel->id() == "External" &&
-               aSel->isInitialized()) {
+    } else if (aSel->isInitialized()) {
       // #19703 : if sketch plane was selected, but after context disappears, it must become invalid
       aSel->update();
       if (aSel->isInvalid()) {
@@ -996,7 +993,7 @@ bool Model_Update::isReason(std::shared_ptr<ModelAPI_Feature>& theFeature,
 void Model_Update::executeFeature(FeaturePtr theFeature)
 {
 #ifdef DEB_UPDATE
-  std::cout<<"Execute Feature "<<theFeature->name()<<std::endl;
+  std::wcout<<L"Execute Feature "<<theFeature->name()<<std::endl;
 #endif
   // execute in try-catch to avoid internal problems of the feature
   ModelAPI_ExecState aState = ModelAPI_StateDone;