Part: improve Python interface

+ rename getCurve2dFromGeom2d to makeFromCurve2d
+ add function makeFromCurve and makeFromTrimmedCurve like makeFromSurface
+ implement OffsetCurve.BasisCurve
+ fix memory leak in BRepOffsetAPI_MakePipeShellPy
This commit is contained in:
wmayer
2020-09-27 23:34:45 +02:00
parent 1ef31842c9
commit a6c55acdb1
10 changed files with 166 additions and 147 deletions

View File

@@ -10,7 +10,8 @@
Namespace="Part"
FatherInclude="Base/PyObjectBase.h"
FatherNamespace="Base"
Constructor="true">
Constructor="true"
Delete="true">
<Documentation>
<Author Licence="LGPL" Name="Werner Mayer" EMail="wmayer[at]users.sourceforge.net" />
<UserDocu>Describes a portion of a circle</UserDocu>

View File

@@ -95,7 +95,7 @@ Py::Object OffsetCurve2dPy::getBasisCurve(void) const
Handle(Geom2d_Curve) basis = curve->BasisCurve();
if (basis.IsNull())
return Py::None();
std::unique_ptr<Geom2dCurve> geo2d = getCurve2dFromGeom2d(basis);
std::unique_ptr<Geom2dCurve> geo2d = makeFromCurve2d(basis);
if (!geo2d)
throw Py::RuntimeError("Unknown curve type");
return Py::asObject(geo2d->getPyObject());

View File

