Salome HOME
Task 2.12. New entities: ellipses and arcs of ellipses (issue #3003)
[modules/shaper.git] / src / SketchAPI / SketchAPI_MacroEllipse.cpp
1 // Copyright (C) 2014-2019  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 email : webmaster.salome@opencascade.com
18 //
19
20 #include "SketchAPI_MacroEllipse.h"
21 #include "SketchAPI_Line.h"
22 #include "SketchAPI_Point.h"
23
24 #include <GeomAPI_Pnt2d.h>
25
26 #include <ModelHighAPI_RefAttr.h>
27 #include <ModelHighAPI_Tools.h>
28
29 #include <SketchPlugin_Sketch.h>
30
31 #define MAJOR_AXIS_NEGATIVE (std::dynamic_pointer_cast<GeomDataAPI_Point2D>( \
32                              feature()->attribute(SketchPlugin_MacroEllipse::FIRST_POINT_ID())))
33 #define MAJOR_AXIS_POSITIVE (std::dynamic_pointer_cast<GeomDataAPI_Point2D>( \
34                              feature()->attribute(SketchPlugin_MacroEllipse::SECOND_POINT_ID())))
35 #define PASSED_POINT (std::dynamic_pointer_cast<GeomDataAPI_Point2D>( \
36                       feature()->attribute(SketchPlugin_MacroEllipse::PASSED_POINT_ID())))
37
38 #define MAJOR_AXIS_NEGATIVE_REF (feature()->refattr( \
39                                  SketchPlugin_MacroEllipse::FIRST_POINT_REF_ID()))
40 #define MAJOR_AXIS_POSITIVE_REF (feature()->refattr( \
41                                  SketchPlugin_MacroEllipse::SECOND_POINT_REF_ID()))
42 #define PASSED_POINT_REF (feature()->refattr(SketchPlugin_MacroEllipse::PASSED_POINT_REF_ID()))
43
44
45 // find a parent sketch
46 static CompositeFeaturePtr sketch(FeaturePtr theFeature)
47 {
48   CompositeFeaturePtr aSketch;
49   const std::set<AttributePtr>& aRefs = theFeature->data()->refsToMe();
50   for (std::set<AttributePtr>::const_iterator anIt = aRefs.begin(); anIt != aRefs.end(); ++anIt)
51     if ((*anIt)->id() == SketchPlugin_Sketch::FEATURES_ID()) {
52       aSketch = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>((*anIt)->owner());
53       break;
54     }
55   return aSketch;
56 }
57
58
59 SketchAPI_MacroEllipse::SketchAPI_MacroEllipse(const std::shared_ptr<ModelAPI_Feature>& theFeature)
60 : SketchAPI_SketchEntity(theFeature)
61 {
62   if (initialize())
63     mySketch = sketch(theFeature);
64 }
65
66 SketchAPI_MacroEllipse::SketchAPI_MacroEllipse(const std::shared_ptr<ModelAPI_Feature>& theFeature,
67                                                double theX1, double theY1,
68                                                double theX2, double theY2,
69                                                double theX3, double theY3,
70                                                bool byCenter)
71   : SketchAPI_SketchEntity(theFeature)
72 {
73   if (initialize()) {
74     if (byCenter)
75       setByCenterAndPassedPoints();
76     else
77       setByMajorAxisAndPassedPoint();
78
79     initializePoints(theX1, theY1, theX2, theY2, theX3, theY3);
80   }
81 }
82
83 SketchAPI_MacroEllipse::SketchAPI_MacroEllipse(const std::shared_ptr<ModelAPI_Feature>& theFeature,
84                                                const std::shared_ptr<GeomAPI_Pnt2d>& thePoint1,
85                                                const std::shared_ptr<GeomAPI_Pnt2d>& thePoint2,
86                                                const std::shared_ptr<GeomAPI_Pnt2d>& thePoint3,
87                                                bool byCenter)
88   : SketchAPI_SketchEntity(theFeature)
89 {
90   if (initialize()) {
91     if (byCenter)
92       setByCenterAndPassedPoints();
93     else
94       setByMajorAxisAndPassedPoint();
95
96     initializePoints(thePoint1, thePoint2, thePoint3);
97   }
98 }
99
100 SketchAPI_MacroEllipse::SketchAPI_MacroEllipse(const std::shared_ptr<ModelAPI_Feature>& theFeature,
101                                                const std::shared_ptr<GeomAPI_Pnt2d>& thePoint1,
102                                                const ModelHighAPI_RefAttr&           thePoint1Ref,
103                                                const std::shared_ptr<GeomAPI_Pnt2d>& thePoint2,
104                                                const ModelHighAPI_RefAttr&           thePoint2Ref,
105                                                const std::shared_ptr<GeomAPI_Pnt2d>& thePoint3,
106                                                const ModelHighAPI_RefAttr&           thePoint3Ref,
107                                                bool byCenter)
108   : SketchAPI_SketchEntity(theFeature)
109 {
110   if (initialize()) {
111     if (byCenter)
112       setByCenterAndPassedPoints();
113     else
114       setByMajorAxisAndPassedPoint();
115
116     initializePoints(thePoint1, thePoint1Ref, thePoint2, thePoint2Ref, thePoint3, thePoint3Ref);
117   }
118 }
119
120 SketchAPI_MacroEllipse::~SketchAPI_MacroEllipse()
121 {
122 }
123
124 void SketchAPI_MacroEllipse::setByCenterAndPassedPoints()
125 {
126   fillAttribute(SketchPlugin_MacroEllipse::ELLIPSE_TYPE_BY_CENTER_AXIS_POINT(), myellipseType);
127 }
128
129 void SketchAPI_MacroEllipse::setByMajorAxisAndPassedPoint()
130 {
131   fillAttribute(SketchPlugin_MacroEllipse::ELLIPSE_TYPE_BY_AXIS_AND_POINT(), myellipseType);
132 }
133
134 void SketchAPI_MacroEllipse::initializePoints(double theX1, double theY1,
135                                               double theX2, double theY2,
136                                               double theX3, double theY3)
137 {
138   fillAttribute(MAJOR_AXIS_NEGATIVE, theX1, theY1);
139   fillAttribute(MAJOR_AXIS_POSITIVE, theX2, theY2);
140   fillAttribute(PASSED_POINT, theX3, theY3);
141
142   mySketch = sketch(feature());
143   execute();
144 }
145
146 void SketchAPI_MacroEllipse::initializePoints(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint1,
147                                               const std::shared_ptr<GeomAPI_Pnt2d>& thePoint2,
148                                               const std::shared_ptr<GeomAPI_Pnt2d>& thePoint3)
149 {
150   fillAttribute(thePoint1, MAJOR_AXIS_NEGATIVE);
151   fillAttribute(thePoint2, MAJOR_AXIS_POSITIVE);
152   fillAttribute(thePoint3, PASSED_POINT);
153
154   mySketch = sketch(feature());
155   execute();
156 }
157
158 static void fillAttribute(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint,
159                           const ModelHighAPI_RefAttr& thePointRef,
160                           std::shared_ptr<GeomDataAPI_Point2D> thePointAttr,
161                           AttributeRefAttrPtr thePointRefAttr)
162 {
163   GeomPnt2dPtr aPoint = thePoint;
164   if (!thePointRef.isEmpty()) {
165     fillAttribute(thePointRef, thePointRefAttr);
166     std::shared_ptr<GeomDataAPI_Point2D> anAttrPnt =
167         std::dynamic_pointer_cast<GeomDataAPI_Point2D>(thePointRefAttr->attr());
168     if (anAttrPnt)
169       aPoint = anAttrPnt->pnt();
170   }
171   fillAttribute(aPoint, thePointAttr);
172 }
173
174 void SketchAPI_MacroEllipse::initializePoints(
175     const std::shared_ptr<GeomAPI_Pnt2d>& theMajorAxisPoint1,
176     const ModelHighAPI_RefAttr&           theMajorAxisPoint1Ref,
177     const std::shared_ptr<GeomAPI_Pnt2d>& theMajorAxisPoint2,
178     const ModelHighAPI_RefAttr&           theMajorAxisPoint2Ref,
179     const std::shared_ptr<GeomAPI_Pnt2d>& thePassedPoint,
180     const ModelHighAPI_RefAttr&           thePassedPointRef)
181 {
182   fillAttribute(theMajorAxisPoint1, theMajorAxisPoint1Ref,
183                 MAJOR_AXIS_NEGATIVE, MAJOR_AXIS_NEGATIVE_REF);
184   fillAttribute(theMajorAxisPoint2, theMajorAxisPoint2Ref,
185                 MAJOR_AXIS_POSITIVE, MAJOR_AXIS_POSITIVE_REF);
186   fillAttribute(thePassedPoint, thePassedPointRef,
187                 PASSED_POINT, PASSED_POINT_REF);
188
189   mySketch = sketch(feature());
190   execute();
191 }
192
193 std::shared_ptr<SketchAPI_Point> SketchAPI_MacroEllipse::center()
194 {
195   if (!myCenter)
196     collectAuxiliary();
197   return myCenter;
198 }
199
200 std::shared_ptr<SketchAPI_Point> SketchAPI_MacroEllipse::focus1()
201 {
202   if (!myFocus1)
203     collectAuxiliary();
204   return myFocus1;
205 }
206
207 std::shared_ptr<SketchAPI_Point> SketchAPI_MacroEllipse::focus2()
208 {
209   if (!myFocus2)
210     collectAuxiliary();
211   return myFocus2;
212 }
213
214 std::shared_ptr<SketchAPI_Point> SketchAPI_MacroEllipse::majorAxisStart()
215 {
216   if (!myMajorAxisStart)
217     collectAuxiliary();
218   return myMajorAxisStart;
219 }
220
221 std::shared_ptr<SketchAPI_Point> SketchAPI_MacroEllipse::majorAxisEnd()
222 {
223   if (!myMajorAxisEnd)
224     collectAuxiliary();
225   return myMajorAxisEnd;
226 }
227
228 std::shared_ptr<SketchAPI_Point> SketchAPI_MacroEllipse::minorAxisStart()
229 {
230   if (!myMinorAxisStart)
231     collectAuxiliary();
232   return myMinorAxisStart;
233 }
234
235 std::shared_ptr<SketchAPI_Point> SketchAPI_MacroEllipse::minorAxisEnd()
236 {
237   if (!myMinorAxisEnd)
238     collectAuxiliary();
239   return myMinorAxisEnd;
240 }
241
242 std::shared_ptr<SketchAPI_Line> SketchAPI_MacroEllipse::majorAxis()
243 {
244   if (!myMajorAxis)
245     collectAuxiliary();
246   return myMajorAxis;
247 }
248
249 std::shared_ptr<SketchAPI_Line> SketchAPI_MacroEllipse::minorAxis()
250 {
251   if (!myMinorAxis)
252     collectAuxiliary();
253   return myMinorAxis;
254 }
255
256 void SketchAPI_MacroEllipse::collectAuxiliary()
257 {
258   // collect auxiliary features
259   int aNbSubs = mySketch->numberOfSubs();
260   std::shared_ptr<SketchAPI_Point>* anAuxPoint[] = {
261     &myCenter, &myFocus1, &myFocus2,
262     &myMajorAxisStart, &myMajorAxisEnd,
263     &myMinorAxisStart, &myMinorAxisEnd
264   };
265   std::shared_ptr<SketchAPI_Line>* anAuxLine[] = {&myMajorAxis, &myMinorAxis};
266   for (int aPtInd = 7, aLinInd = 2; (aPtInd > 0 || aLinInd > 0) && aNbSubs >= 0; ) {
267     FeaturePtr aCurFeature = mySketch->subFeature(--aNbSubs);
268     if (aPtInd > 0 && aCurFeature->getKind() == SketchPlugin_Point::ID())
269       anAuxPoint[--aPtInd]->reset(new SketchAPI_Point(aCurFeature));
270     else if (aLinInd > 0 && aCurFeature->getKind() == SketchPlugin_Line::ID())
271       anAuxLine[--aLinInd]->reset(new SketchAPI_Line(aCurFeature));
272   }
273 }