FreeCAD

Форк
0
/
Geometry2d.cpp 
2446 строк · 71.4 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2016 Werner Mayer <wmayer[at]users.sourceforge.net>     *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
6
 *   This library is free software; you can redistribute it and/or         *
7
 *   modify it under the terms of the GNU Library General Public           *
8
 *   License as published by the Free Software Foundation; either          *
9
 *   version 2 of the License, or (at your option) any later version.      *
10
 *                                                                         *
11
 *   This library  is distributed in the hope that it will be useful,      *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU Library General Public License for more details.                  *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU Library General Public     *
17
 *   License along with this library; see the file COPYING.LIB. If not,    *
18
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
19
 *   Suite 330, Boston, MA  02111-1307, USA                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23
#include "PreCompiled.h"
24
#ifndef _PreComp_
25
# include <BRepBuilderAPI_MakeEdge2d.hxx>
26
# include <BRepBuilderAPI_MakeVertex.hxx>
27
# include <Geom2dAPI_Interpolate.hxx>
28
# include <Geom2dAPI_ProjectPointOnCurve.hxx>
29
# include <Geom2dConvert.hxx>
30
# include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
31
# include <Geom2dLProp_CLProps2d.hxx>
32
# include <gce_ErrorType.hxx>
33
# include <gp_Ax22d.hxx>
34
# include <gp_Circ2d.hxx>
35
# include <gp_Elips2d.hxx>
36
# include <gp_Hypr2d.hxx>
37
# include <gp_Lin2d.hxx>
38
# include <gp_Parab2d.hxx>
39
# include <Standard_ConstructionError.hxx>
40
# include <Standard_Version.hxx>
41
# include <TColgp_Array1OfPnt2d.hxx>
42
# include <TColgp_Array1OfVec2d.hxx>
43
# include <TColgp_HArray1OfPnt2d.hxx>
44
# include <TColStd_Array1OfInteger.hxx>
45
# include <TColStd_Array1OfReal.hxx>
46
# include <TColStd_HArray1OfBoolean.hxx>
47
# include <GCE2d_MakeArcOfCircle.hxx>
48
# include <GCE2d_MakeArcOfEllipse.hxx>
49
# include <GCE2d_MakeArcOfHyperbola.hxx>
50
# include <GCE2d_MakeArcOfParabola.hxx>
51
# include <GCE2d_MakeCircle.hxx>
52
# include <GCE2d_MakeEllipse.hxx>
53
# include <GCE2d_MakeHyperbola.hxx>
54
# include <GCE2d_MakeLine.hxx>
55
# include <GCE2d_MakeParabola.hxx>
56
# include <GCE2d_MakeSegment.hxx>
57
# include <Precision.hxx>
58
#endif
59

60
#include <Base/Exception.h>
61
#include <Base/Reader.h>
62
#include <Base/Writer.h>
63

64
#include "Geometry2d.h"
65

66
#include <Geom2d/ArcOfCircle2dPy.h>
67
#include <Geom2d/ArcOfEllipse2dPy.h>
68
#include <Geom2d/ArcOfHyperbola2dPy.h>
69
#include <Geom2d/ArcOfParabola2dPy.h>
70
#include <Geom2d/BezierCurve2dPy.h>
71
#include <Geom2d/BSplineCurve2dPy.h>
72
#include <Geom2d/Circle2dPy.h>
73
#include <Geom2d/Ellipse2dPy.h>
74
#include <Geom2d/Hyperbola2dPy.h>
75
#include <Geom2d/Line2dSegmentPy.h>
76
#include <Geom2d/Line2dPy.h>
77
#include <Geom2d/OffsetCurve2dPy.h>
78
#include <Geom2d/Parabola2dPy.h>
79

80

81
using namespace Part;
82
using namespace std;
83

84
extern const char* gce_ErrorStatusText(gce_ErrorType et);
85

86

87
TYPESYSTEM_SOURCE_ABSTRACT(Part::Geometry2d, Base::Persistence)
88

89
Geometry2d::Geometry2d() = default;
90

91
Geometry2d::~Geometry2d() = default;
92

93
unsigned int Geometry2d::getMemSize () const
94
{
95
    return sizeof(Geometry2d);
96
}
97

98
void Geometry2d::Save(Base::Writer & /*writer*/) const
99
{
100
    throw Base::NotImplementedError("Save");
101
}
102

103
void Geometry2d::Restore(Base::XMLReader & /*reader*/)
104
{
105
    throw Base::NotImplementedError("Restore");
106
}
107

108
// -------------------------------------------------
109

110
TYPESYSTEM_SOURCE(Part::Geom2dPoint, Part::Geometry2d)
111

112
Geom2dPoint::Geom2dPoint()
113
{
114
    this->myPoint = new Geom2d_CartesianPoint(0,0);
115
}
116

117
Geom2dPoint::Geom2dPoint(const Handle(Geom2d_CartesianPoint)& p)
118
{
119
    this->myPoint = Handle(Geom2d_CartesianPoint)::DownCast(p->Copy());
120
}
121

122
Geom2dPoint::Geom2dPoint(const Base::Vector2d& p)
123
{
124
    this->myPoint = new Geom2d_CartesianPoint(p.x,p.y);
125
}
126

127
Geom2dPoint::~Geom2dPoint() = default;
128

129
TopoDS_Shape Geom2dPoint::toShape() const
130
{
131
    Handle(Geom2d_CartesianPoint) c = Handle(Geom2d_CartesianPoint)::DownCast(handle());
132
    gp_Pnt2d xy = c->Pnt2d();
133
    gp_Pnt pnt;
134
    pnt.SetX(xy.X());
135
    pnt.SetY(xy.Y());
136
    BRepBuilderAPI_MakeVertex mkBuilder(pnt);
137
    return mkBuilder.Shape();
138
}
139

140
const Handle(Geom2d_Geometry)& Geom2dPoint::handle() const
141
{
142
    return myPoint;
143
}
144

145
Geometry2d *Geom2dPoint::clone() const
146
{
147
    Geom2dPoint *newPoint = new Geom2dPoint(myPoint);
148
    return newPoint;
149
}
150

151
Base::Vector2d Geom2dPoint::getPoint()const
152
{
153
    return {myPoint->X(),myPoint->Y()};
154
}
155

156
void Geom2dPoint::setPoint(const Base::Vector2d& p)
157
{
158
    this->myPoint->SetCoord(p.x,p.y);
159
}
160

161
unsigned int Geom2dPoint::getMemSize () const
162
{
163
    return sizeof(Geom2d_CartesianPoint);
164
}
165

166
void Geom2dPoint::Save(Base::Writer &writer) const
167
{
168
    // save the attributes of the father class
169
    Geometry2d::Save(writer);
170

171
    Base::Vector2d Point   =  getPoint();
172
    writer.Stream()
173
        << writer.ind()
174
        << "<Geom2dPoint "
175
        << "X=\"" << Point.x << "\" "
176
        << "Y=\"" << Point.y << "\" "
177
        << "/>" << std::endl;
178
}
179

180
void Geom2dPoint::Restore(Base::XMLReader &reader)
181
{
182
    // read the attributes of the father class
183
    Geometry2d::Restore(reader);
184

185
    double X,Y;
186
    // read my Element
187
    reader.readElement("Geom2dPoint");
188
    // get the value of my Attribute
189
    X = reader.getAttributeAsFloat("X");
190
    Y = reader.getAttributeAsFloat("Y");
191

192
    // set the read geometry
193
    setPoint(Base::Vector2d(X,Y));
194
}
195

196
PyObject *Geom2dPoint::getPyObject()
197
{
198
    Handle(Geom2d_CartesianPoint) c = Handle(Geom2d_CartesianPoint)::DownCast(handle());
199
    gp_Pnt2d xy = c->Pnt2d();
200

201
    Py::Tuple tuple(2);
202
    tuple.setItem(0, Py::Float(xy.X()));
203
    tuple.setItem(1, Py::Float(xy.Y()));
204
    return Py::new_reference_to(tuple);
205
}
206

207
// -------------------------------------------------
208

209
TYPESYSTEM_SOURCE_ABSTRACT(Part::Geom2dCurve, Part::Geometry2d)
210

211
Geom2dCurve::Geom2dCurve() = default;
212

213
Geom2dCurve::~Geom2dCurve() = default;
214

215
TopoDS_Shape Geom2dCurve::toShape() const
216
{
217
    Handle(Geom2d_Curve) c = Handle(Geom2d_Curve)::DownCast(handle());
218
    BRepBuilderAPI_MakeEdge2d mkBuilder(c);
219
    return mkBuilder.Shape();
220
}
221

222
bool Geom2dCurve::tangent(double u, gp_Dir2d& dir) const
223
{
224
    Handle(Geom2d_Curve) c = Handle(Geom2d_Curve)::DownCast(handle());
225
    Geom2dLProp_CLProps2d prop(c,u,2,Precision::Confusion());
226
    if (prop.IsTangentDefined()) {
227
        prop.Tangent(dir);
228
        return true;
229
    }
230

231
    return false;
232
}
233

234
Base::Vector2d Geom2dCurve::pointAtParameter(double u) const
235
{
236
    Handle(Geom2d_Curve) c = Handle(Geom2d_Curve)::DownCast(handle());
237
    Geom2dLProp_CLProps2d prop(c,u,0,Precision::Confusion());
238

239
    const gp_Pnt2d &point=prop.Value();
240
    return {point.X(),point.Y()};
241
}
242

243
Base::Vector2d Geom2dCurve::firstDerivativeAtParameter(double u) const
244
{
245
    Handle(Geom2d_Curve) c = Handle(Geom2d_Curve)::DownCast(handle());
246
    Geom2dLProp_CLProps2d prop(c,u,1,Precision::Confusion());
247

248
    const gp_Vec2d &vec=prop.D1();
249
    return {vec.X(),vec.Y()};
250
}
251

252
Base::Vector2d Geom2dCurve::secondDerivativeAtParameter(double u) const
253
{
254
    Handle(Geom2d_Curve) c = Handle(Geom2d_Curve)::DownCast(handle());
255
    Geom2dLProp_CLProps2d prop(c,u,2,Precision::Confusion());
256

257
    const gp_Vec2d &vec=prop.D2();
258
    return {vec.X(),vec.Y()};
259
}
260

261
bool Geom2dCurve::normal(double u, gp_Dir2d& dir) const
262
{
263
    Handle(Geom2d_Curve) c = Handle(Geom2d_Curve)::DownCast(handle());
264
    Geom2dLProp_CLProps2d prop(c,u,2,Precision::Confusion());
265
    if (prop.IsTangentDefined()) {
266
        prop.Normal(dir);
267
        return true;
268
    }
269

270
    return false;
271
}
272

273
bool Geom2dCurve::closestParameter(const Base::Vector2d& point, double &u) const
274
{
275
    Handle(Geom2d_Curve) c = Handle(Geom2d_Curve)::DownCast(handle());
276
    try {
277
        if (!c.IsNull()) {
278
            gp_Pnt2d pnt(point.x,point.y);
279
            Geom2dAPI_ProjectPointOnCurve ppc(pnt, c);
280
            u = ppc.LowerDistanceParameter();
281
            return true;
282
        }
283
    }
284
    catch (Standard_Failure& e) {
285

286
        std::cout << e.GetMessageString() << std::endl;
287
        return false;
288
    }
289

290
    return false;
291
}
292

293
bool Geom2dCurve::closestParameterToBasicCurve(const Base::Vector2d& point, double &u) const
294
{
295
    Handle(Geom2d_Curve) c = Handle(Geom2d_Curve)::DownCast(handle());
296

297
    if (c->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))){
298
        Handle(Geom2d_TrimmedCurve) tc = Handle(Geom2d_TrimmedCurve)::DownCast(handle());
299
        Handle(Geom2d_Curve) bc = tc->BasisCurve();
300
        try {
301
            if (!bc.IsNull()) {
302
                gp_Pnt2d pnt(point.x,point.y);
303
                Geom2dAPI_ProjectPointOnCurve ppc(pnt, bc);
304
                u = ppc.LowerDistanceParameter();
305
                return true;
306
            }
307
        }
308
        catch (Standard_Failure& e) {
309

310
            std::cout << e.GetMessageString() << std::endl;
311
            return false;
312
        }
313

314
        return false;
315

316
    }
317
    else {
318
        return this->closestParameter(point, u);
319
    }
320
}
321

322
// -------------------------------------------------
323

324
TYPESYSTEM_SOURCE(Part::Geom2dBezierCurve, Part::Geom2dCurve)
325

326
Geom2dBezierCurve::Geom2dBezierCurve()
327
{
328
    TColgp_Array1OfPnt2d poles(1,2);
329
    poles(1) = gp_Pnt2d(0.0,0.0);
330
    poles(2) = gp_Pnt2d(0.0,1.0);
331
    Handle(Geom2d_BezierCurve) b = new Geom2d_BezierCurve(poles);
332
    this->myCurve = b;
333
}
334

335
Geom2dBezierCurve::Geom2dBezierCurve(const Handle(Geom2d_BezierCurve)& b)
336
{
337
    this->myCurve = Handle(Geom2d_BezierCurve)::DownCast(b->Copy());
338
}
339

340
Geom2dBezierCurve::~Geom2dBezierCurve() = default;
341

