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