FreeCAD

Форк
0
/
BSplineSurfacePyImp.cpp 
1728 строк · 57.0 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2008 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 <Geom_BSplineSurface.hxx>
26
# include <GeomAbs_Shape.hxx>
27
# include <GeomAPI_PointsToBSplineSurface.hxx>
28
# include <Precision.hxx>
29
# include <TColgp_Array1OfPnt.hxx>
30
# include <TColgp_Array2OfPnt.hxx>
31
# include <TColStd_Array1OfReal.hxx>
32
# include <TColStd_Array2OfReal.hxx>
33
# include <TColStd_Array1OfInteger.hxx>
34
#endif
35
# include <GeomFill_NSections.hxx>
36

37
#include <Base/GeometryPyCXX.h>
38
#include <Base/PyWrapParseTupleAndKeywords.h>
39
#include <Base/VectorPy.h>
40

41
#include "BSplineSurfacePy.h"
42
#include "BSplineSurfacePy.cpp"
43
#include "BSplineCurvePy.h"
44
#include "OCCError.h"
45

46

47
using namespace Part;
48

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

55
PyObject *BSplineSurfacePy::PyMake(struct _typeobject *, PyObject *, PyObject *)  // Python wrapper
56
{
57
    // create a new instance of BSplineSurfacePy and the Twin object
58
    return new BSplineSurfacePy(new GeomBSplineSurface);
59
}
60

61
// constructor method
62
int BSplineSurfacePy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
63
{
64
    return 0;
65
}
66

67
PyObject* BSplineSurfacePy::bounds(PyObject *args)
68
{
69
    if (!PyArg_ParseTuple(args, ""))
70
        return nullptr;
71

72
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
73
        (getGeometryPtr()->handle());
74
    Py::Tuple bound(4);
75
    Standard_Real u1,u2,v1,v2;
76
    surf->Bounds(u1,u2,v1,v2);
77
    bound.setItem(0,Py::Float(u1));
78
    bound.setItem(1,Py::Float(u2));
79
    bound.setItem(2,Py::Float(v1));
80
    bound.setItem(3,Py::Float(v2));
81
    return Py::new_reference_to(bound);
82
}
83

84
PyObject* BSplineSurfacePy::isURational(PyObject *args)
85
{
86
    if (!PyArg_ParseTuple(args, ""))
87
        return nullptr;
88

89
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
90
        (getGeometryPtr()->handle());
91
    Standard_Boolean val = surf->IsURational();
92
    return PyBool_FromLong(val ? 1 : 0);
93
}
94

95
PyObject* BSplineSurfacePy::isVRational(PyObject *args)
96
{
97
    if (!PyArg_ParseTuple(args, ""))
98
        return nullptr;
99

100
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
101
        (getGeometryPtr()->handle());
102
    Standard_Boolean val = surf->IsVRational();
103
    return PyBool_FromLong(val ? 1 : 0);
104
}
105

106
PyObject* BSplineSurfacePy::isUPeriodic(PyObject *args)
107
{
108
    if (!PyArg_ParseTuple(args, ""))
109
        return nullptr;
110

111
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
112
        (getGeometryPtr()->handle());
113
    Standard_Boolean val = surf->IsUPeriodic();
114
    return PyBool_FromLong(val ? 1 : 0);
115
}
116

117
PyObject* BSplineSurfacePy::isVPeriodic(PyObject *args)
118
{
119
    if (!PyArg_ParseTuple(args, ""))
120
        return nullptr;
121

122
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
123
        (getGeometryPtr()->handle());
124
    Standard_Boolean val = surf->IsVPeriodic();
125
    return PyBool_FromLong(val ? 1 : 0);
126
}
127

128
PyObject* BSplineSurfacePy::isUClosed(PyObject *args)
129
{
130
    if (!PyArg_ParseTuple(args, ""))
131
        return nullptr;
132

133
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
134
        (getGeometryPtr()->handle());
135
    Standard_Boolean val = surf->IsUClosed();
136
    return PyBool_FromLong(val ? 1 : 0);
137
}
138

139
PyObject* BSplineSurfacePy::isVClosed(PyObject *args)
140
{
141
    if (!PyArg_ParseTuple(args, ""))
142
        return nullptr;
143

144
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
145
        (getGeometryPtr()->handle());
146
    Standard_Boolean val = surf->IsVPeriodic();
147
    return PyBool_FromLong(val ? 1 : 0);
148
}
149

150
PyObject* BSplineSurfacePy::increaseDegree(PyObject *args)
151
{
152
    int udegree, vdegree;
153
    if (!PyArg_ParseTuple(args, "ii",&udegree,&vdegree))
154
        return nullptr;
155

156
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
157
        (getGeometryPtr()->handle());
158
    surf->IncreaseDegree(udegree,vdegree);
159
    Py_Return;
160
}
161

162
PyObject* BSplineSurfacePy::increaseUMultiplicity(PyObject *args)
163
{
164
    int mult=-1;
165
    int start, end;
166
    if (!PyArg_ParseTuple(args, "ii|i", &start, &end, &mult))
167
        return nullptr;
168

169
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
170
        (getGeometryPtr()->handle());
171
    if (mult == -1) {
172
        mult = end;
173
        surf->IncreaseUMultiplicity(start, mult);
174
    }
175
    else {
176
        surf->IncreaseUMultiplicity(start, end, mult);
177
    }
178

179
    Py_Return;
180
}
181

182
PyObject* BSplineSurfacePy::increaseVMultiplicity(PyObject *args)
183
{
184
    int mult=-1;
185
    int start, end;
186
    if (!PyArg_ParseTuple(args, "ii|i", &start, &end, &mult))
187
        return nullptr;
188

189
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
190
        (getGeometryPtr()->handle());
191
    if (mult == -1) {
192
        mult = end;
193
        surf->IncreaseVMultiplicity(start, mult);
194
    }
195
    else {
196
        surf->IncreaseVMultiplicity(start, end, mult);
197
    }
198

199
    Py_Return;
200
}
201

202
PyObject* BSplineSurfacePy::incrementUMultiplicity(PyObject *args)
203
{
204
    int start, end, mult;
205
    if (!PyArg_ParseTuple(args, "iii", &start, &end, &mult))
206
        return nullptr;
207

208
    try {
209
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
210
            (getGeometryPtr()->handle());
211
        surf->IncrementUMultiplicity(start, end, mult);
212
    }
213
    catch (Standard_Failure& e) {
214
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
215
        return nullptr;
216
    }
217

218
    Py_Return;
219
}
220

221
PyObject* BSplineSurfacePy::incrementVMultiplicity(PyObject *args)
222
{
223
    int start, end, mult;
224
    if (!PyArg_ParseTuple(args, "iii", &start, &end, &mult))
225
        return nullptr;
226

227
    try {
228
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
229
            (getGeometryPtr()->handle());
230
        surf->IncrementVMultiplicity(start, end, mult);
231
    }
232
    catch (Standard_Failure& e) {
233
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
234
        return nullptr;
235
    }
236

237
    Py_Return;
238
}
239

240
PyObject* BSplineSurfacePy::insertUKnot(PyObject *args)
241
{
242
    double U, tol = 0.0;
243
    int M=1;
244
    PyObject* add = Py_True;
245
    if (!PyArg_ParseTuple(args, "did|O!", &U, &M, &tol, &PyBool_Type, &add))
246
        return nullptr;
247

248
    try {
249
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
250
            (getGeometryPtr()->handle());
251
        surf->InsertUKnot(U, M, tol, Base::asBoolean(add));
252
    }
253
    catch (Standard_Failure& e) {
254
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
255
        return nullptr;
256
    }
257

258
    Py_Return;
259
}
260

