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>
37 #include <GeomAlgoAPI_ShapeTools.h>
42 FeaturesPlugin_Measurement::FeaturesPlugin_Measurement()
46 void FeaturesPlugin_Measurement::initAttributes()
48 data()->addAttribute(FeaturesPlugin_Measurement::MEASURE_KIND(),
49 ModelAPI_AttributeString::typeId());
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());
66 void FeaturesPlugin_Measurement::execute()
70 void FeaturesPlugin_Measurement::attributeChanged(const std::string& theID)
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);
84 else if (theID != RESULT_ID()) {
85 std::string aKind = string(MEASURE_KIND())->value();
86 if (aKind == MEASURE_LENGTH())
88 else if (aKind == MEASURE_DISTANCE())
90 else if (aKind == MEASURE_RADIUS())
92 else if (aKind == MEASURE_ANGLE())
97 void FeaturesPlugin_Measurement::computeLength()
99 AttributeSelectionPtr aSelectedFeature = selection(EDGE_FOR_LENGTH_ID());
103 if (aSelectedFeature && aSelectedFeature->isInitialized()) {
104 aShape = aSelectedFeature->value();
105 if (!aShape && aSelectedFeature->context())
106 aShape = aSelectedFeature->context()->shape();
108 if (aShape && aShape->isEdge())
109 anEdge = GeomEdgePtr(new GeomAPI_Edge(aShape));
111 string(RESULT_ID())->setValue("");
115 std::ostringstream anOutput;
116 anOutput << "Length = " << std::setprecision(10) << anEdge->length();
117 string(RESULT_ID())->setValue(anOutput.str());
119 AttributeDoubleArrayPtr aValues =
120 std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
122 aValues->setValue(0, anEdge->length());
125 void FeaturesPlugin_Measurement::computeDistance()
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();
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();
143 if (!aShape1 || !aShape2) {
144 string(RESULT_ID())->setValue("");
148 double aDistance = GeomAlgoAPI_ShapeTools::minimalDistance(aShape1, aShape2);
150 std::ostringstream anOutput;
151 anOutput << "Distance = " << std::setprecision(10) << aDistance;
152 string(RESULT_ID())->setValue(anOutput.str());
154 AttributeDoubleArrayPtr aValues =
155 std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
157 aValues->setValue(0, aDistance);
160 void FeaturesPlugin_Measurement::computeRadius()
162 AttributeSelectionPtr aSelectedFeature = selection(CIRCULAR_OBJECT_ID());
165 if (aSelectedFeature && aSelectedFeature->isInitialized()) {
166 aShape = aSelectedFeature->value();
167 if (!aShape && aSelectedFeature->context())
168 aShape = aSelectedFeature->context()->shape();
171 double aRadius = -1.0;
173 if (aShape->isEdge()) {
174 GeomEdgePtr anEdge(new GeomAPI_Edge(aShape));
175 if (anEdge->isCircle() || anEdge->isArc()) {
176 aRadius = anEdge->circle()->radius();
178 } else if (aShape->isFace()) {
179 GeomFacePtr aFace(new GeomAPI_Face(aShape));
180 aRadius = GeomAlgoAPI_ShapeTools::radius(aFace);
185 string(RESULT_ID())->setValue("");
189 std::ostringstream anOutput;
190 anOutput << "Radius = " << std::setprecision(10) << aRadius;
191 string(RESULT_ID())->setValue(anOutput.str());
193 AttributeDoubleArrayPtr aValues =
194 std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
196 aValues->setValue(0, aRadius);
199 void FeaturesPlugin_Measurement::computeAngle()
201 AttributeSelectionPtr aFirstFeature = selection(ANGLE_FROM_EDGE_ID());
202 GeomShapePtr aShape1;
204 if (aFirstFeature && aFirstFeature->isInitialized()) {
205 aShape1 = aFirstFeature->value();
206 if (!aShape1 && aFirstFeature->context())
207 aShape1 = aFirstFeature->context()->shape();
209 if (aShape1 && aShape1->isEdge())
210 anEdge1 = GeomEdgePtr(new GeomAPI_Edge(aShape1));
212 AttributeSelectionPtr aSecondFeature = selection(ANGLE_TO_EDGE_ID());
213 GeomShapePtr aShape2;
215 if (aSecondFeature && aSecondFeature->isInitialized()) {
216 aShape2 = aSecondFeature->value();
217 if (!aShape2 && aSecondFeature->context())
218 aShape2 = aSecondFeature->context()->shape();
220 if (aShape2 && aShape2->isEdge())
221 anEdge2 = GeomEdgePtr(new GeomAPI_Edge(aShape2));
223 if (!anEdge1 || !anEdge2) {
224 string(RESULT_ID())->setValue("");
228 GeomShapePtr anInter = anEdge1->intersect(anEdge2);
230 std::ostringstream anOutput;
231 anOutput << std::setprecision(10);
232 std::list<double> aValuesList;
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);
243 GeomAPI_ShapeIterator anIt(anInter);
244 for (int anIndex = 1; anIt.more(); anIt.next(), ++anIndex) {
245 GeomShapePtr aCurrent = anIt.current();
246 if (!aCurrent->isVertex())
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);
258 string(RESULT_ID())->setValue(anOutput.str());
260 AttributeDoubleArrayPtr aValues =
261 std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
262 aValues->setSize((int)aValuesList.size());
264 for (std::list<double>::iterator anIt = aValuesList.begin(); anIt != aValuesList.end(); ++anIt)
265 aValues->setValue(anIndex++, *anIt);