FreeCAD

Форк
0
/
BSplineCurve2dPyImp.cpp 
1295 строк · 43.2 Кб
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 <Geom2d_BSplineCurve.hxx>
26
# include <Geom2dAPI_PointsToBSpline.hxx>
27
# include <Geom2dAPI_Interpolate.hxx>
28
# include <Geom2dConvert_BSplineCurveToBezierCurve.hxx>
29
# include <gp_Pnt2d.hxx>
30
# include <Precision.hxx>
31
# include <TColgp_Array1OfPnt2d.hxx>
32
# include <TColgp_Array1OfVec2d.hxx>
33
# include <TColgp_HArray1OfPnt2d.hxx>
34
# include <TColStd_Array1OfInteger.hxx>
35
# include <TColStd_Array1OfReal.hxx>
36
# include <TColStd_HArray1OfBoolean.hxx>
37
# include <TColStd_HArray1OfReal.hxx>
38
#endif
39

40
#include <Base/GeometryPyCXX.h>
41
#include <Base/PyWrapParseTupleAndKeywords.h>
42

43
#include "Geom2d/BSplineCurve2dPy.h"
44
#include "Geom2d/BSplineCurve2dPy.cpp"
45
#include "Geom2d/BezierCurve2dPy.h"
46
#include "OCCError.h"
47

48

49
using namespace Part;
50

51
// returns a string which represents the object e.g. when printed in python
52
std::string BSplineCurve2dPy::representation() const
53
{
54
    return "<BSplineCurve2d object>";
55
}
56

57
PyObject *BSplineCurve2dPy::PyMake(struct _typeobject *, PyObject *, PyObject *)  // Python wrapper
58
{
59
    // create a new instance of BSplineCurve2dPy and the Twin object
60
    return new BSplineCurve2dPy(new Geom2dBSplineCurve);
61
}
62

63
// constructor method
64
int BSplineCurve2dPy::PyInit(PyObject* args, PyObject* /*kwd*/)
65
{
66
    if (PyArg_ParseTuple(args, "")) {
67
        return 0;
68
    }
69

70
    PyErr_SetString(PyExc_TypeError, "B-spline constructor accepts:\n"
71
        "-- empty parameter list\n");
72
    return -1;
73
}
74

75
PyObject* BSplineCurve2dPy::isRational(PyObject *args)
76
{
77
    if (!PyArg_ParseTuple(args, ""))
78
        return nullptr;
79
    Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
80
        (getGeometry2dPtr()->handle());
81
    Standard_Boolean val = curve->IsRational();
82
    return PyBool_FromLong(val ? 1 : 0);
83
}
84

85
PyObject* BSplineCurve2dPy::isPeriodic(PyObject *args)
86
{
87
    if (!PyArg_ParseTuple(args, ""))
88
        return nullptr;
89
    Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
90
        (getGeometry2dPtr()->handle());
91
    Standard_Boolean val = curve->IsPeriodic();
92
    return PyBool_FromLong(val ? 1 : 0);
93
}
94

95
PyObject* BSplineCurve2dPy::isClosed(PyObject *args)
96
{
97
    if (!PyArg_ParseTuple(args, ""))
98
        return nullptr;
99
    Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
100
        (getGeometry2dPtr()->handle());
101
    Standard_Boolean val = curve->IsClosed();
102
    return PyBool_FromLong(val ? 1 : 0);
103
}
104

105
PyObject* BSplineCurve2dPy::increaseDegree(PyObject * args)
106
{
107
    int degree;
108
    if (!PyArg_ParseTuple(args, "i", &degree))
109
        return nullptr;
110
    try {
111
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
112
            (getGeometry2dPtr()->handle());
113
        curve->IncreaseDegree(degree);
114
        Py_Return;
115
    }
116
    catch (Standard_Failure& e) {
117
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
118
        return nullptr;
119
    }
120
}
121

122
PyObject* BSplineCurve2dPy::increaseMultiplicity(PyObject * args)
123
{
124
    int mult=-1;
125
    int start, end;
126
    if (!PyArg_ParseTuple(args, "ii|i", &start, &end, &mult))
127
        return nullptr;
128

129
    try {
130
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
131
            (getGeometry2dPtr()->handle());
132
        if (mult == -1) {
133
            mult = end;
134
            curve->IncreaseMultiplicity(start, mult);
135
        }
136
        else {
137
            curve->IncreaseMultiplicity(start, end, mult);
138
        }
139

140
        Py_Return;
141
    }
142
    catch (Standard_Failure& e) {
143
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
144
        return nullptr;
145
    }
146
}
147

148
PyObject* BSplineCurve2dPy::incrementMultiplicity(PyObject * args)
149
{
150
    int start, end, mult;
151
    if (!PyArg_ParseTuple(args, "iii", &start, &end, &mult))
152
        return nullptr;
153

154
    try {
155
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
156
            (getGeometry2dPtr()->handle());
157
        curve->IncrementMultiplicity(start, end, mult);
158
    }
159
    catch (Standard_Failure& e) {
160
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
161
        return nullptr;
162
    }
163

164
    Py_Return;
165
}
166

167
PyObject* BSplineCurve2dPy::insertKnot(PyObject * args)
168
{
169
    double U;
170
    double tol = 0.0;
171
    int M=1;
172
    if (!PyArg_ParseTuple(args, "d|id", &U, &M, &tol)) {
173
        return nullptr;
174
    }
175

176
    try {
177
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
178
            (getGeometry2dPtr()->handle());
179
        curve->InsertKnot(U,M,tol);
180
    }
181
    catch (Standard_Failure& e) {
182
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
183
        return nullptr;
184
    }
185

186
    Py_Return;
187
}
188

