FreeCAD

Форк
0
/
TopoShapeWirePyImp.cpp 
743 строки · 26.3 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2008 Jürgen Riegel <juergen.riegel@web.de>              *
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 <Approx_Curve3d.hxx>
26
# include <BRepAdaptor_CompCurve.hxx>
27
# include <BRepBuilderAPI_FindPlane.hxx>
28
# include <BRepBuilderAPI_MakeWire.hxx>
29
# include <BRepGProp.hxx>
30
# include <BRepOffsetAPI_MakeOffset.hxx>
31
# include <BRepTools_WireExplorer.hxx>
32
# include <GProp_GProps.hxx>
33
# include <GProp_PrincipalProps.hxx>
34
# include <GCPnts_QuasiUniformAbscissa.hxx>
35
# include <GCPnts_QuasiUniformDeflection.hxx>
36
# include <GCPnts_TangentialDeflection.hxx>
37
# include <GCPnts_UniformAbscissa.hxx>
38
# include <GCPnts_UniformDeflection.hxx>
39
# include <Precision.hxx>
40
# include <ShapeAlgo_AlgoContainer.hxx>
41
# include <ShapeFix_Wire.hxx>
42
# include <TopExp.hxx>
43
# include <TopoDS.hxx>
44
# include <TopoDS_Wire.hxx>
45
#endif
46
#include <BRepOffsetAPI_MakeEvolved.hxx>
47

48
#include <Base/GeometryPyCXX.h>
49
#include <Base/PyWrapParseTupleAndKeywords.h>
50

51
#include <Mod/Part/App/BSplineCurvePy.h>
52
#include <Mod/Part/App/TopoShapeFacePy.h>
53
#include <Mod/Part/App/TopoShapeWirePy.h>
54
#include <Mod/Part/App/TopoShapeWirePy.cpp>
55
#include "OCCError.h"
56
#include "Tools.h"
57

58

59
using namespace Part;
60

61
namespace Part {
62
    extern Py::Object shape2pyshape(const TopoDS_Shape &shape);
63
}
64

65

66
// returns a string which represents the object e.g. when printed in python
67
std::string TopoShapeWirePy::representation() const
68
{
69
    std::stringstream str;
70
    str << "<Wire object at " << getTopoShapePtr() << ">";
71

72
    return str.str();
73
}
74

75
PyObject *TopoShapeWirePy::PyMake(struct _typeobject *, PyObject *, PyObject *)  // Python wrapper
76
{
77
    // create a new instance of TopoShapeWirePy and the Twin object
78
    return new TopoShapeWirePy(new TopoShape);
79
}
80

81
// constructor method
82
int TopoShapeWirePy::PyInit(PyObject* args, PyObject* /*kwd*/)
83
{
84
    if (PyArg_ParseTuple(args, "")) {
85
        // Undefined Wire
86
        getTopoShapePtr()->setShape(TopoDS_Wire());
87
        return 0;
88
    }
89

90
    PyErr_Clear();
91
    PyObject *pcObj;
92
    if (PyArg_ParseTuple(args, "O!", &(Part::TopoShapePy::Type), &pcObj)) {
93
        BRepBuilderAPI_MakeWire mkWire;
94
        const TopoDS_Shape& sh = static_cast<Part::TopoShapePy*>(pcObj)->getTopoShapePtr()->getShape();
95
        if (sh.IsNull()) {
96
            PyErr_SetString(PyExc_TypeError, "given shape is invalid");
97
            return -1;
98
        }
99
        if (sh.ShapeType() == TopAbs_EDGE)
100
            mkWire.Add(TopoDS::Edge(sh));
101
        else if (sh.ShapeType() == TopAbs_WIRE)
102
            mkWire.Add(TopoDS::Wire(sh));
103
        else {
104
            PyErr_SetString(PyExc_TypeError, "shape is neither edge nor wire");
105
            return -1;
106
        }
107

108
        try {
109
            getTopoShapePtr()->setShape(mkWire.Wire());
110
            return 0;
111
        }
112
        catch (Standard_Failure& e) {
113

114
            PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
115
            return -1;
116
        }
117
    }
118

119
    PyErr_Clear();
120
    if (PyArg_ParseTuple(args, "O", &pcObj)) {
121
        if(!Py::Object(pcObj).isList() && !Py::Object(pcObj).isTuple()) {
122
            PyErr_SetString(PyExc_TypeError, "object is neither a list nor a tuple");
123
            return -1;
124
        }
125

126
        BRepBuilderAPI_MakeWire mkWire;
127
        Py::Sequence list(pcObj);
128
        for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
129
            PyObject* item = (*it).ptr();
130
            if (PyObject_TypeCheck(item, &(Part::TopoShapePy::Type))) {
131
                const TopoDS_Shape& sh = static_cast<Part::TopoShapePy*>(item)->getTopoShapePtr()->getShape();
132
                if (sh.IsNull()) {
133
                    PyErr_SetString(PyExc_TypeError, "given shape is invalid");
134
                    return -1;
135
                }
136
                if (sh.ShapeType() == TopAbs_EDGE)
137
                    mkWire.Add(TopoDS::Edge(sh));
138
                else if (sh.ShapeType() == TopAbs_WIRE)
139
                    mkWire.Add(TopoDS::Wire(sh));
140
                else {
141
                    PyErr_SetString(PyExc_TypeError, "shape is neither edge nor wire");
142
                    return -1;
143
                }
144
            }
145
            else {
146
                PyErr_SetString(PyExc_TypeError, "item is not a shape");
147
                return -1;
148
            }
149
        }
150

151
        try {
152
            getTopoShapePtr()->setShape(mkWire.Wire());
153
            return 0;
154
        }
155
        catch (Standard_Failure& e) {
156

157
            PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
158
            return -1;
159
        }
160
    }
