1
/***************************************************************************
2
* Copyright (c) 2008 Jürgen Riegel <juergen.riegel@web.de> *
4
* This file is part of the FreeCAD CAx development system. *
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. *
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. *
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 *
21
***************************************************************************/
23
#include "PreCompiled.h"
25
# include <BRep_Builder.hxx>
26
# include <BRep_Tool.hxx>
27
# include <BRepAdaptor_Curve.hxx>
28
# include <BRepBuilderAPI_MakeEdge.hxx>
29
# include <BRepBuilderAPI_MakeWire.hxx>
30
# include <BRepGProp.hxx>
31
# include <BRepLProp_CLProps.hxx>
32
# include <BRepLProp_CurveTool.hxx>
33
# include <GProp_GProps.hxx>
34
# include <GProp_PrincipalProps.hxx>
35
# include <Geom_Circle.hxx>
36
# include <Geom_Curve.hxx>
37
# include <Geom_Ellipse.hxx>
38
# include <Geom_Hyperbola.hxx>
39
# include <Geom_Parabola.hxx>
40
# include <Geom_Line.hxx>
41
# include <Geom_OffsetCurve.hxx>
42
# include <Geom_Surface.hxx>
43
# include <Geom2d_Curve.hxx>
44
# include <TopLoc_Location.hxx>
45
# include <Poly_Polygon3D.hxx>
46
# include <Poly_Triangulation.hxx>
47
# include <Poly_PolygonOnTriangulation.hxx>
48
# include <TColStd_Array1OfReal.hxx>
51
# include <TopoDS_Edge.hxx>
52
# include <TopoDS_Shape.hxx>
53
# include <TopoDS_Vertex.hxx>
54
# include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
55
# include <ShapeAnalysis_Edge.hxx>
56
# include <Standard_Failure.hxx>
57
# include <Standard_Version.hxx>
58
# include <GProp_GProps.hxx>
59
# include <GCPnts_AbscissaPoint.hxx>
60
# include <GCPnts_QuasiUniformAbscissa.hxx>
61
# include <GCPnts_QuasiUniformDeflection.hxx>
62
# include <GCPnts_TangentialDeflection.hxx>
63
# include <GCPnts_UniformAbscissa.hxx>
64
# include <GCPnts_UniformDeflection.hxx>
67
#include <Base/GeometryPyCXX.h>
68
#include <Base/PyWrapParseTupleAndKeywords.h>
69
#include <Base/Vector3D.h>
70
#include <Base/VectorPy.h>
72
#include <Mod/Part/App/BezierCurvePy.h>
73
#include <Mod/Part/App/BSplineCurvePy.h>
74
#include <Mod/Part/App/CirclePy.h>
75
#include <Mod/Part/App/EllipsePy.h>
76
#include <Mod/Part/App/GeometryPy.h>
77
#include <Mod/Part/App/HyperbolaPy.h>
78
#include <Mod/Part/App/LinePy.h>
79
#include <Mod/Part/App/OffsetCurvePy.h>
80
#include <Mod/Part/App/ParabolaPy.h>
81
#include <Mod/Part/App/TopoShapeEdgePy.h>
82
#include <Mod/Part/App/TopoShapeEdgePy.cpp>
83
#include <Mod/Part/App/TopoShapeFacePy.h>
84
#include <Mod/Part/App/TopoShapeVertexPy.h>
85
#include <Mod/Part/App/TopoShapeWirePy.h>
87
#include "Geometry2d.h"
95
const TopoDS_Edge& getTopoDSEdge(const TopoShapeEdgePy* theEdge){
96
const TopoDS_Edge& e = TopoDS::Edge(theEdge->getTopoShapePtr()->getShape());
98
throw Py::ValueError("Edge is null");
103
// returns a string which represents the object e.g. when printed in python
104
std::string TopoShapeEdgePy::representation() const
106
std::stringstream str;
107
str << "<Edge object at " << getTopoShapePtr() << ">";
112
PyObject *TopoShapeEdgePy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
114
// create a new instance of TopoShapeEdgePy and the Twin object
115
return new TopoShapeEdgePy(new TopoShape);
119
int TopoShapeEdgePy::PyInit(PyObject* args, PyObject* /*kwd*/)
121
if (PyArg_ParseTuple(args, "")) {
123
getTopoShapePtr()->setShape(TopoDS_Edge());
128
PyObject *pcObj, *pcObj2;
129
double first=DBL_MAX, last=DBL_MAX;
130
if (PyArg_ParseTuple(args, "O!|dd", &(Part::GeometryPy::Type), &pcObj, &first, &last)) {
131
Geometry* geom = static_cast<GeometryPy*>(pcObj)->getGeometryPtr();
132
Handle(Geom_Curve) curve = Handle(Geom_Curve)::DownCast(geom->handle());
133
if (curve.IsNull()) {
134
PyErr_SetString(PartExceptionOCCError, "geometry is not a curve type");
139
first = curve->FirstParameter();
141
last = curve->LastParameter();
144
BRepBuilderAPI_MakeEdge mkEdge(curve, first, last);
145
getTopoShapePtr()->setShape(mkEdge.Edge());
148
catch (Standard_Failure& e) {
150
PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
156
if (PyArg_ParseTuple(args, "O!", &(Part::TopoShapePy::Type), &pcObj)) {
157
TopoShape* shape = static_cast<TopoShapePy*>(pcObj)->getTopoShapePtr();
158
if (shape && !shape->getShape().IsNull() && shape->getShape().ShapeType() == TopAbs_EDGE) {
159
this->getTopoShapePtr()->setShape(shape->getShape());
163
PyErr_SetString(PyExc_TypeError, "Shape is not an edge");
169
if (PyArg_ParseTuple(args, "O!O!", &(Part::TopoShapeVertexPy::Type), &pcObj,
170
&(Part::TopoShapeVertexPy::Type), &pcObj2)) {
171
TopoShape* shape1 = static_cast<TopoShapePy*>(pcObj)->getTopoShapePtr();
172
TopoShape* shape2 = static_cast<TopoShapePy*>(pcObj2)->getTopoShapePtr();
173
const TopoDS_Vertex& v1 = TopoDS::Vertex(shape1->getShape());
174
const TopoDS_Vertex& v2 = TopoDS::Vertex(shape2->getShape());
177
BRepBuilderAPI_MakeEdge mkEdge(v1, v2);
178
getTopoShapePtr()->setShape(mkEdge.Edge());
181
catch (Standard_Failure& e) {
183
PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
188
PyErr_SetString(PartExceptionOCCError, "Curve or shape expected");
192
// ====== Methods ======================================================================
194
PyObject* TopoShapeEdgePy::getParameterByLength(PyObject *args)
197
double t=Precision::Confusion();
198
if (!PyArg_ParseTuple(args, "d|d",&u,&t))
201
auto e = getTopoDSEdge(this);
202
BRepAdaptor_Curve adapt(e);
204
// transform value of [0,Length] to [First,Last]
205
double first = BRepLProp_CurveTool::FirstParameter(adapt);
206
double last = BRepLProp_CurveTool::LastParameter(adapt);
207
if (!Precision::IsInfinite(first) && !Precision::IsInfinite(last)) {
208
double length = GCPnts_AbscissaPoint::Length(adapt,t);
210
if (u < -length || u > length) {
211
PyErr_SetString(PyExc_ValueError, "value out of range");
216
GCPnts_AbscissaPoint abscissaPoint(t,adapt,u,first);
217
double parm = abscissaPoint.Parameter();
218
return PyFloat_FromDouble(parm);
221
return PyFloat_FromDouble(u);
224
PyObject* TopoShapeEdgePy::valueAt(PyObject *args)
227
if (!PyArg_ParseTuple(args, "d",&u))
230
auto e = getTopoDSEdge(this);
231
BRepAdaptor_Curve adapt(e);
233
// Check now the orientation of the edge to make
234
// sure that we get the right wanted point!
235
BRepLProp_CLProps prop(adapt,u,0,Precision::Confusion());
236
const gp_Pnt& V = prop.Value();
237
return new Base::VectorPy(new Base::Vector3d(V.X(),V.Y(),V.Z()));
240
PyObject* TopoShapeEdgePy::parameters(PyObject *args)
242
PyObject* pyface = nullptr;
243
if (!PyArg_ParseTuple(args, "|O!", &(TopoShapeFacePy::Type), &pyface))
246
auto e = getTopoDSEdge(this);
247
TopLoc_Location aLoc;
248
Handle(Poly_Polygon3D) aPoly = BRep_Tool::Polygon3D(e, aLoc);
249
if (!aPoly.IsNull()) {
251
if (!aPoly->HasParameters()) {
252
return Py::new_reference_to(list);
255
const TColStd_Array1OfReal& aNodes = aPoly->Parameters();
256
for (int i=aNodes.Lower(); i<=aNodes.Upper(); i++) {
257
list.append(Py::Float(aNodes(i)));
260
return Py::new_reference_to(list);
263
// build up map edge->face
264
const TopoDS_Shape& face = static_cast<TopoShapeFacePy*>(pyface)->getTopoShapePtr()->getShape();
265
TopTools_IndexedDataMapOfShapeListOfShape edge2Face;
266
TopExp::MapShapesAndAncestors(TopoDS::Face(face), TopAbs_EDGE, TopAbs_FACE, edge2Face);
267
if (edge2Face.Contains(e)) {
268
Handle(Poly_Triangulation) aPolyTria = BRep_Tool::Triangulation(TopoDS::Face(face),aLoc);
269
if (!aPolyTria.IsNull()) {
270
Handle(Poly_PolygonOnTriangulation) aPoly = BRep_Tool::PolygonOnTriangulation(e, aPolyTria, aLoc);
271
if (!aPoly.IsNull()) {
272
if (!aPoly->HasParameters()) {
274
return Py::new_reference_to(list);
277
Handle(TColStd_HArray1OfReal) aNodes = aPoly->Parameters();
278
if (!aNodes.IsNull()) {
280
for (int i=aNodes->Lower(); i<=aNodes->Upper(); i++) {
281
list.append(Py::Float(aNodes->Value(i)));
284
return Py::new_reference_to(list);
290
PyErr_SetString(PyExc_ValueError, "Edge is not part of the face");
295
PyErr_SetString(PyExc_RuntimeError, "Edge has no polygon");
299
PyObject* TopoShapeEdgePy::parameterAt(PyObject *args)
302
PyObject* face=nullptr;
303
if (!PyArg_ParseTuple(args, "O!|O!",&TopoShapeVertexPy::Type,&pnt,
304
&TopoShapeFacePy::Type,&face))
308
const TopoDS_Shape& v = static_cast<TopoShapePy*>(pnt)->getTopoShapePtr()->getShape();
309
auto e = getTopoDSEdge(this);
312
const TopoDS_Shape& f = static_cast<TopoShapeFacePy*>(face)->getTopoShapePtr()->getShape();
313
Standard_Real par = BRep_Tool::Parameter(TopoDS::Vertex(v), e, TopoDS::Face(f));
314
return PyFloat_FromDouble(par);
317
Standard_Real par = BRep_Tool::Parameter(TopoDS::Vertex(v), e);
318
return PyFloat_FromDouble(par);
321
catch (Standard_Failure& e) {
323
PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
328
PyObject* TopoShapeEdgePy::tangentAt(PyObject *args)
331
if (!PyArg_ParseTuple(args, "d",&u))
334
auto e = getTopoDSEdge(this);
335
BRepAdaptor_Curve adapt(e);
337
BRepLProp_CLProps prop(adapt,u,2,Precision::Confusion());
338
if (prop.IsTangentDefined()) {
341
return new Base::VectorPy(new Base::Vector3d(dir.X(),dir.Y(),dir.Z()));
344
PyErr_SetString(PyExc_NotImplementedError, "Tangent not defined at this position!");
349
PyObject* TopoShapeEdgePy::normalAt(PyObject *args)
352
if (!PyArg_ParseTuple(args, "d",&u))
355
auto e = getTopoDSEdge(this);
356
BRepAdaptor_Curve adapt(e);
359
BRepLProp_CLProps prop(adapt,u,2,Precision::Confusion());
362
return new Base::VectorPy(new Base::Vector3d(V.X(),V.Y(),V.Z()));
364
catch (Standard_Failure& e) {
366
PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
371
PyObject* TopoShapeEdgePy::curvatureAt(PyObject *args)
374
if (!PyArg_ParseTuple(args, "d",&u))
377
auto e = getTopoDSEdge(this);
378
BRepAdaptor_Curve adapt(e);
381
BRepLProp_CLProps prop(adapt,u,2,Precision::Confusion());
382
double C = prop.Curvature();
383
return Py::new_reference_to(Py::Float(C));
385
catch (Standard_Failure& e) {
387
PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
392
PyObject* TopoShapeEdgePy::centerOfCurvatureAt(PyObject *args)
395
if (!PyArg_ParseTuple(args, "d",&u))
398
auto e = getTopoDSEdge(this);
399
BRepAdaptor_Curve adapt(e);
402
BRepLProp_CLProps prop(adapt,u,2,Precision::Confusion());
404
prop.CentreOfCurvature(V);
405
return new Base::VectorPy(new Base::Vector3d(V.X(),V.Y(),V.Z()));
407
catch (Standard_Failure& e) {
409
PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
414
PyObject* TopoShapeEdgePy::derivative1At(PyObject *args)
417
if (!PyArg_ParseTuple(args, "d",&u))
420
auto e = getTopoDSEdge(this);
421
BRepAdaptor_Curve adapt(e);
424
BRepLProp_CLProps prop(adapt,u,1,Precision::Confusion());
425
const gp_Vec& V = prop.D1();
426
return new Base::VectorPy(new Base::Vector3d(V.X(),V.Y(),V.Z()));
428
catch (Standard_Failure& e) {
430
PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
435
PyObject* TopoShapeEdgePy::derivative2At(PyObject *args)
438
if (!PyArg_ParseTuple(args, "d",&u))
441
auto e = getTopoDSEdge(this);
442
BRepAdaptor_Curve adapt(e);
445
BRepLProp_CLProps prop(adapt,u,2,Precision::Confusion());
446
const gp_Vec& V = prop.D2();
447
return new Base::VectorPy(new Base::Vector3d(V.X(),V.Y(),V.Z()));
449
catch (Standard_Failure& e) {
451
PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
456
PyObject* TopoShapeEdgePy::derivative3At(PyObject *args)
459
if (!PyArg_ParseTuple(args, "d",&u))
462
auto e = getTopoDSEdge(this);
463
BRepAdaptor_Curve adapt(e);
466
BRepLProp_CLProps prop(adapt,u,3,Precision::Confusion());
467
const gp_Vec& V = prop.D3();
468
return new Base::VectorPy(new Base::Vector3d(V.X(),V.Y(),V.Z()));
470
catch (Standard_Failure& e) {
472
PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
477
PyObject* TopoShapeEdgePy::discretize(PyObject *args, PyObject *kwds)
480
BRepAdaptor_Curve adapt(TopoDS::Edge(getTopoShapePtr()->getShape()));
481
bool uniformAbscissaPoints = false;
482
bool uniformAbscissaDistance = false;
484
double distance = -1;
485
double first = adapt.FirstParameter();
486
double last = adapt.LastParameter();
489
PyObject* dist_or_num;
490
if (PyArg_ParseTuple(args, "O", &dist_or_num)) {
491
if (PyLong_Check(dist_or_num)) {
492
numPoints = PyLong_AsLong(dist_or_num);
493
uniformAbscissaPoints = true;
495
else if (PyFloat_Check(dist_or_num)) {
496
distance = PyFloat_AsDouble(dist_or_num);
497
uniformAbscissaDistance = true;
500
PyErr_SetString(PyExc_TypeError, "Either int or float expected");
506
static const std::array<const char *, 4> kwds_numPoints{"Number", "First", "Last", nullptr};
508
if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "i|dd", kwds_numPoints, &numPoints, &first, &last)) {
509
uniformAbscissaPoints = true;
513
static const std::array<const char *, 4> kwds_Distance{"Distance", "First", "Last", nullptr};
515
if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "d|dd", kwds_Distance, &distance, &first, &last)) {
516
uniformAbscissaDistance = true;
521
if (uniformAbscissaPoints || uniformAbscissaDistance) {
522
GCPnts_UniformAbscissa discretizer;
523
if (uniformAbscissaPoints)
524
discretizer.Initialize (adapt, numPoints, first, last);
526
discretizer.Initialize (adapt, distance, first, last);
528
if (discretizer.IsDone () && discretizer.NbPoints () > 0) {
530
int nbPoints = discretizer.NbPoints ();
531
for (int i=1; i<=nbPoints; i++) {
532
gp_Pnt p = adapt.Value (discretizer.Parameter (i));
533
points.append(Py::Vector(Base::Vector3d(p.X(),p.Y(),p.Z())));
536
return Py::new_reference_to(points);
539
PyErr_SetString(PartExceptionOCCError, "Discretization of edge failed");
544
// use Deflection kwds
545
static const std::array<const char *, 4> kwds_Deflection{"Deflection", "First", "Last", nullptr};
548
if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "d|dd", kwds_Deflection, &deflection, &first, &last)) {
549
GCPnts_UniformDeflection discretizer(adapt, deflection, first, last);
550
if (discretizer.IsDone () && discretizer.NbPoints () > 0) {
552
int nbPoints = discretizer.NbPoints ();
553
for (int i=1; i<=nbPoints; i++) {
554
gp_Pnt p = discretizer.Value (i);
555
points.append(Py::Vector(Base::Vector3d(p.X(),p.Y(),p.Z())));
558
return Py::new_reference_to(points);
561
PyErr_SetString(PartExceptionOCCError, "Discretization of edge failed");
566
// use TangentialDeflection kwds
567
static const std::array<const char *, 6> kwds_TangentialDeflection {"Angular", "Curvature", "First", "Last",
572
int minimumPoints = 2;
573
if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "dd|ddi", kwds_TangentialDeflection, &angular, &curvature,
574
&first, &last, &minimumPoints)) {
575
GCPnts_TangentialDeflection discretizer(adapt, first, last, angular, curvature, minimumPoints);
576
if (discretizer.NbPoints () > 0) {
578
int nbPoints = discretizer.NbPoints ();
579
for (int i=1; i<=nbPoints; i++) {
580
gp_Pnt p = discretizer.Value (i);
581
points.append(Py::Vector(Base::Vector3d(p.X(),p.Y(),p.Z())));
584
return Py::new_reference_to(points);
587
PyErr_SetString(PartExceptionOCCError, "Discretization of edge failed");
592
// use QuasiNumber kwds
593
static const std::array<const char *, 4> kwds_QuasiNumPoints{"QuasiNumber", "First", "Last", nullptr};
596
if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "i|dd", kwds_QuasiNumPoints, &quasiNumPoints, &first,
598
GCPnts_QuasiUniformAbscissa discretizer(adapt, quasiNumPoints, first, last);
599
if (discretizer.NbPoints () > 0) {
601
int nbPoints = discretizer.NbPoints ();
602
for (int i=1; i<=nbPoints; i++) {
603
gp_Pnt p = adapt.Value (discretizer.Parameter (i));
604
points.append(Py::Vector(Base::Vector3d(p.X(),p.Y(),p.Z())));
607
return Py::new_reference_to(points);
610
PyErr_SetString(PartExceptionOCCError, "Discretization of edge failed");
615
// use QuasiDeflection kwds
616
static const std::array<const char *, 4> kwds_QuasiDeflection{"QuasiDeflection", "First", "Last", nullptr};
618
double quasiDeflection;
619
if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "d|dd", kwds_QuasiDeflection,
620
&quasiDeflection, &first, &last)) {
621
GCPnts_QuasiUniformDeflection discretizer(adapt, quasiDeflection, first, last);
622
if (discretizer.NbPoints () > 0) {
624
int nbPoints = discretizer.NbPoints ();
625
for (int i=1; i<=nbPoints; i++) {
626
gp_Pnt p = discretizer.Value (i);
627
points.append(Py::Vector(Base::Vector3d(p.X(),p.Y(),p.Z())));
630
return Py::new_reference_to(points);
633
PyErr_SetString(PartExceptionOCCError, "Discretization of edge failed");
638
catch (const Base::Exception& e) {
639
PyErr_SetString(PartExceptionOCCError, e.what());
643
PyErr_SetString(PartExceptionOCCError,"Wrong arguments");
647
PyObject* TopoShapeEdgePy::countNodes(PyObject *args)
649
if (!PyArg_ParseTuple(args, ""))
652
const TopoDS_Shape& shape = this->getTopoShapePtr()->getShape();
653
TopoDS_Edge aEdge = TopoDS::Edge(shape);
654
TopLoc_Location aLoc;
655
const Handle(Poly_Polygon3D)& aPoly = BRep_Tool::Polygon3D(aEdge, aLoc);
657
if (!aPoly.IsNull()) {
658
count = aPoly->NbNodes();
661
return Py::new_reference_to(Py::Long(count));
664
PyObject* TopoShapeEdgePy::split(PyObject *args)
666
PyObject* float_or_list;
667
if (!PyArg_ParseTuple(args, "O", &float_or_list))
671
BRepAdaptor_Curve adapt(TopoDS::Edge(getTopoShapePtr()->getShape()));
672
Standard_Real f = adapt.FirstParameter();
673
Standard_Real l = adapt.LastParameter();
675
std::vector<Standard_Real> par;
677
if (PyFloat_Check(float_or_list)) {
678
double val = PyFloat_AsDouble(float_or_list);
679
if (val == f || val == l) {
680
PyErr_SetString(PyExc_ValueError, "Cannot split edge at start or end point");
683
else if (val < f || val > l) {
684
PyErr_SetString(PyExc_ValueError, "Value out of parameter range");
689
else if (PySequence_Check(float_or_list)) {
690
Py::Sequence list(float_or_list);
691
for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
692
double val = (double)Py::Float(*it);
693
if (val == f || val == l) {
694
PyErr_SetString(PyExc_ValueError, "Cannot split edge at start or end point");
697
else if (val < f || val > l) {
698
PyErr_SetString(PyExc_ValueError, "Value out of parameter range");
705
PyErr_SetString(PyExc_TypeError, "Either float or list of floats expected");
710
std::sort(par.begin(), par.end());
712
BRepBuilderAPI_MakeWire mkWire;
713
Handle(Geom_Curve) c = adapt.Curve().Curve();
714
const TopoDS_Edge& edge = TopoDS::Edge(this->getTopoShapePtr()->getShape());
715
BRep_Builder builder;
717
std::vector<Standard_Real>::iterator end = par.end() - 1;
718
for (std::vector<Standard_Real>::iterator it = par.begin(); it != end; ++it) {
719
BRepBuilderAPI_MakeEdge mke(c, it[0], it[1]);
721
builder.Transfert(edge, e);
722
builder.Range(e, it[0], it[1], false);
726
return new TopoShapeWirePy(new TopoShape(mkWire.Shape()));
728
catch (Standard_Failure& e) {
730
PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
735
PyObject* TopoShapeEdgePy::isSeam(PyObject *args)
738
if (!PyArg_ParseTuple(args, "O!", &TopoShapeFacePy::Type, &face))
742
const TopoDS_Edge& e = TopoDS::Edge(this->getTopoShapePtr()->getShape());
743
const TopoDS_Face& f = TopoDS::Face(static_cast<TopoShapeFacePy*>(face)->getTopoShapePtr()->getShape());
745
ShapeAnalysis_Edge sa;
746
Standard_Boolean ok = sa.IsSeam(e, f);
747
return PyBool_FromLong(ok ? 1 : 0);
749
catch (Standard_Failure& e) {
751
PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
756
PyObject* TopoShapeEdgePy::firstVertex(PyObject *args)
758
PyObject* orient = Py_False;
759
if (!PyArg_ParseTuple(args, "|O!", &PyBool_Type, &orient))
761
auto e = getTopoDSEdge(this);
762
TopoDS_Vertex v = TopExp::FirstVertex(e, Base::asBoolean(orient));
763
return new TopoShapeVertexPy(new TopoShape(v));
766
PyObject* TopoShapeEdgePy::lastVertex(PyObject *args)
768
PyObject* orient = Py_False;
769
if (!PyArg_ParseTuple(args, "|O!", &PyBool_Type, &orient))
771
auto e = getTopoDSEdge(this);
772
TopoDS_Vertex v = TopExp::LastVertex(e, Base::asBoolean(orient));
773
return new TopoShapeVertexPy(new TopoShape(v));
776
// ====== Attributes ======================================================================
778
Py::String TopoShapeEdgePy::getContinuity() const
780
BRepAdaptor_Curve adapt(TopoDS::Edge(getTopoShapePtr()->getShape()));
782
switch (adapt.Continuity()) {
806
return Py::String(cont);
809
Py::Float TopoShapeEdgePy::getTolerance() const
811
auto e = getTopoDSEdge(this);
812
return Py::Float(BRep_Tool::Tolerance(e));
815
void TopoShapeEdgePy::setTolerance(Py::Float tol)
817
BRep_Builder aBuilder;
818
auto e = getTopoDSEdge(this);
819
aBuilder.UpdateEdge(e, (double)tol);
822
Py::Float TopoShapeEdgePy::getLength() const
824
auto e = getTopoDSEdge(this);
825
BRepAdaptor_Curve adapt(e);
826
return Py::Float(GCPnts_AbscissaPoint::Length(adapt, Precision::Confusion()));
829
#include <App/Application.h>
830
#include <Mod/Part/App/LineSegmentPy.h>
832
Py::Object TopoShapeEdgePy::getCurve() const
834
auto e = getTopoDSEdge(this);
835
BRepAdaptor_Curve adapt(e);
836
Base::PyObjectBase* curve = nullptr;
837
switch(adapt.GetType())
841
GeomLine* line = new GeomLine();
842
Handle(Geom_Line) this_curv = Handle(Geom_Line)::DownCast
844
this_curv->SetLin(adapt.Line());
845
curve = new LinePy(line);
850
GeomCircle* circle = new GeomCircle();
851
Handle(Geom_Circle) this_curv = Handle(Geom_Circle)::DownCast
853
this_curv->SetCirc(adapt.Circle());
854
//Standard_Real dd = adapt.FirstParameter();
855
//Standard_Real ee = adapt.LastParameter();
856
curve = new CirclePy(circle);
859
case GeomAbs_Ellipse:
861
GeomEllipse* elips = new GeomEllipse();
862
Handle(Geom_Ellipse) this_curv = Handle(Geom_Ellipse)::DownCast
864
this_curv->SetElips(adapt.Ellipse());
865
curve = new EllipsePy(elips);
868
case GeomAbs_Hyperbola:
870
GeomHyperbola* hypr = new GeomHyperbola();
871
Handle(Geom_Hyperbola) this_curv = Handle(Geom_Hyperbola)::DownCast
873
this_curv->SetHypr(adapt.Hyperbola());
874
curve = new HyperbolaPy(hypr);
877
case GeomAbs_Parabola:
879
GeomParabola* parab = new GeomParabola();
880
Handle(Geom_Parabola) this_curv = Handle(Geom_Parabola)::DownCast
882
this_curv->SetParab(adapt.Parabola());
883
curve = new ParabolaPy(parab);
886
case GeomAbs_BezierCurve:
888
GeomBezierCurve* bezier = new GeomBezierCurve(adapt.Bezier());
889
curve = new BezierCurvePy(bezier);
892
case GeomAbs_BSplineCurve:
894
GeomBSplineCurve* bspline = new GeomBSplineCurve(adapt.BSpline());
895
curve = new BSplineCurvePy(bspline);
898
case GeomAbs_OffsetCurve:
900
Standard_Real first, last;
901
Handle(Geom_Curve) c = BRep_Tool::Curve(e, first, last);
902
Handle(Geom_OffsetCurve) off = Handle(Geom_OffsetCurve)::DownCast(c);
904
GeomOffsetCurve* offset = new GeomOffsetCurve(off);
905
curve = new OffsetCurvePy(offset);
909
throw Py::RuntimeError("Failed to convert to offset curve");
912
case GeomAbs_OtherCurve:
917
curve->setNotTracking();
918
return Py::asObject(curve);
921
throw Py::TypeError("undefined curve type");
924
Py::Tuple TopoShapeEdgePy::getParameterRange() const
926
auto e = getTopoDSEdge(this);
927
BRepAdaptor_Curve adapt(e);
928
double u = adapt.FirstParameter();
929
double v = adapt.LastParameter();
932
t.setItem(0, Py::Float(u));
933
t.setItem(1, Py::Float(v));
937
Py::Float TopoShapeEdgePy::getFirstParameter() const
939
auto e = getTopoDSEdge(this);
940
BRepAdaptor_Curve adapt(e);
941
double t = adapt.FirstParameter();
945
Py::Float TopoShapeEdgePy::getLastParameter() const
947
auto e = getTopoDSEdge(this);
948
BRepAdaptor_Curve adapt(e);
949
double t = adapt.LastParameter();
953
Py::Object TopoShapeEdgePy::getMass() const
956
BRepGProp::LinearProperties(getTopoShapePtr()->getShape(), props);
957
double c = props.Mass();
961
Py::Object TopoShapeEdgePy::getCenterOfMass() const
964
BRepGProp::LinearProperties(getTopoShapePtr()->getShape(), props);
965
gp_Pnt c = props.CentreOfMass();
966
return Py::Vector(Base::Vector3d(c.X(),c.Y(),c.Z()));
969
Py::Object TopoShapeEdgePy::getMatrixOfInertia() const
972
BRepGProp::LinearProperties(getTopoShapePtr()->getShape(), props);
973
gp_Mat m = props.MatrixOfInertia();
975
for (int i=0; i<3; i++) {
976
for (int j=0; j<3; j++) {
977
mat[i][j] = m(i+1,j+1);
980
return Py::Matrix(mat);
983
Py::Object TopoShapeEdgePy::getStaticMoments() const
986
BRepGProp::LinearProperties(getTopoShapePtr()->getShape(), props);
987
Standard_Real lx,ly,lz;
988
props.StaticMoments(lx,ly,lz);
990
tuple.setItem(0, Py::Float(lx));
991
tuple.setItem(1, Py::Float(ly));
992
tuple.setItem(2, Py::Float(lz));
996
Py::Dict TopoShapeEdgePy::getPrincipalProperties() const
999
BRepGProp::LinearProperties(getTopoShapePtr()->getShape(), props);
1000
GProp_PrincipalProps pprops = props.PrincipalProperties();
1003
dict.setItem("SymmetryAxis", Py::Boolean(pprops.HasSymmetryAxis() ? true : false));
1004
dict.setItem("SymmetryPoint", Py::Boolean(pprops.HasSymmetryPoint() ? true : false));
1005
Standard_Real lx,ly,lz;
1006
pprops.Moments(lx,ly,lz);
1008
tuple.setItem(0, Py::Float(lx));
1009
tuple.setItem(1, Py::Float(ly));
1010
tuple.setItem(2, Py::Float(lz));
1011
dict.setItem("Moments",tuple);
1012
dict.setItem("FirstAxisOfInertia",Py::Vector(Base::convertTo
1013
<Base::Vector3d>(pprops.FirstAxisOfInertia())));
1014
dict.setItem("SecondAxisOfInertia",Py::Vector(Base::convertTo
1015
<Base::Vector3d>(pprops.SecondAxisOfInertia())));
1016
dict.setItem("ThirdAxisOfInertia",Py::Vector(Base::convertTo
1017
<Base::Vector3d>(pprops.ThirdAxisOfInertia())));
1019
Standard_Real Rxx,Ryy,Rzz;
1020
pprops.RadiusOfGyration(Rxx,Ryy,Rzz);
1022
rog.setItem(0, Py::Float(Rxx));
1023
rog.setItem(1, Py::Float(Ryy));
1024
rog.setItem(2, Py::Float(Rzz));
1025
dict.setItem("RadiusOfGyration",rog);
1029
Py::Boolean TopoShapeEdgePy::getClosed() const
1031
if (getTopoShapePtr()->getShape().IsNull())
1032
throw Py::RuntimeError("Cannot determine the 'Closed'' flag of an empty shape");
1033
Standard_Boolean ok = BRep_Tool::IsClosed(getTopoShapePtr()->getShape());
1034
return Py::Boolean(ok ? true : false);
1037
Py::Boolean TopoShapeEdgePy::getDegenerated() const
1039
Standard_Boolean ok = BRep_Tool::Degenerated(TopoDS::Edge(getTopoShapePtr()->getShape()));
1040
return Py::Boolean(ok ? true : false);
1043
PyObject* TopoShapeEdgePy::curveOnSurface(PyObject *args)
1046
if (!PyArg_ParseTuple(args, "i", &idx))
1050
TopoDS_Edge edge = TopoDS::Edge(getTopoShapePtr()->getShape());
1051
Handle(Geom2d_Curve) curve;
1052
Handle(Geom_Surface) surf;
1053
TopLoc_Location loc;
1054
Standard_Real first, last;
1056
BRep_Tool::CurveOnSurface(edge, curve, surf, loc, first, last, idx+1);
1059
std::unique_ptr<Part::Geom2dCurve> geo2d(makeFromCurve2d(curve));
1062
std::unique_ptr<Part::GeomSurface> geosurf(makeFromSurface(surf));
1066
gp_Trsf trsf = loc.Transformation();
1067
gp_XYZ pos = trsf.TranslationPart();
1069
Standard_Real angle;
1070
trsf.GetRotation(axis, angle);
1071
Base::Rotation rot(Base::Vector3d(axis.X(), axis.Y(), axis.Z()), angle);
1072
Base::Placement placement(Base::Vector3d(pos.X(), pos.Y(), pos.Z()), rot);
1075
tuple.setItem(0, Py::asObject(geo2d->getPyObject()));
1076
tuple.setItem(1, Py::asObject(geosurf->getPyObject()));
1077
tuple.setItem(2, Py::asObject(new Base::PlacementPy(placement)));
1078
tuple.setItem(3, Py::Float(first));
1079
tuple.setItem(4, Py::Float(last));
1080
return Py::new_reference_to(tuple);
1082
catch (Standard_Failure& e) {
1083
PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
1088
PyObject *TopoShapeEdgePy::getCustomAttributes(const char* /*attr*/) const
1093
int TopoShapeEdgePy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)