Salome HOME
Fix for the issue #2693 : groups in error after loading dump (3-holes plate)
[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 #include <GeomAPI_Vertex.h>
37
38 #include <GeomAlgoAPI_ShapeTools.h>
39
40 #include <Config_PropManager.h>
41
42 #include <TopoDS.hxx>
43 #include <TopoDS_Edge.hxx>
44 #include <TopoDS_Shape.hxx>
45 #include <AIS_LengthDimension.hxx>
46 #include <AIS_RadiusDimension.hxx>
47 #include <AIS_AngleDimension.hxx>
48 #include <BRepExtrema_DistShapeShape.hxx>
49
50 #include <iomanip>
51 #include <sstream>
52
53 FeaturesPlugin_Measurement::FeaturesPlugin_Measurement() : mySceenScale(1)
54 {
55 }
56
57 void FeaturesPlugin_Measurement::initAttributes()
58 {
59   data()->addAttribute(FeaturesPlugin_Measurement::MEASURE_KIND(),
60                        ModelAPI_AttributeString::typeId());
61
62   // attribute for length
63   data()->addAttribute(EDGE_FOR_LENGTH_ID(), ModelAPI_AttributeSelection::typeId());
64   // attributes for distance
65   data()->addAttribute(DISTANCE_FROM_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
66   data()->addAttribute(DISTANCE_TO_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
67   // attribute for radius
68   data()->addAttribute(CIRCULAR_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
69   // attributes for angle
70   data()->addAttribute(ANGLE_FROM_EDGE_ID(), ModelAPI_AttributeSelection::typeId());
71   data()->addAttribute(ANGLE_TO_EDGE_ID(), ModelAPI_AttributeSelection::typeId());
72   // attributes for angle by 3 points
73   data()->addAttribute(ANGLE_POINT1_ID(), ModelAPI_AttributeSelection::typeId());
74   data()->addAttribute(ANGLE_POINT2_ID(), ModelAPI_AttributeSelection::typeId());
75   data()->addAttribute(ANGLE_POINT3_ID(), ModelAPI_AttributeSelection::typeId());
76   // attributes for result message and values
77   data()->addAttribute(RESULT_ID(), ModelAPI_AttributeString::typeId());
78   data()->addAttribute(RESULT_VALUES_ID(), ModelAPI_AttributeDoubleArray::typeId());
79 }
80
81 void FeaturesPlugin_Measurement::execute()
82 {
83 }
84
85 void FeaturesPlugin_Measurement::attributeChanged(const std::string& theID)
86 {
87   if (theID == MEASURE_KIND()) {
88     // clear results
89     string(RESULT_ID())->setValue("");
90     std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(
91       attribute(RESULT_VALUES_ID()))->setSize(0);
92   }
93   if (theID != RESULT_ID()) {
94     std::string aKind = string(MEASURE_KIND())->value();
95     if (aKind == MEASURE_LENGTH())
96       computeLength();
97     else if (aKind == MEASURE_DISTANCE())
98       computeDistance();
99     else if (aKind == MEASURE_RADIUS())
100       computeRadius();
101     else if (aKind == MEASURE_ANGLE())
102       computeAngle();
103     else if (aKind == MEASURE_ANGLE_POINTS())
104       computeAngleByPoints();
105   }
106 }
107
108 void FeaturesPlugin_Measurement::computeLength()
109 {
110   AttributeSelectionPtr aSelectedFeature = selection(EDGE_FOR_LENGTH_ID());
111
112   GeomShapePtr aShape;
113   GeomEdgePtr anEdge;
114   if (aSelectedFeature && aSelectedFeature->isInitialized()) {
115     aShape = aSelectedFeature->value();
116     if (!aShape && aSelectedFeature->context())
117       aShape = aSelectedFeature->context()->shape();
118   }
119   if (aShape && aShape->isEdge())
120     anEdge = GeomEdgePtr(new GeomAPI_Edge(aShape));
121   if (!anEdge) {
122     string(RESULT_ID())->setValue("");
123     return;
124   }
125
126   std::ostringstream anOutput;
127   anOutput << "Length = " << std::setprecision(10) << anEdge->length();
128   string(RESULT_ID())->setValue(anOutput.str());
129
130   AttributeDoubleArrayPtr aValues =
131       std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
132   aValues->setSize(1);
133   aValues->setValue(0, anEdge->length());
134 }
135
136 void FeaturesPlugin_Measurement::computeDistance()
137 {
138   AttributeSelectionPtr aFirstFeature = selection(DISTANCE_FROM_OBJECT_ID());
139   GeomShapePtr aShape1;
140   if (aFirstFeature && aFirstFeature->isInitialized()) {
141     aShape1 = aFirstFeature->value();
142     if (!aShape1 && aFirstFeature->context())
143       aShape1 = aFirstFeature->context()->shape();
144   }
145
146   AttributeSelectionPtr aSecondFeature = selection(DISTANCE_TO_OBJECT_ID());
147   GeomShapePtr aShape2;
148   if (aSecondFeature && aSecondFeature->isInitialized()) {
149     aShape2 = aSecondFeature->value();
150     if (!aShape2 && aSecondFeature->context())
151       aShape2 = aSecondFeature->context()->shape();
152   }
153
154   if (!aShape1 || !aShape2) {
155     string(RESULT_ID())->setValue("");
156     return;
157   }
158
159   double aDistance = GeomAlgoAPI_ShapeTools::minimalDistance(aShape1, aShape2);
160
161   std::ostringstream anOutput;
162   anOutput << "Distance = " << std::setprecision(10) << aDistance;
163   string(RESULT_ID())->setValue(anOutput.str());
164
165   AttributeDoubleArrayPtr aValues =
166       std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
167   aValues->setSize(1);
168   aValues->setValue(0, aDistance);
169 }
170
171 void FeaturesPlugin_Measurement::computeRadius()
172 {
173   AttributeSelectionPtr aSelectedFeature = selection(CIRCULAR_OBJECT_ID());
174
175   GeomShapePtr aShape;
176   if (aSelectedFeature && aSelectedFeature->isInitialized()) {
177     aShape = aSelectedFeature->value();
178     if (!aShape && aSelectedFeature->context())
179       aShape = aSelectedFeature->context()->shape();
180   }
181
182   double aRadius = -1.0;
183   if (aShape) {
184     if (aShape->isEdge()) {
185       GeomEdgePtr anEdge(new GeomAPI_Edge(aShape));
186       if (anEdge->isCircle() || anEdge->isArc()) {
187         aRadius = anEdge->circle()->radius();
188       }
189     } else if (aShape->isFace()) {
190       GeomFacePtr aFace(new GeomAPI_Face(aShape));
191       aRadius = GeomAlgoAPI_ShapeTools::radius(aFace);
192     }
193   }
194
195   if (aRadius < 0.0) {
196     string(RESULT_ID())->setValue("");
197     return;
198   }
199
200   std::ostringstream anOutput;
201   anOutput << "Radius = " << std::setprecision(10) << aRadius;
202   string(RESULT_ID())->setValue(anOutput.str());
203
204   AttributeDoubleArrayPtr aValues =
205       std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
206   aValues->setSize(1);
207   aValues->setValue(0, aRadius);
208 }
209
210 void FeaturesPlugin_Measurement::computeAngle()
211 {
212   AttributeSelectionPtr aFirstFeature = selection(ANGLE_FROM_EDGE_ID());
213   GeomShapePtr aShape1;
214   GeomEdgePtr anEdge1;
215   if (aFirstFeature && aFirstFeature->isInitialized()) {
216     aShape1 = aFirstFeature->value();
217     if (!aShape1 && aFirstFeature->context())
218       aShape1 = aFirstFeature->context()->shape();
219   }
220   if (aShape1 && aShape1->isEdge())
221     anEdge1 = GeomEdgePtr(new GeomAPI_Edge(aShape1));
222
223   AttributeSelectionPtr aSecondFeature = selection(ANGLE_TO_EDGE_ID());
224   GeomShapePtr aShape2;
225   GeomEdgePtr anEdge2;
226   if (aSecondFeature && aSecondFeature->isInitialized()) {
227     aShape2 = aSecondFeature->value();
228     if (!aShape2 && aSecondFeature->context())
229       aShape2 = aSecondFeature->context()->shape();
230   }
231   if (aShape2 && aShape2->isEdge())
232     anEdge2 = GeomEdgePtr(new GeomAPI_Edge(aShape2));
233
234   if (!anEdge1 || !anEdge2) {
235     string(RESULT_ID())->setValue("");
236     return;
237   }
238
239   GeomShapePtr anInter = anEdge1->intersect(anEdge2);
240
241   std::ostringstream anOutput;
242   anOutput << std::setprecision(10);
243   std::list<double> aValuesList;
244   if (anInter) {
245     if (anInter->isVertex()) {
246       std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(anInter));
247       std::shared_ptr<GeomAPI_Angle> anAngle(
248           new GeomAPI_Angle(anEdge1, anEdge2, aVertex->point()));
249       double anAngleValue = anAngle->angleDegree();
250       anOutput << "Angle = " << std::setprecision(10) << anAngleValue << std::endl;
251       aValuesList.push_back(anAngleValue);
252     }
253     else {
254       GeomAPI_ShapeIterator anIt(anInter);
255       for (int anIndex = 1; anIt.more(); anIt.next(), ++anIndex) {
256         GeomShapePtr aCurrent = anIt.current();
257         if (!aCurrent->isVertex())
258           continue;
259         std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aCurrent));
260         std::shared_ptr<GeomAPI_Angle> anAngle(
261             new GeomAPI_Angle(anEdge1, anEdge2, aVertex->point()));
262         double anAngleValue = anAngle->angleDegree();
263         anOutput << "Angle" << anIndex << " = "
264                  << std::setprecision(10) << anAngleValue << std::endl;
265         aValuesList.push_back(anAngleValue);
266       }
267     }
268   }
269
270   string(RESULT_ID())->setValue(anOutput.str());
271
272   AttributeDoubleArrayPtr aValues =
273       std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
274   aValues->setSize((int)aValuesList.size());
275   int anIndex = 0;
276   for (std::list<double>::iterator anIt = aValuesList.begin(); anIt != aValuesList.end(); ++anIt)
277     aValues->setValue(anIndex++, *anIt);
278 }
279
280 static GeomVertexPtr selectionToVertex(const AttributeSelectionPtr& aSelection)
281 {
282   GeomShapePtr aShape;
283   GeomVertexPtr aVertex;
284   if (aSelection && aSelection->isInitialized()) {
285     aShape = aSelection->value();
286     if (!aShape && aSelection->context())
287       aShape = aSelection->context()->shape();
288   }
289   if (aShape && aShape->isVertex())
290     aVertex = GeomVertexPtr(new GeomAPI_Vertex(aShape));
291   return aVertex;
292 }
293
294 void FeaturesPlugin_Measurement::computeAngleByPoints()
295 {
296   GeomVertexPtr aVertex1 = selectionToVertex(selection(ANGLE_POINT1_ID()));
297   GeomVertexPtr aVertex2 = selectionToVertex(selection(ANGLE_POINT2_ID()));
298   GeomVertexPtr aVertex3 = selectionToVertex(selection(ANGLE_POINT3_ID()));
299
300   if (!aVertex1 || !aVertex2 || ! aVertex3) {
301     string(RESULT_ID())->setValue("");
302     return;
303   }
304
305   std::shared_ptr<GeomAPI_Angle> anAngle(
306       new GeomAPI_Angle(aVertex1->point(), aVertex2->point(), aVertex3->point()));
307   double anAngleValue = anAngle->angleDegree();
308
309   std::ostringstream anOutput;
310   anOutput << "Angle = " << std::setprecision(10) << anAngleValue;
311   string(RESULT_ID())->setValue(anOutput.str());
312
313   AttributeDoubleArrayPtr aValues =
314     std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
315   aValues->setSize(1);
316   aValues->setValue(0, anAngleValue);
317 }
318
319 AISObjectPtr FeaturesPlugin_Measurement::getAISObject(AISObjectPtr thePrevious)
320 {
321   AttributeDoubleArrayPtr aValues =
322     std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(attribute(RESULT_VALUES_ID()));
323   if ((aValues->size() == 0) || (aValues->value(0) <= Precision::Confusion()))
324     return AISObjectPtr();
325
326   AISObjectPtr anAIS;
327   std::string aKind = string(MEASURE_KIND())->value();
328   if (aKind == MEASURE_LENGTH())
329     anAIS = lengthDimension(thePrevious);
330   else if (aKind == MEASURE_DISTANCE())
331     anAIS = distanceDimension(thePrevious);
332   else if (aKind == MEASURE_RADIUS())
333     anAIS = radiusDimension(thePrevious);
334   else if (aKind == MEASURE_ANGLE())
335     anAIS = angleDimension(thePrevious);
336   else if (aKind == MEASURE_ANGLE_POINTS())
337     anAIS = angleByPointsDimension(thePrevious);
338   setupDimension(anAIS);
339   return anAIS;
340 }
341
342 AISObjectPtr FeaturesPlugin_Measurement::lengthDimension(AISObjectPtr thePrevious)
343 {
344   AISObjectPtr aAISObj;
345   if (!myScreenPlane.get())
346     return aAISObj;
347
348   AttributeSelectionPtr aSelectedFeature = selection(EDGE_FOR_LENGTH_ID());
349
350   GeomShapePtr aShape;
351   GeomEdgePtr anEdge;
352   if (aSelectedFeature && aSelectedFeature->isInitialized()) {
353     aShape = aSelectedFeature->value();
354     if (!aShape && aSelectedFeature->context())
355       aShape = aSelectedFeature->context()->shape();
356   }
357   if (aShape && aShape->isEdge())
358     anEdge = GeomEdgePtr(new GeomAPI_Edge(aShape));
359   if (anEdge) {
360     TopoDS_Edge aTEdge = TopoDS::Edge(anEdge->impl<TopoDS_Shape>());
361     GeomPointPtr aPoint1 = anEdge->firstPoint();
362     GeomPointPtr aPoint2 = anEdge->lastPoint();
363
364     gp_Pnt aPnt1(aPoint1->impl<gp_Pnt>());
365     gp_Pnt aPnt2(aPoint2->impl<gp_Pnt>());
366
367     double aLength = aPnt1.Distance(aPnt2);
368     if (aLength > 0) {
369       gp_Pln aPlane = myScreenPlane->impl<gp_Pln>(); // gce_MP.Value();
370       aPlane.SetLocation(aPnt1);
371
372       gp_XYZ aNormal = aPlane.Axis().Direction().XYZ();
373       gp_XYZ aVec(aPnt2.X() - aPnt1.X(), aPnt2.Y() - aPnt1.Y(), aPnt2.Z() - aPnt1.Z());
374       double aDot = aNormal.Dot(aVec);
375       if (fabs(aDot - aLength) <= Precision::Confusion()) {
376         aPlane = gp_Pln(aPnt1, aPlane.XAxis().Direction());
377       }
378
379       Handle(AIS_LengthDimension) aDim;
380       if (thePrevious.get()) {
381         aAISObj = thePrevious;
382         Handle(AIS_InteractiveObject) aAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
383         aDim = Handle(AIS_LengthDimension)::DownCast(aAIS);
384         if (aDim.IsNull()) {
385           aDim = new AIS_LengthDimension(aTEdge, aPlane);
386           aAISObj = AISObjectPtr(new GeomAPI_AISObject());
387           aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
388         }
389         else {
390           aDim->SetMeasuredGeometry(aTEdge, aPlane);
391         }
392       }
393       else {
394         aDim = new AIS_LengthDimension(aTEdge, aPlane);
395         aAISObj = AISObjectPtr(new GeomAPI_AISObject());
396         aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
397       }
398       aDim->SetFlyout(aLength / 3.);
399     }
400   }
401   return aAISObj;
402 }
403
404 AISObjectPtr FeaturesPlugin_Measurement::distanceDimension(AISObjectPtr thePrevious)
405 {
406   AISObjectPtr aAISObj;
407   if (!myScreenPlane.get())
408     return aAISObj;
409
410   AttributeSelectionPtr aFirstFeature = selection(DISTANCE_FROM_OBJECT_ID());
411   AttributeSelectionPtr aSecondFeature = selection(DISTANCE_TO_OBJECT_ID());
412   if (aFirstFeature.get() && aSecondFeature.get()) {
413     GeomShapePtr aShape1;
414     GeomShapePtr aShape2;
415     if (aFirstFeature->isInitialized() && aSecondFeature->isInitialized()) {
416       aShape1 = aFirstFeature->value();
417       if (!aShape1 && aFirstFeature->context())
418         aShape1 = aFirstFeature->context()->shape();
419       aShape2 = aSecondFeature->value();
420       if (!aShape2 && aSecondFeature->context())
421         aShape2 = aSecondFeature->context()->shape();
422     }
423
424     if (aShape1 && aShape2) {
425       const TopoDS_Shape& aShp1 = aShape1->impl<TopoDS_Shape>();
426       const TopoDS_Shape& aShp2 = aShape2->impl<TopoDS_Shape>();
427       BRepExtrema_DistShapeShape aDist(aShp1, aShp2);
428       aDist.Perform();
429       if (aDist.IsDone()) {
430         gp_Pnt aPnt1 = aDist.PointOnShape1(1);
431         gp_Pnt aPnt2 = aDist.PointOnShape2(1);
432         double aDistance = aDist.Value();
433         if (aDistance > 0) {
434           gp_Pln aPlane = myScreenPlane->impl<gp_Pln>();
435           aPlane.SetLocation(aPnt1);
436
437           gp_XYZ aNormal = aPlane.Axis().Direction().XYZ();
438           gp_XYZ aVec(aPnt2.X() - aPnt1.X(), aPnt2.Y() - aPnt1.Y(), aPnt2.Z() - aPnt1.Z());
439           double aDot = aNormal.Dot(aVec);
440           if (fabs(aDot - aDistance) <= Precision::Confusion()) {
441             aPlane = gp_Pln(aPnt1, aPlane.XAxis().Direction());
442           }
443
444           Handle(AIS_LengthDimension) aDim;
445           if (thePrevious.get()) {
446             aAISObj = thePrevious;
447             Handle(AIS_InteractiveObject) aAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
448             aDim = Handle(AIS_LengthDimension)::DownCast(aAIS);
449             if (aDim.IsNull()) {
450               aDim = new AIS_LengthDimension(aPnt1, aPnt2, aPlane);
451               aAISObj = AISObjectPtr(new GeomAPI_AISObject());
452               aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
453             }
454             else {
455               aDim->SetMeasuredGeometry(aPnt1, aPnt2, aPlane);
456               aDim->SetFlyout(aDistance / 3.);
457             }
458           }
459           else {
460             aAISObj = AISObjectPtr(new GeomAPI_AISObject());
461             aDim = new AIS_LengthDimension(aPnt1, aPnt2, aPlane);
462             aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
463           }
464           aDim->SetFlyout(aDistance / 3.);
465         }
466       }
467     }
468   }
469   return aAISObj;
470 }
471
472 AISObjectPtr FeaturesPlugin_Measurement::radiusDimension(AISObjectPtr thePrevious)
473 {
474   AISObjectPtr aAISObj;
475   AttributeSelectionPtr aSelectedFeature = selection(CIRCULAR_OBJECT_ID());
476
477   GeomShapePtr aShape;
478   if (aSelectedFeature && aSelectedFeature->isInitialized()) {
479     aShape = aSelectedFeature->value();
480     if (!aShape && aSelectedFeature->context())
481       aShape = aSelectedFeature->context()->shape();
482   }
483   if (aShape.get()) {
484     TopoDS_Shape aShp = aShape->impl<TopoDS_Shape>();
485     Handle(AIS_RadiusDimension) aDim;
486     if (thePrevious.get()) {
487       aAISObj = thePrevious;
488       Handle(AIS_InteractiveObject) aAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
489       Handle(AIS_RadiusDimension) aDim = Handle(AIS_RadiusDimension)::DownCast(aAIS);
490       if (aDim.IsNull()) {
491         aDim = new AIS_RadiusDimension(aShp);
492         aAISObj = AISObjectPtr(new GeomAPI_AISObject());
493         aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
494       } else
495         aDim->SetMeasuredGeometry(aShp);
496     } else {
497       aAISObj = AISObjectPtr(new GeomAPI_AISObject());
498       Handle(AIS_RadiusDimension) aDim = new AIS_RadiusDimension(aShp);
499       aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
500     }
501   }
502   return aAISObj;
503 }
504
505 AISObjectPtr FeaturesPlugin_Measurement::angleDimension(AISObjectPtr thePrevious)
506 {
507   AISObjectPtr aAISObj;
508   AttributeSelectionPtr aFirstFeature = selection(ANGLE_FROM_EDGE_ID());
509   GeomShapePtr aShape1;
510   GeomEdgePtr anEdge1;
511   if (aFirstFeature && aFirstFeature->isInitialized()) {
512     aShape1 = aFirstFeature->value();
513     if (!aShape1 && aFirstFeature->context())
514       aShape1 = aFirstFeature->context()->shape();
515   }
516   if (aShape1 && aShape1->isEdge())
517     anEdge1 = GeomEdgePtr(new GeomAPI_Edge(aShape1));
518
519   AttributeSelectionPtr aSecondFeature = selection(ANGLE_TO_EDGE_ID());
520   GeomShapePtr aShape2;
521   GeomEdgePtr anEdge2;
522   if (aSecondFeature && aSecondFeature->isInitialized()) {
523     aShape2 = aSecondFeature->value();
524     if (!aShape2 && aSecondFeature->context())
525       aShape2 = aSecondFeature->context()->shape();
526   }
527   if (aShape2 && aShape2->isEdge())
528     anEdge2 = GeomEdgePtr(new GeomAPI_Edge(aShape2));
529
530   if (anEdge1.get() && anEdge2.get()) {
531     TopoDS_Edge aTEdge1 = TopoDS::Edge(anEdge1->impl<TopoDS_Shape>());
532     TopoDS_Edge aTEdge2 = TopoDS::Edge(anEdge2->impl<TopoDS_Shape>());
533
534     Handle(AIS_AngleDimension) aDim;
535     if (thePrevious.get()) {
536       aAISObj = thePrevious;
537       Handle(AIS_InteractiveObject) aAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
538       aDim = Handle(AIS_AngleDimension)::DownCast(aAIS);
539       if (aDim.IsNull()) {
540         aDim = new AIS_AngleDimension(aTEdge1, aTEdge2);
541         aAISObj = AISObjectPtr(new GeomAPI_AISObject());
542         aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
543       } else
544         aDim->SetMeasuredGeometry(aTEdge1, aTEdge2);
545     } else {
546       aAISObj = AISObjectPtr(new GeomAPI_AISObject());
547       aDim = new AIS_AngleDimension(aTEdge1, aTEdge2);
548       aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
549     }
550   }
551   return aAISObj;
552 }
553
554 AISObjectPtr FeaturesPlugin_Measurement::angleByPointsDimension(AISObjectPtr thePrevious)
555 {
556   AISObjectPtr aAISObj;
557   GeomVertexPtr aVertex1 = selectionToVertex(selection(ANGLE_POINT1_ID()));
558   GeomVertexPtr aVertex2 = selectionToVertex(selection(ANGLE_POINT2_ID()));
559   GeomVertexPtr aVertex3 = selectionToVertex(selection(ANGLE_POINT3_ID()));
560
561   if (aVertex1.get() && aVertex2.get() && aVertex3.get()) {
562     GeomPointPtr aPoint1 = aVertex1->point();
563     GeomPointPtr aPoint2 = aVertex2->point();
564     GeomPointPtr aPoint3 = aVertex3->point();
565     gp_Pnt aPnt1(aPoint1->impl<gp_Pnt>());
566     gp_Pnt aPnt2(aPoint2->impl<gp_Pnt>());
567     gp_Pnt aPnt3(aPoint3->impl<gp_Pnt>());
568
569     if (aPnt1.IsEqual(aPnt2, Precision::Confusion()) ||
570       aPnt1.IsEqual(aPnt3, Precision::Confusion()) ||
571       aPnt2.IsEqual(aPnt3, Precision::Confusion()))
572       return thePrevious;
573
574     if (thePrevious.get()) {
575       aAISObj = thePrevious;
576       Handle(AIS_InteractiveObject) aAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
577       Handle(AIS_AngleDimension) aDim = Handle(AIS_AngleDimension)::DownCast(aAIS);
578       if (aDim.IsNull()) {
579         aDim = new AIS_AngleDimension(aPnt1, aPnt2, aPnt3);
580         aAISObj = AISObjectPtr(new GeomAPI_AISObject());
581         aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
582       } else
583         aDim->SetMeasuredGeometry(aPnt1, aPnt2, aPnt3);
584     } else {
585       Handle(AIS_AngleDimension) aDim = new AIS_AngleDimension(aPnt1, aPnt2, aPnt3);
586       aAISObj = AISObjectPtr(new GeomAPI_AISObject());
587       aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aDim));
588     }
589   }
590   return aAISObj;
591 }
592
593
594 void FeaturesPlugin_Measurement::setupDimension(AISObjectPtr theDim)
595 {
596   if (theDim.get()) {
597     Handle(AIS_InteractiveObject) aAIS = theDim->impl<Handle(AIS_InteractiveObject)>();
598     Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast(aAIS);
599     int aSize = Config_PropManager::integer("Visualization", "dimension_arrow_size");
600     int aTextSize = Config_PropManager::integer("Visualization", "dimension_value_size");
601     std::string aFont = Config_PropManager::string("Visualization", "dimension_font");
602
603     Handle(Prs3d_DimensionAspect) anAspect = aDim->DimensionAspect();
604     anAspect->MakeArrows3d(false);
605     anAspect->MakeText3d(false);
606     anAspect->MakeTextShaded(false);
607     anAspect->MakeUnitsDisplayed(false);
608     anAspect->MakeUnitsDisplayed(false);
609     anAspect->TextAspect()->SetFont(aFont.c_str());
610     anAspect->TextAspect()->SetHeight(aTextSize);
611     anAspect->ArrowAspect()->SetLength(aSize / mySceenScale);
612     anAspect->SetExtensionSize((aTextSize / mySceenScale + aSize) / 2.0);
613     aDim->SetDimensionAspect(anAspect);
614
615     aDim->SetZLayer(1);
616     std::vector<int> aColor = Config_PropManager::color("Visualization", "sketch_dimension_color");
617     theDim->setColor(aColor[0], aColor[1], aColor[2]);
618   }
619 }