189
PyObject* BSplineCurve2dPy::insertKnots(PyObject * args)
190
{
191
    double tol = 0.0;
192
    PyObject* add = Py_True;
193
    PyObject* obj1;
194
    PyObject* obj2;
195
    if (!PyArg_ParseTuple(args, "OO|dO!", &obj1,
196
                                          &obj2,
197
                                          &tol, &PyBool_Type, &add))
198
        return nullptr;
199

200
    try {
201
        Py::Sequence knots(obj1);
202
        TColStd_Array1OfReal k(1,knots.size());
203
        int index=1;
204
        for (Py::Sequence::iterator it = knots.begin(); it != knots.end(); ++it) {
205
            Py::Float val(*it);
206
            k(index++) = (double)val;
207
        }
208
        Py::Sequence mults(obj2);
209
        TColStd_Array1OfInteger m(1,mults.size());
210
        index=1;
211
        for (Py::Sequence::iterator it = mults.begin(); it != mults.end(); ++it) {
212
            Py::Long val(*it);
213
            m(index++) = (int)val;
214
        }
215

216
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
217
            (getGeometry2dPtr()->handle());
218
        curve->InsertKnots(k, m, tol, Base::asBoolean(add));
219
        Py_Return;
220
    }
221
    catch (Standard_Failure& e) {
222
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
223
        return nullptr;
224
    }
225

226
    Py_Return;
227
}
228

229
PyObject* BSplineCurve2dPy::removeKnot(PyObject * args)
230
{
231
    double tol;
232
    int Index,M;
233
    if (!PyArg_ParseTuple(args, "iid", &Index, &M, &tol))
234
        return nullptr;
235

236
    try {
237
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
238
            (getGeometry2dPtr()->handle());
239
        Standard_Boolean ok = curve->RemoveKnot(Index,M,tol);
240
        return PyBool_FromLong(ok ? 1 : 0);
241
    }
242
    catch (Standard_Failure& e) {
243
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
244
        return nullptr;
245
    }
246
}
247

248
PyObject* BSplineCurve2dPy::segment(PyObject * args)
249
{
250
    double u1,u2;
251
    if (!PyArg_ParseTuple(args, "dd", &u1,&u2))
252
        return nullptr;
253
    try {
254
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
255
            (getGeometry2dPtr()->handle());
256
        curve->Segment(u1,u2);
257
        Py_Return;
258
    }
259
    catch (Standard_Failure& e) {
260
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
261
        return nullptr;
262
    }
263
}
264

265
PyObject* BSplineCurve2dPy::setKnot(PyObject * args)
266
{
267
    int Index, M=-1;
268
    double K;
269
    if (!PyArg_ParseTuple(args, "id|i", &Index, &K, &M))
270
        return nullptr;
271

272
    Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
273
        (getGeometry2dPtr()->handle());
274
    if (M == -1) {
275
        curve->SetKnot(Index, K);
276
    }
277
    else {
278
        curve->SetKnot(Index, K, M);
279
    }
280

281
    Py_Return;
282
}
283

284
PyObject* BSplineCurve2dPy::getKnot(PyObject * args)
285
{
286
    int Index;
287
    if (!PyArg_ParseTuple(args, "i", &Index))
288
        return nullptr;
289

290
    Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
291
        (getGeometry2dPtr()->handle());
292
    double M = curve->Knot(Index);
293

294
    return Py_BuildValue("d",M);
295
}
296

297
PyObject* BSplineCurve2dPy::setKnots(PyObject * args)
298
{
299
    PyObject* obj;
300
    if (!PyArg_ParseTuple(args, "O", &obj))
301
        return nullptr;
302
    try {
303
        Py::Sequence list(obj);
304
        TColStd_Array1OfReal k(1,list.size());
305
        int index=1;
306
        for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
307
            Py::Float val(*it);
308
            k(index++) = (double)val;
309
        }
310

311
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
312
            (getGeometry2dPtr()->handle());
313
        curve->SetKnots(k);
314
        Py_Return;
315
    }
316
    catch (Standard_Failure& e) {
317
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
318
        return nullptr;
319
    }
320
}
321

322
PyObject* BSplineCurve2dPy::getKnots(PyObject * args)
323
{
324
    if (!PyArg_ParseTuple(args, ""))
325
        return nullptr;
326
    try {
327
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
328
            (getGeometry2dPtr()->handle());
329
        TColStd_Array1OfReal w(1,curve->NbKnots());
330
        curve->Knots(w);
331
        Py::List knots;
332
        for (Standard_Integer i=w.Lower(); i<=w.Upper(); i++) {
333
            knots.append(Py::Float(w(i)));
334
        }
335
        return Py::new_reference_to(knots);
336
    }
337
    catch (Standard_Failure& e) {
338
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
339
        return nullptr;
340
    }
341
}
342

343
PyObject* BSplineCurve2dPy::setPole(PyObject * args)
344
{
345
    int index;
346
    double weight=-1.0;
347
    PyObject* p;
348
    if (!PyArg_ParseTuple(args, "iO!|d", &index, Base::Vector2dPy::type_object(), &p, &weight))
349
        return nullptr;
350
    Base::Vector2d vec = Py::toVector2d(p);
351
    gp_Pnt2d pnt(vec.x, vec.y);
352
    try {
353
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
354
            (getGeometry2dPtr()->handle());
355
        if (weight < 0.0)
356
            curve->SetPole(index,pnt);
357
        else
358
            curve->SetPole(index,pnt,weight);
359
        Py_Return;
360
    }
361
    catch (Standard_Failure& e) {
362
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
363
        return nullptr;
364
    }
365
}
366

367
PyObject* BSplineCurve2dPy::getPole(PyObject * args)
368
{
369
    int index;
370
    if (!PyArg_ParseTuple(args, "i", &index))
371
        return nullptr;
372
    try {
373
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
374
            (getGeometry2dPtr()->handle());
375
        Standard_OutOfRange_Raise_if
376
            (index < 1 || index > curve->NbPoles(), "Pole index out of range");
377
        gp_Pnt2d pnt = curve->Pole(index);
378
        return Py::new_reference_to(Base::Vector2dPy::create(pnt.X(), pnt.Y()));
379
    }
380
    catch (Standard_Failure& e) {
381
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
382
        return nullptr;
383
    }
384
}
385

