Salome HOME
using a better solution to do compare doubles for shape physical properties
[modules/shaper.git] / src / SketchAPI / SketchAPI_Sketch.cpp
1 // Copyright (C) 2014-2024  CEA, EDF
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 "SketchAPI_Sketch.h"
21 //--------------------------------------------------------------------------------------
22 #include <SketchPlugin_Constraint.h>
23 #include <SketchPlugin_ConstraintAngle.h>
24 #include <SketchPlugin_ConstraintCoincidence.h>
25 #include <SketchPlugin_ConstraintCollinear.h>
26 #include <SketchPlugin_ConstraintDistance.h>
27 #include <SketchPlugin_ConstraintDistanceHorizontal.h>
28 #include <SketchPlugin_ConstraintDistanceVertical.h>
29 #include <SketchPlugin_ConstraintEqual.h>
30 #include <SketchPlugin_Fillet.h>
31 #include <SketchPlugin_ConstraintHorizontal.h>
32 #include <SketchPlugin_ConstraintLength.h>
33 #include <SketchPlugin_ConstraintMiddle.h>
34 #include <SketchPlugin_ConstraintMirror.h>
35 #include <SketchPlugin_ConstraintParallel.h>
36 #include <SketchPlugin_ConstraintPerpendicular.h>
37 #include <SketchPlugin_ConstraintRadius.h>
38 #include <SketchPlugin_ConstraintRigid.h>
39 #include <SketchPlugin_CurveFitting.h>
40 #include <SketchPlugin_Trim.h>
41 #include <SketchPlugin_Split.h>
42 #include <SketchPlugin_ConstraintTangent.h>
43 #include <SketchPlugin_ConstraintVertical.h>
44 #include <SketchPlugin_MacroBSpline.h>
45 #include <SketchPlugin_SketchCopy.h>
46 #include <SketchPlugin_Offset.h>
47 #include <SketcherPrs_Tools.h>
48 //--------------------------------------------------------------------------------------
49 #include <ModelAPI_Events.h>
50 #include <ModelAPI_CompositeFeature.h>
51 #include <ModelAPI_ResultConstruction.h>
52 #include <ModelHighAPI_Double.h>
53 #include <ModelHighAPI_Dumper.h>
54 #include <ModelHighAPI_RefAttr.h>
55 #include <ModelHighAPI_Selection.h>
56 #include <ModelHighAPI_Services.h>
57 #include <ModelHighAPI_Tools.h>
58 //--------------------------------------------------------------------------------------
59 #include "SketchAPI_Arc.h"
60 #include "SketchAPI_BSpline.h"
61 #include "SketchAPI_Circle.h"
62 #include "SketchAPI_Ellipse.h"
63 #include "SketchAPI_EllipticArc.h"
64 #include "SketchAPI_IntersectionPoint.h"
65 #include "SketchAPI_Line.h"
66 #include "SketchAPI_MacroArc.h"
67 #include "SketchAPI_MacroCircle.h"
68 #include "SketchAPI_MacroEllipse.h"
69 #include "SketchAPI_MacroEllipticArc.h"
70 #include "SketchAPI_MacroMiddlePoint.h"
71 #include "SketchAPI_Mirror.h"
72 #include "SketchAPI_Offset.h"
73 #include "SketchAPI_Point.h"
74 #include "SketchAPI_Projection.h"
75 #include "SketchAPI_Rectangle.h"
76 #include "SketchAPI_Rotation.h"
77 #include "SketchAPI_Translation.h"
78 #include "SketchAPI_Constraint.h"
79 //--------------------------------------------------------------------------------------
80 #include <GeomAPI_Curve.h>
81 #include <GeomAPI_Dir2d.h>
82 #include <GeomAPI_PlanarEdges.h>
83 #include <GeomAPI_ShapeExplorer.h>
84 #include <GeomAPI_XY.h>
85 #include <GeomAlgoAPI_SketchBuilder.h>
86
87 #include <algorithm>
88 #include <cmath>
89 //--------------------------------------------------------------------------------------
90
91
92 static std::shared_ptr<GeomAPI_Pnt2d> pointCoordinates(const AttributePtr& thePoint)
93 {
94   AttributePoint2DPtr aPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(thePoint);
95   return aPnt ? aPnt->pnt() : std::shared_ptr<GeomAPI_Pnt2d>();
96 }
97
98 static std::shared_ptr<GeomAPI_Pnt2d> middlePointOnLine(const FeaturePtr& theFeature)
99 {
100   AttributePoint2DPtr aStartAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
101     theFeature->attribute(SketchPlugin_Line::START_ID()));
102   AttributePoint2DPtr aEndAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
103     theFeature->attribute(SketchPlugin_Line::END_ID()));
104
105   if (!aStartAttr || !aEndAttr)
106     return std::shared_ptr<GeomAPI_Pnt2d>();
107
108   std::shared_ptr<GeomAPI_XY> aStartPoint = aStartAttr->pnt()->xy();
109   std::shared_ptr<GeomAPI_XY> aEndPoint = aEndAttr->pnt()->xy();
110   return std::shared_ptr<GeomAPI_Pnt2d>(
111     new GeomAPI_Pnt2d(aStartPoint->added(aEndPoint)->multiplied(0.5)));
112 }
113
114 static std::shared_ptr<GeomAPI_Pnt2d> pointOnCircle(const FeaturePtr& theFeature)
115 {
116   AttributePoint2DPtr aCenter = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
117     theFeature->attribute(SketchPlugin_Circle::CENTER_ID()));
118   AttributeDoublePtr aRadius = theFeature->real(SketchPlugin_Circle::RADIUS_ID());
119
120   if (!aCenter || !aRadius)
121     return std::shared_ptr<GeomAPI_Pnt2d>();
122
123   return std::shared_ptr<GeomAPI_Pnt2d>(
124     new GeomAPI_Pnt2d(aCenter->x() + aRadius->value(), aCenter->y()));
125 }
126
127 static std::shared_ptr<GeomAPI_Pnt2d> middlePointOnArc(const FeaturePtr& theFeature)
128 {
129   static const double PI = 3.141592653589793238463;
130
131   AttributePoint2DPtr aCenterAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
132     theFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
133   AttributePoint2DPtr aStartAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
134     theFeature->attribute(SketchPlugin_Arc::START_ID()));
135   AttributePoint2DPtr aEndAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
136     theFeature->attribute(SketchPlugin_Arc::END_ID()));
137
138   if (!aCenterAttr || !aStartAttr || !aEndAttr)
139     return std::shared_ptr<GeomAPI_Pnt2d>();
140
141   std::shared_ptr<GeomAPI_Dir2d> aStartDir(new GeomAPI_Dir2d(
142     aStartAttr->x() - aCenterAttr->x(), aStartAttr->y() - aCenterAttr->y()));
143   std::shared_ptr<GeomAPI_Dir2d> aEndDir(new GeomAPI_Dir2d(
144     aEndAttr->x() - aCenterAttr->x(), aEndAttr->y() - aCenterAttr->y()));
145
146   double anAngle = aStartDir->angle(aEndDir);
147   bool isReversed = theFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->value();
148   if (isReversed && anAngle > 0.)
149     anAngle -= 2.0 * PI;
150   else if (!isReversed && anAngle <= 0.)
151     anAngle += 2.0 * PI;
152
153   double cosA = cos(anAngle);
154   double sinA = sin(anAngle);
155
156   // rotate start dir to find middle point on arc
157   double aRadius = aStartAttr->pnt()->distance(aCenterAttr->pnt());
158   double x = aCenterAttr->x() + aRadius * (aStartDir->x() * cosA - aStartDir->y() * sinA);
159   double y = aCenterAttr->y() + aRadius * (aStartDir->x() * sinA + aStartDir->y() * cosA);
160
161   return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(x, y));
162 }
163
164 static std::shared_ptr<GeomAPI_Pnt2d> pointOnEllipse(const FeaturePtr& theFeature,
165   bool isEllipse = true)
166 {
167   const std::string& anAttrName = isEllipse ? SketchPlugin_Ellipse::MAJOR_AXIS_END_ID() :
168     SketchPlugin_EllipticArc::MAJOR_AXIS_END_ID();
169   AttributePoint2DPtr aMajorAxisEnd = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
170     theFeature->attribute(anAttrName));
171   return aMajorAxisEnd ? aMajorAxisEnd->pnt() : std::shared_ptr<GeomAPI_Pnt2d>();
172 }
173
174 static std::shared_ptr<GeomAPI_Pnt2d> middlePointOnBSpline(const FeaturePtr& theFeature,
175   SketchAPI_Sketch* theSketch)
176 {
177   GeomAPI_Edge anEdge(theFeature->lastResult()->shape());
178   GeomPointPtr aMiddle = anEdge.middlePoint();
179   return theSketch->to2D(aMiddle);
180 }
181
182 static std::shared_ptr<GeomAPI_Pnt2d> middlePoint(const ObjectPtr& theObject,
183   SketchAPI_Sketch* theSketch)
184 {
185   std::shared_ptr<GeomAPI_Pnt2d> aMiddlePoint;
186   FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
187   if (aFeature) {
188     // move only features of the following types
189     const std::string& aFeatureKind = aFeature->getKind();
190     if (aFeatureKind == SketchPlugin_Point::ID())
191       aMiddlePoint = pointCoordinates(aFeature->attribute(SketchPlugin_Point::COORD_ID()));
192     else if (aFeatureKind == SketchPlugin_Line::ID())
193       aMiddlePoint = middlePointOnLine(aFeature);
194     else if (aFeatureKind == SketchPlugin_Circle::ID())
195       aMiddlePoint = pointOnCircle(aFeature);
196     else if (aFeatureKind == SketchPlugin_Arc::ID())
197       aMiddlePoint = middlePointOnArc(aFeature);
198     else if (aFeatureKind == SketchPlugin_Ellipse::ID())
199       aMiddlePoint = pointOnEllipse(aFeature);
200     else if (aFeatureKind == SketchPlugin_EllipticArc::ID())
201       aMiddlePoint = pointOnEllipse(aFeature, false);
202     else if (aFeatureKind == SketchPlugin_BSpline::ID() ||
203       aFeatureKind == SketchPlugin_BSplinePeriodic::ID())
204       aMiddlePoint = middlePointOnBSpline(aFeature, theSketch);
205   }
206   return aMiddlePoint;
207 }
208
209 SketchAPI_Sketch::SketchAPI_Sketch(
210     const std::shared_ptr<ModelAPI_Feature> & theFeature)
211 : ModelHighAPI_Interface(theFeature)
212 {
213   initialize();
214 }
215
216 SketchAPI_Sketch::SketchAPI_Sketch(
217     const std::shared_ptr<ModelAPI_Feature> & theFeature,
218     const std::shared_ptr<GeomAPI_Ax3> & thePlane)
219 : ModelHighAPI_Interface(theFeature)
220 {
221   if (initialize()) {
222     setPlane(thePlane);
223   }
224 }
225
226 SketchAPI_Sketch::SketchAPI_Sketch(
227     const std::shared_ptr<ModelAPI_Feature> & theFeature,
228     const ModelHighAPI_Selection & theExternal)
229 : ModelHighAPI_Interface(theFeature)
230 {
231   if (initialize()) {
232     setExternal(theExternal);
233   }
234 }
235
236 SketchAPI_Sketch::SketchAPI_Sketch(
237     const std::shared_ptr<ModelAPI_Feature> & theFeature,
238     std::shared_ptr<ModelAPI_Object> thePlaneObject)
239 : ModelHighAPI_Interface(theFeature)
240 {
241   if (initialize()) {
242     setExternal(thePlaneObject);
243   }
244 }
245
246 SketchAPI_Sketch::~SketchAPI_Sketch()
247 {
248
249 }
250
251 //--------------------------------------------------------------------------------------
252 std::shared_ptr<ModelAPI_CompositeFeature> SketchAPI_Sketch::compositeFeature() const
253 {
254   return std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(feature());
255 }
256
257 //--------------------------------------------------------------------------------------
258 void SketchAPI_Sketch::setPlane(const std::shared_ptr<GeomAPI_Ax3> & thePlane)
259 {
260   fillAttribute(thePlane->origin(), myorigin);
261   fillAttribute(thePlane->dirX(), mydirX);
262   fillAttribute(thePlane->normal(), mynormal);
263
264   execute();
265 }
266
267 void SketchAPI_Sketch::setPlane(const ModelHighAPI_Selection & thePlane,
268                                 bool theRemoveExternalDependency)
269 {
270   FeaturePtr aSketch = feature();
271
272   DocumentPtr aDoc = aSketch->document();
273   bool useVisible = false;
274   FeaturePtr aCurFeatureBefore = aDoc->currentFeature(useVisible);
275   aDoc->setCurrentFeature(aSketch, useVisible);
276
277   if (theRemoveExternalDependency)
278     aSketch->customAction(SketchPlugin_Sketch::ACTION_REMOVE_EXTERNAL());
279
280   setExternal(thePlane);
281
282   aDoc->setCurrentFeature(aCurFeatureBefore, useVisible);
283 }
284
285 //--------------------------------------------------------------------------------------
286 void SketchAPI_Sketch::setExternal(const ModelHighAPI_Selection & theExternal)
287 {
288   fillAttribute(theExternal, myexternal);
289
290   execute();
291 }
292
293 void SketchAPI_Sketch::setExternal(std::shared_ptr<ModelAPI_Object> thePlaneObject)
294 {
295   ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(thePlaneObject);
296   ModelHighAPI_Selection aSel(aRes);
297   setExternal(aSel);
298 }
299
300 //--------------------------------------------------------------------------------------
301 void SketchAPI_Sketch::setValue(
302     const std::shared_ptr<ModelHighAPI_Interface> & theConstraint,
303     const ModelHighAPI_Double & theValue)
304 {
305   fillAttribute(theValue, theConstraint->feature()->real(SketchPlugin_Constraint::VALUE()));
306
307 //  theConstraint->execute();
308 }
309
310 //--------------------------------------------------------------------------------------
311 std::list<ModelHighAPI_Selection> SketchAPI_Sketch::selectFace() const
312 {
313   const_cast<SketchAPI_Sketch*>(this)->execute();
314
315   std::list<ModelHighAPI_Selection> aSelectionList;
316
317   ResultConstructionPtr aResultConstruction =
318       std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(feature()->firstResult());
319   if (aResultConstruction.get() == NULL)
320     return aSelectionList;
321
322   for (int anIndex = 0; anIndex < aResultConstruction->facesNum(); ++anIndex) {
323     aSelectionList.push_back(
324         ModelHighAPI_Selection(aResultConstruction,
325                                aResultConstruction->face(anIndex)));
326   }
327
328   return aSelectionList;
329 }
330
331 //--------------------------------------------------------------------------------------
332 SketchPtr addSketch(const std::shared_ptr<ModelAPI_Document> & thePart,
333                     const std::shared_ptr<GeomAPI_Ax3> & thePlane)
334 {
335   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(SketchAPI_Sketch::ID());
336   return SketchPtr(new SketchAPI_Sketch(aFeature, thePlane));
337 }
338
339 SketchPtr addSketch(const std::shared_ptr<ModelAPI_Document> & thePart,
340                     const ModelHighAPI_Selection & theExternal)
341 {
342   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(SketchAPI_Sketch::ID());
343   return SketchPtr(new SketchAPI_Sketch(aFeature, theExternal));
344 }
345
346 SketchPtr addSketch(const std::shared_ptr<ModelAPI_Document> & thePart,
347                     const std::wstring & theExternalName)
348 {
349   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(SketchAPI_Sketch::ID());
350   return SketchPtr(
351     new SketchAPI_Sketch(aFeature, ModelHighAPI_Selection("FACE", theExternalName)));
352 }
353
354 SketchPtr addSketch(const std::shared_ptr<ModelAPI_Document> & thePart,
355                     std::shared_ptr<ModelAPI_Object> thePlaneObject)
356 {
357   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(SketchAPI_Sketch::ID());
358   return SketchPtr(new SketchAPI_Sketch(aFeature, thePlaneObject));
359 }
360
361 //--------------------------------------------------------------------------------------
362 SketchPtr copySketch(const std::shared_ptr<ModelAPI_Document> & thePart,
363                      const SketchPtr & theSketch)
364 {
365   FeaturePtr aCopyer = thePart->addFeature(SketchPlugin_SketchCopy::ID());
366   aCopyer->reference(SketchPlugin_SketchCopy::BASE_ID())->setValue(theSketch->feature());
367   aCopyer->execute();
368
369   FeaturePtr aNewSketch = thePart->nextFeature(aCopyer);
370
371   // perform removing the macro-feature
372   thePart->removeFeature(aCopyer);
373   apply();
374
375   return SketchPtr(new SketchAPI_Sketch(aNewSketch));
376 }
377
378
379 //--------------------------------------------------------------------------------------
380 std::list< std::shared_ptr<SketchAPI_Point> > SketchAPI_Sketch::getFreePoints()
381 {
382   std::list< std::shared_ptr<SketchAPI_Point> > aFreePoints;
383   std::list<ResultPtr> aPoints = SketcherPrs_Tools::getFreePoints(compositeFeature());
384   for (std::list<ResultPtr>::iterator anIt = aPoints.begin(); anIt != aPoints.end(); ++anIt) {
385     FeaturePtr aFeature = ModelAPI_Feature::feature(*anIt);
386     PointPtr aPoint(new SketchAPI_Point(aFeature));
387     aFreePoints.push_back(aPoint);
388   }
389   return aFreePoints;
390 }
391
392 //--------------------------------------------------------------------------------------
393 static GeomCurvePtr untrimmedCurve(GeomShapePtr theShape)
394 {
395   GeomCurvePtr aCurve(new GeomAPI_Curve(theShape));
396   if (aCurve->isTrimmed())
397     aCurve = aCurve->basisCurve();
398   return aCurve;
399 }
400
401 void SketchAPI_Sketch::changeFacesOrder(
402     const std::list<std::list<ModelHighAPI_Selection> >& theFaces)
403 {
404   // collect faces of the sketch
405   ResultConstructionPtr aSketchResult =
406       std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(feature()->lastResult());
407   if (!aSketchResult) {
408     // sketch is nested to a boolean operation, thus, it has no result yet.
409     feature()->execute();
410     aSketchResult =
411         std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(feature()->lastResult());
412   }
413   std::list<GeomFacePtr> aFaces;
414   int aFacesNum = aSketchResult->facesNum();
415   for (int i = 0; i < aFacesNum; ++i)
416     aFaces.push_back(aSketchResult->face(i));
417   // find new faces order according to the given lists of edges
418   std::list<GeomFacePtr> aNewFacesOrder;
419   std::list<std::list<ModelHighAPI_Selection> >::const_iterator anIt = theFaces.begin();
420   for (; anIt != theFaces.end(); ++anIt) {
421     // find the appropriate face
422     std::list<GeomFacePtr>::iterator aFIt = aFaces.begin();
423     for (; aFIt != aFaces.end(); ++aFIt) {
424       std::list<ModelHighAPI_Selection>::const_iterator aEdgeIt = anIt->begin();
425       GeomAPI_ShapeExplorer aFExp(*aFIt, GeomAPI_Shape::EDGE);
426       for (; aEdgeIt != anIt->end() && aFExp.more(); ++aEdgeIt, aFExp.next()) {
427         ResultPtr aCurRes = aEdgeIt->resultSubShapePair().first;
428         if (!aCurRes)
429           break;
430         GeomCurvePtr aCurve1 = untrimmedCurve(aCurRes->shape());
431         GeomCurvePtr aCurve2 = untrimmedCurve(aFExp.current());
432         if (!aCurve1->isEqual(aCurve2))
433           break;
434       }
435
436       if (aEdgeIt == anIt->end() && !aFExp.more()) {
437         // face is found
438         aNewFacesOrder.push_back(*aFIt);
439         aFaces.erase(aFIt);
440         break;
441       }
442     }
443   }
444   // place the rest faces at the end of new faces list
445   if (!aFaces.empty())
446     aNewFacesOrder.insert(aNewFacesOrder.end(), aFaces.begin(), aFaces.end());
447   // update the result of the sketch with the new order of faces
448   aSketchResult->setFacesOrder(aNewFacesOrder);
449 }
450
451 //--------------------------------------------------------------------------------------
452 std::shared_ptr<SketchAPI_Point> SketchAPI_Sketch::addPoint(
453     double theX, double theY)
454 {
455   std::shared_ptr<ModelAPI_Feature> aFeature =
456     compositeFeature()->addFeature(SketchPlugin_Point::ID());
457   return PointPtr(new SketchAPI_Point(aFeature, theX, theY));
458 }
459 std::shared_ptr<SketchAPI_Point> SketchAPI_Sketch::addPoint(
460     const std::shared_ptr<GeomAPI_Pnt2d> & thePoint)
461 {
462   std::shared_ptr<ModelAPI_Feature> aFeature =
463     compositeFeature()->addFeature(SketchPlugin_Point::ID());
464   return PointPtr(new SketchAPI_Point(aFeature, thePoint));
465 }
466 std::shared_ptr<SketchAPI_Point>
467   SketchAPI_Sketch::addPoint(const ModelHighAPI_Selection & theExternal)
468 {
469   std::shared_ptr<ModelAPI_Feature> aFeature =
470     compositeFeature()->addFeature(SketchPlugin_Point::ID());
471   return PointPtr(new SketchAPI_Point(aFeature, theExternal));
472 }
473 std::shared_ptr<SketchAPI_Point> SketchAPI_Sketch::addPoint(const std::wstring & theExternalName)
474 {
475   std::shared_ptr<ModelAPI_Feature> aFeature =
476     compositeFeature()->addFeature(SketchPlugin_Point::ID());
477   return PointPtr(new SketchAPI_Point(aFeature, theExternalName));
478 }
479
480 //--------------------------------------------------------------------------------------
481 std::shared_ptr<SketchAPI_IntersectionPoint> SketchAPI_Sketch::addIntersectionPoint(
482     const ModelHighAPI_Selection & theExternal,
483     bool theKeepResult)
484 {
485   std::shared_ptr<ModelAPI_Feature> aFeature =
486     compositeFeature()->addFeature(SketchPlugin_IntersectionPoint::ID());
487   IntersectionPointPtr anIntersection(new SketchAPI_IntersectionPoint(aFeature, theExternal));
488   anIntersection->setIncludeToResult(theKeepResult);
489   return anIntersection;
490 }
491 std::shared_ptr<SketchAPI_IntersectionPoint> SketchAPI_Sketch::addIntersectionPoint(
492     const std::wstring & theExternalName,
493     bool theKeepResult)
494 {
495   std::shared_ptr<ModelAPI_Feature> aFeature =
496     compositeFeature()->addFeature(SketchPlugin_IntersectionPoint::ID());
497   IntersectionPointPtr anIntersection(new SketchAPI_IntersectionPoint(aFeature, theExternalName));
498   anIntersection->setIncludeToResult(theKeepResult);
499   return anIntersection;
500 }
501
502 //--------------------------------------------------------------------------------------
503 std::shared_ptr<SketchAPI_Line> SketchAPI_Sketch::addLine(double theX1, double theY1,
504                                                           double theX2, double theY2)
505 {
506   std::shared_ptr<ModelAPI_Feature> aFeature =
507     compositeFeature()->addFeature(SketchPlugin_Line::ID());
508   return LinePtr(new SketchAPI_Line(aFeature, theX1, theY1, theX2, theY2));
509 }
510 std::shared_ptr<SketchAPI_Line> SketchAPI_Sketch::addLine(
511     const std::shared_ptr<GeomAPI_Pnt2d> & theStartPoint,
512     const std::shared_ptr<GeomAPI_Pnt2d> & theEndPoint)
513 {
514   std::shared_ptr<ModelAPI_Feature> aFeature =
515     compositeFeature()->addFeature(SketchPlugin_Line::ID());
516   return LinePtr(new SketchAPI_Line(aFeature, theStartPoint, theEndPoint));
517 }
518 std::shared_ptr<SketchAPI_Line>
519   SketchAPI_Sketch::addLine(const ModelHighAPI_Selection & theExternal)
520 {
521   std::shared_ptr<ModelAPI_Feature> aFeature =
522     compositeFeature()->addFeature(SketchPlugin_Line::ID());
523   return LinePtr(new SketchAPI_Line(aFeature, theExternal));
524 }
525 std::shared_ptr<SketchAPI_Line> SketchAPI_Sketch::addLine(const std::wstring & theExternalName)
526 {
527   std::shared_ptr<ModelAPI_Feature> aFeature =
528     compositeFeature()->addFeature(SketchPlugin_Line::ID());
529   return LinePtr(new SketchAPI_Line(aFeature, theExternalName));
530 }
531
532 //--------------------------------------------------------------------------------------
533 std::shared_ptr<SketchAPI_Rectangle> SketchAPI_Sketch::addRectangle(double theX1, double theY1,
534                                                                     double theX2, double theY2)
535 {
536   std::shared_ptr<ModelAPI_Feature> aFeature = compositeFeature()->addFeature(SketchAPI_Rectangle::ID());
537   return RectanglePtr(new SketchAPI_Rectangle(aFeature, theX1, theY1, theX2, theY2));
538 }
539
540 static std::shared_ptr<GeomAPI_Pnt2d> pointCoordinates(
541     const std::pair<std::shared_ptr<GeomAPI_Pnt2d>, ModelHighAPI_RefAttr> & thePoint)
542 {
543   if (thePoint.first)
544     return thePoint.first;
545
546   AttributePtr anAttr = thePoint.second.attr();
547   if (thePoint.second.object()) {
548     FeaturePtr aFeature = ModelAPI_Feature::feature(thePoint.second.object());
549     if (aFeature)
550       anAttr = aFeature->attribute(SketchPlugin_Point::COORD_ID());
551   }
552
553   std::shared_ptr<GeomDataAPI_Point2D> aPntAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr);
554   if (aPntAttr)
555     return aPntAttr->pnt();
556   return std::shared_ptr<GeomAPI_Pnt2d>();
557 }
558
559 std::shared_ptr<SketchAPI_Rectangle> SketchAPI_Sketch::addRectangle(
560       const std::pair<std::shared_ptr<GeomAPI_Pnt2d>, ModelHighAPI_RefAttr> & theStartPoint,
561       const std::pair<std::shared_ptr<GeomAPI_Pnt2d>, ModelHighAPI_RefAttr> & theEndPoint)
562 {
563   std::shared_ptr<ModelAPI_Feature> aFeature = compositeFeature()->addFeature(SketchAPI_Rectangle::ID());
564   RectanglePtr aRect(new SketchAPI_Rectangle(aFeature));
565   fillAttribute("RectangleTypeByCorners", aRect->type());
566   fillAttribute(pointCoordinates(theStartPoint), aRect->startPoint());
567   fillAttribute(pointCoordinates(theEndPoint), aRect->endPoint());
568   aRect->execute();
569
570   if (!theStartPoint.second.isEmpty() && aRect->linesList()->size() >= 1) {
571     // Get end point of the first line of rectangle and apply coincidence constraint
572     FeaturePtr aLine = ModelAPI_Feature::feature(aRect->linesList()->object(0));
573     AttributePtr aLinePnt = aLine->attribute(SketchPlugin_Line::END_ID());
574     setCoincident(ModelHighAPI_RefAttr(aLinePnt), theStartPoint.second);
575   }
576
577   if (!theEndPoint.second.isEmpty() && aRect->linesList()->size() >= 4) {
578     // Get start point of the last line of rectangle and apply coincidence constraint
579     FeaturePtr aLine = ModelAPI_Feature::feature(aRect->linesList()->object(3));
580     AttributePtr aLinePnt = aLine->attribute(SketchPlugin_Line::START_ID());
581     setCoincident(ModelHighAPI_RefAttr(aLinePnt), theEndPoint.second);
582   }
583   return aRect;
584 }
585
586 std::pair<std::shared_ptr<SketchAPI_Rectangle>, std::shared_ptr<SketchAPI_Point>> SketchAPI_Sketch::addRectangleCentered(
587     const std::pair<std::shared_ptr<GeomAPI_Pnt2d>, ModelHighAPI_RefAttr> & theCenter,
588     const std::pair<std::shared_ptr<GeomAPI_Pnt2d>, ModelHighAPI_RefAttr> & theCorner)
589 {
590   std::shared_ptr<ModelAPI_Feature> aFeature = compositeFeature()->addFeature(SketchAPI_Rectangle::ID());
591   RectanglePtr aRect(new SketchAPI_Rectangle(aFeature));
592   fillAttribute("RectangleTypeCentered", aRect->type());
593
594   if (!theCenter.second.isEmpty())
595     fillAttribute(theCenter.second, aRect->centerPointRef());
596   else
597     fillAttribute(pointCoordinates(theCenter), aRect->centerPoint());
598
599   fillAttribute(pointCoordinates(theCorner), aRect->cornerPoint());
600   aRect->execute();
601
602   if (!theCorner.second.isEmpty() && aRect->linesList()->size() >= 4) {
603     // get start point of the last line in rectangle and apply coincidence constraint
604     FeaturePtr aLine = ModelAPI_Feature::feature(aRect->linesList()->object(3));
605     AttributePtr aEndPnt = aLine->attribute(SketchPlugin_Line::START_ID());
606     setCoincident(ModelHighAPI_RefAttr(aEndPnt), theCorner.second);
607   }
608   return std::pair<std::shared_ptr<SketchAPI_Rectangle>, std::shared_ptr<SketchAPI_Point>>(aRect, aRect->centerSketchPoint());
609 }
610
611 std::pair<std::shared_ptr<SketchAPI_Rectangle>, std::shared_ptr<SketchAPI_Point>> SketchAPI_Sketch::addRectangleCentered(
612       double theCenterX, double theCenterY,
613       double theCornerX, double theCornerY
614 ) {
615   std::shared_ptr<ModelAPI_Feature> aFeature = compositeFeature()->addFeature(SketchAPI_Rectangle::ID());
616   auto aRect = RectanglePtr(new SketchAPI_Rectangle(aFeature, theCenterX, theCenterY, theCornerX, theCornerY, true));
617   return std::pair<std::shared_ptr<SketchAPI_Rectangle>, std::shared_ptr<SketchAPI_Point>>(aRect, aRect->centerSketchPoint());
618 }
619
620 // Way for create circle without a construction point
621 //--------------------------------------------------------------------------------------
622 std::shared_ptr<SketchAPI_Circle> SketchAPI_Sketch::addCircle(double theCenterX,
623                                                               double theCenterY,
624                                                               double theRadius)
625 {
626   std::shared_ptr<ModelAPI_Feature> aFeature =
627     compositeFeature()->addFeature(SketchPlugin_Circle::ID());
628   return CirclePtr(new SketchAPI_Circle(aFeature, theCenterX, theCenterY, theRadius, false, 0));
629 }
630
631 std::shared_ptr<SketchAPI_Circle> SketchAPI_Sketch::addCircle(
632                                     const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
633                                     double theRadius)
634 {
635   std::shared_ptr<ModelAPI_Feature> aFeature =
636     compositeFeature()->addFeature(SketchPlugin_Circle::ID());
637   return CirclePtr(new SketchAPI_Circle(aFeature, theCenter, theRadius, false, 0));
638 }
639
640 std::shared_ptr<SketchAPI_MacroCircle> SketchAPI_Sketch::addCircle(double theCenterX,
641                                                                    double theCenterY,
642                                                                    double thePassedX,
643                                                                    double thePassedY)
644 {
645   std::shared_ptr<ModelAPI_Feature> aFeature =
646     compositeFeature()->addFeature(SketchPlugin_MacroCircle::ID());
647   return MacroCirclePtr(new SketchAPI_MacroCircle(aFeature, theCenterX, theCenterY,
648                                                             thePassedX, thePassedY, false, 0));
649 }
650
651 std::shared_ptr<SketchAPI_MacroCircle> SketchAPI_Sketch::addCircle(
652     const std::shared_ptr<GeomAPI_Pnt2d>& theCenterPoint,
653     const std::shared_ptr<GeomAPI_Pnt2d>& thePassedPoint)
654 {
655   std::shared_ptr<ModelAPI_Feature> aFeature =
656     compositeFeature()->addFeature(SketchPlugin_MacroCircle::ID());
657   return MacroCirclePtr(new SketchAPI_MacroCircle(aFeature, theCenterPoint, thePassedPoint, false, 0));
658 }
659
660 std::shared_ptr<SketchAPI_MacroCircle> SketchAPI_Sketch::addCircle(double theX1, double theY1,
661                                                                    double theX2, double theY2,
662                                                                    double theX3, double theY3)
663 {
664   std::shared_ptr<ModelAPI_Feature> aFeature =
665     compositeFeature()->addFeature(SketchPlugin_MacroCircle::ID());
666
667   return MacroCirclePtr(new SketchAPI_MacroCircle(aFeature, theX1, theY1,
668                                                             theX2, theY2,
669                                                             theX3, theY3, false, 0));
670 }
671
672 std::shared_ptr<SketchAPI_MacroCircle> SketchAPI_Sketch::addCircle(
673     const std::shared_ptr<GeomAPI_Pnt2d>& thePoint1,
674     const std::shared_ptr<GeomAPI_Pnt2d>& thePoint2,
675     const std::shared_ptr<GeomAPI_Pnt2d>& thePoint3)
676 {
677   std::shared_ptr<ModelAPI_Feature> aFeature =
678     compositeFeature()->addFeature(SketchPlugin_MacroCircle::ID());
679   return MacroCirclePtr(new SketchAPI_MacroCircle(aFeature, thePoint1, thePoint2, thePoint3, false, 0));
680 }
681
682 std::shared_ptr<SketchAPI_Circle>
683   SketchAPI_Sketch::addCircle(const ModelHighAPI_Selection & theExternal)
684 {
685   std::shared_ptr<ModelAPI_Feature> aFeature =
686     compositeFeature()->addFeature(SketchPlugin_Circle::ID());
687   return CirclePtr(new SketchAPI_Circle(aFeature, theExternal));
688 }
689
690 std::shared_ptr<SketchAPI_Circle> SketchAPI_Sketch::addCircle(const std::wstring & theExternalName)
691 {
692   std::shared_ptr<ModelAPI_Feature> aFeature =
693     compositeFeature()->addFeature(SketchPlugin_Circle::ID());
694   return CirclePtr(new SketchAPI_Circle(aFeature, theExternalName));
695 }
696
697 // Way for create Circle with a construction point
698 //--------------------------------------------------------------------------------------
699 std::shared_ptr<SketchAPI_Circle> SketchAPI_Sketch::addCircleWithPoint(double theCenterX,
700   double theCenterY,
701   double theRadius,
702   double theAngle)
703 {
704   std::shared_ptr<ModelAPI_Feature> aFeature =
705     compositeFeature()->addFeature(SketchPlugin_Circle::ID());
706   return CirclePtr(new SketchAPI_Circle(aFeature, theCenterX, theCenterY, theRadius, true, theAngle));
707 }
708
709 std::shared_ptr<SketchAPI_Circle> SketchAPI_Sketch::addCircleWithPoint(
710   const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
711   double theRadius,
712   double theAngle)
713 {
714   std::shared_ptr<ModelAPI_Feature> aFeature =
715     compositeFeature()->addFeature(SketchPlugin_Circle::ID());
716   return CirclePtr(new SketchAPI_Circle(aFeature, theCenter, theRadius, true, theAngle));
717 }
718
719 std::shared_ptr<SketchAPI_MacroCircle> SketchAPI_Sketch::addCircleWithPoint(double theCenterX,
720   double theCenterY,
721   double thePassedX,
722   double thePassedY,
723   double theAngle)
724 {
725   std::shared_ptr<ModelAPI_Feature> aFeature =
726     compositeFeature()->addFeature(SketchPlugin_MacroCircle::ID());
727   return MacroCirclePtr(new SketchAPI_MacroCircle(aFeature, theCenterX, theCenterY,
728     thePassedX, thePassedY, true, theAngle));
729 }
730
731 std::shared_ptr<SketchAPI_MacroCircle> SketchAPI_Sketch::addCircleWithPoint(
732   const std::shared_ptr<GeomAPI_Pnt2d>& theCenterPoint,
733   const std::shared_ptr<GeomAPI_Pnt2d>& thePassedPoint,
734   double theAngle)
735 {
736   std::shared_ptr<ModelAPI_Feature> aFeature =
737     compositeFeature()->addFeature(SketchPlugin_MacroCircle::ID());
738   return MacroCirclePtr(new SketchAPI_MacroCircle(aFeature, theCenterPoint, thePassedPoint, true, theAngle));
739 }
740
741 std::shared_ptr<SketchAPI_MacroCircle> SketchAPI_Sketch::addCircleWithPoint(double theX1, double theY1,
742   double theX2, double theY2,
743   double theX3, double theY3,
744   double theAngle)
745 {
746   std::shared_ptr<ModelAPI_Feature> aFeature =
747     compositeFeature()->addFeature(SketchPlugin_MacroCircle::ID());
748   return MacroCirclePtr(new SketchAPI_MacroCircle(aFeature, theX1, theY1,
749     theX2, theY2,
750     theX3, theY3, true, theAngle));
751 }
752
753 std::shared_ptr<SketchAPI_MacroCircle> SketchAPI_Sketch::addCircleWithPoint(
754   const std::shared_ptr<GeomAPI_Pnt2d>& thePoint1,
755   const std::shared_ptr<GeomAPI_Pnt2d>& thePoint2,
756   const std::shared_ptr<GeomAPI_Pnt2d>& thePoint3,
757   double theAngle)
758 {
759   std::shared_ptr<ModelAPI_Feature> aFeature =
760     compositeFeature()->addFeature(SketchPlugin_MacroCircle::ID());
761   return MacroCirclePtr(new SketchAPI_MacroCircle(aFeature, thePoint1, thePoint2, thePoint3, true, theAngle));
762 }
763
764 std::shared_ptr<SketchAPI_Circle>
765 SketchAPI_Sketch::addCircleWithPoint(const ModelHighAPI_Selection& theExternal)
766 {
767   std::shared_ptr<ModelAPI_Feature> aFeature =
768     compositeFeature()->addFeature(SketchPlugin_Circle::ID());
769   return CirclePtr(new SketchAPI_Circle(aFeature, theExternal));
770 }
771
772 std::shared_ptr<SketchAPI_Circle> SketchAPI_Sketch::addCircleWithPoint(const std::wstring& theExternalName)
773 {
774   std::shared_ptr<ModelAPI_Feature> aFeature =
775     compositeFeature()->addFeature(SketchPlugin_Circle::ID());
776   return CirclePtr(new SketchAPI_Circle(aFeature, theExternalName));
777 }
778
779 //--------------------------------------------------------------------------------------
780 std::shared_ptr<SketchAPI_Arc> SketchAPI_Sketch::addArc(double theCenterX, double theCenterY,
781                                                         double theStartX, double theStartY,
782                                                         double theEndX, double theEndY,
783                                                         bool theInversed)
784 {
785   std::shared_ptr<ModelAPI_Feature> aFeature =
786     compositeFeature()->addFeature(SketchPlugin_Arc::ID());
787   return ArcPtr(new SketchAPI_Arc(aFeature,
788                                   theCenterX, theCenterY,
789                                   theStartX, theStartY,
790                                   theEndX, theEndY,
791                                   theInversed));
792 }
793
794 std::shared_ptr<SketchAPI_Arc> SketchAPI_Sketch::addArc(
795                                               const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
796                                               const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
797                                               const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
798                                               bool theInversed)
799 {
800   std::shared_ptr<ModelAPI_Feature> aFeature =
801     compositeFeature()->addFeature(SketchPlugin_Arc::ID());
802   return ArcPtr(new SketchAPI_Arc(aFeature, theCenter, theStart, theEnd, theInversed));
803 }
804
805 std::shared_ptr<SketchAPI_MacroArc> SketchAPI_Sketch::addArc(double theStartX, double theStartY,
806                                                         double theEndX, double theEndY,
807                                                         double thePassedX, double thePassedY)
808 {
809   std::shared_ptr<ModelAPI_Feature> aFeature =
810     compositeFeature()->addFeature(SketchPlugin_MacroArc::ID());
811   return MacroArcPtr(new SketchAPI_MacroArc(aFeature,
812                                        theStartX, theStartY,
813                                        theEndX, theEndY,
814                                        thePassedX, thePassedY));
815 }
816
817 std::shared_ptr<SketchAPI_MacroArc> SketchAPI_Sketch::addArc(
818                                                 const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
819                                                 const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
820                                                 const std::shared_ptr<GeomAPI_Pnt2d>& thePassed)
821 {
822   std::shared_ptr<ModelAPI_Feature> aFeature =
823     compositeFeature()->addFeature(SketchPlugin_MacroArc::ID());
824   return MacroArcPtr(new SketchAPI_MacroArc(aFeature, theStart, theEnd, thePassed));
825 }
826
827 std::shared_ptr<SketchAPI_MacroArc> SketchAPI_Sketch::addArc(
828                                                 const ModelHighAPI_RefAttr& theTangentPoint,
829                                                 double theEndX, double theEndY,
830                                                 bool theInversed,
831                                                 bool theTransversal)
832 {
833   std::shared_ptr<ModelAPI_Feature> aFeature =
834     compositeFeature()->addFeature(SketchPlugin_MacroArc::ID());
835   MacroArcPtr aMacroArc(new SketchAPI_MacroArc(aFeature));
836   if (theTransversal)
837     aMacroArc->setByTransversal(theTangentPoint, theEndX, theEndY, theInversed);
838   else
839     aMacroArc->setByTangent(theTangentPoint, theEndX, theEndY, theInversed);
840   return aMacroArc;
841 }
842
843 std::shared_ptr<SketchAPI_MacroArc> SketchAPI_Sketch::addArc(
844                                               const ModelHighAPI_RefAttr& theTangentPoint,
845                                               const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
846                                               bool theInversed,
847                                               bool theTransversal)
848 {
849   std::shared_ptr<ModelAPI_Feature> aFeature =
850     compositeFeature()->addFeature(SketchPlugin_MacroArc::ID());
851   MacroArcPtr aMacroArc(new SketchAPI_MacroArc(aFeature));
852   if (theTransversal)
853     aMacroArc->setByTransversal(theTangentPoint, theEnd, theInversed);
854   else
855     aMacroArc->setByTangent(theTangentPoint, theEnd, theInversed);
856   return aMacroArc;
857 }
858
859 std::shared_ptr<SketchAPI_Arc> SketchAPI_Sketch::addArc(const ModelHighAPI_Selection & theExternal)
860 {
861   std::shared_ptr<ModelAPI_Feature> aFeature =
862     compositeFeature()->addFeature(SketchPlugin_Arc::ID());
863   return ArcPtr(new SketchAPI_Arc(aFeature, theExternal));
864 }
865
866 std::shared_ptr<SketchAPI_Arc> SketchAPI_Sketch::addArc(const std::wstring & theExternalName)
867 {
868   std::shared_ptr<ModelAPI_Feature> aFeature =
869     compositeFeature()->addFeature(SketchPlugin_Arc::ID());
870   return ArcPtr(new SketchAPI_Arc(aFeature, theExternalName));
871 }
872
873 //--------------------------------------------------------------------------------------
874 std::shared_ptr<SketchAPI_Ellipse> SketchAPI_Sketch::addEllipse(
875     double theCenterX, double theCenterY,
876     double theFocusX, double theFocusY,
877     double theMinorRadius)
878 {
879   std::shared_ptr<ModelAPI_Feature> aFeature =
880       compositeFeature()->addFeature(SketchPlugin_Ellipse::ID());
881   return EllipsePtr(new SketchAPI_Ellipse(aFeature,
882       theCenterX, theCenterY, theFocusX, theFocusY, theMinorRadius));
883 }
884
885 std::shared_ptr<SketchAPI_Ellipse> SketchAPI_Sketch::addEllipse(
886     const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
887     const std::shared_ptr<GeomAPI_Pnt2d>& theFocus,
888     double theMinorRadius)
889 {
890   std::shared_ptr<ModelAPI_Feature> aFeature =
891       compositeFeature()->addFeature(SketchPlugin_Ellipse::ID());
892   return EllipsePtr(new SketchAPI_Ellipse(aFeature, theCenter, theFocus, theMinorRadius));
893 }
894
895 std::shared_ptr<SketchAPI_MacroEllipse> SketchAPI_Sketch::addEllipse(
896     double thePoint1X, double thePoint1Y,
897     double thePoint2X, double thePoint2Y,
898     double thePassedX, double thePassedY,
899     bool isPoint1Center)
900 {
901   std::shared_ptr<ModelAPI_Feature> aFeature =
902       compositeFeature()->addFeature(SketchPlugin_MacroEllipse::ID());
903   return MacroEllipsePtr(new SketchAPI_MacroEllipse(aFeature,
904       thePoint1X, thePoint1Y, thePoint2X, thePoint2Y, thePassedX, thePassedY, isPoint1Center));
905 }
906
907 std::shared_ptr<SketchAPI_MacroEllipse> SketchAPI_Sketch::addEllipse(
908     const PointOrReference& thePoint1,
909     const PointOrReference& thePoint2,
910     const PointOrReference& thePassedPoint,
911     bool isPoint1Center)
912 {
913   std::shared_ptr<ModelAPI_Feature> aFeature =
914       compositeFeature()->addFeature(SketchPlugin_MacroEllipse::ID());
915   MacroEllipsePtr anEllipse;
916   if (thePoint1.second.isEmpty() &&
917       thePoint2.second.isEmpty() &&
918       thePassedPoint.second.isEmpty()) {
919     anEllipse.reset(new SketchAPI_MacroEllipse(aFeature,
920         thePoint1.first, thePoint2.first, thePassedPoint.first, isPoint1Center));
921   }
922   else {
923     anEllipse.reset(new SketchAPI_MacroEllipse(aFeature,
924         thePoint1.first, thePoint1.second,
925         thePoint2.first, thePoint2.second,
926         thePassedPoint.first, thePassedPoint.second,
927         isPoint1Center));
928   }
929   return anEllipse;
930 }
931
932 std::shared_ptr<SketchAPI_Ellipse> SketchAPI_Sketch::addEllipse(
933     const ModelHighAPI_Selection & theExternal)
934 {
935   std::shared_ptr<ModelAPI_Feature> aFeature =
936       compositeFeature()->addFeature(SketchPlugin_Ellipse::ID());
937   return EllipsePtr(new SketchAPI_Ellipse(aFeature, theExternal));
938 }
939
940 std::shared_ptr<SketchAPI_Ellipse> SketchAPI_Sketch::addEllipse(
941     const std::wstring & theExternalName)
942 {
943   std::shared_ptr<ModelAPI_Feature> aFeature =
944       compositeFeature()->addFeature(SketchPlugin_Ellipse::ID());
945   return EllipsePtr(new SketchAPI_Ellipse(aFeature, theExternalName));
946 }
947
948 //--------------------------------------------------------------------------------------
949 std::shared_ptr<SketchAPI_EllipticArc> SketchAPI_Sketch::addEllipticArc(
950     double theCenterX, double theCenterY,
951     double theFocusX, double theFocusY,
952     double theStartX, double theStartY,
953     double theEndX, double theEndY,
954     bool theInversed)
955 {
956   std::shared_ptr<ModelAPI_Feature> aFeature =
957       compositeFeature()->addFeature(SketchPlugin_EllipticArc::ID());
958   return EllipticArcPtr(new SketchAPI_EllipticArc(aFeature,
959       theCenterX, theCenterY,
960       theFocusX, theFocusY,
961       theStartX, theStartY,
962       theEndX, theEndY,
963       theInversed));
964 }
965
966 std::shared_ptr<SketchAPI_MacroEllipticArc> SketchAPI_Sketch::addEllipticArc(
967     const PointOrReference& theCenter,
968     const PointOrReference& theMajorAxisPoint,
969     const PointOrReference& theStartPoint,
970     const PointOrReference& theEndPoint,
971     bool theInversed)
972 {
973   std::shared_ptr<ModelAPI_Feature> aFeature =
974       compositeFeature()->addFeature(SketchPlugin_MacroEllipticArc::ID());
975   return MacroEllipticArcPtr(new SketchAPI_MacroEllipticArc(aFeature,
976       theCenter.first, theCenter.second,
977       theMajorAxisPoint.first, theMajorAxisPoint.second,
978       theStartPoint.first, theStartPoint.second,
979       theEndPoint.first, theEndPoint.second,
980       theInversed));
981 }
982
983 std::shared_ptr<SketchAPI_EllipticArc> SketchAPI_Sketch::addEllipticArc(
984     const ModelHighAPI_Selection & theExternal)
985 {
986   std::shared_ptr<ModelAPI_Feature> aFeature =
987       compositeFeature()->addFeature(SketchPlugin_EllipticArc::ID());
988   return EllipticArcPtr(new SketchAPI_EllipticArc(aFeature, theExternal));
989 }
990
991 std::shared_ptr<SketchAPI_EllipticArc> SketchAPI_Sketch::addEllipticArc(
992     const std::wstring & theExternalName)
993 {
994   std::shared_ptr<ModelAPI_Feature> aFeature =
995       compositeFeature()->addFeature(SketchPlugin_EllipticArc::ID());
996   return EllipticArcPtr(new SketchAPI_EllipticArc(aFeature, theExternalName));
997 }
998
999 //--------------------------------------------------------------------------------------
1000
1001 std::shared_ptr<SketchAPI_BSpline> SketchAPI_Sketch::addSpline(
1002     const ModelHighAPI_Selection & external,
1003     const int degree,
1004     const std::list<PointOrReference>& poles,
1005     const std::list<ModelHighAPI_Double>& weights,
1006     const std::list<ModelHighAPI_Double>& knots,
1007     const std::list<ModelHighAPI_Integer>& multiplicities,
1008     const bool periodic)
1009 {
1010   // split poles and references to other shapes
1011   bool hasReference = false;
1012   std::list<GeomPnt2dPtr> aPoints;
1013   std::list<ModelHighAPI_RefAttr> aReferences;
1014   for (std::list<PointOrReference>::const_iterator it = poles.begin(); it != poles.end(); ++it) {
1015     aPoints.push_back(it->first);
1016     aReferences.push_back(it->second);
1017     if (!it->second.isEmpty())
1018       hasReference = true;
1019   }
1020
1021   BSplinePtr aBSpline;
1022   CompositeFeaturePtr aSketch = compositeFeature();
1023   if (hasReference) {
1024     // use macro-feature to create coincidences to referred features
1025     FeaturePtr aMacroFeature = aSketch->addFeature(
1026         periodic ? SketchPlugin_MacroBSplinePeriodic::ID() : SketchPlugin_MacroBSpline::ID());
1027     AttributePoint2DArrayPtr aPolesAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(
1028         aMacroFeature->attribute(SketchPlugin_MacroBSpline::POLES_ID()));
1029     AttributeDoubleArrayPtr aWeightsAttr =
1030         aMacroFeature->data()->realArray(SketchPlugin_MacroBSpline::WEIGHTS_ID());
1031     AttributeRefAttrListPtr aPolesRefAttr =
1032         aMacroFeature->data()->refattrlist(SketchPlugin_MacroBSpline::REF_POLES_ID());
1033     // always generate a control polygon to apply coincidences correctly
1034     aMacroFeature->boolean(SketchPlugin_MacroBSpline::CONTROL_POLYGON_ID())->setValue(true);
1035     // initialize B-spline attributes
1036     fillAttribute(aPoints, aPolesAttr);
1037     if (weights.empty())
1038       fillAttribute(std::list<ModelHighAPI_Double>(poles.size(), 1.0), aWeightsAttr);
1039     else
1040       fillAttribute(weights, aWeightsAttr);
1041     fillAttribute(aReferences, aPolesRefAttr);
1042     apply(); // to kill macro-feature
1043
1044     // find created B-spline feature
1045     const std::string& aKindToFind =
1046         periodic ? SketchPlugin_BSplinePeriodic::ID() : SketchPlugin_BSpline::ID();
1047     int aNbSubs = aSketch->numberOfSubs();
1048     for (int anIndex = aNbSubs - 1; anIndex >= 0; --anIndex) {
1049       FeaturePtr aFeature = aSketch->subFeature(anIndex);
1050       if (aFeature->getKind() == aKindToFind) {
1051         aBSpline.reset(periodic ? new SketchAPI_BSplinePeriodic(aFeature)
1052                                 : new SketchAPI_BSpline(aFeature));
1053         aBSpline->execute();
1054         break;
1055       }
1056     }
1057   }
1058   else {
1059     // compute B-spline by parameters
1060     FeaturePtr aFeature = aSketch->addFeature(
1061         periodic ? SketchPlugin_BSplinePeriodic::ID() : SketchPlugin_BSpline::ID());
1062
1063     aBSpline.reset(periodic ? new SketchAPI_BSplinePeriodic(aFeature)
1064                             : new SketchAPI_BSpline(aFeature));
1065     if (external.variantType() != ModelHighAPI_Selection::VT_Empty)
1066       aBSpline->setByExternal(external);
1067     else if (knots.empty() || multiplicities.empty())
1068       aBSpline->setByDegreePolesAndWeights(degree, aPoints, weights);
1069     else
1070       aBSpline->setByParameters(degree, aPoints, weights, knots, multiplicities);
1071   }
1072   return aBSpline;
1073 }
1074
1075 //--------------------------------------------------------------------------------------
1076 static std::shared_ptr<SketchAPI_BSpline> buildInterpolation(
1077     const CompositeFeaturePtr& theSketch,
1078     const FeaturePtr& theCurveFittingFeature,
1079     const std::list<ModelHighAPI_RefAttr>& points,
1080     const bool periodic,
1081     const bool closed)
1082 {
1083   AttributeBooleanPtr aPeriodicAttr =
1084       theCurveFittingFeature->boolean(SketchPlugin_CurveFitting::PERIODIC_ID());
1085   fillAttribute(periodic, aPeriodicAttr);
1086   AttributeBooleanPtr aClosedAttr =
1087       theCurveFittingFeature->boolean(SketchPlugin_CurveFitting::CLOSED_ID());
1088   fillAttribute(closed, aClosedAttr);
1089   AttributeRefAttrListPtr aPointsAttr =
1090       theCurveFittingFeature->refattrlist(SketchPlugin_CurveFitting::POINTS_ID());
1091   fillAttribute(points, aPointsAttr);
1092   apply(); // to execute and kill the macro-feature
1093
1094   // find created B-spline feature
1095   BSplinePtr aBSpline;
1096   const std::string& aKindToFind =
1097       periodic ? SketchPlugin_BSplinePeriodic::ID() : SketchPlugin_BSpline::ID();
1098   int aNbSubs = theSketch->numberOfSubs();
1099   for (int anIndex = aNbSubs - 1; anIndex >= 0; --anIndex) {
1100     FeaturePtr aFeature = theSketch->subFeature(anIndex);
1101     if (aFeature->getKind() == aKindToFind) {
1102       aBSpline.reset(periodic ? new SketchAPI_BSplinePeriodic(aFeature)
1103         : new SketchAPI_BSpline(aFeature));
1104       aBSpline->execute();
1105       break;
1106     }
1107   }
1108   return aBSpline;
1109 }
1110
1111 std::shared_ptr<SketchAPI_BSpline> SketchAPI_Sketch::addInterpolation(
1112     const std::list<ModelHighAPI_RefAttr>& points,
1113     const bool periodic,
1114     const bool closed)
1115 {
1116   CompositeFeaturePtr aSketch = compositeFeature();
1117   FeaturePtr anInterpFeature = aSketch->addFeature(SketchPlugin_CurveFitting::ID());
1118   anInterpFeature->string(SketchPlugin_CurveFitting::TYPE_ID())
1119       ->setValue(SketchPlugin_CurveFitting::TYPE_INTERPOLATION_ID());
1120   return buildInterpolation(aSketch, anInterpFeature, points, periodic, closed);
1121 }
1122
1123 std::shared_ptr<SketchAPI_BSpline> SketchAPI_Sketch::addApproximation(
1124     const std::list<ModelHighAPI_RefAttr>& points,
1125     const ModelHighAPI_Double& precision,
1126     const bool periodic,
1127     const bool closed)
1128 {
1129   CompositeFeaturePtr aSketch = compositeFeature();
1130   FeaturePtr anInterpFeature = aSketch->addFeature(SketchPlugin_CurveFitting::ID());
1131   anInterpFeature->string(SketchPlugin_CurveFitting::TYPE_ID())
1132       ->setValue(SketchPlugin_CurveFitting::TYPE_APPROXIMATION_ID());
1133   fillAttribute(precision, anInterpFeature->real(SketchPlugin_CurveFitting::PRECISION_ID()));
1134   return buildInterpolation(aSketch, anInterpFeature, points, periodic, closed);
1135 }
1136
1137 //--------------------------------------------------------------------------------------
1138 std::shared_ptr<SketchAPI_Projection> SketchAPI_Sketch::addProjection(
1139     const ModelHighAPI_Selection & theExternalFeature,
1140     bool keepResult,
1141     bool keepRefToOriginal)
1142 {
1143   std::shared_ptr<ModelAPI_Feature> aFeature =
1144     compositeFeature()->addFeature(SketchPlugin_Projection::ID());
1145   ProjectionPtr aProjection(new SketchAPI_Projection(aFeature));
1146   aProjection->setIncludeToResult(keepResult);
1147   aProjection->setKeepReferenceToOriginal(keepRefToOriginal);
1148   aProjection->setExternalFeature(theExternalFeature);
1149   return aProjection;
1150 }
1151
1152 //--------------------------------------------------------------------------------------
1153 std::shared_ptr<SketchAPI_Mirror> SketchAPI_Sketch::addMirror(
1154     const ModelHighAPI_RefAttr & theMirrorLine,
1155     const std::list<std::shared_ptr<ModelAPI_Object> > & theObjects)
1156 {
1157   std::shared_ptr<ModelAPI_Feature> aFeature =
1158     compositeFeature()->addFeature(SketchPlugin_ConstraintMirror::ID());
1159   return MirrorPtr(new SketchAPI_Mirror(aFeature, theMirrorLine, theObjects));
1160 }
1161
1162 //--------------------------------------------------------------------------------------
1163 std::shared_ptr<SketchAPI_Offset> SketchAPI_Sketch::addOffset(
1164     const std::list<std::shared_ptr<ModelAPI_Object> > & theObjects,
1165     const ModelHighAPI_Double & theValue,
1166     const bool theReversed,
1167     const std::string & theJointType,
1168     const bool theApprox)
1169 {
1170   std::shared_ptr<ModelAPI_Feature> aFeature =
1171     compositeFeature()->addFeature(SketchPlugin_Offset::ID());
1172   return OffsetPtr(new SketchAPI_Offset(aFeature, theObjects, theValue, theReversed, theJointType, theApprox));
1173 }
1174
1175 //--------------------------------------------------------------------------------------
1176 std::shared_ptr<SketchAPI_Translation> SketchAPI_Sketch::addTranslation(
1177     const std::list<std::shared_ptr<ModelAPI_Object> > & theObjects,
1178     const ModelHighAPI_RefAttr & thePoint1,
1179     const ModelHighAPI_RefAttr & thePoint2,
1180     const ModelHighAPI_Integer & theNumberOfObjects,
1181     bool theFullValue)
1182 {
1183   std::shared_ptr<ModelAPI_Feature> aFeature =
1184     compositeFeature()->addFeature(SketchPlugin_MultiTranslation::ID());
1185   return TranslationPtr(new SketchAPI_Translation(aFeature, theObjects, thePoint1,
1186                                                   thePoint2, theNumberOfObjects, theFullValue));
1187 }
1188
1189 //--------------------------------------------------------------------------------------
1190 std::shared_ptr<SketchAPI_Rotation> SketchAPI_Sketch::addRotation(
1191     const std::list<std::shared_ptr<ModelAPI_Object> > & theObjects,
1192     const ModelHighAPI_RefAttr & theCenter,
1193     const ModelHighAPI_Double & theAngle,
1194     const ModelHighAPI_Integer & theNumberOfObjects,
1195     bool theFullValue,
1196     bool theReversed)
1197 {
1198   std::shared_ptr<ModelAPI_Feature> aFeature =
1199     compositeFeature()->addFeature(SketchPlugin_MultiRotation::ID());
1200   return RotationPtr(
1201     new SketchAPI_Rotation(aFeature, theObjects, theCenter,
1202                            theAngle, theNumberOfObjects, theFullValue, theReversed));
1203 }
1204
1205 //--------------------------------------------------------------------------------------
1206 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::addSplit(
1207                                           const ModelHighAPI_Reference& theFeature,
1208                                           const std::shared_ptr<GeomAPI_Pnt2d>& thePositionPoint)
1209 {
1210   std::shared_ptr<ModelAPI_Feature> aFeature =
1211     compositeFeature()->addFeature(SketchPlugin_Split::ID());
1212   fillAttribute(theFeature, aFeature->reference(SketchPlugin_Split::SELECTED_OBJECT()));
1213
1214   AttributePtr anAttribute = aFeature->attribute(SketchPlugin_Split::SELECTED_POINT());
1215   if (anAttribute->attributeType() == GeomDataAPI_Point2D::typeId()) {
1216     AttributePoint2DPtr aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttribute);
1217     fillAttribute(thePositionPoint, aPointAttr);
1218   }
1219
1220   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1221 }
1222
1223 //--------------------------------------------------------------------------------------
1224 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::addTrim(
1225                                         const ModelHighAPI_Reference& theFeature,
1226                                         const std::shared_ptr<GeomAPI_Pnt2d>& thePositionPoint)
1227 {
1228   std::shared_ptr<ModelAPI_Feature> aFeature =
1229     compositeFeature()->addFeature(SketchPlugin_Trim::ID());
1230   fillAttribute(theFeature, aFeature->reference(SketchPlugin_Trim::SELECTED_OBJECT()));
1231
1232   AttributePtr anAttribute = aFeature->attribute(SketchPlugin_Trim::SELECTED_POINT());
1233   if (anAttribute->attributeType() == GeomDataAPI_Point2D::typeId()) {
1234     AttributePoint2DPtr aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttribute);
1235     fillAttribute(thePositionPoint, aPointAttr);
1236   }
1237
1238   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1239 }
1240
1241 //--------------------------------------------------------------------------------------
1242 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setAngle(
1243     const ModelHighAPI_RefAttr & theLine1,
1244     const ModelHighAPI_RefAttr & theLine2,
1245     const ModelHighAPI_Double & theValue,
1246     const std::string& theType)
1247 {
1248   std::shared_ptr<ModelAPI_Feature> aFeature =
1249       compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID());
1250
1251   const int aVersion = theType.empty() ? SketchPlugin_ConstraintAngle::THE_VERSION_0
1252                                        : SketchPlugin_ConstraintAngle::THE_VERSION_1;
1253   fillAttribute(aVersion, aFeature->integer(SketchPlugin_ConstraintAngle::VERSION_ID()));
1254
1255   int aType = (int)SketcherPrs_Tools::ANGLE_DIRECT;
1256   fillAttribute(aType, aFeature->integer(SketchPlugin_ConstraintAngle::PREV_TYPE_ID()));
1257   fillAttribute(aType, aFeature->integer(SketchPlugin_ConstraintAngle::TYPE_ID()));
1258
1259   if (aVersion == SketchPlugin_ConstraintAngle::THE_VERSION_0)
1260     fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()));
1261
1262   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
1263   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
1264
1265   if (aVersion == SketchPlugin_ConstraintAngle::THE_VERSION_1) {
1266     std::string aTypeLC = theType;
1267     std::transform(aTypeLC.begin(), aTypeLC.end(), aTypeLC.begin(),
1268                    [](char c) { return static_cast<char>(::tolower(c)); });
1269     if (aTypeLC == "supplementary")
1270       aType = (int)SketcherPrs_Tools::ANGLE_COMPLEMENTARY;
1271     else if (aTypeLC == "backward")
1272       aType = (int)SketcherPrs_Tools::ANGLE_BACKWARD;
1273
1274     fillAttribute(aType, aFeature->integer(SketchPlugin_ConstraintAngle::TYPE_ID()));
1275     fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()));
1276   }
1277
1278   aFeature->execute();
1279   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1280 }
1281
1282 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setAngleComplementary(
1283     const ModelHighAPI_RefAttr & theLine1,
1284     const ModelHighAPI_RefAttr & theLine2,
1285     const ModelHighAPI_Double & theValue)
1286 {
1287   std::shared_ptr<ModelAPI_Feature> aFeature =
1288       compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID());
1289   fillAttribute(SketchPlugin_ConstraintAngle::THE_VERSION_0,
1290       aFeature->integer(SketchPlugin_ConstraintAngle::VERSION_ID()));
1291   fillAttribute(SketcherPrs_Tools::ANGLE_COMPLEMENTARY,
1292       aFeature->integer(SketchPlugin_ConstraintAngle::TYPE_ID()));
1293   fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()));
1294   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
1295   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
1296   aFeature->execute();
1297   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1298 }
1299
1300 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setAngleBackward(
1301     const ModelHighAPI_RefAttr & theLine1,
1302     const ModelHighAPI_RefAttr & theLine2,
1303     const ModelHighAPI_Double & theValue)
1304 {
1305   std::shared_ptr<ModelAPI_Feature> aFeature =
1306       compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID());
1307   fillAttribute(SketchPlugin_ConstraintAngle::THE_VERSION_0,
1308       aFeature->integer(SketchPlugin_ConstraintAngle::VERSION_ID()));
1309   fillAttribute(SketcherPrs_Tools::ANGLE_BACKWARD,
1310       aFeature->integer(SketchPlugin_ConstraintAngle::TYPE_ID()));
1311   fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()));
1312   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
1313   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
1314   aFeature->execute();
1315   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1316 }
1317
1318 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setCoincident(
1319     const ModelHighAPI_RefAttr & thePoint1,
1320     const ModelHighAPI_RefAttr & thePoint2)
1321 {
1322   std::shared_ptr<ModelAPI_Feature> aFeature =
1323       compositeFeature()->addFeature(SketchPlugin_ConstraintCoincidence::ID());
1324   fillAttribute(thePoint1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
1325   fillAttribute(thePoint2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
1326   aFeature->execute();
1327   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1328 }
1329
1330 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setCollinear(
1331     const ModelHighAPI_RefAttr & theLine1,
1332     const ModelHighAPI_RefAttr & theLine2)
1333 {
1334   std::shared_ptr<ModelAPI_Feature> aFeature =
1335       compositeFeature()->addFeature(SketchPlugin_ConstraintCollinear::ID());
1336   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
1337   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
1338   aFeature->execute();
1339   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1340 }
1341
1342 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setDistance(
1343     const ModelHighAPI_RefAttr & thePoint,
1344     const ModelHighAPI_RefAttr & thePointOrLine,
1345     const ModelHighAPI_Double & theValue,
1346     bool isSigned)
1347 {
1348   std::shared_ptr<ModelAPI_Feature> aFeature =
1349       compositeFeature()->addFeature(SketchPlugin_ConstraintDistance::ID());
1350   fillAttribute(thePoint, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
1351   fillAttribute(thePointOrLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
1352   fillAttribute(theValue, aFeature->real(SketchPlugin_Constraint::VALUE()));
1353   fillAttribute(isSigned, aFeature->boolean(SketchPlugin_ConstraintDistance::SIGNED()));
1354   aFeature->execute();
1355   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1356 }
1357
1358 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setSignedDistance(
1359     const ModelHighAPI_RefAttr & thePoint,
1360     const ModelHighAPI_RefAttr & thePointOrLine,
1361     const ModelHighAPI_Double & theValue)
1362 {
1363   return setDistance(thePoint, thePointOrLine, theValue, true);
1364 }
1365
1366 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setUnsignedDistance(
1367     const ModelHighAPI_RefAttr & thePoint,
1368     const ModelHighAPI_RefAttr & thePointOrLine,
1369     const ModelHighAPI_Double & theValue)
1370 {
1371   return setDistance(thePoint, thePointOrLine, theValue, false);
1372 }
1373
1374 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setHorizontalDistance(
1375     const ModelHighAPI_RefAttr & thePoint1,
1376     const ModelHighAPI_RefAttr & thePoint2,
1377     const ModelHighAPI_Double & theValue)
1378 {
1379   std::shared_ptr<ModelAPI_Feature> aFeature =
1380       compositeFeature()->addFeature(SketchPlugin_ConstraintDistanceHorizontal::ID());
1381   fillAttribute(thePoint1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
1382   fillAttribute(thePoint2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
1383   fillAttribute(theValue,
1384       aFeature->real(SketchPlugin_ConstraintDistanceAlongDir::DISTANCE_VALUE_ID()));
1385   aFeature->execute();
1386   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1387 }
1388
1389 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setVerticalDistance(
1390     const ModelHighAPI_RefAttr & thePoint1,
1391     const ModelHighAPI_RefAttr & thePoint2,
1392     const ModelHighAPI_Double & theValue)
1393 {
1394   std::shared_ptr<ModelAPI_Feature> aFeature =
1395       compositeFeature()->addFeature(SketchPlugin_ConstraintDistanceVertical::ID());
1396   fillAttribute(thePoint1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
1397   fillAttribute(thePoint2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
1398   fillAttribute(theValue,
1399       aFeature->real(SketchPlugin_ConstraintDistanceAlongDir::DISTANCE_VALUE_ID()));
1400   aFeature->execute();
1401   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1402 }
1403
1404 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setEqual(
1405     const ModelHighAPI_RefAttr & theObject1,
1406     const ModelHighAPI_RefAttr & theObject2)
1407 {
1408   std::shared_ptr<ModelAPI_Feature> aFeature =
1409       compositeFeature()->addFeature(SketchPlugin_ConstraintEqual::ID());
1410   fillAttribute(theObject1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
1411   fillAttribute(theObject2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
1412   aFeature->execute();
1413   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1414 }
1415
1416 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setFillet(
1417     const ModelHighAPI_RefAttr & thePoint)
1418 {
1419   std::shared_ptr<ModelAPI_Feature> aFeature =
1420       compositeFeature()->addFeature(SketchPlugin_Fillet::ID());
1421   fillAttribute(thePoint, aFeature->data()->refattr(SketchPlugin_Fillet::FILLET_POINT_ID()));
1422   apply(); // finish operation to remove Fillet feature correcly
1423   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1424 }
1425
1426 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setFilletWithRadius(
1427     const ModelHighAPI_RefAttr & thePoint,
1428     const ModelHighAPI_Double & theRadius)
1429 {
1430   CompositeFeaturePtr aSketch = compositeFeature();
1431   int aNbSubs = aSketch->numberOfSubs();
1432
1433   // create fillet
1434   InterfacePtr aFilletFeature = setFillet(thePoint);
1435
1436   // set radius for just created arc
1437   FeaturePtr anArc = aSketch->subFeature(aNbSubs - 1);
1438   if (anArc->getKind() == SketchPlugin_Arc::ID())
1439     setRadius(ModelHighAPI_RefAttr(ObjectPtr(anArc->lastResult())), ModelHighAPI_Double(theRadius));
1440
1441   return aFilletFeature;
1442 }
1443
1444 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setFixed(
1445     const ModelHighAPI_RefAttr & theObject)
1446 {
1447   std::shared_ptr<ModelAPI_Feature> aFeature =
1448       compositeFeature()->addFeature(SketchPlugin_ConstraintRigid::ID());
1449   fillAttribute(theObject, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
1450   aFeature->execute();
1451   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1452 }
1453
1454 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setHorizontal(
1455     const ModelHighAPI_RefAttr & theLine)
1456 {
1457   std::shared_ptr<ModelAPI_Feature> aFeature =
1458       compositeFeature()->addFeature(SketchPlugin_ConstraintHorizontal::ID());
1459   fillAttribute(theLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
1460   aFeature->execute();
1461   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1462 }
1463
1464 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setLength(
1465     const ModelHighAPI_RefAttr & theLine,
1466     const ModelHighAPI_Double & theValue)
1467 {
1468   std::shared_ptr<ModelAPI_Feature> aFeature =
1469       compositeFeature()->addFeature(SketchPlugin_ConstraintLength::ID());
1470   fillAttribute(theLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
1471   fillAttribute(theValue, aFeature->real(SketchPlugin_Constraint::VALUE()));
1472   aFeature->execute();
1473   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1474 }
1475
1476 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setMiddlePoint(
1477     const ModelHighAPI_RefAttr & thePoint,
1478     const ModelHighAPI_RefAttr & theLine)
1479 {
1480   std::shared_ptr<ModelAPI_Feature> aFeature =
1481       compositeFeature()->addFeature(SketchPlugin_ConstraintMiddle::ID());
1482   auto aType = aFeature->data()->string(SketchPlugin_ConstraintMiddle::MIDDLE_TYPE());
1483   fillAttribute(SketchPlugin_ConstraintMiddle::MIDDLE_TYPE_BY_LINE_AND_POINT(), aType);
1484
1485   fillAttribute(thePoint, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
1486   fillAttribute(theLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
1487
1488   aFeature->execute();
1489   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1490 }
1491
1492 std::shared_ptr<SketchAPI_MacroMiddlePoint> SketchAPI_Sketch::setMiddlePoint(
1493   const ModelHighAPI_RefAttr& theLine)
1494 {
1495   std::shared_ptr<ModelAPI_Feature> aFeature =
1496     compositeFeature()->addFeature(SketchPlugin_Point::ID());
1497
1498   ObjectPtr anObj = theLine.object();
1499   auto aPoint = middlePoint(anObj, this);
1500
1501   return std::shared_ptr<SketchAPI_MacroMiddlePoint>
1502     (new SketchAPI_MacroMiddlePoint(aFeature, theLine, aPoint));
1503 }
1504
1505 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setParallel(
1506     const ModelHighAPI_RefAttr & theLine1,
1507     const ModelHighAPI_RefAttr & theLine2)
1508 {
1509   std::shared_ptr<ModelAPI_Feature> aFeature =
1510       compositeFeature()->addFeature(SketchPlugin_ConstraintParallel::ID());
1511   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
1512   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
1513   aFeature->execute();
1514   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1515 }
1516
1517 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setPerpendicular(
1518     const ModelHighAPI_RefAttr & theLine1,
1519     const ModelHighAPI_RefAttr & theLine2)
1520 {
1521   std::shared_ptr<ModelAPI_Feature> aFeature =
1522       compositeFeature()->addFeature(SketchPlugin_ConstraintPerpendicular::ID());
1523   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
1524   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
1525   aFeature->execute();
1526   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1527 }
1528
1529 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setRadius(
1530     const ModelHighAPI_RefAttr & theCircleOrArc,
1531     const ModelHighAPI_Double & theValue)
1532 {
1533   std::shared_ptr<ModelAPI_Feature> aFeature =
1534       compositeFeature()->addFeature(SketchPlugin_ConstraintRadius::ID());
1535   fillAttribute(theCircleOrArc, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
1536   fillAttribute(theValue, aFeature->real(SketchPlugin_Constraint::VALUE()));
1537   aFeature->execute();
1538   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1539 }
1540
1541 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setTangent(
1542     const ModelHighAPI_RefAttr & theLine,
1543     const ModelHighAPI_RefAttr & theCircle)
1544 {
1545   std::shared_ptr<ModelAPI_Feature> aFeature =
1546       compositeFeature()->addFeature(SketchPlugin_ConstraintTangent::ID());
1547   fillAttribute(theLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
1548   fillAttribute(theCircle, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
1549   aFeature->execute();
1550   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1551 }
1552
1553 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setVertical(
1554     const ModelHighAPI_RefAttr & theLine)
1555 {
1556   std::shared_ptr<ModelAPI_Feature> aFeature =
1557       compositeFeature()->addFeature(SketchPlugin_ConstraintVertical::ID());
1558   fillAttribute(theLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
1559   aFeature->execute();
1560   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1561 }
1562
1563 //--------------------------------------------------------------------------------------
1564
1565 void SketchAPI_Sketch::move(const ModelHighAPI_RefAttr& theMovedEntity,
1566                             const std::shared_ptr<GeomAPI_Pnt2d>& theTargetPoint)
1567 {
1568   std::shared_ptr<ModelAPI_ObjectMovedMessage> aMessage(new ModelAPI_ObjectMovedMessage);
1569   theMovedEntity.fillMessage(aMessage);
1570
1571   std::shared_ptr<GeomAPI_Pnt2d> anOriginalPosition;
1572   if (aMessage->movedAttribute())
1573     anOriginalPosition = pointCoordinates(aMessage->movedAttribute());
1574   else
1575     anOriginalPosition = middlePoint(aMessage->movedObject(), this);
1576
1577   if (!anOriginalPosition)
1578     return; // something has gone wrong, do not process movement
1579
1580   aMessage->setOriginalPosition(anOriginalPosition);
1581   aMessage->setCurrentPosition(theTargetPoint);
1582   Events_Loop::loop()->send(aMessage);
1583 }
1584
1585 void SketchAPI_Sketch::move(const ModelHighAPI_RefAttr& theMovedEntity,
1586                             double theTargetX, double theTargetY)
1587 {
1588   std::shared_ptr<GeomAPI_Pnt2d> aTargetPoint(new GeomAPI_Pnt2d(theTargetX, theTargetY));
1589   move(theMovedEntity, aTargetPoint);
1590 }
1591
1592 //--------------------------------------------------------------------------------------
1593
1594 std::shared_ptr<GeomAPI_Pnt2d> SketchAPI_Sketch::to2D(const std::shared_ptr<GeomAPI_Pnt>& thePoint)
1595 {
1596   FeaturePtr aBase = feature();
1597   std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
1598       aBase->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
1599   std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1600       aBase->attribute(SketchPlugin_Sketch::NORM_ID()));
1601   std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1602       aBase->attribute(SketchPlugin_Sketch::DIRX_ID()));
1603   std::shared_ptr<GeomAPI_Dir> aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
1604
1605   return thePoint->to2D(aC->pnt(), aX->dir(), aY);
1606 }
1607
1608 //--------------------------------------------------------------------------------------
1609
1610 static bool isDifferent(GeomFacePtr theFace1, GeomFacePtr theFace2)
1611 {
1612   // collect edges of the first face
1613   std::list<GeomShapePtr> anEdges1;
1614   for (GeomAPI_ShapeExplorer anExp(theFace1, GeomAPI_Shape::EDGE); anExp.more(); anExp.next())
1615     anEdges1.push_back(anExp.current());
1616   // compare edges of faces
1617   for (GeomAPI_ShapeExplorer anExp(theFace2, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
1618     GeomShapePtr aCurrent = anExp.current();
1619     bool isFound = false;
1620     std::list<GeomShapePtr>::iterator anIt1 = anEdges1.begin();
1621     for (; anIt1 != anEdges1.end(); ++anIt1)
1622       if (aCurrent->isSameGeometry(*anIt1)) {
1623         isFound = true;
1624         anEdges1.erase(anIt1);
1625         break;
1626       }
1627     if (!isFound)
1628       return true;
1629   }
1630   return !anEdges1.empty();
1631 }
1632
1633 static bool isCustomFacesOrder(CompositeFeaturePtr theSketch)
1634 {
1635   ResultConstructionPtr aSketchResult =
1636       std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(theSketch->lastResult());
1637   if (!aSketchResult)
1638     return false;
1639
1640   std::shared_ptr<GeomAPI_PlanarEdges> aWires =
1641       std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aSketchResult->shape());
1642   if (!aWires)
1643     return false;
1644
1645   // collect faces constructed by SketchBuilder algorithm
1646   GeomAlgoAPI_SketchBuilder aSketchBuilder(aWires->origin(), aWires->dirX(),
1647                                            aWires->norm(), aWires);
1648   const ListOfShape& aFaces = aSketchBuilder.faces();
1649
1650   // compare faces stored in sketch with faces generated by SketchBuilder
1651   int aNbSketchFaces = aSketchResult->facesNum();
1652   int aFaceIndex = 0;
1653   for (ListOfShape::const_iterator aFIt = aFaces.begin();
1654        aFIt != aFaces.end() && aFaceIndex < aNbSketchFaces;
1655        ++aFIt, ++aFaceIndex) {
1656     GeomFacePtr aSketchFace = aSketchResult->face(aFaceIndex);
1657     GeomFacePtr aCurFace = (*aFIt)->face();
1658     if (isDifferent(aSketchFace, aCurFace))
1659       return true;
1660   }
1661   return false;
1662 }
1663
1664 static void edgesOfSketchFaces(CompositeFeaturePtr theSketch,
1665                                std::list<std::list<ResultPtr> >& theEdges)
1666 {
1667   ResultConstructionPtr aSketchResult =
1668       std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(theSketch->lastResult());
1669   if (!aSketchResult)
1670     return;
1671
1672   // collect curves of the sketch
1673   std::map<GeomCurvePtr, ResultPtr, GeomAPI_Curve::Comparator> aCurves;
1674   int aSubNum = theSketch->numberOfSubs();
1675   for (int a = 0; a < aSubNum; ++a) {
1676     FeaturePtr aSub = theSketch->subFeature(a);
1677     const std::list<ResultPtr>& aResults = aSub->results();
1678     std::list<ResultPtr>::const_iterator aRes = aResults.cbegin();
1679     for (; aRes != aResults.cend(); aRes++) {
1680       GeomShapePtr aCurShape = (*aRes)->shape();
1681       if (aCurShape && aCurShape->isEdge())
1682         aCurves[untrimmedCurve(aCurShape)] = *aRes;
1683     }
1684   }
1685
1686   // convert each face to the list of results of its edges
1687   int aFacesNum = aSketchResult->facesNum();
1688   for (int a = 0; a < aFacesNum; ++a) {
1689     theEdges.push_back(std::list<ResultPtr>());
1690     std::list<ResultPtr>& aCurEdges = theEdges.back();
1691
1692     GeomFacePtr aFace = aSketchResult->face(a);
1693     for (GeomAPI_ShapeExplorer anExp(aFace, GeomAPI_Shape::EDGE);
1694          anExp.more(); anExp.next()) {
1695       GeomCurvePtr aCurrent = untrimmedCurve(anExp.current());
1696       aCurEdges.push_back(aCurves[aCurrent]);
1697     }
1698   }
1699 }
1700
1701 //--------------------------------------------------------------------------------------
1702
1703 void SketchAPI_Sketch::dump(ModelHighAPI_Dumper& theDumper) const
1704 {
1705   FeaturePtr aBase = feature();
1706   const std::string& aDocName = theDumper.name(aBase->document());
1707
1708   AttributeSelectionPtr anExternal = aBase->selection(SketchPlugin_SketchEntity::EXTERNAL_ID());
1709   if (anExternal->value()) {
1710     theDumper << aBase << " = model.addSketch(" << aDocName <<
1711       ", " << anExternal << ")" << std::endl;
1712   } else {
1713     // Sketch is base on a plane.
1714     std::shared_ptr<GeomAPI_Pnt> anOrigin = std::dynamic_pointer_cast<GeomDataAPI_Point>(
1715         aBase->attribute(SketchPlugin_Sketch::ORIGIN_ID()))->pnt();
1716     std::shared_ptr<GeomAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1717         aBase->attribute(SketchPlugin_Sketch::NORM_ID()))->dir();
1718     std::shared_ptr<GeomAPI_Dir> aDirX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1719         aBase->attribute(SketchPlugin_Sketch::DIRX_ID()))->dir();
1720
1721     // Check the plane is coordinate plane
1722     std::wstring aPlaneName = defaultPlane(anOrigin, aNormal, aDirX);
1723     if(anExternal->context()) { // checking for selected planes
1724       if (!aPlaneName.empty()
1725           && anExternal->context()->data()
1726           && anExternal->context()->data()->name() == aPlaneName) {
1727         // dump sketch based on coordinate plane
1728         theDumper << aBase << " = model.addSketch(" << aDocName
1729                   << ", model.standardPlane(\"" << aPlaneName << "\"))" << std::endl;
1730       } else { // some other plane
1731         theDumper << aBase << " = model.addSketch(" << aDocName <<
1732           ", " << anExternal<< ")" << std::endl;
1733       }
1734     } else {
1735       if (aPlaneName.empty()) {
1736         // needs import additional module
1737         theDumper.importModule("GeomAPI");
1738         // dump plane parameters
1739         const std::string& aSketchName = theDumper.name(aBase);
1740         std::string anOriginName = aSketchName + "_origin";
1741         std::string aNormalName  = aSketchName + "_norm";
1742         std::string aDirXName    = aSketchName + "_dirx";
1743         // use "\n" instead of std::endl to avoid automatic dumping sketch here
1744         // and then dumplicate dumping it in the next line
1745         theDumper << anOriginName << " = " << anOrigin << "\n"
1746                   << aNormalName  << " = " << aNormal  << "\n"
1747                   << aDirXName    << " = " << aDirX    << "\n";
1748         // dump sketch based on arbitrary plane
1749         theDumper << aBase << " = model.addSketch(" << aDocName << ", GeomAPI_Ax3("
1750                   << anOriginName << ", " << aDirXName << ", " << aNormalName << "))" << std::endl;
1751       } else {
1752         // dump sketch based on coordinate plane
1753         theDumper << aBase << " = model.addSketch(" << aDocName
1754                   << ", model.defaultPlane(\"" << aPlaneName << "\"))" << std::endl;
1755       }
1756     }
1757   }
1758
1759   // dump sketch's subfeatures
1760   CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aBase);
1761   theDumper.processSubs(aCompFeat, true);
1762
1763   // if face order differs to the order generated by SketchBuilder,
1764   // dump the list of faces for correct execution of the script
1765   if (isCustomFacesOrder(aCompFeat)) {
1766     std::list<std::list<ResultPtr> > aFaces;
1767     edgesOfSketchFaces(aCompFeat, aFaces);
1768
1769     const std::string& aSketchName = theDumper.name(aBase);
1770     std::string aMethodName(".changeFacesOrder");
1771     std::string aSpaceShift(aSketchName.size() + aMethodName.size(), ' ');
1772
1773     theDumper << aSketchName << aMethodName << "([";
1774     for (std::list<std::list<ResultPtr> >::iterator aFIt = aFaces.begin();
1775          aFIt != aFaces.end(); ++aFIt) {
1776       if (aFIt != aFaces.begin())
1777         theDumper << ",\n" << aSpaceShift << "  ";
1778       theDumper << *aFIt;
1779     }
1780     theDumper << "\n" << aSpaceShift << " ])" << std::endl;
1781     // call model.do() for correct update of the document's labels related to the changed faces
1782     theDumper << "model.do()" << std::endl;
1783   }
1784 }