Salome HOME
Task 2.12. New entities: ellipses and arcs of ellipses (issue #3003)
[modules/shaper.git] / src / SketchAPI / SketchAPI_Sketch.cpp
1 // Copyright (C) 2014-2019  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "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_Trim.h>
40 #include <SketchPlugin_Split.h>
41 #include <SketchPlugin_ConstraintTangent.h>
42 #include <SketchPlugin_ConstraintVertical.h>
43 #include <SketcherPrs_Tools.h>
44 //--------------------------------------------------------------------------------------
45 #include <ModelAPI_Events.h>
46 #include <ModelAPI_CompositeFeature.h>
47 #include <ModelAPI_ResultConstruction.h>
48 #include <ModelHighAPI_Double.h>
49 #include <ModelHighAPI_Dumper.h>
50 #include <ModelHighAPI_RefAttr.h>
51 #include <ModelHighAPI_Selection.h>
52 #include <ModelHighAPI_Services.h>
53 #include <ModelHighAPI_Tools.h>
54 //--------------------------------------------------------------------------------------
55 #include "SketchAPI_Arc.h"
56 #include "SketchAPI_Circle.h"
57 #include "SketchAPI_Ellipse.h"
58 #include "SketchAPI_IntersectionPoint.h"
59 #include "SketchAPI_Line.h"
60 #include "SketchAPI_MacroArc.h"
61 #include "SketchAPI_MacroCircle.h"
62 #include "SketchAPI_MacroEllipse.h"
63 #include "SketchAPI_Mirror.h"
64 #include "SketchAPI_Point.h"
65 #include "SketchAPI_Projection.h"
66 #include "SketchAPI_Rectangle.h"
67 #include "SketchAPI_Rotation.h"
68 #include "SketchAPI_Translation.h"
69 //--------------------------------------------------------------------------------------
70 #include <GeomAPI_Curve.h>
71 #include <GeomAPI_Dir2d.h>
72 #include <GeomAPI_PlanarEdges.h>
73 #include <GeomAPI_ShapeExplorer.h>
74 #include <GeomAPI_XY.h>
75 #include <GeomAlgoAPI_SketchBuilder.h>
76 #include <cmath>
77 //--------------------------------------------------------------------------------------
78 SketchAPI_Sketch::SketchAPI_Sketch(
79     const std::shared_ptr<ModelAPI_Feature> & theFeature)
80 : ModelHighAPI_Interface(theFeature)
81 {
82   initialize();
83 }
84
85 SketchAPI_Sketch::SketchAPI_Sketch(
86     const std::shared_ptr<ModelAPI_Feature> & theFeature,
87     const std::shared_ptr<GeomAPI_Ax3> & thePlane)
88 : ModelHighAPI_Interface(theFeature)
89 {
90   if (initialize()) {
91     setPlane(thePlane);
92   }
93 }
94
95 SketchAPI_Sketch::SketchAPI_Sketch(
96     const std::shared_ptr<ModelAPI_Feature> & theFeature,
97     const ModelHighAPI_Selection & theExternal)
98 : ModelHighAPI_Interface(theFeature)
99 {
100   if (initialize()) {
101     setExternal(theExternal);
102   }
103 }
104
105 SketchAPI_Sketch::SketchAPI_Sketch(
106     const std::shared_ptr<ModelAPI_Feature> & theFeature,
107     std::shared_ptr<ModelAPI_Object> thePlaneObject)
108 : ModelHighAPI_Interface(theFeature)
109 {
110   if (initialize()) {
111     setExternal(thePlaneObject);
112   }
113 }
114
115 SketchAPI_Sketch::~SketchAPI_Sketch()
116 {
117
118 }
119
120 //--------------------------------------------------------------------------------------
121 std::shared_ptr<ModelAPI_CompositeFeature> SketchAPI_Sketch::compositeFeature() const
122 {
123   return std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(feature());
124 }
125
126 //--------------------------------------------------------------------------------------
127 void SketchAPI_Sketch::setPlane(const std::shared_ptr<GeomAPI_Ax3> & thePlane)
128 {
129   fillAttribute(thePlane->origin(), myorigin);
130   fillAttribute(thePlane->dirX(), mydirX);
131   fillAttribute(thePlane->normal(), mynormal);
132
133   execute();
134 }
135
136 void SketchAPI_Sketch::setPlane(const ModelHighAPI_Selection & thePlane,
137                                 bool theRemoveExternalDependency)
138 {
139   FeaturePtr aSketch = feature();
140
141   DocumentPtr aDoc = aSketch->document();
142   bool useVisible = false;
143   FeaturePtr aCurFeatureBefore = aDoc->currentFeature(useVisible);
144   aDoc->setCurrentFeature(aSketch, useVisible);
145
146   if (theRemoveExternalDependency)
147     aSketch->customAction(SketchPlugin_Sketch::ACTION_REMOVE_EXTERNAL());
148
149   setExternal(thePlane);
150
151   aDoc->setCurrentFeature(aCurFeatureBefore, useVisible);
152 }
153
154 //--------------------------------------------------------------------------------------
155 void SketchAPI_Sketch::setExternal(const ModelHighAPI_Selection & theExternal)
156 {
157   fillAttribute(theExternal, myexternal);
158
159   execute();
160 }
161
162 void SketchAPI_Sketch::setExternal(std::shared_ptr<ModelAPI_Object> thePlaneObject)
163 {
164   ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(thePlaneObject);
165   ModelHighAPI_Selection aSel(aRes);
166   setExternal(aSel);
167 }
168
169 //--------------------------------------------------------------------------------------
170 void SketchAPI_Sketch::setValue(
171     const std::shared_ptr<ModelHighAPI_Interface> & theConstraint,
172     const ModelHighAPI_Double & theValue)
173 {
174   fillAttribute(theValue, theConstraint->feature()->real(SketchPlugin_Constraint::VALUE()));
175
176 //  theConstraint->execute();
177 }
178
179 //--------------------------------------------------------------------------------------
180 std::list<ModelHighAPI_Selection> SketchAPI_Sketch::selectFace() const
181 {
182   const_cast<SketchAPI_Sketch*>(this)->execute();
183
184   std::list<ModelHighAPI_Selection> aSelectionList;
185
186   ResultConstructionPtr aResultConstruction =
187       std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(feature()->firstResult());
188   if (aResultConstruction.get() == NULL)
189     return aSelectionList;
190
191   for (int anIndex = 0; anIndex < aResultConstruction->facesNum(); ++anIndex) {
192     aSelectionList.push_back(
193         ModelHighAPI_Selection(aResultConstruction,
194                                aResultConstruction->face(anIndex)));
195   }
196
197   return aSelectionList;
198 }
199
200 //--------------------------------------------------------------------------------------
201 SketchPtr addSketch(const std::shared_ptr<ModelAPI_Document> & thePart,
202                     const std::shared_ptr<GeomAPI_Ax3> & thePlane)
203 {
204   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(SketchAPI_Sketch::ID());
205   return SketchPtr(new SketchAPI_Sketch(aFeature, thePlane));
206 }
207
208 SketchPtr addSketch(const std::shared_ptr<ModelAPI_Document> & thePart,
209                     const ModelHighAPI_Selection & theExternal)
210 {
211   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(SketchAPI_Sketch::ID());
212   return SketchPtr(new SketchAPI_Sketch(aFeature, theExternal));
213 }
214
215 SketchPtr addSketch(const std::shared_ptr<ModelAPI_Document> & thePart,
216                     const std::string & theExternalName)
217 {
218   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(SketchAPI_Sketch::ID());
219   return SketchPtr(
220     new SketchAPI_Sketch(aFeature, ModelHighAPI_Selection("FACE", theExternalName)));
221 }
222
223 SketchPtr addSketch(const std::shared_ptr<ModelAPI_Document> & thePart,
224                     std::shared_ptr<ModelAPI_Object> thePlaneObject)
225 {
226   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(SketchAPI_Sketch::ID());
227   return SketchPtr(new SketchAPI_Sketch(aFeature, thePlaneObject));
228 }
229
230
231 //--------------------------------------------------------------------------------------
232 std::list< std::shared_ptr<SketchAPI_Point> > SketchAPI_Sketch::getFreePoints()
233 {
234   std::list< std::shared_ptr<SketchAPI_Point> > aFreePoints;
235   std::list<ResultPtr> aPoints = SketcherPrs_Tools::getFreePoints(compositeFeature());
236   for (std::list<ResultPtr>::iterator anIt = aPoints.begin(); anIt != aPoints.end(); ++anIt) {
237     FeaturePtr aFeature = ModelAPI_Feature::feature(*anIt);
238     PointPtr aPoint(new SketchAPI_Point(aFeature));
239     aFreePoints.push_back(aPoint);
240   }
241   return aFreePoints;
242 }
243
244 //--------------------------------------------------------------------------------------
245 static GeomCurvePtr untrimmedCurve(GeomShapePtr theShape)
246 {
247   GeomCurvePtr aCurve(new GeomAPI_Curve(theShape));
248   if (aCurve->isTrimmed())
249     aCurve = aCurve->basisCurve();
250   return aCurve;
251 }
252
253 void SketchAPI_Sketch::changeFacesOrder(
254     const std::list<std::list<ModelHighAPI_Selection> >& theFaces)
255 {
256   // collect faces of the sketch
257   ResultConstructionPtr aSketchResult =
258       std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(feature()->lastResult());
259   if (!aSketchResult) {
260     // sketch is nested to a boolean operation, thus, it has no result yet.
261     feature()->execute();
262     aSketchResult =
263         std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(feature()->lastResult());
264   }
265   std::list<GeomFacePtr> aFaces;
266   int aFacesNum = aSketchResult->facesNum();
267   for (int i = 0; i < aFacesNum; ++i)
268     aFaces.push_back(aSketchResult->face(i));
269   // find new faces order according to the given lists of edges
270   std::list<GeomFacePtr> aNewFacesOrder;
271   std::list<std::list<ModelHighAPI_Selection> >::const_iterator anIt = theFaces.begin();
272   for (; anIt != theFaces.end(); ++anIt) {
273     // find the appropriate face
274     std::list<GeomFacePtr>::iterator aFIt = aFaces.begin();
275     for (; aFIt != aFaces.end(); ++aFIt) {
276       std::list<ModelHighAPI_Selection>::const_iterator aEdgeIt = anIt->begin();
277       GeomAPI_ShapeExplorer aFExp(*aFIt, GeomAPI_Shape::EDGE);
278       for (; aEdgeIt != anIt->end() && aFExp.more(); ++aEdgeIt, aFExp.next()) {
279         ResultPtr aCurRes = aEdgeIt->resultSubShapePair().first;
280         if (!aCurRes)
281           break;
282         GeomCurvePtr aCurve1 = untrimmedCurve(aCurRes->shape());
283         GeomCurvePtr aCurve2 = untrimmedCurve(aFExp.current());
284         if (!aCurve1->isEqual(aCurve2))
285           break;
286       }
287
288       if (aEdgeIt == anIt->end() && !aFExp.more()) {
289         // face is found
290         aNewFacesOrder.push_back(*aFIt);
291         aFaces.erase(aFIt);
292         break;
293       }
294     }
295   }
296   // place the rest faces at the end of new faces list
297   if (!aFaces.empty())
298     aNewFacesOrder.insert(aNewFacesOrder.end(), aFaces.begin(), aFaces.end());
299   // update the result of the sketch with the new order of faces
300   aSketchResult->setFacesOrder(aNewFacesOrder);
301 }
302
303 //--------------------------------------------------------------------------------------
304 std::shared_ptr<SketchAPI_Point> SketchAPI_Sketch::addPoint(
305     double theX, double theY)
306 {
307   std::shared_ptr<ModelAPI_Feature> aFeature =
308     compositeFeature()->addFeature(SketchPlugin_Point::ID());
309   return PointPtr(new SketchAPI_Point(aFeature, theX, theY));
310 }
311 std::shared_ptr<SketchAPI_Point> SketchAPI_Sketch::addPoint(
312     const std::shared_ptr<GeomAPI_Pnt2d> & thePoint)
313 {
314   std::shared_ptr<ModelAPI_Feature> aFeature =
315     compositeFeature()->addFeature(SketchPlugin_Point::ID());
316   return PointPtr(new SketchAPI_Point(aFeature, thePoint));
317 }
318 std::shared_ptr<SketchAPI_Point>
319   SketchAPI_Sketch::addPoint(const ModelHighAPI_Selection & theExternal)
320 {
321   std::shared_ptr<ModelAPI_Feature> aFeature =
322     compositeFeature()->addFeature(SketchPlugin_Point::ID());
323   return PointPtr(new SketchAPI_Point(aFeature, theExternal));
324 }
325 std::shared_ptr<SketchAPI_Point> SketchAPI_Sketch::addPoint(const std::string & theExternalName)
326 {
327   std::shared_ptr<ModelAPI_Feature> aFeature =
328     compositeFeature()->addFeature(SketchPlugin_Point::ID());
329   return PointPtr(new SketchAPI_Point(aFeature, theExternalName));
330 }
331
332 //--------------------------------------------------------------------------------------
333 std::shared_ptr<SketchAPI_IntersectionPoint> SketchAPI_Sketch::addIntersectionPoint(
334     const ModelHighAPI_Selection & theExternal,
335     bool theKeepResult)
336 {
337   std::shared_ptr<ModelAPI_Feature> aFeature =
338     compositeFeature()->addFeature(SketchPlugin_IntersectionPoint::ID());
339   IntersectionPointPtr anIntersection(new SketchAPI_IntersectionPoint(aFeature, theExternal));
340   anIntersection->setIncludeToResult(theKeepResult);
341   return anIntersection;
342 }
343 std::shared_ptr<SketchAPI_IntersectionPoint> SketchAPI_Sketch::addIntersectionPoint(
344     const std::string & theExternalName,
345     bool theKeepResult)
346 {
347   std::shared_ptr<ModelAPI_Feature> aFeature =
348     compositeFeature()->addFeature(SketchPlugin_IntersectionPoint::ID());
349   IntersectionPointPtr anIntersection(new SketchAPI_IntersectionPoint(aFeature, theExternalName));
350   anIntersection->setIncludeToResult(theKeepResult);
351   return anIntersection;
352 }
353
354 //--------------------------------------------------------------------------------------
355 std::shared_ptr<SketchAPI_Line> SketchAPI_Sketch::addLine(double theX1, double theY1,
356                                                           double theX2, double theY2)
357 {
358   std::shared_ptr<ModelAPI_Feature> aFeature =
359     compositeFeature()->addFeature(SketchPlugin_Line::ID());
360   return LinePtr(new SketchAPI_Line(aFeature, theX1, theY1, theX2, theY2));
361 }
362 std::shared_ptr<SketchAPI_Line> SketchAPI_Sketch::addLine(
363     const std::shared_ptr<GeomAPI_Pnt2d> & theStartPoint,
364     const std::shared_ptr<GeomAPI_Pnt2d> & theEndPoint)
365 {
366   std::shared_ptr<ModelAPI_Feature> aFeature =
367     compositeFeature()->addFeature(SketchPlugin_Line::ID());
368   return LinePtr(new SketchAPI_Line(aFeature, theStartPoint, theEndPoint));
369 }
370 std::shared_ptr<SketchAPI_Line>
371   SketchAPI_Sketch::addLine(const ModelHighAPI_Selection & theExternal)
372 {
373   std::shared_ptr<ModelAPI_Feature> aFeature =
374     compositeFeature()->addFeature(SketchPlugin_Line::ID());
375   return LinePtr(new SketchAPI_Line(aFeature, theExternal));
376 }
377 std::shared_ptr<SketchAPI_Line> SketchAPI_Sketch::addLine(const std::string & theExternalName)
378 {
379   std::shared_ptr<ModelAPI_Feature> aFeature =
380     compositeFeature()->addFeature(SketchPlugin_Line::ID());
381   return LinePtr(new SketchAPI_Line(aFeature, theExternalName));
382 }
383
384 //--------------------------------------------------------------------------------------
385 std::shared_ptr<SketchAPI_Rectangle> SketchAPI_Sketch::addRectangle(double theX1, double theY1,
386                                                                     double theX2, double theY2)
387 {
388   std::shared_ptr<ModelAPI_Feature> aFeature =
389     compositeFeature()->addFeature(SketchAPI_Rectangle::ID());
390   return RectanglePtr(new SketchAPI_Rectangle(aFeature, theX1, theY1, theX2, theY2));
391 }
392 std::shared_ptr<SketchAPI_Rectangle> SketchAPI_Sketch::addRectangle(
393     const std::shared_ptr<GeomAPI_Pnt2d> & theStartPoint,
394     const std::shared_ptr<GeomAPI_Pnt2d> & theEndPoint)
395 {
396   std::shared_ptr<ModelAPI_Feature> aFeature =
397     compositeFeature()->addFeature(SketchAPI_Rectangle::ID());
398   return RectanglePtr(new SketchAPI_Rectangle(aFeature, theStartPoint, theEndPoint));
399 }
400
401 //--------------------------------------------------------------------------------------
402 std::shared_ptr<SketchAPI_Circle> SketchAPI_Sketch::addCircle(double theCenterX,
403                                                               double theCenterY,
404                                                               double theRadius)
405 {
406   std::shared_ptr<ModelAPI_Feature> aFeature =
407     compositeFeature()->addFeature(SketchPlugin_Circle::ID());
408   return CirclePtr(new SketchAPI_Circle(aFeature, theCenterX, theCenterY, theRadius));
409 }
410
411 std::shared_ptr<SketchAPI_Circle> SketchAPI_Sketch::addCircle(
412                                     const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
413                                     double theRadius)
414 {
415   std::shared_ptr<ModelAPI_Feature> aFeature =
416     compositeFeature()->addFeature(SketchPlugin_Circle::ID());
417   return CirclePtr(new SketchAPI_Circle(aFeature, theCenter, theRadius));
418 }
419
420 std::shared_ptr<SketchAPI_MacroCircle> SketchAPI_Sketch::addCircle(double theCenterX,
421                                                                    double theCenterY,
422                                                                    double thePassedX,
423                                                                    double thePassedY)
424 {
425   std::shared_ptr<ModelAPI_Feature> aFeature =
426     compositeFeature()->addFeature(SketchPlugin_MacroCircle::ID());
427   return MacroCirclePtr(new SketchAPI_MacroCircle(aFeature, theCenterX, theCenterY,
428                                                             thePassedX, thePassedY));
429 }
430
431 std::shared_ptr<SketchAPI_MacroCircle> SketchAPI_Sketch::addCircle(
432     const std::shared_ptr<GeomAPI_Pnt2d>& theCenterPoint,
433     const std::shared_ptr<GeomAPI_Pnt2d>& thePassedPoint)
434 {
435   std::shared_ptr<ModelAPI_Feature> aFeature =
436     compositeFeature()->addFeature(SketchPlugin_MacroCircle::ID());
437   return MacroCirclePtr(new SketchAPI_MacroCircle(aFeature, theCenterPoint, thePassedPoint));
438 }
439
440 std::shared_ptr<SketchAPI_MacroCircle> SketchAPI_Sketch::addCircle(double theX1, double theY1,
441                                                                    double theX2, double theY2,
442                                                                    double theX3, double theY3)
443 {
444   std::shared_ptr<ModelAPI_Feature> aFeature =
445     compositeFeature()->addFeature(SketchPlugin_MacroCircle::ID());
446   return MacroCirclePtr(new SketchAPI_MacroCircle(aFeature, theX1, theY1,
447                                                             theX2, theY2,
448                                                             theX3, theY3));
449 }
450
451 std::shared_ptr<SketchAPI_MacroCircle> SketchAPI_Sketch::addCircle(
452     const std::shared_ptr<GeomAPI_Pnt2d>& thePoint1,
453     const std::shared_ptr<GeomAPI_Pnt2d>& thePoint2,
454     const std::shared_ptr<GeomAPI_Pnt2d>& thePoint3)
455 {
456   std::shared_ptr<ModelAPI_Feature> aFeature =
457     compositeFeature()->addFeature(SketchPlugin_MacroCircle::ID());
458   return MacroCirclePtr(new SketchAPI_MacroCircle(aFeature, thePoint1, thePoint2, thePoint3));
459 }
460
461 std::shared_ptr<SketchAPI_Circle>
462   SketchAPI_Sketch::addCircle(const ModelHighAPI_Selection & theExternal)
463 {
464   std::shared_ptr<ModelAPI_Feature> aFeature =
465     compositeFeature()->addFeature(SketchPlugin_Circle::ID());
466   return CirclePtr(new SketchAPI_Circle(aFeature, theExternal));
467 }
468
469 std::shared_ptr<SketchAPI_Circle> SketchAPI_Sketch::addCircle(const std::string & theExternalName)
470 {
471   std::shared_ptr<ModelAPI_Feature> aFeature =
472     compositeFeature()->addFeature(SketchPlugin_Circle::ID());
473   return CirclePtr(new SketchAPI_Circle(aFeature, theExternalName));
474 }
475
476 //--------------------------------------------------------------------------------------
477 std::shared_ptr<SketchAPI_Arc> SketchAPI_Sketch::addArc(double theCenterX, double theCenterY,
478                                                         double theStartX, double theStartY,
479                                                         double theEndX, double theEndY,
480                                                         bool theInversed)
481 {
482   std::shared_ptr<ModelAPI_Feature> aFeature =
483     compositeFeature()->addFeature(SketchPlugin_Arc::ID());
484   return ArcPtr(new SketchAPI_Arc(aFeature,
485                                   theCenterX, theCenterY,
486                                   theStartX, theStartY,
487                                   theEndX, theEndY,
488                                   theInversed));
489 }
490
491 std::shared_ptr<SketchAPI_Arc> SketchAPI_Sketch::addArc(
492                                               const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
493                                               const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
494                                               const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
495                                               bool theInversed)
496 {
497   std::shared_ptr<ModelAPI_Feature> aFeature =
498     compositeFeature()->addFeature(SketchPlugin_Arc::ID());
499   return ArcPtr(new SketchAPI_Arc(aFeature, theCenter, theStart, theEnd, theInversed));
500 }
501
502 std::shared_ptr<SketchAPI_MacroArc> SketchAPI_Sketch::addArc(double theStartX, double theStartY,
503                                                         double theEndX, double theEndY,
504                                                         double thePassedX, double thePassedY)
505 {
506   std::shared_ptr<ModelAPI_Feature> aFeature =
507     compositeFeature()->addFeature(SketchPlugin_MacroArc::ID());
508   return MacroArcPtr(new SketchAPI_MacroArc(aFeature,
509                                        theStartX, theStartY,
510                                        theEndX, theEndY,
511                                        thePassedX, thePassedY));
512 }
513
514 std::shared_ptr<SketchAPI_MacroArc> SketchAPI_Sketch::addArc(
515                                                 const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
516                                                 const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
517                                                 const std::shared_ptr<GeomAPI_Pnt2d>& thePassed)
518 {
519   std::shared_ptr<ModelAPI_Feature> aFeature =
520     compositeFeature()->addFeature(SketchPlugin_MacroArc::ID());
521   return MacroArcPtr(new SketchAPI_MacroArc(aFeature, theStart, theEnd, thePassed));
522 }
523
524 std::shared_ptr<SketchAPI_MacroArc> SketchAPI_Sketch::addArc(
525                                                 const ModelHighAPI_RefAttr& theTangentPoint,
526                                                 double theEndX, double theEndY,
527                                                 bool theInversed,
528                                                 bool theTransversal)
529 {
530   std::shared_ptr<ModelAPI_Feature> aFeature =
531     compositeFeature()->addFeature(SketchPlugin_MacroArc::ID());
532   MacroArcPtr aMacroArc(new SketchAPI_MacroArc(aFeature));
533   if (theTransversal)
534     aMacroArc->setByTransversal(theTangentPoint, theEndX, theEndY, theInversed);
535   else
536     aMacroArc->setByTangent(theTangentPoint, theEndX, theEndY, theInversed);
537   return aMacroArc;
538 }
539
540 std::shared_ptr<SketchAPI_MacroArc> SketchAPI_Sketch::addArc(
541                                               const ModelHighAPI_RefAttr& theTangentPoint,
542                                               const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
543                                               bool theInversed,
544                                               bool theTransversal)
545 {
546   std::shared_ptr<ModelAPI_Feature> aFeature =
547     compositeFeature()->addFeature(SketchPlugin_MacroArc::ID());
548   MacroArcPtr aMacroArc(new SketchAPI_MacroArc(aFeature));
549   if (theTransversal)
550     aMacroArc->setByTransversal(theTangentPoint, theEnd, theInversed);
551   else
552     aMacroArc->setByTangent(theTangentPoint, theEnd, theInversed);
553   return aMacroArc;
554 }
555
556 std::shared_ptr<SketchAPI_Arc> SketchAPI_Sketch::addArc(const ModelHighAPI_Selection & theExternal)
557 {
558   std::shared_ptr<ModelAPI_Feature> aFeature =
559     compositeFeature()->addFeature(SketchPlugin_Arc::ID());
560   return ArcPtr(new SketchAPI_Arc(aFeature, theExternal));
561 }
562
563 std::shared_ptr<SketchAPI_Arc> SketchAPI_Sketch::addArc(const std::string & theExternalName)
564 {
565   std::shared_ptr<ModelAPI_Feature> aFeature =
566     compositeFeature()->addFeature(SketchPlugin_Arc::ID());
567   return ArcPtr(new SketchAPI_Arc(aFeature, theExternalName));
568 }
569
570 //--------------------------------------------------------------------------------------
571 std::shared_ptr<SketchAPI_Ellipse> SketchAPI_Sketch::addEllipse(
572     double theCenterX, double theCenterY,
573     double theFocusX, double theFocusY,
574     double theMinorRadius)
575 {
576   std::shared_ptr<ModelAPI_Feature> aFeature =
577       compositeFeature()->addFeature(SketchPlugin_Ellipse::ID());
578   return EllipsePtr(new SketchAPI_Ellipse(aFeature,
579       theCenterX, theCenterY, theFocusX, theFocusY, theMinorRadius));
580 }
581
582 std::shared_ptr<SketchAPI_Ellipse> SketchAPI_Sketch::addEllipse(
583     const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
584     const std::shared_ptr<GeomAPI_Pnt2d>& theFocus,
585     double theMinorRadius)
586 {
587   std::shared_ptr<ModelAPI_Feature> aFeature =
588       compositeFeature()->addFeature(SketchPlugin_Ellipse::ID());
589   return EllipsePtr(new SketchAPI_Ellipse(aFeature, theCenter, theFocus, theMinorRadius));
590 }
591
592 std::shared_ptr<SketchAPI_MacroEllipse> SketchAPI_Sketch::addEllipse(
593     double thePoint1X, double thePoint1Y,
594     double thePoint2X, double thePoint2Y,
595     double thePassedX, double thePassedY,
596     bool isPoint1Center)
597 {
598   std::shared_ptr<ModelAPI_Feature> aFeature =
599       compositeFeature()->addFeature(SketchPlugin_MacroEllipse::ID());
600   return MacroEllipsePtr(new SketchAPI_MacroEllipse(aFeature,
601       thePoint1X, thePoint1Y, thePoint2X, thePoint1Y, thePassedX, thePassedY, isPoint1Center));
602 }
603
604 std::shared_ptr<SketchAPI_MacroEllipse> SketchAPI_Sketch::addEllipse(
605     const std::pair<std::shared_ptr<GeomAPI_Pnt2d>, ModelHighAPI_RefAttr>& thePoint1,
606     const std::pair<std::shared_ptr<GeomAPI_Pnt2d>, ModelHighAPI_RefAttr>& thePoint2,
607     const std::pair<std::shared_ptr<GeomAPI_Pnt2d>, ModelHighAPI_RefAttr>& thePassedPoint,
608     bool isPoint1Center)
609 {
610   std::shared_ptr<ModelAPI_Feature> aFeature =
611       compositeFeature()->addFeature(SketchPlugin_MacroEllipse::ID());
612   MacroEllipsePtr anEllipse;
613   if (thePoint1.second.isEmpty() &&
614       thePoint2.second.isEmpty() &&
615       thePassedPoint.second.isEmpty()) {
616     anEllipse.reset(new SketchAPI_MacroEllipse(aFeature,
617         thePoint1.first, thePoint2.first, thePassedPoint.first, isPoint1Center));
618   }
619   else {
620     anEllipse.reset(new SketchAPI_MacroEllipse(aFeature,
621         thePoint1.first, thePoint1.second,
622         thePoint2.first, thePoint2.second,
623         thePassedPoint.first, thePassedPoint.second,
624         isPoint1Center));
625   }
626   return anEllipse;
627 }
628
629 std::shared_ptr<SketchAPI_Ellipse> SketchAPI_Sketch::addEllipse(
630     const ModelHighAPI_Selection & theExternal)
631 {
632   std::shared_ptr<ModelAPI_Feature> aFeature =
633       compositeFeature()->addFeature(SketchPlugin_Ellipse::ID());
634   return EllipsePtr(new SketchAPI_Ellipse(aFeature, theExternal));
635 }
636
637 std::shared_ptr<SketchAPI_Ellipse> SketchAPI_Sketch::addEllipse(
638     const std::string & theExternalName)
639 {
640   std::shared_ptr<ModelAPI_Feature> aFeature =
641       compositeFeature()->addFeature(SketchPlugin_Ellipse::ID());
642   return EllipsePtr(new SketchAPI_Ellipse(aFeature, theExternalName));
643 }
644
645 //--------------------------------------------------------------------------------------
646 std::shared_ptr<SketchAPI_Projection> SketchAPI_Sketch::addProjection(
647     const ModelHighAPI_Selection & theExternalFeature,
648     bool theKeepResult)
649 {
650   std::shared_ptr<ModelAPI_Feature> aFeature =
651     compositeFeature()->addFeature(SketchPlugin_Projection::ID());
652   ProjectionPtr aProjection(new SketchAPI_Projection(aFeature, theExternalFeature));
653   aProjection->setIncludeToResult(theKeepResult);
654   return aProjection;
655 }
656
657 std::shared_ptr<SketchAPI_Projection> SketchAPI_Sketch::addProjection(
658     const std::string & theExternalName,
659     bool theKeepResult)
660 {
661   std::shared_ptr<ModelAPI_Feature> aFeature =
662     compositeFeature()->addFeature(SketchPlugin_Projection::ID());
663   ProjectionPtr aProjection(new SketchAPI_Projection(aFeature, theExternalName));
664   aProjection->setIncludeToResult(theKeepResult);
665   return aProjection;
666 }
667
668 //--------------------------------------------------------------------------------------
669 std::shared_ptr<SketchAPI_Mirror> SketchAPI_Sketch::addMirror(
670     const ModelHighAPI_RefAttr & theMirrorLine,
671     const std::list<std::shared_ptr<ModelAPI_Object> > & theObjects)
672 {
673   std::shared_ptr<ModelAPI_Feature> aFeature =
674     compositeFeature()->addFeature(SketchPlugin_ConstraintMirror::ID());
675   return MirrorPtr(new SketchAPI_Mirror(aFeature, theMirrorLine, theObjects));
676 }
677
678 //--------------------------------------------------------------------------------------
679 std::shared_ptr<SketchAPI_Translation> SketchAPI_Sketch::addTranslation(
680     const std::list<std::shared_ptr<ModelAPI_Object> > & theObjects,
681     const ModelHighAPI_RefAttr & thePoint1,
682     const ModelHighAPI_RefAttr & thePoint2,
683     const ModelHighAPI_Integer & theNumberOfObjects,
684     bool theFullValue)
685 {
686   std::shared_ptr<ModelAPI_Feature> aFeature =
687     compositeFeature()->addFeature(SketchPlugin_MultiTranslation::ID());
688   return TranslationPtr(new SketchAPI_Translation(aFeature, theObjects, thePoint1,
689                                                   thePoint2, theNumberOfObjects, theFullValue));
690 }
691
692 //--------------------------------------------------------------------------------------
693 std::shared_ptr<SketchAPI_Rotation> SketchAPI_Sketch::addRotation(
694     const std::list<std::shared_ptr<ModelAPI_Object> > & theObjects,
695     const ModelHighAPI_RefAttr & theCenter,
696     const ModelHighAPI_Double & theAngle,
697     const ModelHighAPI_Integer & theNumberOfObjects,
698     bool theFullValue,
699     bool theReversed)
700 {
701   std::shared_ptr<ModelAPI_Feature> aFeature =
702     compositeFeature()->addFeature(SketchPlugin_MultiRotation::ID());
703   return RotationPtr(
704     new SketchAPI_Rotation(aFeature, theObjects, theCenter,
705                            theAngle, theNumberOfObjects, theFullValue, theReversed));
706 }
707
708 //--------------------------------------------------------------------------------------
709 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::addSplit(
710                                           const ModelHighAPI_Reference& theFeature,
711                                           const std::shared_ptr<GeomAPI_Pnt2d>& thePositionPoint)
712 {
713   std::shared_ptr<ModelAPI_Feature> aFeature =
714     compositeFeature()->addFeature(SketchPlugin_Split::ID());
715   fillAttribute(theFeature, aFeature->reference(SketchPlugin_Split::SELECTED_OBJECT()));
716
717   AttributePtr anAttribute = aFeature->attribute(SketchPlugin_Split::SELECTED_POINT());
718   if (anAttribute->attributeType() == GeomDataAPI_Point2D::typeId()) {
719     AttributePoint2DPtr aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttribute);
720     fillAttribute(thePositionPoint, aPointAttr);
721   }
722
723   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
724 }
725
726 //--------------------------------------------------------------------------------------
727 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::addTrim(
728                                         const ModelHighAPI_Reference& theFeature,
729                                         const std::shared_ptr<GeomAPI_Pnt2d>& thePositionPoint)
730 {
731   std::shared_ptr<ModelAPI_Feature> aFeature =
732     compositeFeature()->addFeature(SketchPlugin_Trim::ID());
733   fillAttribute(theFeature, aFeature->reference(SketchPlugin_Trim::SELECTED_OBJECT()));
734
735   AttributePtr anAttribute = aFeature->attribute(SketchPlugin_Trim::SELECTED_POINT());
736   if (anAttribute->attributeType() == GeomDataAPI_Point2D::typeId()) {
737     AttributePoint2DPtr aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttribute);
738     fillAttribute(thePositionPoint, aPointAttr);
739   }
740
741   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
742 }
743
744 //--------------------------------------------------------------------------------------
745 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setAngle(
746     const ModelHighAPI_RefAttr & theLine1,
747     const ModelHighAPI_RefAttr & theLine2,
748     const ModelHighAPI_Double & theValue)
749 {
750   std::shared_ptr<ModelAPI_Feature> aFeature =
751       compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID());
752   fillAttribute(SketcherPrs_Tools::ANGLE_DIRECT,
753       aFeature->integer(SketchPlugin_ConstraintAngle::TYPE_ID()));
754   // fill the value before llines to avoid calculation of angle value by the Angle feature
755   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
756   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
757   fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()));
758   aFeature->execute();
759   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
760 }
761
762 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setAngleComplementary(
763     const ModelHighAPI_RefAttr & theLine1,
764     const ModelHighAPI_RefAttr & theLine2,
765     const ModelHighAPI_Double & theValue)
766 {
767   std::shared_ptr<ModelAPI_Feature> aFeature =
768       compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID());
769   fillAttribute(SketcherPrs_Tools::ANGLE_COMPLEMENTARY,
770       aFeature->integer(SketchPlugin_ConstraintAngle::TYPE_ID()));
771   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
772   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
773   fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()));
774   aFeature->execute();
775   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
776 }
777
778 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setAngleBackward(
779     const ModelHighAPI_RefAttr & theLine1,
780     const ModelHighAPI_RefAttr & theLine2,
781     const ModelHighAPI_Double & theValue)
782 {
783   std::shared_ptr<ModelAPI_Feature> aFeature =
784       compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID());
785   fillAttribute(SketcherPrs_Tools::ANGLE_BACKWARD,
786       aFeature->integer(SketchPlugin_ConstraintAngle::TYPE_ID()));
787   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
788   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
789   fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()));
790   aFeature->execute();
791   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
792 }
793
794 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setCoincident(
795     const ModelHighAPI_RefAttr & thePoint1,
796     const ModelHighAPI_RefAttr & thePoint2)
797 {
798   std::shared_ptr<ModelAPI_Feature> aFeature =
799       compositeFeature()->addFeature(SketchPlugin_ConstraintCoincidence::ID());
800   fillAttribute(thePoint1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
801   fillAttribute(thePoint2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
802   aFeature->execute();
803   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
804 }
805
806 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setCollinear(
807     const ModelHighAPI_RefAttr & theLine1,
808     const ModelHighAPI_RefAttr & theLine2)
809 {
810   std::shared_ptr<ModelAPI_Feature> aFeature =
811       compositeFeature()->addFeature(SketchPlugin_ConstraintCollinear::ID());
812   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
813   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
814   aFeature->execute();
815   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
816 }
817
818 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setDistance(
819     const ModelHighAPI_RefAttr & thePoint,
820     const ModelHighAPI_RefAttr & thePointOrLine,
821     const ModelHighAPI_Double & theValue,
822     bool isSigned)
823 {
824   std::shared_ptr<ModelAPI_Feature> aFeature =
825       compositeFeature()->addFeature(SketchPlugin_ConstraintDistance::ID());
826   fillAttribute(thePoint, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
827   fillAttribute(thePointOrLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
828   fillAttribute(theValue, aFeature->real(SketchPlugin_Constraint::VALUE()));
829   fillAttribute(isSigned, aFeature->boolean(SketchPlugin_ConstraintDistance::SIGNED()));
830   aFeature->execute();
831   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
832 }
833
834 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setSignedDistance(
835     const ModelHighAPI_RefAttr & thePoint,
836     const ModelHighAPI_RefAttr & thePointOrLine,
837     const ModelHighAPI_Double & theValue)
838 {
839   return setDistance(thePoint, thePointOrLine, theValue, true);
840 }
841
842 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setUnsignedDistance(
843     const ModelHighAPI_RefAttr & thePoint,
844     const ModelHighAPI_RefAttr & thePointOrLine,
845     const ModelHighAPI_Double & theValue)
846 {
847   return setDistance(thePoint, thePointOrLine, theValue, false);
848 }
849
850 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setHorizontalDistance(
851     const ModelHighAPI_RefAttr & thePoint1,
852     const ModelHighAPI_RefAttr & thePoint2,
853     const ModelHighAPI_Double & theValue)
854 {
855   std::shared_ptr<ModelAPI_Feature> aFeature =
856       compositeFeature()->addFeature(SketchPlugin_ConstraintDistanceHorizontal::ID());
857   fillAttribute(thePoint1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
858   fillAttribute(thePoint2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
859   fillAttribute(theValue,
860       aFeature->real(SketchPlugin_ConstraintDistanceAlongDir::DISTANCE_VALUE_ID()));
861   aFeature->execute();
862   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
863 }
864
865 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setVerticalDistance(
866     const ModelHighAPI_RefAttr & thePoint1,
867     const ModelHighAPI_RefAttr & thePoint2,
868     const ModelHighAPI_Double & theValue)
869 {
870   std::shared_ptr<ModelAPI_Feature> aFeature =
871       compositeFeature()->addFeature(SketchPlugin_ConstraintDistanceVertical::ID());
872   fillAttribute(thePoint1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
873   fillAttribute(thePoint2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
874   fillAttribute(theValue,
875       aFeature->real(SketchPlugin_ConstraintDistanceAlongDir::DISTANCE_VALUE_ID()));
876   aFeature->execute();
877   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
878 }
879
880 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setEqual(
881     const ModelHighAPI_RefAttr & theObject1,
882     const ModelHighAPI_RefAttr & theObject2)
883 {
884   std::shared_ptr<ModelAPI_Feature> aFeature =
885       compositeFeature()->addFeature(SketchPlugin_ConstraintEqual::ID());
886   fillAttribute(theObject1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
887   fillAttribute(theObject2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
888   aFeature->execute();
889   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
890 }
891
892 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setFillet(
893     const ModelHighAPI_RefAttr & thePoint)
894 {
895   std::shared_ptr<ModelAPI_Feature> aFeature =
896       compositeFeature()->addFeature(SketchPlugin_Fillet::ID());
897   fillAttribute(thePoint, aFeature->data()->refattr(SketchPlugin_Fillet::FILLET_POINT_ID()));
898   apply(); // finish operation to remove Fillet feature correcly
899   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
900 }
901
902 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setFilletWithRadius(
903     const ModelHighAPI_RefAttr & thePoint,
904     const ModelHighAPI_Double & theRadius)
905 {
906   CompositeFeaturePtr aSketch = compositeFeature();
907   int aNbSubs = aSketch->numberOfSubs();
908
909   // create fillet
910   InterfacePtr aFilletFeature = setFillet(thePoint);
911
912   // set radius for just created arc
913   FeaturePtr anArc = aSketch->subFeature(aNbSubs - 1);
914   if (anArc->getKind() == SketchPlugin_Arc::ID())
915     setRadius(ModelHighAPI_RefAttr(ObjectPtr(anArc->lastResult())), ModelHighAPI_Double(theRadius));
916
917   return aFilletFeature;
918 }
919
920 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setFixed(
921     const ModelHighAPI_RefAttr & theObject)
922 {
923   std::shared_ptr<ModelAPI_Feature> aFeature =
924       compositeFeature()->addFeature(SketchPlugin_ConstraintRigid::ID());
925   fillAttribute(theObject, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
926   aFeature->execute();
927   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
928 }
929
930 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setHorizontal(
931     const ModelHighAPI_RefAttr & theLine)
932 {
933   std::shared_ptr<ModelAPI_Feature> aFeature =
934       compositeFeature()->addFeature(SketchPlugin_ConstraintHorizontal::ID());
935   fillAttribute(theLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
936   aFeature->execute();
937   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
938 }
939
940 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setLength(
941     const ModelHighAPI_RefAttr & theLine,
942     const ModelHighAPI_Double & theValue)
943 {
944   std::shared_ptr<ModelAPI_Feature> aFeature =
945       compositeFeature()->addFeature(SketchPlugin_ConstraintLength::ID());
946   fillAttribute(theLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
947   fillAttribute(theValue, aFeature->real(SketchPlugin_Constraint::VALUE()));
948   aFeature->execute();
949   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
950 }
951
952 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setMiddlePoint(
953     const ModelHighAPI_RefAttr & thePoint,
954     const ModelHighAPI_RefAttr & theLine)
955 {
956   std::shared_ptr<ModelAPI_Feature> aFeature =
957       compositeFeature()->addFeature(SketchPlugin_ConstraintMiddle::ID());
958   fillAttribute(thePoint, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
959   fillAttribute(theLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
960   aFeature->execute();
961   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
962 }
963
964 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setParallel(
965     const ModelHighAPI_RefAttr & theLine1,
966     const ModelHighAPI_RefAttr & theLine2)
967 {
968   std::shared_ptr<ModelAPI_Feature> aFeature =
969       compositeFeature()->addFeature(SketchPlugin_ConstraintParallel::ID());
970   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
971   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
972   aFeature->execute();
973   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
974 }
975
976 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setPerpendicular(
977     const ModelHighAPI_RefAttr & theLine1,
978     const ModelHighAPI_RefAttr & theLine2)
979 {
980   std::shared_ptr<ModelAPI_Feature> aFeature =
981       compositeFeature()->addFeature(SketchPlugin_ConstraintPerpendicular::ID());
982   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
983   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
984   aFeature->execute();
985   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
986 }
987
988 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setRadius(
989     const ModelHighAPI_RefAttr & theCircleOrArc,
990     const ModelHighAPI_Double & theValue)
991 {
992   std::shared_ptr<ModelAPI_Feature> aFeature =
993       compositeFeature()->addFeature(SketchPlugin_ConstraintRadius::ID());
994   fillAttribute(theCircleOrArc, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
995   fillAttribute(theValue, aFeature->real(SketchPlugin_Constraint::VALUE()));
996   aFeature->execute();
997   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
998 }
999
1000 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setTangent(
1001     const ModelHighAPI_RefAttr & theLine,
1002     const ModelHighAPI_RefAttr & theCircle)
1003 {
1004   std::shared_ptr<ModelAPI_Feature> aFeature =
1005       compositeFeature()->addFeature(SketchPlugin_ConstraintTangent::ID());
1006   fillAttribute(theLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
1007   fillAttribute(theCircle, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
1008   aFeature->execute();
1009   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1010 }
1011
1012 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setVertical(
1013     const ModelHighAPI_RefAttr & theLine)
1014 {
1015   std::shared_ptr<ModelAPI_Feature> aFeature =
1016       compositeFeature()->addFeature(SketchPlugin_ConstraintVertical::ID());
1017   fillAttribute(theLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
1018   aFeature->execute();
1019   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
1020 }
1021
1022 //--------------------------------------------------------------------------------------
1023
1024 static std::shared_ptr<GeomAPI_Pnt2d> pointCoordinates(const AttributePtr& thePoint)
1025 {
1026   AttributePoint2DPtr aPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(thePoint);
1027   return aPnt ? aPnt->pnt() : std::shared_ptr<GeomAPI_Pnt2d>();
1028 }
1029
1030 static std::shared_ptr<GeomAPI_Pnt2d> middlePointOnLine(const FeaturePtr& theFeature)
1031 {
1032   AttributePoint2DPtr aStartAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
1033       theFeature->attribute(SketchPlugin_Line::START_ID()));
1034   AttributePoint2DPtr aEndAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
1035       theFeature->attribute(SketchPlugin_Line::END_ID()));
1036
1037   if (!aStartAttr || !aEndAttr)
1038     return std::shared_ptr<GeomAPI_Pnt2d>();
1039
1040   std::shared_ptr<GeomAPI_XY> aStartPoint = aStartAttr->pnt()->xy();
1041   std::shared_ptr<GeomAPI_XY> aEndPoint = aEndAttr->pnt()->xy();
1042   return std::shared_ptr<GeomAPI_Pnt2d>(
1043       new GeomAPI_Pnt2d(aStartPoint->added(aEndPoint)->multiplied(0.5)));
1044 }
1045
1046 static std::shared_ptr<GeomAPI_Pnt2d> pointOnCircle(const FeaturePtr& theFeature)
1047 {
1048   AttributePoint2DPtr aCenter = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
1049       theFeature->attribute(SketchPlugin_Circle::CENTER_ID()));
1050   AttributeDoublePtr aRadius = theFeature->real(SketchPlugin_Circle::RADIUS_ID());
1051
1052   if (!aCenter || !aRadius)
1053     return std::shared_ptr<GeomAPI_Pnt2d>();
1054
1055   return std::shared_ptr<GeomAPI_Pnt2d>(
1056       new GeomAPI_Pnt2d(aCenter->x() + aRadius->value(), aCenter->y()));
1057 }
1058
1059 static std::shared_ptr<GeomAPI_Pnt2d> middlePointOnArc(const FeaturePtr& theFeature)
1060 {
1061   static const double PI = 3.141592653589793238463;
1062
1063   AttributePoint2DPtr aCenterAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
1064       theFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
1065   AttributePoint2DPtr aStartAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
1066       theFeature->attribute(SketchPlugin_Arc::START_ID()));
1067   AttributePoint2DPtr aEndAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
1068       theFeature->attribute(SketchPlugin_Arc::END_ID()));
1069
1070   if (!aCenterAttr || !aStartAttr || !aEndAttr)
1071     return std::shared_ptr<GeomAPI_Pnt2d>();
1072
1073   std::shared_ptr<GeomAPI_Dir2d> aStartDir(new GeomAPI_Dir2d(
1074       aStartAttr->x() - aCenterAttr->x(), aStartAttr->y() - aCenterAttr->y()));
1075   std::shared_ptr<GeomAPI_Dir2d> aEndDir(new GeomAPI_Dir2d(
1076       aEndAttr->x() - aCenterAttr->x(), aEndAttr->y() - aCenterAttr->y()));
1077
1078   double anAngle = aStartDir->angle(aEndDir);
1079   bool isReversed = theFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->value();
1080   if (isReversed && anAngle > 0.)
1081     anAngle -= 2.0 * PI;
1082   else if (!isReversed && anAngle <= 0.)
1083     anAngle += 2.0 * PI;
1084
1085   double cosA = cos(anAngle);
1086   double sinA = sin(anAngle);
1087
1088   // rotate start dir to find middle point on arc
1089   double aRadius = aStartAttr->pnt()->distance(aCenterAttr->pnt());
1090   double x = aCenterAttr->x() + aRadius * (aStartDir->x() * cosA - aStartDir->y() * sinA);
1091   double y = aCenterAttr->y() + aRadius * (aStartDir->x() * sinA + aStartDir->y() * cosA);
1092
1093   return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(x, y));
1094 }
1095
1096 static std::shared_ptr<GeomAPI_Pnt2d> middlePoint(const ObjectPtr& theObject)
1097 {
1098   std::shared_ptr<GeomAPI_Pnt2d> aMiddlePoint;
1099   FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
1100   if (aFeature) {
1101     // move only features of the following types
1102     const std::string& aFeatureKind = aFeature->getKind();
1103     if (aFeatureKind == SketchPlugin_Point::ID())
1104       aMiddlePoint = pointCoordinates(aFeature->attribute(SketchPlugin_Point::COORD_ID()));
1105     else if (aFeatureKind == SketchPlugin_Line::ID())
1106       aMiddlePoint = middlePointOnLine(aFeature);
1107     else if (aFeatureKind == SketchPlugin_Circle::ID())
1108       aMiddlePoint = pointOnCircle(aFeature);
1109     else if (aFeatureKind == SketchPlugin_Arc::ID())
1110       aMiddlePoint = middlePointOnArc(aFeature);
1111   }
1112   return aMiddlePoint;
1113 }
1114
1115 void SketchAPI_Sketch::move(const ModelHighAPI_RefAttr& theMovedEntity,
1116                             const std::shared_ptr<GeomAPI_Pnt2d>& theTargetPoint)
1117 {
1118   std::shared_ptr<ModelAPI_ObjectMovedMessage> aMessage(new ModelAPI_ObjectMovedMessage);
1119   theMovedEntity.fillMessage(aMessage);
1120
1121   std::shared_ptr<GeomAPI_Pnt2d> anOriginalPosition;
1122   if (aMessage->movedAttribute())
1123     anOriginalPosition = pointCoordinates(aMessage->movedAttribute());
1124   else
1125     anOriginalPosition = middlePoint(aMessage->movedObject());
1126
1127   if (!anOriginalPosition)
1128     return; // something has gone wrong, do not process movement
1129
1130   aMessage->setOriginalPosition(anOriginalPosition);
1131   aMessage->setCurrentPosition(theTargetPoint);
1132   Events_Loop::loop()->send(aMessage);
1133 }
1134
1135 void SketchAPI_Sketch::move(const ModelHighAPI_RefAttr& theMovedEntity,
1136                             double theTargetX, double theTargetY)
1137 {
1138   std::shared_ptr<GeomAPI_Pnt2d> aTargetPoint(new GeomAPI_Pnt2d(theTargetX, theTargetY));
1139   move(theMovedEntity, aTargetPoint);
1140 }
1141
1142 //--------------------------------------------------------------------------------------
1143
1144 std::shared_ptr<GeomAPI_Pnt2d> SketchAPI_Sketch::to2D(const std::shared_ptr<GeomAPI_Pnt>& thePoint)
1145 {
1146   FeaturePtr aBase = feature();
1147   std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
1148       aBase->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
1149   std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1150       aBase->attribute(SketchPlugin_Sketch::NORM_ID()));
1151   std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1152       aBase->attribute(SketchPlugin_Sketch::DIRX_ID()));
1153   std::shared_ptr<GeomAPI_Dir> aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
1154
1155   return thePoint->to2D(aC->pnt(), aX->dir(), aY);
1156 }
1157
1158 //--------------------------------------------------------------------------------------
1159
1160 static bool isDifferent(GeomFacePtr theFace1, GeomFacePtr theFace2)
1161 {
1162   // collect edges of the first face
1163   std::list<GeomShapePtr> anEdges1;
1164   for (GeomAPI_ShapeExplorer anExp(theFace1, GeomAPI_Shape::EDGE); anExp.more(); anExp.next())
1165     anEdges1.push_back(anExp.current());
1166   // compare edges of faces
1167   for (GeomAPI_ShapeExplorer anExp(theFace2, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
1168     GeomShapePtr aCurrent = anExp.current();
1169     bool isFound = false;
1170     std::list<GeomShapePtr>::iterator anIt1 = anEdges1.begin();
1171     for (; anIt1 != anEdges1.end(); ++anIt1)
1172       if (aCurrent->isSameGeometry(*anIt1)) {
1173         isFound = true;
1174         anEdges1.erase(anIt1);
1175         break;
1176       }
1177     if (!isFound)
1178       return true;
1179   }
1180   return !anEdges1.empty();
1181 }
1182
1183 static bool isCustomFacesOrder(CompositeFeaturePtr theSketch)
1184 {
1185   ResultConstructionPtr aSketchResult =
1186       std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(theSketch->lastResult());
1187   if (!aSketchResult)
1188     return false;
1189
1190   std::shared_ptr<GeomAPI_PlanarEdges> aWires =
1191       std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aSketchResult->shape());
1192   if (!aWires)
1193     return false;
1194
1195   // collect faces constructed by SketchBuilder algorithm
1196   GeomAlgoAPI_SketchBuilder aSketchBuilder(aWires->origin(), aWires->dirX(),
1197                                            aWires->norm(), aWires);
1198   const ListOfShape& aFaces = aSketchBuilder.faces();
1199
1200   // compare faces stored in sketch with faces generated by SketchBuilder
1201   int aNbSketchFaces = aSketchResult->facesNum();
1202   int aFaceIndex = 0;
1203   for (ListOfShape::const_iterator aFIt = aFaces.begin();
1204        aFIt != aFaces.end() && aFaceIndex < aNbSketchFaces;
1205        ++aFIt, ++aFaceIndex) {
1206     GeomFacePtr aSketchFace = aSketchResult->face(aFaceIndex);
1207     GeomFacePtr aCurFace = (*aFIt)->face();
1208     if (isDifferent(aSketchFace, aCurFace))
1209       return true;
1210   }
1211   return false;
1212 }
1213
1214 static void edgesOfSketchFaces(CompositeFeaturePtr theSketch,
1215                                std::list<std::list<ResultPtr> >& theEdges)
1216 {
1217   ResultConstructionPtr aSketchResult =
1218       std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(theSketch->lastResult());
1219   if (!aSketchResult)
1220     return;
1221
1222   // collect curves of the sketch
1223   std::map<GeomCurvePtr, ResultPtr, GeomAPI_Curve::Comparator> aCurves;
1224   int aSubNum = theSketch->numberOfSubs();
1225   for (int a = 0; a < aSubNum; ++a) {
1226     FeaturePtr aSub = theSketch->subFeature(a);
1227     const std::list<ResultPtr>& aResults = aSub->results();
1228     std::list<ResultPtr>::const_iterator aRes = aResults.cbegin();
1229     for (; aRes != aResults.cend(); aRes++) {
1230       GeomShapePtr aCurShape = (*aRes)->shape();
1231       if (aCurShape && aCurShape->isEdge())
1232         aCurves[untrimmedCurve(aCurShape)] = *aRes;
1233     }
1234   }
1235
1236   // convert each face to the list of results of its edges
1237   int aFacesNum = aSketchResult->facesNum();
1238   for (int a = 0; a < aFacesNum; ++a) {
1239     theEdges.push_back(std::list<ResultPtr>());
1240     std::list<ResultPtr>& aCurEdges = theEdges.back();
1241
1242     GeomFacePtr aFace = aSketchResult->face(a);
1243     for (GeomAPI_ShapeExplorer anExp(aFace, GeomAPI_Shape::EDGE);
1244          anExp.more(); anExp.next()) {
1245       GeomCurvePtr aCurrent = untrimmedCurve(anExp.current());
1246       aCurEdges.push_back(aCurves[aCurrent]);
1247     }
1248   }
1249 }
1250
1251 //--------------------------------------------------------------------------------------
1252
1253 void SketchAPI_Sketch::dump(ModelHighAPI_Dumper& theDumper) const
1254 {
1255   FeaturePtr aBase = feature();
1256   const std::string& aDocName = theDumper.name(aBase->document());
1257
1258   AttributeSelectionPtr anExternal = aBase->selection(SketchPlugin_SketchEntity::EXTERNAL_ID());
1259   if (anExternal->value()) {
1260     theDumper << aBase << " = model.addSketch(" << aDocName <<
1261       ", " << anExternal << ")" << std::endl;
1262   } else {
1263     // Sketch is base on a plane.
1264     std::shared_ptr<GeomAPI_Pnt> anOrigin = std::dynamic_pointer_cast<GeomDataAPI_Point>(
1265         aBase->attribute(SketchPlugin_Sketch::ORIGIN_ID()))->pnt();
1266     std::shared_ptr<GeomAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1267         aBase->attribute(SketchPlugin_Sketch::NORM_ID()))->dir();
1268     std::shared_ptr<GeomAPI_Dir> aDirX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1269         aBase->attribute(SketchPlugin_Sketch::DIRX_ID()))->dir();
1270
1271     // Check the plane is coordinate plane
1272     std::string aPlaneName = defaultPlane(anOrigin, aNormal, aDirX);
1273     if(anExternal->context()) { // checking for selected planes
1274       if (!aPlaneName.empty()
1275           && anExternal->context()->data()
1276           && anExternal->context()->data()->name() == aPlaneName) {
1277         // dump sketch based on coordinate plane
1278         theDumper << aBase << " = model.addSketch(" << aDocName
1279                   << ", model.standardPlane(\"" << aPlaneName << "\"))" << std::endl;
1280       } else { // some other plane
1281         theDumper << aBase << " = model.addSketch(" << aDocName <<
1282           ", " << anExternal<< ")" << std::endl;
1283       }
1284     } else {
1285       if (aPlaneName.empty()) {
1286         // needs import additional module
1287         theDumper.importModule("GeomAPI");
1288         // dump plane parameters
1289         const std::string& aSketchName = theDumper.name(aBase);
1290         std::string anOriginName = aSketchName + "_origin";
1291         std::string aNormalName  = aSketchName + "_norm";
1292         std::string aDirXName    = aSketchName + "_dirx";
1293         // use "\n" instead of std::endl to avoid automatic dumping sketch here
1294         // and then dumplicate dumping it in the next line
1295         theDumper << anOriginName << " = " << anOrigin << "\n"
1296                   << aNormalName  << " = " << aNormal  << "\n"
1297                   << aDirXName    << " = " << aDirX    << "\n";
1298         // dump sketch based on arbitrary plane
1299         theDumper << aBase << " = model.addSketch(" << aDocName << ", GeomAPI_Ax3("
1300                   << anOriginName << ", " << aDirXName << ", " << aNormalName << "))" << std::endl;
1301       } else {
1302         // dump sketch based on coordinate plane
1303         theDumper << aBase << " = model.addSketch(" << aDocName
1304                   << ", model.defaultPlane(\"" << aPlaneName << "\"))" << std::endl;
1305       }
1306     }
1307   }
1308
1309   // dump sketch's subfeatures
1310   CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aBase);
1311   theDumper.processSubs(aCompFeat, true);
1312
1313   // if face order differs to the order generated by SketchBuilder,
1314   // dump the list of faces for correct execution of the script
1315   if (isCustomFacesOrder(aCompFeat)) {
1316     std::list<std::list<ResultPtr> > aFaces;
1317     edgesOfSketchFaces(aCompFeat, aFaces);
1318
1319     const std::string& aSketchName = theDumper.name(aBase);
1320     std::string aMethodName(".changeFacesOrder");
1321     std::string aSpaceShift(aSketchName.size() + aMethodName.size(), ' ');
1322
1323     theDumper << aSketchName << aMethodName << "([";
1324     for (std::list<std::list<ResultPtr> >::iterator aFIt = aFaces.begin();
1325          aFIt != aFaces.end(); ++aFIt) {
1326       if (aFIt != aFaces.begin())
1327         theDumper << ",\n" << aSpaceShift << "  ";
1328       theDumper << *aFIt;
1329     }
1330     theDumper << "\n" << aSpaceShift << " ])" << std::endl;
1331   }
1332 }