]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Fix issues #20295
authorJérôme <jerome.lucas@cesgenslab.fr>
Fri, 13 Nov 2020 09:56:38 +0000 (10:56 +0100)
committerJérôme <jerome.lucas@cesgenslab.fr>
Fri, 13 Nov 2020 09:56:38 +0000 (10:56 +0100)
12 files changed:
src/BuildPlugin/BuildPlugin_EvalListener.cpp [deleted file]
src/BuildPlugin/BuildPlugin_EvalListener.h [deleted file]
src/BuildPlugin/BuildPlugin_Interpolation.cpp
src/BuildPlugin/BuildPlugin_Plugin.cpp
src/BuildPlugin/BuildPlugin_Plugin.h
src/BuildPlugin/CMakeLists.txt
src/BuildPlugin/doc/interpolationFeature.rst
src/InitializationPlugin/CMakeLists.txt
src/InitializationPlugin/InitializationPlugin_EvalListener.cpp
src/InitializationPlugin/InitializationPlugin_EvalListener.h
src/ModelAPI/ModelAPI_Events.cpp
src/ModelAPI/ModelAPI_Events.h

diff --git a/src/BuildPlugin/BuildPlugin_EvalListener.cpp b/src/BuildPlugin/BuildPlugin_EvalListener.cpp
deleted file mode 100644 (file)
index 96c552f..0000000
+++ /dev/null
@@ -1,310 +0,0 @@
-// Copyright (C) 2014-2020  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
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-
-#include <pyconfig.h>
-
-#include <BuildPlugin_EvalListener.h>
-#include <BuildPlugin_Interpolation.h>
-#include <InitializationPlugin_PyInterp.h>
-
-#include <Events_InfoMessage.h>
-
-#include <Locale_Convert.h>
-
-#include <ModelAPI_AttributeDouble.h>
-#include <ModelAPI_AttributeTables.h>
-#include <ModelAPI_AttributeInteger.h>
-#include <ModelAPI_AttributeRefList.h>
-#include <ModelAPI_AttributeString.h>
-#include <ModelAPI_AttributeValidator.h>
-#include <ModelAPI_Document.h>
-#include <ModelAPI_Events.h>
-#include <ModelAPI_ResultParameter.h>
-#include <ModelAPI_Session.h>
-#include <ModelAPI_Tools.h>
-
-#include <GeomDataAPI_Point.h>
-#include <GeomDataAPI_Point2D.h>
-
-#include <string>
-#include <set>
-#include <sstream>
-
-//------------------------------------------------------------------------------
-// Tools
-
-std::wstring toString(double theValue)
-{
-  std::wostringstream sstream;
-  // write value in scientific format with 16 digits,
-  // thus, not check the dot position
-  sstream.precision(16);
-  sstream << std::scientific << theValue;
-  return sstream.str();
-}
-
-std::set<std::wstring> toSet(const std::list<std::wstring>& theContainer)
-{
-  return std::set<std::wstring>(theContainer.begin(), theContainer.end());
-}
-
-//------------------------------------------------------------------------------
-
-BuildPlugin_EvalListener::BuildPlugin_EvalListener()
-{
-  Events_Loop* aLoop = Events_Loop::loop();
-
-  aLoop->registerListener(this, ModelAPI_AttributeEvalMessage::eventId(), NULL, true);
-  aLoop->registerListener(this, ModelAPI_BuildEvalMessage::eventId(), NULL, true);
-  aLoop->registerListener(this, ModelAPI_ComputePositionsMessage::eventId(), NULL, true);
-
-  myInterp = std::shared_ptr<InitializationPlugin_PyInterp>(new InitializationPlugin_PyInterp());
-  myInterp->initialize();
-}
-
-BuildPlugin_EvalListener::~BuildPlugin_EvalListener()
-{
-}
-
-double BuildPlugin_EvalListener::evaluate(FeaturePtr theParameter,
-  const std::wstring& theExpression, std::string& theError,
-  std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
-  const bool theIsParameter)
-{
-  std::list<std::wstring> anExprParams = myInterp->compile(theExpression);
-  // find expression's params in the model
-  std::list<std::wstring> aContext;
-  std::list<std::wstring>::iterator it = anExprParams.begin();
-  for ( ; it != anExprParams.end(); it++) {
-    double aValue;
-    ResultParameterPtr aParamRes;
-    // If variable does not exist python interpreter will generate an error. It is OK.
-    // But due to the issue 1479 it should not check the history position of parameters relatively
-    // to feature that contains expression
-    if (!ModelAPI_Tools::findVariable(theIsParameter ? theParameter : FeaturePtr(),
-      *it, aValue, aParamRes, theParameter->document()))
-      continue;
-
-    if (theIsParameter)
-      theParamsList.push_back(aParamRes);
-    aContext.push_back(*it + L"=" + toString(aValue));
-  }
-  myInterp->extendLocalContext(aContext);
-  double result = myInterp->evaluate(theExpression, theError);
-  myInterp->clearLocalContext();
-  return result;
-}
-
-
-void BuildPlugin_EvalListener::processEvent(
-    const std::shared_ptr<Events_Message>& theMessage)
-{
-  if (!theMessage.get())
-    return;
-
-  if (theMessage->eventID() == ModelAPI_AttributeEvalMessage::eventId()) {
-    processEvaluationEvent(theMessage);
-  } else if (theMessage->eventID() == ModelAPI_BuildEvalMessage::eventId()) {
-    std::shared_ptr<ModelAPI_BuildEvalMessage> aMsg =
-      std::dynamic_pointer_cast<ModelAPI_BuildEvalMessage>(theMessage);
-    FeaturePtr aParam = aMsg->parameter();
-
-    AttributeStringPtr anVariableAttr = aParam->string(BuildPlugin_Interpolation::VARIABLE_ID());
-    std::wstring anVar = anVariableAttr->isUValue() ?
-        Locale::Convert::toWString(anVariableAttr->valueU()) :
-        Locale::Convert::toWString(anVariableAttr->value());
-    AttributeTablesPtr anValueAttr = aParam->tables(BuildPlugin_Interpolation::VALUE_ID());
-    std::string anError;
-    std::list<std::shared_ptr<ModelAPI_ResultParameter> > aParamsList;
-
-    AttributeStringPtr anExprAttr;
-    ModelAPI_AttributeTables::Value aVal;
-    for(int step =0; step < anValueAttr->rows(); step++ ){
-        anExprAttr = aParam->string(BuildPlugin_Interpolation::XT_ID());
-        std::wstring anExp = anExprAttr->isUValue() ?
-        Locale::Convert::toWString(anExprAttr->valueU()) :
-        Locale::Convert::toWString(anExprAttr->value());
-        aVal.myDouble = evaluate(anVar,anValueAttr->value(step,0).myDouble,
-                                 aParam,
-                                 anExp,
-                                 anError,aParamsList,
-                                 true);
-        anValueAttr->setValue(aVal,step,1);
-
-        anExprAttr = aParam->string(BuildPlugin_Interpolation::YT_ID());
-        anExp = anExprAttr->isUValue() ?
-        Locale::Convert::toWString(anExprAttr->valueU()) :
-        Locale::Convert::toWString(anExprAttr->value());
-        aVal.myDouble = evaluate(anVar,
-                                anValueAttr->value(step,0).myDouble,
-                                aParam,
-                                anExp,
-                                anError,
-                                aParamsList,
-                                true);
-        anValueAttr->setValue(aVal,step,2);
-
-        anExprAttr = aParam->string(BuildPlugin_Interpolation::ZT_ID());
-        anExp = anExprAttr->isUValue() ?
-        Locale::Convert::toWString(anExprAttr->valueU()) :
-        Locale::Convert::toWString(anExprAttr->value());
-        aVal.myDouble = evaluate(anVar,
-                                  anValueAttr->value(step,0).myDouble,
-                                  aParam,
-                                  anExp,
-                                  anError,
-                                  aParamsList,
-                                  true);
-        anValueAttr->setValue(aVal,step,3);
-    }
-
-    aMsg->setResults(aParamsList, 1, anError);
-  } else if (theMessage->eventID() == ModelAPI_ComputePositionsMessage::eventId()) {
-    std::shared_ptr<ModelAPI_ComputePositionsMessage> aMsg =
-      std::dynamic_pointer_cast<ModelAPI_ComputePositionsMessage>(theMessage);
-    aMsg->setPositions(myInterp->positions(aMsg->expression(), aMsg->parameter()));
-  }
-}
-
-double BuildPlugin_EvalListener::evaluate(
-  std::wstring& theVariable,
-  double theValueVariable,
-  FeaturePtr theParameter,
-  const std::wstring& theExpression,
-  std::string& theError,
-  std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
-  const bool theIsParameter)
-{
-  std::list<std::wstring> anExprParams = myInterp->compile(theExpression);
-  // find expression's params in the model
-  std::list<std::wstring> aContext;
-  std::list<std::wstring>::iterator it = anExprParams.begin();
-  for ( ; it != anExprParams.end(); it++) {
-    double aValue;
-    ResultParameterPtr aParamRes;
-    // If variable does not exist python interpreter will generate an error. It is OK.
-    // But due to the issue 1479 it should not check the history position of parameters relatively
-    // to feature that contains expression
-    if (!ModelAPI_Tools::findVariable(theIsParameter ? theParameter : FeaturePtr(),
-      *it, aValue, aParamRes, theParameter->document()))
-      continue;
-
-    if (theIsParameter)
-      theParamsList.push_back(aParamRes);
-    aContext.push_back(*it + L"=" + toString(aValue));
-  }
-  aContext.push_back(theVariable + L"=" + toString(theValueVariable));
-  myInterp->extendLocalContext(aContext);
-  double result = myInterp->evaluate(theExpression, theError);
-  myInterp->clearLocalContext();
-  return result;
-}
-
-void BuildPlugin_EvalListener::processEvaluationEvent(
-    const std::shared_ptr<Events_Message>& theMessage)
-{
-  std::shared_ptr<ModelAPI_AttributeEvalMessage> aMessage =
-      std::dynamic_pointer_cast<ModelAPI_AttributeEvalMessage>(theMessage);
-
-  std::list<std::shared_ptr<ModelAPI_ResultParameter> > aParamsList;
-  FeaturePtr aParamFeature =
-    std::dynamic_pointer_cast<ModelAPI_Feature>(aMessage->attribute()->owner());
-  if (aMessage->attribute()->attributeType() == ModelAPI_AttributeInteger::typeId()) {
-    AttributeIntegerPtr anAttribute =
-        std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(aMessage->attribute());
-    std::string anError;
-    int aValue = (int)evaluate(aParamFeature, anAttribute->text(), anError, aParamsList);
-    bool isValid = anError.empty();
-    if (isValid)
-      anAttribute->setCalculatedValue(aValue);
-    anAttribute->setUsedParameters(isValid ?
-      toSet(myInterp->compile(anAttribute->text())) : std::set<std::wstring>());
-    anAttribute->setExpressionInvalid(!isValid);
-    anAttribute->setExpressionError(anAttribute->text().empty() ? "" : anError);
-  } else
-  if (aMessage->attribute()->attributeType() == ModelAPI_AttributeDouble::typeId()) {
-    AttributeDoublePtr anAttribute =
-        std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(aMessage->attribute());
-    std::string anError;
-    double aValue = evaluate(aParamFeature, anAttribute->text(), anError, aParamsList);
-    bool isValid = anError.empty();
-    if (isValid)
-      anAttribute->setCalculatedValue(aValue);
-    anAttribute->setUsedParameters(isValid ?
-      toSet(myInterp->compile(anAttribute->text())) : std::set<std::wstring>());
-    anAttribute->setExpressionInvalid(!isValid);
-    anAttribute->setExpressionError(anAttribute->text().empty() ? "" : anError);
-  } else
-  if (aMessage->attribute()->attributeType() == GeomDataAPI_Point::typeId()) {
-    AttributePointPtr anAttribute =
-        std::dynamic_pointer_cast<GeomDataAPI_Point>(aMessage->attribute());
-    std::wstring aText[] = {
-      anAttribute->textX(),
-      anAttribute->textY(),
-      anAttribute->textZ()
-    };
-    double aCalculatedValue[] = {
-      anAttribute->x(),
-      anAttribute->y(),
-      anAttribute->z()
-    };
-    for (int i = 0; i < 3; ++i) {
-      std::string anError;
-      double aValue = evaluate(aParamFeature, aText[i], anError, aParamsList);
-      bool isValid = anError.empty();
-      if (isValid) aCalculatedValue[i] = aValue;
-      anAttribute->setUsedParameters(i,
-        isValid ? toSet(myInterp->compile(aText[i])) : std::set<std::wstring>());
-      anAttribute->setExpressionInvalid(i, !isValid);
-      anAttribute->setExpressionError(i, aText[i].empty() ? "" : anError);
-    }
-    anAttribute->setCalculatedValue(aCalculatedValue[0],
-                                    aCalculatedValue[1],
-                                    aCalculatedValue[2]);
-  } else
-  if (aMessage->attribute()->attributeType() == GeomDataAPI_Point2D::typeId()) {
-    AttributePoint2DPtr anAttribute =
-        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aMessage->attribute());
-    std::wstring aText[] = {
-      anAttribute->textX(),
-      anAttribute->textY()
-    };
-    double aCalculatedValue[] = {
-      anAttribute->x(),
-      anAttribute->y()
-    };
-    for (int i = 0; i < 2; ++i) {
-      std::string anError;
-      double aValue = evaluate(aParamFeature, aText[i], anError, aParamsList);
-      bool isValid = anError.empty();
-      if (isValid) aCalculatedValue[i] = aValue;
-      anAttribute->setUsedParameters(i,
-        isValid ? toSet(myInterp->compile(aText[i])) : std::set<std::wstring>());
-      anAttribute->setExpressionInvalid(i, !isValid);
-      anAttribute->setExpressionError(i, aText[i].empty() ? "" : anError);
-    }
-    anAttribute->setCalculatedValue(aCalculatedValue[0],
-                                    aCalculatedValue[1]);
-  }
-}
-
-void BuildPlugin_EvalListener::initDataModel()
-{
-  myInterp->runString("import salome_iapp;salome_iapp.register_module_in_study(\"Shaper\")");
-}
diff --git a/src/BuildPlugin/BuildPlugin_EvalListener.h b/src/BuildPlugin/BuildPlugin_EvalListener.h
deleted file mode 100644 (file)
index 5ace482..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (C) 2014-2020  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
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-
-#ifndef SRC_BUILDPLUGIN_EVALLISTENER_H_
-#define SRC_BUILDPLUGIN_EVALLISTENER_H_
-
-#include <BuildPlugin.h>
-#include <Events_Loop.h>
-
-class ModelAPI_Attribute;
-class ModelAPI_Document;
-class ModelAPI_Feature;
-class ModelAPI_ResultParameter;
-
-class InitializationPlugin_PyInterp;
-
-/**
- * \class BuildPlugin_EvalListener
- * \ingroup Plugins
- * \brief Class which process the events from the event loop.
- */
-class BuildPlugin_EvalListener : public Events_Listener
-{
- public:
-  BUILDPLUGIN_EXPORT BuildPlugin_EvalListener();
-  BUILDPLUGIN_EXPORT virtual ~BuildPlugin_EvalListener();
-
-  /// Reimplemented from Events_Listener::processEvent().
-  BUILDPLUGIN_EXPORT
-    virtual void processEvent(const std::shared_ptr<Events_Message>& theMessage);
-
-  // performs the python call to initialize high level data model on internal data model creation
-  void initDataModel();
-
- protected:
-  /// Evaluates theExpression and returns its value.
-  double evaluate(std::wstring& theVariable,
-                  double theValueVariable,std::shared_ptr<ModelAPI_Feature> theParameter,
-                  const std::wstring& theExpression, std::string& theError,
-                  std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
-                  const bool theIsParameter = false);
-
-  double evaluate(std::shared_ptr<ModelAPI_Feature> theParameter,
-                  const std::wstring& theExpression, std::string& theError,
-                  std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
-                  const bool theIsParameter = false);
-
-  /// Processes Evaluation event.
-  void processEvaluationEvent(const std::shared_ptr<Events_Message>& theMessage);
-
- private:
-  std::shared_ptr<InitializationPlugin_PyInterp> myInterp;
-};
-
-#endif /* SRC_BUILDPLUGIN_EVALLISTENER_H_ */
index a515c455214b98730c5c3cc23968e4e179edd613..13506b77e6cb7e8dd184fda8787ee24ab437706d 100644 (file)
@@ -108,6 +108,7 @@ void BuildPlugin_Interpolation::initAttributes()
       real(MINT_ID())->setValue(0);
       real(MAXT_ID())->setValue(100);
       integer(NUMSTEP_ID())->setValue(10);
