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