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>
26 #include <SketchPlugin_Arc.h>
27 #include <SketchPlugin_Circle.h>
28 #include <SketchPlugin_Ellipse.h>
29 #include <SketchPlugin_IntersectionPoint.h>
30 #include <SketchPlugin_Line.h>
31 #include <SketchPlugin_Point.h>
33 #include <GeomAPI_Dir2d.h>
34 #include <GeomAPI_Pnt2d.h>
35 #include <GeomAPI_XY.h>
37 static bool isAttributeApplicable(const std::string& theAttrName,
38 const std::string& theOwnerName);
40 static EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes);
41 static EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes);
42 static EntityWrapperPtr createArc(const AttributeEntityMap& theAttributes,
43 PlaneGCSSolver_Storage* theStorage);
44 static EntityWrapperPtr createEllipse(const AttributeEntityMap& theAttributes);
47 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(
48 PlaneGCSSolver_Storage* theStorage)
49 : PlaneGCSSolver_AttributeBuilder(theStorage)
53 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(const StoragePtr& theStorage)
54 : PlaneGCSSolver_AttributeBuilder(theStorage)
58 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createAttribute(
59 AttributePtr theAttribute)
61 FeaturePtr anOwner = ModelAPI_Feature::feature(theAttribute->owner());
62 EntityWrapperPtr anAttr;
63 if (isAttributeApplicable(theAttribute->id(), anOwner->getKind()))
64 anAttr = PlaneGCSSolver_AttributeBuilder::createAttribute(theAttribute);
66 myAttributes[theAttribute] = anAttr;
70 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createFeature(FeaturePtr theFeature)
72 EntityWrapperPtr aResult;
74 aResult = myStorage->entity(theFeature);
78 // Process SketchPlugin features only
79 std::shared_ptr<SketchPlugin_Feature> aFeature =
80 std::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
84 // Verify the feature by its kind
85 const std::string& aFeatureKind = aFeature->getKind();
87 if (aFeatureKind == SketchPlugin_Line::ID())
88 aResult = createLine(myAttributes);
90 else if (aFeatureKind == SketchPlugin_Circle::ID())
91 aResult = createCircle(myAttributes);
93 else if (aFeatureKind == SketchPlugin_Arc::ID())
94 aResult = createArc(myAttributes, myStorage);
96 else if (aFeatureKind == SketchPlugin_Ellipse::ID())
97 aResult = createEllipse(myAttributes);
98 // Point (it has low probability to be an attribute of constraint, so it is checked at the end)
99 else if (aFeatureKind == SketchPlugin_Point::ID() ||
100 aFeatureKind == SketchPlugin_IntersectionPoint::ID()) {
101 AttributeEntityMap::const_iterator anIt = myAttributes.begin();
102 for (; anIt != myAttributes.end(); ++anIt)
103 if (anIt->first->id() == SketchPlugin_Point::COORD_ID()) {
104 aResult = anIt->second;
109 if (aResult && !myStorage)
110 aResult->setExternal(true);
112 myAttributes.clear();
120 // ============== Auxiliary functions =====================================
121 EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes)
123 std::shared_ptr<GCS::Line> aNewLine(new GCS::Line);
125 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
126 for (; anIt != theAttributes.end(); ++anIt) {
127 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
128 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
132 if (anIt->first->id() == SketchPlugin_Line::START_ID())
133 aNewLine->p1 = *(aPoint->point());
134 else if (anIt->first->id() == SketchPlugin_Line::END_ID())
135 aNewLine->p2 = *(aPoint->point());
138 return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewLine));
141 EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes)
143 std::shared_ptr<GCS::Circle> aNewCircle(new GCS::Circle);
145 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
146 for (; anIt != theAttributes.end(); ++anIt) {
147 if (anIt->first->id() == SketchPlugin_Circle::CENTER_ID()) {
148 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
149 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
150 aNewCircle->center = *(aPoint->point());
152 else if(anIt->first->id() == SketchPlugin_Circle::RADIUS_ID()) {
153 ScalarWrapperPtr aScalar =
154 std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(anIt->second);
155 aNewCircle->rad = aScalar->scalar();
159 return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewCircle));
162 static double* createParameter(PlaneGCSSolver_Storage* theStorage)
164 return theStorage ? theStorage->createParameter() : (new double(0));
167 EntityWrapperPtr createArc(const AttributeEntityMap& theAttributes,
168 PlaneGCSSolver_Storage* theStorage)
170 std::shared_ptr<GCS::Arc> aNewArc(new GCS::Arc);
171 BooleanWrapperPtr isReversed;
173 // Base attributes of arc (center, start and end points)
174 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
175 for (; anIt != theAttributes.end(); ++anIt) {
176 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
177 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
179 if (anIt->first->id() == SketchPlugin_Arc::CENTER_ID())
180 aNewArc->center = *(aPoint->point());
181 else if (anIt->first->id() == SketchPlugin_Arc::START_ID())
182 aNewArc->start = *(aPoint->point());
183 else if (anIt->first->id() == SketchPlugin_Arc::END_ID())
184 aNewArc->end = *(aPoint->point());
188 isReversed = std::dynamic_pointer_cast<PlaneGCSSolver_BooleanWrapper>(anIt->second);
192 // Additional atrtributes of arc necessary for PlaneGCS solver
193 // (start and end angles, radius)
194 aNewArc->startAngle = createParameter(theStorage);
195 aNewArc->endAngle = createParameter(theStorage);
196 aNewArc->rad = createParameter(theStorage);
198 static std::shared_ptr<GeomAPI_Dir2d> OX(new GeomAPI_Dir2d(1.0, 0.0));
199 std::shared_ptr<GeomAPI_Pnt2d> aCenter(
200 new GeomAPI_Pnt2d(*aNewArc->center.x, *aNewArc->center.y));
201 std::shared_ptr<GeomAPI_Pnt2d> aStart(
202 new GeomAPI_Pnt2d(*aNewArc->start.x, *aNewArc->start.y));
204 *aNewArc->rad = aStart->distance(aCenter);
206 std::shared_ptr<GeomAPI_Dir2d> aDir(new GeomAPI_Dir2d(aStart->xy()->decreased(aCenter->xy())));
207 *aNewArc->startAngle = OX->angle(aDir);
209 aDir = std::shared_ptr<GeomAPI_Dir2d>(
210 new GeomAPI_Dir2d((*aNewArc->end.x) - aCenter->x(), (*aNewArc->end.y) - aCenter->y()));
211 *aNewArc->endAngle = OX->angle(aDir);
213 EdgeWrapperPtr anArcWrapper(new PlaneGCSSolver_EdgeWrapper(aNewArc));
214 anArcWrapper->setReversed(isReversed);
218 EntityWrapperPtr createEllipse(const AttributeEntityMap& theAttributes)
220 std::shared_ptr<GCS::Ellipse> aNewEllipse(new GCS::Ellipse);
222 std::map<std::string, EntityWrapperPtr> anAdditionalAttributes;
224 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
225 for (; anIt != theAttributes.end(); ++anIt) {
226 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
227 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
229 if (anIt->first->id() == SketchPlugin_Ellipse::CENTER_ID())
230 aNewEllipse->center = *(aPoint->point());
231 else if (anIt->first->id() == SketchPlugin_Ellipse::FIRST_FOCUS_ID())
232 aNewEllipse->focus1 = *(aPoint->point());
234 anAdditionalAttributes[anIt->first->id()] = anIt->second;
236 else if (anIt->first->id() == SketchPlugin_Ellipse::MINOR_RADIUS_ID()) {
237 ScalarWrapperPtr aScalar =
238 std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(anIt->second);
239 aNewEllipse->radmin = aScalar->scalar();
242 anAdditionalAttributes[anIt->first->id()] = anIt->second;
245 EntityWrapperPtr anEllipseWrapper(new PlaneGCSSolver_EdgeWrapper(aNewEllipse));
246 anEllipseWrapper->setAdditionalAttributes(anAdditionalAttributes);
247 return anEllipseWrapper;
250 bool isAttributeApplicable(const std::string& theAttrName, const std::string& theOwnerName)
252 if (theOwnerName == SketchPlugin_Arc::ID()) {
253 return theAttrName == SketchPlugin_Arc::CENTER_ID() ||
254 theAttrName == SketchPlugin_Arc::START_ID() ||
255 theAttrName == SketchPlugin_Arc::END_ID() ||
256 theAttrName == SketchPlugin_Arc::REVERSED_ID();
258 else if (theOwnerName == SketchPlugin_Circle::ID()) {
259 return theAttrName == SketchPlugin_Circle::CENTER_ID() ||
260 theAttrName == SketchPlugin_Circle::RADIUS_ID();
262 else if (theOwnerName == SketchPlugin_Line::ID()) {
263 return theAttrName == SketchPlugin_Line::START_ID() ||
264 theAttrName == SketchPlugin_Line::END_ID();
266 else if (theOwnerName == SketchPlugin_Ellipse::ID()) {
267 return theAttrName == SketchPlugin_Ellipse::CENTER_ID() ||
268 theAttrName == SketchPlugin_Ellipse::FIRST_FOCUS_ID() ||
269 theAttrName == SketchPlugin_Ellipse::SECOND_FOCUS_ID() ||
270 theAttrName == SketchPlugin_Ellipse::MAJOR_AXIS_START_ID() ||
271 theAttrName == SketchPlugin_Ellipse::MAJOR_AXIS_END_ID() ||
272 theAttrName == SketchPlugin_Ellipse::MINOR_AXIS_START_ID() ||
273 theAttrName == SketchPlugin_Ellipse::MINOR_AXIS_END_ID() ||
274 theAttrName == SketchPlugin_Ellipse::MAJOR_RADIUS_ID() ||
275 theAttrName == SketchPlugin_Ellipse::MINOR_RADIUS_ID();
278 // suppose that all remaining features are points
279 return theAttrName == SketchPlugin_Point::COORD_ID();