From c8e241c9f3200818c0f03ac5a7eb7e43e54813bf Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 19 Nov 2015 18:52:19 +0100 Subject: [PATCH] + PLate surface approximation --- src/Mod/Part/App/AppPartPy.cpp | 3 - src/Mod/Part/App/Geometry.cpp | 4 +- src/Mod/Part/App/Tools.cpp | 107 +++++++++++++++++++++++++++++++++ src/Mod/Part/App/Tools.h | 13 ++++ 4 files changed, 122 insertions(+), 5 deletions(-) diff --git a/src/Mod/Part/App/AppPartPy.cpp b/src/Mod/Part/App/AppPartPy.cpp index 3efbeb004..7d6b5e95c 100644 --- a/src/Mod/Part/App/AppPartPy.cpp +++ b/src/Mod/Part/App/AppPartPy.cpp @@ -445,9 +445,6 @@ makeCompound(PyObject *self, PyObject *args) static PyObject * makeFilledFace(PyObject *self, PyObject *args) { - // http://opencascade.blogspot.com/2010/03/surface-modeling-part6.html - // TODO: GeomPlate_BuildPlateSurface - // TODO: GeomPlate_MakeApprox // TODO: BRepFeat_SplitShape PyObject *obj; PyObject *surf=0; diff --git a/src/Mod/Part/App/Geometry.cpp b/src/Mod/Part/App/Geometry.cpp index dbdcbcac2..3403698e9 100644 --- a/src/Mod/Part/App/Geometry.cpp +++ b/src/Mod/Part/App/Geometry.cpp @@ -112,6 +112,7 @@ #include "ConePy.h" #include "CylinderPy.h" #include "OffsetSurfacePy.h" +#include "PlateSurfacePy.h" #include "PlanePy.h" #include "RectangularTrimmedSurfacePy.h" #include "SpherePy.h" @@ -3328,8 +3329,7 @@ void GeomPlateSurface::Restore(Base::XMLReader &/*reader*/) PyObject *GeomPlateSurface::getPyObject(void) { - throw Base::NotImplementedError("GeomPlateSurface::getPyObject"); -// return new PlateSurfacePy(static_cast(this->clone())); + return new PlateSurfacePy(static_cast(this->clone())); } // ------------------------------------------------- diff --git a/src/Mod/Part/App/Tools.cpp b/src/Mod/Part/App/Tools.cpp index f16d6f795..bd36bae4d 100644 --- a/src/Mod/Part/App/Tools.cpp +++ b/src/Mod/Part/App/Tools.cpp @@ -22,12 +22,27 @@ #include "PreCompiled.h" #ifndef _PreComp_ +# include # include # include +# include # include +# include # include # include +# include +# include +# include +# include +# include +# include # include +# include +# include +# include +# include +# include +# include #endif #include @@ -81,3 +96,95 @@ bool Part::intersect(const gp_Pln& pln1, const gp_Pln& pln2, gp_Lin& lin) return found; } + +/*! The objects in \a theBoundaries must be of the type Adaptor3d_HCurveOnSurface or +GeomAdaptor_HCurve or Geom_Point indicating type of a constraint. Otherwise an exception +Standard_TypeMismatch is thrown. + +If the \a theBoundaries list is empty then Standard_ConstructionError is thrown. + +If the algorithm fails it returns a null surface. +\see http://opencascade.blogspot.com/2010/03/surface-modeling-part6.html +*/ +Handle_Geom_Surface +Part::Tools::makeSurface(const TColStd_ListOfTransient &theBoundaries, + const Standard_Real theTol, + const Standard_Integer theNbPnts, + const Standard_Integer theNbIter, + const Standard_Integer theMaxDeg) +{ + //constants for algorithm + const Standard_Integer aNbIter = theNbIter; //number of algorithm iterations + const Standard_Integer aNbPnts = theNbPnts; //sample points per each constraint + const Standard_Integer aDeg = 3; //requested surface degree ? + const Standard_Integer aMaxDeg = theMaxDeg; + const Standard_Integer aMaxSeg = 10000; + const Standard_Real aTol3d = 1.e-04; + const Standard_Real aTol2d = 1.e-05; + const Standard_Real anAngTol = 1.e-02; //angular + const Standard_Real aCurvTol = 1.e-01; //curvature + + Handle(Geom_Surface) aRes; + GeomPlate_BuildPlateSurface aPlateBuilder (aDeg, aNbPnts, aNbIter, aTol2d, aTol3d, anAngTol, aCurvTol); + + TColStd_ListIteratorOfListOfTransient anIt (theBoundaries); + if (anIt.More()) { + int i = 1; + for (; anIt.More(); anIt.Next(), i++) { + const Handle(Standard_Transient)& aCur = anIt.Value(); + if (aCur.IsNull()) { + assert (0); + Standard_ConstructionError::Raise ("Tools::makeSurface()"); + } + else if (aCur->IsKind (STANDARD_TYPE (Adaptor3d_HCurveOnSurface))) { + //G1 constraint + const Handle(Adaptor3d_HCurveOnSurface)& aHCOS = Handle(Adaptor3d_HCurveOnSurface)::DownCast (aCur); + Handle (GeomPlate_CurveConstraint) aConst = new GeomPlate_CurveConstraint (aHCOS, 1 /*GeomAbs_G1*/,aNbPnts, aTol3d, anAngTol, aCurvTol); + aPlateBuilder.Add (aConst); + } + else if (aCur->IsKind (STANDARD_TYPE (GeomAdaptor_HCurve))) { + //G0 constraint + const Handle(GeomAdaptor_HCurve)& aHC = Handle(GeomAdaptor_HCurve)::DownCast (aCur); + Handle (GeomPlate_CurveConstraint) aConst = new GeomPlate_CurveConstraint (aHC, 0 /*GeomAbs_G0*/, aNbPnts, aTol3d); + aPlateBuilder.Add (aConst); + } + else if (aCur->IsKind (STANDARD_TYPE (Geom_Point))) { + //Point constraint + const Handle(Geom_Point)& aGP = Handle(Geom_Point)::DownCast (aCur); + Handle(GeomPlate_PointConstraint) aConst = new GeomPlate_PointConstraint(aGP->Pnt(),0); + aPlateBuilder.Add(aConst); + } + else { + Standard_TypeMismatch::Raise ("Tools::makeSurface()"); + } + } + } + else { + Standard_ConstructionError::Raise ("Tools::makeSurface()"); + } + + //construct + aPlateBuilder.Perform(); + + if (!aPlateBuilder.IsDone()) { + return aRes; + } + + const Handle(GeomPlate_Surface)& aPlate = aPlateBuilder.Surface(); + //approximation (see BRepFill_Filling - when no initial surface was given) + Standard_Real aDMax = aPlateBuilder.G0Error(); + TColgp_SequenceOfXY aS2d; + TColgp_SequenceOfXYZ aS3d; + aPlateBuilder.Disc2dContour (4, aS2d); + aPlateBuilder.Disc3dContour (4, 0, aS3d); + Standard_Real aMax = Max (aTol3d, 10. * aDMax); + GeomPlate_PlateG0Criterion aCriterion (aS2d, aS3d, aMax); + { + //data races in AdvApp2Var used by GeomApprox_Surface, use global mutex + //Standard_Mutex::Sentry aSentry (theBSMutex); + GeomPlate_MakeApprox aMakeApprox (aPlate, aCriterion, aTol3d, aMaxSeg, aMaxDeg); + aRes = aMakeApprox.Surface(); + } + + return aRes; +} diff --git a/src/Mod/Part/App/Tools.h b/src/Mod/Part/App/Tools.h index 16bfc4dc6..55c9b4f52 100644 --- a/src/Mod/Part/App/Tools.h +++ b/src/Mod/Part/App/Tools.h @@ -28,9 +28,11 @@ #include #include #include +#include class gp_Lin; class gp_Pln; +class TColStd_ListOfTransient; namespace Base { // Specialization for gp_Pnt @@ -93,6 +95,17 @@ bool intersect(const gp_Pln& pln1, const gp_Pln& pln2, gp_Lin& lin); PartExport bool tangentialArc(const gp_Pnt& p0, const gp_Vec& v0, const gp_Pnt& p1, gp_Pnt& c, gp_Dir& a); +class PartExport Tools +{ +public: + Handle_Geom_Surface makeSurface (const TColStd_ListOfTransient& theBoundaries, + const Standard_Real theTol, + const Standard_Integer theNbPnts, + const Standard_Integer theNbIter, + const Standard_Integer theMaxDeg); + +}; + } //namespace Part