--- /dev/null
+// 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 <BuildPlugin_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<BuildPlugin_PyInterp>(new BuildPlugin_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\")");
+}
--- /dev/null
+// 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;
+// JL_CGLB n'existe pas class InitializationPlugin_Parameter;
+class BuildPlugin_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<BuildPlugin_PyInterp> myInterp;
+};
+
+#endif /* SRC_BUILDPLUGIN_EVALLISTENER_H_ */
#include <ModelAPI_AttributeInteger.h>
#include <ModelAPI_AttributeDouble.h>
#include <ModelAPI_AttributeRefList.h>
+#include <ModelAPI_AttributeTables.h>
#include <ModelAPI_Session.h>
#include <ModelAPI_Validator.h>
#include <GeomAPI_ShapeExplorer.h>
#include <ModelAPI_Tools.h>
+#include <ModelAPI_Expression.h>
+
#include <algorithm>
#include <iostream>
+#include <sstream>
-std::string ReplaceAll(std::string str, const std::string& from, const std::string& to) {
- size_t start_pos = 0;
- while((start_pos = str.find(from, start_pos)) != std::string::npos) {
- str.replace(start_pos, from.length(), to);
- start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
- }
- return str;
-}
//=================================================================================================
BuildPlugin_Interpolation::BuildPlugin_Interpolation()
{
+
}
//=================================================================================================
data()->addAttribute(EXPRESSION_ID(), ModelAPI_AttributeString::typeId());
data()->addAttribute(EXPRESSION_ERROR_ID(), ModelAPI_AttributeString::typeId());
data()->addAttribute(VARIABLE_ID(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(VALUE_ID(), ModelAPI_AttributeTables::typeId());
data()->string(EXPRESSION_ERROR_ID())->setIsArgument(false);
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXPRESSION_ERROR_ID());
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CREATION_METHODE_BY_SELECTION_ID());
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXPRESSION_ID());
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), VARIABLE_ID());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), VALUE_ID());
data()->addAttribute(ARGUMENTS_ID(), ModelAPI_AttributeRefList::typeId());
data()->reflist(ARGUMENTS_ID())->setIsArgument(false);
}
void BuildPlugin_Interpolation::attributeChanged(const std::string& theID)
-{
+{
+ if( (theID == XT_ID()
+ || theID == YT_ID()
+ || theID == ZT_ID()
+ || theID == MINT_ID()
+ || theID == MAXT_ID()
+ || theID == NUMSTEP_ID())
+ && string(XT_ID())->value() !=""
+ && string(YT_ID())->value() !=""
+ && string(ZT_ID())->value() !=""
+ ){
+ updateCoods();
+ }
+
+}
+
+void BuildPlugin_Interpolation::updateCoods()
+{
+ std::wstring exp;
+ double aMint = real(MINT_ID())->value();
+ double aMaxt = real(MAXT_ID())->value();
+ int aNbrStep = integer(NUMSTEP_ID())->value();
+ double scale = (aMaxt - aMint )/aNbrStep;
+ string(VARIABLE_ID())->setValue("t");
+ tables(VALUE_ID())->setSize(aNbrStep,4);
+ for( int step = 0; step < aNbrStep; step++ ){
+ ModelAPI_AttributeTables::Value aVal;
+ aVal.myDouble = step * scale + aMint;
+ tables(VALUE_ID())->setValue(aVal,step,0);
+ }
+
+ outErrorMessage="";
+
+ evaluate(outErrorMessage);
+ if (!outErrorMessage.empty()){
+ std::cout << L"outErrorMessage= " << outErrorMessage << std::endl;
+ }
}
//=================================================================================================
}else
{
- double aMint = real(MINT_ID())->value();
- double aMaxt = real(MAXT_ID())->value();
- int aNbrStep = integer(NUMSTEP_ID())->value();
- double scale = (aMaxt - aMint )/aNbrStep;
- std::cout << "aMint = " << aMint << std::endl;
- std::cout << "aMaxt = " << aMaxt << std::endl;
- std::cout << "aNbrStep = " << aNbrStep << std::endl;
- std::cout << "scale = " << scale << std::endl;
-
+ if( string( XT_ID())->value() == ""
+ ||string( YT_ID())->value() == ""
+ ||string( ZT_ID())->value() == "")
+ return;
+
+ if (!outErrorMessage.empty()){
+ setError("Error: Python interpreter " + outErrorMessage);
+ return;
+ }
+ AttributeTablesPtr table = tables( VALUE_ID() );
std::list<std::vector<double> > aCoodPoints;
- for( int step = 0; step < aNbrStep; step++ ){
- std::vector<double> coodPoint;
- double result;
- double value = step * scale + aMint;
+ for( int step = 0; step < table->rows() ; step++ ){
+ std::vector<double> coodPoint;
+ ModelAPI_AttributeTables::Value value;
//x
- std::string exp = string( XT_ID())->value();
- exp = ReplaceAll(exp,"t", std::to_string(value) );
- string(EXPRESSION_ID())->setValue(exp);
- if (!updateExpression(result))
- setError("Expression error.", false);
- coodPoint.push_back(result);
+ value = table->value(step, 1);
+ coodPoint.push_back( value.myDouble );
//y
- exp = string( YT_ID())->value();
- exp = ReplaceAll(exp,"t", std::to_string(value) );
- string(EXPRESSION_ID())->setValue(exp);
- if (!updateExpression(result))
- setError("Expression error.", false);
- coodPoint.push_back(result);
- //Z
- exp = string( ZT_ID())->value();
- exp = ReplaceAll(exp,"t", std::to_string(value) );
- string(EXPRESSION_ID())->setValue(exp);
- if (!updateExpression(result))
- setError("Expression error.", false);
- coodPoint.push_back(result);
+ value = table->value(step, 2);
+ coodPoint.push_back( value.myDouble );
+ //
+ value = table->value(step, 3);
+ coodPoint.push_back( value.myDouble );
aCoodPoints.push_back(coodPoint);
}
-
+
std::list<GeomPointPtr> aPoints;
+ std::list<GeomVertexPtr> aVertices;
std::list<std::vector<double> >::const_iterator aItCoodPoints = aCoodPoints.begin();
for( ; aItCoodPoints != aCoodPoints.end(); ++aItCoodPoints ){
std::cout << "cood = " << "(" << (*aItCoodPoints)[0] << ", "<<
(*aItCoodPoints)[1] << ", "<<
(*aItCoodPoints)[2] << " ) "<< std::endl;
- std::shared_ptr<GeomAPI_Vertex> vertex =
+ GeomVertexPtr vertex =
GeomAlgoAPI_PointBuilder::vertex( (*aItCoodPoints)[0],
(*aItCoodPoints)[1],
(*aItCoodPoints)[2]);
aPoints.push_back (vertex->point());
+ aVertices.push_back (vertex);
}
+ /*
GeomDirPtr aDirStart(new GeomAPI_Dir( aCoodPoints.front()[0],
aCoodPoints.front()[1],
aCoodPoints.front()[2]));
GeomDirPtr aDirEnd(new GeomAPI_Dir( aCoodPoints.back()[0],
aCoodPoints.back()[1],
- aCoodPoints.back()[2]));
+ aCoodPoints.back()[2]));*/
// Create curve from points
GeomEdgePtr anEdge =
- GeomAlgoAPI_CurveBuilder::edge(aPoints, false, true, aDirStart, aDirEnd);
+ GeomAlgoAPI_CurveBuilder::edge(aPoints, false, true,GeomDirPtr(),GeomDirPtr()); //aDirStart, aDirEnd);
if (!anEdge.get()) {
setError("Error: Result curve is empty.");
return;
}
-
- // Store result.
+
ResultBodyPtr aResultBody = document()->createBody(data());
- /*std::set<GeomShapePtr>::const_iterator aContextIt = aContexts.begin();
- for (; aContextIt != aContexts.end(); aContextIt++) {
- aResultBody->storeModified(*aContextIt, anEdge, aContextIt == aContexts.begin());
- }
- std::list<GeomPointPtr>::const_iterator aPointsIt = aPoints.begin();
- GeomAPI_ShapeExplorer anExp(anEdge, GeomAPI_Shape::EDGE);
- for (; anExp.more() && aPointsIt != aPoints.cend(); anExp.next(), ++aPointsIt) {
- GeomShapePtr aPoint = std::dynamic_pointer_cast<GeomAPI_Shape>( *aPointsIt );
- GeomShapePtr anEdge = anExp.current();
- aResultBody->generated(aPoint, anEdge);
- }*/
+ // Load the result
+ aResultBody->store(anEdge);
int aVertexIndex = 1;
for (GeomAPI_ShapeExplorer anExp(anEdge, GeomAPI_Shape::VERTEX); anExp.more(); anExp.next()) {
std::string aVertexName = "Vertex_" + std::to_string((long long)aVertexIndex);
aResultBody->generated(anExp.current(), aVertexName);
+ aVertexIndex++;
}
-
+
setResult(aResultBody);
}
}
-double BuildPlugin_Interpolation::evaluate(const std::wstring& /*theExpression*/,
- std::string& theError)
+void BuildPlugin_Interpolation::evaluate(std::string& theError)
{
FeaturePtr aMyPtr = std::dynamic_pointer_cast<ModelAPI_Feature>(data()->owner());
- std::shared_ptr<ModelAPI_ParameterEvalMessage> aProcessMessage =
- ModelAPI_ParameterEvalMessage::send(aMyPtr, this);
+ std::shared_ptr<ModelAPI_BuildEvalMessage> aProcessMessage =
+ ModelAPI_BuildEvalMessage::send(aMyPtr, this);
- double aResult = 0;
if (aProcessMessage->isProcessed()) {
- const std::list<ResultParameterPtr>& aParamsList = aProcessMessage->params();
- aResult = aProcessMessage->result();
theError = aProcessMessage->error();
- // compare the list of parameters to store if changed
- /* AttributeRefListPtr aParams = reflist(ARGUMENTS_ID());
- bool aDifferent = aParams->size() != (int)aParamsList.size();
- if (!aDifferent) {
- std::list<ResultParameterPtr>::const_iterator aNewIter = aParamsList.begin();
- std::list<ObjectPtr> anOldList = aParams->list();
- std::list<ObjectPtr>::const_iterator anOldIter = anOldList.begin();
- for(; !aDifferent && aNewIter != aParamsList.end(); aNewIter++, anOldIter++) {
- if (*aNewIter != *anOldIter)
- aDifferent = true;
- }
- }
- if (aDifferent) {
- aParams->clear();
- std::list<ResultParameterPtr>::const_iterator aNewIter = aParamsList.begin();
- for(; aNewIter != aParamsList.end(); aNewIter++) {
- aParams->append(*aNewIter);
- }
- }*/
+ std::cout << "theError= " << theError << std::endl;
} else { // error: python interpreter is not active
theError = "Python interpreter is not available";
}
- return aResult;
}
-bool BuildPlugin_Interpolation::updateExpression(double& result)
-{
- std::wstring anExpression = string(EXPRESSION_ID())->isUValue() ?
- Locale::Convert::toWString(string(EXPRESSION_ID())->valueU()) :
- Locale::Convert::toWString(string(EXPRESSION_ID())->value());
-
- std::string outErrorMessage;
- result= evaluate(anExpression, outErrorMessage);
-
- data()->string(EXPRESSION_ERROR_ID())->setValue(outErrorMessage);
- if (!outErrorMessage.empty())
- return false;
-
- std::cout << "result = " << result << std::endl;
- return true;
-}
static const std::string MY_VARIABLE_ID("variable");
return MY_VARIABLE_ID;
}
+
+ /// attribute of parameter name
+ inline static const std::string& VALUE_ID()
+ {
+ static const std::string MY_VALUE_ID("value");
+ return MY_VALUE_ID;
+ }
/// attribute of parameter expression
inline static const std::string& EXPRESSION_ID()
protected:
/// Evaluates theExpression and returns its value.
- double evaluate(const std::wstring& theExpression, std::string& theError);
+ void evaluate(std::string& theError);
+
+ void updateCoods();
- bool updateExpression(double& result);
+ std::list<double> aCoodPoints[3];
+ std::string outErrorMessage;
};
#include <BuildPlugin_Filling.h>
#include <BuildPlugin_Validators.h>
+#include <BuildPlugin_EvalListener.h>
+
+
// the only created instance of this plugin
static BuildPlugin_Plugin* MY_INSTANCE = new BuildPlugin_Plugin();
aFactory->registerValidator("BuildPlugin_ValidatorExpressionInterpolation",
new BuildPlugin_ValidatorExpressionInterpolation());
-
// Register this plugin.
ModelAPI_Session::get()->registerPlugin(this);
+
+ myEvalListener =
+ std::shared_ptr<BuildPlugin_EvalListener>(new BuildPlugin_EvalListener());
}
//=================================================================================================
#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.
/// 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
--- /dev/null
+// 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 <BuildPlugin_PyInterp.h>
+
+#include <Locale_Convert.h>
+
+#include <string>
+#include <stdexcept>
+#include <clocale>
+
+BuildPlugin_PyInterp::BuildPlugin_PyInterp()
+: PyInterp_Interp()
+{
+}
+
+BuildPlugin_PyInterp::~BuildPlugin_PyInterp()
+{
+}
+
+const char* aSearchCode =
+ "import ast\n"
+ "class FindName(ast.NodeVisitor):\n"
+ " def __init__(self, name):\n"
+ " self.name = name\n"
+ " def visit_Name(self, node):\n"
+ " if node.id == self.name:\n"
+ " positions.append((node.lineno, node.col_offset))\n"
+ "FindName(name).visit(ast.parse(expression))";
+
+// make the expression be correct for the python interpreter even for the
+// beta=alfa*2 expressions
+static std::wstring adjustExpression(const std::wstring& theExpression) {
+ std::wstring anExpression = theExpression;
+ if (!anExpression.empty() && anExpression.back() == L'=') {
+ anExpression = anExpression.substr(0, anExpression.length() - 1);
+ }
+ return anExpression;
+}
+
+std::list<std::pair<int, int> >
+BuildPlugin_PyInterp::positions(const std::wstring& theExpression,
+ const std::wstring& theName)
+{
+ PyLockWrapper lck; // Acquire GIL until the end of the method
+
+ std::list<std::pair<int, int> > aResult;
+
+ // prepare a context
+ PyObject* aContext = PyDict_New();
+ PyDict_SetItemString(aContext, "__builtins__", PyEval_GetBuiltins());
+
+ std::wstring anExpression = adjustExpression(theExpression);
+ // extend aContext with variables
+ PyDict_SetItemString(aContext, "expression",
+ PyUnicode_FromWideChar(anExpression.c_str(), anExpression.size()));
+ PyDict_SetItemString(aContext, "name", PyUnicode_FromWideChar(theName.c_str(), theName.size()));
+ PyDict_SetItemString(aContext, "positions", Py_BuildValue("[]"));
+
+ // run the search code
+ PyObject* aExecResult = PyRun_String(aSearchCode, Py_file_input, aContext, aContext);
+ Py_XDECREF(aExecResult);
+
+ // receive results from context
+ PyObject* aPositions = PyDict_GetItemString(aContext, "positions");
+ for (int anIndex = 0; anIndex < PyList_Size(aPositions); ++anIndex) {
+ PyObject* aPosition = PyList_GetItem(aPositions, anIndex);
+ PyObject* aLineNo = PyTuple_GetItem(aPosition, 0);
+ PyObject* aColOffset = PyTuple_GetItem(aPosition, 1);
+
+ aResult.push_back(
+ std::pair<int, int>((int)PyLong_AsLong(aLineNo),
+ (int)PyLong_AsLong(aColOffset)));
+ }
+
+ // TODO(spo): after this refCount of the variable is not 0. Is there memory leak?
+ Py_DECREF(aContext);
+
+ return aResult;
+}
+
+
+std::list<std::wstring> BuildPlugin_PyInterp::compile(const std::wstring& theExpression)
+{
+ PyLockWrapper lck; // Acquire GIL until the end of the method
+ std::list<std::wstring> aResult;
+ PyObject *aCodeopModule = PyImport_AddModule("codeop");
+ if(!aCodeopModule) { // Fatal error. No way to go on.
+ PyErr_Print();
+ return aResult;
+ }
+ // support "variable_name=" expression as "variable_name"
+ std::wstring anExpression = adjustExpression(theExpression);
+
+ PyObject *aCodePyObj =
+ PyObject_CallMethod(aCodeopModule, (char*)"compile_command", (char*)"(s)",
+ Locale::Convert::toString(anExpression).c_str());
+
+ if(!aCodePyObj || aCodePyObj == Py_None || !PyCode_Check(aCodePyObj)) {
+ Py_XDECREF(aCodePyObj);
+ return aResult;
+ }
+
+ PyCodeObject* aCodeObj = (PyCodeObject*) aCodePyObj;
+ std::string aCodeName(PyBytes_AsString(aCodeObj->co_code));
+ // co_names should be tuple, but can be changed in modern versions of python (>2.7.3)
+ if(!PyTuple_Check(aCodeObj->co_names)) {
+ return aResult;
+ }
+
+ size_t params_size = PyTuple_Size(aCodeObj->co_names);
+ if (params_size > 0) {
+ for (size_t i = 0; i < params_size; i++) {
+ PyObject* aParamObj = PyTuple_GetItem(aCodeObj->co_names, i);
+ PyObject* aParamObjStr = PyObject_Str(aParamObj);
+ Py_ssize_t aSize;
+ std::wstring aParamName(PyUnicode_AsWideCharString(aParamObjStr, &aSize));
+ aResult.push_back(aParamName);
+ Py_XDECREF(aParamObjStr);
+ }
+ }
+ Py_XDECREF(aCodeObj);
+ return aResult;
+}
+
+void BuildPlugin_PyInterp::extendLocalContext(const std::list<std::wstring>& theParameters)
+{
+ PyLockWrapper lck; // Acquire GIL until the end of the method
+ if (theParameters.empty())
+ return;
+ std::list<std::wstring>::const_iterator it = theParameters.begin();
+ for ( ; it != theParameters.cend(); it++) {
+ std::string aParamValue = Locale::Convert::toString(*it);
+ simpleRun(aParamValue.c_str(), false);
+ }
+}
+
+void BuildPlugin_PyInterp::clearLocalContext()
+{
+ PyLockWrapper lck;
+ PyDict_Clear(_local_context);
+}
+
+double BuildPlugin_PyInterp::evaluate(const std::wstring& theExpression,
+ std::string& theError)
+{
+ // support "variable_name=" expression as "variable_name"
+ std::wstring anExpression = adjustExpression(theExpression);
+
+ PyLockWrapper lck; // Acquire GIL until the end of the method
+ PyCompilerFlags aFlags = {CO_FUTURE_DIVISION};
+ aFlags.cf_flags = CO_FUTURE_DIVISION;
+ PyCodeObject* anExprCode = (PyCodeObject *) Py_CompileStringFlags(
+ Locale::Convert::toString(anExpression).c_str(),
+ "<string>", Py_eval_input, &aFlags);
+ if(!anExprCode) {
+ theError = errorMessage();
+ Py_XDECREF(anExprCode);
+ return 0.;
+ }
+
+ PyObject* anEvalResult = PyEval_EvalCode((PyObject *)anExprCode, _global_context, _local_context);
+ if(!anEvalResult) {
+ theError = errorMessage();
+ Py_XDECREF(anExprCode);
+ Py_XDECREF(anEvalResult);
+ return 0.;
+ }
+
+ PyObject* anEvalStrObj = PyObject_Str(anEvalResult);
+ std::string anEvalStr(PyUnicode_AsUTF8(anEvalStrObj));
+ Py_XDECREF(anExprCode);
+ Py_XDECREF(anEvalResult);
+ Py_XDECREF(anEvalStrObj);
+ double result = 0.;
+ try {
+ // set locale due to the #2485
+ std::string aCurLocale = std::setlocale(LC_NUMERIC, 0);
+ std::setlocale(LC_NUMERIC, "C");
+ result = std::stod(anEvalStr);
+ std::setlocale(LC_NUMERIC, aCurLocale.c_str());
+ }
+ catch (const std::invalid_argument&) {
+ theError = "Unable to eval " + anEvalStr;
+ }
+
+ return result;
+}
+
+std::string BuildPlugin_PyInterp::errorMessage()
+{
+ std::string aPyError;
+ if (PyErr_Occurred()) {
+ PyObject *pstr, *ptype, *pvalue, *ptraceback;
+ PyErr_Fetch(&ptype, &pvalue, &ptraceback);
+ PyErr_NormalizeException(&ptype, &pvalue, &ptraceback);
+ pstr = PyObject_Str(pvalue);
+ aPyError = std::string(PyUnicode_AsUTF8(pstr));
+ Py_XDECREF(pstr);
+ Py_XDECREF(ptype);
+ Py_XDECREF(pvalue);
+ Py_XDECREF(ptraceback);
+ }
+ return aPyError;
+}
+
+bool BuildPlugin_PyInterp::initContext()
+{
+ PyObject *m = PyImport_AddModule("__main__"); // interpreter main module (module context)
+ if(!m){
+ PyErr_Print();
+ return false;
+ }
+ _global_context = PyModule_GetDict(m); // get interpreter global variable context
+ Py_INCREF(_global_context);
+ _local_context = PyDict_New();
+ Py_INCREF(_local_context);
+
+ // to avoid "help()" hang in the python console
+ const static char* aHelpTxt = "def help(): print(\"Available modules:\\n"
+ " salome.shaper.model : higher level access to features and data model\\n"
+ " BuildAPI : Build plugin features allowing to build shapes\\n"
+ " ConfigAPI : configuration management: preferences and XML properties\\n"
+ " ConstructionAPI : Construction plugin for auxiliary features creation\\n"
+ " EventsAPI : application events receiving and emitting manager\\n"
+ " ExchangeAPI : Exchange plugin with import/export features\\n"
+ " FeaturesAPI : Features plugin with general 3D features\\n"
+ " GeomAlgoAPI : geometrical algorithms\\n"
+ " GeomAPI : geometrical data structures\\n"
+ " GeomDataAPI : specific geometrical data structures stored in the data model\\n"
+ " ModelAPI : general low-level interface to access data model\\n"
+ " ModelHighAPI : general high-level interface to access data model\\n"
+ " ParametersAPI : Parameters plugin for parameters feature management\\n"
+ " PartSetAPI : PartSet plugin for management Parts features\\n"
+ " SketchAPI : Sketch plugin with all sketch features\")";
+
+ PyRun_SimpleString(aHelpTxt);
+
+ return PyRun_SimpleString("from math import *") == 0;
+}
+
+void BuildPlugin_PyInterp::closeContext()
+{
+ Py_XDECREF(_local_context);
+ PyInterp_Interp::closeContext();
+}
+
+bool BuildPlugin_PyInterp::runString(std::string theString)
+{
+ PyLockWrapper lck; // Acquire GIL until the end of the method
+ return PyRun_SimpleString(theString.c_str());
+}
--- /dev/null
+// 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 BUILDPLUGIN_PYINTERP_H_
+#define BUILDPLUGIN_PYINTERP_H_
+
+#include <PyInterp_Interp.h>
+#include <BuildPlugin.h>
+
+#include <list>
+#include <string>
+#include <utility>
+
+/**
+ * \class BuildPlugin_PyInterp
+ * \ingroup Plugins
+ * \brief Helper class for using Python interpreter.
+ */
+class BUILDPLUGIN_EXPORT BuildPlugin_PyInterp : public PyInterp_Interp
+{
+ public:
+ BuildPlugin_PyInterp();
+ virtual ~BuildPlugin_PyInterp();
+
+ /// Returns a list of positions for theName in theExpression.
+ std::list<std::pair<int, int> > positions(const std::wstring& theExpression,
+ const std::wstring& theName);
+ /// Compiles theExpression and returns a list of parameters used in theExpression.
+ std::list<std::wstring> compile(const std::wstring& theExpression);
+ /// Extends local context with the list of parameters.
+ void extendLocalContext(const std::list<std::wstring>& theParameters);
+ /// Clears local context.
+ void clearLocalContext();
+ /// Evaluates theExpression and returns its value.
+ double evaluate(const std::wstring& theExpression, std::string& theError);
+
+ /// Runs the string command in the python interpreter. Returns true if no error is in result.
+ bool runString(std::string theString);
+
+ protected:
+ /// Returns error message.
+ std::string errorMessage();
+ /// Overrides PyInterp_Interp.
+ virtual bool initContext();
+ /// Reimplemented from PyInterp_Interp::closeContext().
+ virtual void closeContext();
+};
+
+#endif /* BUILDPLUGIN_PYINTERP_H_ */
${PROJECT_SOURCE_DIR}/src/GeomDataAPI
${PROJECT_SOURCE_DIR}/src/GeomValidators
${PROJECT_SOURCE_DIR}/src/SketchPlugin
+ ${SUIT_INCLUDE}
+ ${PYTHON_INCLUDE_DIR}
)
SET(PROJECT_HEADERS
BuildPlugin_SubShapes.h
BuildPlugin_Filling.h
BuildPlugin_Validators.h
+ BuildPlugin_EvalListener.h
+ BuildPlugin_PyInterp.h
)
SET(PROJECT_SOURCES
BuildPlugin_SubShapes.cpp
BuildPlugin_Filling.cpp
BuildPlugin_Validators.cpp
+ BuildPlugin_EvalListener.cpp
+ BuildPlugin_PyInterp.cpp
)
SET(XML_RESOURCES
GeomAPI
GeomAlgoAPI
GeomValidators
+ ${PyInterp}
+ ${PYTHON_LIBRARIES}
)
ADD_DEFINITIONS(-DBUILDPLUGIN_EXPORTS)
<source>
<toolbox id="interpolation_method">
<box id="by_selection"
- icon="icons/BuildPlugin/edge_by_points_32x32.png">
+ title="Curve by selection"
+ icon="icons/Build/feature_interpolation_by_selection.png">
<multi_selector id="base_objects"
label="Points and vertices:"
tooltip="Select points or vertices objects."
</shape_selector>
</optionalbox>
</optionalbox>
- <validator id="GeomValidators_MinObjectsSelected" parameters="base_objects,2"/>
+ <!--JL_CGLB validator id="GeomValidators_MinObjectsSelected" parameters="base_objects,2"/-->
</box>
<box id="analytical"
- title="Curve parameters"
+ title="Curve analytical"
tooltip="???"
- icon="icons/BuildPlugin/feature_edge.png">
+ icon="icons/Build/feature_interpolation_analytical.png">
<stringvalue id="xt" label="X(t) equation" >
<validator id="BuildPlugin_ValidatorExpressionInterpolation"/>
</stringvalue>
label="Min t"
min="0"
default="0">
- <validator id="GeomValidators_Positive"/>
+ <!--validator id="GeomValidators_Positive"/-->
</doublevalue>
<doublevalue id="maxt"
label="Max t"
min="0"
default="100">
- <validator id="GeomValidators_Positive"/>
+ <!--validator id="GeomValidators_Positive"/-->
</doublevalue>
<integervalue id="numstep"
label="Number of steps"
<source path="edge_widget.xml"/>
</feature>
<feature id="Interpolation" title="Interpolation" tooltip ="Create an interpolation curve from points" icon="icons/Build/feature_interpolation.png"
- auto_preview="false" helpfile="interpolationFeature.html">
+ helpfile="interpolationFeature.html">
<source path="interpolation_widget.xml"/>
</feature>
<feature id="Wire" title="Wire" tooltip ="Create a wire from sketch edges, edges and wires objects" icon="icons/Build/feature_wire.png"
return myError;
}
+ModelAPI_BuildEvalMessage::ModelAPI_BuildEvalMessage(
+ const Events_ID theID, const void* theSender)
+ : Events_Message(theID, theSender), myIsProcessed(false)
+{}
+
+ModelAPI_BuildEvalMessage::~ModelAPI_BuildEvalMessage()
+{}
+
+FeaturePtr ModelAPI_BuildEvalMessage::parameter() const
+{
+ return myParam;
+}
+
+void ModelAPI_BuildEvalMessage::setParameter(FeaturePtr theParam)
+{
+ myParam = theParam;
+}
+
+void ModelAPI_BuildEvalMessage::setResults(
+ const std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
+ const double theResult, 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
+{
+ return myResult;
+}
+
+const std::string& ModelAPI_BuildEvalMessage::error() const
+{
+ return myError;
+}
+
ModelAPI_ComputePositionsMessage::ModelAPI_ComputePositionsMessage(
const Events_ID theID, const void* theSender)
: Events_Message(theID, theSender)
MODELAPI_EXPORT const std::string& error() const;
};
+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
+
+ public:
+ /// Static. Returns EventID of the message.
+ MODELAPI_EXPORT static Events_ID& eventId()
+ {
+ static const char * MY_BUILD_EVALUATION_EVENT_ID("ParameterEvaluationRequest");
+ static Events_ID anId = Events_Loop::eventByName(MY_BUILD_EVALUATION_EVENT_ID);
+ return anId;
+ }
+
+ /// Useful method that creates and sends the event.
+ /// Returns the message, processed, with the resulting fields filled.
+ MODELAPI_EXPORT static std::shared_ptr<ModelAPI_BuildEvalMessage>
+ send(FeaturePtr theParameter, const void* theSender)
+ {
+ std::shared_ptr<ModelAPI_BuildEvalMessage> aMessage =
+ std::shared_ptr<ModelAPI_BuildEvalMessage>(
+ new ModelAPI_BuildEvalMessage(eventId(), theSender));
+ aMessage->setParameter(theParameter);
+ Events_Loop::loop()->send(aMessage);
+ return aMessage;
+ }
+
+ /// Creates an empty message
+ MODELAPI_EXPORT ModelAPI_BuildEvalMessage(const Events_ID theID, const void* theSender = 0);
+ /// The virtual destructor
+ MODELAPI_EXPORT virtual ~ModelAPI_BuildEvalMessage();
+
+ /// Returns a parameter stored in the message
+ MODELAPI_EXPORT FeaturePtr parameter() const;
+ /// Sets a parameter to the 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);
+ /// 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;
+};
/// Message to ask compute the positions of parameters in the expression
class ModelAPI_ComputePositionsMessage : public Events_Message