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