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