342
void Geom2dBezierCurve::setHandle(const Handle(Geom2d_BezierCurve)& c)
343
{
344
    myCurve = Handle(Geom2d_BezierCurve)::DownCast(c->Copy());
345
}
346

347
const Handle(Geom2d_Geometry)& Geom2dBezierCurve::handle() const
348
{
349
    return myCurve;
350
}
351

352
Geometry2d *Geom2dBezierCurve::clone() const
353
{
354
    Geom2dBezierCurve *newCurve = new Geom2dBezierCurve(myCurve);
355
    return newCurve;
356
}
357

358
unsigned int Geom2dBezierCurve::getMemSize () const
359
{
360
    throw Base::NotImplementedError("Geom2dBezierCurve::getMemSize");
361
}
362

363
void Geom2dBezierCurve::Save(Base::Writer &/*writer*/) const
364
{
365
    throw Base::NotImplementedError("Geom2dBezierCurve::Save");
366
}
367

368
void Geom2dBezierCurve::Restore(Base::XMLReader &/*reader*/)
369
{
370
    throw Base::NotImplementedError("Geom2dBezierCurve::Restore");
371
}
372

373
PyObject *Geom2dBezierCurve::getPyObject()
374
{
375
    return new BezierCurve2dPy(static_cast<Geom2dBezierCurve*>(this->clone()));
376
}
377

378
// -------------------------------------------------
379

380
TYPESYSTEM_SOURCE(Part::Geom2dBSplineCurve, Part::Geom2dCurve)
381

382
Geom2dBSplineCurve::Geom2dBSplineCurve()
383
{
384
    TColgp_Array1OfPnt2d poles(1,2);
385
    poles(1) = gp_Pnt2d(0.0,0.0);
386
    poles(2) = gp_Pnt2d(1.0,0.0);
387

388
    TColStd_Array1OfReal knots(1,2);
389
    knots(1) = 0.0;
390
    knots(2) = 1.0;
391

392
    TColStd_Array1OfInteger mults(1,2);
393
    mults(1) = 2;
394
    mults(2) = 2;
395

396
    this->myCurve = new Geom2d_BSplineCurve(poles, knots, mults, 1);
397
}
398

399
Geom2dBSplineCurve::Geom2dBSplineCurve(const Handle(Geom2d_BSplineCurve)& b)
400
{
401
    this->myCurve = Handle(Geom2d_BSplineCurve)::DownCast(b->Copy());
402
}
403

404
Geom2dBSplineCurve::~Geom2dBSplineCurve() = default;
405

406
void Geom2dBSplineCurve::setHandle(const Handle(Geom2d_BSplineCurve)& c)
407
{
408
    myCurve = Handle(Geom2d_BSplineCurve)::DownCast(c->Copy());
409
}
410

411
const Handle(Geom2d_Geometry)& Geom2dBSplineCurve::handle() const
412
{
413
    return myCurve;
414
}
415

416
Geometry2d *Geom2dBSplineCurve::clone() const
417
{
418
    Geom2dBSplineCurve *newCurve = new Geom2dBSplineCurve(myCurve);
419
    return newCurve;
420
}
421

422
int Geom2dBSplineCurve::countPoles() const
423
{
424
    return myCurve->NbPoles();
425
}
426

427
void Geom2dBSplineCurve::setPole(int index, const Base::Vector2d& pole, double weight)
428
{
429
    try {
430
        gp_Pnt2d pnt(pole.x,pole.y);
431
        if (weight < 0.0)
432
            myCurve->SetPole(index+1,pnt);
433
        else
434
            myCurve->SetPole(index+1,pnt,weight);
435
    }
436
    catch (Standard_Failure& e) {
437

438
        std::cout << e.GetMessageString() << std::endl;
439
    }
440
}
441

442
std::vector<Base::Vector2d> Geom2dBSplineCurve::getPoles() const
443
{
444
    std::vector<Base::Vector2d> poles;
445
    poles.reserve(myCurve->NbPoles());
446
    TColgp_Array1OfPnt2d p(1,myCurve->NbPoles());
447
    myCurve->Poles(p);
448

449
    for (Standard_Integer i=p.Lower(); i<=p.Upper(); i++) {
450
        const gp_Pnt2d& pnt = p(i);
451
        poles.emplace_back(pnt.X(), pnt.Y());
452
    }
453
    return poles;
454
}
455

456
bool Geom2dBSplineCurve::join(const Handle(Geom2d_BSplineCurve)& spline)
457
{
458
    Geom2dConvert_CompCurveToBSplineCurve ccbc(this->myCurve);
459
    if (!ccbc.Add(spline, Precision::Approximation()))
460
        return false;
461
    this->myCurve = ccbc.BSplineCurve();
462
    return true;
463
}
464

465
void Geom2dBSplineCurve::interpolate(const std::vector<gp_Pnt2d>& p,
466
                                     const std::vector<gp_Vec2d>& t)
467
{
468
    if (p.size() < 2)
469
        Standard_ConstructionError::Raise();
470
    if (p.size() != t.size())
471
        Standard_ConstructionError::Raise();
472

473
    double tol3d = Precision::Approximation();
474
    Handle(TColgp_HArray1OfPnt2d) pts = new TColgp_HArray1OfPnt2d(1, p.size());
475
    for (std::size_t i=0; i<p.size(); i++) {
476
        pts->SetValue(i+1, p[i]);
477
    }
478

479
    TColgp_Array1OfVec2d tgs(1, t.size());
480
    Handle(TColStd_HArray1OfBoolean) fgs = new TColStd_HArray1OfBoolean(1, t.size());
481
    for (std::size_t i=0; i<p.size(); i++) {
482
        tgs.SetValue(i+1, t[i]);
483
        fgs->SetValue(i+1, Standard_True);
484
    }
485

486
    Geom2dAPI_Interpolate interpolate(pts, Standard_False, tol3d);
487
    interpolate.Load(tgs, fgs);
488
    interpolate.Perform();
489
    this->myCurve = interpolate.Curve();
490
}
491

492
void Geom2dBSplineCurve::getCardinalSplineTangents(const std::vector<gp_Pnt2d>& p,
493
                                                   const std::vector<double>& c,
494
                                                   std::vector<gp_Vec2d>& t) const
495
{
496
    // https://de.wikipedia.org/wiki/Kubisch_Hermitescher_Spline#Cardinal_Spline
497
    if (p.size() < 2)
498
        Standard_ConstructionError::Raise();
499
    if (p.size() != c.size())
500
        Standard_ConstructionError::Raise();
501

502
    t.resize(p.size());
503
    if (p.size() == 2) {
504
        t[0] = gp_Vec2d(p[0], p[1]);
505
        t[1] = gp_Vec2d(p[0], p[1]);
506
    }
507
    else {
508
        std::size_t e = p.size() - 1;
509

510
        for (std::size_t i = 1; i < e; i++) {
511
            gp_Vec2d v = gp_Vec2d(p[i-1], p[i+1]);
512
            double f = 0.5 * (1-c[i]);
513
            v.Scale(f);
514
            t[i] = v;
515
        }
516

517
        t[0] = t[1];
518
        t[t.size()-1] = t[t.size()-2];
519
    }
520
}
521

522
void Geom2dBSplineCurve::getCardinalSplineTangents(const std::vector<gp_Pnt2d>& p, double c,
523
                                                   std::vector<gp_Vec2d>& t) const
524
{
525
    // https://de.wikipedia.org/wiki/Kubisch_Hermitescher_Spline#Cardinal_Spline
526
    if (p.size() < 2)
527
        Standard_ConstructionError::Raise();
528

529
    t.resize(p.size());
530
    if (p.size() == 2) {
531
        t[0] = gp_Vec2d(p[0], p[1]);
532
        t[1] = gp_Vec2d(p[0], p[1]);
533
    }
534
    else {
535
        std::size_t e = p.size() - 1;
536
        double f = 0.5 * (1-c);
537

538
        for (std::size_t i = 1; i < e; i++) {
539
            gp_Vec2d v = gp_Vec2d(p[i-1], p[i+1]);
540
            v.Scale(f);
541
            t[i] = v;
542
        }
543

544
        t[0] = t[1];
545
        t[t.size()-1] = t[t.size()-2];
546
    }
547
}
548

549
void Geom2dBSplineCurve::makeC1Continuous(double tol)
550
{
551
    Geom2dConvert::C0BSplineToC1BSplineCurve(this->myCurve, tol);
552
}
553

554
std::list<Geometry2d*> Geom2dBSplineCurve::toBiArcs(double /*tolerance*/) const
555
{
556
    Standard_Failure::Raise("Not yet implemented");
557
    return {};
558
}
559

560
unsigned int Geom2dBSplineCurve::getMemSize() const
561
{
562
    throw Base::NotImplementedError("Geom2dBSplineCurve::getMemSize");
563
}
564

565
void Geom2dBSplineCurve::Save(Base::Writer &/*writer*/) const
566
{
567
    throw Base::NotImplementedError("Geom2dBSplineCurve::Save");
568
}
569

570
void Geom2dBSplineCurve::Restore(Base::XMLReader &/*reader*/)
571
{
572
    throw Base::NotImplementedError("Geom2dBSplineCurve::Restore");
573
}
574

575
PyObject *Geom2dBSplineCurve::getPyObject()
576
{
577
    return new BSplineCurve2dPy(static_cast<Geom2dBSplineCurve*>(this->clone()));
578
}
579

580
// -------------------------------------------------
581

582
TYPESYSTEM_SOURCE_ABSTRACT(Part::Geom2dConic, Part::Geom2dCurve)
583

584
Geom2dConic::Geom2dConic() = default;
585

586
Geom2dConic::~Geom2dConic() = default;
587

588
Base::Vector2d Geom2dConic::getLocation() const
589
{
590
    Handle(Geom2d_Conic) conic = Handle(Geom2d_Conic)::DownCast(handle());
591
    const gp_Pnt2d& loc = conic->Location();
592
    return {loc.X(),loc.Y()};
593
}
594

595
void Geom2dConic::setLocation(const Base::Vector2d& Center)
596
{
597
    gp_Pnt2d p1(Center.x,Center.y);
598
    Handle(Geom2d_Conic) conic = Handle(Geom2d_Conic)::DownCast(handle());
599

600
    try {
601
        conic->SetLocation(p1);
602
    }
603
    catch (Standard_Failure& e) {
604
        throw Base::CADKernelError(e.GetMessageString());
605
    }
606
}
607

608
bool Geom2dConic::isReversed() const
609
{
610
    Handle(Geom2d_Conic) conic = Handle(Geom2d_Conic)::DownCast(handle());
611
    gp_Dir2d xdir = conic->XAxis().Direction();
612
    gp_Dir2d ydir = conic->YAxis().Direction();
613

614
    Base::Vector3d xd(xdir.X(), xdir.Y(), 0);
615
    Base::Vector3d yd(ydir.X(), ydir.Y(), 0);
616
    Base::Vector3d zd = xd.Cross(yd);
617
    return zd.z < 0;
618
}
619

620
void Geom2dConic::SaveAxis(Base::Writer& writer, const gp_Ax22d& axis) const
621
{
622
    gp_Pnt2d center = axis.Location();
623
    gp_Dir2d xdir = axis.XDirection();
624
    gp_Dir2d ydir = axis.YDirection();
625
    writer.Stream()
626
        << "CenterX=\"" << center.X() << "\" "
627
        << "CenterY=\"" << center.Y() << "\" "
628
        << "XAxisX=\"" << xdir.X() << "\" "
629
        << "XAxisY=\"" << xdir.Y() << "\" "
630
        << "YAxisX=\"" << ydir.X() << "\" "
631
        << "YAxisY=\"" << ydir.Y() << "\" ";
632
}
633

634
void Geom2dConic::RestoreAxis(Base::XMLReader& reader, gp_Ax22d& axis)
635
{
636
    double CenterX,CenterY,XdirX,XdirY,YdirX,YdirY;
637
    CenterX = reader.getAttributeAsFloat("CenterX");
638
    CenterY = reader.getAttributeAsFloat("CenterY");
639
    XdirX = reader.getAttributeAsFloat("XAxisX");
640
    XdirY = reader.getAttributeAsFloat("XAxisY");
641
    YdirX = reader.getAttributeAsFloat("YAxisX");
642
    YdirY = reader.getAttributeAsFloat("YAxisY");
643

644
    // set the read geometry
645
    gp_Pnt2d p1(CenterX,CenterY);
646
    gp_Dir2d xdir(XdirX,XdirY);
647
    gp_Dir2d ydir(YdirX,YdirY);
648
    axis.SetLocation(p1);
649
    axis.SetXDirection(xdir);
650
    axis.SetYDirection(ydir);
651
}
652

653
// -------------------------------------------------
654

655
TYPESYSTEM_SOURCE_ABSTRACT(Part::Geom2dArcOfConic, Part::Geom2dCurve)
656

657
Geom2dArcOfConic::Geom2dArcOfConic() = default;
658

659
Geom2dArcOfConic::~Geom2dArcOfConic() = default;
660

661
Base::Vector2d Geom2dArcOfConic::getLocation() const
662
{
663
    Handle(Geom2d_TrimmedCurve) curve = Handle(Geom2d_TrimmedCurve)::DownCast(handle());
664
    Handle(Geom2d_Conic) conic = Handle(Geom2d_Conic)::DownCast(curve->BasisCurve());
665
    const gp_Pnt2d& loc = conic->Location();
666
    return {loc.X(),loc.Y()};
667
}
668

