FreeCAD

Форк
0
/
Curve2dPyImp.cpp 
850 строк · 29.9 Кб
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 <sstream>
26

27
# include <BRepAdaptor_Curve.hxx>
28
# include <BRepAdaptor_Surface.hxx>
29
# include <BRepBuilderAPI_MakeEdge.hxx>
30
# include <BRepBuilderAPI_MakeEdge2d.hxx>
31
# include <BRep_Builder.hxx>
32
# include <BRep_Tool.hxx>
33
# include <BRepLib.hxx>
34
# include <GCPnts_UniformAbscissa.hxx>
35
# include <GCPnts_UniformDeflection.hxx>
36
# include <GCPnts_TangentialDeflection.hxx>
37
# include <GCPnts_QuasiUniformAbscissa.hxx>
38
# include <GCPnts_QuasiUniformDeflection.hxx>
39
# include <GCPnts_AbscissaPoint.hxx>
40
# include <Geom2d_Curve.hxx>
41
# include <Geom2d_Geometry.hxx>
42
# include <Geom2dAdaptor_Curve.hxx>
43
# include <Geom2dAPI_ExtremaCurveCurve.hxx>
44
# include <Geom2dAPI_InterCurveCurve.hxx>
45
# include <Geom2dAPI_ProjectPointOnCurve.hxx>
46
# include <Geom2dConvert_ApproxCurve.hxx>
47
# include <Geom2dLProp_CLProps2d.hxx>
48
# include <gp_Dir2d.hxx>
49
# include <Precision.hxx>
50
# include <ShapeConstruct_Curve.hxx>
51
# include <Standard_Failure.hxx>
52
# include <Standard_NullValue.hxx>
53
# include <TopoDS.hxx>
54
#endif
55

56
#include <Base/GeometryPyCXX.h>
57
#include <Base/PyWrapParseTupleAndKeywords.h>
58

59
#include "Geom2d/Curve2dPy.h"
60
#include "Geom2d/Curve2dPy.cpp"
61
#include "Geom2d/BSplineCurve2dPy.h"
62
#include "GeometrySurfacePy.h"
63
#include "OCCError.h"
64
#include "TopoShapeFacePy.h"
65

66

67
namespace Part {
68
extern const Py::Object makeGeometryCurvePy(const Handle(Geom_Curve)& c);
69
}
70

71
using namespace Part;
72

73
// returns a string which represents the object e.g. when printed in python
74
std::string Curve2dPy::representation() const
75
{
76
    return "<Curve2d object>";
77
}
78

79
PyObject *Curve2dPy::PyMake(struct _typeobject *, PyObject *, PyObject *)  // Python wrapper
80
{
81
    // never create such objects with the constructor
82
    PyErr_SetString(PyExc_RuntimeError,
83
        "You cannot create an instance of the abstract class 'Curve2d'.");
84
    return nullptr;
85
}
86

87
// constructor method
88
int Curve2dPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
89
{
90
    return 0;
91
}
92

93
PyObject* Curve2dPy::reverse(PyObject * args)
94
{
95
    if (PyArg_ParseTuple(args, "")) {
96
        try {
97
            Handle(Geom2d_Curve) curve = Handle(Geom2d_Curve)::DownCast(getGeom2dCurvePtr()->handle());
98
            curve->Reverse();
99
            Py_Return;
100
        }
101
        catch (Standard_Failure& e) {
102
            PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
103
            return nullptr;
104
        }
105
    }
106

107
    return nullptr;
108
}
109

