]> SALOME platform Git repositories - modules/shaper.git/blob - src/FeaturesPlugin/FeaturesPlugin_Measurement.cpp
Salome HOME
Issue #2551: clear Measurement when selection lost
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_Measurement.cpp
1 // Copyright (C) 2018-20xx  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 //
20
21 #include "FeaturesPlugin_Measurement.h"
22
23 #include <ModelAPI_AttributeDoubleArray.h>
24 #include <ModelAPI_AttributeSelection.h>
25 #include <ModelAPI_AttributeString.h>
26 #include <ModelAPI_Data.h>
27 #include <ModelAPI_Session.h>
28
29 #include <GeomAPI_Angle.h>
30 #include <GeomAPI_Circ.h>
31 #include <GeomAPI_Edge.h>
32 #include <GeomAPI_Face.h>
33 #include <GeomAPI_Pnt.h>
34 #include <GeomAPI_Shape.h>
35 #include <GeomAPI_ShapeIterator.h>
36
37 #include <GeomAlgoAPI_ShapeTools.h>
38
39 #include <iomanip>
40 #include <sstream>
41
42 FeaturesPlugin_Measurement::FeaturesPlugin_Measurement()
43 {
44 }
45
46 void FeaturesPlugin_Measurement::initAttributes()
47 {
48   data()->addAttribute(FeaturesPlugin_Measurement::MEASURE_KIND(),
49                        ModelAPI_AttributeString::typeId());
50
51   // attribute for length
52   data()->addAttribute(EDGE_FOR_LENGTH_ID(), ModelAPI_AttributeSelection::typeId());
53   // attributes for distance
54   data()->addAttribute(DISTANCE_FROM_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
55   data()->addAttribute(DISTANCE_TO_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
56   // attribute for radius
57   data()->addAttribute(CIRCULAR_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
58   // attribute for angle
59   data()->addAttribute(ANGLE_FROM_EDGE_ID(), ModelAPI_AttributeSelection::typeId());
60   data()->addAttribute(ANGLE_TO_EDGE_ID(), ModelAPI_AttributeSelection::typeId());
61   // attribute for result message and values
62   data()->addAttribute(RESULT_ID(), ModelAPI_AttributeString::typeId());
63   data()->addAttribute(RESULT_VALUES_ID(), ModelAPI_AttributeDoubleArray::typeId());
64 }
65
66 void FeaturesPlugin_Measurement::execute()
67 {
68 }
69
70 void FeaturesPlugin_Measurement::attributeChanged(const std::string& theID)
71 {
72   if (theID == MEASURE_KIND()) {
73     // clear selected objects
74     selection(EDGE_FOR_LENGTH_ID())->reset();
75     selection(DISTANCE_FROM_OBJECT_ID())->reset();
76     selection(DISTANCE_TO_OBJECT_ID())->reset();
77     selection(CIRCULAR_OBJECT_ID())->reset();
78     selection(ANGLE_FROM_EDGE_ID())->reset();
79     selection(ANGLE_TO_EDGE_ID())->reset();
80     string(RESULT_ID())->setValue("");
81     std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(
82         attribute(RESULT_VALUES_ID()))->setSize(0);
83   }
84   else if (theID != RESULT_ID()) {
85     std::string aKind = string(MEASURE_KIND())->value();
86     if (aKind == MEASURE_LENGTH())
87       computeLength();
88     else if (aKind == MEASURE_DISTANCE())
89       computeDistance();
90     else if (aKind == MEASURE_RADIUS())
91       computeRadius();
92     else if (aKind == MEASURE_ANGLE())
93       computeAngle();
94   }
95 }
96
97 void FeaturesPlugin_Measurement::computeLength()
98 {
99   AttributeSelectionPtr aSelectedFeature = selection(EDGE_FOR_LENGTH_ID());
100
101   GeomShapePtr aShape;
102   GeomEdgePtr anEdge;
103   if (aSelectedFeature && aSelectedFeature->isInitialized()) {
104     aShape = aSelectedFeature->value();
105     if (!aShape && aSelectedFeature->context())
106       aShape = aSelectedFeature->context()->shape();
107   }
108   if (aShape && aShape->isEdge())
109     anEdge = GeomEdgePtr(new GeomAPI_Edge(aShape));
110   if (!anEdge) {
111     string(RESULT_ID())->setValue("");
112     return;
113   }
114
115   std::ostringstream anOutput;
116   anOutput << "Length = " << std::setprecision(10) << anEdge->length();
117   string(RESULT_ID())->setValue(anOutput.str());
118
119   AttributeDoubleArrayPtr aValues =
120       std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
121   aValues->setSize(1);
122   aValues->setValue(0, anEdge->length());
123 }
124
125 void FeaturesPlugin_Measurement::computeDistance()
126 {
127   AttributeSelectionPtr aFirstFeature = selection(DISTANCE_FROM_OBJECT_ID());
128   GeomShapePtr aShape1;
129   if (aFirstFeature && aFirstFeature->isInitialized()) {
130     aShape1 = aFirstFeature->value();
131     if (!aShape1 && aFirstFeature->context())
132       aShape1 = aFirstFeature->context()->shape();
133   }
134
135   AttributeSelectionPtr aSecondFeature = selection(DISTANCE_TO_OBJECT_ID());
136   GeomShapePtr aShape2;
137   if (aSecondFeature && aSecondFeature->isInitialized()) {
138     aShape2 = aSecondFeature->value();
139     if (!aShape2 && aSecondFeature->context())
140       aShape2 = aSecondFeature->context()->shape();
141   }
142
143   if (!aShape1 || !aShape2) {
144     string(RESULT_ID())->setValue("");
145     return;
146   }
147
148   double aDistance = GeomAlgoAPI_ShapeTools::minimalDistance(aShape1, aShape2);
149
150   std::ostringstream anOutput;
151   anOutput << "Distance = " << std::setprecision(10) << aDistance;
152   string(RESULT_ID())->setValue(anOutput.str());
153
154   AttributeDoubleArrayPtr aValues =
155       std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
156   aValues->setSize(1);
157   aValues->setValue(0, aDistance);
158 }
159
160 void FeaturesPlugin_Measurement::computeRadius()
161 {
162   AttributeSelectionPtr aSelectedFeature = selection(CIRCULAR_OBJECT_ID());
163
164   GeomShapePtr aShape;
165   if (aSelectedFeature && aSelectedFeature->isInitialized()) {
166     aShape = aSelectedFeature->value();
167     if (!aShape && aSelectedFeature->context())
168       aShape = aSelectedFeature->context()->shape();
169   }
170
171   double aRadius = -1.0;
172   if (aShape) {
173     if (aShape->isEdge()) {
174       GeomEdgePtr anEdge(new GeomAPI_Edge(aShape));
175       if (anEdge->isCircle() || anEdge->isArc()) {
176         aRadius = anEdge->circle()->radius();
177       }
178     } else if (aShape->isFace()) {
179       GeomFacePtr aFace(new GeomAPI_Face(aShape));
180       aRadius = GeomAlgoAPI_ShapeTools::radius(aFace);
181     }
182   }
183
184   if (aRadius < 0.0) {
185     string(RESULT_ID())->setValue("");
186     return;
187   }
188
189   std::ostringstream anOutput;
190   anOutput << "Radius = " << std::setprecision(10) << aRadius;
191   string(RESULT_ID())->setValue(anOutput.str());
192
193   AttributeDoubleArrayPtr aValues =
194       std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
195   aValues->setSize(1);
196   aValues->setValue(0, aRadius);
197 }
198
199 void FeaturesPlugin_Measurement::computeAngle()
200 {
201   AttributeSelectionPtr aFirstFeature = selection(ANGLE_FROM_EDGE_ID());
202   GeomShapePtr aShape1;
203   GeomEdgePtr anEdge1;
204   if (aFirstFeature && aFirstFeature->isInitialized()) {
205     aShape1 = aFirstFeature->value();
206     if (!aShape1 && aFirstFeature->context())
207       aShape1 = aFirstFeature->context()->shape();
208   }
209   if (aShape1 && aShape1->isEdge())
210     anEdge1 = GeomEdgePtr(new GeomAPI_Edge(aShape1));
211
212   AttributeSelectionPtr aSecondFeature = selection(ANGLE_TO_EDGE_ID());
213   GeomShapePtr aShape2;
214   GeomEdgePtr anEdge2;
215   if (aSecondFeature && aSecondFeature->isInitialized()) {
216     aShape2 = aSecondFeature->value();
217     if (!aShape2 && aSecondFeature->context())
218       aShape2 = aSecondFeature->context()->shape();
219   }
220   if (aShape2 && aShape2->isEdge())
221     anEdge2 = GeomEdgePtr(new GeomAPI_Edge(aShape2));
222
223   if (!anEdge1 || !anEdge2) {
224     string(RESULT_ID())->setValue("");
225     return;
226   }
227
228   GeomShapePtr anInter = anEdge1->intersect(anEdge2);
229
230   std::ostringstream anOutput;
231   anOutput << std::setprecision(10);
232   std::list<double> aValuesList;
233   if (anInter) {
234     if (anInter->isVertex()) {
235       std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(anInter));
236       std::shared_ptr<GeomAPI_Angle> anAngle(
237           new GeomAPI_Angle(anEdge1, anEdge2, aVertex->point()));
238       double anAngleValue = anAngle->angleDegree();
239       anOutput << "Angle = " << anAngleValue << std::endl;
240       aValuesList.push_back(anAngleValue);
241     }
242     else {
243       GeomAPI_ShapeIterator anIt(anInter);
244       for (int anIndex = 1; anIt.more(); anIt.next(), ++anIndex) {
245         GeomShapePtr aCurrent = anIt.current();
246         if (!aCurrent->isVertex())
247           continue;
248         std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aCurrent));
249         std::shared_ptr<GeomAPI_Angle> anAngle(
250             new GeomAPI_Angle(anEdge1, anEdge2, aVertex->point()));
251         double anAngleValue = anAngle->angleDegree();
252         anOutput << "Angle" << anIndex << " = " << anAngleValue << std::endl;
253         aValuesList.push_back(anAngleValue);
254       }
255     }
256   }
257
258   string(RESULT_ID())->setValue(anOutput.str());
259
260   AttributeDoubleArrayPtr aValues =
261       std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
262   aValues->setSize((int)aValuesList.size());
263   int anIndex = 0;
264   for (std::list<double>::iterator anIt = aValuesList.begin(); anIt != aValuesList.end(); ++anIt)
265     aValues->setValue(anIndex++, *anIt);
266 }