]> SALOME platform Git repositories - modules/shaper.git/blob - src/GeomAlgoAPI/GeomAlgoAPI_Circ2dBuilder.cpp
Salome HOME
d6a62bad6a947e141d34b8ba3fc958161ca55417
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_Circ2dBuilder.cpp
1 // Copyright (C) 2014-2017  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<mailto:webmaster.salome@opencascade.com>
18 //
19
20 #include <GeomAlgoAPI_Circ2dBuilder.h>
21 #include <GeomAPI_Ax3.h>
22 #include <GeomAPI_Circ2d.h>
23 #include <GeomAPI_Pnt2d.h>
24 #include <GeomAPI_Dir2d.h>
25 #include <GeomAPI_Shape.h>
26
27 #include <BRep_Tool.hxx>
28 #include <ElCLib.hxx>
29 #include <GccAna_Circ2d2TanRad.hxx>
30 #include <GccAna_Circ2d3Tan.hxx>
31 #include <GccAna_Circ2dTanCen.hxx>
32 #include <GccEnt.hxx>
33 #include <GccEnt_QualifiedCirc.hxx>
34 #include <GccEnt_QualifiedLin.hxx>
35 #include <Geom2dAdaptor_Curve.hxx>
36 #include <Geom_Plane.hxx>
37 #include <TopoDS.hxx>
38 #include <TopoDS_Edge.hxx>
39
40 #include <cmath>
41
42 typedef std::shared_ptr<gp_Circ2d> Circ2dPtr;
43 typedef std::shared_ptr<Geom2dAdaptor_Curve> CurveAdaptorPtr;
44 typedef std::vector< std::shared_ptr<GccEnt_QualifiedCirc> > VectorOfGccCirc;
45 typedef std::vector< std::shared_ptr<GccEnt_QualifiedLin> >  VectorOfGccLine;
46
47
48 // Provide different mechanisms to create circle:
49 // * by passing points
50 // * by tangent edges
51 // * with specified radius
52 // * etc.
53 class CircleBuilder
54 {
55 public:
56   CircleBuilder(const std::shared_ptr<GeomAPI_Ax3>& theBasePlane)
57     : myPlane(new Geom_Plane(theBasePlane->impl<gp_Ax3>())),
58       myRadius(0.0)
59   {}
60
61   void setRadius(const double theRadius)
62   { myRadius = theRadius; }
63
64   void setCenter(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter)
65   { myCenter = theCenter; }
66
67   void setTangentCurves(const std::vector< std::shared_ptr<GeomAPI_Shape> >& theEdges)
68   {
69     std::vector< std::shared_ptr<GeomAPI_Shape> >::const_iterator anEdgeIt;
70     for (anEdgeIt = theEdges.begin(); anEdgeIt != theEdges.end(); ++anEdgeIt) {
71       const TopoDS_Edge& anEdge = TopoDS::Edge((*anEdgeIt)->impl<TopoDS_Shape>());
72
73       double aFirst, aLast;
74       TopLoc_Location aLoc;
75       Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, myPlane, aLoc, aFirst, aLast);
76       CurveAdaptorPtr aCurveAdaptor(new Geom2dAdaptor_Curve(aCurve, aFirst, aLast));
77
78       // sort curves (circles should become first)
79       if (aCurveAdaptor->GetType() == GeomAbs_Circle)
80         myTangentShapes.insert(myTangentShapes.begin(), aCurveAdaptor);
81       else
82         myTangentShapes.push_back(aCurveAdaptor);
83     }
84   }
85
86   void setPassingPoints(const std::vector< std::shared_ptr<GeomAPI_Pnt2d> >& thePoints)
87   {
88     std::vector< std::shared_ptr<GeomAPI_Pnt2d> >::const_iterator aPIt;
89     for (aPIt = thePoints.begin(); aPIt != thePoints.end(); ++aPIt)
90       myPassingPoints.push_back((*aPIt)->impl<gp_Pnt2d>());
91   }
92
93   void setClosestPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
94   { myClosestPoint = thePoint; }
95
96
97   Circ2dPtr circle()
98   {
99     Circ2dPtr aResult;
100     if (myCenter) {
101       if (myPassingPoints.size() == 1)
102         aResult = circleByCenterAndPassingPoint();
103       else if (myTangentShapes.size() == 1)
104         aResult = circleByCenterAndTangent();
105       else if (myRadius > 0.0)
106         aResult = circleByCenterAndRadius();
107     } else if (myRadius > 0.0) {
108       if (myTangentShapes.size() == 2)
109         aResult = circleByRadiusAndTwoTangentCurves();
110     } else {
111       switch (myPassingPoints.size()) {
112       case 0:
113         aResult = circleByThreeTangentCurves();
114         break;
115       case 1:
116         aResult = circleByPointAndTwoTangentCurves();
117         break;
118       case 2:
119         aResult = circleByTwoPointsAndTangentCurve();
120         break;
121       case 3:
122         aResult = circleByThreePassingPoints();
123         break;
124       default:
125         break;
126       }
127     }
128     return aResult;
129   }
130
131 private:
132   Circ2dPtr circleByCenterAndRadius()
133   {
134     const gp_Pnt2d& aCenter = myCenter->impl<gp_Pnt2d>();
135     return Circ2dPtr(new gp_Circ2d(gp_Ax2d(aCenter, gp::DX2d()), myRadius));
136   }
137
138   Circ2dPtr circleByCenterAndPassingPoint()
139   {
140     const gp_Pnt2d& aCenter = myCenter->impl<gp_Pnt2d>();
141     if (aCenter.SquareDistance(myPassingPoints[0]) > Precision::SquareConfusion()) {
142       GccAna_Circ2dTanCen aBuilder(myPassingPoints[0], aCenter);
143       if (aBuilder.NbSolutions() > 0)
144         return Circ2dPtr(new gp_Circ2d(aBuilder.ThisSolution(1)));
145     }
146     return Circ2dPtr();
147   }
148
149   Circ2dPtr circleByCenterAndTangent()
150   {
151     const gp_Pnt2d& aCenter = myCenter->impl<gp_Pnt2d>();
152     CurveAdaptorPtr aCurve = myTangentShapes[0];
153
154     std::shared_ptr<GccAna_Circ2dTanCen> aCircleBuilder;
155     if (aCurve->GetType() == GeomAbs_Line &&
156         aCurve->Line().Distance(aCenter) > Precision::Confusion()) {
157       aCircleBuilder = std::shared_ptr<GccAna_Circ2dTanCen>(
158           new GccAna_Circ2dTanCen(aCurve->Line(), aCenter));
159     } else if (aCurve->GetType() == GeomAbs_Circle) {
160       aCircleBuilder = std::shared_ptr<GccAna_Circ2dTanCen>(new GccAna_Circ2dTanCen(
161           GccEnt::Unqualified(aCurve->Circle()), aCenter, Precision::Confusion()));
162     }
163
164     return getProperCircle(aCircleBuilder);
165   }
166
167   Circ2dPtr getProperCircle(const std::shared_ptr<GccAna_Circ2dTanCen>& theBuilder) const
168   {
169     if (!theBuilder)
170       return Circ2dPtr();
171
172     CurveAdaptorPtr aCurve = myTangentShapes[0];
173
174     int aNbSol = theBuilder->NbSolutions();
175     if (aNbSol == 0)
176       return Circ2dPtr();
177
178     int anAppropriateSolution = 1;
179     double aMinDist = Precision::Infinite();
180
181     double aParSol, aPonTgCurve;
182     gp_Pnt2d aTgPnt;
183     for (int i = 1; i <= aNbSol && aNbSol > 1 && aCurve; ++i) {
184       theBuilder->Tangency1(i, aParSol, aPonTgCurve, aTgPnt);
185       if (isParamOnCurve(aPonTgCurve, aCurve)) {
186         double aDist = distanceToClosestPoint(theBuilder->ThisSolution(i));
187         if (aDist < aMinDist) {
188           anAppropriateSolution = i;
189           aMinDist = aDist;
190         }
191       }
192     }
193
194     return Circ2dPtr(new gp_Circ2d(theBuilder->ThisSolution(anAppropriateSolution)));
195   }
196
197   double distanceToClosestPoint(const gp_Circ2d& theCirc) const
198   {
199     if (myClosestPoint) {
200       double aDist = myClosestPoint->impl<gp_Pnt2d>().Distance(theCirc.Location());
201       return fabs(aDist - theCirc.Radius());
202     }
203     return 0.0;
204   }
205
206
207   Circ2dPtr circleByThreeTangentCurves()
208   {
209     VectorOfGccCirc aTgCirc;
210     VectorOfGccLine aTgLine;
211     convertTangentCurvesToGccEnt(aTgCirc, aTgLine);
212
213     if (aTgCirc.size() + aTgLine.size() != 3)
214       return Circ2dPtr();
215
216     std::shared_ptr<GccAna_Circ2d3Tan> aCircleBuilder;
217     switch (aTgLine.size()) {
218     case 0:
219       aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
220           *aTgCirc[0], *aTgCirc[1], *aTgCirc[2], Precision::Confusion()));
221       break;
222     case 1:
223       aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
224           *aTgCirc[0], *aTgCirc[1], *aTgLine[0], Precision::Confusion()));
225       break;
226     case 2:
227       aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
228           *aTgCirc[0], *aTgLine[0], *aTgLine[1], Precision::Confusion()));
229       break;
230     case 3:
231       aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
232           *aTgLine[0], *aTgLine[1], *aTgLine[0], Precision::Confusion()));
233       break;
234     default:
235       break;
236     }
237
238     return getProperCircle(aCircleBuilder);
239   }
240
241   Circ2dPtr circleByPointAndTwoTangentCurves()
242   {
243     const gp_Pnt2d& aPoint = myPassingPoints[0];
244     CurveAdaptorPtr aCurve1 = myTangentShapes[0];
245     CurveAdaptorPtr aCurve2 = myTangentShapes[1];
246     if (!aCurve1 || !aCurve2)
247       return Circ2dPtr();
248
249     std::shared_ptr<GccAna_Circ2d3Tan> aCircleBuilder;
250     if (aCurve1->GetType() == GeomAbs_Line) {
251       if (aCurve2->GetType() == GeomAbs_Line) {
252         aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(
253             new GccAna_Circ2d3Tan(GccEnt::Unqualified(aCurve1->Line()),
254                                   GccEnt::Unqualified(aCurve2->Line()),
255                                   aPoint, Precision::Confusion()));
256       } else if (aCurve2->GetType() == GeomAbs_Circle) {
257         aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(
258             new GccAna_Circ2d3Tan(GccEnt::Unqualified(aCurve2->Circle()),
259                                   GccEnt::Unqualified(aCurve1->Line()),
260                                   aPoint, Precision::Confusion()));
261       }
262     } else if (aCurve1->GetType() == GeomAbs_Circle) {
263       if (aCurve2->GetType() == GeomAbs_Line) {
264         aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(
265             new GccAna_Circ2d3Tan(GccEnt::Unqualified(aCurve1->Circle()),
266                                   GccEnt::Unqualified(aCurve2->Line()),
267                                   aPoint, Precision::Confusion()));
268       } else if (aCurve2->GetType() == GeomAbs_Circle) {
269         aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(
270             new GccAna_Circ2d3Tan(GccEnt::Unqualified(aCurve2->Circle()),
271                                   GccEnt::Unqualified(aCurve1->Circle()),
272                                   aPoint, Precision::Confusion()));
273       }
274     }
275
276     return getProperCircle(aCircleBuilder);
277   }
278
279   Circ2dPtr circleByTwoPointsAndTangentCurve()
280   {
281     const gp_Pnt2d& aPoint1 = myPassingPoints[0];
282     const gp_Pnt2d& aPoint2 = myPassingPoints[1];
283     CurveAdaptorPtr aCurve = myTangentShapes[0];
284     if (!aCurve)
285       return Circ2dPtr();
286
287     std::shared_ptr<GccAna_Circ2d3Tan> aCircleBuilder;
288     if (aCurve->GetType() == GeomAbs_Line) {
289       aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
290         GccEnt::Unqualified(aCurve->Line()), aPoint1, aPoint2, Precision::Confusion()));
291     } else if (aCurve->GetType() == GeomAbs_Circle) {
292       aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(new GccAna_Circ2d3Tan(
293           GccEnt::Unqualified(aCurve->Circle()), aPoint1, aPoint2, Precision::Confusion()));
294     }
295
296     return getProperCircle(aCircleBuilder);
297   }
298
299   Circ2dPtr circleByThreePassingPoints()
300   {
301     GccAna_Circ2d3Tan aCircleBuilder(myPassingPoints[0],
302                                      myPassingPoints[1],
303                                      myPassingPoints[2],
304                                      Precision::Confusion());
305     if (aCircleBuilder.NbSolutions() > 0)
306       return Circ2dPtr(new gp_Circ2d(aCircleBuilder.ThisSolution(1)));
307     return Circ2dPtr();
308   }
309
310   Circ2dPtr getProperCircle(const std::shared_ptr<GccAna_Circ2d3Tan>& theBuilder) const
311   {
312     if (!theBuilder)
313       return Circ2dPtr();
314
315     int aNbSol = theBuilder->NbSolutions();
316     if (aNbSol == 0)
317       return Circ2dPtr();
318
319     int anAppropriateSolution = 1;
320     double aMinDist = Precision::Infinite();
321
322     double aParSol, aPonTgCurve;
323     gp_Pnt2d aTgPnt;
324     for (int i = 1; i <= aNbSol && aNbSol > 1; ++i) {
325       bool isApplicable = false;
326       if (myTangentShapes.size() >= 1) {
327         theBuilder->Tangency1(i, aParSol, aPonTgCurve, aTgPnt);
328         isApplicable = isParamOnCurve(aPonTgCurve, myTangentShapes[0]);
329       }
330       if (myTangentShapes.size() >= 2 && isApplicable) {
331         theBuilder->Tangency2(i, aParSol, aPonTgCurve, aTgPnt);
332         isApplicable = isParamOnCurve(aPonTgCurve, myTangentShapes[1]);
333       }
334       if (myTangentShapes.size() >= 3 && isApplicable) {
335         theBuilder->Tangency3(i, aParSol, aPonTgCurve, aTgPnt);
336         isApplicable = isParamOnCurve(aPonTgCurve, myTangentShapes[2]);
337       }
338
339       if (isApplicable) {
340         double aDist = distanceToClosestPoint(theBuilder->ThisSolution(i));
341         if (aDist < aMinDist) {
342           anAppropriateSolution = i;
343           aMinDist = aDist;
344         }
345       }
346     }
347
348     return Circ2dPtr(new gp_Circ2d(theBuilder->ThisSolution(anAppropriateSolution)));
349   }
350
351
352   Circ2dPtr circleByRadiusAndTwoTangentCurves()
353   {
354     VectorOfGccCirc aTgCirc;
355     VectorOfGccLine aTgLine;
356     convertTangentCurvesToGccEnt(aTgCirc, aTgLine);
357
358     if (aTgCirc.size() + aTgLine.size() != 2)
359       return Circ2dPtr();
360
361     std::shared_ptr<GccAna_Circ2d2TanRad> aCircleBuilder;
362     switch (aTgLine.size()) {
363     case 0:
364       aCircleBuilder = std::shared_ptr<GccAna_Circ2d2TanRad>(new GccAna_Circ2d2TanRad(
365           *aTgCirc[0], *aTgCirc[1], myRadius, Precision::Confusion()));
366       break;
367     case 1:
368       aCircleBuilder = std::shared_ptr<GccAna_Circ2d2TanRad>(new GccAna_Circ2d2TanRad(
369           *aTgCirc[0], *aTgLine[0], myRadius, Precision::Confusion()));
370       break;
371     case 2:
372       aCircleBuilder = std::shared_ptr<GccAna_Circ2d2TanRad>(new GccAna_Circ2d2TanRad(
373           *aTgLine[0], *aTgLine[1], myRadius, Precision::Confusion()));
374       break;
375     default:
376       break;
377     }
378
379     return getProperCircle(aCircleBuilder);
380   }
381
382   Circ2dPtr getProperCircle(const std::shared_ptr<GccAna_Circ2d2TanRad>& theBuilder) const
383   {
384     if (!theBuilder)
385       return Circ2dPtr();
386
387     int aNbSol = theBuilder->NbSolutions();
388     if (aNbSol == 0)
389       return Circ2dPtr();
390
391     int anAppropriateSolution = 1;
392     double aMinDist = Precision::Infinite();
393
394     double aParSol, aPonTgCurve;
395     gp_Pnt2d aTgPnt;
396     for (int i = 1; i <= aNbSol && aNbSol > 1; ++i) {
397       bool isApplicable = false;
398       if (myTangentShapes.size() >= 1) {
399         theBuilder->Tangency1(i, aParSol, aPonTgCurve, aTgPnt);
400         isApplicable = isParamInCurve(aPonTgCurve, myTangentShapes[0]);
401       }
402       if (myTangentShapes.size() >= 2 && isApplicable) {
403         theBuilder->Tangency2(i, aParSol, aPonTgCurve, aTgPnt);
404         isApplicable = isParamInCurve(aPonTgCurve, myTangentShapes[1]);
405       }
406
407       if (isApplicable) {
408         double aDist = distanceToClosestPoint(theBuilder->ThisSolution(i));
409         if (aDist < aMinDist) {
410           anAppropriateSolution = i;
411           aMinDist = aDist;
412         }
413       }
414     }
415
416     return Circ2dPtr(new gp_Circ2d(theBuilder->ThisSolution(anAppropriateSolution)));
417   }
418
419
420   void convertTangentCurvesToGccEnt(VectorOfGccCirc& theTangentCircles,
421                                     VectorOfGccLine& theTangentLines)
422   {
423     theTangentCircles.reserve(3);
424     theTangentLines.reserve(3);
425
426     std::vector<CurveAdaptorPtr>::iterator anIt = myTangentShapes.begin();
427     for (; anIt != myTangentShapes.end(); ++anIt) {
428       switch ((*anIt)->GetType()) {
429       case GeomAbs_Line:
430         theTangentLines.push_back(
431             std::shared_ptr<GccEnt_QualifiedLin>(
432             new GccEnt_QualifiedLin((*anIt)->Line(), GccEnt_unqualified))
433         );
434         break;
435       case GeomAbs_Circle:
436         theTangentCircles.push_back(
437             std::shared_ptr<GccEnt_QualifiedCirc>(
438             new GccEnt_QualifiedCirc((*anIt)->Circle(), GccEnt_unqualified))
439         );
440         break;
441       default:
442         break;
443       }
444     }
445   }
446
447
448   static void adjustPeriod(double& theParameter, const CurveAdaptorPtr& theCurve)
449   {
450     if (theCurve->Curve()->IsPeriodic()) {
451       theParameter = ElCLib::InPeriod(theParameter,
452                                       theCurve->FirstParameter(),
453                                       theCurve->FirstParameter() + theCurve->Period());
454     }
455   }
456
457   // boundary parameters of curve are NOT applied
458   static bool isParamInCurve(double& theParameter, const CurveAdaptorPtr& theCurve)
459   {
460     adjustPeriod(theParameter, theCurve);
461     return theParameter > theCurve->FirstParameter() &&
462            theParameter < theCurve->LastParameter();
463   }
464
465   // boundary parameters of curve are applied too
466   static bool isParamOnCurve(double& theParameter, const CurveAdaptorPtr& theCurve)
467   {
468     adjustPeriod(theParameter, theCurve);
469     return theParameter >= theCurve->FirstParameter() &&
470            theParameter <= theCurve->LastParameter();
471   }
472
473 private:
474   Handle(Geom_Plane) myPlane;
475   std::shared_ptr<GeomAPI_Pnt2d> myCenter;
476   std::vector<gp_Pnt2d> myPassingPoints;
477   std::vector<CurveAdaptorPtr> myTangentShapes;
478   double myRadius;
479   std::shared_ptr<GeomAPI_Pnt2d> myClosestPoint;
480 };
481
482
483
484
485
486 GeomAlgoAPI_Circ2dBuilder::GeomAlgoAPI_Circ2dBuilder(const std::shared_ptr<GeomAPI_Ax3>& thePlane)
487   : myPlane(thePlane),
488     myRadius(0.)
489 {
490 }
491
492 void GeomAlgoAPI_Circ2dBuilder::setRadius(const double theRadius)
493 {
494   myRadius = theRadius;
495 }
496
497 void GeomAlgoAPI_Circ2dBuilder::setCenter(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter)
498 {
499   myCenter = theCenter;
500 }
501
502 void GeomAlgoAPI_Circ2dBuilder::addTangentCurve(const std::shared_ptr<GeomAPI_Shape>& theEdge)
503 {
504   if (theEdge->isEdge())
505     myTangentShapes.push_back(theEdge);
506 }
507
508 void GeomAlgoAPI_Circ2dBuilder::addPassingPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
509 {
510   myPassingPoints.push_back(thePoint);
511 }
512
513 void GeomAlgoAPI_Circ2dBuilder::setClosestPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
514 {
515   myClosestPoint = thePoint;
516 }
517
518 std::shared_ptr<GeomAPI_Circ2d> GeomAlgoAPI_Circ2dBuilder::circle(
519     const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
520     const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint,
521     const std::shared_ptr<GeomAPI_Pnt2d>& theThirdPoint)
522 {
523   std::shared_ptr<GeomAPI_Ax3> aPlane(new GeomAPI_Ax3);
524
525   GeomAlgoAPI_Circ2dBuilder aBuilder(aPlane);
526   aBuilder.addPassingPoint(theFirstPoint);
527   aBuilder.addPassingPoint(theSecondPoint);
528   aBuilder.addPassingPoint(theThirdPoint);
529   return aBuilder.circle();
530 }
531
532 std::shared_ptr<GeomAPI_Circ2d> GeomAlgoAPI_Circ2dBuilder::circle()
533 {
534   CircleBuilder aCircleBuilder(myPlane);
535   aCircleBuilder.setCenter(myCenter);
536   aCircleBuilder.setTangentCurves(myTangentShapes);
537   aCircleBuilder.setPassingPoints(myPassingPoints);
538   aCircleBuilder.setClosestPoint(myClosestPoint);
539   aCircleBuilder.setRadius(myRadius);
540   Circ2dPtr aCirc2d = aCircleBuilder.circle();
541
542   std::shared_ptr<GeomAPI_Circ2d> aCircle;
543   if (aCirc2d) {
544     const gp_Pnt2d& aCenter = aCirc2d->Location();
545     const gp_Dir2d& aXAxis = aCirc2d->Position().XDirection();
546
547     std::shared_ptr<GeomAPI_Pnt2d> aCircleCenter(new GeomAPI_Pnt2d(aCenter.X(), aCenter.Y()));
548     std::shared_ptr<GeomAPI_Dir2d> aCircleDir(new GeomAPI_Dir2d(aXAxis.X(), aXAxis.Y()));
549
550     aCircle = std::shared_ptr<GeomAPI_Circ2d>(
551         new GeomAPI_Circ2d(aCircleCenter, aCircleDir, aCirc2d->Radius()));
552   }
553   return aCircle;
554 }