261
PyObject* BSplineSurfacePy::insertUKnots(PyObject *args)
262
{
263
    double tol = 0.0;
264
    PyObject* add = Py_True;
265
    PyObject* obj1;
266
    PyObject* obj2;
267
    if (!PyArg_ParseTuple(args, "OO|dO!", &obj1,
268
                                          &obj2,
269
                                          &tol, &PyBool_Type, &add))
270
        return nullptr;
271

272
    try {
273
        Py::Sequence knots(obj1);
274
        TColStd_Array1OfReal k(1,knots.size());
275
        int index=1;
276
        for (Py::Sequence::iterator it = knots.begin(); it != knots.end(); ++it) {
277
            Py::Float val(*it);
278
            k(index++) = (double)val;
279
        }
280
        Py::Sequence mults(obj2);
281
        TColStd_Array1OfInteger m(1,mults.size());
282
        index=1;
283
        for (Py::Sequence::iterator it = mults.begin(); it != mults.end(); ++it) {
284
            Py::Long val(*it);
285
            m(index++) = (int)val;
286
        }
287

288
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
289
            (getGeometryPtr()->handle());
290
        surf->InsertUKnots(k, m, tol, Base::asBoolean(add));
291
        Py_Return;
292
    }
293
    catch (Standard_Failure& e) {
294
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
295
        return nullptr;
296
    }
297

298
    Py_Return;
299
}
300

301
PyObject* BSplineSurfacePy::insertVKnot(PyObject *args)
302
{
303
    double V, tol = 0.0;
304
    int M=1;
305
    PyObject* add = Py_True;
306
    if (!PyArg_ParseTuple(args, "did|O!", &V, &M, &tol, &PyBool_Type, &add))
307
        return nullptr;
308

309
    try {
310
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
311
            (getGeometryPtr()->handle());
312
        surf->InsertVKnot(V, M, tol, Base::asBoolean(add));
313
    }
314
    catch (Standard_Failure& e) {
315
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
316
        return nullptr;
317
    }
318

319
    Py_Return;
320
}
321

322
PyObject* BSplineSurfacePy::insertVKnots(PyObject *args)
323
{
324
    double tol = 0.0;
325
    PyObject* add = Py_True;
326
    PyObject* obj1;
327
    PyObject* obj2;
328
    if (!PyArg_ParseTuple(args, "OO|dO!", &obj1,
329
                                          &obj2,
330
                                          &tol, &PyBool_Type, &add))
331
        return nullptr;
332

333
    try {
334
        Py::Sequence knots(obj1);
335
        TColStd_Array1OfReal k(1,knots.size());
336
        int index=1;
337
        for (Py::Sequence::iterator it = knots.begin(); it != knots.end(); ++it) {
338
            Py::Float val(*it);
339
            k(index++) = (double)val;
340
        }
341
        Py::Sequence mults(obj2);
342
        TColStd_Array1OfInteger m(1,mults.size());
343
        index=1;
344
        for (Py::Sequence::iterator it = mults.begin(); it != mults.end(); ++it) {
345
            Py::Long val(*it);
346
            m(index++) = (int)val;
347
        }
348

349
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
350
            (getGeometryPtr()->handle());
351
        surf->InsertVKnots(k, m, tol, Base::asBoolean(add));
352
        Py_Return;
353
    }
354
    catch (Standard_Failure& e) {
355
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
356
        return nullptr;
357
    }
358

359
    Py_Return;
360
}
361

362
PyObject* BSplineSurfacePy::removeUKnot(PyObject *args)
363
{
364
    double tol;
365
    int Index,M;
366
    if (!PyArg_ParseTuple(args, "iid", &Index, &M, &tol))
367
        return nullptr;
368

369
    try {
370
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
371
            (getGeometryPtr()->handle());
372
        Standard_Boolean ok = surf->RemoveUKnot(Index,M,tol);
373
        return PyBool_FromLong(ok ? 1 : 0);
374
    }
375
    catch (Standard_Failure& e) {
376
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
377
        return nullptr;
378
    }
379
}
380

381
PyObject* BSplineSurfacePy::removeVKnot(PyObject *args)
382
{
383
    double tol;
384
    int Index,M;
385
    if (!PyArg_ParseTuple(args, "iid", &Index, &M, &tol))
386
        return nullptr;
387

388
    try {
389
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
390
            (getGeometryPtr()->handle());
391
        Standard_Boolean ok = surf->RemoveVKnot(Index,M,tol);
392
        return PyBool_FromLong(ok ? 1 : 0);
393
    }
394
    catch (Standard_Failure& e) {
395
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
396
        return nullptr;
397
    }
398
}
399

400
PyObject* BSplineSurfacePy::segment(PyObject *args)
401
{
402
    double u1,u2,v1,v2;
403
    if (!PyArg_ParseTuple(args, "dddd", &u1,&u2,&v1,&v2))
404
        return nullptr;
405
    try {
406
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
407
            (getGeometryPtr()->handle());
408
        surf->Segment(u1,u2,v1,v2);
409
        Py_Return;
410
    }
411
    catch (Standard_Failure& e) {
412

413
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
414
        return nullptr;
415
    }
416
}
417

418
PyObject* BSplineSurfacePy::setUKnot(PyObject *args)
419
{
420
    int Index, M=-1;
421
    double K;
422
    if (!PyArg_ParseTuple(args, "id|i", &Index, &K, &M))
423
        return nullptr;
424

425
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
426
        (getGeometryPtr()->handle());
427
    if (M == -1) {
428
        surf->SetUKnot(Index, K);
429
    }
430
    else {
431
        surf->SetUKnot(Index, K, M);
432
    }
433

434
    Py_Return;
435
}
436

437
PyObject* BSplineSurfacePy::setVKnot(PyObject *args)
438
{
439
    int Index, M=-1;
440
    double K;
441
    if (!PyArg_ParseTuple(args, "id|i", &Index, &K, &M))
442
        return nullptr;
443

444
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
445
        (getGeometryPtr()->handle());
446
    if (M == -1) {
447
        surf->SetVKnot(Index, K);
448
    }
449
    else {
450
        surf->SetVKnot(Index, K, M);
451
    }
452

453
    Py_Return;
454
}
455

456
PyObject* BSplineSurfacePy::getUKnot(PyObject *args)
457
{
458
    int Index;
459
    if (!PyArg_ParseTuple(args, "i", &Index))
460
        return nullptr;
461

462
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
463
        (getGeometryPtr()->handle());
464
    double M = surf->UKnot(Index);
465

466
    return Py_BuildValue("d",M);
467
}
468

469
PyObject* BSplineSurfacePy::getVKnot(PyObject *args)
470
{
471
    int Index;
472
    if (!PyArg_ParseTuple(args, "i", &Index))
473
        return nullptr;
474

475
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
476
        (getGeometryPtr()->handle());
477
    double M = surf->VKnot(Index);
478

479
    return Py_BuildValue("d",M);
480
}
481

482
PyObject* BSplineSurfacePy::setUKnots(PyObject *args)
483
{
484
    PyObject* obj;
485
    if (!PyArg_ParseTuple(args, "O", &obj))
486
        return nullptr;
487
    try {
488
        Py::Sequence list(obj);
489
        TColStd_Array1OfReal k(1,list.size());
490
        int index=1;
491
        for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
492
            Py::Float val(*it);
493
            k(index++) = (double)val;
494
        }
495

496
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
497
            (getGeometryPtr()->handle());
498
        surf->SetUKnots(k);
499
        Py_Return;
500
    }
501
    catch (Standard_Failure& e) {
502
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
503
        return nullptr;
504
    }
505
}
506

507
PyObject* BSplineSurfacePy::setVKnots(PyObject *args)
508
{
509
    PyObject* obj;
510
    if (!PyArg_ParseTuple(args, "O", &obj))
511
        return nullptr;
512
    try {
513
        Py::Sequence list(obj);
514
        TColStd_Array1OfReal k(1,list.size());
515
        int index=1;
516
        for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
517
            Py::Float val(*it);
518
            k(index++) = (double)val;
519
        }
520

521
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
522
            (getGeometryPtr()->handle());
523
        surf->SetVKnots(k);
524
        Py_Return;
525
    }