+      updateCoordinates();
     }
 }
 
@@ -246,12 +247,16 @@ void BuildPlugin_Interpolation::execute()
         ||string( YT_ID())->value() == ""
         ||string( ZT_ID())->value() == ""
         ||tables(VALUE_ID())->rows()== 0  )
-      return false;
+      return;
 
     if (!outErrorMessage.empty()){
-      setError("Error: Python interpreter " );//+ outErrorMessage);
-      return false;
+      setError("Error Python interpreter :" + outErrorMessage, false );
+      return;
     }
+    bool aWasBlocked = data()->blockSendAttributeUpdated(true);
+    updateCoordinates();
+    data()->blockSendAttributeUpdated(aWasBlocked, false);
+
     AttributeTablesPtr aTable = tables( VALUE_ID() );
     std::list<std::vector<double> > aCoordPoints;
     for( int step = 0; step < aTable->rows() ; step++ ){
@@ -313,9 +318,16 @@ void  BuildPlugin_Interpolation::evaluate(std::string& theError)
 
   if (aProcessMessage->isProcessed()) {
     theError = aProcessMessage->error();
+
+    const std::list<ResultParameterPtr>& aParamsList = aProcessMessage->params();
+    //store the list of parameters to store if changed
+    AttributeRefListPtr aParams = reflist(ARGUMENTS_ID());
+    aParams->clear();
+    std::list<ResultParameterPtr>::const_iterator aNewIter = aParamsList.begin();
+    for(; aNewIter != aParamsList.end(); aNewIter++) {
+      aParams->append(*aNewIter);
+    }
   } else { // error: python interpreter is not active
     theError = "Python interpreter is not available";
   }
-}
-
-
+}
\ No newline at end of file
index fad3b014503eb25bdfeb97f92e0990a0990ff6b2..6614d06847328bbb26a8cf8c7abffc6c0e2b1f4f 100644 (file)
@@ -36,7 +36,7 @@
 #include <BuildPlugin_Filling.h>
 #include <BuildPlugin_Validators.h>
 