386
PyObject* BSplineCurve2dPy::getPoles(PyObject * args)
387
{
388
    if (!PyArg_ParseTuple(args, ""))
389
        return nullptr;
390
    try {
391
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
392
            (getGeometry2dPtr()->handle());
393
        TColgp_Array1OfPnt2d p(1, (int)curve->NbPoles());
394
        curve->Poles(p);
395

396
        Py::List poles;
397
        for (Standard_Integer i=p.Lower(); i<=p.Upper(); i++) {
398
            gp_Pnt2d pnt = p(i);
399
            poles.append(Base::Vector2dPy::create(pnt.X(), pnt.Y()));
400
        }
401
        return Py::new_reference_to(poles);
402
    }
403
    catch (Standard_Failure& e) {
404
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
405
        return nullptr;
406
    }
407
}
408

409
PyObject* BSplineCurve2dPy::getPolesAndWeights(PyObject * args)
410
{
411
    if (!PyArg_ParseTuple(args, ""))
412
        return nullptr;
413
    try {
414
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
415
            (getGeometry2dPtr()->handle());
416
        TColgp_Array1OfPnt2d p(1,curve->NbPoles());
417
        curve->Poles(p);
418
        TColStd_Array1OfReal w(1,curve->NbPoles());
419
        curve->Weights(w);
420

421
        Py::List poles;
422
        for (Standard_Integer i=p.Lower(); i<=p.Upper(); i++) {
423
            gp_Pnt2d pnt = p(i);
424
            double weight = w(i);
425
            Py::Tuple t(3);
426
            t.setItem(0, Py::Float(pnt.X()));
427
            t.setItem(1, Py::Float(pnt.Y()));
428
            t.setItem(2, Py::Float(weight));
429
            poles.append(t);
430
        }
431
        return Py::new_reference_to(poles);
432
    }
433
    catch (Standard_Failure& e) {
434
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
435
        return nullptr;
436
    }
437
}
438

439
PyObject* BSplineCurve2dPy::setWeight(PyObject * args)
440
{
441
    int index;
442
    double weight;
443
    if (!PyArg_ParseTuple(args, "id", &index,&weight))
444
        return nullptr;
445
    try {
446
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
447
            (getGeometry2dPtr()->handle());
448
        curve->SetWeight(index,weight);
449
        Py_Return;
450
    }
451
    catch (Standard_Failure& e) {
452
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
453
        return nullptr;
454
    }
455
}
456

457
PyObject* BSplineCurve2dPy::getWeight(PyObject * args)
458
{
459
    int index;
460
    if (!PyArg_ParseTuple(args, "i", &index))
461
        return nullptr;
462
    try {
463
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
464
            (getGeometry2dPtr()->handle());
465
        Standard_OutOfRange_Raise_if
466
            (index < 1 || index > curve->NbPoles() , "Weight index out of range");
467
        double weight = curve->Weight(index);
468
        return Py_BuildValue("d", weight);
469
    }
470
    catch (Standard_Failure& e) {
471
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
472
        return nullptr;
473
    }
474
}
475

476
PyObject* BSplineCurve2dPy::getWeights(PyObject * args)
477
{
478
    if (!PyArg_ParseTuple(args, ""))
479
        return nullptr;
480
    try {
481
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
482
            (getGeometry2dPtr()->handle());
483
        TColStd_Array1OfReal w(1,curve->NbPoles());
484
        curve->Weights(w);
485
        Py::List weights;
486
        for (Standard_Integer i=w.Lower(); i<=w.Upper(); i++) {
487
            weights.append(Py::Float(w(i)));
488
        }
489
        return Py::new_reference_to(weights);
490
    }
491
    catch (Standard_Failure& e) {
492
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
493
        return nullptr;
494
    }
495
}
496

497
PyObject* BSplineCurve2dPy::getResolution(PyObject * args)
498
{
499
    double tol;
500
    if (!PyArg_ParseTuple(args, "d", &tol))
501
        return nullptr;
502
    try {
503
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
504
            (getGeometry2dPtr()->handle());
505
        double utol;
506
        curve->Resolution(tol,utol);
507
        return Py_BuildValue("d",utol);
508
    }
509
    catch (Standard_Failure& e) {
510
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
511
        return nullptr;
512
    }
513
}
514

515
PyObject* BSplineCurve2dPy::movePoint(PyObject * args)
516
{
517
    double U;
518
    int index1, index2;
519
    PyObject* pnt;
520
    if (!PyArg_ParseTuple(args, "dO!ii", &U, Base::Vector2dPy::type_object(),&pnt, &index1, &index2))
521
        return nullptr;
522
    try {
523
        Base::Vector2d p = Py::toVector2d(pnt);
524
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
525
            (getGeometry2dPtr()->handle());
526
        int first, last;
527
        curve->MovePoint(U, gp_Pnt2d(p.x,p.y), index1, index2, first, last);
528
        return Py_BuildValue("(ii)",first, last);
529
    }
530
    catch (Standard_Failure& e) {
531
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
532
        return nullptr;
533
    }
534
}
535

536
PyObject* BSplineCurve2dPy::setNotPeriodic(PyObject * args)
537
{
538
    if (!PyArg_ParseTuple(args, ""))
539
        return nullptr;
540
    try {
541
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
542
            (getGeometry2dPtr()->handle());
543
        curve->SetNotPeriodic();
544
        Py_Return;
545
    }
546
    catch (Standard_Failure& e) {
547
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
548
        return nullptr;
549
    }
550
}
551

552
PyObject* BSplineCurve2dPy::setPeriodic(PyObject * args)
553
{
554
    if (!PyArg_ParseTuple(args, ""))
555
        return nullptr;
556
    try {
557
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
558
            (getGeometry2dPtr()->handle());
559
        curve->SetPeriodic();
560
        Py_Return;
561
    }
562
    catch (Standard_Failure& e) {
563
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
564
        return nullptr;
565
    }
566
}
567

568
PyObject* BSplineCurve2dPy::setOrigin(PyObject * args)
569
{
570
    int index;
571
    if (!PyArg_ParseTuple(args, "i", &index))
572
        return nullptr;
573
    try {
574
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
575
            (getGeometry2dPtr()->handle());
576
        curve->SetOrigin(index);
577
        Py_Return;
578
    }
579
    catch (Standard_Failure& e) {
580
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
581
        return nullptr;
582
    }
583
}
584