669
void Geom2dArcOfConic::setLocation(const Base::Vector2d& Center)
670
{
671
    gp_Pnt2d p1(Center.x,Center.y);
672
    Handle(Geom2d_TrimmedCurve) curve = Handle(Geom2d_TrimmedCurve)::DownCast(handle());
673
    Handle(Geom2d_Conic) conic = Handle(Geom2d_Conic)::DownCast(curve->BasisCurve());
674

675
    try {
676
        conic->SetLocation(p1);
677
    }
678
    catch (Standard_Failure& e) {
679
        throw Base::CADKernelError(e.GetMessageString());
680
    }
681
}
682

683
bool Geom2dArcOfConic::isReversed() const
684
{
685
    Handle(Geom2d_TrimmedCurve) curve = Handle(Geom2d_TrimmedCurve)::DownCast(handle());
686
    Handle(Geom2d_Conic) conic = Handle(Geom2d_Conic)::DownCast(curve->BasisCurve());
687
    gp_Dir2d xdir = conic->XAxis().Direction();
688
    gp_Dir2d ydir = conic->YAxis().Direction();
689

690
    Base::Vector3d xd(xdir.X(), xdir.Y(), 0);
691
    Base::Vector3d yd(ydir.X(), ydir.Y(), 0);
692
    Base::Vector3d zd = xd.Cross(yd);
693
    return zd.z < 0;
694
}
695

696
/*!
697
 * \brief Geom2dArcOfConic::getStartPoint
698
 * \return XY of the arc's starting point.
699
 */
700
Base::Vector2d Geom2dArcOfConic::getStartPoint() const
701
{
702
    Handle(Geom2d_TrimmedCurve) curve = Handle(Geom2d_TrimmedCurve)::DownCast(handle());
703
    gp_Pnt2d pnt = curve->StartPoint();
704
    return {pnt.X(), pnt.Y()};
705
}
706

707
/*!
708
 * \brief Geom2dArcOfConic::getEndPoint
709
 * \return XY of the arc's ending point.
710
 */
711
Base::Vector2d Geom2dArcOfConic::getEndPoint() const
712
{
713
    Handle(Geom2d_TrimmedCurve) curve = Handle(Geom2d_TrimmedCurve)::DownCast(handle());
714
    gp_Pnt2d pnt = curve->EndPoint();
715
    return {pnt.X(), pnt.Y()};
716
}
717

718
/*!
719
 * \brief Geom2dArcOfConic::getRange
720
 * \param u [out] start angle of the arc, in radians.
721
 * \param v [out] end angle of the arc, in radians.
722
 */
723
void Geom2dArcOfConic::getRange(double& u, double& v) const
724
{
725
    Handle(Geom2d_TrimmedCurve) curve = Handle(Geom2d_TrimmedCurve)::DownCast(handle());
726
    u = curve->FirstParameter();
727
    v = curve->LastParameter();
728
}
729

730
/*!
731
 * \brief Geom2dArcOfConic::setRange
732
 * \param u [in] start angle of the arc, in radians.
733
 * \param v [in] end angle of the arc, in radians.
734
 */
735
void Geom2dArcOfConic::setRange(double u, double v)
736
{
737
    try {
738
        Handle(Geom2d_TrimmedCurve) curve = Handle(Geom2d_TrimmedCurve)::DownCast(handle());
739
        curve->SetTrim(u, v);
740
    }
741
    catch (Standard_Failure& e) {
742
        throw Base::CADKernelError(e.GetMessageString());
743
    }
744
}
745

746
void Geom2dArcOfConic::SaveAxis(Base::Writer& writer, const gp_Ax22d& axis, double u, double v) const
747
{
748
    gp_Pnt2d center = axis.Location();
749
    gp_Dir2d xdir = axis.XDirection();
750
    gp_Dir2d ydir = axis.YDirection();
751
    writer.Stream()
752
        << "CenterX=\"" << center.X() << "\" "
753
        << "CenterY=\"" << center.Y() << "\" "
754
        << "XAxisX=\"" << xdir.X() << "\" "
755
        << "XAxisY=\"" << xdir.Y() << "\" "
756
        << "YAxisX=\"" << ydir.X() << "\" "
757
        << "YAxisY=\"" << ydir.Y() << "\" "
758
        << "FirstParameter=\"" << u << "\" "
759
        << "LastParameter=\"" << v << "\" ";
760
}
761

762
void Geom2dArcOfConic::RestoreAxis(Base::XMLReader& reader, gp_Ax22d& axis, double& u, double &v)
763
{
764
    double CenterX,CenterY,XdirX,XdirY,YdirX,YdirY;
765
    CenterX = reader.getAttributeAsFloat("CenterX");
766
    CenterY = reader.getAttributeAsFloat("CenterY");
767
    XdirX = reader.getAttributeAsFloat("XAxisX");
768
    XdirY = reader.getAttributeAsFloat("XAxisY");
769
    YdirX = reader.getAttributeAsFloat("YAxisX");
770
    YdirY = reader.getAttributeAsFloat("YAxisY");
771
    u = reader.getAttributeAsFloat("FirstParameter");
772
    v = reader.getAttributeAsFloat("LastParameter");
773

774
    // set the read geometry
775
    gp_Pnt2d p1(CenterX,CenterY);
776
    gp_Dir2d xdir(XdirX,XdirY);
777
    gp_Dir2d ydir(YdirX,YdirY);
778
    axis.SetLocation(p1);
779
    axis.SetXDirection(xdir);
780
    axis.SetYDirection(ydir);
781
}
782

783
// -------------------------------------------------
784

785
TYPESYSTEM_SOURCE(Part::Geom2dCircle, Part::Geom2dConic)
786

787
Geom2dCircle::Geom2dCircle()
788
{
789
    Handle(Geom2d_Circle) c = new Geom2d_Circle(gp_Circ2d());
790
    this->myCurve = c;
791
}
792

793
Geom2dCircle::Geom2dCircle(const Handle(Geom2d_Circle)& c)
794
{
795
    this->myCurve = Handle(Geom2d_Circle)::DownCast(c->Copy());
796
}
797

798
Geom2dCircle::~Geom2dCircle() = default;
799

800
const Handle(Geom2d_Geometry)& Geom2dCircle::handle() const
801
{
802
    return myCurve;
803
}
804

805
Geometry2d *Geom2dCircle::clone() const
806
{
807
    Geom2dCircle *newCirc = new Geom2dCircle(myCurve);
808
    return newCirc;
809
}
810

811
double Geom2dCircle::getRadius() const
812
{
813
    Handle(Geom2d_Circle) circle = Handle(Geom2d_Circle)::DownCast(handle());
814
    return circle->Radius();
815
}
816

817
void Geom2dCircle::setRadius(double Radius)
818
{
819
    Handle(Geom2d_Circle) circle = Handle(Geom2d_Circle)::DownCast(handle());
820

821
    try {
822
        gp_Circ2d c = circle->Circ2d();
823
        c.SetRadius(Radius);
824
        circle->SetCirc2d(c);
825
    }
826
    catch (Standard_Failure& e) {
827
        throw Base::CADKernelError(e.GetMessageString());
828
    }
829
}
830

831
unsigned int Geom2dCircle::getMemSize () const
832
{
833
    return sizeof(Geom2d_Circle);
834
}
835

836
void Geom2dCircle::Save(Base::Writer& writer) const
837
{
838
    // save the attributes of the father class
839
    Geom2dCurve::Save(writer);
840

841
    Handle(Geom2d_Circle) circle = Handle(Geom2d_Circle)::DownCast(handle());
842
    gp_Circ2d c = circle->Circ2d();
843
    gp_Ax22d axis = c.Axis();
844

845
    writer.Stream()
846
        << writer.ind()
847
        << "<Geom2dCircle ";
848
    SaveAxis(writer, axis);
849
    writer.Stream()
850
        << "Radius=\"" << c.Radius() << "\" "
851
        << "/>" << std::endl;
852
}
853

854
void Geom2dCircle::Restore(Base::XMLReader& reader)
855
{
856
    // read the attributes of the father class
857
    Geom2dCurve::Restore(reader);
858

859
    double Radius;
860
    gp_Ax22d axis;
861
    // read my Element
862
    reader.readElement("Geom2dCircle");
863
    // get the value of my Attribute
864
    RestoreAxis(reader, axis);
865
    Radius = reader.getAttributeAsFloat("Radius");
866

867
    try {
868
        GCE2d_MakeCircle mc(axis, Radius);
869
        if (!mc.IsDone())
870
            throw Base::CADKernelError(gce_ErrorStatusText(mc.Status()));
871

872
        this->myCurve = mc.Value();
873
    }
874
    catch (Standard_Failure& e) {
875
        throw Base::CADKernelError(e.GetMessageString());
876
    }
877
}
878

879
PyObject *Geom2dCircle::getPyObject()
880
{
881
    return new Circle2dPy(static_cast<Geom2dCircle*>(this->clone()));
882
}
883

884
/*
885
Find the centerpoint of a circle drawn through any 3 points:
886

887
Given points p1-3, draw 2 lines: S12 and S23 which each connect two points.  From the
888
midpoint of each line, draw a perpendicular line (S12p/S23p) across the circle.  These
889
lines will cross at the centerpoint.
890

891
Mathematically, line S12 will have a slope of m12 which can be determined.  Therefore,
892
the slope m12p is -1/m12. Line S12p will have an equation of y = m12p*x + b12p.  b12p can
893
be solved for using the midpoint of the line.  This can be done for both lines.  Since
894
both S12p and S23p cross at the centerpoint, solving the two equations together will give
895
the location of the centerpoint.
896
*/
897
Base::Vector2d Geom2dCircle::getCircleCenter (const Base::Vector2d &p1, const Base::Vector2d &p2, const Base::Vector2d &p3)
898
{
899
    Base::Vector2d u = p2-p1;
900
    Base::Vector2d v = p3-p2;
901
    Base::Vector2d w = p1-p3;
902

903
    double uu =  u*u;
904
    double vv =  v*v;
905
    double ww =  w*w;
906

907
    double eps2 = Precision::SquareConfusion();
908
    if (uu < eps2 || vv < eps2 || ww < eps2)
909
        THROWM(Base::ValueError,"Two points are coincident");
910

911
    double uv = -(u*v);
912
    double vw = -(v*w);
913
    double uw = -(u*w);
914

915
    double w0 = (2 * sqrt(abs(uu * ww - uw * uw)) * uw / (uu * ww));
916
    double w1 = (2 * sqrt(abs(uu * vv - uv * uv)) * uv / (uu * vv));
917
    double w2 = (2 * sqrt(abs(vv * ww - vw * vw)) * vw / (vv * ww));
918

919
    double wx = w0 + w1 + w2;
920

921
    if (abs(wx) < Precision::Confusion())
922
        THROWM(Base::ValueError,"Points are collinear");
923

924
    double x = (w0*p1.x + w1*p2.x + w2*p3.x)/wx;
925
    double y = (w0*p1.y + w1*p2.y + w2*p3.y)/wx;
926

927
    return {x, y};
928
}
929

930
// -------------------------------------------------
931

932
TYPESYSTEM_SOURCE(Part::Geom2dArcOfCircle, Part::Geom2dArcOfConic)
933

934
Geom2dArcOfCircle::Geom2dArcOfCircle()
935
{
936
    Handle(Geom2d_Circle) c = new Geom2d_Circle(gp_Circ2d());
937
    this->myCurve = new Geom2d_TrimmedCurve(c, c->FirstParameter(),c->LastParameter());
938
}
939

940
Geom2dArcOfCircle::Geom2dArcOfCircle(const Handle(Geom2d_Circle)& c)
941
{
942
    this->myCurve = new Geom2d_TrimmedCurve(c, c->FirstParameter(),c->LastParameter());
943
}
944

945
Geom2dArcOfCircle::~Geom2dArcOfCircle() = default;
946

947
void Geom2dArcOfCircle::setHandle(const Handle(Geom2d_TrimmedCurve)& c)
948
{
949
    Handle(Geom2d_Circle) basis = Handle(Geom2d_Circle)::DownCast(c->BasisCurve());
950
    if (basis.IsNull())
951
        Standard_Failure::Raise("Basis curve is not a circle");
952
    this->myCurve = Handle(Geom2d_TrimmedCurve)::DownCast(c->Copy());
953
}
954

955
const Handle(Geom2d_Geometry)& Geom2dArcOfCircle::handle() const
956
{
957
    return myCurve;
958
}
959

960
Geometry2d *Geom2dArcOfCircle::clone() const
961
{
962
    Geom2dArcOfCircle* copy = new Geom2dArcOfCircle();
963
    copy->setHandle(this->myCurve);
964
    return copy;
965
}
966

967
double Geom2dArcOfCircle::getRadius() const
968
{
969
    Handle(Geom2d_Circle) circle = Handle(Geom2d_Circle)::DownCast(myCurve->BasisCurve());
970
    return circle->Radius();
971
}
972

973
void Geom2dArcOfCircle::setRadius(double Radius)
974
{
975
    Handle(Geom2d_Circle) circle = Handle(Geom2d_Circle)::DownCast(myCurve->BasisCurve());
976

977
    try {
978
        gp_Circ2d c = circle->Circ2d();
979
        c.SetRadius(Radius);
980
        circle->SetCirc2d(c);
981
    }
982
    catch (Standard_Failure& e) {
983
        throw Base::CADKernelError(e.GetMessageString());
984
    }
985
}
986

