1 // Copyright (C) 2014-2023 CEA, EDF
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()
124 double aMint = real(MINT_ID())->value();
125 double aMaxt = real(MAXT_ID())->value();
126 int aNbrStep = integer(NUMSTEP_ID())->value();
129 setError("The minimum value of the parameter must be less than maximum value !!!");
132 double aScale = (aMaxt - aMint)/aNbrStep;
133 string(VARIABLE_ID())->setValue("t");
135 tables(VALUE_ID())->setSize(aNbrStep+1,4);
136 for (int step = 0; step <= aNbrStep; step++) {
137 ModelAPI_AttributeTables::Value aVal;
138 aVal.myDouble = step * aScale + aMint;
139 tables(VALUE_ID())->setValue(aVal,step,0);
143 evaluate(outErrorMessage);
144 data()->string(EXPRESSION_ERROR_ID())->setValue(outErrorMessage);
145 if (!outErrorMessage.empty()) {
146 setError("Error: Python interpreter ");
151 //=================================================================================================
152 static GeomDirPtr selectionToDir(const AttributeSelectionPtr& theSelection)
157 GeomShapePtr aShape = theSelection->value();
158 if (!aShape && theSelection->context()) {
159 aShape = theSelection->context()->shape();
162 if (aShape && aShape->isEdge()) {
163 anEdge = GeomEdgePtr(new GeomAPI_Edge(aShape));
166 if (anEdge && anEdge->isLine()) {
167 aDir = anEdge->line()->direction();
173 //=================================================================================================
174 void BuildPlugin_Interpolation::execute()
176 if (string(CREATION_METHOD_ID())->value() == CREATION_METHOD_BY_SELECTION_ID()) {
177 // Get closed flag value
178 bool isClosed = boolean(CLOSED_ID())->value();
180 // Get reorder flag value
181 bool isToReorder = boolean(REORDER_ID())->value();
183 // Get use tangents flag value
184 bool isToUseTangents = isClosed? false : (!string(USE_TANGENTS_ID())->value().empty());
186 // Get tangent for start and end points
187 GeomDirPtr aDirStart, aDirEnd;
188 if (isToUseTangents) {
189 aDirStart = selectionToDir(selection(TANGENT_START_ID()));
190 aDirEnd = selectionToDir(selection(TANGENT_END_ID()));
193 // Get base objects list.
194 AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID());
197 std::list<GeomPointPtr> aPoints;
198 std::set<GeomShapePtr> aContexts;
199 for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
200 AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
202 GeomShapePtr aContextShape = aSelection->context()->shape();
203 aContexts.insert(aContextShape);
205 GeomShapePtr aShape = aSelection->value();
207 aShape = aContextShape;
210 GeomPointPtr aPoint = GeomAlgoAPI_PointBuilder::point(aShape);
211 aPoints.push_back(aPoint);
214 // Create curve from points
216 GeomAlgoAPI_CurveBuilder::edge(aPoints, isClosed, isToReorder, aDirStart, aDirEnd);
218 setError("Error: Result curve is empty.");
223 ResultBodyPtr aResultBody = document()->createBody(data());
224 std::set<GeomShapePtr>::const_iterator aContextIt = aContexts.begin();
225 for (; aContextIt != aContexts.end(); aContextIt++) {
226 aResultBody->storeModified(*aContextIt, anEdge, aContextIt == aContexts.begin());
228 int aVertexIndex = 1;
229 for (GeomAPI_ShapeExplorer anExp(anEdge, GeomAPI_Shape::VERTEX); anExp.more(); anExp.next()) {
230 std::string aVertexName = "Vertex_" + std::to_string((long long)aVertexIndex);
231 aResultBody->generated(anExp.current(), aVertexName);
234 setResult(aResultBody);
237 if (string(XT_ID())->value() == ""
238 ||string(YT_ID())->value() == ""
239 ||string(ZT_ID())->value() == ""
240 ||tables(VALUE_ID())->rows()== 0)
243 bool aWasBlocked = data()->blockSendAttributeUpdated(true);
245 data()->blockSendAttributeUpdated(aWasBlocked, false);
247 AttributeTablesPtr aTable = tables(VALUE_ID());
248 std::list<std::vector<double>> aCoordPoints;
249 for (int step = 0; step < aTable->rows(); step++) {
250 std::vector<double> aCoordPoint;
251 ModelAPI_AttributeTables::Value aValue;
253 aValue = aTable->value(step, 1);
254 aCoordPoint.push_back(aValue.myDouble);
256 aValue = aTable->value(step, 2);
257 aCoordPoint.push_back(aValue.myDouble);
259 aValue = aTable->value(step, 3);
260 aCoordPoint.push_back(aValue.myDouble);
262 aCoordPoints.push_back(aCoordPoint);
265 std::list<GeomPointPtr> aPoints;
266 std::list<std::vector<double>>::const_iterator anItCoordPoints = aCoordPoints.begin();
268 for (; anItCoordPoints!=aCoordPoints.end(); ++anItCoordPoints) {
270 GeomVertexPtr aVertex = GeomAlgoAPI_PointBuilder::vertex((*anItCoordPoints)[0],
271 (*anItCoordPoints)[1],
272 (*anItCoordPoints)[2]);
273 aPoints.push_back(aVertex->point());
276 // test if some points are identical
277 std::list<GeomPointPtr>::const_iterator anItPoint1 = aPoints.begin();
278 std::list<GeomPointPtr>::const_iterator anItPoint2;
279 for(; anItPoint1 != aPoints.end(); ++ anItPoint1) {
280 anItPoint2 = anItPoint1;
282 for(; anItPoint2 != aPoints.end(); ++ anItPoint2)
283 if ((*anItPoint2)->isEqual(*anItPoint1)) {
284 setError("Error: Several points are identical");
289 // Create curve from points
291 GeomAlgoAPI_CurveBuilder::edge(aPoints, false, false,GeomDirPtr(),GeomDirPtr());
293 setError("Error: Result curve is empty.");
297 ResultBodyPtr aResultBody = document()->createBody(data());
299 aResultBody->store(anEdge);
300 int aVertexIndex = 1;
301 for (GeomAPI_ShapeExplorer anExp(anEdge, GeomAPI_Shape::VERTEX); anExp.more(); anExp.next()) {
302 std::string aVertexName = "Vertex_" + std::to_string((long long)aVertexIndex);
303 aResultBody->generated(anExp.current(), aVertexName);
306 setResult(aResultBody);
310 //=================================================================================================
311 void BuildPlugin_Interpolation::evaluate(std::string& theError)
313 FeaturePtr aMyPtr = std::dynamic_pointer_cast<ModelAPI_Feature>(data()->owner());
314 std::shared_ptr<ModelAPI_BuildEvalMessage> aProcessMessage =
315 ModelAPI_BuildEvalMessage::send(aMyPtr, this);
317 if (aProcessMessage->isProcessed()) {
318 theError = aProcessMessage->error();
320 const std::list<ResultParameterPtr>& aParamsList = aProcessMessage->params();
321 //store the list of parameters to store if changed
322 AttributeRefListPtr aParams = reflist(ARGUMENTS_ID());
324 std::list<ResultParameterPtr>::const_iterator aNewIter = aParamsList.begin();
325 for (; aNewIter != aParamsList.end(); aNewIter++) {
326 aParams->append(*aNewIter);
328 } else { // error: python interpreter is not active
329 theError = "Python interpreter is not available";