From 30fc5097a91c49b1862b4b0771e725df24ed6c16 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me?= Date: Fri, 13 Nov 2020 10:56:38 +0100 Subject: [PATCH] Fix issues #20295 --- src/BuildPlugin/BuildPlugin_EvalListener.cpp | 310 ------------------ src/BuildPlugin/BuildPlugin_EvalListener.h | 71 ---- src/BuildPlugin/BuildPlugin_Interpolation.cpp | 24 +- src/BuildPlugin/BuildPlugin_Plugin.cpp | 4 +- src/BuildPlugin/BuildPlugin_Plugin.h | 4 - src/BuildPlugin/CMakeLists.txt | 2 - src/BuildPlugin/doc/interpolationFeature.rst | 12 +- src/InitializationPlugin/CMakeLists.txt | 1 + .../InitializationPlugin_EvalListener.cpp | 106 ++++++ .../InitializationPlugin_EvalListener.h | 12 +- src/ModelAPI/ModelAPI_Events.cpp | 14 +- src/ModelAPI/ModelAPI_Events.h | 16 +- 12 files changed, 154 insertions(+), 422 deletions(-) delete mode 100644 src/BuildPlugin/BuildPlugin_EvalListener.cpp delete mode 100644 src/BuildPlugin/BuildPlugin_EvalListener.h diff --git a/src/BuildPlugin/BuildPlugin_EvalListener.cpp b/src/BuildPlugin/BuildPlugin_EvalListener.cpp deleted file mode 100644 index 96c552f89..000000000 --- a/src/BuildPlugin/BuildPlugin_EvalListener.cpp +++ /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 - -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -//------------------------------------------------------------------------------ -// 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 toSet(const std::list& theContainer) -{ - return std::set(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(new InitializationPlugin_PyInterp()); - myInterp->initialize(); -} - -BuildPlugin_EvalListener::~BuildPlugin_EvalListener() -{ -} - -double BuildPlugin_EvalListener::evaluate(FeaturePtr theParameter, - const std::wstring& theExpression, std::string& theError, - std::list >& theParamsList, - const bool theIsParameter) -{ - std::list anExprParams = myInterp->compile(theExpression); - // find expression's params in the model - std::list aContext; - std::list::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& theMessage) -{ - if (!theMessage.get()) - return; - - if (theMessage->eventID() == ModelAPI_AttributeEvalMessage::eventId()) { - processEvaluationEvent(theMessage); - } else if (theMessage->eventID() == ModelAPI_BuildEvalMessage::eventId()) { - std::shared_ptr aMsg = - std::dynamic_pointer_cast(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 > 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 aMsg = - std::dynamic_pointer_cast(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 >& theParamsList, - const bool theIsParameter) -{ - std::list anExprParams = myInterp->compile(theExpression); - // find expression's params in the model - std::list aContext; - std::list::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& theMessage) -{ - std::shared_ptr aMessage = - std::dynamic_pointer_cast(theMessage); - - std::list > aParamsList; - FeaturePtr aParamFeature = - std::dynamic_pointer_cast(aMessage->attribute()->owner()); - if (aMessage->attribute()->attributeType() == ModelAPI_AttributeInteger::typeId()) { - AttributeIntegerPtr anAttribute = - std::dynamic_pointer_cast(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()); - anAttribute->setExpressionInvalid(!isValid); - anAttribute->setExpressionError(anAttribute->text().empty() ? "" : anError); - } else - if (aMessage->attribute()->attributeType() == ModelAPI_AttributeDouble::typeId()) { - AttributeDoublePtr anAttribute = - std::dynamic_pointer_cast(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()); - anAttribute->setExpressionInvalid(!isValid); - anAttribute->setExpressionError(anAttribute->text().empty() ? "" : anError); - } else - if (aMessage->attribute()->attributeType() == GeomDataAPI_Point::typeId()) { - AttributePointPtr anAttribute = - std::dynamic_pointer_cast(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()); - 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(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()); - 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 index 5ace4821f..000000000 --- a/src/BuildPlugin/BuildPlugin_EvalListener.h +++ /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 -#include - -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& 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 theParameter, - const std::wstring& theExpression, std::string& theError, - std::list >& theParamsList, - const bool theIsParameter = false); - - double evaluate(std::shared_ptr theParameter, - const std::wstring& theExpression, std::string& theError, - std::list >& theParamsList, - const bool theIsParameter = false); - - /// Processes Evaluation event. - void processEvaluationEvent(const std::shared_ptr& theMessage); - - private: - std::shared_ptr myInterp; -}; - -#endif /* SRC_BUILDPLUGIN_EVALLISTENER_H_ */ diff --git a/src/BuildPlugin/BuildPlugin_Interpolation.cpp b/src/BuildPlugin/BuildPlugin_Interpolation.cpp index a515c4552..13506b77e 100644 --- a/src/BuildPlugin/BuildPlugin_Interpolation.cpp +++ b/src/BuildPlugin/BuildPlugin_Interpolation.cpp @@ -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 > 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& aParamsList = aProcessMessage->params(); + //store the list of parameters to store if changed + AttributeRefListPtr aParams = reflist(ARGUMENTS_ID()); + aParams->clear(); + std::list::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 diff --git a/src/BuildPlugin/BuildPlugin_Plugin.cpp b/src/BuildPlugin/BuildPlugin_Plugin.cpp index fad3b0145..6614d0684 100644 --- a/src/BuildPlugin/BuildPlugin_Plugin.cpp +++ b/src/BuildPlugin/BuildPlugin_Plugin.cpp @@ -36,7 +36,7 @@ #include #include -#include + // 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(new BuildPlugin_EvalListener()); } //================================================================================================= diff --git a/src/BuildPlugin/BuildPlugin_Plugin.h b/src/BuildPlugin/BuildPlugin_Plugin.h index 4f3f7f62a..b8df03d47 100644 --- a/src/BuildPlugin/BuildPlugin_Plugin.h +++ b/src/BuildPlugin/BuildPlugin_Plugin.h @@ -25,8 +25,6 @@ #include #include -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 myEvalListener; }; #endif diff --git a/src/BuildPlugin/CMakeLists.txt b/src/BuildPlugin/CMakeLists.txt index f5f04f61e..5c42102b1 100644 --- a/src/BuildPlugin/CMakeLists.txt +++ b/src/BuildPlugin/CMakeLists.txt @@ -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 diff --git a/src/BuildPlugin/doc/interpolationFeature.rst b/src/BuildPlugin/doc/interpolationFeature.rst index 62b600381..0bbba240d 100644 --- a/src/BuildPlugin/doc/interpolationFeature.rst +++ b/src/BuildPlugin/doc/interpolationFeature.rst @@ -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 diff --git a/src/InitializationPlugin/CMakeLists.txt b/src/InitializationPlugin/CMakeLists.txt index a9518f877..93162e0aa 100644 --- a/src/InitializationPlugin/CMakeLists.txt +++ b/src/InitializationPlugin/CMakeLists.txt @@ -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} ) diff --git a/src/InitializationPlugin/InitializationPlugin_EvalListener.cpp b/src/InitializationPlugin/InitializationPlugin_EvalListener.cpp index e2dceb117..9268004a4 100644 --- a/src/InitializationPlugin/InitializationPlugin_EvalListener.cpp +++ b/src/InitializationPlugin/InitializationPlugin_EvalListener.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -32,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +46,8 @@ #include #include #include +#include +#include //------------------------------------------------------------------------------ // 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(new InitializationPlugin_PyInterp()); @@ -105,9 +110,110 @@ void InitializationPlugin_EvalListener::processEvent( std::shared_ptr aMsg = std::dynamic_pointer_cast(theMessage); aMsg->setPositions(myInterp->positions(aMsg->expression(), aMsg->parameter())); + }if (theMessage->eventID() == ModelAPI_BuildEvalMessage::eventId()) { + std::shared_ptr aMsg = + std::dynamic_pointer_cast(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 > 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 >& theParamsList, + bool theIsFirstTime) +{ + std::list anExprParams = myInterp->compile(theExpression); + // find expression's params in the model + std::list aContext; + std::list::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::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 >& theParamsList, diff --git a/src/InitializationPlugin/InitializationPlugin_EvalListener.h b/src/InitializationPlugin/InitializationPlugin_EvalListener.h index 756b335ec..5036863a9 100644 --- a/src/InitializationPlugin/InitializationPlugin_EvalListener.h +++ b/src/InitializationPlugin/InitializationPlugin_EvalListener.h @@ -50,11 +50,21 @@ class InitializationPlugin_EvalListener : public Events_Listener protected: /// Evaluates theExpression and returns its value. - double evaluate(std::shared_ptr theParameter, + double evaluate(std::shared_ptr theParameter, const std::wstring& theExpression, std::string& theError, std::list >& theParamsList, const bool theIsParameter = false); + /// Evaluates theExpression with variable local and returns its value. + double evaluate(std::wstring& theVariable, + double theValueVariable, + std::shared_ptr theParameter, + const std::wstring& theExpression, + std::string& theError, + std::list >& theParamsList, + bool theIsFirstTime); + + /// Processes Evaluation event. void processEvaluationEvent(const std::shared_ptr& theMessage); diff --git a/src/ModelAPI/ModelAPI_Events.cpp b/src/ModelAPI/ModelAPI_Events.cpp index 7632dca2d..054d0bacf 100644 --- a/src/ModelAPI/ModelAPI_Events.cpp +++ b/src/ModelAPI/ModelAPI_Events.cpp @@ -207,29 +207,23 @@ void ModelAPI_BuildEvalMessage::setParameter(FeaturePtr theParam) } void ModelAPI_BuildEvalMessage::setResults( - const std::list >& theParamsList, - const double theResult, const std::string& theError) + const std::list >& theParamsList, + const std::string& theError) { myParamsList = theParamsList; - myResult = theResult; myError = theError; myIsProcessed = true; } -bool ModelAPI_BuildEvalMessage::isProcessed() -{ - return myIsProcessed; -} - const std::list >& 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 diff --git a/src/ModelAPI/ModelAPI_Events.h b/src/ModelAPI/ModelAPI_Events.h index dffa73a8d..06972aa17 100644 --- a/src/ModelAPI/ModelAPI_Events.h +++ b/src/ModelAPI/ModelAPI_Events.h @@ -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 > 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 > 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 >& theParamsList, - const double theResult, const std::string& theError); + const std::list >& theParamsList, + const std::string& theError); + /// Returns the results of processing: list of parameters found in the expression + MODELAPI_EXPORT const std::list >& 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 >& 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; }; -- 2.39.2