Salome HOME
Fix for the issue #593: do not remove naming attribute, but use TNaming_Builder for...
[modules/shaper.git] / src / ParametersPlugin / ParametersPlugin_EvalListener.cpp
1 /*
2  * ParametersPlugin_EvalListener.cpp
3  *
4  *  Created on: Apr 28, 2015
5  *      Author: sbh
6  */
7
8 #include <ParametersPlugin_EvalListener.h>
9
10 #include <Events_Error.h>
11
12 #include <ModelAPI_Events.h>
13 #include <ModelAPI_Tools.h>
14 #include <ModelAPI_AttributeDouble.h>
15 #include <GeomDataAPI_Point.h>
16 #include <GeomDataAPI_Point2D.h>
17
18 #include <string>
19 #include <sstream>
20
21 ParametersPlugin_EvalListener::ParametersPlugin_EvalListener()
22 {
23   Events_Loop* aLoop = Events_Loop::loop();
24   const Events_ID kEvaluationEvent = ModelAPI_AttributeEvalMessage::eventId();
25   aLoop->registerListener(this, kEvaluationEvent, NULL, true);
26
27   myInterp = std::shared_ptr<ParametersPlugin_PyInterp>(new ParametersPlugin_PyInterp());
28   myInterp->initialize();
29 }
30
31 ParametersPlugin_EvalListener::~ParametersPlugin_EvalListener()
32 {
33 }
34
35 void ParametersPlugin_EvalListener::processEvent(const std::shared_ptr<Events_Message>& theMessage)
36 {
37   if (!theMessage.get())
38     return;
39
40   const Events_ID kEvaluationEvent = ModelAPI_AttributeEvalMessage::eventId();
41   if (theMessage->eventID() == kEvaluationEvent) {
42     std::shared_ptr<ModelAPI_AttributeEvalMessage> aMessage =
43         std::dynamic_pointer_cast<ModelAPI_AttributeEvalMessage>(theMessage);
44
45     // Double
46     AttributeDoublePtr aDoubleAttribute =
47         std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(aMessage->attribute());
48     if (aDoubleAttribute.get()) {
49       std::string anError;
50       double aValue = evaluate(aDoubleAttribute->text(), anError);
51       if (anError.empty()) {
52         aDoubleAttribute->setValue(aValue);
53         aDoubleAttribute->setExpressionInvalid(false);
54       } else { // set feature as invalid-parameter arguments
55         aDoubleAttribute->setExpressionInvalid(true);
56       }
57     }
58
59     // Point
60     AttributePointPtr aPointAttribute =
61         std::dynamic_pointer_cast<GeomDataAPI_Point>(aMessage->attribute());
62     if (aPointAttribute.get()) {
63       std::string anError[3];
64       double aValue[3] = {
65           evaluate(aPointAttribute->textX(), anError[0]),
66           evaluate(aPointAttribute->textY(), anError[1]),
67           evaluate(aPointAttribute->textZ(), anError[2])
68       };
69       bool isValid[3] = {
70           anError[0].empty(),
71           anError[1].empty(),
72           anError[2].empty()
73       };
74       aPointAttribute->setExpressionInvalid(0, !isValid[0]);
75       aPointAttribute->setExpressionInvalid(1, !isValid[1]);
76       aPointAttribute->setExpressionInvalid(2, !isValid[2]);
77
78       aPointAttribute->setValue(
79           isValid[0] ? aValue[0] : aPointAttribute->x(),
80           isValid[1] ? aValue[1] : aPointAttribute->y(),
81           isValid[2] ? aValue[2] : aPointAttribute->z()
82       );
83     }
84
85     // Point2D
86     AttributePoint2DPtr aPoint2DAttribute =
87         std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aMessage->attribute());
88     if (aPoint2DAttribute.get()) {
89       std::string anError[2];
90       double aValue[2] = {
91           evaluate(aPoint2DAttribute->textX(), anError[0]),
92           evaluate(aPoint2DAttribute->textY(), anError[1])
93       };
94       bool isValid[2] = {
95           anError[0].empty(),
96           anError[1].empty()
97       };
98       aPoint2DAttribute->setExpressionInvalid(0, !isValid[0]);
99       aPoint2DAttribute->setExpressionInvalid(1, !isValid[1]);
100
101       aPoint2DAttribute->setValue(
102           isValid[0] ? aValue[0] : aPoint2DAttribute->x(),
103           isValid[1] ? aValue[1] : aPoint2DAttribute->y()
104       );
105     }
106   } else {
107     Events_Error::send(std::string("ParametersPlugin python interpreter, unhandled message caught: ")
108                        + theMessage->eventID().eventText());
109   }
110 }
111
112 double ParametersPlugin_EvalListener::evaluate(const std::string& theExpression,
113                                                std::string& theError)
114 {
115   std::list<std::string> anExprParams = myInterp->compile(theExpression);
116   // find expression's params in the model
117   std::list<std::string> aContext;
118   std::list<std::string>::iterator it = anExprParams.begin();
119   for ( ; it != anExprParams.end(); it++) {
120     double aValue;
121     ResultParameterPtr aParamRes;
122     if (!ModelAPI_Tools::findVariable(*it, aValue, aParamRes)) continue;
123
124     std::ostringstream sstream;
125     sstream << aValue;
126     std::string aParamValue = sstream.str();
127     aContext.push_back(*it + "=" + aParamValue);
128   }
129   myInterp->extendLocalContext(aContext);
130   double result = myInterp->evaluate(theExpression, theError);
131   myInterp->clearLocalContext();
132   return result;
133 }