110
namespace Part {
111
extern Py::Object shape2pyshape(const TopoDS_Shape &shape);
112

113
void create3dCurve(const TopoDS_Edge& edge)
114
{
115
    TopoDS_Edge edge3d;
116
    BRepAdaptor_Curve adapt_curve(edge);
117
    switch(adapt_curve.GetType()) {
118
    case GeomAbs_Line:
119
        {
120
            BRepBuilderAPI_MakeEdge mkBuilder3d(adapt_curve.Line(),
121
                                                adapt_curve.FirstParameter(),
122
                                                adapt_curve.LastParameter());
123
            edge3d =  mkBuilder3d.Edge();
124
        } break;
125
    case GeomAbs_Circle:
126
        {
127
            BRepBuilderAPI_MakeEdge mkBuilder3d(adapt_curve.Circle(),
128
                                                adapt_curve.FirstParameter(),
129
                                                adapt_curve.LastParameter());
130
            edge3d =  mkBuilder3d.Edge();
131
        } break;
132
    case GeomAbs_Ellipse:
133
        {
134
            BRepBuilderAPI_MakeEdge mkBuilder3d(adapt_curve.Ellipse(),
135
                                                adapt_curve.FirstParameter(),
136
                                                adapt_curve.LastParameter());
137
            edge3d =  mkBuilder3d.Edge();
138
        } break;
139
    case GeomAbs_Hyperbola:
140
        {
141
            BRepBuilderAPI_MakeEdge mkBuilder3d(adapt_curve.Hyperbola(),
142
                                                adapt_curve.FirstParameter(),
143
                                                adapt_curve.LastParameter());
144
            edge3d =  mkBuilder3d.Edge();
145
        } break;
146
    case GeomAbs_Parabola:
147
        {
148
            BRepBuilderAPI_MakeEdge mkBuilder3d(adapt_curve.Parabola(),
149
                                                adapt_curve.FirstParameter(),
150
                                                adapt_curve.LastParameter());
151
            edge3d =  mkBuilder3d.Edge();
152
        } break;
153
    case GeomAbs_BezierCurve:
154
        {
155
            BRepBuilderAPI_MakeEdge mkBuilder3d(adapt_curve.Bezier(),
156
                                                adapt_curve.FirstParameter(),
157
                                                adapt_curve.LastParameter());
158
            edge3d =  mkBuilder3d.Edge();
159
        } break;
160
    default:
161
        edge3d = edge;
162
        BRepLib::BuildCurves3d(edge3d, Precision::Confusion(), GeomAbs_Shape::GeomAbs_C1, 14, 10000);
163
        break;
164
    }
165
    Standard_Real aFirst, aLast;
166
    Handle(Geom_Curve) curve = BRep_Tool::Curve(edge3d, aFirst, aLast);
167
    BRep_Builder builder;
168
    builder.UpdateEdge(edge, curve, Precision::Confusion());
169
    builder.Range(edge, aFirst, aLast, true);
170
    return;
171
}
172
}
173