585
PyObject* BSplineCurve2dPy::getMultiplicity(PyObject * args)
586
{
587
    int index;
588
    if (!PyArg_ParseTuple(args, "i", &index))
589
        return nullptr;
590
    try {
591
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
592
            (getGeometry2dPtr()->handle());
593
        int mult = curve->Multiplicity(index);
594
        return Py_BuildValue("i", mult);
595
    }
596
    catch (Standard_Failure& e) {
597

598
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
599
        return nullptr;
600
    }
601
}
602

603
PyObject* BSplineCurve2dPy::getMultiplicities(PyObject * args)
604
{
605
    if (!PyArg_ParseTuple(args, ""))
606
        return nullptr;
607
    try {
608
        Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
609
            (getGeometry2dPtr()->handle());
610
        TColStd_Array1OfInteger m(1,curve->NbKnots());
611
        curve->Multiplicities(m);
612
        Py::List mults;
613
        for (Standard_Integer i=m.Lower(); i<=m.Upper(); i++) {
614
            mults.append(Py::Long(m(i)));
615
        }
616
        return Py::new_reference_to(mults);
617
    }
618
    catch (Standard_Failure& e) {
619
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
620
        return nullptr;
621
    }
622
}
623

624
Py::Long BSplineCurve2dPy::getDegree() const
625
{
626
    Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
627
        (getGeometry2dPtr()->handle());
628
    return Py::Long(curve->Degree());
629
}
630

631
Py::Long BSplineCurve2dPy::getMaxDegree() const
632
{
633
    Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
634
        (getGeometry2dPtr()->handle());
635
    return Py::Long(curve->MaxDegree());
636
}
637

638
Py::Long BSplineCurve2dPy::getNbPoles() const
639
{
640
    Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
641
        (getGeometry2dPtr()->handle());
642
    return Py::Long(curve->NbPoles());
643
}
644

645
Py::Long BSplineCurve2dPy::getNbKnots() const
646
{
647
    Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
648
        (getGeometry2dPtr()->handle());
649
    return Py::Long(curve->NbKnots());
650
}
651

652
Py::Object BSplineCurve2dPy::getStartPoint() const
653
{
654
    Handle(Geom2d_BSplineCurve) c = Handle(Geom2d_BSplineCurve)::DownCast
655
        (getGeometry2dPtr()->handle());
656
    gp_Pnt2d pnt = c->StartPoint();
657
    return Base::Vector2dPy::create(pnt.X(), pnt.Y());
658
}
659

660
Py::Object BSplineCurve2dPy::getEndPoint() const
661
{
662
    Handle(Geom2d_BSplineCurve) c = Handle(Geom2d_BSplineCurve)::DownCast
663
        (getGeometry2dPtr()->handle());
664
    gp_Pnt2d pnt = c->EndPoint();
665
    return Base::Vector2dPy::create(pnt.X(), pnt.Y());
666
}
667

668
Py::Object BSplineCurve2dPy::getFirstUKnotIndex() const
669
{
670
    Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
671
        (getGeometry2dPtr()->handle());
672
    return Py::Long(curve->FirstUKnotIndex());
673
}
674

675
Py::Object BSplineCurve2dPy::getLastUKnotIndex() const
676
{
677
    Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
678
        (getGeometry2dPtr()->handle());
679
    return Py::Long(curve->LastUKnotIndex());
680
}
681

682
Py::List BSplineCurve2dPy::getKnotSequence() const
683
{
684
    Handle(Geom2d_BSplineCurve) curve = Handle(Geom2d_BSplineCurve)::DownCast
685
        (getGeometry2dPtr()->handle());
686
    Standard_Integer m = 0;
687
    if (curve->IsPeriodic()) {
688
        // knots=poles+2*degree-mult(1)+2
689
        m = (int)(curve->NbPoles() + 2*curve->Degree() - curve->Multiplicity(1) + 2);
690
    }
691
    else {
692
        // knots=poles+degree+1
693
        for (int i=1; i<= curve->NbKnots(); i++)
694
            m += (int)curve->Multiplicity(i);
695
    }
696

697
    TColStd_Array1OfReal k(1,m);
698
    curve->KnotSequence(k);
699
    Py::List list;
700
    for (Standard_Integer i=k.Lower(); i<=k.Upper(); i++) {
701
        list.append(Py::Float(k(i)));
702
    }
703
    return list;
704
}
705

706
PyObject* BSplineCurve2dPy::toBiArcs(PyObject * args)
707
{
708
    double tolerance = 0.001;
709
    if (!PyArg_ParseTuple(args, "d", &tolerance))
710
        return nullptr;
711
    try {
712
        Geom2dBSplineCurve* curve = getGeom2dBSplineCurvePtr();
713
        std::list<Geometry2d*> arcs;
714
        arcs = curve->toBiArcs(tolerance);
715

716
        Py::List list;
717
        for (auto arc : arcs) {
718
            list.append(Py::asObject(arc->getPyObject()));
719
            delete arc;
720
        }
721

722
        return Py::new_reference_to(list);
723
    }
724
    catch (Standard_Failure& e) {
725
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
726
        return nullptr;
727
    }
728
}
729