161

162
    PyErr_SetString(PartExceptionOCCError, "edge or wire or list of edges and wires expected");
163
    return -1;
164
}
165

166
PyObject* TopoShapeWirePy::add(PyObject *args)
167
{
168
    PyObject* edge;
169
    if (!PyArg_ParseTuple(args, "O!",&(TopoShapePy::Type), &edge))
170
        return nullptr;
171
    const TopoDS_Wire& w = TopoDS::Wire(getTopoShapePtr()->getShape());
172
    BRepBuilderAPI_MakeWire mkWire(w);
173

174
    const TopoDS_Shape& sh = static_cast<Part::TopoShapePy*>(edge)->getTopoShapePtr()->getShape();
175
    if (sh.IsNull()) {
176
        PyErr_SetString(PyExc_TypeError, "given shape is invalid");
177
        return nullptr;
178
    }
179
    if (sh.ShapeType() == TopAbs_EDGE)
180
        mkWire.Add(TopoDS::Edge(sh));
181
    else if (sh.ShapeType() == TopAbs_WIRE)
182
        mkWire.Add(TopoDS::Wire(sh));
183
    else {
184
        PyErr_SetString(PyExc_TypeError, "shape is neither edge nor wire");
185
        return nullptr;
186
    }
187

188
    try {
189
        getTopoShapePtr()->setShape(mkWire.Wire());
190
        Py_Return;
191
    }
192
    catch (Standard_Failure& e) {
193

194
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
195
        return nullptr;
196
    }
197
}
198

199
PyObject* TopoShapeWirePy::fixWire(PyObject *args)
200
{
201
    PyObject* face=nullptr;
202
    double tol = Precision::Confusion();
203
    if (!PyArg_ParseTuple(args, "|O!d",&(TopoShapeFacePy::Type), &face, &tol))
204
        return nullptr;
205

206
    try {
207
        ShapeFix_Wire aFix;
208
        const TopoDS_Wire& w = TopoDS::Wire(getTopoShapePtr()->getShape());
209

210
        if (face) {
211
            const TopoDS_Face& f = TopoDS::Face(static_cast<TopoShapePy*>(face)->getTopoShapePtr()->getShape());
212
            aFix.Init(w, f, tol);
213
        }
214
        else {
215
            aFix.SetPrecision(tol);
216
            aFix.Load(w);
217
        }
218

219
        aFix.FixReorder();
220
        aFix.FixConnected();
221
        aFix.FixClosed();
222
        getTopoShapePtr()->setShape(aFix.Wire());
223

224
        Py_Return;
225
    }
226
    catch (Standard_Failure& e) {
227

228
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
229
        return nullptr;
230
    }
231
}
232