174
PyObject* Curve2dPy::toShape(PyObject *args)
175
{
176
    if (PyArg_ParseTuple(args, "")) {
177
        try {
178
            Handle(Geom2d_Curve) curv = Handle(Geom2d_Curve)::DownCast(getGeometry2dPtr()->handle());
179

180
            BRepBuilderAPI_MakeEdge2d mkBuilder(curv);
181
            TopoDS_Shape edge =  mkBuilder.Shape();
182
            return Py::new_reference_to(shape2pyshape(edge));
183
        }
184
        catch (Standard_Failure& e) {
185
            PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
186
            return nullptr;
187
        }
188
    }
189

190
    PyErr_Clear();
191
    double u1, u2;
192
    if (PyArg_ParseTuple(args, "dd", &u1, &u2)) {
193
        try {
194
            Handle(Geom2d_Curve) curv = Handle(Geom2d_Curve)::DownCast(getGeometry2dPtr()->handle());
195

196
            BRepBuilderAPI_MakeEdge2d mkBuilder(curv, u1, u2);
197
            TopoDS_Shape edge =  mkBuilder.Shape();
198
            return Py::new_reference_to(shape2pyshape(edge));
199
        }
200
        catch (Standard_Failure& e) {
201
            PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
202
            return nullptr;
203
        }
204
    }
205

206
    PyErr_Clear();
207
    PyObject* p;
208
    if (PyArg_ParseTuple(args, "O!", &(Part::GeometrySurfacePy::Type), &p)) {
209
        try {
210
            Handle(Geom_Surface) surf = Handle(Geom_Surface)::DownCast(
211
                        static_cast<GeometrySurfacePy*>(p)->getGeomSurfacePtr()->handle());
212
            Handle(Geom2d_Curve) curv = Handle(Geom2d_Curve)::DownCast(getGeometry2dPtr()->handle());
213

214
            BRepBuilderAPI_MakeEdge mkBuilder(curv, surf);
215
            TopoDS_Edge edge =  mkBuilder.Edge();
216
            create3dCurve(edge);
217

218
            return Py::new_reference_to(shape2pyshape(edge));
219
        }
220
        catch (Standard_Failure& e) {
221
            PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
222
            return nullptr;
223
        }
224
    }
225

226
    PyErr_Clear();
227
    if (PyArg_ParseTuple(args, "O!dd", &(Part::GeometrySurfacePy::Type), &p, &u1, &u2)) {
228
        try {
229
            Handle(Geom_Surface) surf = Handle(Geom_Surface)::DownCast(
230
                        static_cast<GeometrySurfacePy*>(p)->getGeomSurfacePtr()->handle());
231
            Handle(Geom2d_Curve) curv = Handle(Geom2d_Curve)::DownCast(getGeometry2dPtr()->handle());
232

233
            BRepBuilderAPI_MakeEdge mkBuilder(curv, surf, u1, u2);
234
            TopoDS_Edge edge =  mkBuilder.Edge();
235
            create3dCurve(edge);
236

237
            return Py::new_reference_to(shape2pyshape(edge));
238
        }
239
        catch (Standard_Failure& e) {
240

241
            PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
242
            return nullptr;
243
        }
244
    }
245

246
    PyErr_Clear();
247
    if (PyArg_ParseTuple(args, "O!", &(Part::TopoShapeFacePy::Type), &p)) {
248
        try {
249
            const TopoDS_Face& face = TopoDS::Face(static_cast<TopoShapeFacePy*>(p)->getTopoShapePtr()->getShape());
250
            Handle(Geom2d_Curve) curv = Handle(Geom2d_Curve)::DownCast(getGeometry2dPtr()->handle());
251

252
            BRepAdaptor_Surface adapt(face);
253
            BRepBuilderAPI_MakeEdge mkBuilder(curv, adapt.Surface().Surface());
254
            TopoDS_Edge edge =  mkBuilder.Edge();
255
            create3dCurve(edge);
256

257
            return Py::new_reference_to(shape2pyshape(edge));
258
        }
259
        catch (Standard_Failure& e) {
260
            PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
261
            return nullptr;
262
        }
263
    }
264

265
    PyErr_Clear();
266
    if (PyArg_ParseTuple(args, "O!dd", &(Part::TopoShapeFacePy::Type), &p, &u1, &u2)) {
267
        try {
268
            const TopoDS_Face& face = TopoDS::Face(static_cast<TopoShapeFacePy*>(p)->getTopoShapePtr()->getShape());
269
            Handle(Geom2d_Curve) curv = Handle(Geom2d_Curve)::DownCast(getGeometry2dPtr()->handle());
270

271
            BRepAdaptor_Surface adapt(face);
272
            BRepBuilderAPI_MakeEdge mkBuilder(curv, adapt.Surface().Surface(), u1, u2);
273
            TopoDS_Edge edge =  mkBuilder.Edge();
274
            create3dCurve(edge);
275

276
            return Py::new_reference_to(shape2pyshape(edge));
277
        }
278
        catch (Standard_Failure& e) {
279
            PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
280
            return nullptr;
281
        }
282
    }
283

284
    PyErr_SetString(PyExc_TypeError, "empty parameter list, parameter range or surface expected");
285
    return nullptr;
286
}
287

288
PyObject* Curve2dPy::discretize(PyObject *args, PyObject *kwds)
289
{
290
    try {
291
        Handle(Geom2d_Geometry) g = getGeometry2dPtr()->handle();
292
        Handle(Geom2d_Curve) c = Handle(Geom2d_Curve)::DownCast(g);
293
        if (c.IsNull()) {
294
            PyErr_SetString(PartExceptionOCCError, "Geometry is not a curve");
295
            return nullptr;
296
        }
297

298
        Geom2dAdaptor_Curve adapt(c);
299
        double first = adapt.FirstParameter();
300
        double last = adapt.LastParameter();
301

302
        // use Number kwds
303
        static const std::array<const char *, 4> kwds_numPoints {"Number", "First", "Last", nullptr};
304
        PyErr_Clear();
305
        int numPoints = -1;
306
        if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "i|dd", kwds_numPoints, &numPoints, &first, &last)) {
307
            GCPnts_UniformAbscissa discretizer;
308
            discretizer.Initialize (adapt, numPoints, first, last);
309

310
            if (discretizer.IsDone () && discretizer.NbPoints () > 0) {
311
                Py::List points;
312
                int nbPoints = discretizer.NbPoints ();
313

314
                for (int i=1; i<=nbPoints; i++) {
315
                    gp_Pnt2d p = adapt.Value (discretizer.Parameter (i));
316
                    points.append(Base::Vector2dPy::create(p.X(), p.Y()));
317
                }
318

319
                return Py::new_reference_to(points);
320
            }
321
            else {
322
                PyErr_SetString(PartExceptionOCCError, "Discretization of curve failed");
323
                return nullptr;
324
            }
325
        }
