1 // Copyright (C) 2014-2021 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "BuildPlugin_Interpolation.h"
22 #include <ModelAPI_AttributeBoolean.h>
23 #include <ModelAPI_AttributeDouble.h>
24 #include <ModelAPI_AttributeInteger.h>
25 #include <ModelAPI_AttributeRefList.h>
26 #include <ModelAPI_AttributeSelectionList.h>
27 #include <ModelAPI_AttributeString.h>
28 #include <ModelAPI_AttributeTables.h>
29 #include <ModelAPI_Events.h>
30 #include <ModelAPI_ResultBody.h>
31 #include <ModelAPI_ResultParameter.h>
32 #include <ModelAPI_Session.h>
33 #include <ModelAPI_Validator.h>
35 #include <Events_InfoMessage.h>
37 #include <Locale_Convert.h>
39 #include <GeomAlgoAPI_ShapeTools.h>
40 #include <GeomAlgoAPI_CurveBuilder.h>
41 #include <GeomAlgoAPI_PointBuilder.h>
43 #include <GeomAPI_Edge.h>
44 #include <GeomAPI_Lin.h>
45 #include <GeomAPI_ShapeExplorer.h>
50 //=================================================================================================
51 BuildPlugin_Interpolation::BuildPlugin_Interpolation()
55 //=================================================================================================
56 void BuildPlugin_Interpolation::initAttributes()
58 data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
59 data()->addAttribute(CLOSED_ID(), ModelAPI_AttributeBoolean::typeId());
60 data()->addAttribute(REORDER_ID(), ModelAPI_AttributeBoolean::typeId());
61 data()->addAttribute(USE_TANGENTS_ID(), ModelAPI_AttributeString::typeId());
62 data()->addAttribute(TANGENT_START_ID(), ModelAPI_AttributeSelection::typeId());
63 data()->addAttribute(TANGENT_END_ID(), ModelAPI_AttributeSelection::typeId());
65 data()->addAttribute(CREATION_METHOD_ID(), ModelAPI_AttributeString::typeId());
66 data()->addAttribute(CREATION_METHOD_BY_SELECTION_ID(), ModelAPI_AttributeString::typeId());
67 data()->addAttribute(CREATION_METHOD_ANALYTICAL_ID(), ModelAPI_AttributeString::typeId());
68 data()->addAttribute(EXPRESSION_ERROR_ID(), ModelAPI_AttributeString::typeId());
69 data()->addAttribute(VARIABLE_ID(), ModelAPI_AttributeString::typeId());
70 data()->addAttribute(VALUE_ID(), ModelAPI_AttributeTables::typeId());
71 data()->string(EXPRESSION_ERROR_ID())->setIsArgument(false);
72 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXPRESSION_ERROR_ID());
74 data()->addAttribute(XT_ID(), ModelAPI_AttributeString::typeId());
75 data()->addAttribute(YT_ID(), ModelAPI_AttributeString::typeId());
76 data()->addAttribute(ZT_ID(), ModelAPI_AttributeString::typeId());
77 data()->addAttribute(MINT_ID(), ModelAPI_AttributeDouble::typeId());
78 data()->addAttribute(MAXT_ID(), ModelAPI_AttributeDouble::typeId());
79 data()->addAttribute(NUMSTEP_ID(), ModelAPI_AttributeInteger::typeId());
81 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
82 CREATION_METHOD_ANALYTICAL_ID());
83 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
84 CREATION_METHOD_BY_SELECTION_ID());
85 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), VARIABLE_ID());
86 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), VALUE_ID());
87 data()->addAttribute(ARGUMENTS_ID(), ModelAPI_AttributeRefList::typeId());
88 data()->reflist(ARGUMENTS_ID())->setIsArgument(false);
89 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), ARGUMENTS_ID());
91 if (string(XT_ID())->value() == ""
92 && string(YT_ID())->value() == ""
93 && string(ZT_ID())->value() == "") {
94 string(XT_ID())->setValue("t");
95 string(YT_ID())->setValue("t");
96 string(ZT_ID())->setValue("t");
97 real(MINT_ID())->setValue(0);
98 real(MAXT_ID())->setValue(100);
99 integer(NUMSTEP_ID())->setValue(10);
104 //=================================================================================================
105 void BuildPlugin_Interpolation::attributeChanged(const std::string& theID)
107 if ((theID == XT_ID()
110 || theID == MINT_ID()
111 || theID == MAXT_ID()
112 || theID == NUMSTEP_ID())
113 && string(XT_ID())->value() !=""
114 && string(YT_ID())->value() !=""
115 && string(ZT_ID())->value() !=""
116 && string(CREATION_METHOD_ID())->value() == CREATION_METHOD_ANALYTICAL_ID()) {
121 //=================================================================================================
122 void BuildPlugin_Interpolation::updateCoordinates()
125 double aMint = real(MINT_ID())->value();
126 double aMaxt = real(MAXT_ID())->value();
127 int aNbrStep = integer(NUMSTEP_ID())->value();
130 setError("The minimum value of the parameter must be less than maximum value !!!");
133 double aScale = (aMaxt - aMint)/aNbrStep;
134 string(VARIABLE_ID())->setValue("t");
136 tables(VALUE_ID())->setSize(aNbrStep+1,4);
137 for (int step = 0; step <= aNbrStep; step++) {
138 ModelAPI_AttributeTables::Value aVal;
139 aVal.myDouble = step * aScale + aMint;
140 tables(VALUE_ID())->setValue(aVal,step,0);
144 evaluate(outErrorMessage);
145 data()->string(EXPRESSION_ERROR_ID())->setValue(outErrorMessage);
146 if (!outErrorMessage.empty()) {
147 setError("Error: Python interpreter ");
152 //=================================================================================================
153 static GeomDirPtr selectionToDir(const AttributeSelectionPtr& theSelection)
158 GeomShapePtr aShape = theSelection->value();
159 if (!aShape && theSelection->context()) {
160 aShape = theSelection->context()->shape();
163 if (aShape && aShape->isEdge()) {
164 anEdge = GeomEdgePtr(new GeomAPI_Edge(aShape));
167 if (anEdge && anEdge->isLine()) {
168 aDir = anEdge->line()->direction();
174 //=================================================================================================
175 void BuildPlugin_Interpolation::execute()
177 if (string(CREATION_METHOD_ID())->value() == CREATION_METHOD_BY_SELECTION_ID()) {
178 // Get closed flag value
179 bool isClosed = boolean(CLOSED_ID())->value();
181 // Get reorder flag value
182 bool isToReorder = boolean(REORDER_ID())->value();
184 // Get use tangents flag value
185 bool isToUseTangents = isClosed? false : (!string(USE_TANGENTS_ID())->value().empty());
187 // Get tangent for start and end points
188 GeomDirPtr aDirStart, aDirEnd;
189 if (isToUseTangents) {
190 aDirStart = selectionToDir(selection(TANGENT_START_ID()));
191 aDirEnd = selectionToDir(selection(TANGENT_END_ID()));
194 // Get base objects list.
195 AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID());
198 std::list<GeomPointPtr> aPoints;
199 std::set<GeomShapePtr> aContexts;
200 for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
201 AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
203 GeomShapePtr aContextShape = aSelection->context()->shape();
204 aContexts.insert(aContextShape);
206 GeomShapePtr aShape = aSelection->value();
208 aShape = aContextShape;
211 GeomPointPtr aPoint = GeomAlgoAPI_PointBuilder::point(aShape);
212 aPoints.push_back(aPoint);
215 // Create curve from points
217 GeomAlgoAPI_CurveBuilder::edge(aPoints, isClosed, isToReorder, aDirStart, aDirEnd);
219 setError("Error: Result curve is empty.");
224 ResultBodyPtr aResultBody = document()->createBody(data());
225 std::set<GeomShapePtr>::const_iterator aContextIt = aContexts.begin();
226 for (; aContextIt != aContexts.end(); aContextIt++) {
227 aResultBody->storeModified(*aContextIt, anEdge, aContextIt == aContexts.begin());
229 int aVertexIndex = 1;
230 for (GeomAPI_ShapeExplorer anExp(anEdge, GeomAPI_Shape::VERTEX); anExp.more(); anExp.next()) {
231 std::string aVertexName = "Vertex_" + std::to_string((long long)aVertexIndex);
232 aResultBody->generated(anExp.current(), aVertexName);
235 setResult(aResultBody);
238 if (string(XT_ID())->value() == ""
239 ||string(YT_ID())->value() == ""
240 ||string(ZT_ID())->value() == ""
241 ||tables(VALUE_ID())->rows()== 0)
244 bool aWasBlocked = data()->blockSendAttributeUpdated(true);
246 data()->blockSendAttributeUpdated(aWasBlocked, false);
248 AttributeTablesPtr aTable = tables(VALUE_ID());
249 std::list<std::vector<double>> aCoordPoints;
250 for (int step = 0; step < aTable->rows(); step++) {
251 std::vector<double> aCoordPoint;
252 ModelAPI_AttributeTables::Value aValue;
254 aValue = aTable->value(step, 1);
255 aCoordPoint.push_back(aValue.myDouble);
257 aValue = aTable->value(step, 2);
258 aCoordPoint.push_back(aValue.myDouble);
260 aValue = aTable->value(step, 3);
261 aCoordPoint.push_back(aValue.myDouble);
263 aCoordPoints.push_back(aCoordPoint);
266 std::list<GeomPointPtr> aPoints;
267 std::list<std::vector<double>>::const_iterator anItCoordPoints = aCoordPoints.begin();
269 for (; anItCoordPoints!=aCoordPoints.end(); ++anItCoordPoints) {
271 GeomVertexPtr aVertex = GeomAlgoAPI_PointBuilder::vertex((*anItCoordPoints)[0],
272 (*anItCoordPoints)[1],
273 (*anItCoordPoints)[2]);
274 aPoints.push_back(aVertex->point());
277 // test if some points are identical
278 std::list<GeomPointPtr>::const_iterator anItPoint1 = aPoints.begin();
279 std::list<GeomPointPtr>::const_iterator anItPoint2;
280 for(; anItPoint1 != aPoints.end(); ++ anItPoint1) {
281 anItPoint2 = anItPoint1;
283 for(; anItPoint2 != aPoints.end(); ++ anItPoint2)
284 if ((*anItPoint2)->isEqual(*anItPoint1)) {
285 setError("Error: Several points are identical");
290 // Create curve from points
292 GeomAlgoAPI_CurveBuilder::edge(aPoints, false, false,GeomDirPtr(),GeomDirPtr());
294 setError("Error: Result curve is empty.");
298 ResultBodyPtr aResultBody = document()->createBody(data());
300 aResultBody->store(anEdge);
301 int aVertexIndex = 1;
302 for (GeomAPI_ShapeExplorer anExp(anEdge, GeomAPI_Shape::VERTEX); anExp.more(); anExp.next()) {
303 std::string aVertexName = "Vertex_" + std::to_string((long long)aVertexIndex);
304 aResultBody->generated(anExp.current(), aVertexName);
307 setResult(aResultBody);
311 //=================================================================================================
312 void BuildPlugin_Interpolation::evaluate(std::string& theError)
314 FeaturePtr aMyPtr = std::dynamic_pointer_cast<ModelAPI_Feature>(data()->owner());
315 std::shared_ptr<ModelAPI_BuildEvalMessage> aProcessMessage =
316 ModelAPI_BuildEvalMessage::send(aMyPtr, this);
318 if (aProcessMessage->isProcessed()) {
319 theError = aProcessMessage->error();
321 const std::list<ResultParameterPtr>& aParamsList = aProcessMessage->params();
322 //store the list of parameters to store if changed
323 AttributeRefListPtr aParams = reflist(ARGUMENTS_ID());
325 std::list<ResultParameterPtr>::const_iterator aNewIter = aParamsList.begin();
326 for (; aNewIter != aParamsList.end(); aNewIter++) {
327 aParams->append(*aNewIter);
329 } else { // error: python interpreter is not active
330 theError = "Python interpreter is not available";