233
PyObject* TopoShapeWirePy::makeOffset(PyObject *args)
234
{
235
    double dist;
236
    if (!PyArg_ParseTuple(args, "d",&dist))
237
        return nullptr;
238
    const TopoDS_Wire& w = TopoDS::Wire(getTopoShapePtr()->getShape());
239
    BRepBuilderAPI_FindPlane findPlane(w);
240
    if (!findPlane.Found()) {
241
        PyErr_SetString(PartExceptionOCCError, "No planar wire");
242
        return nullptr;
243
    }
244

245
    BRepOffsetAPI_MakeOffset mkOffset(w);
246
    mkOffset.Perform(dist);
247

248
    return new TopoShapePy(new TopoShape(mkOffset.Shape()));
249
}
250

251
PyObject* TopoShapeWirePy::makePipe(PyObject *args)
252
{
253
    PyObject *pShape;
254
    if (PyArg_ParseTuple(args, "O!", &(Part::TopoShapePy::Type), &pShape)) {
255
        try {
256
            TopoDS_Shape profile = static_cast<TopoShapePy*>(pShape)->getTopoShapePtr()->getShape();
257
            TopoDS_Shape shape = this->getTopoShapePtr()->makePipe(profile);
258
            return new TopoShapePy(new TopoShape(shape));
259
        }
260
        catch (Standard_Failure& e) {
261

262
            PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
263
            return nullptr;
264
        }
265
    }
266

267
    return nullptr;
268
}
269

270
PyObject* TopoShapeWirePy::makePipeShell(PyObject *args)
271
{
272
    PyObject *obj;
273
    PyObject *make_solid = Py_False;
274
    PyObject *is_Frenet = Py_False;
275
    int transition = 0;
276

277
    if (PyArg_ParseTuple(args, "O|O!O!i", &obj,
278
                             &PyBool_Type, &make_solid,
279
                             &PyBool_Type, &is_Frenet,
280
                             &transition)) {
281
        try {
282
            TopTools_ListOfShape sections;
283
            Py::Sequence list(obj);
284
            for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
285
                if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapePy::Type))) {
286
                    const TopoDS_Shape& shape = static_cast<TopoShapePy*>((*it).ptr())->getTopoShapePtr()->getShape();
287
                    sections.Append(shape);
288
                }
289
            }
290
            TopoDS_Shape shape = this->getTopoShapePtr()->makePipeShell(sections,
291
                Base::asBoolean(make_solid), Base::asBoolean(is_Frenet), transition);
292
            return new TopoShapePy(new TopoShape(shape));
293
        }
294
        catch (Standard_Failure& e) {
295

296
            PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
297
            return nullptr;
298
        }
299
    }
300

301
    return nullptr;
302
}
303

304
/*
305
import PartEnums
306
v = App.Vector
307
profile = Part.makePolygon([v(0.,0.,0.), v(-60.,-60.,-100.), v(-60.,-60.,-140.)])
308
spine = Part.makePolygon([v(0.,0.,0.), v(100.,0.,0.), v(100.,100.,0.), v(0.,100.,0.), v(0.,0.,0.)])
309
evolve = spine.makeEvolved(Profile=profile, Join=PartEnums.JoinType.Arc)
310
*/
311
PyObject* TopoShapeWirePy::makeEvolved(PyObject *args, PyObject *kwds)
312
{
313
    PyObject* Profile;
314
    PyObject* AxeProf = Py_True;
315
    PyObject* Solid = Py_False;
316
    PyObject* ProfOnSpine = Py_False;
317
    int JoinType = int(GeomAbs_Arc);
318
    double Tolerance = 0.0000001;
319

320
    static const std::array<const char *, 7> kwds_evolve{"Profile", "Join", "AxeProf", "Solid", "ProfOnSpine",
321
                                                         "Tolerance", nullptr};
322
    if (!Base::Wrapped_ParseTupleAndKeywords(args, kwds, "O!|iO!O!O!d", kwds_evolve,
323
                                             &TopoShapeWirePy::Type, &Profile, &JoinType,
324
                                             &PyBool_Type, &AxeProf, &PyBool_Type, &Solid,
325
                                             &PyBool_Type, &ProfOnSpine, &Tolerance)) {
326
        return nullptr;
327
    }
328

329
    const TopoDS_Wire& spine = TopoDS::Wire(getTopoShapePtr()->getShape());
330
    BRepBuilderAPI_FindPlane findPlane(spine);
331
    if (!findPlane.Found()) {
332
        PyErr_SetString(PartExceptionOCCError, "No planar wire");
333
        return nullptr;
334
    }
335

336
    const TopoDS_Wire& profile = TopoDS::Wire(static_cast<TopoShapeWirePy*>(Profile)->getTopoShapePtr()->getShape());
337

338
    GeomAbs_JoinType joinType;
339
    switch (JoinType) {
340
    case GeomAbs_Tangent:
341
        joinType = GeomAbs_Tangent;
342
        break;
343
    case GeomAbs_Intersection:
344
        joinType = GeomAbs_Intersection;
345
        break;
346
    default:
347
        joinType = GeomAbs_Arc;
348
        break;
349
    }
350

351
    try {
352
        BRepOffsetAPI_MakeEvolved evolved(spine, profile, joinType,
353
                                          Base::asBoolean(AxeProf),
354
                                          Base::asBoolean(Solid),
355
                                          Base::asBoolean(ProfOnSpine),
356
                                          Tolerance);
357
        TopoDS_Shape shape = evolved.Shape();
358
        return Py::new_reference_to(shape2pyshape(shape));
359
    }
360
    catch (Standard_Failure& e) {
361
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
362
        return nullptr;
363
    }
364
}
365