526
    catch (Standard_Failure& e) {
527
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
528
        return nullptr;
529
    }
530
}
531

532
PyObject* BSplineSurfacePy::getUKnots(PyObject *args)
533
{
534
    if (!PyArg_ParseTuple(args, ""))
535
        return nullptr;
536
    try {
537
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
538
            (getGeometryPtr()->handle());
539
        TColStd_Array1OfReal w(1,surf->NbUKnots());
540
        surf->UKnots(w);
541
        Py::List knots;
542
        for (Standard_Integer i=w.Lower(); i<=w.Upper(); i++) {
543
            knots.append(Py::Float(w(i)));
544
        }
545
        return Py::new_reference_to(knots);
546
    }
547
    catch (Standard_Failure& e) {
548
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
549
        return nullptr;
550
    }
551
}
552

553
PyObject* BSplineSurfacePy::getVKnots(PyObject *args)
554
{
555
    if (!PyArg_ParseTuple(args, ""))
556
        return nullptr;
557
    try {
558
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
559
            (getGeometryPtr()->handle());
560
        TColStd_Array1OfReal w(1,surf->NbVKnots());
561
        surf->VKnots(w);
562
        Py::List knots;
563
        for (Standard_Integer i=w.Lower(); i<=w.Upper(); i++) {
564
            knots.append(Py::Float(w(i)));
565
        }
566
        return Py::new_reference_to(knots);
567
    }
568
    catch (Standard_Failure& e) {
569
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
570
        return nullptr;
571
    }
572
}
573

574
PyObject* BSplineSurfacePy::setPole(PyObject *args)
575
{
576
    int uindex, vindex;
577
    double weight=-1.0;
578
    PyObject* p;
579
    if (!PyArg_ParseTuple(args, "iiO!|d", &uindex,&vindex,&(Base::VectorPy::Type),&p,&weight))
580
        return nullptr;
581
    Base::Vector3d vec = static_cast<Base::VectorPy*>(p)->value();
582
    gp_Pnt pnt(vec.x, vec.y, vec.z);
583
    try {
584
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
585
            (getGeometryPtr()->handle());
586
        if (weight < 0.0)
587
            surf->SetPole(uindex,vindex,pnt);
588
        else
589
            surf->SetPole(uindex,vindex,pnt,weight);
590
        Py_Return;
591
    }
592
    catch (Standard_Failure& e) {
593
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
594
        return nullptr;
595
    }
596
}
597

598
PyObject* BSplineSurfacePy::setPoleCol(PyObject *args)
599
{
600
    int vindex;
601
    PyObject* obj;
602
    PyObject* obj2=nullptr;
603
    if (!PyArg_ParseTuple(args, "iO|O",&vindex,&obj,&obj2))
604
        return nullptr;
605
    try {
606
        Py::Sequence list(obj);
607
        TColgp_Array1OfPnt poles(1, list.size());
608
        int index=1;
609
        for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
610
            Py::Vector p(*it);
611
            Base::Vector3d v = p.toVector();
612
            poles(index++) = gp_Pnt(v.x,v.y,v.z);
613
        }
614

615
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
616
            (getGeometryPtr()->handle());
617
        if (!obj2) {
618
            surf->SetPoleCol(vindex, poles);
619
        }
620
        else {
621
            Py::Sequence list(obj2);
622
            TColStd_Array1OfReal weights(1, list.size());
623
            int index=1;
624
            for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
625
                weights(index++) = (double)Py::Float(*it);
626
            }
627
            surf->SetPoleCol(vindex, poles, weights);
628
        }
629

630
        Py_Return;
631
    }
632
    catch (Standard_Failure& e) {
633
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
634
        return nullptr;
635
    }
636
}
637

638
PyObject* BSplineSurfacePy::setPoleRow(PyObject *args)
639
{
640
    int uindex;
641
    PyObject* obj;
642
    PyObject* obj2=nullptr;
643
    if (!PyArg_ParseTuple(args, "iO|O",&uindex,&obj,&obj2))
644
        return nullptr;
645
    try {
646
        Py::Sequence list(obj);
647
        TColgp_Array1OfPnt poles(1, list.size());
648
        int index=1;
649
        for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
650
            Py::Vector p(*it);
651
            Base::Vector3d v = p.toVector();
652
            poles(index++) = gp_Pnt(v.x,v.y,v.z);
653
        }
654

655
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
656
            (getGeometryPtr()->handle());
657
        if (!obj2) {
658
            surf->SetPoleRow(uindex, poles);
659
        }
660
        else {
661
            Py::Sequence list(obj2);
662
            TColStd_Array1OfReal weights(1, list.size());
663
            int index=1;
664
            for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
665
                weights(index++) = (double)Py::Float(*it);
666
            }
667
            surf->SetPoleRow(uindex, poles, weights);
668
        }
669

670
        Py_Return;
671
    }
672
    catch (Standard_Failure& e) {
673
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
674
        return nullptr;
675
    }
676
}
677

678
PyObject* BSplineSurfacePy::getPole(PyObject *args)
679
{
680
    int uindex,vindex;
681
    if (!PyArg_ParseTuple(args, "ii", &uindex,&vindex))
682
        return nullptr;
683
    try {
684
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
685
            (getGeometryPtr()->handle());
686
        Standard_OutOfRange_Raise_if
687
            (uindex < 1 || uindex > surf->NbUPoles() ||
688
             vindex < 1 || vindex > surf->NbVPoles(), "Pole index out of range");
689
        gp_Pnt pnt = surf->Pole(uindex,vindex);
690
        Base::VectorPy* vec = new Base::VectorPy(Base::Vector3d(
691
            pnt.X(), pnt.Y(), pnt.Z()));
692
        return vec;
693
    }
694
    catch (Standard_Failure& e) {
695
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
696
        return nullptr;
697
    }
698
}
699

700
PyObject* BSplineSurfacePy::getPoles(PyObject *args)
701
{
702
    if (!PyArg_ParseTuple(args, ""))
703
        return nullptr;
704
    try {
705
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
706
            (getGeometryPtr()->handle());
707
        TColgp_Array2OfPnt p(1,surf->NbUPoles(),1,surf->NbVPoles());
708
        surf->Poles(p);
709
        Py::List poles;
710
        for (Standard_Integer i=p.LowerRow(); i<=p.UpperRow(); i++) {
711
            Py::List row;
712
            for (Standard_Integer j=p.LowerCol(); j<=p.UpperCol(); j++) {
713
                const gp_Pnt& pole = p(i,j);
714
                row.append(Py::asObject(new Base::VectorPy(
715
                    Base::Vector3d(pole.X(),pole.Y(),pole.Z()))));
716
            }
717
            poles.append(row);
718
        }
719
        return Py::new_reference_to(poles);
720
    }
721
    catch (Standard_Failure& e) {
722
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
723
        return nullptr;
724
    }
725
}
726

727
PyObject* BSplineSurfacePy::setWeight(PyObject *args)
728
{
729
    int uindex,vindex;
730
    double weight;
731
    if (!PyArg_ParseTuple(args, "iid",&uindex,&vindex,&weight))
732
        return nullptr;
733
    try {
734
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
735
            (getGeometryPtr()->handle());
736
        surf->SetWeight(uindex,vindex,weight);
737
        Py_Return;
738
    }
739
    catch (Standard_Failure& e) {
740
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
741
        return nullptr;
742
    }
743
}
744

745
PyObject* BSplineSurfacePy::setWeightCol(PyObject *args)
746
{
747
    int vindex;
748
    PyObject* obj;
749
    if (!PyArg_ParseTuple(args, "iO",&vindex,&obj))
750
        return nullptr;
751
    try {
752
        Py::Sequence list(obj);
753
        TColStd_Array1OfReal weights(1, list.size());
754
        int index=1;
755
        for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
756
            weights(index++) = (double)Py::Float(*it);
757
        }
758

759
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
760
            (getGeometryPtr()->handle());
761
        surf->SetWeightCol(vindex, weights);
762
        Py_Return;
763
    }