326

327
        // use Distance kwds
328
        static const std::array<const char *, 4> kwds_Distance{"Distance", "First", "Last", nullptr};
329
        PyErr_Clear();
330
        double distance = -1;
331
        if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "d|dd", kwds_Distance, &distance, &first, &last)) {
332
            GCPnts_UniformAbscissa discretizer;
333
            discretizer.Initialize (adapt, distance, first, last);
334

335
            if (discretizer.IsDone () && discretizer.NbPoints () > 0) {
336
                Py::List points;
337
                int nbPoints = discretizer.NbPoints ();
338

339
                for (int i=1; i<=nbPoints; i++) {
340
                    gp_Pnt2d p = adapt.Value (discretizer.Parameter (i));
341
                    points.append(Base::Vector2dPy::create(p.X(), p.Y()));
342
                }
343

344
                return Py::new_reference_to(points);
345
            }
346
            else {
347
                PyErr_SetString(PartExceptionOCCError, "Discretization of curve failed");
348
                return nullptr;
349
            }
350
        }
351

352
        // use Deflection kwds
353
        static const std::array<const char *, 4> kwds_Deflection{"Deflection", "First", "Last", nullptr};
354
        PyErr_Clear();
355
        double deflection;
356
        if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "d|dd", kwds_Deflection, &deflection, &first, &last)) {
357
            GCPnts_UniformDeflection discretizer(adapt, deflection, first, last);
358
            if (discretizer.IsDone () && discretizer.NbPoints () > 0) {
359
                Py::List points;
360
                int nbPoints = discretizer.NbPoints ();
361

362
                for (int i=1; i<=nbPoints; i++) {
363
                    gp_Pnt p = discretizer.Value (i);
364
                    points.append(Base::Vector2dPy::create(p.X(), p.Y()));
365
                }
366

367
                return Py::new_reference_to(points);
368
            }
369
            else {
370
                PyErr_SetString(PartExceptionOCCError, "Discretization of curve failed");
371
                return nullptr;
372
            }
373
        }
374

375
        // use TangentialDeflection kwds
376
        static const std::array<const char *, 6> kwds_TangentialDeflection{"Angular", "Curvature", "First", "Last",
377
                                                                           "Minimum", nullptr};
378
        PyErr_Clear();
379
        double angular;
380
        double curvature;
381
        int minimumPoints = 2;
382
        if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "dd|ddi", kwds_TangentialDeflection, &angular, &curvature,
383
                                                &first, &last, &minimumPoints)) {
384
            GCPnts_TangentialDeflection discretizer(adapt, first, last, angular, curvature, minimumPoints);
385
            if (discretizer.NbPoints () > 0) {
386
                Py::List points;
387
                int nbPoints = discretizer.NbPoints ();
388

389
                for (int i=1; i<=nbPoints; i++) {
390
                    gp_Pnt p = discretizer.Value (i);
391
                    points.append(Base::Vector2dPy::create(p.X(), p.Y()));
392
                }
393

394
                return Py::new_reference_to(points);
395
            }
396
            else {
397
                PyErr_SetString(PartExceptionOCCError, "Discretization of curve failed");
398
                return nullptr;
399
            }
400
        }
401

402
        // use QuasiNumber kwds
403
        static const std::array<const char *, 4> kwds_QuasiNumPoints{"QuasiNumber", "First", "Last", nullptr};
404
        PyErr_Clear();
405
        int quasiNumPoints;
406
        if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "i|dd", kwds_QuasiNumPoints, &quasiNumPoints, &first,
