1 // Copyright (C) 2014-2019 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
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>
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>
35 #include <GeomAPI_Dir2d.h>
36 #include <GeomAPI_Pnt2d.h>
37 #include <GeomAPI_XY.h>
39 static bool isAttributeApplicable(const std::string& theAttrName,
40 const std::string& theOwnerName);
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);
51 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(
52 PlaneGCSSolver_Storage* theStorage)
53 : PlaneGCSSolver_AttributeBuilder(theStorage)
57 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(const StoragePtr& theStorage)
58 : PlaneGCSSolver_AttributeBuilder(theStorage)
62 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createAttribute(
63 AttributePtr theAttribute)
65 FeaturePtr anOwner = ModelAPI_Feature::feature(theAttribute->owner());
66 EntityWrapperPtr anAttr;
67 if (isAttributeApplicable(theAttribute->id(), anOwner->getKind()))
68 anAttr = PlaneGCSSolver_AttributeBuilder::createAttribute(theAttribute);
70 myAttributes[theAttribute] = anAttr;
74 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createFeature(FeaturePtr theFeature)
76 EntityWrapperPtr aResult;
78 aResult = myStorage->entity(theFeature);
82 // Process SketchPlugin features only
83 std::shared_ptr<SketchPlugin_Feature> aFeature =
84 std::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
88 // Verify the feature by its kind
89 const std::string& aFeatureKind = aFeature->getKind();
91 if (aFeatureKind == SketchPlugin_Line::ID())
92 aResult = createLine(myAttributes);
94 else if (aFeatureKind == SketchPlugin_Circle::ID())
95 aResult = createCircle(myAttributes);
97 else if (aFeatureKind == SketchPlugin_Arc::ID())
98 aResult = createArc(myAttributes, myStorage);
100 else if (aFeatureKind == SketchPlugin_Ellipse::ID())
101 aResult = createEllipse(myAttributes);
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;
116 if (aResult && !myStorage)
117 aResult->setExternal(true);
119 myAttributes.clear();
127 // ============== Auxiliary functions =====================================
128 EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes)
130 std::shared_ptr<GCS::Line> aNewLine(new GCS::Line);
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);
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());
145 return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewLine));
148 EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes)
150 std::shared_ptr<GCS::Circle> aNewCircle(new GCS::Circle);
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());
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();
166 return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewCircle));
169 static double* createParameter(PlaneGCSSolver_Storage* theStorage)
171 return theStorage ? theStorage->createParameter() : (new double(0));
174 EntityWrapperPtr createArc(const AttributeEntityMap& theAttributes,
175 PlaneGCSSolver_Storage* theStorage)
177 std::shared_ptr<GCS::Arc> aNewArc(new GCS::Arc);
178 BooleanWrapperPtr isReversed;
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);
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());
195 isReversed = std::dynamic_pointer_cast<PlaneGCSSolver_BooleanWrapper>(anIt->second);
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);
205 EdgeWrapperPtr anArcWrapper(new PlaneGCSSolver_EdgeWrapper(aNewArc));
206 anArcWrapper->setReversed(isReversed);
207 PlaneGCSSolver_Tools::recalculateArcParameters(anArcWrapper);
212 EntityWrapperPtr createEllipse(const AttributeEntityMap& theAttributes)
214 std::shared_ptr<GCS::Ellipse> aNewEllipse(new GCS::Ellipse);
216 std::map<std::string, EntityWrapperPtr> anAdditionalAttributes;
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);
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());
228 anAdditionalAttributes[anIt->first->id()] = anIt->second;
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();
236 anAdditionalAttributes[anIt->first->id()] = anIt->second;
239 EntityWrapperPtr anEllipseWrapper(new PlaneGCSSolver_EdgeWrapper(aNewEllipse));
240 anEllipseWrapper->setAdditionalAttributes(anAdditionalAttributes);
241 return anEllipseWrapper;
244 EntityWrapperPtr createEllipticArc(const AttributeEntityMap& theAttributes,
245 PlaneGCSSolver_Storage* theStorage)
247 std::shared_ptr<GCS::ArcOfEllipse> aNewArc(new GCS::ArcOfEllipse);
249 BooleanWrapperPtr isReversed;
250 std::map<std::string, EntityWrapperPtr> anAdditionalAttributes;
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);
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());
266 anAdditionalAttributes[anIt->first->id()] = anIt->second;
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();
273 else if (anIt->first->id() == SketchPlugin_EllipticArc::REVERSED_ID())
274 isReversed = std::dynamic_pointer_cast<PlaneGCSSolver_BooleanWrapper>(anIt->second);
276 anAdditionalAttributes[anIt->first->id()] = anIt->second;
279 // Additional attributes of elliptic arc necessary for PlaneGCS solver (start and end angles)
280 aNewArc->startAngle = createParameter(theStorage);
281 aNewArc->endAngle = createParameter(theStorage);
283 EdgeWrapperPtr anEllipseWrapper(new PlaneGCSSolver_EdgeWrapper(aNewArc));
284 anEllipseWrapper->setReversed(isReversed);
285 anEllipseWrapper->setAdditionalAttributes(anAdditionalAttributes);
286 PlaneGCSSolver_Tools::recalculateArcParameters(anEllipseWrapper);
288 return anEllipseWrapper;
291 bool isAttributeApplicable(const std::string& theAttrName, const std::string& theOwnerName)
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();
299 else if (theOwnerName == SketchPlugin_Circle::ID()) {
300 return theAttrName == SketchPlugin_Circle::CENTER_ID() ||
301 theAttrName == SketchPlugin_Circle::RADIUS_ID();
303 else if (theOwnerName == SketchPlugin_Line::ID()) {
304 return theAttrName == SketchPlugin_Line::START_ID() ||
305 theAttrName == SketchPlugin_Line::END_ID();
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();
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();
333 // suppose that all remaining features are points
334 return theAttrName == SketchPlugin_Point::COORD_ID();