987
unsigned int Geom2dArcOfCircle::getMemSize () const
988
{
989
    return sizeof(Geom2d_Circle) + 2 *sizeof(double);
990
}
991

992
void Geom2dArcOfCircle::Save(Base::Writer &writer) const
993
{
994
    // save the attributes of the father class
995
    Geom2dCurve::Save(writer);
996

997
    Handle(Geom2d_Circle) circle = Handle(Geom2d_Circle)::DownCast(this->myCurve->BasisCurve());
998

999
    gp_Circ2d c = circle->Circ2d();
1000
    gp_Ax22d axis = c.Axis();
1001
    double u = this->myCurve->FirstParameter();
1002
    double v = this->myCurve->LastParameter();
1003

1004
    writer.Stream()
1005
        << writer.ind()
1006
        << "<Geom2dArcOfCircle ";
1007
    SaveAxis(writer, axis, u, v);
1008
    writer.Stream()
1009
        << "Radius=\"" << c.Radius() << "\" "
1010
        << "/>" << std::endl;
1011
}
1012

1013
void Geom2dArcOfCircle::Restore(Base::XMLReader &reader)
1014
{
1015
    // read the attributes of the father class
1016
    Geom2dCurve::Restore(reader);
1017

1018
    double Radius,u,v;
1019
    gp_Ax22d axis;
1020
    // read my Element
1021
    reader.readElement("Geom2dArcOfCircle");
1022
    // get the value of my Attribute
1023
    RestoreAxis(reader, axis, u, v);
1024
    Radius = reader.getAttributeAsFloat("Radius");
1025

1026
    try {
1027
        GCE2d_MakeCircle mc(axis, Radius);
1028
        if (!mc.IsDone())
1029
            throw Base::CADKernelError(gce_ErrorStatusText(mc.Status()));
1030
        GCE2d_MakeArcOfCircle ma(mc.Value()->Circ2d(), u, v);
1031
        if (!ma.IsDone())
1032
            throw Base::CADKernelError(gce_ErrorStatusText(ma.Status()));
1033

1034
        Handle(Geom2d_TrimmedCurve) tmpcurve = ma.Value();
1035
        Handle(Geom2d_Circle) tmpcircle = Handle(Geom2d_Circle)::DownCast(tmpcurve->BasisCurve());
1036
        Handle(Geom2d_Circle) circle = Handle(Geom2d_Circle)::DownCast(this->myCurve->BasisCurve());
1037

1038
        circle->SetCirc2d(tmpcircle->Circ2d());
1039
        this->myCurve->SetTrim(tmpcurve->FirstParameter(), tmpcurve->LastParameter());
1040
    }
1041
    catch (Standard_Failure& e) {
1042
        throw Base::CADKernelError(e.GetMessageString());
1043
    }
1044
}
1045

1046
PyObject *Geom2dArcOfCircle::getPyObject()
1047
{
1048
    return new ArcOfCircle2dPy(static_cast<Geom2dArcOfCircle*>(this->clone()));
1049
}
1050

1051
// -------------------------------------------------
1052

1053
TYPESYSTEM_SOURCE(Part::Geom2dEllipse, Part::Geom2dConic)
1054

1055
Geom2dEllipse::Geom2dEllipse()
1056
{
1057
    Handle(Geom2d_Ellipse) e = new Geom2d_Ellipse(gp_Elips2d());
1058
    this->myCurve = e;
1059
}
1060

1061
Geom2dEllipse::Geom2dEllipse(const Handle(Geom2d_Ellipse)& e)
1062
{
1063
    this->myCurve = Handle(Geom2d_Ellipse)::DownCast(e->Copy());
1064
}
1065

1066
Geom2dEllipse::~Geom2dEllipse() = default;
1067

1068
const Handle(Geom2d_Geometry)& Geom2dEllipse::handle() const
1069
{
1070
    return myCurve;
1071
}
1072

1073
Geometry2d *Geom2dEllipse::clone() const
1074
{
1075
    Geom2dEllipse *newEllipse = new Geom2dEllipse(myCurve);
1076
    return newEllipse;
1077
}
1078

1079
double Geom2dEllipse::getMajorRadius() const
1080
{
1081
    Handle(Geom2d_Ellipse) ellipse = Handle(Geom2d_Ellipse)::DownCast(handle());
1082
    return ellipse->MajorRadius();
1083
}
1084

1085
void Geom2dEllipse::setMajorRadius(double Radius)
1086
{
1087
    Handle(Geom2d_Ellipse) ellipse = Handle(Geom2d_Ellipse)::DownCast(handle());
1088

1089
    try {
1090
        ellipse->SetMajorRadius(Radius);
1091
    }
1092
    catch (Standard_Failure& e) {
1093
        throw Base::CADKernelError(e.GetMessageString());
1094
    }
1095
}
1096

1097
double Geom2dEllipse::getMinorRadius() const
1098
{
1099
    Handle(Geom2d_Ellipse) ellipse = Handle(Geom2d_Ellipse)::DownCast(handle());
1100
    return ellipse->MinorRadius();
1101
}
1102

1103
void Geom2dEllipse::setMinorRadius(double Radius)
1104
{
1105
    Handle(Geom2d_Ellipse) ellipse = Handle(Geom2d_Ellipse)::DownCast(handle());
1106

1107
    try {
1108
        ellipse->SetMinorRadius(Radius);
1109
    }
1110
    catch (Standard_Failure& e) {
1111
        throw Base::CADKernelError(e.GetMessageString());
1112
    }
1113
}
1114

1115
/*!
1116
 * \brief Geom2dEllipse::getMajorAxisDir
1117
 * \return the direction vector (unit-length) of major axis of the ellipse. The
1118
 * direction also points to the first focus.
1119
 */
1120
Base::Vector2d Geom2dEllipse::getMajorAxisDir() const
1121
{
1122
    gp_Dir2d xdir = myCurve->XAxis().Direction();
1123
    return {xdir.X(), xdir.Y()};
1124
}
1125

1126
/*!
1127
 * \brief Geom2dEllipse::setMajorAxisDir Rotates the ellipse in its plane, so
1128
 * that its major axis is as close as possible to the provided direction.
1129
 * \param newdir [in] is the new direction. If the vector is small, the
1130
 * orientation of the ellipse will be preserved. If the vector is not small,
1131
 * but its projection onto plane of the ellipse is small, an exception will be
1132
 * thrown.
1133
 */
1134
void Geom2dEllipse::setMajorAxisDir(Base::Vector2d newdir)
1135
{
1136
    if (newdir.Length() < Precision::Confusion())
1137
        return;//zero vector was passed. Keep the old orientation.
1138
    try {
1139
        gp_Elips2d e = myCurve->Elips2d();
1140
        gp_Ax22d pos = e.Axis();
1141
        pos.SetXDirection(gp_Dir2d(newdir.x, newdir.y));
1142
        e.SetAxis(pos);
1143
        myCurve->SetElips2d(e);
1144
    }
1145
    catch (Standard_Failure& e) {
1146
        throw Base::CADKernelError(e.GetMessageString());
1147
    }
1148
}
1149

1150
unsigned int Geom2dEllipse::getMemSize () const
1151
{
1152
    return sizeof(Geom2d_Ellipse);
1153
}
1154

1155
void Geom2dEllipse::Save(Base::Writer& writer) const
1156
{
1157
    // save the attributes of the father class
1158
    Geom2dCurve::Save(writer);
1159

1160
    gp_Elips2d e = this->myCurve->Elips2d();
1161
    gp_Ax22d axis = e.Axis();
1162

1163
    writer.Stream()
1164
        << writer.ind()
1165
        << "<Geom2dEllipse ";
1166
    SaveAxis(writer, axis);
1167
    writer.Stream()
1168
        << "MajorRadius=\"" << e.MajorRadius() << "\" "
1169
        << "MinorRadius=\"" << e.MinorRadius() << "\" "
1170
        << "/>" << std::endl;
1171
}
1172

1173
void Geom2dEllipse::Restore(Base::XMLReader& reader)
1174
{
1175
    // read the attributes of the father class
1176
    Geom2dCurve::Restore(reader);
1177

1178
    double MajorRadius,MinorRadius;
1179
    gp_Ax22d axis;
1180
    // read my Element
1181
    reader.readElement("Geom2dEllipse");
1182
    // get the value of my Attribute
1183
    RestoreAxis(reader, axis);
1184
    MajorRadius = reader.getAttributeAsFloat("MajorRadius");
1185
    MinorRadius = reader.getAttributeAsFloat("MinorRadius");
1186

1187
    try {
1188
        GCE2d_MakeEllipse mc(axis, MajorRadius, MinorRadius);
1189
        if (!mc.IsDone())
1190
            throw Base::CADKernelError(gce_ErrorStatusText(mc.Status()));
1191

1192
        this->myCurve = mc.Value();
1193
    }
1194
    catch (Standard_Failure& e) {
1195
        throw Base::CADKernelError(e.GetMessageString());
1196
    }
1197
}
1198

1199
PyObject *Geom2dEllipse::getPyObject()
1200
{
1201
    return new Ellipse2dPy(static_cast<Geom2dEllipse*>(this->clone()));
1202
}
1203

1204
void Geom2dEllipse::setHandle(const Handle(Geom2d_Ellipse) &e)
1205
{
1206
    this->myCurve = Handle(Geom2d_Ellipse)::DownCast(e->Copy());
1207
}
1208

1209
// -------------------------------------------------
1210

1211
TYPESYSTEM_SOURCE(Part::Geom2dArcOfEllipse, Part::Geom2dArcOfConic)
1212

1213
Geom2dArcOfEllipse::Geom2dArcOfEllipse()
1214
{
1215
    Handle(Geom2d_Ellipse) e = new Geom2d_Ellipse(gp_Elips2d());
1216
    this->myCurve = new Geom2d_TrimmedCurve(e, e->FirstParameter(),e->LastParameter());
1217
}
1218

1219
Geom2dArcOfEllipse::Geom2dArcOfEllipse(const Handle(Geom2d_Ellipse)& e)
1220
{
1221
    this->myCurve = new Geom2d_TrimmedCurve(e, e->FirstParameter(),e->LastParameter());
1222
}
1223

1224
Geom2dArcOfEllipse::~Geom2dArcOfEllipse() = default;
1225

1226
void Geom2dArcOfEllipse::setHandle(const Handle(Geom2d_TrimmedCurve)& c)
1227
{
1228
    Handle(Geom2d_Ellipse) basis = Handle(Geom2d_Ellipse)::DownCast(c->BasisCurve());
1229
    if (basis.IsNull())
1230
        Standard_Failure::Raise("Basis curve is not an ellipse");
1231
    this->myCurve = Handle(Geom2d_TrimmedCurve)::DownCast(c->Copy());
1232
}
1233

1234
const Handle(Geom2d_Geometry)& Geom2dArcOfEllipse::handle() const
1235
{
1236
    return myCurve;
1237
}
1238

1239
Geometry2d *Geom2dArcOfEllipse::clone() const
1240
{
1241
    Geom2dArcOfEllipse* copy = new Geom2dArcOfEllipse();
1242
    copy->setHandle(this->myCurve);
1243
    return copy;
1244
}
1245

1246
double Geom2dArcOfEllipse::getMajorRadius() const
1247
{
1248
    Handle(Geom2d_Ellipse) ellipse = Handle(Geom2d_Ellipse)::DownCast(myCurve->BasisCurve());
1249
    return ellipse->MajorRadius();
1250
}
1251

1252
void Geom2dArcOfEllipse::setMajorRadius(double Radius)
1253
{
1254
    Handle(Geom2d_Ellipse) ellipse = Handle(Geom2d_Ellipse)::DownCast(myCurve->BasisCurve());
1255

1256
    try {
1257
        ellipse->SetMajorRadius(Radius);
1258
    }
1259
    catch (Standard_Failure& e) {
1260
        throw Base::CADKernelError(e.GetMessageString());
1261
    }
1262
}
1263

1264
double Geom2dArcOfEllipse::getMinorRadius() const
1265
{
1266
    Handle(Geom2d_Ellipse) ellipse = Handle(Geom2d_Ellipse)::DownCast(myCurve->BasisCurve());
1267
    return ellipse->MinorRadius();
1268
}
1269

1270
void Geom2dArcOfEllipse::setMinorRadius(double Radius)
1271
{
1272
    Handle(Geom2d_Ellipse) ellipse = Handle(Geom2d_Ellipse)::DownCast(myCurve->BasisCurve());
1273

1274
    try {
1275
        ellipse->SetMinorRadius(Radius);
1276
    }
1277
    catch (Standard_Failure& e) {
1278
        throw Base::CADKernelError(e.GetMessageString());
1279
    }
1280
}
1281

1282
/*!
1283
 * \brief Geom2dArcOfEllipse::getMajorAxisDir
1284
 * \return the direction vector (unit-length) of major axis of the ellipse. The
1285
 * direction also points to the first focus.
1286
 */
1287
Base::Vector2d Geom2dArcOfEllipse::getMajorAxisDir() const
1288
{
1289
    Handle(Geom2d_Ellipse) c = Handle(Geom2d_Ellipse)::DownCast(myCurve->BasisCurve());
1290
    assert(!c.IsNull());
1291
    gp_Dir2d xdir = c->XAxis().Direction();
1292
    return {xdir.X(), xdir.Y()};
1293
}
1294