730
PyObject* BSplineCurve2dPy::approximate(PyObject *args, PyObject *kwds)
731
{
732
    PyObject* obj;
733
    Standard_Integer degMin=3;
734
    Standard_Integer degMax=8;
735
    const char* continuity = "C2";
736
    double tol3d = 1e-3;
737
    const char* parType = "ChordLength";
738
    PyObject* par = nullptr;
739
    double weight1 = 0;
740
    double weight2 = 0;
741
    double weight3 = 0;
742

743
    static const std::array<const char *, 11> kwds_interp{"Points", "DegMax", "Continuity", "Tolerance", "DegMin",
744
                                                          "ParamType", "Parameters", "LengthWeight", "CurvatureWeight",
745
                                                          "TorsionWeight", nullptr};
746

747
    if (!Base::Wrapped_ParseTupleAndKeywords(args, kwds, "O|isdisOddd",kwds_interp,
748
                                             &obj, &degMax,
749
                                             &continuity, &tol3d, &degMin,
750
                                             &parType, &par,
751
                                             &weight1, &weight2, &weight3)) {
752
        return nullptr;
753
    }
754

755
    try {
756
        Py::Sequence list(obj);
757
        TColgp_Array1OfPnt2d pnts(1,list.size());
758
        Standard_Integer index = 1;
759
        for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
760
            Base::Vector2d vec = Py::toVector2d(*it);
761
            pnts(index++) = gp_Pnt2d(vec.x,vec.y);
762
        }
763

764
        if (degMin > degMax) {
765
            Standard_Failure::Raise("DegMin must be lower or equal to DegMax");
766
        }
767

768
        GeomAbs_Shape c;
769
        std::string str = continuity;
770
        if (str == "C0")
771
            c = GeomAbs_C0;
772
        else if (str == "G1")
773
            c = GeomAbs_G1;
774
        else if (str == "C1")
775
            c = GeomAbs_C1;
776
        else if (str == "G2")
777
            c = GeomAbs_G2;
778
        else if (str == "C2")
779
            c = GeomAbs_C2;
780
        else if (str == "C3")
781
            c = GeomAbs_C3;
782
        else if (str == "CN")
783
            c = GeomAbs_CN;
784
        else
785
            c = GeomAbs_C2;
786

787
        if (weight1 || weight2 || weight3) {
788
            // It seems that this function only works with Continuity = C0, C1 or C2
789
            if (!(c == GeomAbs_C0 || c == GeomAbs_C1 || c == GeomAbs_C2)) {
790
                c = GeomAbs_C2;
791
            }
792

793
            Geom2dAPI_PointsToBSpline fit(pnts, weight1, weight2, weight3, degMax, c, tol3d);
794
            Handle(Geom2d_BSplineCurve) spline = fit.Curve();
795
            if (!spline.IsNull()) {
796
                this->getGeom2dBSplineCurvePtr()->setHandle(spline);
797
                Py_Return;
798
            }
799
            else {
800
                Standard_Failure::Raise("Smoothing approximation failed");
801
                return nullptr; // goes to the catch block
802
            }
803
        }
804

805
        if (par) {
806
            Py::Sequence plist(par);
807
            TColStd_Array1OfReal parameters(1,plist.size());
808
            Standard_Integer index = 1;
809
            for (Py::Sequence::iterator it = plist.begin(); it != plist.end(); ++it) {
810
                Py::Float f(*it);
811
                parameters(index++) = static_cast<double>(f);
812
            }
813

814
            Geom2dAPI_PointsToBSpline fit(pnts, parameters, degMin, degMax, c, tol3d);
815
            Handle(Geom2d_BSplineCurve) spline = fit.Curve();
816
            if (!spline.IsNull()) {
817
                this->getGeom2dBSplineCurvePtr()->setHandle(spline);
818
                Py_Return;
819
            }
820
            else {
821
                Standard_Failure::Raise("Approximation with parameters failed");
822
                return nullptr; // goes to the catch block
823
            }
824
        }
825

826
        Approx_ParametrizationType pt;
827
        std::string pstr = parType;
828
        if (pstr == "Uniform")
829
            pt = Approx_IsoParametric;
830
        else if (pstr == "Centripetal")
831
            pt = Approx_Centripetal;
832
        else
833
            pt = Approx_ChordLength;
834

835
        Geom2dAPI_PointsToBSpline fit(pnts, pt, degMin, degMax, c, tol3d);
836
        Handle(Geom2d_BSplineCurve) spline = fit.Curve();
837
        if (!spline.IsNull()) {
838
            this->getGeom2dBSplineCurvePtr()->setHandle(spline);
839
            Py_Return;
840
        }
841
        else {
842
            Standard_Failure::Raise("failed to approximate points");
843
            return nullptr; // goes to the catch block
844
        }
845
    }
846
    catch (Standard_Failure& e) {
847
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
848
        return nullptr;
849
    }
850
}
851

852
PyObject* BSplineCurve2dPy::getCardinalSplineTangents(PyObject *args, PyObject *kwds)
853
{
854
    PyObject* pts;
855
    PyObject* tgs;
856
    double parameter;
857

858
    static const std::array<const char *, 3> kwds_interp1 {"Points", "Parameter", nullptr};
859
    if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "Od", kwds_interp1, &pts, &parameter)) {
860
        Py::Sequence list(pts);
861
        std::vector<gp_Pnt2d> interpPoints;
862
        interpPoints.reserve(list.size());
863
        for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
864
            Base::Vector2d pnt = Py::toVector2d(*it);
865
            interpPoints.emplace_back(pnt.x,pnt.y);
866
        }
867

868
        Geom2dBSplineCurve* bspline = this->getGeom2dBSplineCurvePtr();
869
        std::vector<gp_Vec2d> tangents;
870
        bspline->getCardinalSplineTangents(interpPoints, parameter, tangents);
871

872
        Py::List vec;
873
        for (gp_Vec2d it : tangents) {
874
            vec.append(Base::Vector2dPy::create(it.X(), it.Y()));
875
        }
876
        return Py::new_reference_to(vec);
877
    }
878

879
    PyErr_Clear();
880
    static const std::array<const char *, 3> kwds_interp2 {"Points", "Parameters", nullptr};
881
    if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "OO", kwds_interp2, &pts, &tgs)) {
882
        Py::Sequence list(pts);
883
        std::vector<gp_Pnt2d> interpPoints;
884
        interpPoints.reserve(list.size());
885
        for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
886
            Base::Vector2d pnt = Py::toVector2d(*it);
887
            interpPoints.emplace_back(pnt.x,pnt.y);
888
        }
889

890
        Py::Sequence list2(tgs);
891
        std::vector<double> parameters;
892
        parameters.reserve(list2.size());
893
        for (Py::Sequence::iterator it = list2.begin(); it != list2.end(); ++it) {
894
            Py::Float p(*it);
895
            parameters.push_back(static_cast<double>(p));
896
        }