407
                                                &last)) {
408
            GCPnts_QuasiUniformAbscissa discretizer(adapt, quasiNumPoints, first, last);
409
            if (discretizer.NbPoints () > 0) {
410
                Py::List points;
411
                int nbPoints = discretizer.NbPoints ();
412

413
                for (int i=1; i<=nbPoints; i++) {
414
                    gp_Pnt2d p = adapt.Value (discretizer.Parameter (i));
415
                    points.append(Base::Vector2dPy::create(p.X(), p.Y()));
416
                }
417

418
                return Py::new_reference_to(points);
419
            }
420
            else {
421
                PyErr_SetString(PartExceptionOCCError, "Discretization of curve failed");
422
                return nullptr;
423
            }
424
        }
425

426
        // use QuasiDeflection kwds
427
        static const std::array<const char *, 4> kwds_QuasiDeflection {"QuasiDeflection","First","Last",nullptr};
428
        PyErr_Clear();
429
        double quasiDeflection;
430
        if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "d|dd", kwds_QuasiDeflection, &quasiDeflection, &first,
431
                                                &last)) {
432
            GCPnts_QuasiUniformDeflection discretizer(adapt, quasiDeflection, first, last);
433
            if (discretizer.NbPoints () > 0) {
434
                Py::List points;
435
                int nbPoints = discretizer.NbPoints ();
436
                for (int i=1; i<=nbPoints; i++) {
437
                    gp_Pnt p = discretizer.Value (i);
438
                    points.append(Base::Vector2dPy::create(p.X(), p.Y()));
439
                }
440

441
                return Py::new_reference_to(points);
442
            }
443
            else {
444
                PyErr_SetString(PartExceptionOCCError, "Discretization of curve failed");
445
                return nullptr;
446
            }
447
        }
448
    }
449
    catch (const Base::Exception& e) {
450
        PyErr_SetString(PartExceptionOCCError, e.what());
451
        return nullptr;
452
    }
453

454
    PyErr_SetString(PartExceptionOCCError,"Wrong arguments");
455
    return nullptr;
456
}
457

458
PyObject* Curve2dPy::length(PyObject *args)
459
{
460
    Handle(Geom2d_Geometry) g = getGeometry2dPtr()->handle();
461
    Handle(Geom2d_Curve) c = Handle(Geom2d_Curve)::DownCast(g);
462
    try {
463
        if (!c.IsNull()) {
464
            double u=c->FirstParameter();
465
            double v=c->LastParameter();
466
            double t=Precision::Confusion();
467
            if (!PyArg_ParseTuple(args, "|ddd", &u,&v,&t))
468
                return nullptr;
469
            Geom2dAdaptor_Curve adapt(c);
470
            double len = GCPnts_AbscissaPoint::Length(adapt,u,v,t);
471
            return PyFloat_FromDouble(len);
472
        }
473
    }
474
    catch (Standard_Failure& e) {
475
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
476
        return nullptr;
477
    }
478

479
    PyErr_SetString(PartExceptionOCCError, "Geometry is not a curve");
480
    return nullptr;
481
}
482

483
PyObject* Curve2dPy::parameterAtDistance(PyObject *args)
484
{
485
    Handle(Geom2d_Geometry) g = getGeometry2dPtr()->handle();
486
    Handle(Geom2d_Curve) c = Handle(Geom2d_Curve)::DownCast(g);
487
    try {
488
        if (!c.IsNull()) {
489
            double abscissa;
490
            double u = 0;
491
            if (!PyArg_ParseTuple(args, "d|d", &abscissa,&u))
492
                return nullptr;
493
            Geom2dAdaptor_Curve adapt(c);
494
            GCPnts_AbscissaPoint abscissaPoint(adapt,abscissa,u);
495
            double parm = abscissaPoint.Parameter();
496
            return PyFloat_FromDouble(parm);
497
        }
498
    }
499
    catch (Standard_Failure& e) {
500
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
501
        return nullptr;
502
    }
503

504
    PyErr_SetString(PartExceptionOCCError, "Geometry is not a curve");
505
    return nullptr;
506
}
507

508
PyObject* Curve2dPy::value(PyObject *args)
509
{
510
    Handle(Geom2d_Geometry) g = getGeometry2dPtr()->handle();
511
    Handle(Geom2d_Curve) c = Handle(Geom2d_Curve)::DownCast(g);
512
    try {
513
        if (!c.IsNull()) {
514
            double u;
515
            if (!PyArg_ParseTuple(args, "d", &u))
516
                return nullptr;
517
            gp_Pnt2d p = c->Value(u);
518
            return Py::new_reference_to(Base::Vector2dPy::create(p.X(), p.Y()));
519
        }
520
    }
521
    catch (Standard_Failure& e) {
522
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
523
        return nullptr;
524
    }
525

526
    PyErr_SetString(PartExceptionOCCError, "Geometry is not a curve");
527
    return nullptr;
528
}
529