764
    catch (Standard_Failure& e) {
765
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
766
        return nullptr;
767
    }
768
}
769

770
PyObject* BSplineSurfacePy::setWeightRow(PyObject *args)
771
{
772
    int uindex;
773
    PyObject* obj;
774
    if (!PyArg_ParseTuple(args, "iO",&uindex,&obj))
775
        return nullptr;
776
    try {
777
        Py::Sequence list(obj);
778
        TColStd_Array1OfReal weights(1, list.size());
779
        int index=1;
780
        for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
781
            weights(index++) = (double)Py::Float(*it);
782
        }
783

784
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
785
            (getGeometryPtr()->handle());
786
        surf->SetWeightRow(uindex, weights);
787
        Py_Return;
788
    }
789
    catch (Standard_Failure& e) {
790
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
791
        return nullptr;
792
    }
793
}
794

795
PyObject* BSplineSurfacePy::getWeight(PyObject *args)
796
{
797
    int uindex,vindex;
798
    if (!PyArg_ParseTuple(args, "ii",&uindex,&vindex))
799
        return nullptr;
800
    try {
801
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
802
            (getGeometryPtr()->handle());
803
        Standard_OutOfRange_Raise_if
804
            (uindex < 1 || uindex > surf->NbUPoles() ||
805
             vindex < 1 || vindex > surf->NbVPoles(), "Weight index out of range");
806
        double w = surf->Weight(uindex,vindex);
807
        return Py_BuildValue("d", w);
808
    }
809
    catch (Standard_Failure& e) {
810
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
811
        return nullptr;
812
    }
813
}
814

815
PyObject* BSplineSurfacePy::getWeights(PyObject *args)
816
{
817
    if (!PyArg_ParseTuple(args, ""))
818
        return nullptr;
819
    try {
820
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
821
            (getGeometryPtr()->handle());
822
        TColStd_Array2OfReal w(1,surf->NbUPoles(),1,surf->NbVPoles());
823
        surf->Weights(w);
824
        Py::List weights;
825
        for (Standard_Integer i=w.LowerRow(); i<=w.UpperRow(); i++) {
826
            Py::List row;
827
            for (Standard_Integer j=w.LowerCol(); j<=w.UpperCol(); j++) {
828
                row.append(Py::Float(w(i,j)));
829
            }
830
            weights.append(row);
831
        }
832
        return Py::new_reference_to(weights);
833
    }
834
    catch (Standard_Failure& e) {
835
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
836
        return nullptr;
837
    }
838
}
839

840
PyObject* BSplineSurfacePy::getPolesAndWeights(PyObject *args)
841
{
842
    if (!PyArg_ParseTuple(args, ""))
843
        return nullptr;
844
    try {
845
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
846
            (getGeometryPtr()->handle());
847
        TColgp_Array2OfPnt p(1,surf->NbUPoles(),1,surf->NbVPoles());
848
        surf->Poles(p);
849
        TColStd_Array2OfReal w(1,surf->NbUPoles(),1,surf->NbVPoles());
850
        surf->Weights(w);
851

852
        Py::List poles;
853
        for (Standard_Integer i=p.LowerRow(); i<=p.UpperRow(); i++) {
854
            Py::List row;
855
            for (Standard_Integer j=p.LowerCol(); j<=p.UpperCol(); j++) {
856
                const gp_Pnt& pole = p(i,j);
857
                double weight = w(i,j);
858
                Py::Tuple t(4);
859
                t.setItem(0, Py::Float(pole.X()));
860
                t.setItem(1, Py::Float(pole.Y()));
861
                t.setItem(2, Py::Float(pole.Z()));
862
                t.setItem(3, Py::Float(weight));
863
                row.append(t);
864
            }
865
            poles.append(row);
866
        }
867
        return Py::new_reference_to(poles);
868
    }
869
    catch (Standard_Failure& e) {
870
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
871
        return nullptr;
872
    }
873
}
874

875
PyObject* BSplineSurfacePy::getResolution(PyObject *args)
876
{
877
    double tol;
878
    if (!PyArg_ParseTuple(args, "d", &tol))
879
        return nullptr;
880
    try {
881
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
882
            (getGeometryPtr()->handle());
883
        double utol, vtol;
884
        surf->Resolution(tol,utol,vtol);
885
        return Py_BuildValue("(dd)",utol,vtol);
886
    }
887
    catch (Standard_Failure& e) {
888
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
889
        return nullptr;
890
    }
891
}
892

893
PyObject* BSplineSurfacePy::movePoint(PyObject *args)
894
{
895
    double U,V;
896
    int uindex1, uindex2;
897
    int vindex1, vindex2;
898
    PyObject* pnt;
899
    if (!PyArg_ParseTuple(args, "ddO!iiii", &U, &V, &(Base::VectorPy::Type),&pnt,
900
                                            &uindex1, &uindex2,&vindex1, &vindex2))
901
        return nullptr;
902
    try {
903
        Base::Vector3d p = static_cast<Base::VectorPy*>(pnt)->value();
904
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
905
            (getGeometryPtr()->handle());
906
        int ufirst, ulast, vfirst, vlast;
907
        surf->MovePoint(U, V, gp_Pnt(p.x,p.y,p.z), uindex1, uindex2, vindex1, vindex2,
908
            ufirst, ulast, vfirst, vlast);
909
        return Py_BuildValue("(iiii)",ufirst, ulast, vfirst, vlast);
910
    }
911
    catch (Standard_Failure& e) {
912
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
913
        return nullptr;
914
    }
915
}
916

917
PyObject* BSplineSurfacePy::setUNotPeriodic(PyObject *args)
918
{
919
    if (!PyArg_ParseTuple(args, ""))
920
        return nullptr;
921
    try {
922
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
923
            (getGeometryPtr()->handle());
924
        surf->SetUNotPeriodic();
925
        Py_Return;
926
    }
927
    catch (Standard_Failure& e) {
928
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
929
        return nullptr;
930
    }
931
}
932

933
PyObject* BSplineSurfacePy::setVNotPeriodic(PyObject *args)
934
{
935
    if (!PyArg_ParseTuple(args, ""))
936
        return nullptr;
937
    try {
938
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
939
            (getGeometryPtr()->handle());
940
        surf->SetVNotPeriodic();
941
        Py_Return;
942
    }
943
    catch (Standard_Failure& e) {
944
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
945
        return nullptr;
946
    }
947
}
948

949
PyObject* BSplineSurfacePy::setUPeriodic(PyObject *args)
950
{
951
    if (!PyArg_ParseTuple(args, ""))
952
        return nullptr;
953
    try {
954
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
955
            (getGeometryPtr()->handle());
956
        surf->SetUPeriodic();
957
        Py_Return;
958
    }
959
    catch (Standard_Failure& e) {
960
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
961
        return nullptr;
962
    }
963
}
964

965
PyObject* BSplineSurfacePy::setVPeriodic(PyObject *args)
966
{
967
    if (!PyArg_ParseTuple(args, ""))
968
        return nullptr;
969
    try {
970
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
971
            (getGeometryPtr()->handle());
972
        surf->SetVPeriodic();
973
        Py_Return;
974
    }
975
    catch (Standard_Failure& e) {
976
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
977
        return nullptr;
978
    }
979
}
980

981
PyObject* BSplineSurfacePy::setUOrigin(PyObject *args)
982
{
983
    int index;
984
    if (!PyArg_ParseTuple(args, "i", &index))
985
        return nullptr;
986
    try {
987
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
988
            (getGeometryPtr()->handle());
989
        surf->SetUOrigin(index);
990
        Py_Return;
991
    }
992
    catch (Standard_Failure& e) {
993
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
994
        return nullptr;
995
    }
996
}
997