897

898
        Geom2dBSplineCurve* bspline = this->getGeom2dBSplineCurvePtr();
899
        std::vector<gp_Vec2d> tangents;
900
        bspline->getCardinalSplineTangents(interpPoints, parameters, tangents);
901

902
        Py::List vec;
903
        for (gp_Vec2d it : tangents) {
904
            vec.append(Base::Vector2dPy::create(it.X(), it.Y()));
905
        }
906
        return Py::new_reference_to(vec);
907
    }
908

909
    return nullptr;
910
}
911

912
PyObject* BSplineCurve2dPy::interpolate(PyObject *args, PyObject *kwds)
913
{
914
    PyObject* obj;
915
    PyObject* par = nullptr;
916
    double tol3d = Precision::Approximation();
917
    PyObject* periodic = Py_False;
918
    PyObject* t1 = nullptr; PyObject* t2 = nullptr;
919
    PyObject* ts = nullptr; PyObject* fl = nullptr;
920

921
    static const std::array<const char *, 9> kwds_interp{"Points", "PeriodicFlag", "Tolerance", "InitialTangent",
922
                                                         "FinalTangent", "Tangents", "TangentFlags", "Parameters",
923
                                                         nullptr};
924

925
    if (!Base::Wrapped_ParseTupleAndKeywords(args, kwds, "O|O!dO!O!OOO",kwds_interp,
926
                                             &obj, &PyBool_Type, &periodic, &tol3d,
927
                                             Base::Vector2dPy::type_object(), &t1,
928
                                             Base::Vector2dPy::type_object(), &t2,
929
                                             &ts, &fl, &par)) {
930
        return nullptr;
931
    }
932

933
    try {
934
        Py::Sequence list(obj);
935
        Handle(TColgp_HArray1OfPnt2d) interpolationPoints = new TColgp_HArray1OfPnt2d(1, list.size());
936
        Standard_Integer index = 1;
937
        for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
938
            Base::Vector2d pnt = Py::toVector2d(*it);
939
            interpolationPoints->SetValue(index++, gp_Pnt2d(pnt.x,pnt.y));
940
        }
941

942
        if (interpolationPoints->Length() < 2) {
943
            Standard_Failure::Raise("not enough points given");
944
        }
945

946
        Handle(TColStd_HArray1OfReal) parameters;
947
        if (par) {
948
            Py::Sequence plist(par);
949
            parameters = new TColStd_HArray1OfReal(1, plist.size());
950
            Standard_Integer pindex = 1;
951
            for (Py::Sequence::iterator it = plist.begin(); it != plist.end(); ++it) {
952
                Py::Float f(*it);
953
                parameters->SetValue(pindex++, static_cast<double>(f));
954
            }
955
        }
956

957
        std::unique_ptr<Geom2dAPI_Interpolate> aBSplineInterpolation;
958
        if (parameters.IsNull()) {
959
            aBSplineInterpolation = std::make_unique<Geom2dAPI_Interpolate>(
960
                interpolationPoints,
961
                Base::asBoolean(periodic), tol3d
962
            );
963
        }
964
        else {
965
            aBSplineInterpolation = std::make_unique<Geom2dAPI_Interpolate>(
966
                interpolationPoints, parameters,
967
                Base::asBoolean(periodic), tol3d
968
            );
969
        }
970

971
        if (t1 && t2) {
972
            Base::Vector2d v1 = Py::toVector2d(t1);
973
            Base::Vector2d v2 = Py::toVector2d(t2);
974
            gp_Vec2d initTangent(v1.x,v1.y), finalTangent(v2.x,v2.y);
975
            aBSplineInterpolation->Load(initTangent, finalTangent);
976
        }
977
        else if (ts && fl) {
978
            Py::Sequence tlist(ts);
979
            TColgp_Array1OfVec2d tangents(1, tlist.size());
980
            Standard_Integer index = 1;
981
            for (Py::Sequence::iterator it = tlist.begin(); it != tlist.end(); ++it) {
982
                Base::Vector2d vec = Py::toVector2d(*it);
983
                tangents.SetValue(index++, gp_Vec2d(vec.x,vec.y));
984
            }
985

986
            Py::Sequence flist(fl);
987
            Handle(TColStd_HArray1OfBoolean) tangentFlags = new TColStd_HArray1OfBoolean(1, flist.size());
988
            Standard_Integer findex = 1;
989
            for (Py::Sequence::iterator it = flist.begin(); it != flist.end(); ++it) {
990
                Py::Boolean flag(*it);
991
                tangentFlags->SetValue(findex++, static_cast<bool>(flag) ? Standard_True : Standard_False);
992
            }
993

994
            aBSplineInterpolation->Load(tangents, tangentFlags);
995
        }
996

997
        aBSplineInterpolation->Perform();
998
        if (aBSplineInterpolation->IsDone()) {
999
            Handle(Geom2d_BSplineCurve) aBSplineCurve(aBSplineInterpolation->Curve());
1000
            this->getGeom2dBSplineCurvePtr()->setHandle(aBSplineCurve);
1001
            Py_Return;
1002
        }
1003
        else {
1004
            Standard_Failure::Raise("failed to interpolate points");
1005
            return nullptr; // goes to the catch block
1006
        }
1007
    }
1008
    catch (Standard_Failure& e) {
1009
        std::string err = e.GetMessageString();
1010
        if (err.empty()) err = e.DynamicType()->Name();
1011
        PyErr_SetString(PartExceptionOCCError, err.c_str());
1012
        return nullptr;
1013
    }
1014
}
1015