530
PyObject* Curve2dPy::tangent(PyObject *args)
531
{
532
    Handle(Geom2d_Geometry) g = getGeometry2dPtr()->handle();
533
    Handle(Geom2d_Curve) c = Handle(Geom2d_Curve)::DownCast(g);
534
    try {
535
        if (!c.IsNull()) {
536
            double u;
537
            if (!PyArg_ParseTuple(args, "d", &u))
538
                return nullptr;
539
            gp_Dir2d dir;
540
            Geom2dLProp_CLProps2d prop(c,u,2,Precision::Confusion());
541
            if (prop.IsTangentDefined()) {
542
                prop.Tangent(dir);
543
            }
544

545
            return Py::new_reference_to(Base::Vector2dPy::create(dir.X(), dir.Y()));
546
        }
547
    }
548
    catch (Standard_Failure& e) {
549
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
550
        return nullptr;
551
    }
552

553
    PyErr_SetString(PartExceptionOCCError, "Geometry is not a curve");
554
    return nullptr;
555
}
556

557
PyObject* Curve2dPy::normal(PyObject *args)
558
{
559
    Handle(Geom2d_Geometry) g = getGeometry2dPtr()->handle();
560
    Handle(Geom2d_Curve) c = Handle(Geom2d_Curve)::DownCast(g);
561
    try {
562
        if (!c.IsNull()) {
563
            double u;
564
            if (!PyArg_ParseTuple(args, "d", &u))
565
                return nullptr;
566
            gp_Dir2d dir;
567
            Geom2dLProp_CLProps2d prop(c,u,2,Precision::Confusion());
568
            prop.Normal(dir);
569

570
            return Py::new_reference_to(Base::Vector2dPy::create(dir.X(), dir.Y()));
571
        }
572
    }
573
    catch (Standard_Failure& e) {
574
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
575
        return nullptr;
576
    }
577

578
    PyErr_SetString(PartExceptionOCCError, "Geometry is not a curve");
579
    return nullptr;
580
}
581

582
PyObject* Curve2dPy::curvature(PyObject *args)
583
{
584
    Handle(Geom2d_Geometry) g = getGeometry2dPtr()->handle();
585
    Handle(Geom2d_Curve) c = Handle(Geom2d_Curve)::DownCast(g);
586
    try {
587
        if (!c.IsNull()) {
588
            double u;
589
            if (!PyArg_ParseTuple(args, "d", &u))
590
                return nullptr;
591
            Geom2dLProp_CLProps2d prop(c,u,2,Precision::Confusion());
592
            double C = prop.Curvature();
593
            return Py::new_reference_to(Py::Float(C));
594
        }
595
    }
596
    catch (Standard_Failure& e) {
597
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
598
        return nullptr;
599
    }
600

601
    PyErr_SetString(PartExceptionOCCError, "Geometry is not a curve");
602
    return nullptr;
603
}
604

605
PyObject* Curve2dPy::centerOfCurvature(PyObject *args)
606
{
607
    Handle(Geom2d_Geometry) g = getGeometry2dPtr()->handle();
608
    Handle(Geom2d_Curve) c = Handle(Geom2d_Curve)::DownCast(g);
609
    try {
610
        if (!c.IsNull()) {
611
            double u;
612
            if (!PyArg_ParseTuple(args, "d", &u))
613
                return nullptr;
614
            Geom2dLProp_CLProps2d prop(c,u,2,Precision::Confusion());
615
            gp_Pnt2d pnt ;
616
            prop.CentreOfCurvature(pnt);
617

618
            return Py::new_reference_to(Base::Vector2dPy::create(pnt.X(), pnt.Y()));
619
        }
620
    }
621
    catch (Standard_Failure& e) {
622
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
623
        return nullptr;
624
    }
625

626
    PyErr_SetString(PartExceptionOCCError, "Geometry is not a curve");
627
    return nullptr;
628
}
629