998
PyObject* BSplineSurfacePy::setVOrigin(PyObject *args)
999
{
1000
    int index;
1001
    if (!PyArg_ParseTuple(args, "i", &index))
1002
        return nullptr;
1003
    try {
1004
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
1005
            (getGeometryPtr()->handle());
1006
        surf->SetVOrigin(index);
1007
        Py_Return;
1008
    }
1009
    catch (Standard_Failure& e) {
1010
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
1011
        return nullptr;
1012
    }
1013
}
1014

1015
PyObject* BSplineSurfacePy::getUMultiplicity(PyObject *args)
1016
{
1017
    int index;
1018
    if (!PyArg_ParseTuple(args, "i", &index))
1019
        return nullptr;
1020
    try {
1021
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
1022
            (getGeometryPtr()->handle());
1023
        int mult = surf->UMultiplicity(index);
1024
        return Py_BuildValue("i", mult);
1025
    }
1026
    catch (Standard_Failure& e) {
1027
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
1028
        return nullptr;
1029
    }
1030
}
1031

1032
PyObject* BSplineSurfacePy::getVMultiplicity(PyObject *args)
1033
{
1034
    int index;
1035
    if (!PyArg_ParseTuple(args, "i", &index))
1036
        return nullptr;
1037
    try {
1038
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
1039
            (getGeometryPtr()->handle());
1040
        int mult = surf->VMultiplicity(index);
1041
        return Py_BuildValue("i", mult);
1042
    }
1043
    catch (Standard_Failure& e) {
1044
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
1045
        return nullptr;
1046
    }
1047
}
1048

1049
PyObject* BSplineSurfacePy::getUMultiplicities(PyObject *args)
1050
{
1051
    if (!PyArg_ParseTuple(args, ""))
1052
        return nullptr;
1053
    try {
1054
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
1055
            (getGeometryPtr()->handle());
1056
        TColStd_Array1OfInteger m(1,surf->NbUKnots());
1057
        surf->UMultiplicities(m);
1058
        Py::List mults;
1059
        for (Standard_Integer i=m.Lower(); i<=m.Upper(); i++) {
1060
            mults.append(Py::Long(m(i)));
1061
        }
1062
        return Py::new_reference_to(mults);
1063
    }
1064
    catch (Standard_Failure& e) {
1065
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
1066
        return nullptr;
1067
    }
1068
}
1069

1070
PyObject* BSplineSurfacePy::getVMultiplicities(PyObject *args)
1071
{
1072
    if (!PyArg_ParseTuple(args, ""))
1073
        return nullptr;
1074
    try {
1075
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
1076
            (getGeometryPtr()->handle());
1077
        TColStd_Array1OfInteger m(1,surf->NbVKnots());
1078
        surf->VMultiplicities(m);
1079
        Py::List mults;
1080
        for (Standard_Integer i=m.Lower(); i<=m.Upper(); i++) {
1081
            mults.append(Py::Long(m(i)));
1082
        }
1083
        return Py::new_reference_to(mults);
1084
    }
1085
    catch (Standard_Failure& e) {
1086
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
1087
        return nullptr;
1088
    }
1089
}
1090

1091
PyObject* BSplineSurfacePy::exchangeUV(PyObject *args)
1092
{
1093
    if (!PyArg_ParseTuple(args, ""))
1094
        return nullptr;
1095

1096
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
1097
        (getGeometryPtr()->handle());
1098
    surf->ExchangeUV();
1099
    Py_Return;
1100
}
1101

1102
PyObject* BSplineSurfacePy::reparametrize(PyObject * args)
1103
{
1104
    int u,v;
1105
    double tol = 0.000001;
1106
    if (!PyArg_ParseTuple(args, "ii|d", &u, &v, &tol))
1107
        return nullptr;
1108

1109
    // u,v must be at least 2
1110
    u = std::max<int>(u, 2);
1111
    v = std::max<int>(v, 2);
1112

1113
    try {
1114
        Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
1115
            (getGeometryPtr()->handle());
1116

1117
        double maxU = surf->UKnot(surf->NbUKnots()); // 1.0 if normalized surface
1118
        double maxV = surf->VKnot(surf->NbVKnots()); // 1.0 if normalized surface
1119

1120
        GeomBSplineSurface* geom = new GeomBSplineSurface();
1121
        Handle(Geom_BSplineSurface) spline = Handle(Geom_BSplineSurface)::DownCast
1122
            (geom->handle());
1123
        for (int i=1; i<u-1; i++) {
1124
            double U = i * 1.0 / (u-1.0);
1125
            spline->InsertUKnot(U,i,tol,Standard_True);
1126
        }
1127

1128
        for (int i=1; i<v-1; i++) {
1129
            double V = i * 1.0 / (v-1.0);
1130
            spline->InsertVKnot(V,i,tol,Standard_True);
1131
        }
1132

1133
        for (int j=0; j<u; j++) {
1134
            double U = j * maxU / (u-1.0);
1135
            double newU = j * 1.0 / (u-1.0);
1136
            for (int k=0; k<v; k++) {
1137
                double V = k * maxV / (v-1.0);
1138
                double newV = k * 1.0 / (v-1.0);
1139
                // Get UV point and move new surface UV point
1140
                gp_Pnt point = surf->Value(U,V);
1141
                int ufirst, ulast, vfirst, vlast;
1142
                spline->MovePoint(newU, newV, point, j+1, j+1, k+1, k+1, ufirst, ulast, vfirst, vlast);
1143
            }
1144
        }
1145

1146
        return new BSplineSurfacePy(geom);
1147
    }
1148
    catch (Standard_Failure& e) {
1149
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
1150
        return nullptr;
1151
    }
1152
}
1153

