Salome HOME
Simplification and refactoring of unit tests for SketchPlugin
[modules/shaper.git] / src / SketchPlugin / SketchPlugin_Ellipse.cpp
1 // Copyright (C) 2017-20xx CEA/DEN, EDF R&D -->
2
3 // File:        SketchPlugin_Ellipse.cpp
4 // Created:     26 April 2017
5 // Author:      Artem ZHIDKOV
6
7 #include <SketchPlugin_Ellipse.h>
8 #include <SketchPlugin_Sketch.h>
9
10 #include <GeomAlgoAPI_EdgeBuilder.h>
11 #include <GeomAPI_Edge.h>
12 #include <GeomAPI_Ellipse.h>
13 #include <GeomDataAPI_Point2D.h>
14 #include <ModelAPI_AttributeDouble.h>
15 #include <ModelAPI_ResultConstruction.h>
16 #include <ModelAPI_Session.h>
17 #include <ModelAPI_Validator.h>
18
19 static const double tolerance = 1e-7;
20
21
22 SketchPlugin_Ellipse::SketchPlugin_Ellipse()
23 : SketchPlugin_SketchEntity()
24 {
25 }
26
27 void SketchPlugin_Ellipse::initDerivedClassAttributes()
28 {
29   data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::typeId());
30   data()->addAttribute(FOCUS_ID(), GeomDataAPI_Point2D::typeId());
31   data()->addAttribute(MAJOR_RADIUS_ID(), ModelAPI_AttributeDouble::typeId());
32   data()->addAttribute(MINOR_RADIUS_ID(), ModelAPI_AttributeDouble::typeId());
33
34   data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
35   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
36 }
37
38 void SketchPlugin_Ellipse::execute()
39 {
40   SketchPlugin_Sketch* aSketch = sketch();
41   if(!aSketch) {
42     return;
43   }
44
45   // Compute a ellipse in 3D view.
46   std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr =
47       std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
48   std::shared_ptr<GeomDataAPI_Point2D> aFocusAttr =
49       std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(FOCUS_ID()));
50   AttributeDoublePtr aMajorRadiusAttr = real(MAJOR_RADIUS_ID());
51   AttributeDoublePtr aMinorRadiusAttr = real(MINOR_RADIUS_ID());
52   if (!aCenterAttr->isInitialized() ||
53       !aFocusAttr->isInitialized() ||
54       !aMajorRadiusAttr->isInitialized() ||
55       !aMinorRadiusAttr->isInitialized()) {
56     return;
57   }
58
59   double aMajorRadius = aMajorRadiusAttr->value();
60   double aMinorRadius = aMinorRadiusAttr->value();
61   if(aMajorRadius < tolerance || aMinorRadius < tolerance) {
62     return;
63   }
64
65   // Make a visible point.
66   SketchPlugin_Sketch::createPoint2DResult(this, aSketch, CENTER_ID(), 0);
67
68   std::shared_ptr<GeomDataAPI_Dir> aNDir = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
69       aSketch->attribute(SketchPlugin_Sketch::NORM_ID()));
70
71   // Make a visible ellipse.
72   std::shared_ptr<GeomAPI_Pnt> aCenter(aSketch->to3D(aCenterAttr->x(), aCenterAttr->y()));
73   std::shared_ptr<GeomAPI_Pnt> aFocus(aSketch->to3D(aFocusAttr->x(), aFocusAttr->y()));
74   std::shared_ptr<GeomAPI_Dir> aNormal = aNDir->dir();
75   std::shared_ptr<GeomAPI_Dir> aMajorAxis(new GeomAPI_Dir(aFocus->x() - aCenter->x(),
76       aFocus->y() - aCenter->y(), aFocus->z() - aCenter->z()));
77
78   std::shared_ptr<GeomAPI_Shape> anEllipseShape =
79       GeomAlgoAPI_EdgeBuilder::ellipse(aCenter, aNormal, aMajorAxis, aMajorRadius, aMinorRadius);
80
81   std::shared_ptr<ModelAPI_ResultConstruction> aResult = document()->createConstruction(data(), 1);
82   aResult->setShape(anEllipseShape);
83   aResult->setIsInHistory(false);
84   setResult(aResult, 1);
85 }
86
87 void SketchPlugin_Ellipse::move(double theDeltaX, double theDeltaY)
88 {
89   std::shared_ptr<ModelAPI_Data> aData = data();
90   if(!aData->isValid()) {
91     return;
92   }
93
94   std::shared_ptr<GeomDataAPI_Point2D> aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
95       aData->attribute(CENTER_ID()));
96   if(aPoint->isInitialized()) {
97     aPoint->move(theDeltaX, theDeltaY);
98   }
99 }
100
101 bool SketchPlugin_Ellipse::isFixed() {
102   return data()->selection(EXTERNAL_ID())->context().get() != NULL;
103 }
104
105 void SketchPlugin_Ellipse::attributeChanged(const std::string& theID) {
106   // the second condition for unability to move external segments anywhere
107   if (theID == EXTERNAL_ID() || isFixed()) {
108     std::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(EXTERNAL_ID())->value();
109     if (!aSelection) {
110       // empty shape in selection shows that the shape is equal to context
111       ResultPtr anExtRes = selection(EXTERNAL_ID())->context();
112       if (anExtRes)
113         aSelection = anExtRes->shape();
114     }
115     // update arguments due to the selection value
116     if (aSelection && !aSelection->isNull() && aSelection->isEdge()) {
117       std::shared_ptr<GeomAPI_Edge> anEdge( new GeomAPI_Edge(aSelection));
118       std::shared_ptr<GeomAPI_Ellipse> anEllipse = anEdge->ellipse();
119
120       std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr =
121           std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(CENTER_ID()));
122       aCenterAttr->setValue(sketch()->to2D(anEllipse->center()));
123
124       std::shared_ptr<GeomDataAPI_Point2D> aFocusAttr =
125           std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(FOCUS_ID()));
126       aFocusAttr->setValue(sketch()->to2D(anEllipse->firstFocus()));
127
128       real(MAJOR_RADIUS_ID())->setValue(anEllipse->majorRadius());
129       real(MINOR_RADIUS_ID())->setValue(anEllipse->minorRadius());
130     }
131   }
132 }