1295
/*!
1296
 * \brief Geom2dArcOfEllipse::setMajorAxisDir Rotates the ellipse in its plane, so
1297
 * that its major axis is as close as possible to the provided direction.
1298
 * \param newdir [in] is the new direction. If the vector is small, the
1299
 * orientation of the ellipse will be preserved. If the vector is not small,
1300
 * but its projection onto plane of the ellipse is small, an exception will be
1301
 * thrown.
1302
 */
1303
void Geom2dArcOfEllipse::setMajorAxisDir(Base::Vector2d newdir)
1304
{
1305
    Handle(Geom2d_Ellipse) c = Handle(Geom2d_Ellipse)::DownCast(myCurve->BasisCurve());
1306
    assert(!c.IsNull());
1307
    if (newdir.Length() < Precision::Confusion())
1308
        return;//zero vector was passed. Keep the old orientation.
1309
    try {
1310
        gp_Elips2d e = c->Elips2d();
1311
        gp_Ax22d pos = e.Axis();
1312
        pos.SetXDirection(gp_Dir2d(newdir.x, newdir.y));
1313
        e.SetAxis(pos);
1314
        c->SetElips2d(e);
1315
    }
1316
    catch (Standard_Failure& e) {
1317
        throw Base::CADKernelError(e.GetMessageString());
1318
    }
1319
}
1320

1321
unsigned int Geom2dArcOfEllipse::getMemSize () const
1322
{
1323
    return sizeof(Geom2d_Ellipse) + 2 *sizeof(double);
1324
}
1325

1326
void Geom2dArcOfEllipse::Save(Base::Writer &writer) const
1327
{
1328
    // save the attributes of the father class
1329
    Geom2dCurve::Save(writer);
1330

1331
    Handle(Geom2d_Ellipse) ellipse = Handle(Geom2d_Ellipse)::DownCast(this->myCurve->BasisCurve());
1332

1333
    gp_Elips2d e = ellipse->Elips2d();
1334
    gp_Ax22d axis = e.Axis();
1335
    double u = this->myCurve->FirstParameter();
1336
    double v = this->myCurve->LastParameter();
1337

1338
    writer.Stream()
1339
        << writer.ind()
1340
        << "<Geom2dArcOfEllipse ";
1341
    SaveAxis(writer, axis, u, v);
1342
    writer.Stream()
1343
        << "MajorRadius=\"" << e.MajorRadius() << "\" "
1344
        << "MinorRadius=\"" << e.MinorRadius() << "\" "
1345
        << "/>" << std::endl;
1346
}
1347

1348
void Geom2dArcOfEllipse::Restore(Base::XMLReader &reader)
1349
{
1350
    // read the attributes of the father class
1351
    Geom2dCurve::Restore(reader);
1352

1353
    double MajorRadius,MinorRadius,u,v;
1354
    gp_Ax22d axis;
1355
    // read my Element
1356
    reader.readElement("Geom2dArcOfEllipse");
1357
    // get the value of my Attribute
1358
    RestoreAxis(reader, axis, u, v);
1359
    MajorRadius = reader.getAttributeAsFloat("MajorRadius");
1360
    MinorRadius = reader.getAttributeAsFloat("MinorRadius");
1361

1362
    try {
1363
        GCE2d_MakeEllipse mc(axis, MajorRadius, MinorRadius);
1364
        if (!mc.IsDone())
1365
            throw Base::CADKernelError(gce_ErrorStatusText(mc.Status()));
1366

1367
        GCE2d_MakeArcOfEllipse ma(mc.Value()->Elips2d(), u, v);
1368
        if (!ma.IsDone())
1369
            throw Base::CADKernelError(gce_ErrorStatusText(ma.Status()));
1370

1371
        Handle(Geom2d_TrimmedCurve) tmpcurve = ma.Value();
1372
        Handle(Geom2d_Ellipse) tmpellipse = Handle(Geom2d_Ellipse)::DownCast(tmpcurve->BasisCurve());
1373
        Handle(Geom2d_Ellipse) ellipse = Handle(Geom2d_Ellipse)::DownCast(this->myCurve->BasisCurve());
1374

1375
        ellipse->SetElips2d(tmpellipse->Elips2d());
1376
        this->myCurve->SetTrim(tmpcurve->FirstParameter(), tmpcurve->LastParameter());
1377
    }
1378
    catch (Standard_Failure& e) {
1379
        throw Base::CADKernelError(e.GetMessageString());
1380
    }
1381
}
1382

1383
PyObject *Geom2dArcOfEllipse::getPyObject()
1384
{
1385
    return new ArcOfEllipse2dPy(static_cast<Geom2dArcOfEllipse*>(this->clone()));
1386
}
1387

1388
// -------------------------------------------------
1389

1390
TYPESYSTEM_SOURCE(Part::Geom2dHyperbola, Part::Geom2dConic)
1391

1392
Geom2dHyperbola::Geom2dHyperbola()
1393
{
1394
    Handle(Geom2d_Hyperbola) h = new Geom2d_Hyperbola(gp_Hypr2d());
1395
    this->myCurve = h;
1396
}
1397

1398
Geom2dHyperbola::Geom2dHyperbola(const Handle(Geom2d_Hyperbola)& h)
1399
{
1400
    this->myCurve = Handle(Geom2d_Hyperbola)::DownCast(h->Copy());
1401
}
1402

1403
Geom2dHyperbola::~Geom2dHyperbola() = default;
1404

1405
const Handle(Geom2d_Geometry)& Geom2dHyperbola::handle() const
1406
{
1407
    return myCurve;
1408
}
1409

1410
Geometry2d *Geom2dHyperbola::clone() const
1411
{
1412
    Geom2dHyperbola *newHyp = new Geom2dHyperbola(myCurve);
1413
    return newHyp;
1414
}
1415

1416
double Geom2dHyperbola::getMajorRadius() const
1417
{
1418
    Handle(Geom2d_Hyperbola) h = Handle(Geom2d_Hyperbola)::DownCast(handle());
1419
    return h->MajorRadius();
1420
}
1421

1422
void Geom2dHyperbola::setMajorRadius(double Radius)
1423
{
1424
    Handle(Geom2d_Hyperbola) h = Handle(Geom2d_Hyperbola)::DownCast(handle());
1425

1426
    try {
1427
        h->SetMajorRadius(Radius);
1428
    }
1429
    catch (Standard_Failure& e) {
1430
        throw Base::CADKernelError(e.GetMessageString());
1431
    }
1432
}
1433

1434
double Geom2dHyperbola::getMinorRadius() const
1435
{
1436
    Handle(Geom2d_Hyperbola) h = Handle(Geom2d_Hyperbola)::DownCast(handle());
1437
    return h->MinorRadius();
1438
}
1439

1440
void Geom2dHyperbola::setMinorRadius(double Radius)
1441
{
1442
    Handle(Geom2d_Hyperbola) h = Handle(Geom2d_Hyperbola)::DownCast(handle());
1443

1444
    try {
1445
        h->SetMinorRadius(Radius);
1446
    }
1447
    catch (Standard_Failure& e) {
1448
        throw Base::CADKernelError(e.GetMessageString());
1449
    }
1450
}
1451

1452
unsigned int Geom2dHyperbola::getMemSize () const
1453
{
1454
    return sizeof(Geom2d_Hyperbola);
1455
}
1456

1457
void Geom2dHyperbola::Save(Base::Writer& writer) const
1458
{
1459
    // save the attributes of the father class
1460
    Geom2dCurve::Save(writer);
1461

1462
    gp_Hypr2d h = this->myCurve->Hypr2d();
1463
    gp_Ax22d axis = h.Axis();
1464

1465
    writer.Stream()
1466
        << writer.ind()
1467
        << "<Geom2dHyperbola ";
1468
    SaveAxis(writer, axis);
1469
    writer.Stream()
1470
        << "MajorRadius=\"" <<  h.MajorRadius() << "\" "
1471
        << "MinorRadius=\"" <<  h.MinorRadius() << "\" "
1472
        << "/>" << std::endl;
1473
}
1474

1475
void Geom2dHyperbola::Restore(Base::XMLReader& reader)
1476
{
1477
    // read the attributes of the father class
1478
    Geom2dCurve::Restore(reader);
1479

1480
    double MajorRadius,MinorRadius;
1481
    gp_Ax22d axis;
1482
    // read my Element
1483
    reader.readElement("Geom2dHyperbola");
1484
    // get the value of my Attribute
1485
    RestoreAxis(reader, axis);
1486
    MajorRadius = reader.getAttributeAsFloat("MajorRadius");
1487
    MinorRadius = reader.getAttributeAsFloat("MinorRadius");
1488

1489
    try {
1490
        GCE2d_MakeHyperbola mc(axis, MajorRadius, MinorRadius);
1491
        if (!mc.IsDone())
1492
            throw Base::CADKernelError(gce_ErrorStatusText(mc.Status()));
1493

1494
        this->myCurve = mc.Value();
1495
    }
1496
    catch (Standard_Failure& e) {
1497
        throw Base::CADKernelError(e.GetMessageString());
1498
    }
1499
}
1500

1501
PyObject *Geom2dHyperbola::getPyObject()
1502
{
1503
    return new Hyperbola2dPy(static_cast<Geom2dHyperbola*>(this->clone()));
1504
}
1505

1506
// -------------------------------------------------
1507

1508
TYPESYSTEM_SOURCE(Part::Geom2dArcOfHyperbola, Part::Geom2dArcOfConic)
1509

1510
Geom2dArcOfHyperbola::Geom2dArcOfHyperbola()
1511
{
1512
    Handle(Geom2d_Hyperbola) h = new Geom2d_Hyperbola(gp_Hypr2d());
1513
    this->myCurve = new Geom2d_TrimmedCurve(h, h->FirstParameter(),h->LastParameter());
1514
}
1515

1516
Geom2dArcOfHyperbola::Geom2dArcOfHyperbola(const Handle(Geom2d_Hyperbola)& h)
1517
{
1518
    this->myCurve = new Geom2d_TrimmedCurve(h, h->FirstParameter(),h->LastParameter());
1519
}
1520

1521
Geom2dArcOfHyperbola::~Geom2dArcOfHyperbola() = default;
1522

1523
void Geom2dArcOfHyperbola::setHandle(const Handle(Geom2d_TrimmedCurve)& c)
1524
{
1525
    Handle(Geom2d_Hyperbola) basis = Handle(Geom2d_Hyperbola)::DownCast(c->BasisCurve());
1526
    if (basis.IsNull())
1527
        Standard_Failure::Raise("Basis curve is not an hyperbola");
1528
    this->myCurve = Handle(Geom2d_TrimmedCurve)::DownCast(c->Copy());
1529
}
1530

1531
const Handle(Geom2d_Geometry)& Geom2dArcOfHyperbola::handle() const
1532
{
1533
    return myCurve;
1534
}
1535

1536
Geometry2d *Geom2dArcOfHyperbola::clone() const
1537
{
1538
    Geom2dArcOfHyperbola* copy = new Geom2dArcOfHyperbola();
1539
    copy->setHandle(this->myCurve);
1540
    return copy;
1541
}
1542

1543
double Geom2dArcOfHyperbola::getMajorRadius() const
1544
{
1545
    Handle(Geom2d_Hyperbola) h = Handle(Geom2d_Hyperbola)::DownCast(myCurve->BasisCurve());
1546
    return h->MajorRadius();
1547
}
1548

1549
void Geom2dArcOfHyperbola::setMajorRadius(double Radius)
1550
{
1551
    Handle(Geom2d_Hyperbola) h = Handle(Geom2d_Hyperbola)::DownCast(myCurve->BasisCurve());
1552

1553
    try {
1554
        h->SetMajorRadius(Radius);
1555
    }
1556
    catch (Standard_Failure& e) {
1557
        throw Base::CADKernelError(e.GetMessageString());
1558
    }
1559
}
1560

1561
double Geom2dArcOfHyperbola::getMinorRadius() const
1562
{
1563
    Handle(Geom2d_Hyperbola) h = Handle(Geom2d_Hyperbola)::DownCast(myCurve->BasisCurve());
1564
    return h->MinorRadius();
1565
}
1566

1567
void Geom2dArcOfHyperbola::setMinorRadius(double Radius)
1568
{
1569
    Handle(Geom2d_Hyperbola) h = Handle(Geom2d_Hyperbola)::DownCast(myCurve->BasisCurve());
1570

1571
    try {
1572
        h->SetMinorRadius(Radius);
1573
    }
1574
    catch (Standard_Failure& e) {
1575
        throw Base::CADKernelError(e.GetMessageString());
1576
    }
1577
}
1578

1579
unsigned int Geom2dArcOfHyperbola::getMemSize () const
1580
{
1581
    return sizeof(Geom2d_Hyperbola) + 2 *sizeof(double);
1582
}
1583