-#include <BuildPlugin_EvalListener.h>
+
 
 
 // the only created instance of this plugin
@@ -68,8 +68,6 @@ BuildPlugin_Plugin::BuildPlugin_Plugin()
   // Register this plugin.
   ModelAPI_Session::get()->registerPlugin(this);
 
-  myEvalListener =
-    std::shared_ptr<BuildPlugin_EvalListener>(new BuildPlugin_EvalListener());
 }
 
 //=================================================================================================
index 4f3f7f62a30709845d1bf02e7b10b233f6f5bc7e..b8df03d478339bc9ed96cfc6058b09b178ce9740 100644 (file)
@@ -25,8 +25,6 @@
 #include <ModelAPI_Plugin.h>
 #include <ModelAPI_Feature.h>
 
-class BuildPlugin_EvalListener;
-
 /// \class BuildPlugin_Plugin
 /// \ingroup Plugins
 /// \brief The main class for management the build features as plugin.
@@ -39,8 +37,6 @@ public:
   /// Creates the feature object of this plugin by the feature string ID
   virtual FeaturePtr createFeature(std::string theFeatureID);
 
- private:
-   std::shared_ptr<BuildPlugin_EvalListener> myEvalListener;
 };
 
 #endif
index f5f04f61e162b0d1eb2cb0f666554c4e563fda06..5c42102b1b0682777192eaa42e95afb0a64a4548 100644 (file)
@@ -51,7 +51,6 @@ SET(PROJECT_HEADERS
     BuildPlugin_SubShapes.h
     BuildPlugin_Filling.h
     BuildPlugin_Validators.h
-    BuildPlugin_EvalListener.h
 )
 
 SET(PROJECT_SOURCES
@@ -70,7 +69,6 @@ SET(PROJECT_SOURCES
     BuildPlugin_SubShapes.cpp
     BuildPlugin_Filling.cpp
     BuildPlugin_Validators.cpp
-    BuildPlugin_EvalListener.cpp
 )
 
 SET(XML_RESOURCES
index 62b600381d97d6c4f554eef1e51a082ed41c4b35..0bbba240dbae8725e794197f74810ec0eb7c9c3e 100644 (file)
@@ -116,12 +116,12 @@ Select one or several vertices or points in the viewer.
 .. py:function:: model.addInterpolation(Part_doc, xt, yt, zt, mint, maxt, nbSteps)
 
     :param part: The current part object.
-    :param xt: Expression of x.
-    :param yt: Expression of y.
-    :param zt: Expression of z.
-    :param mint: Minimum value of t
-    :param maxt: Maximum value of t.
-    :param nbSteps: Number of steps. 
+    :param string: Expression of x.
+    :param string: Expression of y.
+    :param string: Expression of z.
+    :param number: Minimum value of t.
+    :param number: Maximum value of t.
+    :param number: Number of steps. 
     :return: Result object.
 
 Result
index a9518f877e54d45ea856962b16f9a7b496cc9cfc..93162e0aaac470779bf9c3c101ad1f56ad16ac71 100644 (file)
@@ -26,6 +26,7 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Events
                     ${PROJECT_SOURCE_DIR}/src/GeomDataAPI
                     ${PROJECT_SOURCE_DIR}/src/Locale
                     ${PROJECT_SOURCE_DIR}/src/ParametersPlugin
+                    ${PROJECT_SOURCE_DIR}/src/BuildPlugin
                     ${SUIT_INCLUDE}
                     ${PYTHON_INCLUDE_DIR}
 )
index e2dceb117b7870bc89080d29f5f1bec3bafe24b8..9268004a47b8166cda1180faae020d76b2b8103f 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <InitializationPlugin_EvalListener.h>
 #include <ParametersPlugin_Parameter.h>
+#include <BuildPlugin_Interpolation.h>
 #include <InitializationPlugin_PyInterp.h>
 
 #include <Events_InfoMessage.h>
@@ -32,6 +33,7 @@
 #include <ModelAPI_AttributeRefList.h>
 #include <ModelAPI_AttributeString.h>
 #include <ModelAPI_AttributeValidator.h>
+#include <ModelAPI_AttributeTables.h>
 #include <ModelAPI_Document.h>
 #include <ModelAPI_Events.h>
 #include <ModelAPI_ResultParameter.h>
@@ -44,6 +46,8 @@
 #include <string>
 #include <set>
 #include <sstream>
+#include <iostream>
+#include <algorithm>
 
 //------------------------------------------------------------------------------
 // Tools
@@ -71,6 +75,7 @@ InitializationPlugin_EvalListener::InitializationPlugin_EvalListener()
 
   aLoop->registerListener(this, ModelAPI_AttributeEvalMessage::eventId(), NULL, true);
   aLoop->registerListener(this, ModelAPI_ParameterEvalMessage::eventId(), NULL, true);
+  aLoop->registerListener(this, ModelAPI_BuildEvalMessage::eventId(), NULL, true);
   aLoop->registerListener(this, ModelAPI_ComputePositionsMessage::eventId(), NULL, true);
 
   myInterp = std::shared_ptr<InitializationPlugin_PyInterp>(new InitializationPlugin_PyInterp());
@@ -105,9 +110,110 @@ void InitializationPlugin_EvalListener::processEvent(
     std::shared_ptr<ModelAPI_ComputePositionsMessage> aMsg =
       std::dynamic_pointer_cast<ModelAPI_ComputePositionsMessage>(theMessage);
     aMsg->setPositions(myInterp->positions(aMsg->expression(), aMsg->parameter()));
+  }if (theMessage->eventID() == ModelAPI_BuildEvalMessage::eventId()) {
+    std::shared_ptr<ModelAPI_BuildEvalMessage> aMsg =
+      std::dynamic_pointer_cast<ModelAPI_BuildEvalMessage>(theMessage);
+    FeaturePtr aParam = aMsg->parameter();
+
+    AttributeStringPtr anVariableAttr = aParam->string(BuildPlugin_Interpolation::VARIABLE_ID());
+    std::wstring anVar = anVariableAttr->isUValue() ?
+        Locale::Convert::toWString(anVariableAttr->valueU()) :
+        Locale::Convert::toWString(anVariableAttr->value());
+    AttributeTablesPtr anValueAttr = aParam->tables(BuildPlugin_Interpolation::VALUE_ID());
+    std::string anError;
+
+    std::list<std::shared_ptr<ModelAPI_ResultParameter> > aParamsList;
+
+    AttributeStringPtr anExprAttr;
+    ModelAPI_AttributeTables::Value aVal;
+    bool anIsFirstTime = true;
+    for(int step =0; step < anValueAttr->rows(); step++ ){
+        anExprAttr = aParam->string(BuildPlugin_Interpolation::XT_ID());
+        std::wstring anExp = anExprAttr->isUValue() ?
+        Locale::Convert::toWString(anExprAttr->valueU()) :
+        Locale::Convert::toWString(anExprAttr->value());
+        aVal.myDouble = evaluate(anVar,
+                                 anValueAttr->value(step,0).myDouble,
+                                 aParam,
+                                 anExp,
+                                 anError,
+                                 aParamsList,
+                                 anIsFirstTime);
+        anValueAttr->setValue(aVal,step,1);
+        if( !anError.empty()) break;
+        anExprAttr = aParam->string(BuildPlugin_Interpolation::YT_ID());
+        anExp = anExprAttr->isUValue() ?
+        Locale::Convert::toWString(anExprAttr->valueU()) :
+        Locale::Convert::toWString(anExprAttr->value());
+        aVal.myDouble = evaluate(anVar,
+                                anValueAttr->value(step,0).myDouble,
+                                aParam,
+                                anExp,
+                                anError,
+                                aParamsList,
+                                anIsFirstTime);
+        anValueAttr->setValue(aVal,step,2);
+        if( !anError.empty()) break;
+        anExprAttr = aParam->string(BuildPlugin_Interpolation::ZT_ID());
+        anExp = anExprAttr->isUValue() ?
+        Locale::Convert::toWString(anExprAttr->valueU()) :
+        Locale::Convert::toWString(anExprAttr->value());
+        aVal.myDouble = evaluate(anVar,
+                                 anValueAttr->value(step,0).myDouble,
+                                 aParam,
+                                 anExp,
+                                 anError,
+                                 aParamsList,
+                                 anIsFirstTime);
+        if( !anError.empty()) break;
+        anValueAttr->setValue(aVal,step,3);
+        if ( anIsFirstTime )
+            anIsFirstTime = false;
+    }
+
+    aMsg->setResults(aParamsList, anError);
+  }
+}
+
+double InitializationPlugin_EvalListener::evaluate(
+  std::wstring& theVariable,
+  double theValueVariable,
+  FeaturePtr theParameter,
+  const std::wstring& theExpression,
+  std::string& theError,
+  std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
+  bool theIsFirstTime)
+{
+  std::list<std::wstring> anExprParams = myInterp->compile(theExpression);
+  // find expression's params in the model
+  std::list<std::wstring> aContext;
+  std::list<std::wstring>::iterator it = anExprParams.begin();
+  for ( ; it != anExprParams.end(); it++) {
+    double aValue;
+    ResultParameterPtr aParamRes;
+    // If variable does not exist python interpreter will generate an error.
+    if (!ModelAPI_Tools::findVariable(FeaturePtr(),
+                           *it, aValue, aParamRes, theParameter->document()))
+      continue;
+
+    if( theIsFirstTime )
+    {
+      std::list<ResultParameterPtr>::iterator anIter =
+                          std::find(theParamsList.begin(),theParamsList.end(), aParamRes );
+      if(anIter == theParamsList.end())
+        theParamsList.push_back(aParamRes);
+    }
+
+    aContext.push_back(*it + L"=" + toString(aValue));
   }
+  aContext.push_back(theVariable + L"=" + toString(theValueVariable));
+  myInterp->extendLocalContext(aContext);
+  double result = myInterp->evaluate(theExpression, theError);
+  myInterp->clearLocalContext();
+  return result;
 }
 