630
PyObject* Curve2dPy::parameter(PyObject *args)
631
{
632
    Handle(Geom2d_Geometry) g = getGeometry2dPtr()->handle();
633
    Handle(Geom2d_Curve) c = Handle(Geom2d_Curve)::DownCast(g);
634
    try {
635
        if (!c.IsNull()) {
636
            PyObject *p;
637
            if (!PyArg_ParseTuple(args, "O!", Base::Vector2dPy::type_object(), &p))
638
                return nullptr;
639
            Base::Vector2d v = Py::toVector2d(p);
640
            gp_Pnt2d pnt(v.x,v.y);
641
            Geom2dAPI_ProjectPointOnCurve ppc(pnt, c);
642
            double val = ppc.LowerDistanceParameter();
643
            return Py::new_reference_to(Py::Float(val));
644
        }
645
    }
646
    catch (Standard_Failure& e) {
647

648
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
649
        return nullptr;
650
    }
651

652
    PyErr_SetString(PartExceptionOCCError, "Geometry is not a curve");
653
    return nullptr;
654
}
655

656
PyObject* Curve2dPy::toBSpline(PyObject * args)
657
{
658
    Handle(Geom2d_Geometry) g = getGeometry2dPtr()->handle();
659
    Handle(Geom2d_Curve) c = Handle(Geom2d_Curve)::DownCast(g);
660
    try {
661
        if (!c.IsNull()) {
662
            double u,v;
663
            u=c->FirstParameter();
664
            v=c->LastParameter();
665
            if (!PyArg_ParseTuple(args, "|dd", &u,&v))
666
                return nullptr;
667
            ShapeConstruct_Curve scc;
668
            Handle(Geom2d_BSplineCurve) spline = scc.ConvertToBSpline(c, u, v, Precision::Confusion());
669
            if (spline.IsNull())
670
                Standard_NullValue::Raise("Conversion to B-spline failed");
671
            return new BSplineCurve2dPy(new Geom2dBSplineCurve(spline));
672
        }
673
    }
674
    catch (Standard_Failure& e) {
675
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
676
        return nullptr;
677
    }
678

679
    PyErr_SetString(PartExceptionOCCError, "Geometry is not a curve");
680
    return nullptr;
681
}
682

683
PyObject* Curve2dPy::approximateBSpline(PyObject *args)
684
{
685
    double tolerance;
686
    int maxSegment, maxDegree;
687
    const char* order = "C2";
688
    if (!PyArg_ParseTuple(args, "dii|s", &tolerance, &maxSegment, &maxDegree, &order))
689
        return nullptr;
690

691
    GeomAbs_Shape absShape;
692
    std::string str = order;
693
    if (str == "C0")
694
        absShape = GeomAbs_C0;
695
    else if (str == "G1")
696
        absShape = GeomAbs_G1;
697
    else if (str == "C1")
698
        absShape = GeomAbs_C1;
699
    else if (str == "G2")
700
        absShape = GeomAbs_G2;
701
    else if (str == "C2")
702
        absShape = GeomAbs_C2;
703
    else if (str == "C3")
704
        absShape = GeomAbs_C3;
705
    else if (str == "CN")
706
        absShape = GeomAbs_CN;
707
    else
708
        absShape = GeomAbs_C2;
709

710
    try {
711
        Handle(Geom2d_Curve) self = Handle(Geom2d_Curve)::DownCast(getGeometry2dPtr()->handle());
712
        Geom2dConvert_ApproxCurve approx(self, tolerance, absShape, maxSegment, maxDegree);
713
        if (approx.IsDone()) {
714
            return new BSplineCurve2dPy(new Geom2dBSplineCurve(approx.Curve()));
715
        }
716
        else if (approx.HasResult()) {
717
            std::stringstream str;
718
            str << "Maximum error (" << approx.MaxError() << ") is outside tolerance";
719
            PyErr_SetString(PyExc_RuntimeError, str.str().c_str());
720
            return nullptr;
721
        }
722
        else {
723
            PyErr_SetString(PyExc_RuntimeError, "Approximation of curve failed");
724
            return nullptr;
725
        }
726
    }
727
    catch (Standard_Failure& e) {
728
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
729
        return nullptr;
730
    }
731
}
732