1154
PyObject* BSplineSurfacePy::approximate(PyObject *args, PyObject *kwds)
1155
{
1156
    PyObject* obj;
1157
    Standard_Integer degMin=3;
1158
    Standard_Integer degMax=8;
1159
    Standard_Integer continuity=2;
1160
    Standard_Real tol3d = Precision::Approximation();
1161
    const char* parType = "None";
1162
    Standard_Real weight1 = 1.0;
1163
    Standard_Real weight2 = 1.0;
1164
    Standard_Real weight3 = 1.0;
1165
    Standard_Real X0=0;
1166
    Standard_Real dX=0;
1167
    Standard_Real Y0=0;
1168
    Standard_Real dY=0;
1169

1170
    static const std::array<const char *, 14> kwds_interp{"Points", "DegMin", "DegMax", "Continuity", "Tolerance", "X0",
1171
                                                          "dX", "Y0", "dY", "ParamType", "LengthWeight",
1172
                                                          "CurvatureWeight", "TorsionWeight", nullptr};
1173

1174
    if (!Base::Wrapped_ParseTupleAndKeywords(args, kwds, "O|iiidddddsddd", kwds_interp, &obj, &degMin, &degMax,
1175
                                             &continuity, &tol3d, &X0, &dX, &Y0, &dY, &parType, &weight1, &weight2,
1176
                                             &weight3)) {
1177
        return nullptr;
1178
    }
1179
    try {
1180
        Py::Sequence list(obj);
1181
        Standard_Integer lu = list.size();
1182
        Py::Sequence col(list.getItem(0));
1183
        Standard_Integer lv = col.size();
1184
        TColgp_Array2OfPnt interpolationPoints(1, lu, 1, lv);
1185
        TColStd_Array2OfReal zPoints(1, lu, 1, lv);
1186
        //Base::Console().Message("lu=%d, lv=%d\n", lu, lv);
1187

1188
        Standard_Integer index1 = 0;
1189
        Standard_Integer index2 = 0;
1190
        for (Py::Sequence::iterator it1 = list.begin(); it1 != list.end(); ++it1) {
1191
            index1++;
1192
            index2=0;
1193
            Py::Sequence row(*it1);
1194
            for (Py::Sequence::iterator it2 = row.begin(); it2 != row.end(); ++it2) {
1195
                index2++;
1196
                if ((dX == 0) || (dY == 0)){
1197
                    Py::Vector v(*it2);
1198
                    Base::Vector3d pnt = v.toVector();
1199
                    gp_Pnt newPoint(pnt.x,pnt.y,pnt.z);
1200
                    interpolationPoints.SetValue(index1, index2, newPoint);
1201
                }
1202
                else {
1203
                    Standard_Real val = PyFloat_AsDouble((*it2).ptr());
1204
                    zPoints.SetValue(index1, index2, val);
1205
                }
1206
            }
1207
        }
1208

1209
        if (continuity<0 || continuity>2) {
1210
            Standard_Failure::Raise("continuity must be between 0 and 2");
1211
        }
1212

1213
        if (interpolationPoints.RowLength() < 2 || interpolationPoints.ColLength() < 2) {
1214
            Standard_Failure::Raise("not enough points given");
1215
        }
1216

1217
        GeomAbs_Shape c = GeomAbs_C2;
1218
        switch(continuity){
1219
        case 0:
1220
            c = GeomAbs_C0;
1221
            break;
1222
        case 1:
1223
            c = GeomAbs_C1;
1224
            break;
1225
        case 2:
1226
            c = GeomAbs_C2;
1227
            break;
1228
        }
1229

1230
        Approx_ParametrizationType pt;
1231
        std::string pstr = parType;
1232
        Standard_Boolean useParam = Standard_True;
1233
        if (pstr == "Uniform" )
1234
            pt = Approx_IsoParametric;
1235
        else if (pstr == "Centripetal" )
1236
            pt = Approx_Centripetal;
1237
        else if (pstr == "ChordLength" )
1238
            pt = Approx_ChordLength;
1239
        else
1240
            useParam = Standard_False;
1241

1242
        GeomAPI_PointsToBSplineSurface surInterpolation;
1243
        if (!(dX == 0) && !(dY == 0)) {
1244
            // dX and dY are not null : we use the zPoints method
1245
            surInterpolation.Init(zPoints, X0, dX, Y0, dY, degMin, degMax, c, tol3d);
1246
        }
1247
        else if (useParam) {
1248
            // a parametrization type has been supplied
1249
            surInterpolation.Init(interpolationPoints, pt, degMin, degMax, c, tol3d);
1250
        }
1251
        else if (!(weight1 == 0) || !(weight2 == 0) || !(weight3 == 0)) {
1252
            // one of the weights is not null, we use the smoothing algorithm
1253
            surInterpolation.Init(interpolationPoints, weight1, weight2, weight3, degMax, c, tol3d);
1254
        }
1255
        else {
1256
            // fallback to strandard method
1257
            surInterpolation.Init(interpolationPoints, degMin, degMax, c, tol3d);
1258
        }
1259
        Handle(Geom_BSplineSurface) sur(surInterpolation.Surface());
1260
        this->getGeomBSplineSurfacePtr()->setHandle(sur);
1261
        Py_Return;
1262
    }
1263
    catch (Standard_Failure& e) {
1264
        std::string err = e.GetMessageString();
1265
        if (err.empty()) err = e.DynamicType()->Name();
1266
        PyErr_SetString(PartExceptionOCCError, err.c_str());
1267
        return nullptr;
1268
    }
1269
}
1270

1271
PyObject* BSplineSurfacePy::interpolate(PyObject *args)
1272
{
1273
    PyObject* obj;
1274
    Standard_Real X0=0;
1275
    Standard_Real dX=0;
1276
    Standard_Real Y0=0;
1277
    Standard_Real dY=0;
1278

1279
    int len = PyTuple_GET_SIZE(args);
1280

1281
    if (!PyArg_ParseTuple(args, "O|dddd", &obj, &X0, &dX, &Y0, &dY))
1282
        return nullptr;
1283
    try {
1284
        Py::Sequence list(obj);
1285
        Standard_Integer lu = list.size();
1286
        Py::Sequence col(list.getItem(0));
1287
        Standard_Integer lv = col.size();
1288
        TColgp_Array2OfPnt interpolationPoints(1, lu, 1, lv);
1289
        TColStd_Array2OfReal zPoints(1, lu, 1, lv);
1290

1291
        Standard_Integer index1 = 0;
1292
        Standard_Integer index2 = 0;
1293
        for (Py::Sequence::iterator it1 = list.begin(); it1 != list.end(); ++it1) {
1294
            index1++;
1295
            index2=0;
1296
            Py::Sequence row(*it1);
1297
            for (Py::Sequence::iterator it2 = row.begin(); it2 != row.end(); ++it2) {
1298
                index2++;
1299
                if(len == 1){
1300
                    Py::Vector v(*it2);
1301
                    Base::Vector3d pnt = v.toVector();
1302
                    gp_Pnt newPoint(pnt.x,pnt.y,pnt.z);
1303
                    interpolationPoints.SetValue(index1, index2, newPoint);
1304
                }
1305
                else {
1306
                    Standard_Real val = PyFloat_AsDouble((*it2).ptr());
1307
                    zPoints.SetValue(index1, index2, val);
1308
                }
1309
            }
1310
        }
1311

1312
        if (interpolationPoints.RowLength() < 2 || interpolationPoints.ColLength() < 2) {
1313
            Standard_Failure::Raise("not enough points given");
1314
        }
1315

1316
        GeomAPI_PointsToBSplineSurface surInterpolation;
1317
        if(len == 1){
1318
            surInterpolation.Interpolate (interpolationPoints);
1319
        }
1320
        else {
1321
            surInterpolation.Interpolate(zPoints, X0, dX, Y0, dY);
1322
        }
1323
        Handle(Geom_BSplineSurface) sur(surInterpolation.Surface());
1324
        this->getGeomBSplineSurfacePtr()->setHandle(sur);
1325
        Py_Return;
1326
    }
1327
    catch (Standard_Failure& e) {
1328
        std::string err = e.GetMessageString();
1329
        if (err.empty()) err = e.DynamicType()->Name();
1330
        PyErr_SetString(PartExceptionOCCError, err.c_str());
1331
        return nullptr;
1332
    }
1333
}
1334

