]> SALOME platform Git repositories - modules/shaper.git/blob - src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_FeatureBuilder.cpp
Salome HOME
Task 2.12. New entities: ellipses and arcs of ellipses (issue #3003)
[modules/shaper.git] / src / SketchSolver / PlaneGCSSolver / PlaneGCSSolver_FeatureBuilder.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 <PlaneGCSSolver_FeatureBuilder.h>
21 #include <PlaneGCSSolver_EdgeWrapper.h>
22 #include <PlaneGCSSolver_PointWrapper.h>
23 #include <PlaneGCSSolver_ScalarWrapper.h>
24 #include <PlaneGCSSolver_BooleanWrapper.h>
25
26 #include <SketchPlugin_Arc.h>
27 #include <SketchPlugin_Circle.h>
28 #include <SketchPlugin_Ellipse.h>
29 #include <SketchPlugin_IntersectionPoint.h>
30 #include <SketchPlugin_Line.h>
31 #include <SketchPlugin_Point.h>
32
33 #include <GeomAPI_Dir2d.h>
34 #include <GeomAPI_Pnt2d.h>
35 #include <GeomAPI_XY.h>
36
37 static bool isAttributeApplicable(const std::string& theAttrName,
38                                   const std::string& theOwnerName);
39
40 static EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes);
41 static EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes);
42 static EntityWrapperPtr createArc(const AttributeEntityMap&    theAttributes,
43                                   PlaneGCSSolver_Storage*      theStorage);
44 static EntityWrapperPtr createEllipse(const AttributeEntityMap& theAttributes);
45
46
47 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(
48     PlaneGCSSolver_Storage* theStorage)
49   : PlaneGCSSolver_AttributeBuilder(theStorage)
50 {
51 }
52
53 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(const StoragePtr& theStorage)
54   : PlaneGCSSolver_AttributeBuilder(theStorage)
55 {
56 }
57
58 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createAttribute(
59     AttributePtr theAttribute)
60 {
61   FeaturePtr anOwner = ModelAPI_Feature::feature(theAttribute->owner());
62   EntityWrapperPtr anAttr;
63   if (isAttributeApplicable(theAttribute->id(), anOwner->getKind()))
64     anAttr = PlaneGCSSolver_AttributeBuilder::createAttribute(theAttribute);
65   if (anAttr)
66     myAttributes[theAttribute] = anAttr;
67   return anAttr;
68 }
69
70 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createFeature(FeaturePtr theFeature)
71 {
72   EntityWrapperPtr aResult;
73   if (myStorage)
74     aResult = myStorage->entity(theFeature);
75   if (aResult)
76     return aResult;
77
78   // Process SketchPlugin features only
79   std::shared_ptr<SketchPlugin_Feature> aFeature =
80       std::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
81   if (!aFeature)
82     return aResult;
83
84   // Verify the feature by its kind
85   const std::string& aFeatureKind = aFeature->getKind();
86   // Line
87   if (aFeatureKind == SketchPlugin_Line::ID())
88     aResult = createLine(myAttributes);
89   // Circle
90   else if (aFeatureKind == SketchPlugin_Circle::ID())
91     aResult = createCircle(myAttributes);
92   // Arc
93   else if (aFeatureKind == SketchPlugin_Arc::ID())
94     aResult = createArc(myAttributes, myStorage);
95   // Ellipse
96   else if (aFeatureKind == SketchPlugin_Ellipse::ID())
97     aResult = createEllipse(myAttributes);
98   // Point (it has low probability to be an attribute of constraint, so it is checked at the end)
99   else if (aFeatureKind == SketchPlugin_Point::ID() ||
100            aFeatureKind == SketchPlugin_IntersectionPoint::ID()) {
101     AttributeEntityMap::const_iterator anIt = myAttributes.begin();
102     for (; anIt != myAttributes.end(); ++anIt)
103       if (anIt->first->id() == SketchPlugin_Point::COORD_ID()) {
104         aResult = anIt->second;
105         break;
106       }
107   }
108
109   if (aResult && !myStorage)
110     aResult->setExternal(true);
111
112   myAttributes.clear();
113   return aResult;
114 }
115
116
117
118
119
120 // ==============   Auxiliary functions   =====================================
121 EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes)
122 {
123   std::shared_ptr<GCS::Line> aNewLine(new GCS::Line);
124
125   AttributeEntityMap::const_iterator anIt = theAttributes.begin();
126   for (; anIt != theAttributes.end(); ++anIt) {
127     std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
128         std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
129     if (!aPoint)
130       continue;
131
132     if (anIt->first->id() == SketchPlugin_Line::START_ID())
133       aNewLine->p1 = *(aPoint->point());
134     else if (anIt->first->id() == SketchPlugin_Line::END_ID())
135       aNewLine->p2 = *(aPoint->point());
136   }
137
138   return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewLine));
139 }
140
141 EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes)
142 {
143   std::shared_ptr<GCS::Circle> aNewCircle(new GCS::Circle);
144
145   AttributeEntityMap::const_iterator anIt = theAttributes.begin();
146   for (; anIt != theAttributes.end(); ++anIt) {
147     if (anIt->first->id() == SketchPlugin_Circle::CENTER_ID()) {
148       std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
149           std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
150       aNewCircle->center = *(aPoint->point());
151     }
152     else if(anIt->first->id() == SketchPlugin_Circle::RADIUS_ID()) {
153       ScalarWrapperPtr aScalar =
154           std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(anIt->second);
155       aNewCircle->rad = aScalar->scalar();
156     }
157   }
158
159   return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewCircle));
160 }
161
162 static double* createParameter(PlaneGCSSolver_Storage* theStorage)
163 {
164   return theStorage ? theStorage->createParameter() : (new double(0));
165 }
166
167 EntityWrapperPtr createArc(const AttributeEntityMap&    theAttributes,
168                            PlaneGCSSolver_Storage*      theStorage)
169 {
170   std::shared_ptr<GCS::Arc> aNewArc(new GCS::Arc);
171   BooleanWrapperPtr isReversed;
172
173   // Base attributes of arc (center, start and end points)
174   AttributeEntityMap::const_iterator anIt = theAttributes.begin();
175   for (; anIt != theAttributes.end(); ++anIt) {
176     std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
177         std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
178     if (aPoint) {
179       if (anIt->first->id() == SketchPlugin_Arc::CENTER_ID())
180         aNewArc->center = *(aPoint->point());
181       else if (anIt->first->id() == SketchPlugin_Arc::START_ID())
182         aNewArc->start = *(aPoint->point());
183       else if (anIt->first->id() == SketchPlugin_Arc::END_ID())
184         aNewArc->end = *(aPoint->point());
185     }
186     else {
187       // reversed flag
188       isReversed = std::dynamic_pointer_cast<PlaneGCSSolver_BooleanWrapper>(anIt->second);
189     }
190   }
191
192   // Additional atrtributes of arc necessary for PlaneGCS solver
193   // (start and end angles, radius)
194   aNewArc->startAngle = createParameter(theStorage);
195   aNewArc->endAngle   = createParameter(theStorage);
196   aNewArc->rad        = createParameter(theStorage);
197
198   static std::shared_ptr<GeomAPI_Dir2d> OX(new GeomAPI_Dir2d(1.0, 0.0));
199   std::shared_ptr<GeomAPI_Pnt2d> aCenter(
200       new GeomAPI_Pnt2d(*aNewArc->center.x, *aNewArc->center.y));
201   std::shared_ptr<GeomAPI_Pnt2d> aStart(
202       new GeomAPI_Pnt2d(*aNewArc->start.x, *aNewArc->start.y));
203
204   *aNewArc->rad = aStart->distance(aCenter);
205
206   std::shared_ptr<GeomAPI_Dir2d> aDir(new GeomAPI_Dir2d(aStart->xy()->decreased(aCenter->xy())));
207   *aNewArc->startAngle = OX->angle(aDir);
208
209   aDir = std::shared_ptr<GeomAPI_Dir2d>(
210       new GeomAPI_Dir2d((*aNewArc->end.x) - aCenter->x(), (*aNewArc->end.y) - aCenter->y()));
211   *aNewArc->endAngle = OX->angle(aDir);
212
213   EdgeWrapperPtr anArcWrapper(new PlaneGCSSolver_EdgeWrapper(aNewArc));
214   anArcWrapper->setReversed(isReversed);
215   return anArcWrapper;
216 }
217
218 EntityWrapperPtr createEllipse(const AttributeEntityMap& theAttributes)
219 {
220   std::shared_ptr<GCS::Ellipse> aNewEllipse(new GCS::Ellipse);
221
222   std::map<std::string, EntityWrapperPtr> anAdditionalAttributes;
223
224   AttributeEntityMap::const_iterator anIt = theAttributes.begin();
225   for (; anIt != theAttributes.end(); ++anIt) {
226     std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
227         std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
228     if (aPoint) {
229       if (anIt->first->id() == SketchPlugin_Ellipse::CENTER_ID())
230         aNewEllipse->center = *(aPoint->point());
231       else if (anIt->first->id() == SketchPlugin_Ellipse::FIRST_FOCUS_ID())
232         aNewEllipse->focus1 = *(aPoint->point());
233       else
234         anAdditionalAttributes[anIt->first->id()] = anIt->second;
235     }
236     else if (anIt->first->id() == SketchPlugin_Ellipse::MINOR_RADIUS_ID()) {
237       ScalarWrapperPtr aScalar =
238           std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(anIt->second);
239       aNewEllipse->radmin = aScalar->scalar();
240     }
241     else
242       anAdditionalAttributes[anIt->first->id()] = anIt->second;
243   }
244
245   EntityWrapperPtr anEllipseWrapper(new PlaneGCSSolver_EdgeWrapper(aNewEllipse));
246   anEllipseWrapper->setAdditionalAttributes(anAdditionalAttributes);
247   return anEllipseWrapper;
248 }
249
250 bool isAttributeApplicable(const std::string& theAttrName, const std::string& theOwnerName)
251 {
252   if (theOwnerName == SketchPlugin_Arc::ID()) {
253     return theAttrName == SketchPlugin_Arc::CENTER_ID() ||
254            theAttrName == SketchPlugin_Arc::START_ID() ||
255            theAttrName == SketchPlugin_Arc::END_ID() ||
256            theAttrName == SketchPlugin_Arc::REVERSED_ID();
257   }
258   else if (theOwnerName == SketchPlugin_Circle::ID()) {
259     return theAttrName == SketchPlugin_Circle::CENTER_ID() ||
260            theAttrName == SketchPlugin_Circle::RADIUS_ID();
261   }
262   else if (theOwnerName == SketchPlugin_Line::ID()) {
263     return theAttrName == SketchPlugin_Line::START_ID() ||
264            theAttrName == SketchPlugin_Line::END_ID();
265   }
266   else if (theOwnerName == SketchPlugin_Ellipse::ID()) {
267     return theAttrName == SketchPlugin_Ellipse::CENTER_ID() ||
268            theAttrName == SketchPlugin_Ellipse::FIRST_FOCUS_ID() ||
269            theAttrName == SketchPlugin_Ellipse::SECOND_FOCUS_ID() ||
270            theAttrName == SketchPlugin_Ellipse::MAJOR_AXIS_START_ID() ||
271            theAttrName == SketchPlugin_Ellipse::MAJOR_AXIS_END_ID() ||
272            theAttrName == SketchPlugin_Ellipse::MINOR_AXIS_START_ID() ||
273            theAttrName == SketchPlugin_Ellipse::MINOR_AXIS_END_ID() ||
274            theAttrName == SketchPlugin_Ellipse::MAJOR_RADIUS_ID() ||
275            theAttrName == SketchPlugin_Ellipse::MINOR_RADIUS_ID();
276   }
277
278   // suppose that all remaining features are points
279   return theAttrName == SketchPlugin_Point::COORD_ID();
280 }