@@ -4899,4 +4899,144 @@ std::unique_ptr<GeomSurface> makeFromSurface(const Handle(Geom_Surface)& s)
return geoSurf;
}
std::unique_ptr<GeomCurve> makeFromCurve(const Handle(Geom_Curve)& c)
{
std::unique_ptr<GeomCurve> geoCurve;
if (c->IsKind(STANDARD_TYPE(Geom_Circle))) {
Handle(Geom_Circle) circ = Handle(Geom_Circle)::DownCast(c);
geoCurve.reset(new GeomCircle(circ));
}
else if (c->IsKind(STANDARD_TYPE(Geom_Ellipse))) {
Handle(Geom_Ellipse) ell = Handle(Geom_Ellipse)::DownCast(c);
geoCurve.reset(new GeomEllipse(ell));
}
else if (c->IsKind(STANDARD_TYPE(Geom_Hyperbola))) {
Handle(Geom_Hyperbola) hyp = Handle(Geom_Hyperbola)::DownCast(c);
geoCurve.reset(new GeomHyperbola(hyp));
}
else if (c->IsKind(STANDARD_TYPE(Geom_Line))) {
Handle(Geom_Line) lin = Handle(Geom_Line)::DownCast(c);
geoCurve.reset(new GeomLine(lin));
}
else if (c->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) {
Handle(Geom_OffsetCurve) oc = Handle(Geom_OffsetCurve)::DownCast(c);
geoCurve.reset(new GeomOffsetCurve(oc));
}
else if (c->IsKind(STANDARD_TYPE(Geom_Parabola))) {
Handle(Geom_Parabola) par = Handle(Geom_Parabola)::DownCast(c);
geoCurve.reset(new GeomParabola(par));
}
else if (c->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
return makeFromTrimmedCurve(c, c->FirstParameter(), c->LastParameter());
}
/*else if (c->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) {
Handle(Geom_BoundedCurve) bc = Handle(Geom_BoundedCurve)::DownCast(c);
return Py::asObject(new GeometryCurvePy(new GeomBoundedCurve(bc)));
}*/
else if (c->IsKind(STANDARD_TYPE(Geom_BezierCurve))) {
Handle(Geom_BezierCurve) bezier = Handle(Geom_BezierCurve)::DownCast(c);
geoCurve.reset(new GeomBezierCurve(bezier));
}
else if (c->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) {
Handle(Geom_BSplineCurve) bspline = Handle(Geom_BSplineCurve)::DownCast(c);
geoCurve.reset(new GeomBSplineCurve(bspline));
}
else {
std::string err = "Unhandled curve type ";
err += c->DynamicType()->Name();
throw Base::TypeError(err);
}
return geoCurve;
}
std::unique_ptr<GeomCurve> makeFromTrimmedCurve(const Handle(Geom_Curve)& c, double f, double l)
{
if (c->IsKind(STANDARD_TYPE(Geom_Circle))) {
Handle(Geom_Circle) circ = Handle(Geom_Circle)::DownCast(c);
std::unique_ptr<GeomArcOfCircle> arc(new GeomArcOfCircle());
Handle(Geom_TrimmedCurve) this_arc = Handle(Geom_TrimmedCurve)::DownCast
(arc->handle());
Handle(Geom_Circle) this_circ = Handle(Geom_Circle)::DownCast
(this_arc->BasisCurve());
this_circ->SetCirc(circ->Circ());
this_arc->SetTrim(f, l);
return arc;
}
else if (c->IsKind(STANDARD_TYPE(Geom_Ellipse))) {
Handle(Geom_Ellipse) ellp = Handle(Geom_Ellipse)::DownCast(c);
std::unique_ptr<GeomArcOfEllipse> arc(new GeomArcOfEllipse());
Handle(Geom_TrimmedCurve) this_arc = Handle(Geom_TrimmedCurve)::DownCast
(arc->handle());
Handle(Geom_Ellipse) this_ellp = Handle(Geom_Ellipse)::DownCast
(this_arc->BasisCurve());
this_ellp->SetElips(ellp->Elips());
this_arc->SetTrim(f, l);
return arc;
}
else if (c->IsKind(STANDARD_TYPE(Geom_Hyperbola))) {
Handle(Geom_Hyperbola) hypr = Handle(Geom_Hyperbola)::DownCast(c);
std::unique_ptr<GeomArcOfHyperbola> arc(new GeomArcOfHyperbola());
Handle(Geom_TrimmedCurve) this_arc = Handle(Geom_TrimmedCurve)::DownCast
(arc->handle());
Handle(Geom_Hyperbola) this_hypr = Handle(Geom_Hyperbola)::DownCast
(this_arc->BasisCurve());
this_hypr->SetHypr(hypr->Hypr());
this_arc->SetTrim(f, l);
return arc;
}
else if (c->IsKind(STANDARD_TYPE(Geom_Line))) {
Handle(Geom_Line) line = Handle(Geom_Line)::DownCast(c);
std::unique_ptr<GeomLineSegment> segm(new GeomLineSegment());
Handle(Geom_TrimmedCurve) this_segm = Handle(Geom_TrimmedCurve)::DownCast
(segm->handle());
Handle(Geom_Line) this_line = Handle(Geom_Line)::DownCast
(this_segm->BasisCurve());
this_line->SetLin(line->Lin());
this_segm->SetTrim(f, l);
return segm;
}
else if (c->IsKind(STANDARD_TYPE(Geom_Parabola))) {
Handle(Geom_Parabola) para = Handle(Geom_Parabola)::DownCast(c);
std::unique_ptr<GeomArcOfParabola> arc(new GeomArcOfParabola());
Handle(Geom_TrimmedCurve) this_arc = Handle(Geom_TrimmedCurve)::DownCast
(arc->handle());
Handle(Geom_Parabola) this_para = Handle(Geom_Parabola)::DownCast
(this_arc->BasisCurve());
this_para->SetParab(para->Parab());
this_arc->SetTrim(f, l);
return arc;
}
else if (c->IsKind(STANDARD_TYPE(Geom_BezierCurve))) {
Handle(Geom_BezierCurve) bezier = Handle(Geom_BezierCurve)::DownCast(c->Copy());
bezier->Segment(f, l);
return std::unique_ptr<GeomBezierCurve>(new GeomBezierCurve(bezier));
}
else if (c->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) {
Handle(Geom_BSplineCurve) bspline = Handle(Geom_BSplineCurve)::DownCast(c->Copy());
bspline->Segment(f, l);
return std::unique_ptr<GeomBSplineCurve>(new GeomBSplineCurve(bspline));
}
else if (c->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) {
Handle(Geom_OffsetCurve) oc = Handle(Geom_OffsetCurve)::DownCast(c);
double v = oc->Offset();
gp_Dir dir = oc->Direction();
std::unique_ptr<GeomCurve> bc(makeFromTrimmedCurve(oc->BasisCurve(), f, l));
return std::unique_ptr<GeomOffsetCurve>(new GeomOffsetCurve(Handle(Geom_Curve)::DownCast(bc->handle()), v, dir));
}
else if (c->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
Handle(Geom_TrimmedCurve) trc = Handle(Geom_TrimmedCurve)::DownCast(c);
return makeFromTrimmedCurve(trc->BasisCurve(), f, l);
}
/*else if (c->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) {
Handle(Geom_BoundedCurve) bc = Handle(Geom_BoundedCurve)::DownCast(c);
return Py::asObject(new GeometryCurvePy(new GeomBoundedCurve(bc)));
}*/
else {
std::string err = "Unhandled curve type ";
err += c->DynamicType()->Name();
throw Base::TypeError(err);
}
}
}