+
 double InitializationPlugin_EvalListener::evaluate(FeaturePtr theParameter,
   const std::wstring& theExpression, std::string& theError,
   std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
index 756b335ec0a739ee10c9bd1d63f7255338b87b3e..5036863a98be9bcc508d6d943aa535d4a947d66a 100644 (file)
@@ -50,11 +50,21 @@ class InitializationPlugin_EvalListener : public Events_Listener
 
  protected:
   /// Evaluates theExpression and returns its value.
-   double evaluate(std::shared_ptr<ModelAPI_Feature> theParameter,
+  double evaluate(std::shared_ptr<ModelAPI_Feature> theParameter,
                   const std::wstring& theExpression, std::string& theError,
                   std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
                   const bool theIsParameter = false);
 
+  /// Evaluates theExpression with variable local and returns its value.
+  double evaluate(std::wstring& theVariable,
+                  double theValueVariable,
+                  std::shared_ptr<ModelAPI_Feature> theParameter,
+                  const std::wstring& theExpression,
+                  std::string& theError,
+                  std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
+                  bool theIsFirstTime);
+
+
   /// Processes Evaluation event.
   void processEvaluationEvent(const std::shared_ptr<Events_Message>& theMessage);
 
index 7632dca2d43ba5536b40fa294d576c868c7159e0..054d0bacf4dc43c2b86e90a360aaa638707d2988 100644 (file)
@@ -207,29 +207,23 @@ void ModelAPI_BuildEvalMessage::setParameter(FeaturePtr theParam)
 }
 
 void ModelAPI_BuildEvalMessage::setResults(
-    const std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
-    const double theResult, const std::string& theError)
+            const std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
+            const std::string& theError)
 {
   myParamsList = theParamsList;
-  myResult = theResult;
   myError = theError;
   myIsProcessed = true;
 }
 