733
Py::String Curve2dPy::getContinuity() const
734
{
735
    GeomAbs_Shape c = Handle(Geom2d_Curve)::DownCast
736
        (getGeometry2dPtr()->handle())->Continuity();
737
    std::string str;
738
    switch (c) {
739
    case GeomAbs_C0:
740
        str = "C0";
741
        break;
742
    case GeomAbs_G1:
743
        str = "G1";
744
        break;
745
    case GeomAbs_C1:
746
        str = "C1";
747
        break;
748
    case GeomAbs_G2:
749
        str = "G2";
750
        break;
751
    case GeomAbs_C2:
752
        str = "C2";
753
        break;
754
    case GeomAbs_C3:
755
        str = "C3";
756
        break;
757
    case GeomAbs_CN:
758
        str = "CN";
759
        break;
760
    default:
761
        str = "Unknown";
762
        break;
763
    }
764
    return Py::String(str);
765
}
766

767
Py::Boolean Curve2dPy::getClosed() const
768
{
769
    return Py::Boolean(Handle(Geom2d_Curve)::DownCast
770
        (getGeometry2dPtr()->handle())->IsClosed() ? true : false);
771
}
772

773
Py::Boolean Curve2dPy::getPeriodic() const
774
{
775
    return Py::Boolean(Handle(Geom2d_Curve)::DownCast
776
        (getGeometry2dPtr()->handle())->IsPeriodic() ? true : false);
777
}
778

779
Py::Float Curve2dPy::getFirstParameter() const
780
{
781
    return Py::Float(Handle(Geom2d_Curve)::DownCast
782
        (getGeometry2dPtr()->handle())->FirstParameter());
783
}
784

785
Py::Float Curve2dPy::getLastParameter() const
786
{
787
    return Py::Float(Handle(Geom2d_Curve)::DownCast
788
        (getGeometry2dPtr()->handle())->LastParameter());
789
}
790

791
PyObject *Curve2dPy::getCustomAttributes(const char* /*attr*/) const
792
{
793
    return nullptr;
794
}
795

796
int Curve2dPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
797
{
798
    return 0;
799
}
800

801
PyObject* Curve2dPy::intersectCC(PyObject *args)
802
{
803
    Handle(Geom2d_Curve) curve1 = Handle(Geom2d_Curve)::DownCast(getGeometry2dPtr()->handle());
804
    try {
805
        if (!curve1.IsNull()) {
806
            PyObject *p;
807
            double prec = Precision::Confusion();
808
            if (!PyArg_ParseTuple(args, "O!|d", &(Part::Curve2dPy::Type), &p, &prec))
809
                return nullptr;
810

811
            Handle(Geom2d_Curve) curve2 = Handle(Geom2d_Curve)::DownCast(static_cast<Geometry2dPy*>(p)->getGeometry2dPtr()->handle());
812
            Py::List points;
813
            Geom2dAPI_InterCurveCurve intersector(curve1, curve2, prec);
814
            if ((intersector.NbPoints() == 0) && (intersector.NbSegments() == 0)) {
815
                // No intersection
816
                return Py::new_reference_to(Py::List());
817
            }
818
            if (intersector.NbPoints() > 0) {
819
                // Cross intersections
820
                for (int i = 1; i <= intersector.NbPoints(); i++) {
821
                    gp_Pnt2d p1 = intersector.Point(i);
822
                    points.append(Base::Vector2dPy::create(p1.X(), p1.Y()));
823
                }
824
            }
825
            if (intersector.NbSegments() > 0) {
826
                // Tangential intersections
827
                Geom2dAPI_ExtremaCurveCurve intersector2(curve1, curve2,
828
                                                        curve1->FirstParameter(),
829
                                                        curve1->LastParameter(),
830
                                                        curve2->FirstParameter(),
831
                                                        curve2->LastParameter());
832
                for (int i = 1; i <= intersector2.NbExtrema(); i++) {
833
                    if (intersector2.Distance(i) > prec)
834
                        continue;
835
                    gp_Pnt2d p1, p2;
836
                    intersector2.Points(i, p1, p2);
837
                    points.append(Base::Vector2dPy::create(p1.X(), p1.Y()));
838
                }
839
            }
840
            return Py::new_reference_to(points);
841
        }
842
    }
843
    catch (Standard_Failure& e) {
844
        PyErr_SetString(PyExc_RuntimeError, e.GetMessageString());
845
        return nullptr;
846
    }
847

848
    PyErr_SetString(PyExc_TypeError, "Geometry is not a curve");
849
    return nullptr;
850
}
851

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

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

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

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