1 // Copyright (C) 2018-20xx 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
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include "FeaturesPlugin_Measurement.h"
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>
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 #include <GeomAPI_Vertex.h>
38 #include <GeomAlgoAPI_ShapeTools.h>
43 FeaturesPlugin_Measurement::FeaturesPlugin_Measurement()
47 void FeaturesPlugin_Measurement::initAttributes()
49 data()->addAttribute(FeaturesPlugin_Measurement::MEASURE_KIND(),
50 ModelAPI_AttributeString::typeId());
52 // attribute for length
53 data()->addAttribute(EDGE_FOR_LENGTH_ID(), ModelAPI_AttributeSelection::typeId());
54 // attributes for distance
55 data()->addAttribute(DISTANCE_FROM_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
56 data()->addAttribute(DISTANCE_TO_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
57 // attribute for radius
58 data()->addAttribute(CIRCULAR_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
59 // attributes for angle
60 data()->addAttribute(ANGLE_FROM_EDGE_ID(), ModelAPI_AttributeSelection::typeId());
61 data()->addAttribute(ANGLE_TO_EDGE_ID(), ModelAPI_AttributeSelection::typeId());
62 // attributes for angle by 3 points
63 data()->addAttribute(ANGLE_POINT1_ID(), ModelAPI_AttributeSelection::typeId());
64 data()->addAttribute(ANGLE_POINT2_ID(), ModelAPI_AttributeSelection::typeId());
65 data()->addAttribute(ANGLE_POINT3_ID(), ModelAPI_AttributeSelection::typeId());
66 // attributes for result message and values
67 data()->addAttribute(RESULT_ID(), ModelAPI_AttributeString::typeId());
68 data()->addAttribute(RESULT_VALUES_ID(), ModelAPI_AttributeDoubleArray::typeId());
71 void FeaturesPlugin_Measurement::execute()
75 void FeaturesPlugin_Measurement::attributeChanged(const std::string& theID)
77 if (theID == MEASURE_KIND()) {
79 string(RESULT_ID())->setValue("");
80 std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(
81 attribute(RESULT_VALUES_ID()))->setSize(0);
83 if (theID != RESULT_ID()) {
84 std::string aKind = string(MEASURE_KIND())->value();
85 if (aKind == MEASURE_LENGTH())
87 else if (aKind == MEASURE_DISTANCE())
89 else if (aKind == MEASURE_RADIUS())
91 else if (aKind == MEASURE_ANGLE())
93 else if (aKind == MEASURE_ANGLE_POINTS())
94 computeAngleByPoints();
98 void FeaturesPlugin_Measurement::computeLength()
100 AttributeSelectionPtr aSelectedFeature = selection(EDGE_FOR_LENGTH_ID());
104 if (aSelectedFeature && aSelectedFeature->isInitialized()) {
105 aShape = aSelectedFeature->value();
106 if (!aShape && aSelectedFeature->context())
107 aShape = aSelectedFeature->context()->shape();
109 if (aShape && aShape->isEdge())
110 anEdge = GeomEdgePtr(new GeomAPI_Edge(aShape));
112 string(RESULT_ID())->setValue("");
116 std::ostringstream anOutput;
117 anOutput << "Length = " << std::setprecision(10) << anEdge->length();
118 string(RESULT_ID())->setValue(anOutput.str());
120 AttributeDoubleArrayPtr aValues =
121 std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
123 aValues->setValue(0, anEdge->length());
126 void FeaturesPlugin_Measurement::computeDistance()
128 AttributeSelectionPtr aFirstFeature = selection(DISTANCE_FROM_OBJECT_ID());
129 GeomShapePtr aShape1;
130 if (aFirstFeature && aFirstFeature->isInitialized()) {
131 aShape1 = aFirstFeature->value();
132 if (!aShape1 && aFirstFeature->context())
133 aShape1 = aFirstFeature->context()->shape();
136 AttributeSelectionPtr aSecondFeature = selection(DISTANCE_TO_OBJECT_ID());
137 GeomShapePtr aShape2;
138 if (aSecondFeature && aSecondFeature->isInitialized()) {
139 aShape2 = aSecondFeature->value();
140 if (!aShape2 && aSecondFeature->context())
141 aShape2 = aSecondFeature->context()->shape();
144 if (!aShape1 || !aShape2) {
145 string(RESULT_ID())->setValue("");
149 double aDistance = GeomAlgoAPI_ShapeTools::minimalDistance(aShape1, aShape2);
151 std::ostringstream anOutput;
152 anOutput << "Distance = " << std::setprecision(10) << aDistance;
153 string(RESULT_ID())->setValue(anOutput.str());
155 AttributeDoubleArrayPtr aValues =
156 std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
158 aValues->setValue(0, aDistance);
161 void FeaturesPlugin_Measurement::computeRadius()
163 AttributeSelectionPtr aSelectedFeature = selection(CIRCULAR_OBJECT_ID());
166 if (aSelectedFeature && aSelectedFeature->isInitialized()) {
167 aShape = aSelectedFeature->value();
168 if (!aShape && aSelectedFeature->context())
169 aShape = aSelectedFeature->context()->shape();
172 double aRadius = -1.0;
174 if (aShape->isEdge()) {
175 GeomEdgePtr anEdge(new GeomAPI_Edge(aShape));
176 if (anEdge->isCircle() || anEdge->isArc()) {
177 aRadius = anEdge->circle()->radius();
179 } else if (aShape->isFace()) {
180 GeomFacePtr aFace(new GeomAPI_Face(aShape));
181 aRadius = GeomAlgoAPI_ShapeTools::radius(aFace);
186 string(RESULT_ID())->setValue("");
190 std::ostringstream anOutput;
191 anOutput << "Radius = " << std::setprecision(10) << aRadius;
192 string(RESULT_ID())->setValue(anOutput.str());
194 AttributeDoubleArrayPtr aValues =
195 std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
197 aValues->setValue(0, aRadius);
200 void FeaturesPlugin_Measurement::computeAngle()
202 AttributeSelectionPtr aFirstFeature = selection(ANGLE_FROM_EDGE_ID());
203 GeomShapePtr aShape1;
205 if (aFirstFeature && aFirstFeature->isInitialized()) {
206 aShape1 = aFirstFeature->value();
207 if (!aShape1 && aFirstFeature->context())
208 aShape1 = aFirstFeature->context()->shape();
210 if (aShape1 && aShape1->isEdge())
211 anEdge1 = GeomEdgePtr(new GeomAPI_Edge(aShape1));
213 AttributeSelectionPtr aSecondFeature = selection(ANGLE_TO_EDGE_ID());
214 GeomShapePtr aShape2;
216 if (aSecondFeature && aSecondFeature->isInitialized()) {
217 aShape2 = aSecondFeature->value();
218 if (!aShape2 && aSecondFeature->context())
219 aShape2 = aSecondFeature->context()->shape();
221 if (aShape2 && aShape2->isEdge())
222 anEdge2 = GeomEdgePtr(new GeomAPI_Edge(aShape2));
224 if (!anEdge1 || !anEdge2) {
225 string(RESULT_ID())->setValue("");
229 GeomShapePtr anInter = anEdge1->intersect(anEdge2);
231 std::ostringstream anOutput;
232 anOutput << std::setprecision(10);
233 std::list<double> aValuesList;
235 if (anInter->isVertex()) {
236 std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(anInter));
237 std::shared_ptr<GeomAPI_Angle> anAngle(
238 new GeomAPI_Angle(anEdge1, anEdge2, aVertex->point()));
239 double anAngleValue = anAngle->angleDegree();
240 anOutput << "Angle = " << std::setprecision(10) << anAngleValue << std::endl;
241 aValuesList.push_back(anAngleValue);
244 GeomAPI_ShapeIterator anIt(anInter);
245 for (int anIndex = 1; anIt.more(); anIt.next(), ++anIndex) {
246 GeomShapePtr aCurrent = anIt.current();
247 if (!aCurrent->isVertex())
249 std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aCurrent));
250 std::shared_ptr<GeomAPI_Angle> anAngle(
251 new GeomAPI_Angle(anEdge1, anEdge2, aVertex->point()));
252 double anAngleValue = anAngle->angleDegree();
253 anOutput << "Angle" << anIndex << " = "
254 << std::setprecision(10) << anAngleValue << std::endl;
255 aValuesList.push_back(anAngleValue);
260 string(RESULT_ID())->setValue(anOutput.str());
262 AttributeDoubleArrayPtr aValues =
263 std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
264 aValues->setSize((int)aValuesList.size());
266 for (std::list<double>::iterator anIt = aValuesList.begin(); anIt != aValuesList.end(); ++anIt)
267 aValues->setValue(anIndex++, *anIt);
270 static GeomVertexPtr selectionToVertex(const AttributeSelectionPtr& aSelection)
273 GeomVertexPtr aVertex;
274 if (aSelection && aSelection->isInitialized()) {
275 aShape = aSelection->value();
276 if (!aShape && aSelection->context())
277 aShape = aSelection->context()->shape();
279 if (aShape && aShape->isVertex())
280 aVertex = GeomVertexPtr(new GeomAPI_Vertex(aShape));
284 void FeaturesPlugin_Measurement::computeAngleByPoints()
286 GeomVertexPtr aVertex1 = selectionToVertex(selection(ANGLE_POINT1_ID()));
287 GeomVertexPtr aVertex2 = selectionToVertex(selection(ANGLE_POINT2_ID()));
288 GeomVertexPtr aVertex3 = selectionToVertex(selection(ANGLE_POINT3_ID()));
290 if (!aVertex1 || !aVertex2 || ! aVertex3) {
291 string(RESULT_ID())->setValue("");
295 std::shared_ptr<GeomAPI_Angle> anAngle(
296 new GeomAPI_Angle(aVertex1->point(), aVertex2->point(), aVertex3->point()));
297 double anAngleValue = anAngle->angleDegree();
299 std::ostringstream anOutput;
300 anOutput << "Angle = " << std::setprecision(10) << anAngleValue;
301 string(RESULT_ID())->setValue(anOutput.str());
303 AttributeDoubleArrayPtr aValues =
304 std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
306 aValues->setValue(0, anAngleValue);