-bool ModelAPI_BuildEvalMessage::isProcessed()
-{
-  return myIsProcessed;
-}
-
 const std::list<std::shared_ptr<ModelAPI_ResultParameter> >&
   ModelAPI_BuildEvalMessage::params() const
 {
   return myParamsList;
 }
 
-const double& ModelAPI_BuildEvalMessage::result() const
+bool ModelAPI_BuildEvalMessage::isProcessed()
 {
-  return myResult;
+  return myIsProcessed;
 }
 
 const std::string& ModelAPI_BuildEvalMessage::error() const
index dffa73a8d60e6a3361d2fbd90901aac6b288d0c7..06972aa1757175115d8923fac2bbb725e9d40775 100644 (file)
@@ -356,10 +356,9 @@ class ModelAPI_BuildEvalMessage : public Events_Message
 {
   FeaturePtr myParam; ///< parameters that should be evaluated
   bool myIsProcessed; ///< true if results were set
-  /// result of processing, list of parameters in expression found
-  std::list<std::shared_ptr<ModelAPI_ResultParameter> > myParamsList;
-  double myResult; ///< result of processing, the computed value of the expression
   std::string myError; ///< error of processing, empty if there is no error
+    /// result of processing, list of parameters in expression found
+  std::list<std::shared_ptr<ModelAPI_ResultParameter> > myParamsList;
 
  public:
   /// Static. Returns EventID of the message.
@@ -394,14 +393,13 @@ class ModelAPI_BuildEvalMessage : public Events_Message
   MODELAPI_EXPORT void setParameter(FeaturePtr theParam);
   /// Sets the results of processing
   MODELAPI_EXPORT void setResults(
-    const std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
-    const double theResult, const std::string& theError);
+            const std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
+            const std::string& theError);
+    /// Returns the results of processing: list of parameters found in the expression
+  MODELAPI_EXPORT const std::list<std::shared_ptr<ModelAPI_ResultParameter> >& params() const;
   /// Returns true if the expression is processed
   MODELAPI_EXPORT bool isProcessed();
-  /// Returns the results of processing: list of parameters found in the expression
-  MODELAPI_EXPORT const std::list<std::shared_ptr<ModelAPI_ResultParameter> >& params() const;
-  /// Returns the expression result
-  MODELAPI_EXPORT const double& result() const;
+
   /// Returns the interpreter error (empty if no error)
   MODELAPI_EXPORT const std::string& error() const;
 };