View File

@@ -1081,6 +1081,12 @@ GeomArcOfCircle *createFilletGeometry(const GeomLineSegment *lineSeg1, const Geo
const Base::Vector3d &center, double radius);
PartExport
std::unique_ptr<GeomSurface> makeFromSurface(const Handle(Geom_Surface)&);
PartExport
std::unique_ptr<GeomCurve> makeFromCurve(const Handle(Geom_Curve)&);
PartExport
std::unique_ptr<GeomCurve> makeFromTrimmedCurve(const Handle(Geom_Curve)&, double f, double l);
}
#endif // PART_GEOMETRY_H

View File

@@ -2256,7 +2256,7 @@ PyObject *Geom2dTrimmedCurve::getPyObject(void)
// ------------------------------------------------------------------
namespace Part {
std::unique_ptr<Geom2dCurve> getCurve2dFromGeom2d(Handle(Geom2d_Curve) curve)
std::unique_ptr<Geom2dCurve> makeFromCurve2d(Handle(Geom2d_Curve) curve)
{
std::unique_ptr<Geom2dCurve> geo2d;
if (curve.IsNull())

View File

@@ -564,7 +564,7 @@ private:
Handle(Geom2d_TrimmedCurve) myCurve;
};
std::unique_ptr<Geom2dCurve> getCurve2dFromGeom2d(Handle(Geom2d_Curve));
std::unique_ptr<Geom2dCurve> makeFromCurve2d(Handle(Geom2d_Curve));
}

View File

