diff --git a/src/Mod/Part/App/AppPart.cpp b/src/Mod/Part/App/AppPart.cpp index 4e623335a..cc614c9c1 100644 --- a/src/Mod/Part/App/AppPart.cpp +++ b/src/Mod/Part/App/AppPart.cpp @@ -75,7 +75,6 @@ #include "ArcOfHyperbolaPy.h" #include "BezierCurvePy.h" #include "BSplineCurvePy.h" -#include "HermiteCurvePy.h" #include "HyperbolaPy.h" #include "OffsetCurvePy.h" #include "ParabolaPy.h" @@ -201,7 +200,6 @@ PyMODINIT_FUNC initPart() Base::Interpreter().addType(&Part::ArcOfHyperbolaPy ::Type,partModule,"ArcOfHyperbola"); Base::Interpreter().addType(&Part::BezierCurvePy ::Type,partModule,"BezierCurve"); Base::Interpreter().addType(&Part::BSplineCurvePy ::Type,partModule,"BSplineCurve"); - Base::Interpreter().addType(&Part::HermiteCurvePy ::Type,partModule,"HermiteCurve"); Base::Interpreter().addType(&Part::OffsetCurvePy ::Type,partModule,"OffsetCurve"); Base::Interpreter().addType(&Part::PlanePy ::Type,partModule,"Plane"); @@ -322,7 +320,6 @@ PyMODINIT_FUNC initPart() Part::GeomCurve ::init(); Part::GeomBezierCurve ::init(); Part::GeomBSplineCurve ::init(); - Part::GeomHermiteCurve ::init(); Part::GeomCircle ::init(); Part::GeomArcOfCircle ::init(); Part::GeomArcOfEllipse ::init(); diff --git a/src/Mod/Part/App/BSplineCurvePy.xml b/src/Mod/Part/App/BSplineCurvePy.xml index 2047f1e78..5ce664c0c 100644 --- a/src/Mod/Part/App/BSplineCurvePy.xml +++ b/src/Mod/Part/App/BSplineCurvePy.xml @@ -327,6 +327,11 @@ from the knots table of this B-Spline curve. + + + Compute the tangents for a Cardinal spline + + diff --git a/src/Mod/Part/App/BSplineCurvePyImp.cpp b/src/Mod/Part/App/BSplineCurvePyImp.cpp index 7bbde729b..ab16b4b9e 100644 --- a/src/Mod/Part/App/BSplineCurvePyImp.cpp +++ b/src/Mod/Part/App/BSplineCurvePyImp.cpp @@ -865,6 +865,66 @@ PyObject* BSplineCurvePy::approximate(PyObject *args, PyObject *kwds) } } +PyObject* BSplineCurvePy::getCardinalSplineTangents(PyObject *args, PyObject *kwds) +{ + PyObject* pts; + PyObject* tgs; + double parameter; + + static char* kwds_interp1[] = {"Points", "Parameter", NULL}; + if (PyArg_ParseTupleAndKeywords(args, kwds, "Od",kwds_interp1, &pts, ¶meter)) { + Py::Sequence list(pts); + std::vector interpPoints; + interpPoints.reserve(list.size()); + for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { + Py::Vector v(*it); + Base::Vector3d pnt = v.toVector(); + interpPoints.push_back(gp_Pnt(pnt.x,pnt.y,pnt.z)); + } + + GeomBSplineCurve* bspline = this->getGeomBSplineCurvePtr(); + std::vector tangents; + bspline->getCardinalSplineTangents(interpPoints, parameter, tangents); + + Py::List vec; + for (gp_Vec it : tangents) + vec.append(Py::Vector(Base::Vector3d(it.X(), it.Y(), it.Z()))); + return Py::new_reference_to(vec); + } + + PyErr_Clear(); + static char* kwds_interp2[] = {"Points", "Parameters", NULL}; + if (PyArg_ParseTupleAndKeywords(args, kwds, "OO",kwds_interp2, &pts, &tgs)) { + Py::Sequence list(pts); + std::vector interpPoints; + interpPoints.reserve(list.size()); + for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { + Py::Vector v(*it); + Base::Vector3d pnt = v.toVector(); + interpPoints.push_back(gp_Pnt(pnt.x,pnt.y,pnt.z)); + } + + Py::Sequence list2(tgs); + std::vector parameters; + parameters.reserve(list2.size()); + for (Py::Sequence::iterator it = list2.begin(); it != list2.end(); ++it) { + Py::Float p(*it); + parameters.push_back(static_cast(p)); + } + + GeomBSplineCurve* bspline = this->getGeomBSplineCurvePtr(); + std::vector tangents; + bspline->getCardinalSplineTangents(interpPoints, parameters, tangents); + + Py::List vec; + for (gp_Vec it : tangents) + vec.append(Py::Vector(Base::Vector3d(it.X(), it.Y(), it.Z()))); + return Py::new_reference_to(vec); + } + + return 0; +} + PyObject* BSplineCurvePy::interpolate(PyObject *args, PyObject *kwds) { PyObject* obj; diff --git a/src/Mod/Part/App/CMakeLists.txt b/src/Mod/Part/App/CMakeLists.txt index dba514687..bee0cdcee 100644 --- a/src/Mod/Part/App/CMakeLists.txt +++ b/src/Mod/Part/App/CMakeLists.txt @@ -56,7 +56,6 @@ generate_from_xml(LinePy) generate_from_xml(PointPy) generate_from_xml(BezierCurvePy) generate_from_xml(BSplineCurvePy) -generate_from_xml(HermiteCurvePy) generate_from_xml(PlanePy) generate_from_xml(ConePy) generate_from_xml(CylinderPy) @@ -195,8 +194,6 @@ SET(Python_SRCS BezierCurvePyImp.cpp BSplineCurvePy.xml BSplineCurvePyImp.cpp - HermiteCurvePy.xml - HermiteCurvePyImp.cpp PlanePy.xml PlanePyImp.cpp ConePy.xml diff --git a/src/Mod/Part/App/Geometry.cpp b/src/Mod/Part/App/Geometry.cpp index a9adf80f4..e3c97c853 100644 --- a/src/Mod/Part/App/Geometry.cpp +++ b/src/Mod/Part/App/Geometry.cpp @@ -98,33 +98,32 @@ #endif -#include "LinePy.h" #include -#include "CirclePy.h" -#include "EllipsePy.h" -#include "ArcPy.h" -#include "ArcOfCirclePy.h" -#include "ArcOfEllipsePy.h" -#include "ArcOfParabolaPy.h" -#include "BezierCurvePy.h" -#include "BSplineCurvePy.h" -#include "HermiteCurvePy.h" -#include "HyperbolaPy.h" -#include "ArcOfHyperbolaPy.h" -#include "OffsetCurvePy.h" -#include "ParabolaPy.h" -#include "BezierSurfacePy.h" -#include "BSplineSurfacePy.h" -#include "ConePy.h" -#include "CylinderPy.h" -#include "OffsetSurfacePy.h" -#include "PlateSurfacePy.h" -#include "PlanePy.h" -#include "RectangularTrimmedSurfacePy.h" -#include "SpherePy.h" -#include "SurfaceOfExtrusionPy.h" -#include "SurfaceOfRevolutionPy.h" -#include "ToroidPy.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -473,148 +472,6 @@ PyObject *GeomBezierCurve::getPyObject(void) // ------------------------------------------------- -TYPESYSTEM_SOURCE(Part::GeomHermiteCurve,Part::GeomCurve); - -GeomHermiteCurve::GeomHermiteCurve() -{ - std::vector p; - p.push_back(gp_Pnt(0.0,0.0,0.0)); - p.push_back(gp_Pnt(1.0,0.0,0.0)); - - std::vector t; - t.push_back(gp_Vec(1,0,0)); - t.push_back(gp_Vec(1,0,0)); - - compute(p, t); -} - -GeomHermiteCurve::GeomHermiteCurve(const std::vector& p, - const std::vector& t) -{ - compute(p, t); -} - -GeomHermiteCurve::~GeomHermiteCurve() -{ -} - -void GeomHermiteCurve::interpolate(const std::vector& p, - const std::vector& t) -{ - if (p.size() < 2) - Standard_ConstructionError::Raise(); - if (p.size() != t.size()) - Standard_ConstructionError::Raise(); - - compute(p, t); -} - -void GeomHermiteCurve::getCardinalSplineTangents(const std::vector& p, - const std::vector& c, - std::vector& t) const -{ - // https://de.wikipedia.org/wiki/Kubisch_Hermitescher_Spline#Cardinal_Spline - if (p.size() < 2) - Standard_ConstructionError::Raise(); - if (p.size() != c.size()) - Standard_ConstructionError::Raise(); - - t.resize(p.size()); - if (p.size() == 2) { - t[0] = gp_Vec(p[0], p[1]); - t[1] = gp_Vec(p[0], p[1]); - } - else { - std::size_t e = p.size() - 1; - - for (std::size_t i = 1; i < e; i++) { - gp_Vec v = gp_Vec(p[i-1], p[i+1]); - double f = 0.5 * (1-c[i]); - v.Scale(f); - t[i] = v; - } - - t[0] = t[1]; - t[t.size()-1] = t[t.size()-2]; - } -} - -void GeomHermiteCurve::getCardinalSplineTangents(const std::vector& p, double c, - std::vector& t) const -{ - // https://de.wikipedia.org/wiki/Kubisch_Hermitescher_Spline#Cardinal_Spline - if (p.size() < 2) - Standard_ConstructionError::Raise(); - - t.resize(p.size()); - if (p.size() == 2) { - t[0] = gp_Vec(p[0], p[1]); - t[1] = gp_Vec(p[0], p[1]); - } - else { - std::size_t e = p.size() - 1; - double f = 0.5 * (1-c); - - for (std::size_t i = 1; i < e; i++) { - gp_Vec v = gp_Vec(p[i-1], p[i+1]); - v.Scale(f); - t[i] = v; - } - - t[0] = t[1]; - t[t.size()-1] = t[t.size()-2]; - } -} - -const Handle_Geom_Geometry& GeomHermiteCurve::handle() const -{ - return myCurve; -} - -void GeomHermiteCurve::compute(const std::vector& p, - const std::vector& t) -{ - double tol3d = Precision::Approximation(); - Handle_TColgp_HArray1OfPnt pts = new TColgp_HArray1OfPnt(1, p.size()); - for (std::size_t i=0; iSetValue(i+1, p[i]); - } - - TColgp_Array1OfVec tgs(1, t.size()); - Handle_TColStd_HArray1OfBoolean fgs = new TColStd_HArray1OfBoolean(1, t.size()); - for (std::size_t i=0; iSetValue(i+1, Standard_True); - } - - GeomAPI_Interpolate interpolate(pts, Standard_False, tol3d); - interpolate.Load(tgs, fgs); - interpolate.Perform(); - this->myCurve = interpolate.Curve(); - - this->poles = p; - this->tangents = t; -} - -Geometry *GeomHermiteCurve::clone(void) const -{ - GeomHermiteCurve *newCurve = new GeomHermiteCurve(poles, tangents); - newCurve->Construction = this->Construction; - return newCurve; -} - -// Persistence implementer -unsigned int GeomHermiteCurve::getMemSize (void) const {assert(0); return 0;/* not implemented yet */} -void GeomHermiteCurve::Save (Base::Writer &/*writer*/) const {assert(0); /* not implemented yet */} -void GeomHermiteCurve::Restore (Base::XMLReader &/*reader*/) {assert(0); /* not implemented yet */} - -PyObject *GeomHermiteCurve::getPyObject(void) -{ - return new HermiteCurvePy(static_cast(this->clone())); -} - -// ------------------------------------------------- - TYPESYSTEM_SOURCE(Part::GeomBSplineCurve,Part::GeomCurve); GeomBSplineCurve::GeomBSplineCurve() @@ -703,6 +560,90 @@ bool GeomBSplineCurve::join(const Handle_Geom_BSplineCurve& spline) return true; } +void GeomBSplineCurve::interpolate(const std::vector& p, + const std::vector& t) +{ + if (p.size() < 2) + Standard_ConstructionError::Raise(); + if (p.size() != t.size()) + Standard_ConstructionError::Raise(); + + double tol3d = Precision::Approximation(); + Handle_TColgp_HArray1OfPnt pts = new TColgp_HArray1OfPnt(1, p.size()); + for (std::size_t i=0; iSetValue(i+1, p[i]); + } + + TColgp_Array1OfVec tgs(1, t.size()); + Handle_TColStd_HArray1OfBoolean fgs = new TColStd_HArray1OfBoolean(1, t.size()); + for (std::size_t i=0; iSetValue(i+1, Standard_True); + } + + GeomAPI_Interpolate interpolate(pts, Standard_False, tol3d); + interpolate.Load(tgs, fgs); + interpolate.Perform(); + this->myCurve = interpolate.Curve(); +} + +void GeomBSplineCurve::getCardinalSplineTangents(const std::vector& p, + const std::vector& c, + std::vector& t) const +{ + // https://de.wikipedia.org/wiki/Kubisch_Hermitescher_Spline#Cardinal_Spline + if (p.size() < 2) + Standard_ConstructionError::Raise(); + if (p.size() != c.size()) + Standard_ConstructionError::Raise(); + + t.resize(p.size()); + if (p.size() == 2) { + t[0] = gp_Vec(p[0], p[1]); + t[1] = gp_Vec(p[0], p[1]); + } + else { + std::size_t e = p.size() - 1; + + for (std::size_t i = 1; i < e; i++) { + gp_Vec v = gp_Vec(p[i-1], p[i+1]); + double f = 0.5 * (1-c[i]); + v.Scale(f); + t[i] = v; + } + + t[0] = t[1]; + t[t.size()-1] = t[t.size()-2]; + } +} + +void GeomBSplineCurve::getCardinalSplineTangents(const std::vector& p, double c, + std::vector& t) const +{ + // https://de.wikipedia.org/wiki/Kubisch_Hermitescher_Spline#Cardinal_Spline + if (p.size() < 2) + Standard_ConstructionError::Raise(); + + t.resize(p.size()); + if (p.size() == 2) { + t[0] = gp_Vec(p[0], p[1]); + t[1] = gp_Vec(p[0], p[1]); + } + else { + std::size_t e = p.size() - 1; + double f = 0.5 * (1-c); + + for (std::size_t i = 1; i < e; i++) { + gp_Vec v = gp_Vec(p[i-1], p[i+1]); + v.Scale(f); + t[i] = v; + } + + t[0] = t[1]; + t[t.size()-1] = t[t.size()-2]; + } +} + void GeomBSplineCurve::makeC1Continuous(double tol, double ang_tol) { GeomConvert::C0BSplineToC1BSplineCurve(this->myCurve, tol, ang_tol); diff --git a/src/Mod/Part/App/Geometry.h b/src/Mod/Part/App/Geometry.h index 464cfa41e..0453316ca 100644 --- a/src/Mod/Part/App/Geometry.h +++ b/src/Mod/Part/App/Geometry.h @@ -153,20 +153,15 @@ private: Handle_Geom_BezierCurve myCurve; }; -/*! - * \brief The GeomHermiteCurve class - * The GeomHermiteCurve describes a cubic Hermite spline. - * @note Since OpenCascade doesn't directly support Hermite splines - * the returned curve will be a B-Spline curve. - */ -class PartExport GeomHermiteCurve : public GeomCurve +class PartExport GeomBSplineCurve : public GeomCurve { TYPESYSTEM_HEADER(); public: - GeomHermiteCurve(); - GeomHermiteCurve(const std::vector&, const std::vector&); - virtual ~GeomHermiteCurve(); + GeomBSplineCurve(); + GeomBSplineCurve(const Handle_Geom_BSplineCurve&); + virtual ~GeomBSplineCurve(); virtual Geometry *clone(void) const; + /*! * Set the poles and tangents for the cubic Hermite spline */ @@ -186,33 +181,6 @@ public: void getCardinalSplineTangents(const std::vector&, double, std::vector&) const; - // Persistence implementer --------------------- - virtual unsigned int getMemSize (void) const; - virtual void Save (Base::Writer &/*writer*/) const; - virtual void Restore(Base::XMLReader &/*reader*/); - // Base implementer ---------------------------- - virtual PyObject *getPyObject(void); - - const Handle_Geom_Geometry& handle() const; - -private: - void compute(const std::vector&, const std::vector&); - -private: - Handle_Geom_BSplineCurve myCurve; - std::vector poles; - std::vector tangents; -}; - -class PartExport GeomBSplineCurve : public GeomCurve -{ - TYPESYSTEM_HEADER(); -public: - GeomBSplineCurve(); - GeomBSplineCurve(const Handle_Geom_BSplineCurve&); - virtual ~GeomBSplineCurve(); - virtual Geometry *clone(void) const; - int countPoles() const; void setPole(int index, const Base::Vector3d&, double weight=-1); std::vector getPoles() const; diff --git a/src/Mod/Part/App/HermiteCurvePy.xml b/src/Mod/Part/App/HermiteCurvePy.xml deleted file mode 100644 index b35270dac..000000000 --- a/src/Mod/Part/App/HermiteCurvePy.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - Describes a Hermite curve - - - - - Set the poles and tangents to compute the Hermite curve. - - - - - Compute the tangents for a Cardinal spline - - - - diff --git a/src/Mod/Part/App/HermiteCurvePyImp.cpp b/src/Mod/Part/App/HermiteCurvePyImp.cpp deleted file mode 100644 index b87826fc2..000000000 --- a/src/Mod/Part/App/HermiteCurvePyImp.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2016 Werner Mayer * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#include "PreCompiled.h" - -#include "Geometry.h" -#include - -#include -#include -#include - -using namespace Part; - -// returns a string which represents the object e.g. when printed in python -std::string HermiteCurvePy::representation(void) const -{ - return std::string(""); -} - -PyObject *HermiteCurvePy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper -{ - // create a new instance of HermiteCurvePy and the Twin object - return new HermiteCurvePy(new GeomHermiteCurve); -} - -// constructor method -int HermiteCurvePy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/) -{ - return 0; -} - -PyObject* HermiteCurvePy::interpolate(PyObject *args, PyObject *kwds) -{ - PyObject* pts; - PyObject* tgs; - - static char* kwds_interp1[] = {"Points", "Tangents", NULL}; - if (PyArg_ParseTupleAndKeywords(args, kwds, "OO",kwds_interp1, &pts, &tgs)) { - Py::Sequence list(pts); - std::vector interpPoints; - interpPoints.reserve(list.size()); - for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { - Py::Vector v(*it); - Base::Vector3d pnt = v.toVector(); - interpPoints.push_back(gp_Pnt(pnt.x,pnt.y,pnt.z)); - } - Py::Sequence list2(tgs); - std::vector interpTangents; - interpTangents.reserve(list2.size()); - for (Py::Sequence::iterator it = list2.begin(); it != list2.end(); ++it) { - Py::Vector v(*it); - Base::Vector3d vec = v.toVector(); - interpTangents.push_back(gp_Vec(vec.x,vec.y,vec.z)); - } - - GeomHermiteCurve* hermite = this->getGeomHermiteCurvePtr(); - hermite->interpolate(interpPoints, interpTangents); - Handle_Geom_BSplineCurve aBSpline = Handle_Geom_BSplineCurve::DownCast - (hermite->handle()); - return new BSplineCurvePy(new GeomBSplineCurve(aBSpline)); - } - - return 0; -} - -PyObject* HermiteCurvePy::getCardinalSplineTangents(PyObject *args, PyObject *kwds) -{ - PyObject* pts; - PyObject* tgs; - double parameter; - - static char* kwds_interp1[] = {"Points", "Parameter", NULL}; - if (PyArg_ParseTupleAndKeywords(args, kwds, "Od",kwds_interp1, &pts, ¶meter)) { - Py::Sequence list(pts); - std::vector interpPoints; - interpPoints.reserve(list.size()); - for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { - Py::Vector v(*it); - Base::Vector3d pnt = v.toVector(); - interpPoints.push_back(gp_Pnt(pnt.x,pnt.y,pnt.z)); - } - - GeomHermiteCurve* hermite = this->getGeomHermiteCurvePtr(); - std::vector tangents; - hermite->getCardinalSplineTangents(interpPoints, parameter, tangents); - - Py::List vec; - for (gp_Vec it : tangents) - vec.append(Py::Vector(Base::Vector3d(it.X(), it.Y(), it.Z()))); - return Py::new_reference_to(vec); - } - - PyErr_Clear(); - static char* kwds_interp2[] = {"Points", "Parameters", NULL}; - if (PyArg_ParseTupleAndKeywords(args, kwds, "OO",kwds_interp2, &pts, &tgs)) { - Py::Sequence list(pts); - std::vector interpPoints; - interpPoints.reserve(list.size()); - for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { - Py::Vector v(*it); - Base::Vector3d pnt = v.toVector(); - interpPoints.push_back(gp_Pnt(pnt.x,pnt.y,pnt.z)); - } - - Py::Sequence list2(tgs); - std::vector parameters; - parameters.reserve(list2.size()); - for (Py::Sequence::iterator it = list2.begin(); it != list2.end(); ++it) { - Py::Float p(*it); - parameters.push_back(static_cast(p)); - } - - GeomHermiteCurve* hermite = this->getGeomHermiteCurvePtr(); - std::vector tangents; - hermite->getCardinalSplineTangents(interpPoints, parameters, tangents); - - Py::List vec; - for (gp_Vec it : tangents) - vec.append(Py::Vector(Base::Vector3d(it.X(), it.Y(), it.Z()))); - return Py::new_reference_to(vec); - } - - return 0; -} - -PyObject *HermiteCurvePy::getCustomAttributes(const char* /*attr*/) const -{ - return 0; -} - -int HermiteCurvePy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) -{ - return 0; -}