From b277620138eea91353850993e717021a9559df2c Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Wed, 4 Jan 2017 23:47:15 +0100 Subject: [PATCH] Part: GeomBSpline extension for basic BSPline Sketcher support ============================================================== 1) Basic set/get interface for poles, weights, knots and multiplicities 2) Introduction of GeomBoundedCurve class replicating OCC hierarchy. Why? To provide seamless start/end point interface for any bounded curve, i.e. Bezier, BSpline, Note: The ArcOfConic start/end point interface relies on GeomTrimmedCurve, and introduces CCW/CW correcting code which relies on Axis. Axis are introduced in GeomConic and are not part of GeomBounded. Note 2: In the future, it may be thought to make GeomArcOfConic (the equivalent of GeomTrimmedCurve) deriving from GeomBoundedCurve, as to fully replicate OCC hierarchy. GeomBoundedCurve defines the functions as virtual to allow seamless integration. --- src/Mod/Part/App/AppPart.cpp | 1 + src/Mod/Part/App/Geometry.cpp | 155 +++++++++++++++++++++++++++++++++- src/Mod/Part/App/Geometry.h | 27 +++++- 3 files changed, 179 insertions(+), 4 deletions(-) diff --git a/src/Mod/Part/App/AppPart.cpp b/src/Mod/Part/App/AppPart.cpp index bc4c86d7b..fa8392328 100644 --- a/src/Mod/Part/App/AppPart.cpp +++ b/src/Mod/Part/App/AppPart.cpp @@ -460,6 +460,7 @@ PyMODINIT_FUNC initPart() Part::Geometry ::init(); Part::GeomPoint ::init(); Part::GeomCurve ::init(); + Part::GeomBoundedCurve ::init(); Part::GeomBezierCurve ::init(); Part::GeomBSplineCurve ::init(); Part::GeomConic ::init(); diff --git a/src/Mod/Part/App/Geometry.cpp b/src/Mod/Part/App/Geometry.cpp index 71d8843fb..ffa57ec42 100644 --- a/src/Mod/Part/App/Geometry.cpp +++ b/src/Mod/Part/App/Geometry.cpp @@ -421,10 +421,37 @@ bool GeomCurve::closestParameterToBasicCurve(const Base::Vector3d& point, double } } +// ------------------------------------------------- +TYPESYSTEM_SOURCE_ABSTRACT(Part::GeomBoundedCurve, Part::GeomCurve) + +GeomBoundedCurve::GeomBoundedCurve() +{ +} + +GeomBoundedCurve::~GeomBoundedCurve() +{ +} + +Base::Vector3d GeomBoundedCurve::getStartPoint() const +{ + Handle_Geom_BoundedCurve curve = Handle_Geom_BoundedCurve::DownCast(handle()); + gp_Pnt pnt = curve->StartPoint(); + + return Base::Vector3d(pnt.X(), pnt.Y(), pnt.Z()); +} + +Base::Vector3d GeomBoundedCurve::getEndPoint() const +{ + Handle_Geom_BoundedCurve curve = Handle_Geom_BoundedCurve::DownCast(handle()); + gp_Pnt pnt = curve->EndPoint(); + + return Base::Vector3d(pnt.X(), pnt.Y(), pnt.Z()); +} + // ------------------------------------------------- -TYPESYSTEM_SOURCE(Part::GeomBezierCurve,Part::GeomCurve) +TYPESYSTEM_SOURCE(Part::GeomBezierCurve,Part::GeomBoundedCurve) GeomBezierCurve::GeomBezierCurve() { @@ -473,7 +500,7 @@ PyObject *GeomBezierCurve::getPyObject(void) // ------------------------------------------------- -TYPESYSTEM_SOURCE(Part::GeomBSplineCurve,Part::GeomCurve) +TYPESYSTEM_SOURCE(Part::GeomBSplineCurve,Part::GeomBoundedCurve) GeomBSplineCurve::GeomBSplineCurve() { @@ -538,6 +565,27 @@ void GeomBSplineCurve::setPole(int index, const Base::Vector3d& pole, double wei } } +void GeomBSplineCurve::setPoles(const std::vector& poles, const std::vector& weights) +{ + Standard_Integer index=0; + + std::vector::const_iterator it1; + std::vector::const_iterator it2; + + for(it1 = poles.begin(), it2 = weights.begin(); it1 != poles.end() && it2 != weights.end(); ++it1, ++it2, index++){ + setPole(index, (*it1), (*it2) ); + } +} + +void GeomBSplineCurve::setPoles(const std::vector& poles) +{ + Standard_Integer index=0; + + for(std::vector::const_iterator it1 = poles.begin(); it1 != poles.end(); ++it1, index++){ + setPole(index, (*it1)); + } +} + std::vector GeomBSplineCurve::getPoles() const { std::vector poles; @@ -552,6 +600,109 @@ std::vector GeomBSplineCurve::getPoles() const return poles; } +std::vector GeomBSplineCurve::getWeights() const +{ + std::vector weights; + weights.reserve(myCurve->NbPoles()); + TColStd_Array1OfReal w(1,myCurve->NbPoles()); + myCurve->Weights(w); + + for (Standard_Integer i=w.Lower(); i<=w.Upper(); i++) { + const Standard_Real& real = w(i); + weights.push_back(real); + } + return weights; +} + + +void GeomBSplineCurve::setWeights(const std::vector& weights) +{ + try { + Standard_Integer index=0; + + for(std::vector::const_iterator it = weights.begin(); it != weights.end(); ++it, index++){ + myCurve->SetWeight(index,(*it)); + } + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + std::cout << e->GetMessageString() << std::endl; + } +} + +void GeomBSplineCurve::setKnot(int index, const double val, int mult) +{ + try { + if (mult < 0) + myCurve->SetKnot(index+1, val); + else + myCurve->SetKnot(index+1, val, mult); + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + std::cout << e->GetMessageString() << std::endl; + } +} + +void GeomBSplineCurve::setKnots(const std::vector& knots) +{ + Standard_Integer index=0; + + for(std::vector::const_iterator it1 = knots.begin(); it1 != knots.end(); ++it1, index++){ + setKnot(index, (*it1)); + } +} + +void GeomBSplineCurve::setKnots(const std::vector& knots, const std::vector multiplicities) +{ + Standard_Integer index=0; + + std::vector::const_iterator it1; + std::vector::const_iterator it2; + + for(it1 = knots.begin(), it2 = multiplicities.begin(); it1 != knots.end() && it2 != multiplicities.end(); ++it1, ++it2, index++){ + setKnot(index, (*it1), (*it2) ); + } +} + +std::vector GeomBSplineCurve::getKnots() const +{ + std::vector knots; + knots.reserve(myCurve->NbKnots()); + TColStd_Array1OfReal k(1,myCurve->NbKnots()); + myCurve->Knots(k); + + for (Standard_Integer i=k.Lower(); i<=k.Upper(); i++) { + const Standard_Real& real = k(i); + knots.push_back(real); + } + return knots; +} + +std::vector GeomBSplineCurve::getMultiplicities() const +{ + std::vector mults; + mults.reserve(myCurve->NbKnots()); + TColStd_Array1OfInteger m(1,myCurve->NbKnots()); + myCurve->Multiplicities(m); + + for (Standard_Integer i=m.Lower(); i<=m.Upper(); i++) { + const Standard_Integer& nm = m(i); + mults.push_back(nm); + } + return mults; +} + +int GeomBSplineCurve::getDegree() const +{ + return myCurve->Degree(); +} + +bool GeomBSplineCurve::IsPeriodic() const +{ + return myCurve->IsPeriodic()==Standard_True; +} + bool GeomBSplineCurve::join(const Handle_Geom_BSplineCurve& spline) { GeomConvert_CompCurveToBSplineCurve ccbc(this->myCurve); diff --git a/src/Mod/Part/App/Geometry.h b/src/Mod/Part/App/Geometry.h index 391b1e783..b650ecc01 100644 --- a/src/Mod/Part/App/Geometry.h +++ b/src/Mod/Part/App/Geometry.h @@ -130,7 +130,19 @@ public: bool closestParameterToBasicCurve(const Base::Vector3d& point, double &u) const; }; -class PartExport GeomBezierCurve : public GeomCurve +class PartExport GeomBoundedCurve : public GeomCurve +{ + TYPESYSTEM_HEADER(); +public: + GeomBoundedCurve(); + virtual ~GeomBoundedCurve(); + + // Geometry helper + virtual Base::Vector3d getStartPoint() const; + virtual Base::Vector3d getEndPoint() const; +}; + +class PartExport GeomBezierCurve : public GeomBoundedCurve { TYPESYSTEM_HEADER(); public: @@ -153,7 +165,7 @@ private: Handle_Geom_BezierCurve myCurve; }; -class PartExport GeomBSplineCurve : public GeomCurve +class PartExport GeomBSplineCurve : public GeomBoundedCurve { TYPESYSTEM_HEADER(); public: @@ -183,7 +195,18 @@ public: int countPoles() const; void setPole(int index, const Base::Vector3d&, double weight=-1); + void setPoles(const std::vector& poles, const std::vector& weights); + void setPoles(const std::vector& poles); + void setWeights(const std::vector& weights); + void setKnot(int index, const double val, int mult=-1); + void setKnots(const std::vector& knots); + void setKnots(const std::vector& knots, const std::vector multiplicities); std::vector getPoles() const; + std::vector getWeights() const; + std::vector getKnots() const; + std::vector getMultiplicities() const; + int getDegree() const; + bool IsPeriodic() const; bool join(const Handle_Geom_BSplineCurve&); void makeC1Continuous(double, double); std::list toBiArcs(double tolerance) const;