1335
PyObject* BSplineSurfacePy::buildFromPolesMultsKnots(PyObject *args, PyObject *keywds)
1336
{
1337
    static const std::array<const char *, 11> kwlist{"poles", "umults", "vmults", "uknots", "vknots", "uperiodic",
1338
                                                     "vperiodic", "udegree", "vdegree", "weights", nullptr};
1339
    PyObject* uperiodic = Py_False; // NOLINT
1340
    PyObject* vperiodic = Py_False; // NOLINT
1341
    PyObject* poles = Py_None;
1342
    PyObject* umults = Py_None;
1343
    PyObject* vmults = Py_None;
1344
    PyObject* uknots = Py_None;
1345
    PyObject* vknots = Py_None;
1346
    PyObject* weights = Py_None;
1347
    int udegree = 3;
1348
    int vdegree = 3;
1349
    int number_of_uknots = 0;
1350
    int number_of_vknots = 0;
1351
    int sum_of_umults = 0;
1352
    int sum_of_vmults = 0;
1353

1354
    if (!Base::Wrapped_ParseTupleAndKeywords(args, keywds, "OOO|OOO!O!iiO", kwlist,
1355
                                             &poles, &umults, &vmults, //required
1356
                                             &uknots, &vknots, //optional
1357
                                             &PyBool_Type, &uperiodic, &PyBool_Type, &vperiodic, //optional
1358
                                             &udegree, &vdegree, &weights)) {
1359
        return nullptr;
1360
    }
1361
    try {
1362
        Py::Sequence list(poles);
1363
        Standard_Integer lu = list.size();
1364
        Py::Sequence col(list.getItem(0));
1365
        Standard_Integer lv = col.size();
1366
        TColgp_Array2OfPnt occpoles(1, lu, 1, lv);
1367
        TColStd_Array2OfReal occweights(1, lu, 1, lv);
1368
        Standard_Boolean genweights = (weights==Py_None) ? Standard_True : Standard_False; //cache
1369
        Standard_Integer index1 = 0;
1370
        Standard_Integer index2 = 0;
1371
        for (Py::Sequence::iterator it1 = list.begin(); it1 != list.end(); ++it1) {
1372
            index1++;
1373
            index2=0;
1374
            Py::Sequence row(*it1);
1375
            for (Py::Sequence::iterator it2 = row.begin(); it2 != row.end(); ++it2) {
1376
                index2++;
1377
                Py::Vector v(*it2);
1378
                Base::Vector3d pnt = v.toVector();
1379
                gp_Pnt newPoint(pnt.x,pnt.y,pnt.z);
1380
                occpoles.SetValue(index1, index2, newPoint);
1381
                if (genweights) occweights.SetValue(index1, index2, 1.0); //set weights if they are not given
1382
            }
1383
        }
1384
        if (occpoles.RowLength() < 2 || occpoles.ColLength() < 2) {
1385
            Standard_Failure::Raise("not enough points given");
1386
        }
1387
        if (!genweights) {//copy the weights
1388
            Py::Sequence list(weights);
1389
            Standard_Integer lwu = list.size();
1390
            Py::Sequence col(list.getItem(0));
1391
            Standard_Integer lwv = col.size();
1392
            if (lwu != lu || lwv != lv) { Standard_Failure::Raise("weights and poles mismatch");}
1393
            Standard_Integer index1 = 0;
1394
            Standard_Integer index2 = 0;
1395
            for (Py::Sequence::iterator it1 = list.begin(); it1 != list.end(); ++it1) {
1396
                index1++;
1397
                index2=0;
1398
                Py::Sequence row(*it1);
1399
                for (Py::Sequence::iterator it2 = row.begin(); it2 != row.end(); ++it2) {
1400
                    index2++;
1401
                    Py::Float f(*it2);
1402
                    occweights.SetValue(index1, index2, f);
1403
                }
1404
            }
1405
        }
1406
        number_of_uknots = PyObject_Length(umults);
1407
        number_of_vknots = PyObject_Length(vmults);
1408
        if (((uknots != Py_None) && PyObject_Length(uknots) != number_of_uknots) ||
1409
                ((vknots != Py_None) && PyObject_Length(vknots) != number_of_vknots)){
1410
            Standard_Failure::Raise("number of knots and mults mismatch");
1411
            return nullptr;
1412
        }
1413
        //copy mults
1414
        TColStd_Array1OfInteger occumults(1,number_of_uknots);
1415
        TColStd_Array1OfInteger occvmults(1,number_of_vknots);
1416
        TColStd_Array1OfReal occuknots(1,number_of_uknots);
1417
        TColStd_Array1OfReal occvknots(1,number_of_vknots);
1418
        Py::Sequence umultssq(umults);
1419
        Standard_Integer index = 1;
1420
        for (Py::Sequence::iterator it = umultssq.begin(); it != umultssq.end() && index <= occumults.Length(); ++it) {
1421
            Py::Long mult(*it);
1422
            if (index < occumults.Length() || !Base::asBoolean(uperiodic)) {
1423
                sum_of_umults += static_cast<int>(mult); //sum up the mults to compare them against the number of poles later
1424
            }
1425
            occumults(index++) = static_cast<int>(mult);
1426
        }
1427
        Py::Sequence vmultssq(vmults);
1428
        index = 1;
1429
        for (Py::Sequence::iterator it = vmultssq.begin(); it != vmultssq.end() && index <= occvmults.Length(); ++it) {
1430
            Py::Long mult(*it);
1431
            if (index < occvmults.Length() || !Base::asBoolean(vperiodic)) {
1432
                sum_of_vmults += static_cast<int>(mult); //sum up the mults to compare them against the number of poles later
1433
            }
1434
            occvmults(index++) = static_cast<int>(mult);
1435
        }
1436
        //copy or generate knots
1437
        if (uknots != Py_None) { //uknots are given
1438
            Py::Sequence uknotssq(uknots);
1439
            index = 1;
1440
            for (Py::Sequence::iterator it = uknotssq.begin(); it != uknotssq.end() && index <= occuknots.Length(); ++it) {
1441
                Py::Float knot(*it);
1442
                occuknots(index++) = knot;
1443
            }
1444
        }
1445
        else { // knotes are uniformly spaced 0..1 if not given
1446
            for (int i=1; i<=occuknots.Length(); i++){
1447
                occuknots.SetValue(i,(double)(i-1)/(occuknots.Length()-1));
1448
            }
1449
        }
1450
        if (vknots != Py_None) { //vknots are given
1451
            Py::Sequence vknotssq(vknots);
1452
            index = 1;
1453
            for (Py::Sequence::iterator it = vknotssq.begin(); it != vknotssq.end() && index <= occvknots.Length(); ++it) {
1454
                Py::Float knot(*it);
1455
                occvknots(index++) = knot;
1456
            }
1457
        }
1458
        else { // knotes are uniformly spaced 0..1 if not given
1459
            for (int i=1; i<=occvknots.Length(); i++){
1460
                occvknots.SetValue(i,(double)(i-1)/(occvknots.Length()-1));
1461
            }
1462
        }
1463
        if ((Base::asBoolean(uperiodic) && sum_of_umults != lu) ||
1464
            (!Base::asBoolean(uperiodic) && sum_of_umults - udegree -1 != lu) ||
1465
            (Base::asBoolean(vperiodic) && sum_of_vmults != lv) ||
1466
            (!Base::asBoolean(vperiodic) && sum_of_vmults - vdegree -1 != lv)) {
1467
            Standard_Failure::Raise("number of poles and sum of mults mismatch");
1468
        }
1469
        // check multiplicity of inner knots
1470
        for (Standard_Integer i=2; i < occumults.Length(); i++) {
1471
            if (occumults(i) > udegree) {
1472
                Standard_Failure::Raise("multiplicity of inner knot higher than degree");
1473
            }
1474
        }
1475
        for (Standard_Integer i=2; i < occvmults.Length(); i++) {
1476
            if (occvmults(i) > vdegree) {
1477
                Standard_Failure::Raise("multiplicity of inner knot higher than degree");
1478
            }
1479
        }
1480

1481
        Handle(Geom_BSplineSurface) spline = new Geom_BSplineSurface(occpoles,occweights,
1482
            occuknots,occvknots,occumults,occvmults,udegree,vdegree,
1483
            Base::asBoolean(uperiodic),
1484
            Base::asBoolean(vperiodic));
1485
        if (!spline.IsNull()) {
1486
            this->getGeomBSplineSurfacePtr()->setHandle(spline);
1487
            Py_Return;
1488
        }
1489
        else {
1490
            Standard_Failure::Raise("failed to create spline");
1491
            return nullptr; // goes to the catch block
1492
        }
1493

1494
    }
1495
    catch (const Standard_Failure& e) {
1496
        Standard_CString msg = e.GetMessageString();
1497
        PyErr_SetString(PartExceptionOCCError, msg  ? msg : "");
1498
        return nullptr;
1499
    }
1500
}
1501

1502
/*!
1503
 * \code
1504
import math
1505
c = Part.Circle()
1506
c.Radius=50
1507
c = c.trim(0, math.pi)
1508

1509
e1 = Part.Ellipse()
1510
e1.Center = (0, 0, 75)
1511
e1.MajorRadius = 30
1512
e1.MinorRadius = 5
1513
e1 = e1.trim(0, math.pi)
1514

1515
e2 = Part.Ellipse()
1516
e2.Center = (0, 0, 100)
1517
e2.MajorRadius = 20
1518
e2.MinorRadius = 5
1519
e2 = e2.trim(0, math.pi)
1520

1521
bs = Part.BSplineSurface()
1522
bs.buildFromNSections([c, e1, e2])
1523
 * \endcode
1524
 */
