Salome HOME
Correct misprint
[modules/shaper.git] / src / SketchSolver / PlaneGCSSolver / PlaneGCSSolver_FeatureBuilder.cpp
1 // Copyright (C) 2014-2017  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
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 //
20
21 #include <PlaneGCSSolver_FeatureBuilder.h>
22 #include <PlaneGCSSolver_EdgeWrapper.h>
23 #include <PlaneGCSSolver_PointWrapper.h>
24 #include <PlaneGCSSolver_ScalarWrapper.h>
25
26 #include <SketchPlugin_Arc.h>
27 #include <SketchPlugin_Circle.h>
28 #include <SketchPlugin_IntersectionPoint.h>
29 #include <SketchPlugin_Line.h>
30 #include <SketchPlugin_Point.h>
31
32 #include <GeomAPI_Dir2d.h>
33 #include <GeomAPI_Pnt2d.h>
34 #include <GeomAPI_XY.h>
35
36 static bool isAttributeApplicable(const std::string& theAttrName,
37                                   const std::string& theOwnerName);
38
39 static EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes);
40 static EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes);
41 static EntityWrapperPtr createArc(const AttributeEntityMap&    theAttributes,
42                                   PlaneGCSSolver_Storage*      theStorage);
43
44
45 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(
46     PlaneGCSSolver_Storage* theStorage)
47   : PlaneGCSSolver_AttributeBuilder(theStorage)
48 {
49 }
50
51 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(const StoragePtr& theStorage)
52   : PlaneGCSSolver_AttributeBuilder(theStorage)
53 {
54 }
55
56 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createAttribute(
57     AttributePtr theAttribute)
58 {
59   FeaturePtr anOwner = ModelAPI_Feature::feature(theAttribute->owner());
60   EntityWrapperPtr anAttr;
61   if (isAttributeApplicable(theAttribute->id(), anOwner->getKind()))
62     anAttr = PlaneGCSSolver_AttributeBuilder::createAttribute(theAttribute);
63   if (anAttr)
64     myAttributes[theAttribute] = anAttr;
65   return anAttr;
66 }
67
68 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createFeature(FeaturePtr theFeature)
69 {
70   EntityWrapperPtr aResult;
71   if (myStorage)
72     aResult = myStorage->entity(theFeature);
73   if (aResult)
74     return aResult;
75
76   // Process SketchPlugin features only
77   std::shared_ptr<SketchPlugin_Feature> aFeature =
78       std::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
79   if (!aFeature)
80     return aResult;
81
82   // Verify the feature by its kind
83   const std::string& aFeatureKind = aFeature->getKind();
84   // Line
85   if (aFeatureKind == SketchPlugin_Line::ID())
86     aResult = createLine(myAttributes);
87   // Circle
88   else if (aFeatureKind == SketchPlugin_Circle::ID())
89     aResult = createCircle(myAttributes);
90   // Arc
91   else if (aFeatureKind == SketchPlugin_Arc::ID())
92     aResult = createArc(myAttributes, myStorage);
93   // Point (it has low probability to be an attribute of constraint, so it is checked at the end)
94   else if (aFeatureKind == SketchPlugin_Point::ID() ||
95            aFeatureKind == SketchPlugin_IntersectionPoint::ID()) {
96     AttributeEntityMap::const_iterator anIt = myAttributes.begin();
97     for (; anIt != myAttributes.end(); ++anIt)
98       if (anIt->first->id() == SketchPlugin_Point::COORD_ID()) {
99         aResult = anIt->second;
100         break;
101       }
102   }
103
104   if (aResult && !myStorage)
105     aResult->setExternal(true);
106
107   myAttributes.clear();
108   return aResult;
109 }
110
111
112
113
114
115 // ==============   Auxiliary functions   =====================================
116 EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes)
117 {
118   std::shared_ptr<GCS::Line> aNewLine(new GCS::Line);
119
120   AttributeEntityMap::const_iterator anIt = theAttributes.begin();
121   for (; anIt != theAttributes.end(); ++anIt) {
122     std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
123         std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
124     if (!aPoint)
125       continue;
126
127     if (anIt->first->id() == SketchPlugin_Line::START_ID())
128       aNewLine->p1 = *(aPoint->point());
129     else if (anIt->first->id() == SketchPlugin_Line::END_ID())
130       aNewLine->p2 = *(aPoint->point());
131   }
132
133   return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewLine));
134 }
135
136 EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes)
137 {
138   std::shared_ptr<GCS::Circle> aNewCircle(new GCS::Circle);
139
140   AttributeEntityMap::const_iterator anIt = theAttributes.begin();
141   for (; anIt != theAttributes.end(); ++anIt) {
142     if (anIt->first->id() == SketchPlugin_Circle::CENTER_ID()) {
143       std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
144           std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
145       aNewCircle->center = *(aPoint->point());
146     }
147     else if(anIt->first->id() == SketchPlugin_Circle::RADIUS_ID()) {
148       ScalarWrapperPtr aScalar =
149           std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(anIt->second);
150       aNewCircle->rad = aScalar->scalar();
151     }
152   }
153
154   return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewCircle));
155 }
156
157 static double* createParameter(PlaneGCSSolver_Storage* theStorage)
158 {
159   return theStorage ? theStorage->createParameter() : (new double(0));
160 }
161
162 EntityWrapperPtr createArc(const AttributeEntityMap&    theAttributes,
163                            PlaneGCSSolver_Storage*      theStorage)
164 {
165   std::shared_ptr<GCS::Arc> aNewArc(new GCS::Arc);
166
167   // Base attributes of arc (center, start and end points)
168   AttributeEntityMap::const_iterator anIt = theAttributes.begin();
169   for (; anIt != theAttributes.end(); ++anIt) {
170     std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
171         std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
172     if (!aPoint)
173       continue;
174
175     if (anIt->first->id() == SketchPlugin_Arc::CENTER_ID())
176       aNewArc->center = *(aPoint->point());
177     else if (anIt->first->id() == SketchPlugin_Arc::START_ID())
178       aNewArc->start = *(aPoint->point());
179     else if (anIt->first->id() == SketchPlugin_Arc::END_ID())
180       aNewArc->end = *(aPoint->point());
181   }
182
183   // Additional atrtributes of arc necessary for PlaneGCS solver
184   // (start and end angles, radius)
185   aNewArc->startAngle = createParameter(theStorage);
186   aNewArc->endAngle   = createParameter(theStorage);
187   aNewArc->rad        = createParameter(theStorage);
188
189   static std::shared_ptr<GeomAPI_Dir2d> OX(new GeomAPI_Dir2d(1.0, 0.0));
190   std::shared_ptr<GeomAPI_Pnt2d> aCenter(
191       new GeomAPI_Pnt2d(*aNewArc->center.x, *aNewArc->center.y));
192   std::shared_ptr<GeomAPI_Pnt2d> aStart(
193       new GeomAPI_Pnt2d(*aNewArc->start.x, *aNewArc->start.y));
194
195   *aNewArc->rad = aStart->distance(aCenter);
196
197   std::shared_ptr<GeomAPI_Dir2d> aDir(new GeomAPI_Dir2d(aStart->xy()->decreased(aCenter->xy())));
198   *aNewArc->startAngle = OX->angle(aDir);
199
200   aDir = std::shared_ptr<GeomAPI_Dir2d>(
201       new GeomAPI_Dir2d((*aNewArc->end.x) - aCenter->x(), (*aNewArc->end.y) - aCenter->y()));
202   *aNewArc->endAngle = OX->angle(aDir);
203
204   return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewArc));
205 }
206
207 bool isAttributeApplicable(const std::string& theAttrName, const std::string& theOwnerName)
208 {
209   if (theOwnerName == SketchPlugin_Arc::ID()) {
210     return theAttrName == SketchPlugin_Arc::CENTER_ID() ||
211            theAttrName == SketchPlugin_Arc::START_ID() ||
212            theAttrName == SketchPlugin_Arc::END_ID();
213   }
214   else if (theOwnerName == SketchPlugin_Circle::ID()) {
215     return theAttrName == SketchPlugin_Circle::CENTER_ID() ||
216            theAttrName == SketchPlugin_Circle::RADIUS_ID();
217   }
218   else if (theOwnerName == SketchPlugin_Line::ID()) {
219     return theAttrName == SketchPlugin_Line::START_ID() ||
220            theAttrName == SketchPlugin_Line::END_ID();
221   }
222
223   // suppose that all remaining features are points
224   return theAttrName == SketchPlugin_Point::COORD_ID();
225 }