366
PyObject* TopoShapeWirePy::makeHomogenousWires(PyObject *args)
367
{
368
    PyObject* wire;
369
    if (!PyArg_ParseTuple(args, "O!",&(Part::TopoShapeWirePy::Type),&wire))
370
        return nullptr;
371
    try {
372
        TopoDS_Wire o1, o2;
373
        const TopoDS_Wire& w1 = TopoDS::Wire(getTopoShapePtr()->getShape());
374
        const TopoDS_Wire& w2 = TopoDS::Wire(static_cast<TopoShapePy*>(wire)->getTopoShapePtr()->getShape());
375
        ShapeAlgo_AlgoContainer shapeAlgo;
376
        if (shapeAlgo.HomoWires(w1,w2,o1,o2,Standard_True)) {
377
            getTopoShapePtr()->setShape(o1);
378
            return new TopoShapeWirePy(new TopoShape(o2));
379
        }
380
        else {
381
            Py_INCREF(wire);
382
            return wire;
383
        }
384
    }
385
    catch (Standard_Failure& e) {
386

387
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
388
        return nullptr;
389
    }
390
}
391

392
PyObject* TopoShapeWirePy::approximate(PyObject *args, PyObject *kwds)
393
{
394
    double tol2d = gp::Resolution();
395
    double tol3d = 0.0001;
396
    int maxseg=10, maxdeg=3;
397

398
    static const std::array<const char *, 5> kwds_approx{"Tol2d", "Tol3d", "MaxSegments", "MaxDegree", nullptr};
399
    if (!Base::Wrapped_ParseTupleAndKeywords(args, kwds, "|ddii", kwds_approx, &tol2d, &tol3d, &maxseg, &maxdeg)) {
400
        return nullptr;
401
    }
402
    try {
403
        BRepAdaptor_CompCurve adapt(TopoDS::Wire(getTopoShapePtr()->getShape()));
404
        auto hcurve = adapt.Trim(adapt.FirstParameter(),
405
                                 adapt.LastParameter(),
406
                                 tol2d);
407
        Approx_Curve3d approx(hcurve, tol3d, GeomAbs_C0, maxseg, maxdeg);
408
        if (approx.IsDone()) {
409
            return new BSplineCurvePy(new GeomBSplineCurve(approx.Curve()));
410
        }
411
        else {
412
            PyErr_SetString(PartExceptionOCCError, "failed to approximate wire");
413
            return nullptr;
414
        }
415
    }
416
    catch (Standard_Failure&) {
417
        PyErr_SetString(PartExceptionOCCError, "failed to approximate wire");
418
        return nullptr;
419
    }
420
}
421