1525
PyObject* BSplineSurfacePy::buildFromNSections(PyObject *args)
1526
{
1527
    PyObject* list;
1528
    PyObject* refSurf = Py_False;
1529
    if (!PyArg_ParseTuple(args, "O|O!", &list, &PyBool_Type, &refSurf))
1530
        return nullptr;
1531

1532
    try {
1533
        TColGeom_SequenceOfCurve curveSeq;
1534
        Py::Sequence curves(list);
1535
        for (Py::Sequence::iterator it = curves.begin(); it != curves.end(); ++it) {
1536
            Py::Object obj(*it);
1537
            if (PyObject_TypeCheck(obj.ptr(), &GeometryCurvePy::Type)) {
1538
                GeomCurve* geom = static_cast<GeometryCurvePy*>(obj.ptr())->getGeomCurvePtr();
1539
                curveSeq.Append(Handle(Geom_Curve)::DownCast(geom->handle()));
1540
            }
1541
        }
1542

1543
        GeomFill_NSections fillOp(curveSeq);
1544
        if (Base::asBoolean(refSurf)) {
1545
            Handle(Geom_BSplineSurface) ref = Handle(Geom_BSplineSurface)::DownCast
1546
                (getGeometryPtr()->handle());
1547
            fillOp.SetSurface(ref);
1548
        }
1549

1550
        fillOp.ComputeSurface();
1551

1552
        Handle(Geom_BSplineSurface) aSurf = fillOp.BSplineSurface();
1553
        this->getGeomBSplineSurfacePtr()->setHandle(aSurf);
1554
        Py_Return;
1555
    }
1556
    catch (const Standard_Failure& e) {
1557
        Standard_CString msg = e.GetMessageString();
1558
        PyErr_SetString(PartExceptionOCCError, msg  ? msg : "");
1559
        return nullptr;
1560
    }
1561
}
1562

1563
Py::Long BSplineSurfacePy::getUDegree() const
1564
{
1565
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
1566
        (getGeometryPtr()->handle());
1567
    int deg = surf->UDegree();
1568
    return Py::Long(deg);
1569
}
1570

1571
Py::Long BSplineSurfacePy::getVDegree() const
1572
{
1573
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
1574
        (getGeometryPtr()->handle());
1575
    int deg = surf->VDegree();
1576
    return Py::Long(deg);
1577
}
1578

1579
Py::Long BSplineSurfacePy::getMaxDegree() const
1580
{
1581
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
1582
        (getGeometryPtr()->handle());
1583
    return Py::Long(surf->MaxDegree());
1584
}
1585

1586
Py::Long BSplineSurfacePy::getNbUPoles() const
1587
{
1588
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
1589
        (getGeometryPtr()->handle());
1590
    return Py::Long(surf->NbUPoles());
1591
}
1592

1593
Py::Long BSplineSurfacePy::getNbVPoles() const
1594
{
1595
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
1596
        (getGeometryPtr()->handle());
1597
    return Py::Long(surf->NbVPoles());
1598
}
1599

1600
Py::Long BSplineSurfacePy::getNbUKnots() const
1601
{
1602
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
1603
        (getGeometryPtr()->handle());
1604
    return Py::Long(surf->NbUKnots());
1605
}
1606

1607
Py::Long BSplineSurfacePy::getNbVKnots() const
1608
{
1609
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
1610
        (getGeometryPtr()->handle());
1611
    return Py::Long(surf->NbVKnots());
1612
}
1613

1614
Py::Object BSplineSurfacePy::getFirstUKnotIndex() const
1615
{
1616
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
1617
        (getGeometryPtr()->handle());
1618
    int index = surf->FirstUKnotIndex();
1619
    return Py::Long(index);
1620
}
1621

1622
Py::Object BSplineSurfacePy::getLastUKnotIndex() const
1623
{
1624
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
1625
        (getGeometryPtr()->handle());
1626
    int index = surf->LastUKnotIndex();
1627
    return Py::Long(index);
1628
}
1629

1630
Py::Object BSplineSurfacePy::getFirstVKnotIndex() const
1631
{
1632
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
1633
        (getGeometryPtr()->handle());
1634
    int index = surf->FirstVKnotIndex();
1635
    return Py::Long(index);
1636
}
1637

1638
Py::Object BSplineSurfacePy::getLastVKnotIndex() const
1639
{
1640
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
1641
        (getGeometryPtr()->handle());
1642
    int index = surf->LastVKnotIndex();
1643
    return Py::Long(index);
1644
}
1645

1646
Py::List BSplineSurfacePy::getUKnotSequence() const
1647
{
1648
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
1649
        (getGeometryPtr()->handle());
1650
    Standard_Integer m = 0;
1651
    if (surf->IsUPeriodic()) {
1652
        // knots=poles+2*degree-mult(1)+2
1653
        m = surf->NbUPoles() + 2*surf->UDegree() - surf->UMultiplicity(1) + 2;
1654
    }
1655
    else {
1656
        for (int i=1; i<= surf->NbUKnots(); i++)
1657
            m += surf->UMultiplicity(i);
1658
    }
1659
    TColStd_Array1OfReal k(1,m);
1660
    surf->UKnotSequence(k);
1661
    Py::List list;
1662
    for (Standard_Integer i=k.Lower(); i<=k.Upper(); i++) {
1663
        list.append(Py::Float(k(i)));
1664
    }
1665
    return list;
1666
}
1667

1668
Py::List BSplineSurfacePy::getVKnotSequence() const
1669
{
1670
    Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast
1671
        (getGeometryPtr()->handle());
1672
    Standard_Integer m = 0;
1673
    if (surf->IsVPeriodic()) {
1674
        // knots=poles+2*degree-mult(1)+2
1675
        m = surf->NbVPoles() + 2*surf->VDegree() - surf->VMultiplicity(1) + 2;
1676
    }
1677
    else {
1678
        for (int i=1; i<= surf->NbVKnots(); i++)
1679
            m += surf->VMultiplicity(i);
1680
    }
1681
    TColStd_Array1OfReal k(1,m);
1682
    surf->VKnotSequence(k);
1683
    Py::List list;
1684
    for (Standard_Integer i=k.Lower(); i<=k.Upper(); i++) {
1685
        list.append(Py::Float(k(i)));
1686
    }
1687
    return list;
1688
}
1689

1690
PyObject* BSplineSurfacePy::scaleKnotsToBounds(PyObject *args)
1691
{
1692
    double u0=0.0;
1693
    double u1=1.0;
1694
    double v0=0.0;
1695
    double v1=1.0;
1696

1697
    if (!PyArg_ParseTuple(args, "|dddd", &u0, &u1, &v0, &v1))
1698
        return nullptr;
1699
    try {
1700
        if (u0 >= u1 || v0 >= v1) {
1701
            Standard_Failure::Raise("Bad parameter range");
1702
            return nullptr;;
1703
        }
1704
        GeomBSplineSurface* surf = getGeomBSplineSurfacePtr();
1705
        surf->scaleKnotsToBounds(u0, u1, v0, v1);
1706
        Py_Return;
1707
    }
1708
    catch (Standard_Failure& e) {
1709
        std::string err = e.GetMessageString();
1710
        if (err.empty()) err = e.DynamicType()->Name();
1711
        PyErr_SetString(PartExceptionOCCError, err.c_str());
1712
        return nullptr;
1713
    }
1714
}
1715

1716
PyObject *BSplineSurfacePy::getCustomAttributes(const char* attr) const
1717
{
1718
    // for backward compatibility
1719
    if (strcmp(attr, "setBounds") == 0) {
1720
        return PyObject_GetAttrString(const_cast<BSplineSurfacePy*>(this), "scaleKnotsToBounds");
1721
    }
1722
    return nullptr;
1723
}
1724

1725
int BSplineSurfacePy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
1726
{
1727
    return 0;
1728
}
1729

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

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

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

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