1584
void Geom2dArcOfHyperbola::Save(Base::Writer &writer) const
1585
{
1586
    // save the attributes of the father class
1587
    Geom2dCurve::Save(writer);
1588

1589
    Handle(Geom2d_Hyperbola) hh = Handle(Geom2d_Hyperbola)::DownCast(this->myCurve->BasisCurve());
1590

1591
    gp_Hypr2d h = hh->Hypr2d();
1592
    gp_Ax22d axis = h.Axis();
1593
    double u = this->myCurve->FirstParameter();
1594
    double v = this->myCurve->LastParameter();
1595

1596
    writer.Stream()
1597
        << writer.ind()
1598
        << "<Geom2dHyperbola ";
1599
    SaveAxis(writer, axis, u, v);
1600
    writer.Stream()
1601
        << "MajorRadius=\"" <<  h.MajorRadius() << "\" "
1602
        << "MinorRadius=\"" <<  h.MinorRadius() << "\" "
1603
        << "/>" << std::endl;
1604
}
1605

1606
void Geom2dArcOfHyperbola::Restore(Base::XMLReader &reader)
1607
{
1608
    // read the attributes of the father class
1609
    Geom2dCurve::Restore(reader);
1610

1611
    double MajorRadius,MinorRadius,u,v;
1612
    gp_Ax22d axis;
1613
    // read my Element
1614
    reader.readElement("Geom2dHyperbola");
1615
    // get the value of my Attribute
1616
    RestoreAxis(reader, axis, u, v);
1617
    MajorRadius = reader.getAttributeAsFloat("MajorRadius");
1618
    MinorRadius = reader.getAttributeAsFloat("MinorRadius");
1619

1620
    try {
1621
        GCE2d_MakeHyperbola mc(axis, MajorRadius, MinorRadius);
1622
        if (!mc.IsDone())
1623
            throw Base::CADKernelError(gce_ErrorStatusText(mc.Status()));
1624

1625
        GCE2d_MakeArcOfHyperbola ma(mc.Value()->Hypr2d(), u, v);
1626
        if (!ma.IsDone())
1627
            throw Base::CADKernelError(gce_ErrorStatusText(ma.Status()));
1628

1629
        Handle(Geom2d_TrimmedCurve) tmpcurve = ma.Value();
1630
        Handle(Geom2d_Hyperbola) tmphyperbola = Handle(Geom2d_Hyperbola)::DownCast(tmpcurve->BasisCurve());
1631
        Handle(Geom2d_Hyperbola) hyperbola = Handle(Geom2d_Hyperbola)::DownCast(this->myCurve->BasisCurve());
1632

1633
        hyperbola->SetHypr2d(tmphyperbola->Hypr2d());
1634
        this->myCurve->SetTrim(tmpcurve->FirstParameter(), tmpcurve->LastParameter());
1635
    }
1636
    catch (Standard_Failure& e) {
1637
        throw Base::CADKernelError(e.GetMessageString());
1638
    }
1639
}
1640

1641
PyObject *Geom2dArcOfHyperbola::getPyObject()
1642
{
1643
    return new ArcOfHyperbola2dPy(static_cast<Geom2dArcOfHyperbola*>(this->clone()));
1644
}
1645

1646
// -------------------------------------------------
1647

1648
TYPESYSTEM_SOURCE(Part::Geom2dParabola, Part::Geom2dConic)
1649

1650
Geom2dParabola::Geom2dParabola()
1651
{
1652
    Handle(Geom2d_Parabola) p = new Geom2d_Parabola(gp_Parab2d());
1653
    this->myCurve = p;
1654
}
1655

1656
Geom2dParabola::Geom2dParabola(const Handle(Geom2d_Parabola)& p)
1657
{
1658
    this->myCurve = Handle(Geom2d_Parabola)::DownCast(p->Copy());
1659
}
1660

1661
Geom2dParabola::~Geom2dParabola() = default;
1662

1663
const Handle(Geom2d_Geometry)& Geom2dParabola::handle() const
1664
{
1665
    return myCurve;
1666
}
1667

1668
Geometry2d *Geom2dParabola::clone() const
1669
{
1670
    Geom2dParabola *newPar = new Geom2dParabola(myCurve);
1671
    return newPar;
1672
}
1673

1674
double Geom2dParabola::getFocal() const
1675
{
1676
    Handle(Geom2d_Parabola) p = Handle(Geom2d_Parabola)::DownCast(handle());
1677
    return p->Focal();
1678
}
1679

1680
void Geom2dParabola::setFocal(double length)
1681
{
1682
    Handle(Geom2d_Parabola) p = Handle(Geom2d_Parabola)::DownCast(handle());
1683

1684
    try {
1685
        p->SetFocal(length);
1686
    }
1687
    catch (Standard_Failure& e) {
1688
        throw Base::CADKernelError(e.GetMessageString());
1689
    }
1690
}
1691

1692
unsigned int Geom2dParabola::getMemSize () const
1693
{
1694
    return sizeof(Geom2d_Parabola);
1695
}
1696

1697
void Geom2dParabola::Save(Base::Writer& writer) const
1698
{
1699
    // save the attributes of the father class
1700
    Geom2dCurve::Save(writer);
1701

1702
    gp_Parab2d p = this->myCurve->Parab2d();
1703
    gp_Ax22d axis = p.Axis();
1704
    double focal = p.Focal();
1705

1706
    writer.Stream()
1707
        << writer.ind()
1708
        << "<Geom2dParabola ";
1709
    SaveAxis(writer, axis);
1710
    writer.Stream()
1711
        << "Focal=\"" << focal << "\" "
1712
        << "/>" << std::endl;
1713
}
1714

1715
void Geom2dParabola::Restore(Base::XMLReader& reader)
1716
{
1717
    // read the attributes of the father class
1718
    Geom2dCurve::Restore(reader);
1719

1720
    double Focal;
1721
    // read my Element
1722
    reader.readElement("Geom2dParabola");
1723
    gp_Ax22d axis;
1724
    // get the value of my Attribute
1725
    RestoreAxis(reader, axis);
1726
    Focal = reader.getAttributeAsFloat("Focal");
1727

1728
    try {
1729
        GCE2d_MakeParabola mc(axis, Focal);
1730
        if (!mc.IsDone())
1731
            throw Base::CADKernelError(gce_ErrorStatusText(mc.Status()));
1732

1733
        this->myCurve = mc.Value();
1734
    }
1735
    catch (Standard_Failure& e) {
1736
        throw Base::CADKernelError(e.GetMessageString());
1737
    }
1738
}
1739

1740
PyObject *Geom2dParabola::getPyObject()
1741
{
1742
    return new Parabola2dPy(static_cast<Geom2dParabola*>(this->clone()));
1743
}
1744

1745
// -------------------------------------------------
1746

1747
TYPESYSTEM_SOURCE(Part::Geom2dArcOfParabola, Part::Geom2dArcOfConic)
1748

1749
Geom2dArcOfParabola::Geom2dArcOfParabola()
1750
{
1751
    Handle(Geom2d_Parabola) p = new Geom2d_Parabola(gp_Parab2d());
1752
    this->myCurve = new Geom2d_TrimmedCurve(p, p->FirstParameter(),p->LastParameter());
1753
}
1754

1755
Geom2dArcOfParabola::Geom2dArcOfParabola(const Handle(Geom2d_Parabola)& h)
1756
{
1757
    this->myCurve = new Geom2d_TrimmedCurve(h, h->FirstParameter(),h->LastParameter());
1758
}
1759

1760
Geom2dArcOfParabola::~Geom2dArcOfParabola() = default;
1761

1762
void Geom2dArcOfParabola::setHandle(const Handle(Geom2d_TrimmedCurve)& c)
1763
{
1764
    Handle(Geom2d_Parabola) basis = Handle(Geom2d_Parabola)::DownCast(c->BasisCurve());
1765
    if (basis.IsNull())
1766
        Standard_Failure::Raise("Basis curve is not a parabola");
1767
    this->myCurve = Handle(Geom2d_TrimmedCurve)::DownCast(c->Copy());
1768
}
1769

1770
const Handle(Geom2d_Geometry)& Geom2dArcOfParabola::handle() const
1771
{
1772
    return myCurve;
1773
}
1774

1775
Geometry2d *Geom2dArcOfParabola::clone() const
1776
{
1777
    Geom2dArcOfParabola* copy = new Geom2dArcOfParabola();
1778
    copy->setHandle(this->myCurve);
1779
    return copy;
1780
}
1781

1782
double Geom2dArcOfParabola::getFocal() const
1783
{
1784
    Handle(Geom2d_Parabola) p = Handle(Geom2d_Parabola)::DownCast(myCurve->BasisCurve());
1785
    return p->Focal();
1786
}
1787

1788
void Geom2dArcOfParabola::setFocal(double length)
1789
{
1790
    Handle(Geom2d_Parabola) p = Handle(Geom2d_Parabola)::DownCast(myCurve->BasisCurve());
1791

1792
    try {
1793
        p->SetFocal(length);
1794
    }
1795
    catch (Standard_Failure& e) {
1796
        throw Base::CADKernelError(e.GetMessageString());
1797
    }
1798
}
1799

1800
unsigned int Geom2dArcOfParabola::getMemSize () const
1801
{
1802
    return sizeof(Geom2d_Parabola) + 2 *sizeof(double);
1803
}
1804

1805
void Geom2dArcOfParabola::Save(Base::Writer &writer) const
1806
{
1807
    // save the attributes of the father class
1808
    Geom2dCurve::Save(writer);
1809

1810
    Handle(Geom2d_Parabola) hp = Handle(Geom2d_Parabola)::DownCast(this->myCurve->BasisCurve());
1811
    gp_Parab2d p = hp->Parab2d();
1812
    gp_Ax22d axis = p.Axis();
1813
    double u = this->myCurve->FirstParameter();
1814
    double v = this->myCurve->LastParameter();
1815
    double focal = p.Focal();
1816

1817
    writer.Stream()
1818
        << writer.ind()
1819
        << "<Geom2dArcOfParabola ";
1820
    SaveAxis(writer, axis, u, v);
1821
    writer.Stream()
1822
        << "Focal=\"" << focal << "\" "
1823
        << "/>" << std::endl;
1824
}
1825

1826
void Geom2dArcOfParabola::Restore(Base::XMLReader &reader)
1827
{
1828
    // read the attributes of the father class
1829
    Geom2dCurve::Restore(reader);
1830

1831
    double Focal,u,v;
1832
    gp_Ax22d axis;
1833
    // read my Element
1834
    reader.readElement("Geom2dParabola");
1835
    // get the value of my Attribute
1836
    RestoreAxis(reader, axis, u, v);
1837
    Focal = reader.getAttributeAsFloat("Focal");
1838

1839
    try {
1840
        GCE2d_MakeParabola mc(axis, Focal);
1841
        if (!mc.IsDone())
1842
            throw Base::CADKernelError(gce_ErrorStatusText(mc.Status()));
1843

1844
        GCE2d_MakeArcOfParabola ma(mc.Value()->Parab2d(), u, v);
1845
        if (!ma.IsDone())
1846
            throw Base::CADKernelError(gce_ErrorStatusText(ma.Status()));
1847

1848
        Handle(Geom2d_TrimmedCurve) tmpcurve = ma.Value();
1849
        Handle(Geom2d_Parabola) tmpparabola = Handle(Geom2d_Parabola)::DownCast(tmpcurve->BasisCurve());
1850
        Handle(Geom2d_Parabola) parabola = Handle(Geom2d_Parabola)::DownCast(this->myCurve->BasisCurve());
1851

1852
        parabola->SetParab2d(tmpparabola->Parab2d());
1853
        this->myCurve->SetTrim(tmpcurve->FirstParameter(), tmpcurve->LastParameter());
1854
    }
1855
    catch (Standard_Failure& e) {
1856
        throw Base::CADKernelError(e.GetMessageString());
1857
    }
1858
}
1859

1860
PyObject *Geom2dArcOfParabola::getPyObject()
1861
{
1862
    return new ArcOfParabola2dPy(static_cast<Geom2dArcOfParabola*>(this->clone()));
1863
}
1864

1865
// -------------------------------------------------
1866

1867
TYPESYSTEM_SOURCE(Part::Geom2dLine, Part::Geom2dCurve)
1868

1869
Geom2dLine::Geom2dLine()
1870
{
1871
    Handle(Geom2d_Line) c = new Geom2d_Line(gp_Lin2d());
1872
    this->myCurve = c;
1873
}
1874

1875
Geom2dLine::Geom2dLine(const Handle(Geom2d_Line)& l)
1876
{
1877
    this->myCurve = Handle(Geom2d_Line)::DownCast(l->Copy());
1878
}
1879

1880
Geom2dLine::Geom2dLine(const Base::Vector2d& Pos, const Base::Vector2d& Dir)
1881
{
1882
    this->myCurve = new Geom2d_Line(gp_Pnt2d(Pos.x,Pos.y),gp_Dir2d(Dir.x,Dir.y));
1883
}
1884

1885
Geom2dLine::~Geom2dLine() = default;
1886

1887
void Geom2dLine::setLine(const Base::Vector2d& Pos, const Base::Vector2d& Dir)
1888
{
1889
    this->myCurve->SetLocation(gp_Pnt2d(Pos.x,Pos.y));
1890
    this->myCurve->SetDirection(gp_Dir2d(Dir.x,Dir.y));
1891
}
1892

1893
Base::Vector2d Geom2dLine::getPos() const
1894
{
1895
    gp_Pnt2d Pos = this->myCurve->Lin2d().Location();
1896
    return {Pos.X(),Pos.Y()};
1897
}
1898

