Salome HOME
Fix issue #1127: parameter is not created
[modules/shaper.git] / src / ParametersPlugin / ParametersPlugin_Parameter.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 // File:        ParametersPlugin_Parameter.cpp
4 // Created:     23 MArch 2015
5 // Author:      sbh
6
7 #include <pyconfig.h>
8
9 #include "ParametersPlugin_Parameter.h"
10 #include <ParametersPlugin_PyInterp.h>
11
12 #include <ModelAPI_AttributeString.h>
13 #include <ModelAPI_ResultParameter.h>
14 #include <ModelAPI_AttributeDouble.h>
15 #include <ModelAPI_AttributeRefList.h>
16 #include <ModelAPI_Tools.h>
17 #include <ModelAPI_Session.h>
18 #include <ModelAPI_Validator.h>
19
20 #include <string>
21 #include <sstream>
22
23 ParametersPlugin_Parameter::ParametersPlugin_Parameter()
24 {
25   myInterp = std::shared_ptr<ParametersPlugin_PyInterp>(new ParametersPlugin_PyInterp());
26   myInterp->initialize();
27 }
28
29 ParametersPlugin_Parameter::~ParametersPlugin_Parameter()
30 {
31 }
32
33 void ParametersPlugin_Parameter::initAttributes()
34 {
35   data()->addAttribute(VARIABLE_ID(), ModelAPI_AttributeString::typeId());
36   data()->addAttribute(EXPRESSION_ID(), ModelAPI_AttributeString::typeId());
37
38   data()->addAttribute(EXPRESSION_ERROR_ID(), ModelAPI_AttributeString::typeId());
39   data()->string(EXPRESSION_ERROR_ID())->setIsArgument(false);
40   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXPRESSION_ERROR_ID());
41
42   data()->addAttribute(ARGUMENTS_ID(), ModelAPI_AttributeRefList::typeId());
43   data()->reflist(ARGUMENTS_ID())->setIsArgument(false);
44   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), ARGUMENTS_ID());
45 }
46
47 bool ParametersPlugin_Parameter::isInHistory()
48 {
49   return false;
50 }
51
52 void ParametersPlugin_Parameter::attributeChanged(const std::string& theID)
53 {
54   if (theID == EXPRESSION_ID())
55     updateExpression();
56
57   data()->execState(ModelAPI_StateMustBeUpdated);
58 }
59
60 void ParametersPlugin_Parameter::updateName()
61 {
62   std::string aName = string(VARIABLE_ID())->value();
63   data()->setName(aName);
64
65   ResultParameterPtr aParam = document()->createParameter(data());
66   aParam->data()->setName(aName);
67   setResult(aParam);
68 }
69
70 bool ParametersPlugin_Parameter::updateExpression()
71 {
72   std::string anExpression = string(EXPRESSION_ID())->value();
73
74   std::string outErrorMessage;
75   double aValue = evaluate(anExpression, outErrorMessage);
76
77   data()->string(EXPRESSION_ERROR_ID())->setValue(outErrorMessage);
78   if (!outErrorMessage.empty())
79     return false;
80
81   ResultParameterPtr aParam = document()->createParameter(data());
82   AttributeDoublePtr aValueAttribute = aParam->data()->real(ModelAPI_ResultParameter::VALUE());
83   aValueAttribute->setValue(aValue);
84   setResult(aParam);
85   return true;
86 }
87
88 void ParametersPlugin_Parameter::execute()
89 {
90   updateName();
91   if (!updateExpression())
92     setError("Expression error.", false);
93 }
94
95 double ParametersPlugin_Parameter::evaluate(const std::string& theExpression, std::string& theError)
96 {
97   std::list<std::string> anExprParams = myInterp->compile(theExpression);
98   // find expression's params in the model
99   std::list<std::string> aContext;
100   std::list<std::string>::iterator it = anExprParams.begin();
101   std::list<ResultParameterPtr> aParamsList;
102   for ( ; it != anExprParams.end(); it++) {
103     std::string& aVariableName = *it;
104
105     // Parameter with the same name should be searched in the parent document.
106     // For the PartSet assume that the parameter is absent.
107     // Currently there is no way to get parent document, so we get PartSet for all.
108     DocumentPtr aDocument = document();
109     if (data()->name() == aVariableName) {
110       if (aDocument == ModelAPI_Session::get()->moduleDocument())
111         continue;
112       aDocument = ModelAPI_Session::get()->moduleDocument();
113     }
114
115     double aValue;
116     ResultParameterPtr aParamRes;
117     if (!ModelAPI_Tools::findVariable(aVariableName, aValue, aParamRes, aDocument)) continue;
118     aParamsList.push_back(aParamRes);
119
120     std::ostringstream sstream;
121     sstream << aValue;
122     std::string aParamValue = sstream.str();
123     aContext.push_back(*it + "=" + aParamValue);
124   }
125   // compare the list of parameters to store if changed
126   AttributeRefListPtr aParams = reflist(ARGUMENTS_ID());
127   bool aDifferent = aParams->size() != aParamsList.size();
128   if (!aDifferent) {
129     std::list<ResultParameterPtr>::iterator aNewIter = aParamsList.begin();
130     std::list<ObjectPtr> anOldList = aParams->list();
131     std::list<ObjectPtr>::iterator anOldIter = anOldList.begin();
132     for(; !aDifferent && aNewIter != aParamsList.end(); aNewIter++, anOldIter++) {
133       if (*aNewIter != *anOldIter)
134         aDifferent = true;
135     }
136   }
137   if (aDifferent) {
138     aParams->clear();
139     std::list<ResultParameterPtr>::iterator aNewIter = aParamsList.begin();
140     for(; aNewIter != aParamsList.end(); aNewIter++) {
141       aParams->append(*aNewIter);
142     }
143   }
144
145   myInterp->extendLocalContext(aContext);
146   double result = myInterp->evaluate(theExpression, theError);
147   myInterp->clearLocalContext();
148   return result;
149 }
150
151 bool ParametersPlugin_Parameter::isPreviewNeeded() const
152 {
153   return false;
154 }