1016
PyObject* BSplineCurve2dPy::buildFromPoles(PyObject *args)
1017
{
1018
    PyObject* obj;
1019
    int degree = 3;
1020
    PyObject* periodic = Py_False;
1021
    PyObject* interpolate = Py_False;
1022
    if (!PyArg_ParseTuple(args, "O|O!iO!",&obj, &PyBool_Type, &periodic, &degree, &PyBool_Type, interpolate))
1023
        return nullptr;
1024
    try {
1025
        Py::Sequence list(obj);
1026
        TColgp_Array1OfPnt2d poles(1, list.size());
1027
        Standard_Integer index = 1;
1028
        for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
1029
            Base::Vector2d pnt = Py::toVector2d(*it);
1030
            poles(index++) = gp_Pnt2d(pnt.x,pnt.y);
1031
        }
1032

1033
        if (poles.Length() <= degree)
1034
            degree = poles.Length()-1;
1035

1036
        if (Base::asBoolean(periodic)) {
1037
            int mult;
1038
            int len;
1039
            if (Base::asBoolean(interpolate)) {
1040
                mult = degree;
1041
                len = poles.Length() - mult + 2;
1042
            }
1043
            else {
1044
                mult = 1;
1045
                len = poles.Length() + 1;
1046
            }
1047
            TColStd_Array1OfReal knots(1, len);
1048
            TColStd_Array1OfInteger mults(1, len);
1049
            for (int i=1; i<=knots.Length(); i++){
1050
                knots.SetValue(i,(double)(i-1)/(knots.Length()-1));
1051
                mults.SetValue(i,1);
1052
            }
1053
            mults.SetValue(1, mult);
1054
            mults.SetValue(knots.Length(), mult);
1055

1056
            Handle(Geom2d_BSplineCurve) spline = new Geom2d_BSplineCurve(poles, knots, mults, degree, Standard_True);
1057
            if (!spline.IsNull()) {
1058
                this->getGeom2dBSplineCurvePtr()->setHandle(spline);
1059
                Py_Return;
1060
            }
1061
            else {
1062
                Standard_Failure::Raise("failed to create spline");
1063
                return nullptr; // goes to the catch block
1064
            }
1065
        }
1066
        else {
1067
            TColStd_Array1OfReal knots(1, poles.Length()+degree+1-2*(degree));
1068
            TColStd_Array1OfInteger mults(1, poles.Length()+degree+1-2*(degree));
1069
            for (int i=1; i<=knots.Length(); i++){
1070
                knots.SetValue(i,(double)(i-1)/(knots.Length()-1));
1071
                mults.SetValue(i,1);
1072
            }
1073
            mults.SetValue(1, degree+1);
1074
            mults.SetValue(knots.Length(), degree+1);
1075

1076
            Handle(Geom2d_BSplineCurve) spline = new Geom2d_BSplineCurve(poles, knots, mults, degree, Standard_False);
1077
            if (!spline.IsNull()) {
1078
                this->getGeom2dBSplineCurvePtr()->setHandle(spline);
1079
                Py_Return;
1080
            }
1081
            else {
1082
                Standard_Failure::Raise("failed to create spline");
1083
                return nullptr; // goes to the catch block
1084
            }
1085
        }
1086
    }
1087
    catch (Standard_Failure& e) {
1088
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
1089
        return nullptr;
1090
    }
1091
}
1092

1093
PyObject* BSplineCurve2dPy::buildFromPolesMultsKnots(PyObject *args, PyObject *keywds)
1094
{
1095
    static const std::array<const char *, 7> kwlist{"poles", "mults", "knots", "periodic", "degree", "weights",
1096
                                                    nullptr};
1097
    PyObject* periodic = Py_False;
1098
    PyObject* poles = Py_None;
1099
    PyObject* mults = Py_None;
1100
    PyObject* knots = Py_None;
1101
    PyObject* weights = Py_None;
1102
    int degree = 3;
1103
    int number_of_poles = 0;
1104
    int number_of_knots = 0;
1105
    int sum_of_mults = 0;
1106
    if (!Base::Wrapped_ParseTupleAndKeywords(args, keywds, "O|OOO!iO", kwlist,
1107
        &poles, &mults, &knots,
1108
        &PyBool_Type, &periodic,
1109
        &degree, &weights)) {
1110
        return nullptr;
1111
    }
1112
    try {
1113
        // poles have to be present
1114
        Py::Sequence list(poles);
1115

1116
        number_of_poles = list.size();
1117
        if ((number_of_poles) < 2) {
1118
            Standard_Failure::Raise("need two or more poles");
1119
            return nullptr;
1120
        }
1121
        TColgp_Array1OfPnt2d occpoles(1, number_of_poles);
1122
        Standard_Integer index = 1;
1123
        for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
1124
            Base::Vector2d pnt = Py::toVector2d(*it);
1125
            occpoles(index++) = gp_Pnt2d(pnt.x,pnt.y);
1126
        }
1127
        //Calculate the number of knots
1128
        if (mults != Py_None && knots != Py_None) {
1129
            number_of_knots = PyObject_Length(mults);
1130
            if (PyObject_Length(knots) != number_of_knots) {
1131
                Standard_Failure::Raise("number of knots and mults mismatch");
1132
                return nullptr;
1133
            }
1134
        }
1135
        else {
1136
            if (mults != Py_None) {
1137
                number_of_knots = PyObject_Length(mults);
1138
            }
1139
            else {
1140
                if (knots != Py_None) { number_of_knots = PyObject_Length(knots); }
1141
                else { //guess number of knots
1142
                    if (Base::asBoolean(periodic)) {
1143
                        if (number_of_poles < degree) {degree = number_of_poles+1;}
1144
                        number_of_knots = number_of_poles+1;
1145
                    }
1146
                    else {
1147
                        if (number_of_poles <= degree) {degree = number_of_poles-1;}
1148
                        number_of_knots = number_of_poles-degree+1;
1149
                    }
1150
                }
1151
            }
1152
        }
1153
        TColStd_Array1OfInteger occmults(1,number_of_knots);
1154
        TColStd_Array1OfReal occknots(1,number_of_knots);
1155
        TColStd_Array1OfReal occweights(1,number_of_poles);
1156
        if (mults != Py_None) { //mults are given
1157
            Py::Sequence multssq(mults);
1158
            Standard_Integer index = 1;
1159
            for (Py::Sequence::iterator it = multssq.begin(); it != multssq.end() && index <= occmults.Length(); ++it) {
1160
                Py::Long mult(*it);
1161
                if (index < occmults.Length() || !Base::asBoolean(periodic)) {
1162
                    sum_of_mults += (int)mult; //sum up the mults to compare them against the number of poles later
1163
                }
1164
                occmults(index++) = mult;
1165
            }
1166
        }
1167
        else { //mults are 1 or degree+1 at the ends
1168
            for (int i=1; i<=occmults.Length(); i++){
1169
                occmults.SetValue(i,1);
1170
            }
1171
            if (!Base::asBoolean(periodic) && occmults.Length() > 0) {
1172
                occmults.SetValue(1, degree+1);
1173
                occmults.SetValue(occmults.Length(), degree+1);
1174
                sum_of_mults = occmults.Length()+2*degree;
1175
            }
1176
            else { sum_of_mults = occmults.Length()-1;}
1177
        }
1178
        if (knots != Py_None) { //knots are given
1179
            Py::Sequence knotssq(knots);
1180
            index = 1;
1181
            for (Py::Sequence::iterator it = knotssq.begin(); it != knotssq.end() && index <= occknots.Length(); ++it) {
1182
                Py::Float knot(*it);
1183
                occknots(index++) = knot;
1184
            }
1185
        }
1186
        else { // knotes are uniformly spaced 0..1 if not given
1187
            for (int i=1; i<=occknots.Length(); i++){
1188
                occknots.SetValue(i,(double)(i-1)/(occknots.Length()-1));
1189
            }
1190
        }
1191
        if (weights != Py_None) { //weights are given
1192
            if (PyObject_Length(weights) != number_of_poles) {
1193
                Standard_Failure::Raise("number of poles and weights mismatch");
1194
                return nullptr;
1195
            } //complain about mismatch
1196
            Py::Sequence weightssq(weights);
1197
            Standard_Integer index = 1;
1198
            for (Py::Sequence::iterator it = weightssq.begin(); it != weightssq.end(); ++it) {
1199
                Py::Float weight(*it);
1200
                occweights(index++) = weight;
1201
            }
1202
        }
1203
        else { // weights are 1.0
1204
            for (int i=1; i<=occweights.Length(); i++){
1205
                occweights.SetValue(i,1.0);
1206
            }
1207
        }
1208
        // check if the number of poles matches the sum of mults
1209
        if (((Base::asBoolean(periodic)) && sum_of_mults != number_of_poles) ||
1210
             (!Base::asBoolean(periodic) && sum_of_mults - degree -1 != number_of_poles)) {
1211
            Standard_Failure::Raise("number of poles and sum of mults mismatch");
1212
            return(nullptr);
1213
        }
1214

1215
        Handle(Geom2d_BSplineCurve) spline = new Geom2d_BSplineCurve(occpoles, occweights, occknots,
1216
                                                                     occmults, degree, Base::asBoolean(periodic));
1217
        if (!spline.IsNull()) {
1218
            this->getGeom2dBSplineCurvePtr()->setHandle(spline);
1219
            Py_Return;
1220
        }
1221
        else {
1222
            Standard_Failure::Raise("failed to create spline");
1223
            return nullptr; // goes to the catch block
1224
        }
1225
    }