1899
Base::Vector2d Geom2dLine::getDir() const
1900
{
1901
    gp_Dir2d Dir = this->myCurve->Lin2d().Direction();
1902
    return {Dir.X(),Dir.Y()};
1903
}
1904

1905
const Handle(Geom2d_Geometry)& Geom2dLine::handle() const
1906
{
1907
    return myCurve;
1908
}
1909

1910
Geometry2d *Geom2dLine::clone() const
1911
{
1912
    Geom2dLine *newLine = new Geom2dLine(myCurve);
1913
    return newLine;
1914
}
1915

1916
unsigned int Geom2dLine::getMemSize () const
1917
{
1918
    return sizeof(Geom2d_Line);
1919
}
1920

1921
void Geom2dLine::Save(Base::Writer &writer) const
1922
{
1923
    // save the attributes of the father class
1924
    Geometry2d::Save(writer);
1925

1926
    Base::Vector2d Pos = getPos();
1927
    Base::Vector2d Dir = getDir();
1928

1929
    writer.Stream()
1930
        << writer.ind()
1931
        << "<Geom2dLine "
1932
        << "PosX=\"" << Pos.x << "\" "
1933
        << "PosY=\"" << Pos.y << "\" "
1934
        << "DirX=\"" << Dir.x << "\" "
1935
        << "DirY=\"" << Dir.y << "\" "
1936
        << "/>" << std::endl;
1937
}
1938

1939
void Geom2dLine::Restore(Base::XMLReader &reader)
1940
{
1941
    // read the attributes of the father class
1942
    Geom2dCurve::Restore(reader);
1943

1944
    double PosX,PosY,DirX,DirY;
1945
    // read my Element
1946
    reader.readElement("Geom2dLine");
1947
    // get the value of my Attribute
1948
    PosX = reader.getAttributeAsFloat("PosX");
1949
    PosY = reader.getAttributeAsFloat("PosY");
1950
    DirX = reader.getAttributeAsFloat("DirX");
1951
    DirY = reader.getAttributeAsFloat("DirY");
1952
    gp_Pnt2d pnt(PosX, PosY);
1953
    gp_Dir2d dir(DirX, DirY);
1954

1955
    try {
1956
        GCE2d_MakeLine mc(pnt, dir);
1957
        if (!mc.IsDone())
1958
            throw Base::CADKernelError(gce_ErrorStatusText(mc.Status()));
1959

1960
        this->myCurve = mc.Value();
1961
    }
1962
    catch (Standard_Failure& e) {
1963
        throw Base::CADKernelError(e.GetMessageString());
1964
    }
1965
}
1966

1967
PyObject *Geom2dLine::getPyObject()
1968
{
1969
    return new Line2dPy(static_cast<Geom2dLine*>(this->clone()));
1970
}
1971

1972
// -------------------------------------------------
1973

1974
TYPESYSTEM_SOURCE(Part::Geom2dLineSegment, Part::Geom2dCurve)
1975

1976
Geom2dLineSegment::Geom2dLineSegment()
1977
{
1978
    gp_Lin2d line;
1979
    line.SetLocation(gp_Pnt2d(0.0,0.0));
1980
    line.SetDirection(gp_Dir2d(0.0,1.0));
1981
    Handle(Geom2d_Line) c = new Geom2d_Line(line);
1982
    this->myCurve = new Geom2d_TrimmedCurve(c, 0.0,1.0);
1983
}
1984

1985
Geom2dLineSegment::~Geom2dLineSegment() = default;
1986

1987
void Geom2dLineSegment::setHandle(const Handle(Geom2d_TrimmedCurve)& c)
1988
{
1989
    Handle(Geom2d_Line) basis = Handle(Geom2d_Line)::DownCast(c->BasisCurve());
1990
    if (basis.IsNull())
1991
        Standard_Failure::Raise("Basis curve is not a line");
1992
    this->myCurve = Handle(Geom2d_TrimmedCurve)::DownCast(c->Copy());
1993
}
1994

1995
const Handle(Geom2d_Geometry)& Geom2dLineSegment::handle() const
1996
{
1997
    return myCurve;
1998
}
1999

2000
Geometry2d *Geom2dLineSegment::clone()const
2001
{
2002
    Geom2dLineSegment *tempCurve = new Geom2dLineSegment();
2003
    tempCurve->myCurve = Handle(Geom2d_TrimmedCurve)::DownCast(myCurve->Copy());
2004
    return tempCurve;
2005
}
2006

2007
Base::Vector2d Geom2dLineSegment::getStartPoint() const
2008
{
2009
    Handle(Geom2d_TrimmedCurve) this_curve = Handle(Geom2d_TrimmedCurve)::DownCast(handle());
2010
    gp_Pnt2d pnt = this_curve->StartPoint();
2011
    return {pnt.X(), pnt.Y()};
2012
}
2013

2014
Base::Vector2d Geom2dLineSegment::getEndPoint() const
2015
{
2016
    Handle(Geom2d_TrimmedCurve) this_curve = Handle(Geom2d_TrimmedCurve)::DownCast(handle());
2017
    gp_Pnt2d pnt = this_curve->EndPoint();
2018
    return {pnt.X(), pnt.Y()};
2019
}
2020

2021
void Geom2dLineSegment::setPoints(const Base::Vector2d& Start, const Base::Vector2d& End)
2022
{
2023
    gp_Pnt2d p1(Start.x,Start.y), p2(End.x,End.y);
2024
    Handle(Geom2d_TrimmedCurve) this_curv = Handle(Geom2d_TrimmedCurve)::DownCast(handle());
2025

2026
    try {
2027
        // Create line out of two points
2028
        if (p1.Distance(p2) < gp::Resolution())
2029
            Standard_Failure::Raise("Both points are equal");
2030
        GCE2d_MakeSegment ms(p1, p2);
2031
        if (!ms.IsDone()) {
2032
            throw Base::CADKernelError(gce_ErrorStatusText(ms.Status()));
2033
        }
2034

2035
        // get Geom_Line of line segment
2036
        Handle(Geom2d_Line) this_line = Handle(Geom2d_Line)::DownCast
2037
            (this_curv->BasisCurve());
2038
        Handle(Geom2d_TrimmedCurve) that_curv = ms.Value();
2039
        Handle(Geom2d_Line) that_line = Handle(Geom2d_Line)::DownCast(that_curv->BasisCurve());
2040
        this_line->SetLin2d(that_line->Lin2d());
2041
        this_curv->SetTrim(that_curv->FirstParameter(), that_curv->LastParameter());
2042
    }
2043
    catch (Standard_Failure& e) {
2044
        throw Base::CADKernelError(e.GetMessageString());
2045
    }
2046
}
2047

2048
unsigned int Geom2dLineSegment::getMemSize () const
2049
{
2050
    return sizeof(Geom2d_TrimmedCurve) + sizeof(Geom2d_Line);
2051
}
2052

2053
void Geom2dLineSegment::Save(Base::Writer &writer) const
2054
{
2055
    // save the attributes of the father class
2056
    Geom2dCurve::Save(writer);
2057

2058
    Base::Vector2d End   =  getEndPoint();
2059
    Base::Vector2d Start =  getStartPoint();
2060

2061
    writer.Stream()
2062
        << writer.ind()
2063
        << "<Geom2dLineSegment "
2064
        << "StartX=\"" << Start.x << "\" "
2065
        << "StartY=\"" << Start.y << "\" "
2066
        << "EndX=\"" << End.x << "\" "
2067
        << "EndY=\"" << End.y << "\" "
2068
        << "/>" << std::endl;
2069
}
2070

2071
void Geom2dLineSegment::Restore(Base::XMLReader &reader)
2072
{
2073
    // read the attributes of the father class
2074
    Geom2dCurve::Restore(reader);
2075

2076
    double StartX,StartY,EndX,EndY;
2077
    // read my Element
2078
    reader.readElement("Geom2dLineSegment");
2079
    // get the value of my Attribute
2080
    StartX = reader.getAttributeAsFloat("StartX");
2081
    StartY = reader.getAttributeAsFloat("StartY");
2082
    EndX   = reader.getAttributeAsFloat("EndX");
2083
    EndY   = reader.getAttributeAsFloat("EndY");
2084

2085
    gp_Pnt2d p1(StartX, StartY);
2086
    gp_Pnt2d p2(EndX, EndY);
2087

2088
    try {
2089
        GCE2d_MakeSegment mc(p1, p2);
2090
        if (!mc.IsDone())
2091
            throw Base::CADKernelError(gce_ErrorStatusText(mc.Status()));
2092

2093
        this->myCurve = mc.Value();
2094
    }
2095
    catch (Standard_Failure& e) {
2096
        throw Base::CADKernelError(e.GetMessageString());
2097
    }
2098
}
2099

2100
PyObject *Geom2dLineSegment::getPyObject()
2101
{
2102
    return new Line2dSegmentPy(static_cast<Geom2dLineSegment*>(this->clone()));
2103
}
2104

2105
// -------------------------------------------------
2106

2107
TYPESYSTEM_SOURCE(Part::Geom2dOffsetCurve, Part::Geom2dCurve)
2108

2109
Geom2dOffsetCurve::Geom2dOffsetCurve() = default;
2110

2111
Geom2dOffsetCurve::Geom2dOffsetCurve(const Handle(Geom2d_Curve)& c, double offset)
2112
{
2113
    this->myCurve = new Geom2d_OffsetCurve(c, offset);
2114
}
2115

2116
Geom2dOffsetCurve::Geom2dOffsetCurve(const Handle(Geom2d_OffsetCurve)& c)
2117
{
2118
    this->myCurve = Handle(Geom2d_OffsetCurve)::DownCast(c->Copy());
2119
}
2120

2121
Geom2dOffsetCurve::~Geom2dOffsetCurve() = default;
2122

2123
Geometry2d *Geom2dOffsetCurve::clone() const
2124
{
2125
    Geom2dOffsetCurve *newCurve = new Geom2dOffsetCurve(myCurve);
2126
    return newCurve;
2127
}
2128

2129
void Geom2dOffsetCurve::setHandle(const Handle(Geom2d_OffsetCurve)& c)
2130
{
2131
    this->myCurve = Handle(Geom2d_OffsetCurve)::DownCast(c->Copy());
2132
}
2133

2134
const Handle(Geom2d_Geometry)& Geom2dOffsetCurve::handle() const
2135
{
2136
    return this->myCurve;
2137
}
2138

2139
unsigned int Geom2dOffsetCurve::getMemSize () const
2140
{
2141
    throw Base::NotImplementedError("Geom2dOffsetCurve::getMemSize");
2142
}
2143

2144
void Geom2dOffsetCurve::Save(Base::Writer &/*writer*/) const
2145
{
2146
    throw Base::NotImplementedError("Geom2dOffsetCurve::Save");
2147
}
2148

2149
void Geom2dOffsetCurve::Restore(Base::XMLReader &/*reader*/)
2150
{
2151
    throw Base::NotImplementedError("Geom2dOffsetCurve::Restore");
2152
}
2153

2154
PyObject *Geom2dOffsetCurve::getPyObject()
2155
{
2156
    return new OffsetCurve2dPy(static_cast<Geom2dOffsetCurve*>(this->clone()));
2157
}
2158

2159
// -------------------------------------------------
2160

2161
TYPESYSTEM_SOURCE(Part::Geom2dTrimmedCurve, Part::Geom2dCurve)
2162

2163
Geom2dTrimmedCurve::Geom2dTrimmedCurve() = default;
2164

2165
Geom2dTrimmedCurve::Geom2dTrimmedCurve(const Handle(Geom2d_TrimmedCurve)& c)
2166
{
2167
    this->myCurve = Handle(Geom2d_TrimmedCurve)::DownCast(c->Copy());
2168
}
2169

2170
Geom2dTrimmedCurve::~Geom2dTrimmedCurve() = default;
2171

2172
void Geom2dTrimmedCurve::setHandle(const Handle(Geom2d_TrimmedCurve)& c)
2173
{
2174
    this->myCurve = Handle(Geom2d_TrimmedCurve)::DownCast(c->Copy());
2175
}
2176

2177
const Handle(Geom2d_Geometry)& Geom2dTrimmedCurve::handle() const
2178
{
2179
    return myCurve;
2180
}
2181

2182
Geometry2d *Geom2dTrimmedCurve::clone() const
2183
{
2184
    Geom2dTrimmedCurve *newCurve =  new Geom2dTrimmedCurve(myCurve);
2185
    return newCurve;
2186
}
2187

2188
unsigned int Geom2dTrimmedCurve::getMemSize () const
2189
{
2190
    throw Base::NotImplementedError("Geom2dTrimmedCurve::getMemSize");
2191
}
2192

2193
void Geom2dTrimmedCurve::Save(Base::Writer &/*writer*/) const
2194
{
2195
    throw Base::NotImplementedError("Geom2dTrimmedCurve::Save");
2196
}
2197

2198
void Geom2dTrimmedCurve::Restore(Base::XMLReader &/*reader*/)
2199
{
2200
    throw Base::NotImplementedError("Geom2dTrimmedCurve::Restore");
2201
}
2202