@@ -75,155 +75,26 @@
#include <Mod/Part/App/TopoShapeFacePy.h>
namespace Part {
const Py::Object makeTrimmedCurvePy(const Handle(Geom_Curve)& c, double f,double l)
const Py::Object makeTrimmedCurvePy(const Handle(Geom_Curve)& c, double f, double l)
{
if (c->IsKind(STANDARD_TYPE(Geom_Circle))) {
Handle(Geom_Circle) circ = Handle(Geom_Circle)::DownCast(c);
GeomArcOfCircle* arc = new GeomArcOfCircle();
Handle(Geom_TrimmedCurve) this_arc = Handle(Geom_TrimmedCurve)::DownCast
(arc->handle());
Handle(Geom_Circle) this_circ = Handle(Geom_Circle)::DownCast
(this_arc->BasisCurve());
this_circ->SetCirc(circ->Circ());
this_arc->SetTrim(f, l);
return Py::Object(new ArcOfCirclePy(arc),true);
try {
std::unique_ptr<GeomCurve> gc(makeFromTrimmedCurve(c, f, l));
return Py::asObject(gc->getPyObject());
}
else if (c->IsKind(STANDARD_TYPE(Geom_Ellipse))) {
Handle(Geom_Ellipse) ellp = Handle(Geom_Ellipse)::DownCast(c);
GeomArcOfEllipse* arc = new GeomArcOfEllipse();
Handle(Geom_TrimmedCurve) this_arc = Handle(Geom_TrimmedCurve)::DownCast
(arc->handle());
Handle(Geom_Ellipse) this_ellp = Handle(Geom_Ellipse)::DownCast
(this_arc->BasisCurve());
this_ellp->SetElips(ellp->Elips());
this_arc->SetTrim(f, l);
return Py::Object(new ArcOfEllipsePy(arc),true);
catch (const Base::Exception& e) {
throw Py::TypeError(e.what());
}
else if (c->IsKind(STANDARD_TYPE(Geom_Hyperbola))) {
Handle(Geom_Hyperbola) hypr = Handle(Geom_Hyperbola)::DownCast(c);
GeomArcOfHyperbola* arc = new GeomArcOfHyperbola();
Handle(Geom_TrimmedCurve) this_arc = Handle(Geom_TrimmedCurve)::DownCast
(arc->handle());
Handle(Geom_Hyperbola) this_hypr = Handle(Geom_Hyperbola)::DownCast
(this_arc->BasisCurve());
this_hypr->SetHypr(hypr->Hypr());
this_arc->SetTrim(f, l);
return Py::Object(new ArcOfHyperbolaPy(arc),true);
}
else if (c->IsKind(STANDARD_TYPE(Geom_Line))) {
Handle(Geom_Line) line = Handle(Geom_Line)::DownCast(c);
GeomLineSegment* segm = new GeomLineSegment();
Handle(Geom_TrimmedCurve) this_segm = Handle(Geom_TrimmedCurve)::DownCast
(segm->handle());
Handle(Geom_Line) this_line = Handle(Geom_Line)::DownCast
(this_segm->BasisCurve());
this_line->SetLin(line->Lin());
this_segm->SetTrim(f, l);
return Py::Object(new LineSegmentPy(segm),true);
}
else if (c->IsKind(STANDARD_TYPE(Geom_Parabola))) {
Handle(Geom_Parabola) para = Handle(Geom_Parabola)::DownCast(c);
GeomArcOfParabola* arc = new GeomArcOfParabola();
Handle(Geom_TrimmedCurve) this_arc = Handle(Geom_TrimmedCurve)::DownCast
(arc->handle());
Handle(Geom_Parabola) this_para = Handle(Geom_Parabola)::DownCast
(this_arc->BasisCurve());
this_para->SetParab(para->Parab());
this_arc->SetTrim(f, l);
return Py::Object(new ArcOfParabolaPy(arc),true);
}
else if (c->IsKind(STANDARD_TYPE(Geom_BezierCurve))) {
Handle(Geom_BezierCurve) bezier = Handle(Geom_BezierCurve)::DownCast(c->Copy());
bezier->Segment(f, l);
return Py::asObject(new BezierCurvePy(new GeomBezierCurve(bezier)));
}
else if (c->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) {
Handle(Geom_BSplineCurve) bspline = Handle(Geom_BSplineCurve)::DownCast(c->Copy());
bspline->Segment(f, l);
return Py::asObject(new BSplineCurvePy(new GeomBSplineCurve(bspline)));
}
else if (c->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) {
Handle(Geom_OffsetCurve) oc = Handle(Geom_OffsetCurve)::DownCast(c);
double v = oc->Offset();
gp_Dir dir = oc->Direction();
Py::Object off(makeTrimmedCurvePy(oc->BasisCurve(), f, l));
Py::Tuple args(3);
args.setItem(0, off);
args.setItem(1, Py::Float(v));
Py::Module baseModule("__FreeCADBase__");
Py::Callable method(baseModule.getAttr("Vector"));
Py::Tuple coords(3);
coords.setItem(0, Py::Float(dir.X()));
coords.setItem(1, Py::Float(dir.Y()));
coords.setItem(2, Py::Float(dir.Z()));
args.setItem(2, method.apply(coords));
Py::Module partModule(PyImport_ImportModule("Part"), true);
Py::Callable call(partModule.getAttr("OffsetCurve"));
return call.apply(args);
}
else if (c->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
Handle(Geom_TrimmedCurve) trc = Handle(Geom_TrimmedCurve)::DownCast(c);
return makeTrimmedCurvePy(trc->BasisCurve(), f, l);
}
/*else if (c->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) {
Handle(Geom_BoundedCurve) bc = Handle(Geom_BoundedCurve)::DownCast(c);
return Py::asObject(new GeometryCurvePy(new GeomBoundedCurve(bc)));
}*/
std::string err = "Unhandled curve type ";
err += c->DynamicType()->Name();
throw Py::TypeError(err);
}
const Py::Object makeGeometryCurvePy(const Handle(Geom_Curve)& c)
{
if (c->IsKind(STANDARD_TYPE(Geom_Circle))) {
Handle(Geom_Circle) circ = Handle(Geom_Circle)::DownCast(c);
return Py::asObject(new CirclePy(new GeomCircle(circ)));
try {
std::unique_ptr<GeomCurve> gc(makeFromCurve(c));
return Py::asObject(gc->getPyObject());
}
else if (c->IsKind(STANDARD_TYPE(Geom_Ellipse))) {
Handle(Geom_Ellipse) ell = Handle(Geom_Ellipse)::DownCast(c);
return Py::asObject(new EllipsePy(new GeomEllipse(ell)));
catch (const Base::Exception& e) {
throw Py::TypeError(e.what());
}
else if (c->IsKind(STANDARD_TYPE(Geom_Hyperbola))) {
Handle(Geom_Hyperbola) hyp = Handle(Geom_Hyperbola)::DownCast(c);
return Py::asObject(new HyperbolaPy(new GeomHyperbola(hyp)));
}
else if (c->IsKind(STANDARD_TYPE(Geom_Line))) {
Handle(Geom_Line) lin = Handle(Geom_Line)::DownCast(c);
return Py::asObject(new LinePy(new GeomLine(lin)));
}
else if (c->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) {
Handle(Geom_OffsetCurve) oc = Handle(Geom_OffsetCurve)::DownCast(c);
return Py::asObject(new OffsetCurvePy(new GeomOffsetCurve(oc)));
}
else if (c->IsKind(STANDARD_TYPE(Geom_Parabola))) {
Handle(Geom_Parabola) par = Handle(Geom_Parabola)::DownCast(c);
return Py::asObject(new ParabolaPy(new GeomParabola(par)));
}
else if (c->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
return makeTrimmedCurvePy(c, c->FirstParameter(), c->LastParameter());
}
/*else if (c->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) {
Handle(Geom_BoundedCurve) bc = Handle(Geom_BoundedCurve)::DownCast(c);
return Py::asObject(new GeometryCurvePy(new GeomBoundedCurve(bc)));
}*/
else if (c->IsKind(STANDARD_TYPE(Geom_BezierCurve))) {
Handle(Geom_BezierCurve) bezier = Handle(Geom_BezierCurve)::DownCast(c);
return Py::asObject(new BezierCurvePy(new GeomBezierCurve(bezier)));
}
else if (c->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) {
Handle(Geom_BSplineCurve) bspline = Handle(Geom_BSplineCurve)::DownCast(c);
return Py::asObject(new BSplineCurvePy(new GeomBSplineCurve(bspline)));
}
std::string err = "Unhandled curve type ";
err += c->DynamicType()->Name();
throw Py::TypeError(err);
}
} // Part

View File

@@ -125,7 +125,8 @@ Py::Object OffsetCurvePy::getBasisCurve(void) const
{
Handle(Geom_OffsetCurve) curve = Handle(Geom_OffsetCurve)::DownCast(getGeometryPtr()->handle());
Handle(Geom_Curve) basis = curve->BasisCurve();
throw Py::Exception(PyExc_NotImplementedError, "Not yet implemented");
std::unique_ptr<GeomCurve> ptr(Part::makeFromCurve(basis));
return Py::asObject(ptr->getPyObject());
}
void OffsetCurvePy::setBasisCurve(Py::Object arg)

View File

@@ -1065,7 +1065,7 @@ PyObject* TopoShapeEdgePy::curveOnSurface(PyObject *args)
BRep_Tool::CurveOnSurface(edge, curve, surf, loc, first, last, idx+1);
if (curve.IsNull())
Py_Return;
std::unique_ptr<Part::Geom2dCurve> geo2d(getCurve2dFromGeom2d(curve));
std::unique_ptr<Part::Geom2dCurve> geo2d(makeFromCurve2d(curve));
if (!geo2d)
Py_Return;
std::unique_ptr<Part::GeomSurface> geosurf(makeFromSurface(surf));

View File

@@ -713,7 +713,7 @@ PyObject* TopoShapeFacePy::curveOnSurface(PyObject *args)
Standard_Real first, last;
Handle(Geom2d_Curve) curve = BRep_Tool::CurveOnSurface(edge, face, first, last);
std::unique_ptr<Part::Geom2dCurve> geo2d = getCurve2dFromGeom2d(curve);
std::unique_ptr<Part::Geom2dCurve> geo2d = makeFromCurve2d(curve);
if (!geo2d)
Py_Return;