Salome HOME
setDisplayed has to be called in order to synchronize internal state of the object
[modules/shaper.git] / src / Model / Model_Update.cpp
index 8eae85c9308a51cfbe38bdd10527573f685482e8..e710c5a876693c6ce87fee66ec6aa5769621e1a2 100644 (file)
@@ -23,6 +23,8 @@
 #include <ModelAPI_CompositeFeature.h>
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Tools.h>
+#include <GeomDataAPI_Point.h>
+#include <GeomDataAPI_Point2D.h>
 #include <Events_Loop.h>
 #include <Events_LongOp.h>
 #include <Events_Error.h>
@@ -110,11 +112,13 @@ void Model_Update::processEvent(const std::shared_ptr<Events_Message>& theMessag
     isOperationChanged = true;
   }
   if (isOperationChanged) {
-    // remove all macros before clearing all created
+    // remove all macros before clearing all created and execute all not-previewed
     std::set<ObjectPtr>::iterator aCreatedIter = myJustCreated.begin();
-    for(; aCreatedIter != myJustCreated.end(); aCreatedIter++) {
-      FeaturePtr aFeature = 
-        std::dynamic_pointer_cast<ModelAPI_Feature>(*aCreatedIter);
+    std::set<ObjectPtr>::iterator anUpdatedIter = myJustUpdated.begin();
+    for(; aCreatedIter != myJustCreated.end() || anUpdatedIter != myJustUpdated.end();
+      aCreatedIter == myJustCreated.end() ? anUpdatedIter++ : aCreatedIter++) {
+      FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(*
+        (aCreatedIter == myJustCreated.end() ? anUpdatedIter : aCreatedIter));
       if (aFeature.get()) {
         // execute not-previewed feature on "apply"
         if (!aFeature->isPreviewNeeded() && (myJustCreated.find(aFeature) != myJustCreated.end() ||
@@ -143,7 +147,7 @@ void Model_Update::processOperation(const bool theTotalUpdate, const bool theFin
     for(aFIter = myJustCreated.begin(); aFIter != myJustCreated.end(); aFIter++)
     {
       FeaturePtr aF = std::dynamic_pointer_cast<ModelAPI_Feature>(*aFIter);
-      if (aF && aF->data().get() && aF->getKind() == "Extrusion") {
+      if (aF && aF->data()->isValid() && aF->getKind() == "Extrusion") {
         AttributeSelectionListPtr aBase = aF->selectionList("base");
         if (aBase.get()) {
           for(int a = aBase->size() - 1; a >= 0; a--) {
@@ -260,27 +264,51 @@ void Model_Update::updateArguments(FeaturePtr theFeature) {
   ModelAPI_ExecState aState = theFeature->data()->execState();
   if (aState == ModelAPI_StateInvalidArgument) // a chance to be corrected
     aState = ModelAPI_StateMustBeUpdated;
-  // check the parameters: values can be changed
-  /* parameters evaluator now does this
-  std::list<AttributePtr> aDoubles = 
-    theFeature->data()->attributes(ModelAPI_AttributeDouble::typeId()); 
+  // check the parameters state
+  // Double
+  std::list<AttributePtr> aDoubles =
+    theFeature->data()->attributes(ModelAPI_AttributeDouble::typeId());
   std::list<AttributePtr>::iterator aDoubleIter = aDoubles.begin();
   for(; aDoubleIter != aDoubles.end(); aDoubleIter++) {
-    AttributeDoublePtr aDouble = 
+    AttributeDoublePtr aDouble =
       std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(*aDoubleIter);
     if (aDouble.get() && !aDouble->text().empty()) {
-      double aNewVal;
-      if (ModelAPI_Tools::findVariable(aDouble->text(), aNewVal)) {
-        if (aNewVal != aDouble->value()) {
-          aDouble->setValue(aNewVal);
-          aJustUpdated = true;
-        }
-      } else {
+      if (aDouble->expressionInvalid()) {
         aState = ModelAPI_StateInvalidArgument;
       }
     }
   }
-  */
+  // Point
+  {
+    std::list<AttributePtr> anAttributes =
+      theFeature->data()->attributes(GeomDataAPI_Point::typeId());
+    std::list<AttributePtr>::iterator anIter = anAttributes.begin();
+    for(; anIter != anAttributes.end(); anIter++) {
+      AttributePointPtr aPointAttribute =
+        std::dynamic_pointer_cast<GeomDataAPI_Point>(*anIter);
+      if (aPointAttribute.get()) {
+        if ((!aPointAttribute->textX().empty() && aPointAttribute->expressionInvalid(0)) ||
+            (!aPointAttribute->textY().empty() && aPointAttribute->expressionInvalid(1)) ||
+            (!aPointAttribute->textZ().empty() && aPointAttribute->expressionInvalid(2)))
+          aState = ModelAPI_StateInvalidArgument;
+      }
+    }
+  }
+  // Point2D
+  {
+    std::list<AttributePtr> anAttributes =
+      theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
+    std::list<AttributePtr>::iterator anIter = anAttributes.begin();
+    for(; anIter != anAttributes.end(); anIter++) {
+      AttributePoint2DPtr aPoint2DAttribute =
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*anIter);
+      if (aPoint2DAttribute.get()) {
+        if ((!aPoint2DAttribute->textX().empty() && aPoint2DAttribute->expressionInvalid(0)) ||
+            (!aPoint2DAttribute->textY().empty() && aPoint2DAttribute->expressionInvalid(1)))
+          aState = ModelAPI_StateInvalidArgument;
+      }
+    }
+  }
 
   //if (aState == ModelAPI_StateDone) {// all referenced objects are ready to be used
     //std::cout<<"Execute feature "<<theFeature->getKind()<<std::endl;
@@ -381,31 +409,37 @@ void Model_Update::updateFeature(FeaturePtr theFeature)
     //std::cout<<"Update feature "<<theFeature->getKind()<<" must be updated = "<<aMustbeUpdated<<std::endl;
     // execute feature if it must be updated
     if (aJustUpdated) {
-      if ((std::dynamic_pointer_cast<Model_Document>(theFeature->document())->executeFeatures() ||
-          !theFeature->isPersistentResult()) && theFeature->isPreviewNeeded()) {
-        if (aFactory->validate(theFeature)) {
-          if (myIsAutomatic || !theFeature->isPersistentResult() /* execute quick, not persistent results */
-              || (isUpdated(theFeature) && 
-               theFeature == theFeature->document()->currentFeature(false))) // currently edited
-          {
-            if (aState == ModelAPI_StateDone || aState == ModelAPI_StateMustBeUpdated) {
-              executeFeature(theFeature);
-            }
-          } else { // must be updatet, but not updated yet
-            theFeature->data()->execState(ModelAPI_StateMustBeUpdated);
-            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++) {
-              std::shared_ptr<ModelAPI_Result> aRes = *aRIter;
-              aRes->data()->execState(ModelAPI_StateMustBeUpdated);
+      if (theFeature->isPreviewNeeded()) {
+        if (std::dynamic_pointer_cast<Model_Document>(theFeature->document())->executeFeatures() ||
+            !theFeature->isPersistentResult()) {
+          if (aFactory->validate(theFeature)) {
+            if (myIsAutomatic || !theFeature->isPersistentResult() /* execute quick, not persistent results */
+                || (isUpdated(theFeature) && 
+                     (theFeature == theFeature->document()->currentFeature(false) || 
+                      theFeature->document()->currentFeature(false)->isMacro()))) // currently edited
+            {
+              if (aState == ModelAPI_StateDone || aState == ModelAPI_StateMustBeUpdated) {
+                executeFeature(theFeature);
+              }
+            } else { // must be updatet, but not updated yet
+              theFeature->data()->execState(ModelAPI_StateMustBeUpdated);
+              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++) {
+                std::shared_ptr<ModelAPI_Result> aRes = *aRIter;
+                aRes->data()->execState(ModelAPI_StateMustBeUpdated);
+              }
             }
+          } else {
+            theFeature->eraseResults();
+            redisplayWithResults(theFeature, ModelAPI_StateInvalidArgument); // result also must be updated
           }
-        } else {
-          theFeature->eraseResults();
-          redisplayWithResults(theFeature, ModelAPI_StateInvalidArgument); // result also must be updated
+        } else { // for automatically updated features (on abort, etc) it is necessary to redisplay anyway
+          redisplayWithResults(theFeature, ModelAPI_StateNothing);
         }
-      } else { // for automatically updated features (on abort, etc) it is necessary to redisplay anyway
-        redisplayWithResults(theFeature, ModelAPI_StateNothing);
+      } else { // preview is not needed => make state Done
+        if (theFeature->data()->execState() == ModelAPI_StateMustBeUpdated)
+          theFeature->data()->execState(ModelAPI_StateDone);
       }
     }
   }