From 7328f2f3023ba4afd3e9db6036dfab84261c9d67 Mon Sep 17 00:00:00 2001 From: tomate44 Date: Tue, 26 Jul 2022 11:05:56 +0200 Subject: [PATCH] [Part] BSplineSurface: add setBounds method --- src/Mod/Part/App/BSplineSurfacePy.xml | 10 +++++++ src/Mod/Part/App/BSplineSurfacePyImp.cpp | 26 ++++++++++++++++++ src/Mod/Part/App/Geometry.cpp | 35 ++++++++++++++++++++++++ src/Mod/Part/App/Geometry.h | 1 + 4 files changed, 72 insertions(+) diff --git a/src/Mod/Part/App/BSplineSurfacePy.xml b/src/Mod/Part/App/BSplineSurfacePy.xml index b53cbecb4c..8c6352ae7c 100644 --- a/src/Mod/Part/App/BSplineSurfacePy.xml +++ b/src/Mod/Part/App/BSplineSurfacePy.xml @@ -729,5 +729,15 @@ + + + + Changes the U and V parametric bounds of the surface. + The geometry is not modified. + bspline_surf.setBounds(u0, u1, v0, v1) + Default arguments are 0.0, 1.0, 0.0, 1.0 + + + diff --git a/src/Mod/Part/App/BSplineSurfacePyImp.cpp b/src/Mod/Part/App/BSplineSurfacePyImp.cpp index 7e7f593a6a..73f92dd409 100644 --- a/src/Mod/Part/App/BSplineSurfacePyImp.cpp +++ b/src/Mod/Part/App/BSplineSurfacePyImp.cpp @@ -1680,6 +1680,32 @@ Py::List BSplineSurfacePy::getVKnotSequence(void) const return list; } +PyObject* BSplineSurfacePy::setBounds(PyObject *args) +{ + double u0=0.0; + double u1=1.0; + double v0=0.0; + double v1=1.0; + + if (!PyArg_ParseTuple(args, "|dddd", &u0, &u1, &v0, &v1)) + return nullptr; + try { + if (u0 >= u1 || v0 >= v1) { + Standard_Failure::Raise("Bad parameter range"); + return nullptr;; + } + GeomBSplineSurface* surf = getGeomBSplineSurfacePtr(); + surf->setBounds(u0, u1, v0, v1); + Py_Return; + } + catch (Standard_Failure& e) { + std::string err = e.GetMessageString(); + if (err.empty()) err = e.DynamicType()->Name(); + PyErr_SetString(PartExceptionOCCError, err.c_str()); + return nullptr; + } +} + PyObject *BSplineSurfacePy::getCustomAttributes(const char* /*attr*/) const { return nullptr; diff --git a/src/Mod/Part/App/Geometry.cpp b/src/Mod/Part/App/Geometry.cpp index 6e348aec08..63524e2c43 100644 --- a/src/Mod/Part/App/Geometry.cpp +++ b/src/Mod/Part/App/Geometry.cpp @@ -4458,6 +4458,41 @@ Geometry *GeomBSplineSurface::copy(void) const return newSurf; } +void GeomBSplineSurface::setBounds(double u0, double u1, double v0, double v1) +{ + try { + Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast(mySurface->Copy()); + Standard_RangeError_Raise_if (u1 <= u0 || v1 <= v0, " "); + Standard_Real bu0,bu1,bv0,bv1; + surf->Bounds(bu0,bu1,bv0,bv1); + if ((abs(u0-bu0) > Precision::Confusion()) || (abs(u1-bu1) > Precision::Confusion())) { + TColStd_Array1OfReal uk(1,surf->NbUKnots()); + TColStd_Array1OfReal nuk(1,surf->NbUKnots()); + surf->UKnots(uk); + Standard_Real ur = uk(uk.Upper()) - uk(uk.Lower()); + for (Standard_Integer i=uk.Lower(); i<=uk.Upper(); i++) { + nuk(i) = u0 + ((u1 - u0) * (uk(i) - uk(uk.Lower())) / ur); + } + surf->SetUKnots(nuk); + } + if ((abs(v0-bv0) > Precision::Confusion()) || (abs(v1-bv1) > Precision::Confusion())) { + TColStd_Array1OfReal vk(1,surf->NbVKnots()); + TColStd_Array1OfReal nvk(1,surf->NbVKnots()); + surf->VKnots(vk); + Standard_Real vr = vk(vk.Upper()) - vk(vk.Lower()); + for (Standard_Integer j=vk.Lower(); j<=vk.Upper(); j++) { + nvk(j) = v0 + ((v1 - v0) * (vk(j) - vk(vk.Lower())) / vr); + } + surf->SetVKnots(nvk); + } + mySurface = surf; + return; + } + catch (Standard_Failure& e) { + THROWM(Base::CADKernelError,e.GetMessageString()) + } +} + // Persistence implementer unsigned int GeomBSplineSurface::getMemSize (void) const { diff --git a/src/Mod/Part/App/Geometry.h b/src/Mod/Part/App/Geometry.h index b13626772f..b596ace45a 100644 --- a/src/Mod/Part/App/Geometry.h +++ b/src/Mod/Part/App/Geometry.h @@ -844,6 +844,7 @@ public: virtual ~GeomBSplineSurface(); virtual Geometry *copy(void) const; + void setBounds(double u0, double u1, double v0, double v1); // Persistence implementer --------------------- virtual unsigned int getMemSize(void) const; virtual void Save(Base::Writer &/*writer*/) const;