Salome HOME
Merge remote-tracking branch 'remotes/origin/CHANGE_SKETCH_PLANE'
[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_MacroArc.h"
57 #include "SketchAPI_Circle.h"
58 #include "SketchAPI_IntersectionPoint.h"
59 #include "SketchAPI_Line.h"
60 #include "SketchAPI_MacroCircle.h"
61 #include "SketchAPI_Mirror.h"
62 #include "SketchAPI_Point.h"
63 #include "SketchAPI_Projection.h"
64 #include "SketchAPI_Rectangle.h"
65 #include "SketchAPI_Rotation.h"
66 #include "SketchAPI_Translation.h"
67 //--------------------------------------------------------------------------------------
68 #include <GeomAPI_Dir2d.h>
69 #include <GeomAPI_XY.h>
70 #include <cmath>
71 //--------------------------------------------------------------------------------------
72 SketchAPI_Sketch::SketchAPI_Sketch(
73     const std::shared_ptr<ModelAPI_Feature> & theFeature)
74 : ModelHighAPI_Interface(theFeature)
75 {
76   initialize();
77 }
78
79 SketchAPI_Sketch::SketchAPI_Sketch(
80     const std::shared_ptr<ModelAPI_Feature> & theFeature,
81     const std::shared_ptr<GeomAPI_Ax3> & thePlane)
82 : ModelHighAPI_Interface(theFeature)
83 {
84   if (initialize()) {
85     setPlane(thePlane);
86   }
87 }
88
89 SketchAPI_Sketch::SketchAPI_Sketch(
90     const std::shared_ptr<ModelAPI_Feature> & theFeature,
91     const ModelHighAPI_Selection & theExternal)
92 : ModelHighAPI_Interface(theFeature)
93 {
94   if (initialize()) {
95     setExternal(theExternal);
96   }
97 }
98
99 SketchAPI_Sketch::SketchAPI_Sketch(
100     const std::shared_ptr<ModelAPI_Feature> & theFeature,
101     std::shared_ptr<ModelAPI_Object> thePlaneObject)
102 : ModelHighAPI_Interface(theFeature)
103 {
104   if (initialize()) {
105     setExternal(thePlaneObject);
106   }
107 }
108
109 SketchAPI_Sketch::~SketchAPI_Sketch()
110 {
111
112 }
113
114 //--------------------------------------------------------------------------------------
115 std::shared_ptr<ModelAPI_CompositeFeature> SketchAPI_Sketch::compositeFeature() const
116 {
117   return std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(feature());
118 }
119
120 //--------------------------------------------------------------------------------------
121 void SketchAPI_Sketch::setPlane(const std::shared_ptr<GeomAPI_Ax3> & thePlane)
122 {
123   fillAttribute(thePlane->origin(), myorigin);
124   fillAttribute(thePlane->dirX(), mydirX);
125   fillAttribute(thePlane->normal(), mynormal);
126
127   execute();
128 }
129
130 void SketchAPI_Sketch::setPlane(const ModelHighAPI_Selection & thePlane,
131                                 bool theRemoveExternalDependency)
132 {
133   FeaturePtr aSketch = feature();
134
135   DocumentPtr aDoc = aSketch->document();
136   bool useVisible = false;
137   FeaturePtr aCurFeatureBefore = aDoc->currentFeature(useVisible);
138   aDoc->setCurrentFeature(aSketch, useVisible);
139
140   if (theRemoveExternalDependency)
141     aSketch->customAction(SketchPlugin_Sketch::ACTION_REMOVE_EXTERNAL());
142
143   setExternal(thePlane);
144
145   aDoc->setCurrentFeature(aCurFeatureBefore, useVisible);
146 }
147
148 //--------------------------------------------------------------------------------------
149 void SketchAPI_Sketch::setExternal(const ModelHighAPI_Selection & theExternal)
150 {
151   fillAttribute(theExternal, myexternal);
152
153   execute();
154 }
155
156 void SketchAPI_Sketch::setExternal(std::shared_ptr<ModelAPI_Object> thePlaneObject)
157 {
158   ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(thePlaneObject);
159   ModelHighAPI_Selection aSel(aRes);
160   setExternal(aSel);
161 }
162
163 //--------------------------------------------------------------------------------------
164 void SketchAPI_Sketch::setValue(
165     const std::shared_ptr<ModelHighAPI_Interface> & theConstraint,
166     const ModelHighAPI_Double & theValue)
167 {
168   fillAttribute(theValue, theConstraint->feature()->real(SketchPlugin_Constraint::VALUE()));
169
170 //  theConstraint->execute();
171 }
172
173 //--------------------------------------------------------------------------------------
174 std::list<ModelHighAPI_Selection> SketchAPI_Sketch::selectFace() const
175 {
176   const_cast<SketchAPI_Sketch*>(this)->execute();
177
178   std::list<ModelHighAPI_Selection> aSelectionList;
179
180   ResultConstructionPtr aResultConstruction =
181       std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(feature()->firstResult());
182   if (aResultConstruction.get() == NULL)
183     return aSelectionList;
184
185   for (int anIndex = 0; anIndex < aResultConstruction->facesNum(); ++anIndex) {
186     aSelectionList.push_back(
187         ModelHighAPI_Selection(aResultConstruction,
188                                aResultConstruction->face(anIndex)));
189   }
190
191   return aSelectionList;
192 }
193
194 //--------------------------------------------------------------------------------------
195 SketchPtr addSketch(const std::shared_ptr<ModelAPI_Document> & thePart,
196                     const std::shared_ptr<GeomAPI_Ax3> & thePlane)
197 {
198   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(SketchAPI_Sketch::ID());
199   return SketchPtr(new SketchAPI_Sketch(aFeature, thePlane));
200 }
201
202 SketchPtr addSketch(const std::shared_ptr<ModelAPI_Document> & thePart,
203                     const ModelHighAPI_Selection & theExternal)
204 {
205   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(SketchAPI_Sketch::ID());
206   return SketchPtr(new SketchAPI_Sketch(aFeature, theExternal));
207 }
208
209 SketchPtr addSketch(const std::shared_ptr<ModelAPI_Document> & thePart,
210                     const std::string & theExternalName)
211 {
212   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(SketchAPI_Sketch::ID());
213   return SketchPtr(
214     new SketchAPI_Sketch(aFeature, ModelHighAPI_Selection("FACE", theExternalName)));
215 }
216
217 SketchPtr addSketch(const std::shared_ptr<ModelAPI_Document> & thePart,
218                     std::shared_ptr<ModelAPI_Object> thePlaneObject)
219 {
220   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(SketchAPI_Sketch::ID());
221   return SketchPtr(new SketchAPI_Sketch(aFeature, thePlaneObject));
222 }
223
224
225 //--------------------------------------------------------------------------------------
226 std::shared_ptr<SketchAPI_Point> SketchAPI_Sketch::addPoint(
227     double theX, double theY)
228 {
229   std::shared_ptr<ModelAPI_Feature> aFeature =
230     compositeFeature()->addFeature(SketchPlugin_Point::ID());
231   return PointPtr(new SketchAPI_Point(aFeature, theX, theY));
232 }
233 std::shared_ptr<SketchAPI_Point> SketchAPI_Sketch::addPoint(
234     const std::shared_ptr<GeomAPI_Pnt2d> & thePoint)
235 {
236   std::shared_ptr<ModelAPI_Feature> aFeature =
237     compositeFeature()->addFeature(SketchPlugin_Point::ID());
238   return PointPtr(new SketchAPI_Point(aFeature, thePoint));
239 }
240 std::shared_ptr<SketchAPI_Point>
241   SketchAPI_Sketch::addPoint(const ModelHighAPI_Selection & theExternal)
242 {
243   std::shared_ptr<ModelAPI_Feature> aFeature =
244     compositeFeature()->addFeature(SketchPlugin_Point::ID());
245   return PointPtr(new SketchAPI_Point(aFeature, theExternal));
246 }
247 std::shared_ptr<SketchAPI_Point> SketchAPI_Sketch::addPoint(const std::string & theExternalName)
248 {
249   std::shared_ptr<ModelAPI_Feature> aFeature =
250     compositeFeature()->addFeature(SketchPlugin_Point::ID());
251   return PointPtr(new SketchAPI_Point(aFeature, theExternalName));
252 }
253
254 //--------------------------------------------------------------------------------------
255 std::shared_ptr<SketchAPI_IntersectionPoint> SketchAPI_Sketch::addIntersectionPoint(
256     const ModelHighAPI_Selection & theExternal,
257     bool theKeepResult)
258 {
259   std::shared_ptr<ModelAPI_Feature> aFeature =
260     compositeFeature()->addFeature(SketchPlugin_IntersectionPoint::ID());
261   IntersectionPointPtr anIntersection(new SketchAPI_IntersectionPoint(aFeature, theExternal));
262   anIntersection->setIncludeToResult(theKeepResult);
263   return anIntersection;
264 }
265 std::shared_ptr<SketchAPI_IntersectionPoint> SketchAPI_Sketch::addIntersectionPoint(
266     const std::string & theExternalName,
267     bool theKeepResult)
268 {
269   std::shared_ptr<ModelAPI_Feature> aFeature =
270     compositeFeature()->addFeature(SketchPlugin_IntersectionPoint::ID());
271   IntersectionPointPtr anIntersection(new SketchAPI_IntersectionPoint(aFeature, theExternalName));
272   anIntersection->setIncludeToResult(theKeepResult);
273   return anIntersection;
274 }
275
276 //--------------------------------------------------------------------------------------
277 std::shared_ptr<SketchAPI_Line> SketchAPI_Sketch::addLine(double theX1, double theY1,
278                                                           double theX2, double theY2)
279 {
280   std::shared_ptr<ModelAPI_Feature> aFeature =
281     compositeFeature()->addFeature(SketchPlugin_Line::ID());
282   return LinePtr(new SketchAPI_Line(aFeature, theX1, theY1, theX2, theY2));
283 }
284 std::shared_ptr<SketchAPI_Line> SketchAPI_Sketch::addLine(
285     const std::shared_ptr<GeomAPI_Pnt2d> & theStartPoint,
286     const std::shared_ptr<GeomAPI_Pnt2d> & theEndPoint)
287 {
288   std::shared_ptr<ModelAPI_Feature> aFeature =
289     compositeFeature()->addFeature(SketchPlugin_Line::ID());
290   return LinePtr(new SketchAPI_Line(aFeature, theStartPoint, theEndPoint));
291 }
292 std::shared_ptr<SketchAPI_Line>
293   SketchAPI_Sketch::addLine(const ModelHighAPI_Selection & theExternal)
294 {
295   std::shared_ptr<ModelAPI_Feature> aFeature =
296     compositeFeature()->addFeature(SketchPlugin_Line::ID());
297   return LinePtr(new SketchAPI_Line(aFeature, theExternal));
298 }
299 std::shared_ptr<SketchAPI_Line> SketchAPI_Sketch::addLine(const std::string & theExternalName)
300 {
301   std::shared_ptr<ModelAPI_Feature> aFeature =
302     compositeFeature()->addFeature(SketchPlugin_Line::ID());
303   return LinePtr(new SketchAPI_Line(aFeature, theExternalName));
304 }
305
306 //--------------------------------------------------------------------------------------
307 std::shared_ptr<SketchAPI_Rectangle> SketchAPI_Sketch::addRectangle(double theX1, double theY1,
308                                                                     double theX2, double theY2)
309 {
310   std::shared_ptr<ModelAPI_Feature> aFeature =
311     compositeFeature()->addFeature(SketchAPI_Rectangle::ID());
312   return RectanglePtr(new SketchAPI_Rectangle(aFeature, theX1, theY1, theX2, theY2));
313 }
314 std::shared_ptr<SketchAPI_Rectangle> SketchAPI_Sketch::addRectangle(
315     const std::shared_ptr<GeomAPI_Pnt2d> & theStartPoint,
316     const std::shared_ptr<GeomAPI_Pnt2d> & theEndPoint)
317 {
318   std::shared_ptr<ModelAPI_Feature> aFeature =
319     compositeFeature()->addFeature(SketchAPI_Rectangle::ID());
320   return RectanglePtr(new SketchAPI_Rectangle(aFeature, theStartPoint, theEndPoint));
321 }
322
323 //--------------------------------------------------------------------------------------
324 std::shared_ptr<SketchAPI_Circle> SketchAPI_Sketch::addCircle(double theCenterX,
325                                                               double theCenterY,
326                                                               double theRadius)
327 {
328   std::shared_ptr<ModelAPI_Feature> aFeature =
329     compositeFeature()->addFeature(SketchPlugin_Circle::ID());
330   return CirclePtr(new SketchAPI_Circle(aFeature, theCenterX, theCenterY, theRadius));
331 }
332
333 std::shared_ptr<SketchAPI_Circle> SketchAPI_Sketch::addCircle(
334                                     const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
335                                     double theRadius)
336 {
337   std::shared_ptr<ModelAPI_Feature> aFeature =
338     compositeFeature()->addFeature(SketchPlugin_Circle::ID());
339   return CirclePtr(new SketchAPI_Circle(aFeature, theCenter, theRadius));
340 }
341
342 std::shared_ptr<SketchAPI_MacroCircle> SketchAPI_Sketch::addCircle(double theCenterX,
343                                                                    double theCenterY,
344                                                                    double thePassedX,
345                                                                    double thePassedY)
346 {
347   std::shared_ptr<ModelAPI_Feature> aFeature =
348     compositeFeature()->addFeature(SketchPlugin_MacroCircle::ID());
349   return MacroCirclePtr(new SketchAPI_MacroCircle(aFeature, theCenterX, theCenterY,
350                                                             thePassedX, thePassedY));
351 }
352
353 std::shared_ptr<SketchAPI_MacroCircle> SketchAPI_Sketch::addCircle(
354     const std::shared_ptr<GeomAPI_Pnt2d>& theCenterPoint,
355     const std::shared_ptr<GeomAPI_Pnt2d>& thePassedPoint)
356 {
357   std::shared_ptr<ModelAPI_Feature> aFeature =
358     compositeFeature()->addFeature(SketchPlugin_MacroCircle::ID());
359   return MacroCirclePtr(new SketchAPI_MacroCircle(aFeature, theCenterPoint, thePassedPoint));
360 }
361
362 std::shared_ptr<SketchAPI_MacroCircle> SketchAPI_Sketch::addCircle(double theX1, double theY1,
363                                                                    double theX2, double theY2,
364                                                                    double theX3, double theY3)
365 {
366   std::shared_ptr<ModelAPI_Feature> aFeature =
367     compositeFeature()->addFeature(SketchPlugin_MacroCircle::ID());
368   return MacroCirclePtr(new SketchAPI_MacroCircle(aFeature, theX1, theY1,
369                                                             theX2, theY2,
370                                                             theX3, theY3));
371 }
372
373 std::shared_ptr<SketchAPI_MacroCircle> SketchAPI_Sketch::addCircle(
374     const std::shared_ptr<GeomAPI_Pnt2d>& thePoint1,
375     const std::shared_ptr<GeomAPI_Pnt2d>& thePoint2,
376     const std::shared_ptr<GeomAPI_Pnt2d>& thePoint3)
377 {
378   std::shared_ptr<ModelAPI_Feature> aFeature =
379     compositeFeature()->addFeature(SketchPlugin_MacroCircle::ID());
380   return MacroCirclePtr(new SketchAPI_MacroCircle(aFeature, thePoint1, thePoint2, thePoint3));
381 }
382
383 std::shared_ptr<SketchAPI_Circle>
384   SketchAPI_Sketch::addCircle(const ModelHighAPI_Selection & theExternal)
385 {
386   std::shared_ptr<ModelAPI_Feature> aFeature =
387     compositeFeature()->addFeature(SketchPlugin_Circle::ID());
388   return CirclePtr(new SketchAPI_Circle(aFeature, theExternal));
389 }
390
391 std::shared_ptr<SketchAPI_Circle> SketchAPI_Sketch::addCircle(const std::string & theExternalName)
392 {
393   // TODO(spo): Add constraint SketchConstraintRigid like in PythonAPI. Is it necessary?
394   std::shared_ptr<ModelAPI_Feature> aFeature =
395     compositeFeature()->addFeature(SketchPlugin_Circle::ID());
396   return CirclePtr(new SketchAPI_Circle(aFeature, theExternalName));
397 }
398
399 //--------------------------------------------------------------------------------------
400 std::shared_ptr<SketchAPI_Arc> SketchAPI_Sketch::addArc(double theCenterX, double theCenterY,
401                                                         double theStartX, double theStartY,
402                                                         double theEndX, double theEndY,
403                                                         bool theInversed)
404 {
405   std::shared_ptr<ModelAPI_Feature> aFeature =
406     compositeFeature()->addFeature(SketchPlugin_Arc::ID());
407   return ArcPtr(new SketchAPI_Arc(aFeature,
408                                   theCenterX, theCenterY,
409                                   theStartX, theStartY,
410                                   theEndX, theEndY,
411                                   theInversed));
412 }
413
414 std::shared_ptr<SketchAPI_Arc> SketchAPI_Sketch::addArc(
415                                               const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
416                                               const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
417                                               const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
418                                               bool theInversed)
419 {
420   std::shared_ptr<ModelAPI_Feature> aFeature =
421     compositeFeature()->addFeature(SketchPlugin_Arc::ID());
422   return ArcPtr(new SketchAPI_Arc(aFeature, theCenter, theStart, theEnd, theInversed));
423 }
424
425 std::shared_ptr<SketchAPI_MacroArc> SketchAPI_Sketch::addArc(double theStartX, double theStartY,
426                                                         double theEndX, double theEndY,
427                                                         double thePassedX, double thePassedY)
428 {
429   std::shared_ptr<ModelAPI_Feature> aFeature =
430     compositeFeature()->addFeature(SketchPlugin_MacroArc::ID());
431   return MacroArcPtr(new SketchAPI_MacroArc(aFeature,
432                                        theStartX, theStartY,
433                                        theEndX, theEndY,
434                                        thePassedX, thePassedY));
435 }
436
437 std::shared_ptr<SketchAPI_MacroArc> SketchAPI_Sketch::addArc(
438                                                 const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
439                                                 const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
440                                                 const std::shared_ptr<GeomAPI_Pnt2d>& thePassed)
441 {
442   std::shared_ptr<ModelAPI_Feature> aFeature =
443     compositeFeature()->addFeature(SketchPlugin_MacroArc::ID());
444   return MacroArcPtr(new SketchAPI_MacroArc(aFeature, theStart, theEnd, thePassed));
445 }
446
447 std::shared_ptr<SketchAPI_MacroArc> SketchAPI_Sketch::addArc(
448                                                 const ModelHighAPI_RefAttr& theTangentPoint,
449                                                 double theEndX, double theEndY,
450                                                 bool theInversed)
451 {
452   std::shared_ptr<ModelAPI_Feature> aFeature =
453     compositeFeature()->addFeature(SketchPlugin_MacroArc::ID());
454   return MacroArcPtr(new SketchAPI_MacroArc(
455     aFeature, theTangentPoint, theEndX, theEndY, theInversed));
456 }
457
458 std::shared_ptr<SketchAPI_MacroArc> SketchAPI_Sketch::addArc(
459                                               const ModelHighAPI_RefAttr& theTangentPoint,
460                                               const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
461                                               bool theInversed)
462 {
463   std::shared_ptr<ModelAPI_Feature> aFeature =
464     compositeFeature()->addFeature(SketchPlugin_MacroArc::ID());
465   return MacroArcPtr(new SketchAPI_MacroArc(aFeature, theTangentPoint, theEnd, theInversed));
466 }
467
468 std::shared_ptr<SketchAPI_Arc> SketchAPI_Sketch::addArc(const ModelHighAPI_Selection & theExternal)
469 {
470   std::shared_ptr<ModelAPI_Feature> aFeature =
471     compositeFeature()->addFeature(SketchPlugin_Arc::ID());
472   return ArcPtr(new SketchAPI_Arc(aFeature, theExternal));
473 }
474
475 std::shared_ptr<SketchAPI_Arc> SketchAPI_Sketch::addArc(const std::string & theExternalName)
476 {
477   // TODO(spo): Add constraint SketchConstraintRigid like in PythonAPI. Is it necessary?
478   std::shared_ptr<ModelAPI_Feature> aFeature =
479     compositeFeature()->addFeature(SketchPlugin_Arc::ID());
480   return ArcPtr(new SketchAPI_Arc(aFeature, theExternalName));
481 }
482
483 //--------------------------------------------------------------------------------------
484 std::shared_ptr<SketchAPI_Projection> SketchAPI_Sketch::addProjection(
485     const ModelHighAPI_Selection & theExternalFeature,
486     bool theKeepResult)
487 {
488   std::shared_ptr<ModelAPI_Feature> aFeature =
489     compositeFeature()->addFeature(SketchPlugin_Projection::ID());
490   ProjectionPtr aProjection(new SketchAPI_Projection(aFeature, theExternalFeature));
491   aProjection->setIncludeToResult(theKeepResult);
492   return aProjection;
493 }
494
495 std::shared_ptr<SketchAPI_Projection> SketchAPI_Sketch::addProjection(
496     const std::string & theExternalName,
497     bool theKeepResult)
498 {
499   std::shared_ptr<ModelAPI_Feature> aFeature =
500     compositeFeature()->addFeature(SketchPlugin_Projection::ID());
501   ProjectionPtr aProjection(new SketchAPI_Projection(aFeature, theExternalName));
502   aProjection->setIncludeToResult(theKeepResult);
503   return aProjection;
504 }
505
506 //--------------------------------------------------------------------------------------
507 std::shared_ptr<SketchAPI_Mirror> SketchAPI_Sketch::addMirror(
508     const ModelHighAPI_RefAttr & theMirrorLine,
509     const std::list<std::shared_ptr<ModelAPI_Object> > & theObjects)
510 {
511   std::shared_ptr<ModelAPI_Feature> aFeature =
512     compositeFeature()->addFeature(SketchPlugin_ConstraintMirror::ID());
513   return MirrorPtr(new SketchAPI_Mirror(aFeature, theMirrorLine, theObjects));
514 }
515
516 //--------------------------------------------------------------------------------------
517 std::shared_ptr<SketchAPI_Translation> SketchAPI_Sketch::addTranslation(
518     const std::list<std::shared_ptr<ModelAPI_Object> > & theObjects,
519     const ModelHighAPI_RefAttr & thePoint1,
520     const ModelHighAPI_RefAttr & thePoint2,
521     const ModelHighAPI_Integer & theNumberOfObjects,
522     bool theFullValue)
523 {
524   std::shared_ptr<ModelAPI_Feature> aFeature =
525     compositeFeature()->addFeature(SketchPlugin_MultiTranslation::ID());
526   return TranslationPtr(new SketchAPI_Translation(aFeature, theObjects, thePoint1,
527                                                   thePoint2, theNumberOfObjects, theFullValue));
528 }
529
530 //--------------------------------------------------------------------------------------
531 std::shared_ptr<SketchAPI_Rotation> SketchAPI_Sketch::addRotation(
532     const std::list<std::shared_ptr<ModelAPI_Object> > & theObjects,
533     const ModelHighAPI_RefAttr & theCenter,
534     const ModelHighAPI_Double & theAngle,
535     const ModelHighAPI_Integer & theNumberOfObjects,
536     bool theFullValue,
537     bool theReversed)
538 {
539   std::shared_ptr<ModelAPI_Feature> aFeature =
540     compositeFeature()->addFeature(SketchPlugin_MultiRotation::ID());
541   return RotationPtr(
542     new SketchAPI_Rotation(aFeature, theObjects, theCenter,
543                            theAngle, theNumberOfObjects, theFullValue, theReversed));
544 }
545
546 //--------------------------------------------------------------------------------------
547 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::addSplit(
548                                           const ModelHighAPI_Reference& theFeature,
549                                           const std::shared_ptr<GeomAPI_Pnt2d>& thePositionPoint)
550 {
551   std::shared_ptr<ModelAPI_Feature> aFeature =
552     compositeFeature()->addFeature(SketchPlugin_Split::ID());
553   fillAttribute(theFeature, aFeature->reference(SketchPlugin_Split::SELECTED_OBJECT()));
554
555   AttributePtr anAttribute = aFeature->attribute(SketchPlugin_Split::SELECTED_POINT());
556   if (anAttribute->attributeType() == GeomDataAPI_Point2D::typeId()) {
557     AttributePoint2DPtr aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttribute);
558     fillAttribute(thePositionPoint, aPointAttr);
559   }
560
561   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
562 }
563
564 //--------------------------------------------------------------------------------------
565 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::addTrim(
566                                         const ModelHighAPI_Reference& theFeature,
567                                         const std::shared_ptr<GeomAPI_Pnt2d>& thePositionPoint)
568 {
569   std::shared_ptr<ModelAPI_Feature> aFeature =
570     compositeFeature()->addFeature(SketchPlugin_Trim::ID());
571   fillAttribute(theFeature, aFeature->reference(SketchPlugin_Trim::SELECTED_OBJECT()));
572
573   AttributePtr anAttribute = aFeature->attribute(SketchPlugin_Trim::SELECTED_POINT());
574   if (anAttribute->attributeType() == GeomDataAPI_Point2D::typeId()) {
575     AttributePoint2DPtr aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttribute);
576     fillAttribute(thePositionPoint, aPointAttr);
577   }
578
579   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
580 }
581
582 //--------------------------------------------------------------------------------------
583 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setAngle(
584     const ModelHighAPI_RefAttr & theLine1,
585     const ModelHighAPI_RefAttr & theLine2,
586     const ModelHighAPI_Double & theValue)
587 {
588   std::shared_ptr<ModelAPI_Feature> aFeature =
589       compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID());
590   fillAttribute(SketcherPrs_Tools::ANGLE_DIRECT,
591       aFeature->integer(SketchPlugin_ConstraintAngle::TYPE_ID()));
592   // fill the value before llines to avoid calculation of angle value by the Angle feature
593   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
594   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
595   fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()));
596   aFeature->execute();
597   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
598 }
599
600 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setAngleComplementary(
601     const ModelHighAPI_RefAttr & theLine1,
602     const ModelHighAPI_RefAttr & theLine2,
603     const ModelHighAPI_Double & theValue)
604 {
605   std::shared_ptr<ModelAPI_Feature> aFeature =
606       compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID());
607   fillAttribute(SketcherPrs_Tools::ANGLE_COMPLEMENTARY,
608       aFeature->integer(SketchPlugin_ConstraintAngle::TYPE_ID()));
609   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
610   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
611   fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()));
612   aFeature->execute();
613   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
614 }
615
616 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setAngleBackward(
617     const ModelHighAPI_RefAttr & theLine1,
618     const ModelHighAPI_RefAttr & theLine2,
619     const ModelHighAPI_Double & theValue)
620 {
621   std::shared_ptr<ModelAPI_Feature> aFeature =
622       compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID());
623   fillAttribute(SketcherPrs_Tools::ANGLE_BACKWARD,
624       aFeature->integer(SketchPlugin_ConstraintAngle::TYPE_ID()));
625   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
626   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
627   fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()));
628   aFeature->execute();
629   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
630 }
631
632 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setCoincident(
633     const ModelHighAPI_RefAttr & thePoint1,
634     const ModelHighAPI_RefAttr & thePoint2)
635 {
636   std::shared_ptr<ModelAPI_Feature> aFeature =
637       compositeFeature()->addFeature(SketchPlugin_ConstraintCoincidence::ID());
638   fillAttribute(thePoint1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
639   fillAttribute(thePoint2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
640   aFeature->execute();
641   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
642 }
643
644 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setCollinear(
645     const ModelHighAPI_RefAttr & theLine1,
646     const ModelHighAPI_RefAttr & theLine2)
647 {
648   std::shared_ptr<ModelAPI_Feature> aFeature =
649       compositeFeature()->addFeature(SketchPlugin_ConstraintCollinear::ID());
650   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
651   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
652   aFeature->execute();
653   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
654 }
655
656 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setDistance(
657     const ModelHighAPI_RefAttr & thePoint,
658     const ModelHighAPI_RefAttr & thePointOrLine,
659     const ModelHighAPI_Double & theValue,
660     bool isSigned)
661 {
662   std::shared_ptr<ModelAPI_Feature> aFeature =
663       compositeFeature()->addFeature(SketchPlugin_ConstraintDistance::ID());
664   fillAttribute(thePoint, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
665   fillAttribute(thePointOrLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
666   fillAttribute(theValue, aFeature->real(SketchPlugin_Constraint::VALUE()));
667   fillAttribute(isSigned, aFeature->boolean(SketchPlugin_ConstraintDistance::SIGNED()));
668   aFeature->execute();
669   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
670 }
671
672 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setSignedDistance(
673     const ModelHighAPI_RefAttr & thePoint,
674     const ModelHighAPI_RefAttr & thePointOrLine,
675     const ModelHighAPI_Double & theValue)
676 {
677   return setDistance(thePoint, thePointOrLine, theValue, true);
678 }
679
680 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setUnsignedDistance(
681     const ModelHighAPI_RefAttr & thePoint,
682     const ModelHighAPI_RefAttr & thePointOrLine,
683     const ModelHighAPI_Double & theValue)
684 {
685   return setDistance(thePoint, thePointOrLine, theValue, false);
686 }
687
688 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setHorizontalDistance(
689     const ModelHighAPI_RefAttr & thePoint1,
690     const ModelHighAPI_RefAttr & thePoint2,
691     const ModelHighAPI_Double & theValue)
692 {
693   std::shared_ptr<ModelAPI_Feature> aFeature =
694       compositeFeature()->addFeature(SketchPlugin_ConstraintDistanceHorizontal::ID());
695   fillAttribute(thePoint1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
696   fillAttribute(thePoint2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
697   fillAttribute(theValue,
698       aFeature->real(SketchPlugin_ConstraintDistanceAlongDir::DISTANCE_VALUE_ID()));
699   aFeature->execute();
700   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
701 }
702
703 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setVerticalDistance(
704     const ModelHighAPI_RefAttr & thePoint1,
705     const ModelHighAPI_RefAttr & thePoint2,
706     const ModelHighAPI_Double & theValue)
707 {
708   std::shared_ptr<ModelAPI_Feature> aFeature =
709       compositeFeature()->addFeature(SketchPlugin_ConstraintDistanceVertical::ID());
710   fillAttribute(thePoint1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
711   fillAttribute(thePoint2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
712   fillAttribute(theValue,
713       aFeature->real(SketchPlugin_ConstraintDistanceAlongDir::DISTANCE_VALUE_ID()));
714   aFeature->execute();
715   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
716 }
717
718 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setEqual(
719     const ModelHighAPI_RefAttr & theObject1,
720     const ModelHighAPI_RefAttr & theObject2)
721 {
722   std::shared_ptr<ModelAPI_Feature> aFeature =
723       compositeFeature()->addFeature(SketchPlugin_ConstraintEqual::ID());
724   fillAttribute(theObject1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
725   fillAttribute(theObject2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
726   aFeature->execute();
727   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
728 }
729
730 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setFillet(
731     const ModelHighAPI_RefAttr & thePoint)
732 {
733   std::shared_ptr<ModelAPI_Feature> aFeature =
734       compositeFeature()->addFeature(SketchPlugin_Fillet::ID());
735   fillAttribute(thePoint, aFeature->data()->refattr(SketchPlugin_Fillet::FILLET_POINT_ID()));
736   apply(); // finish operation to remove Fillet feature correcly
737   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
738 }
739
740 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setFilletWithRadius(
741     const ModelHighAPI_RefAttr & thePoint,
742     const ModelHighAPI_Double & theRadius)
743 {
744   CompositeFeaturePtr aSketch = compositeFeature();
745   int aNbSubs = aSketch->numberOfSubs();
746
747   // create fillet
748   InterfacePtr aFilletFeature = setFillet(thePoint);
749
750   // set radius for just created arc
751   FeaturePtr anArc = aSketch->subFeature(aNbSubs - 1);
752   if (anArc->getKind() == SketchPlugin_Arc::ID())
753     setRadius(ModelHighAPI_RefAttr(ObjectPtr(anArc->lastResult())), ModelHighAPI_Double(theRadius));
754
755   return aFilletFeature;
756 }
757
758 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setFixed(
759     const ModelHighAPI_RefAttr & theObject)
760 {
761   std::shared_ptr<ModelAPI_Feature> aFeature =
762       compositeFeature()->addFeature(SketchPlugin_ConstraintRigid::ID());
763   fillAttribute(theObject, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
764   aFeature->execute();
765   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
766 }
767
768 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setHorizontal(
769     const ModelHighAPI_RefAttr & theLine)
770 {
771   std::shared_ptr<ModelAPI_Feature> aFeature =
772       compositeFeature()->addFeature(SketchPlugin_ConstraintHorizontal::ID());
773   fillAttribute(theLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
774   aFeature->execute();
775   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
776 }
777
778 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setLength(
779     const ModelHighAPI_RefAttr & theLine,
780     const ModelHighAPI_Double & theValue)
781 {
782   std::shared_ptr<ModelAPI_Feature> aFeature =
783       compositeFeature()->addFeature(SketchPlugin_ConstraintLength::ID());
784   fillAttribute(theLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
785   fillAttribute(theValue, aFeature->real(SketchPlugin_Constraint::VALUE()));
786   aFeature->execute();
787   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
788 }
789
790 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setMiddlePoint(
791     const ModelHighAPI_RefAttr & thePoint,
792     const ModelHighAPI_RefAttr & theLine)
793 {
794   std::shared_ptr<ModelAPI_Feature> aFeature =
795       compositeFeature()->addFeature(SketchPlugin_ConstraintMiddle::ID());
796   fillAttribute(thePoint, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
797   fillAttribute(theLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
798   aFeature->execute();
799   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
800 }
801
802 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setParallel(
803     const ModelHighAPI_RefAttr & theLine1,
804     const ModelHighAPI_RefAttr & theLine2)
805 {
806   std::shared_ptr<ModelAPI_Feature> aFeature =
807       compositeFeature()->addFeature(SketchPlugin_ConstraintParallel::ID());
808   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
809   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
810   aFeature->execute();
811   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
812 }
813
814 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setPerpendicular(
815     const ModelHighAPI_RefAttr & theLine1,
816     const ModelHighAPI_RefAttr & theLine2)
817 {
818   std::shared_ptr<ModelAPI_Feature> aFeature =
819       compositeFeature()->addFeature(SketchPlugin_ConstraintPerpendicular::ID());
820   fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
821   fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
822   aFeature->execute();
823   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
824 }
825
826 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setRadius(
827     const ModelHighAPI_RefAttr & theCircleOrArc,
828     const ModelHighAPI_Double & theValue)
829 {
830   std::shared_ptr<ModelAPI_Feature> aFeature =
831       compositeFeature()->addFeature(SketchPlugin_ConstraintRadius::ID());
832   fillAttribute(theCircleOrArc, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
833   fillAttribute(theValue, aFeature->real(SketchPlugin_Constraint::VALUE()));
834   aFeature->execute();
835   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
836 }
837
838 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setTangent(
839     const ModelHighAPI_RefAttr & theLine,
840     const ModelHighAPI_RefAttr & theCircle)
841 {
842   std::shared_ptr<ModelAPI_Feature> aFeature =
843       compositeFeature()->addFeature(SketchPlugin_ConstraintTangent::ID());
844   fillAttribute(theLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
845   fillAttribute(theCircle, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B()));
846   aFeature->execute();
847   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
848 }
849
850 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setVertical(
851     const ModelHighAPI_RefAttr & theLine)
852 {
853   std::shared_ptr<ModelAPI_Feature> aFeature =
854       compositeFeature()->addFeature(SketchPlugin_ConstraintVertical::ID());
855   fillAttribute(theLine, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A()));
856   aFeature->execute();
857   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
858 }
859
860 //--------------------------------------------------------------------------------------
861
862 static std::shared_ptr<GeomAPI_Pnt2d> pointCoordinates(const AttributePtr& thePoint)
863 {
864   AttributePoint2DPtr aPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(thePoint);
865   return aPnt ? aPnt->pnt() : std::shared_ptr<GeomAPI_Pnt2d>();
866 }
867
868 static std::shared_ptr<GeomAPI_Pnt2d> middlePointOnLine(const FeaturePtr& theFeature)
869 {
870   AttributePoint2DPtr aStartAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
871       theFeature->attribute(SketchPlugin_Line::START_ID()));
872   AttributePoint2DPtr aEndAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
873       theFeature->attribute(SketchPlugin_Line::END_ID()));
874
875   if (!aStartAttr || !aEndAttr)
876     return std::shared_ptr<GeomAPI_Pnt2d>();
877
878   std::shared_ptr<GeomAPI_XY> aStartPoint = aStartAttr->pnt()->xy();
879   std::shared_ptr<GeomAPI_XY> aEndPoint = aEndAttr->pnt()->xy();
880   return std::shared_ptr<GeomAPI_Pnt2d>(
881       new GeomAPI_Pnt2d(aStartPoint->added(aEndPoint)->multiplied(0.5)));
882 }
883
884 static std::shared_ptr<GeomAPI_Pnt2d> pointOnCircle(const FeaturePtr& theFeature)
885 {
886   AttributePoint2DPtr aCenter = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
887       theFeature->attribute(SketchPlugin_Circle::CENTER_ID()));
888   AttributeDoublePtr aRadius = theFeature->real(SketchPlugin_Circle::RADIUS_ID());
889
890   if (!aCenter || !aRadius)
891     return std::shared_ptr<GeomAPI_Pnt2d>();
892
893   return std::shared_ptr<GeomAPI_Pnt2d>(
894       new GeomAPI_Pnt2d(aCenter->x() + aRadius->value(), aCenter->y()));
895 }
896
897 static std::shared_ptr<GeomAPI_Pnt2d> middlePointOnArc(const FeaturePtr& theFeature)
898 {
899   static const double PI = 3.141592653589793238463;
900
901   AttributePoint2DPtr aCenterAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
902       theFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
903   AttributePoint2DPtr aStartAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
904       theFeature->attribute(SketchPlugin_Arc::START_ID()));
905   AttributePoint2DPtr aEndAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
906       theFeature->attribute(SketchPlugin_Arc::END_ID()));
907
908   if (!aCenterAttr || !aStartAttr || !aEndAttr)
909     return std::shared_ptr<GeomAPI_Pnt2d>();
910
911   std::shared_ptr<GeomAPI_Dir2d> aStartDir(new GeomAPI_Dir2d(
912       aStartAttr->x() - aCenterAttr->x(), aStartAttr->y() - aCenterAttr->y()));
913   std::shared_ptr<GeomAPI_Dir2d> aEndDir(new GeomAPI_Dir2d(
914       aEndAttr->x() - aCenterAttr->x(), aEndAttr->y() - aCenterAttr->y()));
915
916   double anAngle = aStartDir->angle(aEndDir);
917   bool isReversed = theFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->value();
918   if (isReversed && anAngle > 0.)
919     anAngle -= 2.0 * PI;
920   else if (!isReversed && anAngle <= 0.)
921     anAngle += 2.0 * PI;
922
923   double cosA = cos(anAngle);
924   double sinA = sin(anAngle);
925
926   // rotate start dir to find middle point on arc
927   double aRadius = aStartAttr->pnt()->distance(aCenterAttr->pnt());
928   double x = aCenterAttr->x() + aRadius * (aStartDir->x() * cosA - aStartDir->y() * sinA);
929   double y = aCenterAttr->y() + aRadius * (aStartDir->x() * sinA + aStartDir->y() * cosA);
930
931   return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(x, y));
932 }
933
934 static std::shared_ptr<GeomAPI_Pnt2d> middlePoint(const ObjectPtr& theObject)
935 {
936   std::shared_ptr<GeomAPI_Pnt2d> aMiddlePoint;
937   FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
938   if (aFeature) {
939     // move only features of the following types
940     const std::string& aFeatureKind = aFeature->getKind();
941     if (aFeatureKind == SketchPlugin_Point::ID())
942       aMiddlePoint = pointCoordinates(aFeature->attribute(SketchPlugin_Point::COORD_ID()));
943     else if (aFeatureKind == SketchPlugin_Line::ID())
944       aMiddlePoint = middlePointOnLine(aFeature);
945     else if (aFeatureKind == SketchPlugin_Circle::ID())
946       aMiddlePoint = pointOnCircle(aFeature);
947     else if (aFeatureKind == SketchPlugin_Arc::ID())
948       aMiddlePoint = middlePointOnArc(aFeature);
949   }
950   return aMiddlePoint;
951 }
952
953 void SketchAPI_Sketch::move(const ModelHighAPI_RefAttr& theMovedEntity,
954                             const std::shared_ptr<GeomAPI_Pnt2d>& theTargetPoint)
955 {
956   std::shared_ptr<ModelAPI_ObjectMovedMessage> aMessage(new ModelAPI_ObjectMovedMessage);
957   theMovedEntity.fillMessage(aMessage);
958
959   std::shared_ptr<GeomAPI_Pnt2d> anOriginalPosition;
960   if (aMessage->movedAttribute())
961     anOriginalPosition = pointCoordinates(aMessage->movedAttribute());
962   else
963     anOriginalPosition = middlePoint(aMessage->movedObject());
964
965   if (!anOriginalPosition)
966     return; // something has gone wrong, do not process movement
967
968   aMessage->setOriginalPosition(anOriginalPosition);
969   aMessage->setCurrentPosition(theTargetPoint);
970   Events_Loop::loop()->send(aMessage);
971 }
972
973 void SketchAPI_Sketch::move(const ModelHighAPI_RefAttr& theMovedEntity,
974                             double theTargetX, double theTargetY)
975 {
976   std::shared_ptr<GeomAPI_Pnt2d> aTargetPoint(new GeomAPI_Pnt2d(theTargetX, theTargetY));
977   move(theMovedEntity, aTargetPoint);
978 }
979
980 //--------------------------------------------------------------------------------------
981
982 std::shared_ptr<GeomAPI_Pnt2d> SketchAPI_Sketch::to2D(const std::shared_ptr<GeomAPI_Pnt>& thePoint)
983 {
984   FeaturePtr aBase = feature();
985   std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
986       aBase->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
987   std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
988       aBase->attribute(SketchPlugin_Sketch::NORM_ID()));
989   std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
990       aBase->attribute(SketchPlugin_Sketch::DIRX_ID()));
991   std::shared_ptr<GeomAPI_Dir> aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
992
993   return thePoint->to2D(aC->pnt(), aX->dir(), aY);
994 }
995
996 //--------------------------------------------------------------------------------------
997
998 void SketchAPI_Sketch::dump(ModelHighAPI_Dumper& theDumper) const
999 {
1000   FeaturePtr aBase = feature();
1001   const std::string& aDocName = theDumper.name(aBase->document());
1002
1003   AttributeSelectionPtr anExternal = aBase->selection(SketchPlugin_SketchEntity::EXTERNAL_ID());
1004   if (anExternal->value()) {
1005     theDumper << aBase << " = model.addSketch(" << aDocName <<
1006       ", " << anExternal << ")" << std::endl;
1007   } else {
1008     // Sketch is base on a plane.
1009     std::shared_ptr<GeomAPI_Pnt> anOrigin = std::dynamic_pointer_cast<GeomDataAPI_Point>(
1010         aBase->attribute(SketchPlugin_Sketch::ORIGIN_ID()))->pnt();
1011     std::shared_ptr<GeomAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1012         aBase->attribute(SketchPlugin_Sketch::NORM_ID()))->dir();
1013     std::shared_ptr<GeomAPI_Dir> aDirX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1014         aBase->attribute(SketchPlugin_Sketch::DIRX_ID()))->dir();
1015
1016     // Check the plane is coordinate plane
1017     std::string aPlaneName = defaultPlane(anOrigin, aNormal, aDirX);
1018     if(anExternal->context()) { // checking for selected planes
1019       if (!aPlaneName.empty()
1020           && anExternal->context()->data()
1021           && anExternal->context()->data()->name() == aPlaneName) {
1022         // dump sketch based on coordinate plane
1023         theDumper << aBase << " = model.addSketch(" << aDocName
1024                   << ", model.standardPlane(\"" << aPlaneName << "\"))" << std::endl;
1025       } else { // some other plane
1026         theDumper << aBase << " = model.addSketch(" << aDocName <<
1027           ", " << anExternal<< ")" << std::endl;
1028       }
1029     } else {
1030       if (aPlaneName.empty()) {
1031         // needs import additional module
1032         theDumper.importModule("GeomAPI");
1033         // dump plane parameters
1034         const std::string& aSketchName = theDumper.name(aBase);
1035         std::string anOriginName = aSketchName + "_origin";
1036         std::string aNormalName  = aSketchName + "_norm";
1037         std::string aDirXName    = aSketchName + "_dirx";
1038         // use "\n" instead of std::endl to avoid automatic dumping sketch here
1039         // and then dumplicate dumping it in the next line
1040         theDumper << anOriginName << " = " << anOrigin << "\n"
1041                   << aNormalName  << " = " << aNormal  << "\n"
1042                   << aDirXName    << " = " << aDirX    << "\n";
1043         // dump sketch based on arbitrary plane
1044         theDumper << aBase << " = model.addSketch(" << aDocName << ", GeomAPI_Ax3("
1045                   << anOriginName << ", " << aDirXName << ", " << aNormalName << "))" << std::endl;
1046       } else {
1047         // dump sketch based on coordinate plane
1048         theDumper << aBase << " = model.addSketch(" << aDocName
1049                   << ", model.defaultPlane(\"" << aPlaneName << "\"))" << std::endl;
1050       }
1051     }
1052   }
1053
1054   // dump sketch's subfeatures
1055   CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aBase);
1056   theDumper.processSubs(aCompFeat, true);
1057 }