422
PyObject* TopoShapeWirePy::discretize(PyObject *args, PyObject *kwds)
423
{
424
    try {
425
        BRepAdaptor_CompCurve adapt(TopoDS::Wire(getTopoShapePtr()->getShape()));
426
        bool uniformAbscissaPoints = false;
427
        bool uniformAbscissaDistance = false;
428
        int numPoints = -1;
429
        double distance = -1;
430
        double first = adapt.FirstParameter();
431
        double last = adapt.LastParameter();
432

433
        // use no kwds
434
        PyObject* dist_or_num;
435
        if (PyArg_ParseTuple(args, "O", &dist_or_num)) {
436
            if (PyLong_Check(dist_or_num)) {
437
                numPoints = PyLong_AsLong(dist_or_num);
438
                uniformAbscissaPoints = true;
439
            }
440
            else if (PyFloat_Check(dist_or_num)) {
441
                distance = PyFloat_AsDouble(dist_or_num);
442
                uniformAbscissaDistance = true;
443
            }
444
            else {
445
                PyErr_SetString(PyExc_TypeError, "Either int or float expected");
446
                return nullptr;
447
            }
448
        }
449
        else {
450
            // use Number kwds
451
            static const std::array<const char *, 4> kwds_numPoints{"Number", "First", "Last", nullptr};
452
            PyErr_Clear();
453
            if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "i|dd", kwds_numPoints, &numPoints, &first, &last)) {
454
                uniformAbscissaPoints = true;
455
            }
456
            else {
457
                // use Abscissa kwds
458
                static const std::array<const char *, 4> kwds_Distance{"Distance", "First", "Last", nullptr};
459
                PyErr_Clear();
460
                if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "d|dd", kwds_Distance, &distance, &first, &last)) {
461
                    uniformAbscissaDistance = true;
462
                }
463
            }
464
        }
465

466
        if (uniformAbscissaPoints || uniformAbscissaDistance) {
467
            GCPnts_UniformAbscissa discretizer;
468
            if (uniformAbscissaPoints)
469
                discretizer.Initialize (adapt, numPoints, first, last);
470
            else
471
                discretizer.Initialize (adapt, distance, first, last);
472

473
            if (discretizer.IsDone () && discretizer.NbPoints () > 0) {
474
                Py::List points;
475
                int nbPoints = discretizer.NbPoints ();
476
                for (int i=1; i<=nbPoints; i++) {
477
                    gp_Pnt p = adapt.Value (discretizer.Parameter (i));
478
                    points.append(Py::Vector(Base::Vector3d(p.X(),p.Y(),p.Z())));
479
                }
480

481
                return Py::new_reference_to(points);
482
            }
483
            else {
484
                PyErr_SetString(PartExceptionOCCError, "Discretization of wire failed");
485
                return nullptr;
486
            }
487
        }
488

489
        // use Deflection kwds
490
        static const std::array<const char *, 4> kwds_Deflection{"Deflection", "First", "Last", nullptr};
491
        PyErr_Clear();
492
        double deflection;
493
        if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "d|dd", kwds_Deflection, &deflection, &first, &last)) {
494
            GCPnts_UniformDeflection discretizer(adapt, deflection, first, last);
495
            if (discretizer.IsDone () && discretizer.NbPoints () > 0) {
496
                Py::List points;
497
                int nbPoints = discretizer.NbPoints ();
498
                for (int i=1; i<=nbPoints; i++) {
499
                    gp_Pnt p = discretizer.Value (i);
500
                    points.append(Py::Vector(Base::Vector3d(p.X(),p.Y(),p.Z())));
501
                }
502

503
                return Py::new_reference_to(points);
504
            }
505
            else {
506
                PyErr_SetString(PartExceptionOCCError, "Discretization of wire failed");
507
                return nullptr;
508
            }
509
        }
510

511
        // use TangentialDeflection kwds
512
        static const std::array<const char *, 6> kwds_TangentialDeflection{"Angular", "Curvature", "First", "Last",
513
                                                                           "Minimum", nullptr};
514
        PyErr_Clear();
515
        double angular;
516
        double curvature;
517
        int minimumPoints = 2;
518
        if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "dd|ddi", kwds_TangentialDeflection,
519
                                                &angular, &curvature, &first, &last, &minimumPoints)) {
520
            GCPnts_TangentialDeflection discretizer(adapt, first, last, angular, curvature, minimumPoints);
521
            if (discretizer.NbPoints () > 0) {
522
                Py::List points;
523
                int nbPoints = discretizer.NbPoints ();
524
                for (int i=1; i<=nbPoints; i++) {
525
                    gp_Pnt p = discretizer.Value (i);
526
                    points.append(Py::Vector(Base::Vector3d(p.X(),p.Y(),p.Z())));
527
                }
528

529
                return Py::new_reference_to(points);
530
            }
531
            else {
532
                PyErr_SetString(PartExceptionOCCError, "Discretization of wire failed");
533
                return nullptr;
534
            }
535
        }