1226
    catch (const Standard_Failure& e) {
1227
        Standard_CString msg = e.GetMessageString();
1228
        PyErr_SetString(PartExceptionOCCError, msg  ? msg : "");
1229
        return nullptr;
1230
    }
1231
}
1232

1233
PyObject* BSplineCurve2dPy::toBezier(PyObject *args)
1234
{
1235
    if (!PyArg_ParseTuple(args, ""))
1236
        return nullptr;
1237

1238
    Handle(Geom2d_BSplineCurve) spline = Handle(Geom2d_BSplineCurve)::DownCast
1239
        (this->getGeom2dBSplineCurvePtr()->handle());
1240
    Geom2dConvert_BSplineCurveToBezierCurve crt(spline);
1241

1242
    Py::List list;
1243
    Standard_Integer arcs = crt.NbArcs();
1244
    for (Standard_Integer i=1; i<=arcs; i++) {
1245
        Handle(Geom2d_BezierCurve) bezier = crt.Arc(i);
1246
        list.append(Py::asObject(new BezierCurve2dPy(new Geom2dBezierCurve(bezier))));
1247
    }
1248

1249
    return Py::new_reference_to(list);
1250
}
1251

1252
PyObject* BSplineCurve2dPy::join(PyObject *args)
1253
{
1254
    PyObject* c;
1255
    if (!PyArg_ParseTuple(args, "O!", &BSplineCurve2dPy::Type, &c))
1256
        return nullptr;
1257

1258
    Geom2dBSplineCurve* curve1 = this->getGeom2dBSplineCurvePtr();
1259
    BSplineCurve2dPy* curve2 = static_cast<BSplineCurve2dPy*>(c);
1260
    Handle(Geom2d_BSplineCurve) spline = Handle(Geom2d_BSplineCurve)::DownCast
1261
        (curve2->getGeom2dBSplineCurvePtr()->handle());
1262

1263
    bool ok = curve1->join(spline);
1264

1265
    return PyBool_FromLong(ok ? 1 : 0);
1266
}
1267

1268
PyObject* BSplineCurve2dPy::makeC1Continuous(PyObject *args)
1269
{
1270
    double tol = Precision::Approximation();
1271
    if (!PyArg_ParseTuple(args, "|d", &tol))
1272
        return nullptr;
1273

1274
    try {
1275
        Geom2dBSplineCurve* spline = this->getGeom2dBSplineCurvePtr();
1276
        spline->makeC1Continuous(tol);
1277
        Py_Return;
1278
    }
1279
    catch (Standard_Failure& e) {
1280
        std::string err = e.GetMessageString();
1281
        if (err.empty()) err = e.DynamicType()->Name();
1282
        PyErr_SetString(PartExceptionOCCError, err.c_str());
1283
        return nullptr;
1284
    }
1285
}
1286

1287
PyObject* BSplineCurve2dPy::getCustomAttributes(const char* /*attr*/) const
1288
{
1289
    return nullptr;
1290
}
1291

1292
int BSplineCurve2dPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
1293
{
1294
    return 0;
1295
}
1296

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

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

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

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