]> SALOME platform Git repositories - modules/shaper.git/blob - src/SketchAPI/SketchAPI_Ellipse.cpp
Salome HOME
6bcd6c0dc019d36d40f6dd94de01cb3165ff3bd6
[modules/shaper.git] / src / SketchAPI / SketchAPI_Ellipse.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_Ellipse.h"
21
22 #include <GeomAPI_Pnt2d.h>
23
24 #include <ModelHighAPI_Dumper.h>
25 #include <ModelHighAPI_Selection.h>
26 #include <ModelHighAPI_Tools.h>
27
28 #include <SketchPlugin_ConstraintCoincidenceInternal.h>
29 #include <SketchPlugin_Line.h>
30 #include <SketchPlugin_Point.h>
31
32 static const std::string AUXILIARY_VALUE = "aux";
33 static const std::string MAJOR_AXIS_ID = "majorAxis";
34 static const std::string MINOR_AXIS_ID = "minorAxis";
35
36 SketchAPI_Ellipse::SketchAPI_Ellipse(const std::shared_ptr<ModelAPI_Feature> & theFeature)
37   : SketchAPI_SketchEntity(theFeature)
38 {
39   initialize();
40 }
41
42 SketchAPI_Ellipse::SketchAPI_Ellipse(const std::shared_ptr<ModelAPI_Feature>& theFeature,
43                                      double theCenterX, double theCenterY,
44                                      double theFocusX, double theFocusY,
45                                      double theMinorRadius)
46   : SketchAPI_SketchEntity(theFeature)
47 {
48   if(initialize()) {
49     setByCenterFocusAndRadius(theCenterX, theCenterY, theFocusX, theFocusY, theMinorRadius);
50   }
51 }
52
53 SketchAPI_Ellipse::SketchAPI_Ellipse(const std::shared_ptr<ModelAPI_Feature>& theFeature,
54                                      const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
55                                      const std::shared_ptr<GeomAPI_Pnt2d>& theFocus,
56                                      double theMinorRadius)
57 : SketchAPI_SketchEntity(theFeature)
58 {
59   if(initialize()) {
60     setByCenterFocusAndRadius(theCenter, theFocus, theMinorRadius);
61   }
62 }
63
64 SketchAPI_Ellipse::SketchAPI_Ellipse(const std::shared_ptr<ModelAPI_Feature>& theFeature,
65                                      const ModelHighAPI_Selection& theExternal)
66   : SketchAPI_SketchEntity(theFeature)
67 {
68   if (initialize()) {
69     setByExternal(theExternal);
70   }
71 }
72
73 SketchAPI_Ellipse::SketchAPI_Ellipse(const std::shared_ptr<ModelAPI_Feature>& theFeature,
74                                      const std::string& theExternalName)
75   : SketchAPI_SketchEntity(theFeature)
76 {
77   if (initialize()) {
78     setByExternalName(theExternalName);
79   }
80 }
81
82 SketchAPI_Ellipse::~SketchAPI_Ellipse()
83 {
84 }
85
86 void SketchAPI_Ellipse::setByCenterFocusAndRadius(double theCenterX, double theCenterY,
87                                                   double theFocusX, double theFocusY,
88                                                   double theMinorRadius)
89 {
90   fillAttribute(center(), theCenterX, theCenterY);
91   fillAttribute(firstFocus(), theFocusX, theFocusY);
92   fillAttribute(theMinorRadius, myminorRadius);
93
94   execute();
95 }
96
97 void SketchAPI_Ellipse::setByCenterFocusAndRadius(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
98                                                   const std::shared_ptr<GeomAPI_Pnt2d>& theFocus,
99                                                   double theMinorRadius)
100 {
101   fillAttribute(theCenter, mycenter);
102   fillAttribute(theFocus, myfirstFocus);
103   fillAttribute(theMinorRadius, myminorRadius);
104
105   execute();
106 }
107
108 void SketchAPI_Ellipse::setByExternal(const ModelHighAPI_Selection & theExternal)
109 {
110   fillAttribute(theExternal, external());
111   execute();
112 }
113
114 void SketchAPI_Ellipse::setByExternalName(const std::string & theExternalName)
115 {
116   fillAttribute(ModelHighAPI_Selection("EDGE", theExternalName), external());
117   execute();
118 }
119
120 void SketchAPI_Ellipse::setCenter(double theX, double theY)
121 {
122   fillAttribute(center(), theX, theY);
123   execute();
124 }
125
126 void SketchAPI_Ellipse::setCenter(const std::shared_ptr<GeomAPI_Pnt2d> & theCenter)
127 {
128   fillAttribute(theCenter, mycenter);
129   execute();
130 }
131
132 void SketchAPI_Ellipse::setFocus(double theX, double theY)
133 {
134   fillAttribute(firstFocus(), theX, theY);
135   execute();
136 }
137
138 void SketchAPI_Ellipse::setFocus(const std::shared_ptr<GeomAPI_Pnt2d> & theFocus)
139 {
140   fillAttribute(theFocus, myfirstFocus);
141   execute();
142 }
143
144 void SketchAPI_Ellipse::setMinorRadius(double theMinorRadius)
145 {
146   fillAttribute(theMinorRadius, myminorRadius);
147   execute();
148 }
149
150 ModelHighAPI_Selection SketchAPI_Ellipse::majorAxis() const
151 {
152   return ModelHighAPI_Selection();
153 }
154
155 ModelHighAPI_Selection SketchAPI_Ellipse::minorAxis() const
156 {
157   return ModelHighAPI_Selection();
158 }
159
160 static CompositeFeaturePtr sketchForFeature(FeaturePtr theFeature)
161 {
162   const std::set<AttributePtr>& aRefs = theFeature->data()->refsToMe();
163   for (std::set<AttributePtr>::const_iterator anIt = aRefs.begin(); anIt != aRefs.end(); ++anIt)
164     if ((*anIt)->id() == SketchPlugin_Sketch::FEATURES_ID())
165       return std::dynamic_pointer_cast<ModelAPI_CompositeFeature>((*anIt)->owner());
166   return CompositeFeaturePtr();
167 }
168
169 static void createInternalConstraint(const CompositeFeaturePtr& theSketch,
170                                      const AttributePoint2DPtr& thePoint1,
171                                      const AttributePoint2DPtr& thePoint2)
172 {
173   FeaturePtr aConstraint = theSketch->addFeature(SketchPlugin_ConstraintCoincidenceInternal::ID());
174   aConstraint->refattr(SketchPlugin_Constraint::ENTITY_A())->setAttr(thePoint1);
175   aConstraint->refattr(SketchPlugin_Constraint::ENTITY_B())->setAttr(thePoint2);
176   aConstraint->execute();
177 }
178
179 static FeaturePtr createPoint(const CompositeFeaturePtr& theSketch,
180                               const FeaturePtr& theEllipse,
181                               const std::string& theCoincident,
182                               const std::string& theAuxOrName)
183 {
184   AttributePoint2DPtr anElPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
185       theEllipse->attribute(theCoincident));
186
187   FeaturePtr aPointFeature = theSketch->addFeature(SketchPlugin_Point::ID());
188   AttributePoint2DPtr aCoord = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
189       aPointFeature->attribute(SketchPlugin_Point::COORD_ID()));
190   aCoord->setValue(anElPoint->x(), anElPoint->y());
191   aPointFeature->reference(SketchPlugin_Point::PARENT_ID())->setValue(theEllipse);
192   aPointFeature->execute();
193
194   std::string aName = theEllipse->name() + "_" + theCoincident;
195   aPointFeature->data()->setName(aName);
196   aPointFeature->lastResult()->data()->setName(aName);
197
198   if (theAuxOrName == AUXILIARY_VALUE)
199     aPointFeature->boolean(SketchPlugin_Point::AUXILIARY_ID())->setValue(true);
200   else if (!theAuxOrName.empty()) {
201     aPointFeature->data()->setName(theAuxOrName);
202     aPointFeature->lastResult()->data()->setName(theAuxOrName);
203   }
204
205   createInternalConstraint(theSketch, anElPoint, aCoord);
206
207   return aPointFeature;
208 }
209
210 static FeaturePtr createAxis(const CompositeFeaturePtr& theSketch,
211                              const FeaturePtr& theEllipse,
212                              const std::string& theCoincidentStart,
213                              const std::string& theCoincidentEnd,
214                              const std::string& theAuxOrName)
215 {
216   AttributePoint2DPtr aStartPoint =
217       std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theEllipse->attribute(theCoincidentStart));
218   AttributePoint2DPtr aEndPoint =
219       std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theEllipse->attribute(theCoincidentEnd));
220
221   FeaturePtr aLineFeature = theSketch->addFeature(SketchPlugin_Line::ID());
222   AttributePoint2DPtr aLineStart = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
223       aLineFeature->attribute(SketchPlugin_Line::START_ID()));
224   aLineStart->setValue(aStartPoint->x(), aStartPoint->y());
225   AttributePoint2DPtr aLineEnd = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
226       aLineFeature->attribute(SketchPlugin_Line::END_ID()));
227   aLineEnd->setValue(aEndPoint->x(), aEndPoint->y());
228   aLineFeature->reference(SketchPlugin_Point::PARENT_ID())->setValue(theEllipse);
229   aLineFeature->execute();
230
231   std::string aName = theEllipse->name() + "_" +
232       (theCoincidentStart == SketchPlugin_Ellipse::MAJOR_AXIS_START_ID() ?
233        "major_axis" : "minor_axis");
234   aLineFeature->data()->setName(aName);
235   aLineFeature->lastResult()->data()->setName(aName);
236
237   if (theAuxOrName == AUXILIARY_VALUE)
238     aLineFeature->boolean(SketchPlugin_Line::AUXILIARY_ID())->setValue(true);
239   else if (!theAuxOrName.empty()) {
240     aLineFeature->data()->setName(theAuxOrName);
241     aLineFeature->lastResult()->data()->setName(theAuxOrName);
242   }
243
244   createInternalConstraint(theSketch, aStartPoint, aLineStart);
245   createInternalConstraint(theSketch, aEndPoint, aLineEnd);
246
247   return aLineFeature;
248 }
249
250 std::list<std::shared_ptr<SketchAPI_SketchEntity> > SketchAPI_Ellipse::construction(
251     const std::string& center,
252     const std::string& firstFocus,
253     const std::string& secondFocus,
254     const std::string& majorAxisStart,
255     const std::string& majorAxisEnd,
256     const std::string& minorAxisStart,
257     const std::string& minorAxisEnd,
258     const std::string& majorAxis,
259     const std::string& minorAxis) const
260 {
261   FeaturePtr anEllipse = feature();
262   CompositeFeaturePtr aSketch = sketchForFeature(anEllipse);
263
264   std::list<FeaturePtr> anEntities;
265   if (!center.empty()) {
266     anEntities.push_back(
267         createPoint(aSketch, anEllipse, SketchPlugin_Ellipse::CENTER_ID(), center));
268   }
269   if (!firstFocus.empty()) {
270     anEntities.push_back(
271         createPoint(aSketch, anEllipse, SketchPlugin_Ellipse::FIRST_FOCUS_ID(), firstFocus));
272   }
273   if (!secondFocus.empty()) {
274     anEntities.push_back(
275         createPoint(aSketch, anEllipse, SketchPlugin_Ellipse::SECOND_FOCUS_ID(), secondFocus));
276   }
277   if (!majorAxisStart.empty()) {
278     anEntities.push_back(createPoint(aSketch, anEllipse,
279         SketchPlugin_Ellipse::MAJOR_AXIS_START_ID(), majorAxisStart));
280   }
281   if (!majorAxisEnd.empty()) {
282     anEntities.push_back(createPoint(aSketch, anEllipse,
283         SketchPlugin_Ellipse::MAJOR_AXIS_END_ID(), majorAxisEnd));
284   }
285   if (!minorAxisStart.empty()) {
286     anEntities.push_back(createPoint(aSketch, anEllipse,
287         SketchPlugin_Ellipse::MINOR_AXIS_START_ID(), minorAxisStart));
288   }
289   if (!minorAxisEnd.empty()) {
290     anEntities.push_back(createPoint(aSketch, anEllipse,
291         SketchPlugin_Ellipse::MINOR_AXIS_END_ID(), minorAxisEnd));
292   }
293   if (!majorAxis.empty()) {
294     anEntities.push_back(
295         createAxis(aSketch, anEllipse, SketchPlugin_Ellipse::MAJOR_AXIS_START_ID(),
296                    SketchPlugin_Ellipse::MAJOR_AXIS_END_ID(), majorAxis));
297   }
298   if (!minorAxis.empty()) {
299     anEntities.push_back(
300         createAxis(aSketch, anEllipse, SketchPlugin_Ellipse::MINOR_AXIS_START_ID(),
301                    SketchPlugin_Ellipse::MINOR_AXIS_END_ID(), minorAxis));
302   }
303
304   return SketchAPI_SketchEntity::wrap(anEntities);
305 }
306
307 static void ellipseAttributeAndAuxiliaryFeature(
308     const FeaturePtr& theInternalConstraint,
309     std::map<std::string, FeaturePtr>& theAttrToFeature)
310 {
311   AttributeRefAttrPtr aRefAttrA =
312       theInternalConstraint->refattr(SketchPlugin_Constraint::ENTITY_A());
313   AttributeRefAttrPtr aRefAttrB =
314       theInternalConstraint->refattr(SketchPlugin_Constraint::ENTITY_B());
315   // the first point is usually an ellipse attribute
316   // and the second point is an attribute of the auxiliary feature
317   ObjectPtr anAuxObject;
318   if (aRefAttrB->isObject())
319     anAuxObject = aRefAttrB->object();
320   else
321     anAuxObject = aRefAttrB->attr()->owner();
322
323   FeaturePtr anAuxFeature = ModelAPI_Feature::feature(anAuxObject);
324   if (anAuxFeature->getKind() == SketchPlugin_Point::ID())
325     theAttrToFeature[aRefAttrA->attr()->id()] = anAuxFeature;
326   else {
327     const std::string& anAttrID = aRefAttrA->attr()->id();
328     if (anAttrID == SketchPlugin_Ellipse::MAJOR_AXIS_START_ID() ||
329         anAttrID == SketchPlugin_Ellipse::MAJOR_AXIS_END_ID())
330       theAttrToFeature[MAJOR_AXIS_ID] = anAuxFeature;
331     else if (anAttrID == SketchPlugin_Ellipse::MINOR_AXIS_START_ID() ||
332              anAttrID == SketchPlugin_Ellipse::MINOR_AXIS_END_ID())
333       theAttrToFeature[MINOR_AXIS_ID] = anAuxFeature;
334   }
335 }
336
337 void SketchAPI_Ellipse::dump(ModelHighAPI_Dumper& theDumper) const
338 {
339   if (isCopy())
340     return; // no need to dump copied feature
341
342   FeaturePtr aBase = feature();
343   const std::string& aSketchName = theDumper.parentName(aBase);
344
345   AttributeSelectionPtr anExternal = aBase->selection(SketchPlugin_SketchEntity::EXTERNAL_ID());
346   if (anExternal->context()) {
347     // circle is external
348     theDumper << aBase << " = " << aSketchName << ".addEllipse(" << anExternal << ")" << std::endl;
349   } else {
350     // ellipse given by center, focus and radius
351     theDumper << aBase << " = " << aSketchName << ".addEllipse("
352               << center() << ", " << firstFocus() << ", " << minorRadius() << ")" << std::endl;
353   }
354   // dump "auxiliary" flag if necessary
355   SketchAPI_SketchEntity::dump(theDumper);
356
357   // dump auxiliary features produced by ellipse
358   std::map<std::string, FeaturePtr> anAuxFeatures;
359   const std::set<AttributePtr>& aRefs = aBase->data()->refsToMe();
360   for (std::set<AttributePtr>::const_iterator aRefIt = aRefs.begin();
361        aRefIt != aRefs.end(); ++aRefIt) {
362     FeaturePtr anOwner = ModelAPI_Feature::feature((*aRefIt)->owner());
363     if (anOwner->getKind() != SketchPlugin_ConstraintCoincidenceInternal::ID())
364       continue; // process internal constraints only
365     ellipseAttributeAndAuxiliaryFeature(anOwner, anAuxFeatures);
366   }
367   if (!anAuxFeatures.empty()) {
368     typedef std::pair<std::string, std::string> PairOfStrings;
369     static PairOfStrings anAttributes[] = {
370         PairOfStrings(SketchPlugin_Ellipse::CENTER_ID(), "center"),
371         PairOfStrings(SketchPlugin_Ellipse::FIRST_FOCUS_ID(), "firstFocus"),
372         PairOfStrings(SketchPlugin_Ellipse::SECOND_FOCUS_ID(), "secondFocus"),
373         PairOfStrings(SketchPlugin_Ellipse::MAJOR_AXIS_START_ID(), "majorAxisStart"),
374         PairOfStrings(SketchPlugin_Ellipse::MAJOR_AXIS_END_ID(), "majorAxisEnd"),
375         PairOfStrings(SketchPlugin_Ellipse::MINOR_AXIS_START_ID(), "minorAxisStart"),
376         PairOfStrings(SketchPlugin_Ellipse::MINOR_AXIS_END_ID(), "minorAxisEnd"),
377         PairOfStrings(MAJOR_AXIS_ID, MAJOR_AXIS_ID),
378         PairOfStrings(MINOR_AXIS_ID, MINOR_AXIS_ID)
379     };
380
381     theDumper << "[";
382     bool isFirst = true;
383     for (PairOfStrings* anIt = std::begin(anAttributes);
384          anIt != std::end(anAttributes); ++anIt) {
385       std::map<std::string, FeaturePtr>::iterator aFound = anAuxFeatures.find(anIt->first);
386       if (aFound == anAuxFeatures.end())
387         continue;
388       if (!isFirst)
389         theDumper << ", ";
390       theDumper << theDumper.name(aFound->second, false);
391       theDumper.doNotDumpFeature(aFound->second);
392       isFirst = false;
393     }
394     theDumper << "] = " << theDumper.name(aBase) << ".construction(";
395     isFirst = true;
396     for (PairOfStrings* anIt = std::begin(anAttributes);
397          anIt != std::end(anAttributes); ++anIt) {
398       std::map<std::string, FeaturePtr>::iterator aFound = anAuxFeatures.find(anIt->first);
399       if (aFound == anAuxFeatures.end())
400         continue;
401       if (!isFirst)
402         theDumper << ", ";
403       isFirst = false;
404       theDumper << anIt->second << " = \"";
405       if (aFound->second->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->value())
406         theDumper << AUXILIARY_VALUE;
407       else
408         theDumper << aFound->second->name();
409       theDumper << "\"";
410     }
411     theDumper << ")" << std::endl;
412   }
413 }