536

537
        // use QuasiNumber kwds
538
        static const std::array<const char *, 4> kwds_QuasiNumPoints{"QuasiNumber", "First", "Last", nullptr};
539
        PyErr_Clear();
540
        int quasiNumPoints;
541
        if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "i|dd", kwds_QuasiNumPoints,
542
                                                &quasiNumPoints, &first, &last)) {
543
            GCPnts_QuasiUniformAbscissa discretizer(adapt, quasiNumPoints, first, last);
544
            if (discretizer.NbPoints () > 0) {
545
                Py::List points;
546
                int nbPoints = discretizer.NbPoints ();
547
                for (int i=1; i<=nbPoints; i++) {
548
                    gp_Pnt p = adapt.Value (discretizer.Parameter (i));
549
                    points.append(Py::Vector(Base::Vector3d(p.X(),p.Y(),p.Z())));
550
                }
551

552
                return Py::new_reference_to(points);
553
            }
554
            else {
555
                PyErr_SetString(PartExceptionOCCError, "Discretization of wire failed");
556
                return nullptr;
557
            }
558
        }
559

560
        // use QuasiDeflection kwds
561
        static const std::array<const char *, 4> kwds_QuasiDeflection{"QuasiDeflection", "First", "Last", nullptr};
562
        PyErr_Clear();
563
        double quasiDeflection;
564
        if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "d|dd", kwds_QuasiDeflection,
565
                                                &quasiDeflection, &first, &last)) {
566
            GCPnts_QuasiUniformDeflection discretizer(adapt, quasiDeflection, first, last);
567
            if (discretizer.NbPoints () > 0) {
568
                Py::List points;
569
                int nbPoints = discretizer.NbPoints ();
570
                for (int i=1; i<=nbPoints; i++) {
571
                    gp_Pnt p = discretizer.Value (i);
572
                    points.append(Py::Vector(Base::Vector3d(p.X(),p.Y(),p.Z())));
573
                }
574

575
                return Py::new_reference_to(points);
576
            }
577
            else {
578
                PyErr_SetString(PartExceptionOCCError, "Discretization of wire failed");
579
                return nullptr;
580
            }
581
        }
582
    }
583
    catch (const Base::Exception& e) {
584
        PyErr_SetString(PartExceptionOCCError, e.what());
585
        return nullptr;
586
    }
587

588
    PyErr_SetString(PartExceptionOCCError,"Wrong arguments");
589
    return nullptr;
590
}
591

592
Py::String TopoShapeWirePy::getContinuity() const
593
{
594
    BRepAdaptor_CompCurve adapt(TopoDS::Wire(getTopoShapePtr()->getShape()));
595
    std::string cont;
596
    switch (adapt.Continuity()) {
597
    case GeomAbs_C0:
598
        cont = "C0";
599
        break;
600
    case GeomAbs_G1:
601
        cont = "G1";
602
        break;
603
    case GeomAbs_C1:
604
        cont = "C1";
605
        break;
606
    case GeomAbs_G2:
607
        cont = "G2";
608
        break;
609
    case GeomAbs_C2:
610
        cont = "C2";
611
        break;
612
    case GeomAbs_C3:
613
        cont = "C3";
614
        break;
615
    case GeomAbs_CN:
616
        cont = "CN";
617
        break;
618
    }
619

620
    return Py::String(cont);
621
}
622

623
Py::Object TopoShapeWirePy::getMass() const
624
{
625
    GProp_GProps props;
626
    BRepGProp::LinearProperties(getTopoShapePtr()->getShape(), props);
627
    double c = props.Mass();
628
    return Py::Float(c);
629
}
630

631
Py::Object TopoShapeWirePy::getCenterOfMass() const
632
{
633
    GProp_GProps props;
634
    BRepGProp::LinearProperties(getTopoShapePtr()->getShape(), props);
635
    gp_Pnt c = props.CentreOfMass();
636
    return Py::Vector(Base::Vector3d(c.X(),c.Y(),c.Z()));
637
}
638