2203
PyObject *Geom2dTrimmedCurve::getPyObject()
2204
{
2205
    Handle(Geom2d_Curve) basis = this->myCurve->BasisCurve();
2206
    if (basis.IsNull())
2207
        Py_Return;
2208
    if (basis->IsKind(STANDARD_TYPE (Geom2d_Parabola))) {
2209
        Geom2dArcOfParabola c;
2210
        c.setHandle(this->myCurve);
2211
        return c.getPyObject();
2212
    }
2213
    if (basis->IsKind(STANDARD_TYPE (Geom2d_Hyperbola))) {
2214
        Geom2dArcOfHyperbola c;
2215
        c.setHandle(this->myCurve);
2216
        return c.getPyObject();
2217
    }
2218
    if (basis->IsKind(STANDARD_TYPE (Geom2d_Ellipse))) {
2219
        Geom2dArcOfEllipse c;
2220
        c.setHandle(this->myCurve);
2221
        return c.getPyObject();
2222
    }
2223
    if (basis->IsKind(STANDARD_TYPE (Geom2d_Circle))) {
2224
        Geom2dArcOfCircle c;
2225
        c.setHandle(this->myCurve);
2226
        return c.getPyObject();
2227
    }
2228
    if (basis->IsKind(STANDARD_TYPE (Geom2d_Line))) {
2229
        Geom2dLineSegment c;
2230
        c.setHandle(this->myCurve);
2231
        return c.getPyObject();
2232
    }
2233
    if (basis->IsKind(STANDARD_TYPE (Geom2d_BSplineCurve))) {
2234
        Geom2dBSplineCurve c;
2235
        c.setHandle(Handle(Geom2d_BSplineCurve)::DownCast(basis));
2236
        return c.getPyObject();
2237
    }
2238
    if (basis->IsKind(STANDARD_TYPE (Geom2d_BezierCurve))) {
2239
        Geom2dBezierCurve c;
2240
        c.setHandle(Handle(Geom2d_BezierCurve)::DownCast(basis));
2241
        return c.getPyObject();
2242
    }
2243

2244
    PyErr_SetString(PyExc_RuntimeError, "Unknown curve type");
2245
    return nullptr;
2246
}
2247

2248
// ------------------------------------------------------------------
2249

2250
namespace Part {
2251
std::unique_ptr<Geom2dCurve> makeFromCurve2d(Handle(Geom2d_Curve) curve)
2252
{
2253
    std::unique_ptr<Geom2dCurve> geo2d;
2254
    if (curve.IsNull())
2255
        return geo2d;
2256
    if (curve->IsKind(STANDARD_TYPE (Geom2d_Parabola))) {
2257
        geo2d = std::make_unique<Geom2dParabola>(Handle(Geom2d_Parabola)::DownCast(curve));
2258
    }
2259
    else if (curve->IsKind(STANDARD_TYPE (Geom2d_Hyperbola))) {
2260
        geo2d = std::make_unique<Geom2dHyperbola>(Handle(Geom2d_Hyperbola)::DownCast(curve));
2261
    }
2262
    else if (curve->IsKind(STANDARD_TYPE (Geom2d_Ellipse))) {
2263
        geo2d = std::make_unique<Geom2dEllipse>(Handle(Geom2d_Ellipse)::DownCast(curve));
2264
    }
2265
    else if (curve->IsKind(STANDARD_TYPE (Geom2d_Circle))) {
2266
        geo2d = std::make_unique<Geom2dCircle>(Handle(Geom2d_Circle)::DownCast(curve));
2267
    }
2268
    else if (curve->IsKind(STANDARD_TYPE (Geom2d_Line))) {
2269
        geo2d = std::make_unique<Geom2dLine>(Handle(Geom2d_Line)::DownCast(curve));
2270
    }
2271
    else if (curve->IsKind(STANDARD_TYPE (Geom2d_BSplineCurve))) {
2272
        geo2d = std::make_unique<Geom2dBSplineCurve>(Handle(Geom2d_BSplineCurve)::DownCast(curve));
2273
    }
2274
    else if (curve->IsKind(STANDARD_TYPE (Geom2d_BezierCurve))) {
2275
        geo2d = std::make_unique<Geom2dBezierCurve>(Handle(Geom2d_BezierCurve)::DownCast(curve));
2276
    }
2277
    else if (curve->IsKind(STANDARD_TYPE (Geom2d_TrimmedCurve))) {
2278
        geo2d = std::make_unique<Geom2dTrimmedCurve>(Handle(Geom2d_TrimmedCurve)::DownCast(curve));
2279
    }
2280

2281
    return geo2d;
2282
}
2283

2284
std::unique_ptr<Geom2dCurve> makeFromTrimmedCurve2d(const Handle(Geom2d_Curve)& c, double f, double l)
2285
{
2286
    if (c->IsKind(STANDARD_TYPE(Geom2d_Circle))) {
2287
        Handle(Geom2d_Circle) circ = Handle(Geom2d_Circle)::DownCast(c);
2288
        std::unique_ptr<Geom2dCurve> arc(new Geom2dArcOfCircle());
2289

2290
        Handle(Geom2d_TrimmedCurve) this_arc = Handle(Geom2d_TrimmedCurve)::DownCast
2291
            (arc->handle());
2292
        Handle(Geom2d_Circle) this_circ = Handle(Geom2d_Circle)::DownCast
2293
            (this_arc->BasisCurve());
2294
        this_circ->SetCirc2d(circ->Circ2d());
2295
        this_arc->SetTrim(f, l);
2296
        return arc;
2297
    }
2298
    else if (c->IsKind(STANDARD_TYPE(Geom2d_Ellipse))) {
2299
        Handle(Geom2d_Ellipse) ellp = Handle(Geom2d_Ellipse)::DownCast(c);
2300
        std::unique_ptr<Geom2dCurve> arc(new Geom2dArcOfEllipse());
2301

2302
        Handle(Geom2d_TrimmedCurve) this_arc = Handle(Geom2d_TrimmedCurve)::DownCast
2303
            (arc->handle());
2304
        Handle(Geom2d_Ellipse) this_ellp = Handle(Geom2d_Ellipse)::DownCast
2305
            (this_arc->BasisCurve());
2306
        this_ellp->SetElips2d(ellp->Elips2d());
2307
        this_arc->SetTrim(f, l);
2308
        return arc;
2309
    }
2310
    else if (c->IsKind(STANDARD_TYPE(Geom2d_Hyperbola))) {
2311
        Handle(Geom2d_Hyperbola) hypr = Handle(Geom2d_Hyperbola)::DownCast(c);
2312
        std::unique_ptr<Geom2dCurve> arc(new Geom2dArcOfHyperbola());
2313

2314
        Handle(Geom2d_TrimmedCurve) this_arc = Handle(Geom2d_TrimmedCurve)::DownCast
2315
            (arc->handle());
2316
        Handle(Geom2d_Hyperbola) this_hypr = Handle(Geom2d_Hyperbola)::DownCast
2317
            (this_arc->BasisCurve());
2318
        this_hypr->SetHypr2d(hypr->Hypr2d());
2319
        this_arc->SetTrim(f, l);
2320
        return arc;
2321
    }
2322
    else if (c->IsKind(STANDARD_TYPE(Geom2d_Line))) {
2323
        Handle(Geom2d_Line) line = Handle(Geom2d_Line)::DownCast(c);
2324
        std::unique_ptr<Geom2dCurve> segm(new Geom2dLineSegment());
2325

2326
        Handle(Geom2d_TrimmedCurve) this_segm = Handle(Geom2d_TrimmedCurve)::DownCast
2327
            (segm->handle());
2328
        Handle(Geom2d_Line) this_line = Handle(Geom2d_Line)::DownCast
2329
            (this_segm->BasisCurve());
2330
        this_line->SetLin2d(line->Lin2d());
2331
        this_segm->SetTrim(f, l);
2332
        return segm;
2333
    }
2334
    else if (c->IsKind(STANDARD_TYPE(Geom2d_Parabola))) {
2335
        Handle(Geom2d_Parabola) para = Handle(Geom2d_Parabola)::DownCast(c);
2336
        std::unique_ptr<Geom2dCurve> arc(new Geom2dArcOfParabola());
2337

2338
        Handle(Geom2d_TrimmedCurve) this_arc = Handle(Geom2d_TrimmedCurve)::DownCast
2339
            (arc->handle());
2340
        Handle(Geom2d_Parabola) this_para = Handle(Geom2d_Parabola)::DownCast
2341
            (this_arc->BasisCurve());
2342
        this_para->SetParab2d(para->Parab2d());
2343
        this_arc->SetTrim(f, l);
2344
        return arc;
2345
    }
2346
    else if (c->IsKind(STANDARD_TYPE(Geom2d_BezierCurve))) {
2347
        Handle(Geom2d_BezierCurve) bezier = Handle(Geom2d_BezierCurve)::DownCast(c->Copy());
2348
        bezier->Segment(f, l);
2349
        return std::unique_ptr<Geom2dCurve>(new Geom2dBezierCurve(bezier));
2350
    }
2351
    else if (c->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
2352
        Handle(Geom2d_BSplineCurve) bspline = Handle(Geom2d_BSplineCurve)::DownCast(c->Copy());
2353
        bspline->Segment(f, l);
2354
        return std::unique_ptr<Geom2dCurve>(new Geom2dBSplineCurve(bspline));
2355
    }
2356
    else if (c->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) {
2357
        Handle(Geom2d_OffsetCurve) oc = Handle(Geom2d_OffsetCurve)::DownCast(c);
2358
        double v = oc->Offset();
2359
        std::unique_ptr<Geom2dCurve> bc(makeFromTrimmedCurve2d(oc->BasisCurve(), f, l));
2360
        return std::unique_ptr<Geom2dCurve>(new Geom2dOffsetCurve(Handle(Geom2d_Curve)::DownCast(bc->handle()), v));
2361
    }
2362
    else if (c->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
2363
        Handle(Geom2d_TrimmedCurve) trc = Handle(Geom2d_TrimmedCurve)::DownCast(c);
2364
        return makeFromTrimmedCurve2d(trc->BasisCurve(), f, l);
2365
    }
2366
    else {
2367
        std::string err = "Unhandled curve type ";
2368
        err += c->DynamicType()->Name();
2369
        throw Base::TypeError(err);
2370
    }
2371
}
2372
std::unique_ptr<Geom2dCurve> makeFromCurveAdaptor2d(const Adaptor2d_Curve2d& adapt)
2373
{
2374
    std::unique_ptr<Geom2dCurve> geoCurve;
2375
    switch (adapt.GetType())
2376
    {
2377
    case GeomAbs_Line:
2378
        {
2379
            geoCurve = std::make_unique<Geom2dLine>();
2380
            Handle(Geom2d_Line) this_curv = Handle(Geom2d_Line)::DownCast
2381
                (geoCurve->handle());
2382
            this_curv->SetLin2d(adapt.Line());
2383
            break;
2384
        }
2385
    case GeomAbs_Circle:
2386
        {
2387
            geoCurve = std::make_unique<Geom2dCircle>();
2388
            Handle(Geom2d_Circle) this_curv = Handle(Geom2d_Circle)::DownCast
2389
                (geoCurve->handle());
2390
            this_curv->SetCirc2d(adapt.Circle());
2391
            break;
2392
        }
2393
    case GeomAbs_Ellipse:
2394
        {
2395
            geoCurve = std::make_unique<Geom2dEllipse>();
2396
            Handle(Geom2d_Ellipse) this_curv = Handle(Geom2d_Ellipse)::DownCast
2397
                (geoCurve->handle());
2398
            this_curv->SetElips2d(adapt.Ellipse());
2399
            break;
2400
        }
2401
    case GeomAbs_Hyperbola:
2402
        {
2403
            geoCurve = std::make_unique<Geom2dHyperbola>();
2404
            Handle(Geom2d_Hyperbola) this_curv = Handle(Geom2d_Hyperbola)::DownCast
2405
                (geoCurve->handle());
2406
            this_curv->SetHypr2d(adapt.Hyperbola());
2407
            break;
2408
        }
2409
    case GeomAbs_Parabola:
2410
        {
2411
            geoCurve = std::make_unique<Geom2dParabola>();
2412
            Handle(Geom2d_Parabola) this_curv = Handle(Geom2d_Parabola)::DownCast
2413
                (geoCurve->handle());
2414
            this_curv->SetParab2d(adapt.Parabola());
2415
            break;
2416
        }
2417
    case GeomAbs_BezierCurve:
2418
        {
2419
            geoCurve = std::make_unique<Geom2dBezierCurve>(adapt.Bezier());
2420
            break;
2421
        }
2422
    case GeomAbs_BSplineCurve:
2423
        {
2424
            geoCurve = std::make_unique<Geom2dBSplineCurve>(adapt.BSpline());
2425
            break;
2426
        }
2427
    case GeomAbs_OtherCurve:
2428
    default:
2429
        break;
2430
    }
2431

2432
    if (!geoCurve)
2433
        throw Base::TypeError("Unhandled curve type");
2434

2435
    // Check if the curve must be trimmed
2436
    Handle(Geom2d_Curve) curv2d = Handle(Geom2d_Curve)::DownCast
2437
        (geoCurve->handle());
2438
    double u = curv2d->FirstParameter();
2439
    double v = curv2d->LastParameter();
2440
    if (u != adapt.FirstParameter() || v != adapt.LastParameter()) {
2441
        geoCurve = makeFromTrimmedCurve2d(curv2d, adapt.FirstParameter(), adapt.LastParameter());
2442
    }
2443

2444
    return geoCurve;
2445
}
2446
}
2447

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.