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_PointArrayWrapper.h>
24 #include <PlaneGCSSolver_ScalarWrapper.h>
25 #include <PlaneGCSSolver_ScalarArrayWrapper.h>
26 #include <PlaneGCSSolver_BooleanWrapper.h>
27 #include <PlaneGCSSolver_Tools.h>
29 #include <SketchPlugin_Arc.h>
30 #include <SketchPlugin_BSpline.h>
31 #include <SketchPlugin_Circle.h>
32 #include <SketchPlugin_Ellipse.h>
33 #include <SketchPlugin_EllipticArc.h>
34 #include <SketchPlugin_IntersectionPoint.h>
35 #include <SketchPlugin_Line.h>
36 #include <SketchPlugin_Point.h>
38 #include <GeomAPI_Dir2d.h>
39 #include <GeomAPI_Pnt2d.h>
40 #include <GeomAPI_XY.h>
42 static bool isAttributeApplicable(const std::string& theAttrName,
43 const std::string& theOwnerName);
45 static EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes);
46 static EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes);
47 static EntityWrapperPtr createArc(const AttributeEntityMap& theAttributes,
48 PlaneGCSSolver_Storage* theStorage);
49 static EntityWrapperPtr createEllipse(const AttributeEntityMap& theAttributes);
50 static EntityWrapperPtr createEllipticArc(const AttributeEntityMap& theAttributes,
51 PlaneGCSSolver_Storage* theStorage);
52 static EntityWrapperPtr createBSpline(const AttributeEntityMap& theAttributes);
55 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(
56 PlaneGCSSolver_Storage* theStorage)
57 : PlaneGCSSolver_AttributeBuilder(theStorage)
61 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(const StoragePtr& theStorage)
62 : PlaneGCSSolver_AttributeBuilder(theStorage)
66 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createAttribute(
67 AttributePtr theAttribute)
69 FeaturePtr anOwner = ModelAPI_Feature::feature(theAttribute->owner());
70 EntityWrapperPtr anAttr;
71 if (isAttributeApplicable(theAttribute->id(), anOwner->getKind()))
72 anAttr = PlaneGCSSolver_AttributeBuilder::createAttribute(theAttribute);
74 myAttributes[theAttribute] = anAttr;
78 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createFeature(FeaturePtr theFeature)
80 EntityWrapperPtr aResult;
82 aResult = myStorage->entity(theFeature);
86 // Process SketchPlugin features only
87 std::shared_ptr<SketchPlugin_Feature> aFeature =
88 std::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
92 // Verify the feature by its kind
93 const std::string& aFeatureKind = aFeature->getKind();
95 if (aFeatureKind == SketchPlugin_Line::ID())
96 aResult = createLine(myAttributes);
98 else if (aFeatureKind == SketchPlugin_Circle::ID())
99 aResult = createCircle(myAttributes);
101 else if (aFeatureKind == SketchPlugin_Arc::ID())
102 aResult = createArc(myAttributes, myStorage);
104 else if (aFeatureKind == SketchPlugin_Ellipse::ID())
105 aResult = createEllipse(myAttributes);
107 else if (aFeatureKind == SketchPlugin_EllipticArc::ID())
108 aResult = createEllipticArc(myAttributes, myStorage);
110 else if (aFeatureKind == SketchPlugin_BSpline::ID())
111 aResult = createBSpline(myAttributes);
112 // Point (it has low probability to be an attribute of constraint, so it is checked at the end)
113 else if (aFeatureKind == SketchPlugin_Point::ID() ||
114 aFeatureKind == SketchPlugin_IntersectionPoint::ID()) {
115 AttributeEntityMap::const_iterator anIt = myAttributes.begin();
116 for (; anIt != myAttributes.end(); ++anIt)
117 if (anIt->first->id() == SketchPlugin_Point::COORD_ID()) {
118 aResult = anIt->second;
123 if (aResult && !myStorage)
124 aResult->setExternal(true);
126 myAttributes.clear();
134 // ============== Auxiliary functions =====================================
135 EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes)
137 std::shared_ptr<GCS::Line> aNewLine(new GCS::Line);
139 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
140 for (; anIt != theAttributes.end(); ++anIt) {
141 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
142 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
146 if (anIt->first->id() == SketchPlugin_Line::START_ID())
147 aNewLine->p1 = *(aPoint->point());
148 else if (anIt->first->id() == SketchPlugin_Line::END_ID())
149 aNewLine->p2 = *(aPoint->point());
152 return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewLine));
155 EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes)
157 std::shared_ptr<GCS::Circle> aNewCircle(new GCS::Circle);
159 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
160 for (; anIt != theAttributes.end(); ++anIt) {
161 if (anIt->first->id() == SketchPlugin_Circle::CENTER_ID()) {
162 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
163 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
164 aNewCircle->center = *(aPoint->point());
166 else if(anIt->first->id() == SketchPlugin_Circle::RADIUS_ID()) {
167 ScalarWrapperPtr aScalar =
168 std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(anIt->second);
169 aNewCircle->rad = aScalar->scalar();
173 return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewCircle));
176 static double* createParameter(PlaneGCSSolver_Storage* theStorage)
178 return theStorage ? theStorage->createParameter() : (new double(0));
181 EntityWrapperPtr createArc(const AttributeEntityMap& theAttributes,
182 PlaneGCSSolver_Storage* theStorage)
184 std::shared_ptr<GCS::Arc> aNewArc(new GCS::Arc);
185 BooleanWrapperPtr isReversed;
187 // Base attributes of arc (center, start and end points)
188 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
189 for (; anIt != theAttributes.end(); ++anIt) {
190 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
191 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
193 if (anIt->first->id() == SketchPlugin_Arc::CENTER_ID())
194 aNewArc->center = *(aPoint->point());
195 else if (anIt->first->id() == SketchPlugin_Arc::START_ID())
196 aNewArc->start = *(aPoint->point());
197 else if (anIt->first->id() == SketchPlugin_Arc::END_ID())
198 aNewArc->end = *(aPoint->point());
202 isReversed = std::dynamic_pointer_cast<PlaneGCSSolver_BooleanWrapper>(anIt->second);
206 // Additional attributes of arc necessary for PlaneGCS solver
207 // (start and end angles, radius)
208 aNewArc->startAngle = createParameter(theStorage);
209 aNewArc->endAngle = createParameter(theStorage);
210 aNewArc->rad = createParameter(theStorage);
212 EdgeWrapperPtr anArcWrapper(new PlaneGCSSolver_EdgeWrapper(aNewArc));
213 anArcWrapper->setReversed(isReversed);
214 PlaneGCSSolver_Tools::recalculateArcParameters(anArcWrapper);
219 EntityWrapperPtr createEllipse(const AttributeEntityMap& theAttributes)
221 std::shared_ptr<GCS::Ellipse> aNewEllipse(new GCS::Ellipse);
223 std::map<std::string, EntityWrapperPtr> anAdditionalAttributes;
225 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
226 for (; anIt != theAttributes.end(); ++anIt) {
227 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
228 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
230 if (anIt->first->id() == SketchPlugin_Ellipse::CENTER_ID())
231 aNewEllipse->center = *(aPoint->point());
232 else if (anIt->first->id() == SketchPlugin_Ellipse::FIRST_FOCUS_ID())
233 aNewEllipse->focus1 = *(aPoint->point());
235 anAdditionalAttributes[anIt->first->id()] = anIt->second;
237 else if (anIt->first->id() == SketchPlugin_Ellipse::MINOR_RADIUS_ID()) {
238 ScalarWrapperPtr aScalar =
239 std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(anIt->second);
240 aNewEllipse->radmin = aScalar->scalar();
243 anAdditionalAttributes[anIt->first->id()] = anIt->second;
246 EntityWrapperPtr anEllipseWrapper(new PlaneGCSSolver_EdgeWrapper(aNewEllipse));
247 anEllipseWrapper->setAdditionalAttributes(anAdditionalAttributes);
248 return anEllipseWrapper;
251 EntityWrapperPtr createEllipticArc(const AttributeEntityMap& theAttributes,
252 PlaneGCSSolver_Storage* theStorage)
254 std::shared_ptr<GCS::ArcOfEllipse> aNewArc(new GCS::ArcOfEllipse);
256 BooleanWrapperPtr isReversed;
257 std::map<std::string, EntityWrapperPtr> anAdditionalAttributes;
259 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
260 for (; anIt != theAttributes.end(); ++anIt) {
261 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
262 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
264 if (anIt->first->id() == SketchPlugin_EllipticArc::CENTER_ID())
265 aNewArc->center = *(aPoint->point());
266 else if (anIt->first->id() == SketchPlugin_EllipticArc::FIRST_FOCUS_ID())
267 aNewArc->focus1 = *(aPoint->point());
268 else if (anIt->first->id() == SketchPlugin_EllipticArc::START_POINT_ID())
269 aNewArc->start = *(aPoint->point());
270 else if (anIt->first->id() == SketchPlugin_EllipticArc::END_POINT_ID())
271 aNewArc->end = *(aPoint->point());
273 anAdditionalAttributes[anIt->first->id()] = anIt->second;
275 else if (anIt->first->id() == SketchPlugin_EllipticArc::MINOR_RADIUS_ID()) {
276 ScalarWrapperPtr aScalar =
277 std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(anIt->second);
278 aNewArc->radmin = aScalar->scalar();
280 else if (anIt->first->id() == SketchPlugin_EllipticArc::REVERSED_ID())
281 isReversed = std::dynamic_pointer_cast<PlaneGCSSolver_BooleanWrapper>(anIt->second);
283 anAdditionalAttributes[anIt->first->id()] = anIt->second;
286 // Additional attributes of elliptic arc necessary for PlaneGCS solver (start and end angles)
287 aNewArc->startAngle = createParameter(theStorage);
288 aNewArc->endAngle = createParameter(theStorage);
290 EdgeWrapperPtr anEllipseWrapper(new PlaneGCSSolver_EdgeWrapper(aNewArc));
291 anEllipseWrapper->setReversed(isReversed);
292 anEllipseWrapper->setAdditionalAttributes(anAdditionalAttributes);
293 PlaneGCSSolver_Tools::recalculateArcParameters(anEllipseWrapper);
295 return anEllipseWrapper;
298 EntityWrapperPtr createBSpline(const AttributeEntityMap& theAttributes)
300 std::shared_ptr<GCS::BSpline> aNewSpline(new GCS::BSpline);
302 aNewSpline->degree = 3;
303 aNewSpline->periodic = false;
305 AttributeEntityMap::const_iterator anIt = theAttributes.begin();
306 for (; anIt != theAttributes.end(); ++anIt) {
307 const std::string& anAttrID = anIt->first->id();
308 if (anAttrID == SketchPlugin_BSpline::POLES_ID()) {
309 PointArrayWrapperPtr anArray =
310 std::dynamic_pointer_cast<PlaneGCSSolver_PointArrayWrapper>(anIt->second);
312 int aSize = anArray->size();
313 aNewSpline->poles.reserve(aSize);
314 for (int anIndex = 0; anIndex < aSize; ++anIndex)
315 aNewSpline->poles.push_back(*anArray->value(anIndex)->point());
317 aNewSpline->start = aNewSpline->poles.front();
318 aNewSpline->end = aNewSpline->poles.back();
320 else if (anAttrID == SketchPlugin_BSpline::WEIGHTS_ID()) {
321 ScalarArrayWrapperPtr anArray =
322 std::dynamic_pointer_cast<PlaneGCSSolver_ScalarArrayWrapper>(anIt->second);
323 aNewSpline->weights = anArray->array();
327 return EdgeWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewSpline));
330 bool isAttributeApplicable(const std::string& theAttrName, const std::string& theOwnerName)
332 if (theOwnerName == SketchPlugin_Arc::ID()) {
333 return theAttrName == SketchPlugin_Arc::CENTER_ID() ||
334 theAttrName == SketchPlugin_Arc::START_ID() ||
335 theAttrName == SketchPlugin_Arc::END_ID() ||
336 theAttrName == SketchPlugin_Arc::REVERSED_ID();
338 else if (theOwnerName == SketchPlugin_Circle::ID()) {
339 return theAttrName == SketchPlugin_Circle::CENTER_ID() ||
340 theAttrName == SketchPlugin_Circle::RADIUS_ID();
342 else if (theOwnerName == SketchPlugin_Line::ID()) {
343 return theAttrName == SketchPlugin_Line::START_ID() ||
344 theAttrName == SketchPlugin_Line::END_ID();
346 else if (theOwnerName == SketchPlugin_Ellipse::ID()) {
347 return theAttrName == SketchPlugin_Ellipse::CENTER_ID() ||
348 theAttrName == SketchPlugin_Ellipse::FIRST_FOCUS_ID() ||
349 theAttrName == SketchPlugin_Ellipse::SECOND_FOCUS_ID() ||
350 theAttrName == SketchPlugin_Ellipse::MAJOR_AXIS_START_ID() ||
351 theAttrName == SketchPlugin_Ellipse::MAJOR_AXIS_END_ID() ||
352 theAttrName == SketchPlugin_Ellipse::MINOR_AXIS_START_ID() ||
353 theAttrName == SketchPlugin_Ellipse::MINOR_AXIS_END_ID() ||
354 theAttrName == SketchPlugin_Ellipse::MAJOR_RADIUS_ID() ||
355 theAttrName == SketchPlugin_Ellipse::MINOR_RADIUS_ID();
357 else if (theOwnerName == SketchPlugin_EllipticArc::ID()) {
358 return theAttrName == SketchPlugin_EllipticArc::CENTER_ID() ||
359 theAttrName == SketchPlugin_EllipticArc::FIRST_FOCUS_ID() ||
360 theAttrName == SketchPlugin_EllipticArc::SECOND_FOCUS_ID() ||
361 theAttrName == SketchPlugin_EllipticArc::MAJOR_AXIS_START_ID() ||
362 theAttrName == SketchPlugin_EllipticArc::MAJOR_AXIS_END_ID() ||
363 theAttrName == SketchPlugin_EllipticArc::MINOR_AXIS_START_ID() ||
364 theAttrName == SketchPlugin_EllipticArc::MINOR_AXIS_END_ID() ||
365 theAttrName == SketchPlugin_EllipticArc::MAJOR_RADIUS_ID() ||
366 theAttrName == SketchPlugin_EllipticArc::MINOR_RADIUS_ID() ||
367 theAttrName == SketchPlugin_EllipticArc::START_POINT_ID() ||
368 theAttrName == SketchPlugin_EllipticArc::END_POINT_ID() ||
369 theAttrName == SketchPlugin_EllipticArc::REVERSED_ID();
371 else if (theOwnerName == SketchPlugin_BSpline::ID()) {
372 return theAttrName == SketchPlugin_BSpline::POLES_ID() ||
373 theAttrName == SketchPlugin_BSpline::WEIGHTS_ID();
376 // suppose that all remaining features are points
377 return theAttrName == SketchPlugin_Point::COORD_ID();