639
Py::Object TopoShapeWirePy::getMatrixOfInertia() const
640
{
641
    GProp_GProps props;
642
    BRepGProp::LinearProperties(getTopoShapePtr()->getShape(), props);
643
    gp_Mat m = props.MatrixOfInertia();
644
    Base::Matrix4D mat;
645
    for (int i=0; i<3; i++) {
646
        for (int j=0; j<3; j++) {
647
            mat[i][j] = m(i+1,j+1);
648
        }
649
    }
650
    return Py::Matrix(mat);
651
}
652

653
Py::Object TopoShapeWirePy::getStaticMoments() const
654
{
655
    GProp_GProps props;
656
    BRepGProp::LinearProperties(getTopoShapePtr()->getShape(), props);
657
    Standard_Real lx,ly,lz;
658
    props.StaticMoments(lx,ly,lz);
659
    Py::Tuple tuple(3);
660
    tuple.setItem(0, Py::Float(lx));
661
    tuple.setItem(1, Py::Float(ly));
662
    tuple.setItem(2, Py::Float(lz));
663
    return tuple;
664
}
665

666
Py::Dict TopoShapeWirePy::getPrincipalProperties() const
667
{
668
    GProp_GProps props;
669
    BRepGProp::LinearProperties(getTopoShapePtr()->getShape(), props);
670
    GProp_PrincipalProps pprops = props.PrincipalProperties();
671

672
    Py::Dict dict;
673
    dict.setItem("SymmetryAxis", Py::Boolean(pprops.HasSymmetryAxis() ? true : false));
674
    dict.setItem("SymmetryPoint", Py::Boolean(pprops.HasSymmetryPoint() ? true : false));
675
    Standard_Real lx,ly,lz;
676
    pprops.Moments(lx,ly,lz);
677
    Py::Tuple tuple(3);
678
    tuple.setItem(0, Py::Float(lx));
679
    tuple.setItem(1, Py::Float(ly));
680
    tuple.setItem(2, Py::Float(lz));
681
    dict.setItem("Moments",tuple);
682
    dict.setItem("FirstAxisOfInertia",Py::Vector(Base::convertTo
683
        <Base::Vector3d>(pprops.FirstAxisOfInertia())));
684
    dict.setItem("SecondAxisOfInertia",Py::Vector(Base::convertTo
685
        <Base::Vector3d>(pprops.SecondAxisOfInertia())));
686
    dict.setItem("ThirdAxisOfInertia",Py::Vector(Base::convertTo
687
        <Base::Vector3d>(pprops.ThirdAxisOfInertia())));
688

689
    Standard_Real Rxx,Ryy,Rzz;
690
    pprops.RadiusOfGyration(Rxx,Ryy,Rzz);
691
    Py::Tuple rog(3);
692
    rog.setItem(0, Py::Float(Rxx));
693
    rog.setItem(1, Py::Float(Ryy));
694
    rog.setItem(2, Py::Float(Rzz));
695
    dict.setItem("RadiusOfGyration",rog);
696
    return dict;
697
}
698

699
Py::List TopoShapeWirePy::getOrderedEdges() const
700
{
701
    Py::List ret;
702

703
    BRepTools_WireExplorer xp(TopoDS::Wire(getTopoShapePtr()->getShape()));
704
    while (xp.More()) {
705
        ret.append(shape2pyshape(xp.Current()));
706
        xp.Next();
707
    }
708

709
    return ret;
710
}
711

712
Py::List TopoShapeWirePy::getOrderedVertexes() const
713
{
714
    Py::List ret;
715

716
    TopoDS_Wire wire = TopoDS::Wire(getTopoShapePtr()->getShape());
717
    BRepTools_WireExplorer xp(wire);
718
    while (xp.More()) {
719
        ret.append(shape2pyshape(xp.CurrentVertex()));
720
        xp.Next();
721
    }
722

723
    // special treatment for open wires
724
    TopoDS_Vertex Vfirst, Vlast;
725
    TopExp::Vertices(wire, Vfirst, Vlast);
726
    if (!Vfirst.IsNull() && !Vlast.IsNull()) {
727
        if (!Vfirst.IsSame(Vlast)) {
728
            ret.append(shape2pyshape(Vlast));
729
        }
730
    }
731

732
    return ret;
733
}
734

735
PyObject *TopoShapeWirePy::getCustomAttributes(const char* /*attr*/) const
736
{
737
    return nullptr;
738
}
739

740
int TopoShapeWirePy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
741
{
742
    return 0;
743
}
744

745

746

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

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

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

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