diff --git a/src/Mod/Part/App/GeometryCurvePy.xml b/src/Mod/Part/App/GeometryCurvePy.xml index b8a5498eaf31..ba3cc7854bb5 100644 --- a/src/Mod/Part/App/GeometryCurvePy.xml +++ b/src/Mod/Part/App/GeometryCurvePy.xml @@ -66,6 +66,14 @@ of the nearest orthogonal projection of the point. + + + + Approximates a curve of any type to a B-Spline curve + approximateBSpline(Tolerance, MaxSegments, MaxDegree, [Order='C2']) -> B-Spline curve + + + diff --git a/src/Mod/Part/App/GeometryCurvePyImp.cpp b/src/Mod/Part/App/GeometryCurvePyImp.cpp index 1e59fab9c729..1c8966e77cfc 100644 --- a/src/Mod/Part/App/GeometryCurvePyImp.cpp +++ b/src/Mod/Part/App/GeometryCurvePyImp.cpp @@ -23,6 +23,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ +# include # include # include # include @@ -42,6 +43,7 @@ # include # include # include +# include # include # include #endif @@ -367,6 +369,57 @@ PyObject* GeometryCurvePy::toBSpline(PyObject * args) return 0; } +PyObject* GeometryCurvePy::approximateBSpline(PyObject *args) +{ + double tolerance; + int maxSegment, maxDegree; + char* order = "C2"; + if (!PyArg_ParseTuple(args, "dii|s", &tolerance, &maxSegment, &maxDegree, &order)) + return 0; + + GeomAbs_Shape absShape; + std::string str = order; + if (str == "C0") + absShape = GeomAbs_C0; + else if (str == "G1") + absShape = GeomAbs_G1; + else if (str == "C1") + absShape = GeomAbs_C1; + else if (str == "G2") + absShape = GeomAbs_G2; + else if (str == "C2") + absShape = GeomAbs_C2; + else if (str == "C3") + absShape = GeomAbs_C3; + else if (str == "CN") + absShape = GeomAbs_CN; + else + absShape = GeomAbs_C2; + + try { + Handle_Geom_Curve self = Handle_Geom_Curve::DownCast(getGeometryPtr()->handle()); + GeomConvert_ApproxCurve approx(self, tolerance, absShape, maxSegment, maxDegree); + if (approx.IsDone()) { + return new BSplineCurvePy(new GeomBSplineCurve(approx.Curve())); + } + else if (approx.HasResult()) { + std::stringstream str; + str << "Maximum error (" << approx.MaxError() << ") is outside tolerance"; + PyErr_SetString(PyExc_RuntimeError, str.str().c_str()); + return 0; + } + else { + PyErr_SetString(PyExc_RuntimeError, "Approximation of curve failed"); + return 0; + } + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(PyExc_Exception, e->GetMessageString()); + return 0; + } +} + Py::String GeometryCurvePy::getContinuity(void) const { GeomAbs_Shape c = Handle_Geom_Curve::DownCast @@ -376,7 +429,6 @@ Py::String GeometryCurvePy::getContinuity(void) const case GeomAbs_C0: str = "C0"; break; - break; case GeomAbs_G1: str = "G1"; break;