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   initialize();
63 }
64
65 SketchAPI_MacroEllipse::SketchAPI_MacroEllipse(const std::shared_ptr<ModelAPI_Feature>& theFeature,
66                                                double theX1, double theY1,
67                                                double theX2, double theY2,
68                                                double theX3, double theY3,
69                                                bool byCenter)
70   : SketchAPI_SketchEntity(theFeature)
71 {
72   if (initialize()) {
73     if (byCenter)
74       setByCenterAndPassedPoints();
75     else
76       setByMajorAxisAndPassedPoint();
77
78     initializePoints(theX1, theY1, theX2, theY2, theX3, theY3);
79   }
80 }
81
82 SketchAPI_MacroEllipse::SketchAPI_MacroEllipse(const std::shared_ptr<ModelAPI_Feature>& theFeature,
83                                                const std::shared_ptr<GeomAPI_Pnt2d>& thePoint1,
84                                                const std::shared_ptr<GeomAPI_Pnt2d>& thePoint2,
85                                                const std::shared_ptr<GeomAPI_Pnt2d>& thePoint3,
86                                                bool byCenter)
87   : SketchAPI_SketchEntity(theFeature)
88 {
89   if (initialize()) {
90     if (byCenter)
91       setByCenterAndPassedPoints();
92     else
93       setByMajorAxisAndPassedPoint();
94
95     initializePoints(thePoint1, thePoint2, thePoint3);
96   }
97 }
98
99 SketchAPI_MacroEllipse::SketchAPI_MacroEllipse(const std::shared_ptr<ModelAPI_Feature>& theFeature,
100                                                const std::shared_ptr<GeomAPI_Pnt2d>& thePoint1,
101                                                const ModelHighAPI_RefAttr&           thePoint1Ref,
102                                                const std::shared_ptr<GeomAPI_Pnt2d>& thePoint2,
103                                                const ModelHighAPI_RefAttr&           thePoint2Ref,
104                                                const std::shared_ptr<GeomAPI_Pnt2d>& thePoint3,
105                                                const ModelHighAPI_RefAttr&           thePoint3Ref,
106                                                bool byCenter)
107   : SketchAPI_SketchEntity(theFeature)
108 {
109   if (initialize()) {
110     if (byCenter)
111       setByCenterAndPassedPoints();
112     else
113       setByMajorAxisAndPassedPoint();
114
115     initializePoints(thePoint1, thePoint1Ref, thePoint2, thePoint2Ref, thePoint3, thePoint3Ref);
116   }
117 }
118
119 SketchAPI_MacroEllipse::~SketchAPI_MacroEllipse()
120 {
121 }
122
123 void SketchAPI_MacroEllipse::setByCenterAndPassedPoints()
124 {
125   fillAttribute(SketchPlugin_MacroEllipse::ELLIPSE_TYPE_BY_CENTER_AXIS_POINT(), myellipseType);
126 }
127
128 void SketchAPI_MacroEllipse::setByMajorAxisAndPassedPoint()
129 {
130   fillAttribute(SketchPlugin_MacroEllipse::ELLIPSE_TYPE_BY_AXIS_AND_POINT(), myellipseType);
131 }
132
133 void SketchAPI_MacroEllipse::initializePoints(double theX1, double theY1,
134                                               double theX2, double theY2,
135                                               double theX3, double theY3)
136 {
137   fillAttribute(MAJOR_AXIS_NEGATIVE, theX1, theY1);
138   fillAttribute(MAJOR_AXIS_POSITIVE, theX2, theY2);
139   fillAttribute(PASSED_POINT, theX3, theY3);
140
141   mySketch = sketch(feature());
142   execute();
143 }
144
145 void SketchAPI_MacroEllipse::initializePoints(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint1,
146                                               const std::shared_ptr<GeomAPI_Pnt2d>& thePoint2,
147                                               const std::shared_ptr<GeomAPI_Pnt2d>& thePoint3)
148 {
149   fillAttribute(thePoint1, MAJOR_AXIS_NEGATIVE);
150   fillAttribute(thePoint2, MAJOR_AXIS_POSITIVE);
151   fillAttribute(thePoint3, PASSED_POINT);
152
153   mySketch = sketch(feature());
154   execute();
155 }
156
157 static void fillAttribute(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint,
158                           const ModelHighAPI_RefAttr& thePointRef,
159                           std::shared_ptr<GeomDataAPI_Point2D> thePointAttr,
160                           AttributeRefAttrPtr thePointRefAttr)
161 {
162   GeomPnt2dPtr aPoint = thePoint;
163   if (!thePointRef.isEmpty()) {
164     fillAttribute(thePointRef, thePointRefAttr);
165     std::shared_ptr<GeomDataAPI_Point2D> anAttrPnt =
166         std::dynamic_pointer_cast<GeomDataAPI_Point2D>(thePointRefAttr->attr());
167     if (anAttrPnt)
168       aPoint = anAttrPnt->pnt();
169   }
170   fillAttribute(aPoint, thePointAttr);
171 }
172
173 void SketchAPI_MacroEllipse::initializePoints(
174     const std::shared_ptr<GeomAPI_Pnt2d>& theMajorAxisPoint1,
175     const ModelHighAPI_RefAttr&           theMajorAxisPoint1Ref,
176     const std::shared_ptr<GeomAPI_Pnt2d>& theMajorAxisPoint2,
177     const ModelHighAPI_RefAttr&           theMajorAxisPoint2Ref,
178     const std::shared_ptr<GeomAPI_Pnt2d>& thePassedPoint,
179     const ModelHighAPI_RefAttr&           thePassedPointRef)
180 {
181   fillAttribute(theMajorAxisPoint1, theMajorAxisPoint1Ref,
182                 MAJOR_AXIS_NEGATIVE, MAJOR_AXIS_NEGATIVE_REF);
183   fillAttribute(theMajorAxisPoint2, theMajorAxisPoint2Ref,
184                 MAJOR_AXIS_POSITIVE, MAJOR_AXIS_POSITIVE_REF);
185   fillAttribute(thePassedPoint, thePassedPointRef,
186                 PASSED_POINT, PASSED_POINT_REF);
187
188   mySketch = sketch(feature());
189   execute();
190 }
191
192 std::shared_ptr<SketchAPI_Point> SketchAPI_MacroEllipse::center()
193 {
194   if (!myCenter)
195     collectAuxiliary();
196   return myCenter;
197 }
198
199 std::shared_ptr<SketchAPI_Point> SketchAPI_MacroEllipse::focus1()
200 {
201   if (!myFocus1)
202     collectAuxiliary();
203   return myFocus1;
204 }
205
206 std::shared_ptr<SketchAPI_Point> SketchAPI_MacroEllipse::focus2()
207 {
208   if (!myFocus2)
209     collectAuxiliary();
210   return myFocus2;
211 }
212
213 std::shared_ptr<SketchAPI_Point> SketchAPI_MacroEllipse::majorAxisStart()
214 {
215   if (!myMajorAxisStart)
216     collectAuxiliary();
217   return myMajorAxisStart;
218 }
219
220 std::shared_ptr<SketchAPI_Point> SketchAPI_MacroEllipse::majorAxisEnd()
221 {
222   if (!myMajorAxisEnd)
223     collectAuxiliary();
224   return myMajorAxisEnd;
225 }
226
227 std::shared_ptr<SketchAPI_Point> SketchAPI_MacroEllipse::minorAxisStart()
228 {
229   if (!myMinorAxisStart)
230     collectAuxiliary();
231   return myMinorAxisStart;
232 }
233
234 std::shared_ptr<SketchAPI_Point> SketchAPI_MacroEllipse::minorAxisEnd()
235 {
236   if (!myMinorAxisEnd)
237     collectAuxiliary();
238   return myMinorAxisEnd;
239 }
240
241 std::shared_ptr<SketchAPI_Line> SketchAPI_MacroEllipse::majorAxis()
242 {
243   if (!myMajorAxis)
244     collectAuxiliary();
245   return myMajorAxis;
246 }
247
248 std::shared_ptr<SketchAPI_Line> SketchAPI_MacroEllipse::minorAxis()
249 {
250   if (!myMinorAxis)
251     collectAuxiliary();
252   return myMinorAxis;
253 }
254
255 void SketchAPI_MacroEllipse::collectAuxiliary()
256 {
257   // collect auxiliary features
258   int aNbSubs = mySketch->numberOfSubs();
259   std::shared_ptr<SketchAPI_Point>* anAuxPoint[] = {
260     &myCenter, &myFocus1, &myFocus2,
261     &myMajorAxisStart, &myMajorAxisEnd,
262     &myMinorAxisStart, &myMinorAxisEnd
263   };
264   std::shared_ptr<SketchAPI_Line>* anAuxLine[] = {&myMajorAxis, &myMinorAxis};
265   for (int aPtInd = 7, aLinInd = 2; (aPtInd > 0 || aLinInd > 0) && aNbSubs >= 0; ) {
266     FeaturePtr aCurFeature = mySketch->subFeature(--aNbSubs);
267     if (aPtInd > 0 && aCurFeature->getKind() == SketchPlugin_Point::ID())
268       anAuxPoint[--aPtInd]->reset(new SketchAPI_Point(aCurFeature));
269     else if (aLinInd > 0 && aCurFeature->getKind() == SketchPlugin_Line::ID())
270       anAuxLine[--aLinInd]->reset(new SketchAPI_Line(aCurFeature));
271   }
272 }