From f998596a105f64f10e4f0b848efb8a8161d8ea52 Mon Sep 17 00:00:00 2001 From: ifv Date: Tue, 11 Jul 2017 10:15:28 +0300 Subject: [PATCH] 0028909: Algorithm of BO is stuck while fusing shell and edges Approximation parameters: degmin, degmax, max number of segments, boundary condition, maximal distance of projecting are added in interface of classes ProjLib_ProjectedCurve, ProjLib_ComputeApprox, ProjLib_ComputeApproxOnPolarSurface Algorithm of Approx/Approx_ComputeCLine is modified in order to treat maximal number of segments allowed for cutting. Algorithm of method BOPTools_AlgoTools2D::MakePCurveOnFace(...) is modified in order to manage cases with big edge tolerances. Test case added Some test cases were modified according to new behavior of algorithms --- src/Approx/Approx_ComputeCLine.gxx | 26 +- src/Approx/Approx_FitAndDivide.hxx | 4 + src/Approx/Approx_FitAndDivide2d.hxx | 4 + src/BOPTools/BOPTools_AlgoTools2D.cxx | 53 +++- src/BRepFill/BRepFill_ComputeCLine.hxx | 5 +- src/ProjLib/ProjLib.cxx | 23 ++ src/ProjLib/ProjLib.hxx | 8 +- src/ProjLib/ProjLib_ComputeApprox.cxx | 123 ++++++-- src/ProjLib/ProjLib_ComputeApprox.hxx | 45 ++- .../ProjLib_ComputeApproxOnPolarSurface.cxx | 280 ++++++++++++------ .../ProjLib_ComputeApproxOnPolarSurface.hxx | 81 ++++- src/ProjLib/ProjLib_ProjectedCurve.cxx | 172 ++++++++++- src/ProjLib/ProjLib_ProjectedCurve.hxx | 54 +++- tests/bugs/modalg_6/bug26130 | 1 - tests/bugs/modalg_7/bug28909 | 23 ++ tests/de/step_4/D9 | 2 +- tests/de/step_4/E1 | 2 +- 17 files changed, 743 insertions(+), 163 deletions(-) create mode 100644 tests/bugs/modalg_7/bug28909 diff --git a/src/Approx/Approx_ComputeCLine.gxx b/src/Approx/Approx_ComputeCLine.gxx index f2fc63c460..9e21aad47b 100644 --- a/src/Approx/Approx_ComputeCLine.gxx +++ b/src/Approx/Approx_ComputeCLine.gxx @@ -50,6 +50,7 @@ Approx_ComputeCLine::Approx_ComputeCLine mycut = cutting; myfirstC = FirstC; mylastC = LastC; + myMaxSegments = IntegerLast(); alldone = Standard_False; Perform(Line); } @@ -76,6 +77,7 @@ Approx_ComputeCLine::Approx_ComputeCLine mycut = cutting; myfirstC = FirstC; mylastC = LastC; + myMaxSegments = IntegerLast(); } //======================================================================= @@ -91,9 +93,11 @@ void Approx_ComputeCLine::Perform(const MultiLine& Line) Standard_Real thetol3d = Precision::Confusion(), thetol2d = Precision::Confusion(); UFirst = Line.FirstParameter(); ULast = Line.LastParameter(); - Standard_Real TolU = (ULast-UFirst)*1.e-05; + Standard_Real TolU = Max((ULast-UFirst)*1.e-05, Precision::PApproximation()); Standard_Real myfirstU = UFirst; Standard_Real mylastU = ULast; + Standard_Integer aMaxSegments = 0; + Standard_Integer aMaxSegments1 = myMaxSegments - 1; if (!mycut) { @@ -126,7 +130,8 @@ void Approx_ComputeCLine::Perform(const MultiLine& Line) // Calcul de la partie a approximer. myfirstU = mylastU; mylastU = ULast; - if (Abs(ULast-myfirstU) <= RealEpsilon()) + if (Abs(ULast-myfirstU) <= RealEpsilon() + || aMaxSegments >= myMaxSegments) { Finish = Standard_True; alldone = Standard_True; @@ -155,11 +160,15 @@ void Approx_ComputeCLine::Perform(const MultiLine& Line) // Calcul des parametres sur ce nouvel intervalle. Ok = Compute(Line, myfirstU, mylastU, thetol3d, thetol2d); + if(Ok) + { + aMaxSegments++; + } //cout << myfirstU << " - " << mylastU << " tol : " << thetol3d << " " << thetol2d << endl; // is new decision better? - if (!Ok && Abs(myfirstU-mylastU) <= TolU) + if (!Ok && (Abs(myfirstU-mylastU) <= TolU || aMaxSegments >= aMaxSegments1)) { Ok = Standard_True; // stop interval cutting, approx the rest part @@ -176,6 +185,7 @@ void Approx_ComputeCLine::Perform(const MultiLine& Line) tolreached = Standard_False; // helas myMultiCurves.Append(KeptMultiCurve); + aMaxSegments++; Tolers3d.Append (KeptT3d); Tolers2d.Append (KeptT2d); myfirstparam.Append (KeptUfirst); @@ -303,6 +313,16 @@ void Approx_ComputeCLine::SetConstraints(const AppParCurves_Constraint FirstC, mylastC = LastC; } +//======================================================================= +//function : SetMaxSegments +//purpose : Changes the max number of segments, which is allowed for cutting. +//======================================================================= + +void Approx_ComputeCLine:: SetMaxSegments(const Standard_Integer theMaxSegments) +{ + myMaxSegments = theMaxSegments; +} + //======================================================================= //function : IsAllApproximated //purpose : returns False if at a moment of the approximation, diff --git a/src/Approx/Approx_FitAndDivide.hxx b/src/Approx/Approx_FitAndDivide.hxx index 81a55658b7..f33f83e243 100644 --- a/src/Approx/Approx_FitAndDivide.hxx +++ b/src/Approx/Approx_FitAndDivide.hxx @@ -60,6 +60,9 @@ public: //! Changes the constraints of the approximation. Standard_EXPORT void SetConstraints (const AppParCurves_Constraint FirstC, const AppParCurves_Constraint LastC); + + //! Changes the max number of segments, which is allowed for cutting. + Standard_EXPORT void SetMaxSegments (const Standard_Integer theMaxSegments); //! returns False if at a moment of the approximation, //! the status NoApproximation has been sent by the user @@ -114,6 +117,7 @@ private: Standard_Boolean mycut; AppParCurves_Constraint myfirstC; AppParCurves_Constraint mylastC; + Standard_Integer myMaxSegments; }; diff --git a/src/Approx/Approx_FitAndDivide2d.hxx b/src/Approx/Approx_FitAndDivide2d.hxx index 646f45aba3..829bd82fcb 100644 --- a/src/Approx/Approx_FitAndDivide2d.hxx +++ b/src/Approx/Approx_FitAndDivide2d.hxx @@ -60,6 +60,9 @@ public: //! Changes the constraints of the approximation. Standard_EXPORT void SetConstraints (const AppParCurves_Constraint FirstC, const AppParCurves_Constraint LastC); + + //! Changes the max number of segments, which is allowed for cutting. + Standard_EXPORT void SetMaxSegments (const Standard_Integer theMaxSegments); //! returns False if at a moment of the approximation, //! the status NoApproximation has been sent by the user @@ -114,6 +117,7 @@ private: Standard_Boolean mycut; AppParCurves_Constraint myfirstC; AppParCurves_Constraint mylastC; + Standard_Integer myMaxSegments; }; diff --git a/src/BOPTools/BOPTools_AlgoTools2D.cxx b/src/BOPTools/BOPTools_AlgoTools2D.cxx index 9697b92f56..20efb35b5c 100644 --- a/src/BOPTools/BOPTools_AlgoTools2D.cxx +++ b/src/BOPTools/BOPTools_AlgoTools2D.cxx @@ -629,11 +629,13 @@ void BOPTools_AlgoTools2D::MakePCurveOnFace Handle(GeomAdaptor_HCurve) aBAHC = new GeomAdaptor_HCurve(aC3D, aT1, aT2); // Standard_Real aTolR; + Standard_Real aTR = Precision::Confusion();//1.e-7; + Standard_Real aMaxTol = 1.e3 * aTR; //0.0001 + Standard_Boolean isAnaSurf = ProjLib::IsAnaSurf(aBAHS); + //when the type of surface is GeomAbs_SurfaceOfRevolution - if (pBAS->GetType() == GeomAbs_SurfaceOfRevolution) { - Standard_Real aTR; - // - aTR=Precision::Confusion();//1.e-7; + if (pBAS->GetType() == GeomAbs_SurfaceOfRevolution) + { if (TolReached2d > aTR) { aTR=TolReached2d; } @@ -642,23 +644,44 @@ void BOPTools_AlgoTools2D::MakePCurveOnFace ProjLib::MakePCurveOfType(aProj1, aC2D); aTolR = aProj1.GetTolerance(); } - else { - ProjLib_ProjectedCurve aProjCurv(aBAHS, aBAHC);// 1 + else + { + ProjLib_ProjectedCurve aProjCurv(aBAHS); + Standard_Integer aDegMin = -1, aDegMax = -1, aMaxSegments = -1; + Standard_Real aMaxDist = -1; + AppParCurves_Constraint aBndPnt = AppParCurves_TangencyPoint; + if ((TolReached2d >= 10. * aTR) && (TolReached2d <= aMaxTol || isAnaSurf)) + { + aTR = Min(aMaxTol, 0.1*TolReached2d); + aMaxSegments = 100; + aMaxDist = 1.e3*TolReached2d; + if(!isAnaSurf) + { + aBndPnt = AppParCurves_PassPoint; + } + } + else if(TolReached2d > aMaxTol) + { + aTR = Min(TolReached2d, 1.e3 * aMaxTol); + aMaxDist = 1.e2 * aTR; + aMaxSegments = 100; + } + aProjCurv.Load(aTR); + aProjCurv.SetDegree(aDegMin, aDegMax); + aProjCurv.SetMaxSegments(aMaxSegments); + aProjCurv.SetBndPnt(aBndPnt); + aProjCurv.SetMaxDist(aMaxDist); + aProjCurv.Perform(aBAHC); ProjLib::MakePCurveOfType(aProjCurv, aC2D); aTolR=aProjCurv.GetTolerance(); } // - if (aC2D.IsNull()) { - ProjLib_ProjectedCurve aProjCurvAgain(aBAHS, aBAHC, TolReached2d);// 2 + if (aC2D.IsNull() && (aTR < aMaxTol || aTR < TolReached2d)) + { + aTR = Max(TolReached2d, aMaxTol); + ProjLib_ProjectedCurve aProjCurvAgain(aBAHS, aBAHC, aTR);// 2 ProjLib::MakePCurveOfType(aProjCurvAgain, aC2D); aTolR = aProjCurvAgain.GetTolerance(); - // - if (aC2D.IsNull()) { - Standard_Real aTR=0.0001; - ProjLib_ProjectedCurve aProj3(aBAHS, aBAHC, aTR);// 3 - ProjLib::MakePCurveOfType(aProj3, aC2D); - aTolR = aProj3.GetTolerance(); - } } // if(aC2D.IsNull()) diff --git a/src/BRepFill/BRepFill_ComputeCLine.hxx b/src/BRepFill/BRepFill_ComputeCLine.hxx index 2b438001d5..5391c41aae 100644 --- a/src/BRepFill/BRepFill_ComputeCLine.hxx +++ b/src/BRepFill/BRepFill_ComputeCLine.hxx @@ -61,6 +61,9 @@ public: //! Changes the constraints of the approximation. Standard_EXPORT void SetConstraints (const AppParCurves_Constraint FirstC, const AppParCurves_Constraint LastC); + //! Changes the max number of segments, which is allowed for cutting. + Standard_EXPORT void SetMaxSegments (const Standard_Integer theMaxSegments); + //! returns False if at a moment of the approximation, //! the status NoApproximation has been sent by the user //! when more points were needed. @@ -114,7 +117,7 @@ private: Standard_Boolean mycut; AppParCurves_Constraint myfirstC; AppParCurves_Constraint mylastC; - + Standard_Integer myMaxSegments; }; diff --git a/src/ProjLib/ProjLib.cxx b/src/ProjLib/ProjLib.cxx index c9f380bcc8..36ee34ddbc 100644 --- a/src/ProjLib/ProjLib.cxx +++ b/src/ProjLib/ProjLib.cxx @@ -48,6 +48,7 @@ #include #include #include +#include //======================================================================= //function : Project @@ -281,3 +282,25 @@ void ProjLib::MakePCurveOfType break; } } +//======================================================================= +//function : IsAnaSurf +//purpose : +//======================================================================= +Standard_Boolean ProjLib::IsAnaSurf + (const Handle(Adaptor3d_HSurface)& theAS) +{ + switch (theAS->GetType()) + { + + case GeomAbs_Plane: + case GeomAbs_Cylinder: + case GeomAbs_Cone: + case GeomAbs_Sphere: + case GeomAbs_Torus: + return Standard_True; + break; + default : + return Standard_False; + break; + } +} diff --git a/src/ProjLib/ProjLib.hxx b/src/ProjLib/ProjLib.hxx index b5fa7ac097..f533479643 100644 --- a/src/ProjLib/ProjLib.hxx +++ b/src/ProjLib/ProjLib.hxx @@ -55,7 +55,7 @@ class ProjLib_Cylinder; class ProjLib_Cone; class ProjLib_Sphere; class ProjLib_Torus; - +class Adaptor3d_HSurface; //! The projLib package first provides projection of //! curves on a plane along a given Direction. The @@ -132,6 +132,12 @@ public: //! Make empty P-Curve of relevant to type Standard_EXPORT static void MakePCurveOfType (const ProjLib_ProjectedCurve& PC, Handle(Geom2d_Curve)& aC); + //! Returns "true" if surface is analytical, that is it can be + //! Plane, Cylinder, Cone, Sphere, Torus. + //! For all other types of surface method returns "false". + Standard_EXPORT static Standard_Boolean IsAnaSurf + (const Handle(Adaptor3d_HSurface)& theAS); + diff --git a/src/ProjLib/ProjLib_ComputeApprox.cxx b/src/ProjLib/ProjLib_ComputeApprox.cxx index 9fc50d35fd..5090998187 100644 --- a/src/ProjLib/ProjLib_ComputeApprox.cxx +++ b/src/ProjLib/ProjLib_ComputeApprox.cxx @@ -17,6 +17,7 @@ // modified by NIZHNY-OFV Thu Jan 20 11:04:19 2005 #include +#include #include #include @@ -956,6 +957,18 @@ static Standard_Real ComputeTolV(const Handle(Adaptor3d_HSurface)& theSurf, return aTolV; } +//======================================================================= +//function : ProjLib_ComputeApprox +//purpose : +//======================================================================= + +ProjLib_ComputeApprox::ProjLib_ComputeApprox(): + myTolerance(Precision::PApproximation()), + myDegMin(-1), myDegMax(-1), + myMaxSegments(-1), + myBndPnt(AppParCurves_TangencyPoint) +{ +} //======================================================================= //function : ProjLib_ComputeApprox @@ -965,19 +978,32 @@ static Standard_Real ComputeTolV(const Handle(Adaptor3d_HSurface)& theSurf, ProjLib_ComputeApprox::ProjLib_ComputeApprox (const Handle(Adaptor3d_HCurve) & C, const Handle(Adaptor3d_HSurface) & S, - const Standard_Real Tol ) + const Standard_Real Tol): + myTolerance(Max(Tol, Precision::PApproximation())), + myDegMin(-1), myDegMax(-1), + myMaxSegments(-1), + myBndPnt(AppParCurves_TangencyPoint) +{ + Perform(C, S); +} + +//======================================================================= +//function : Perform +//purpose : +//======================================================================= + +void ProjLib_ComputeApprox::Perform + (const Handle(Adaptor3d_HCurve) & C, + const Handle(Adaptor3d_HSurface) & S ) { // if the surface is a plane and the curve a BSpline or a BezierCurve, // don`t make an Approx but only the projection of the poles. - myTolerance = Max(Precision::PApproximation(),Tol); Standard_Integer NbKnots, NbPoles ; GeomAbs_CurveType CType = C->GetType(); GeomAbs_SurfaceType SType = S->GetType(); - Standard_Boolean SurfIsAnal = (SType != GeomAbs_BSplineSurface) && - (SType != GeomAbs_BezierSurface) && - (SType != GeomAbs_OtherSurface) ; + Standard_Boolean SurfIsAnal = ProjLib::IsAnaSurf(S); Standard_Boolean CurvIsAnal = (CType != GeomAbs_BSplineCurve) && (CType != GeomAbs_BezierCurve) && @@ -1085,21 +1111,43 @@ ProjLib_ComputeApprox::ProjLib_ComputeApprox #endif //----------- - Standard_Integer Deg1, Deg2; + Standard_Integer Deg1 = 8, Deg2; if(simplecase) { - Deg1 = 8; Deg2 = 10; } else { - Deg1 = 8; Deg2 = 12; } + if(myDegMin > 0) + { + Deg1 = myDegMin; + } + // + if(myDegMax > 0) + { + Deg2 = myDegMax; + } + // + Standard_Integer aMaxSegments = 1000; + if(myMaxSegments > 0) + { + aMaxSegments = myMaxSegments; + } + AppParCurves_Constraint aFistC = AppParCurves_TangencyPoint, aLastC = AppParCurves_TangencyPoint; + if(myBndPnt != AppParCurves_TangencyPoint) + { + aFistC = myBndPnt; + aLastC = myBndPnt; + } + //------------- const Standard_Real aTolU = ComputeTolU(S, myTolerance); const Standard_Real aTolV = ComputeTolV(S, myTolerance); const Standard_Real aTol2d = Max(Sqrt(aTolU*aTolU + aTolV*aTolV), Precision::PConfusion()); - Approx_FitAndDivide2d Fit(F, Deg1, Deg2, myTolerance, aTol2d, Standard_True); + Approx_FitAndDivide2d Fit(Deg1, Deg2, myTolerance, aTol2d, Standard_True, aFistC, aLastC); + Fit.SetMaxSegments(aMaxSegments); + Fit.Perform(F); Standard_Real aNewTol2d = 0; if(Fit.IsAllApproximated()) { @@ -1115,8 +1163,7 @@ ProjLib_ComputeApprox::ProjLib_ComputeApprox aNewTol2d = Max(aNewTol2d, Tol2d); AppParCurves_MultiCurve MC = Fit.Value( i); //Charge la Ieme Curve TColgp_Array1OfPnt2d Poles2d( 1, MC.Degree() + 1);//Recupere les poles - MC.Curve(1, Poles2d); - + MC.Curve(1, Poles2d); Conv.AddCurve(Poles2d); } @@ -1141,13 +1188,6 @@ ProjLib_ComputeApprox::ProjLib_ComputeApprox C->LastParameter(), NewKnots); - /*cout << endl; - for (int i = 1; i <= NbPoles; i++) - { - cout << NewPoles.Value(i).X() << " " << NewPoles.Value(i).Y() << endl; - } - cout << endl; */ - // il faut recadrer les poles de debut et de fin: // ( Car pour les problemes de couture, on a du ouvrir l`intervalle // de definition de la courbe.) @@ -1157,6 +1197,17 @@ ProjLib_ComputeApprox::ProjLib_ComputeApprox NewKnots, NewMults, Conv.Degree()); + + if(aFistC == AppParCurves_PassPoint || aLastC == AppParCurves_PassPoint) + { + // try to smoother the Curve GeomAbs_C1. + Standard_Integer aDeg = myBSpline->Degree(); + Standard_Boolean OK = Standard_True; + Standard_Real aSmoothTol = Max(Precision::Confusion(), aNewTol2d); + for (Standard_Integer ij = 2; ij < NbKnots; ij++) { + OK = OK && myBSpline->RemoveKnot(ij, aDeg-1, aSmoothTol); + } + } } else { Standard_Integer NbCurves = Fit.NbMultiCurves(); @@ -1254,6 +1305,42 @@ ProjLib_ComputeApprox::ProjLib_ComputeApprox } } } +//======================================================================= +//function : SetTolerance +//purpose : +//======================================================================= +void ProjLib_ComputeApprox::SetTolerance(const Standard_Real theTolerance) +{ + myTolerance = theTolerance; +} + +//======================================================================= +//function : SetDegree +//purpose : +//======================================================================= +void ProjLib_ComputeApprox::SetDegree(const Standard_Integer theDegMin, + const Standard_Integer theDegMax) +{ + myDegMin = theDegMin; + myDegMax = theDegMax; +} +//======================================================================= +//function : SetMaxSegments +//purpose : +//======================================================================= +void ProjLib_ComputeApprox::SetMaxSegments(const Standard_Integer theMaxSegments) +{ + myMaxSegments = theMaxSegments; +} + +//======================================================================= +//function : SetBndPnt +//purpose : +//======================================================================= +void ProjLib_ComputeApprox::SetBndPnt(const AppParCurves_Constraint theBndPnt) +{ + myBndPnt = theBndPnt; +} //======================================================================= //function : BSpline diff --git a/src/ProjLib/ProjLib_ComputeApprox.hxx b/src/ProjLib/ProjLib_ComputeApprox.hxx index 6bb6d54a36..c1aeda678b 100644 --- a/src/ProjLib/ProjLib_ComputeApprox.hxx +++ b/src/ProjLib/ProjLib_ComputeApprox.hxx @@ -22,6 +22,8 @@ #include #include +#include + class Geom2d_BSplineCurve; class Geom2d_BezierCurve; class Adaptor3d_HCurve; @@ -31,17 +33,51 @@ class Adaptor3d_HSurface; //! Approximate the projection of a 3d curve on an //! analytic surface and stores the result in Approx. //! The result is a 2d curve. +//! For approximation some parameters are used, including +//! required tolerance of approximation. +//! Tolerance is maximal possible value of 3d deviation of 3d projection of projected curve from +//! "exact" 3d projection. Since algorithm searches 2d curve on surface, required 2d tolerance is computed +//! from 3d tolerance with help of U,V resolutions of surface. +//! 3d and 2d tolerances have sence only for curves on surface, it defines precision of projecting and approximation +//! and have nothing to do with distance between the projected curve and the surface. class ProjLib_ComputeApprox { public: DEFINE_STANDARD_ALLOC - + //! Empty constructor, it only sets some initial values for class fields. + Standard_EXPORT ProjLib_ComputeApprox(); + //! is the tolerance with which the //! approximation is performed. + //! Other parameters for approximation have default values. Standard_EXPORT ProjLib_ComputeApprox(const Handle(Adaptor3d_HCurve)& C, const Handle(Adaptor3d_HSurface)& S, const Standard_Real Tol); + //! Performs projecting. + //! In case of approximation current values of parameters are used: + //! default values or set by corresponding methods Set... + Standard_EXPORT void Perform(const Handle(Adaptor3d_HCurve)& C, const Handle(Adaptor3d_HSurface)& S); + + //! Set tolerance of approximation. + //! Default value is Precision::Confusion(). + Standard_EXPORT void SetTolerance(const Standard_Real theTolerance); + + //! Set min and max possible degree of result BSpline curve2d, which is got by approximation. + //! If theDegMin/Max < 0, algorithm uses values that are chosen depending of types curve 3d + //! and surface. + Standard_EXPORT void SetDegree(const Standard_Integer theDegMin, const Standard_Integer theDegMax); + + //! Set the parameter, which defines maximal value of parametric intervals the projected + //! curve can be cut for approximation. If theMaxSegments < 0, algorithm uses default + //! value = 1000. + Standard_EXPORT void SetMaxSegments(const Standard_Integer theMaxSegments); + + //! Set the parameter, which defines type of boundary condition between segments during approximation. + //! It can be AppParCurves_PassPoint or AppParCurves_TangencyPoint. + //! Default value is AppParCurves_TangencyPoint; + Standard_EXPORT void SetBndPnt(const AppParCurves_Constraint theBndPnt); + Standard_EXPORT Handle(Geom2d_BSplineCurve) BSpline() const; Standard_EXPORT Handle(Geom2d_BezierCurve) Bezier() const; @@ -60,12 +96,13 @@ protected: private: - - Standard_Real myTolerance; Handle(Geom2d_BSplineCurve) myBSpline; Handle(Geom2d_BezierCurve) myBezier; - + Standard_Integer myDegMin; + Standard_Integer myDegMax; + Standard_Integer myMaxSegments; + AppParCurves_Constraint myBndPnt; }; diff --git a/src/ProjLib/ProjLib_ComputeApproxOnPolarSurface.cxx b/src/ProjLib/ProjLib_ComputeApproxOnPolarSurface.cxx index 82f567cac8..14185a3504 100644 --- a/src/ProjLib/ProjLib_ComputeApproxOnPolarSurface.cxx +++ b/src/ProjLib/ProjLib_ComputeApproxOnPolarSurface.cxx @@ -477,11 +477,15 @@ class ProjLib_PolarFunction : public AppCont_Function ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface() : myProjIsDone(Standard_False), - myTolerance (-1.0) + myTolerance(Precision::Approximation()), + myTolReached(-1.0), + myDegMin(-1), myDegMax(-1), + myMaxSegments(-1), + myMaxDist(-1.), + myBndPnt(AppParCurves_TangencyPoint) { } - //======================================================================= //function : ProjLib_ComputeApproxOnPolarSurface //purpose : @@ -493,10 +497,37 @@ ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface const Handle(Adaptor3d_HSurface)& theSurface, const Standard_Real theTolerance3D) : myProjIsDone(Standard_False), - myTolerance (theTolerance3D) + myTolerance(theTolerance3D), + myTolReached(-1.0), + myDegMin(-1), myDegMax(-1), + myMaxSegments(-1), + myMaxDist(-1.), + myBndPnt(AppParCurves_TangencyPoint) { myBSpline = Perform(theInitialCurve2d, theCurve, theSurface); } + +//======================================================================= +//function : ProjLib_ComputeApproxOnPolarSurface +//purpose : case without curve of initialization +//======================================================================= + +ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface + (const Handle(Adaptor3d_HCurve)& theCurve, + const Handle(Adaptor3d_HSurface)& theSurface, + const Standard_Real theTolerance3D) +: myProjIsDone(Standard_False), + myTolerance(theTolerance3D), + myTolReached(-1.0), + myDegMin(-1), myDegMax(-1), + myMaxSegments(-1), + myMaxDist(-1.), + myBndPnt(AppParCurves_TangencyPoint) +{ + const Handle(Adaptor2d_HCurve2d) anInitCurve2d; + myBSpline = Perform(anInitCurve2d, theCurve, theSurface); +} + //======================================================================= //function : ProjLib_ComputeApproxOnPolarSurface //purpose : Process the case of sewing @@ -509,7 +540,12 @@ ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface const Handle(Adaptor3d_HSurface)& theSurface, const Standard_Real theTolerance3D) : myProjIsDone(Standard_False), - myTolerance (theTolerance3D) + myTolerance(theTolerance3D), + myTolReached(-1.0), + myDegMin(-1), myDegMax(-1), + myMaxSegments(-1), + myMaxDist(-1.), + myBndPnt(AppParCurves_TangencyPoint) { // InitialCurve2d and InitialCurve2dBis are two pcurves of the sewing Handle(Geom2d_BSplineCurve) bsc = @@ -538,21 +574,6 @@ ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface } } -//======================================================================= -//function : ProjLib_ComputeApproxOnPolarSurface -//purpose : case without curve of initialization -//======================================================================= - -ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface - (const Handle(Adaptor3d_HCurve)& theCurve, - const Handle(Adaptor3d_HSurface)& theSurface, - const Standard_Real theTolerance3D) -: myProjIsDone(Standard_False), - myTolerance (theTolerance3D) -{ - const Handle(Adaptor2d_HCurve2d) anInitCurve2d; - myBSpline = Perform(anInitCurve2d, theCurve, theSurface); -} //======================================================================= //function : Concat @@ -628,15 +649,27 @@ static Handle(Geom2d_BSplineCurve) Concat(Handle(Geom2d_BSplineCurve) C1, return BS; } +//======================================================================= +//function : Perform +//purpose : +//======================================================================= + +void ProjLib_ComputeApproxOnPolarSurface::Perform +(const Handle(Adaptor3d_HCurve)& Curve, const Handle(Adaptor3d_HSurface)& S) +{ + const Handle(Adaptor2d_HCurve2d) anInitCurve2d; + myBSpline = Perform(anInitCurve2d, Curve, S); +} //======================================================================= //function : Perform //purpose : //======================================================================= + Handle(Geom2d_BSplineCurve) ProjLib_ComputeApproxOnPolarSurface::Perform (const Handle(Adaptor2d_HCurve2d)& InitialCurve2d, const Handle(Adaptor3d_HCurve)& Curve, - const Handle(Adaptor3d_HSurface)& S) + const Handle(Adaptor3d_HSurface)& S) { //OCC217 Standard_Real Tol3d = myTolerance; @@ -752,8 +785,11 @@ Handle(Geom2d_BSplineCurve) ProjLib_ComputeApproxOnPolarSurface::Perform } if(myProjIsDone) { - BSC2d = ProjectUsingInitialCurve2d(AHC, S, AHC2d); - if(BSC2d.IsNull()) return Handle(Geom2d_BSplineCurve)(); //IFV + BSC2d = ProjectUsingInitialCurve2d(AHC, S, AHC2d); + if(BSC2d.IsNull()) + { + return Handle(Geom2d_BSplineCurve)(); + } LOfBSpline2d.Append(BSC2d); } else { @@ -799,7 +835,7 @@ Handle(Geom2d_BSplineCurve) ProjLib_ComputeApproxOnPolarSurface::Perform } } if(myProjIsDone) { - BSC2d = ProjectUsingInitialCurve2d(AHC, S, AHC2d); + BSC2d = ProjectUsingInitialCurve2d(AHC, S, AHC2d); if(BSC2d.IsNull()) { return Handle(Geom2d_BSplineCurve)(); } @@ -854,9 +890,10 @@ Handle(Geom2d_BSplineCurve) ProjLib_ComputeApproxOnPolarSurface::Perform if(!myProjIsDone) return Handle(Geom2d_BSplineCurve)(); } - return ProjectUsingInitialCurve2d(AHC, S, AHC2d); + return ProjectUsingInitialCurve2d(AHC, S, AHC2d); } + //======================================================================= //function : ProjLib_BuildInitialCurve2d //purpose : @@ -875,7 +912,11 @@ Handle(Adaptor2d_HCurve2d) Standard_Real Tol3d = myTolerance; Standard_Real TolU = Surf->UResolution(Tol3d), TolV = Surf->VResolution(Tol3d); Standard_Real DistTol3d = 100.0*Tol3d; - + if(myMaxDist > 0.) + { + DistTol3d = myMaxDist; + } + Standard_Real DistTol3d2 = DistTol3d * DistTol3d; Standard_Real uperiod = 0.0, vperiod = 0.0; computePeriodicity(Surf, uperiod, vperiod); @@ -1055,7 +1096,7 @@ Handle(Adaptor2d_HCurve2d) aMinSqDist = aSqDist; } } - if (aMinSqDist > DistTol3d * DistTol3d) //try to project with less tolerance + if (aMinSqDist > DistTol3d2) //try to project with less tolerance { TolU = Min(TolU, Precision::PConfusion()); TolV = Min(TolV, Precision::PConfusion()); @@ -1071,7 +1112,7 @@ Handle(Adaptor2d_HCurve2d) Standard_Integer GoodValue = 1; for ( i = 1 ; i <= aExtPS.NbExt() ; i++ ) { - if( aExtPS.SquareDistance(i) < DistTol3d * DistTol3d ) { + if( aExtPS.SquareDistance(i) < DistTol3d2 ) { if( aExtPS.SquareDistance(i) <= 1.e-18 ) { aExtPS.Point(i).Parameter(u,v); gp_Pnt2d p2d(u,v); @@ -1093,7 +1134,7 @@ Handle(Adaptor2d_HCurve2d) if( Sols.Length() > 1 ) areManyZeros = Standard_True; - if( Dist2Min <= DistTol3d * DistTol3d) { + if( Dist2Min <= DistTol3d2) { if( !areManyZeros ) { aExtPS.Point(GoodValue).Parameter(u,v); Pts2d(1).SetCoord(u,v); @@ -1123,7 +1164,7 @@ Handle(Adaptor2d_HCurve2d) Dist2Min = 1.e+200; if( aTPS.IsDone() && aTPS.NbExt() >= 1 ) { for( j = 1 ; j <= aTPS.NbExt() ; j++ ) { - if( aTPS.SquareDistance(j) < DistTol3d * DistTol3d ) { + if( aTPS.SquareDistance(j) < DistTol3d2 ) { nbExtOk++; if( aTPS.SquareDistance(j) < Dist2Min ) { Dist2Min = aTPS.SquareDistance(j); @@ -1151,7 +1192,7 @@ Handle(Adaptor2d_HCurve2d) Standard_Integer indExt = 0; if( aTPS.IsDone() && aTPS.NbExt() >= 1 ) { for( i = 1 ; i <= aTPS.NbExt() ; i++ ) { - if( aTPS.SquareDistance(i) < DistTol3d * DistTol3d && aTPS.SquareDistance(i) < Dist2Min ) { + if( aTPS.SquareDistance(i) < DistTol3d2 && aTPS.SquareDistance(i) < Dist2Min ) { Dist2Min = aTPS.SquareDistance(i); indExt = i; isFound = Standard_True; @@ -1225,7 +1266,7 @@ Handle(Adaptor2d_HCurve2d) if (aLocateExtPS.IsDone()) { - if (aLocateExtPS.SquareDistance() < DistTol3d * DistTol3d) + if (aLocateExtPS.SquareDistance() < DistTol3d2) { //OCC217 //if (aLocateExtPS.SquareDistance() < Tol3d * Tol3d) { (aLocateExtPS.Point()).Parameter(U0,V0); @@ -1250,7 +1291,7 @@ Handle(Adaptor2d_HCurve2d) imin = isol; } } - if (LocalMinSqDist < DistTol3d * DistTol3d) + if (LocalMinSqDist < DistTol3d2) { Standard_Real LocalU, LocalV; aGlobalExtr.Point(imin).Parameter(LocalU, LocalV); @@ -1322,7 +1363,7 @@ Handle(Adaptor2d_HCurve2d) locext.Perform(pntproj, Uaux, V0); if (locext.IsDone()) - if (locext.SquareDistance() < DistTol3d * DistTol3d) { //OCC217 + if (locext.SquareDistance() < DistTol3d2) { //OCC217 //if (locext.SquareDistance() < Tol3d * Tol3d) { (locext.Point()).Parameter(u,v); if((aUsup - U0) > (U0 - aUinf)) @@ -1349,7 +1390,7 @@ Handle(Adaptor2d_HCurve2d) locext.Perform(pntproj, U0, Vaux); if (locext.IsDone()) - if (locext.SquareDistance() < DistTol3d * DistTol3d) { //OCC217 + if (locext.SquareDistance() < DistTol3d2) { //OCC217 //if (locext.SquareDistance() < Tol3d * Tol3d) { (locext.Point()).Parameter(u,v); if((aVsup - V0) > (V0 - aVinf)) @@ -1378,7 +1419,7 @@ Handle(Adaptor2d_HCurve2d) locext.Perform(pntproj, Uaux, Vaux); if (locext.IsDone()) - if (locext.SquareDistance() < DistTol3d * DistTol3d) { + if (locext.SquareDistance() < DistTol3d2) { //if (locext.SquareDistance() < Tol3d * Tol3d) { (locext.Point()).Parameter(u,v); if((Usup - U0) > (U0 - Uinf)) @@ -1406,7 +1447,7 @@ Handle(Adaptor2d_HCurve2d) Dist2Min = ext.SquareDistance(j); aGoodValue = j; } - if (Dist2Min < DistTol3d * DistTol3d) { + if (Dist2Min < DistTol3d2) { //if (Dist2Min < Tol3d * Tol3d) { (ext.Point(aGoodValue)).Parameter(u,v); if(uperiod) { @@ -1491,9 +1532,6 @@ Handle(Adaptor2d_HCurve2d) // Modified by Sergey KHROMOV - Thu Apr 18 10:58:02 2002 End } - - - //======================================================================= //function : ProjLib_ProjectUsingInitialCurve2d //purpose : @@ -1502,24 +1540,27 @@ Handle(Geom2d_BSplineCurve) ProjLib_ComputeApproxOnPolarSurface:: ProjectUsingInitialCurve2d(const Handle(Adaptor3d_HCurve)& Curve, const Handle(Adaptor3d_HSurface)& Surf, - const Handle(Adaptor2d_HCurve2d)& InitCurve2d) + const Handle(Adaptor2d_HCurve2d)& InitCurve2d) { //OCC217 Standard_Real Tol3d = myTolerance; - Standard_Real DistTol3d = 1.0*Tol3d; + Standard_Real DistTol3d = 100.0*Tol3d; + if(myMaxDist > 0.) + { + DistTol3d = myMaxDist; + } + Standard_Real DistTol3d2 = DistTol3d * DistTol3d; Standard_Real TolU = Surf->UResolution(Tol3d), TolV = Surf->VResolution(Tol3d); Standard_Real Tol2d = Max(Sqrt(TolU*TolU + TolV*TolV), Precision::PConfusion()); Standard_Integer i; GeomAbs_SurfaceType TheTypeS = Surf->GetType(); GeomAbs_CurveType TheTypeC = Curve->GetType(); -// Handle(Standard_Type) TheTypeS = Surf->DynamicType(); -// Handle(Standard_Type) TheTypeC = Curve->DynamicType(); // si on a : -// if(TheTypeS == STANDARD_TYPE(Geom_BSplineSurface)) { if(TheTypeS == GeomAbs_Plane) { Standard_Real S, T; gp_Pln Plane = Surf->Plane(); if(TheTypeC == GeomAbs_BSplineCurve) { + myTolReached = Precision::Confusion(); Handle(Geom_BSplineCurve) BSC = Curve->BSpline(); TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles()); for(i = 1;i <= Curve->NbPoles();i++) { @@ -1541,6 +1582,7 @@ Handle(Geom2d_BSplineCurve) } if(TheTypeC == GeomAbs_BezierCurve) { + myTolReached = Precision::Confusion(); Handle(Geom_BezierCurve) BC = Curve->Bezier(); TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles()); for(i = 1;i <= Curve->NbPoles();i++) { @@ -1573,17 +1615,11 @@ Handle(Geom2d_BSplineCurve) gp_Pnt p22 = BSS->Pole(2,2); gp_Vec V1(p11,p12); gp_Vec V2(p21,p22); - if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/M_PI))){ //OCC217 - //if(V1.IsEqual(V2,myTolerance,myTolerance/(p11.Distance(p12)*180/M_PI))){ - // so the polar surface is plane - // and if it is enough to projet the poles of Curve + if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/M_PI))){ Standard_Integer Dist2Min = IntegerLast(); Standard_Real u,v; - //OCC217 - //Standard_Real TolU = Surf->UResolution(myTolerance) - // , TolV = Surf->VResolution(myTolerance); -// gp_Pnt pntproj; if(TheTypeC == GeomAbs_BSplineCurve) { + myTolReached = Tol3d; Handle(Geom_BSplineCurve) BSC = Curve->BSpline(); TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles()); for(i = 1;i <= Curve->NbPoles();i++) { @@ -1595,8 +1631,7 @@ Handle(Geom2d_BSplineCurve) if (extrloc.IsDone()) { Dist2Min = (Standard_Integer ) extrloc.SquareDistance(); - if (Dist2Min < DistTol3d * DistTol3d) { //OCC217 - //if (Dist2Min < myTolerance * myTolerance) { + if (Dist2Min < DistTol3d2) { (extrloc.Point()).Parameter(u,v); Poles2d(i).SetCoord(u,v); myProjIsDone = Standard_True; @@ -1625,6 +1660,7 @@ Handle(Geom2d_BSplineCurve) } } if(TheTypeC == GeomAbs_BezierCurve) { + myTolReached = Tol3d; Handle(Geom_BezierCurve) BC = Curve->Bezier(); TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles()); for(i = 1;i <= Curve->NbPoles();i++) { @@ -1635,8 +1671,7 @@ Handle(Geom2d_BSplineCurve) if (extrloc.IsDone()) { Dist2Min = (Standard_Integer ) extrloc.SquareDistance(); - if (Dist2Min < DistTol3d * DistTol3d) { //OCC217 - //if (Dist2Min < myTolerance * myTolerance) { + if (Dist2Min < DistTol3d2) { (extrloc.Point()).Parameter(u,v); Poles2d(i).SetCoord(u,v); myProjIsDone = Standard_True; @@ -1678,19 +1713,15 @@ Handle(Geom2d_BSplineCurve) gp_Pnt p22 = BS->Pole(2,2); gp_Vec V1(p11,p12); gp_Vec V2(p21,p22); - if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/M_PI))){ //OCC217 - //if (V1.IsEqual(V2,myTolerance,myTolerance/(p11.Distance(p12)*180/M_PI))){ - // and if it is enough to project the poles of Curve + if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/M_PI))){ Standard_Integer Dist2Min = IntegerLast(); Standard_Real u,v; - //OCC217 - //Standard_Real TolU = Surf->UResolution(myTolerance) - // , TolV = Surf->VResolution(myTolerance); - + // gp_Pnt pntproj; if(TheTypeC == GeomAbs_BSplineCurve) { + myTolReached = Tol3d; Handle(Geom_BSplineCurve) BSC = Curve->BSpline(); - TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles()); + TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles()); for(i = 1;i <= Curve->NbPoles();i++) { myProjIsDone = Standard_False; Dist2Min = IntegerLast(); @@ -1700,8 +1731,7 @@ Handle(Geom2d_BSplineCurve) if (extrloc.IsDone()) { Dist2Min = (Standard_Integer ) extrloc.SquareDistance(); - if (Dist2Min < DistTol3d * DistTol3d) { //OCC217 - //if (Dist2Min < myTolerance * myTolerance) { + if (Dist2Min < DistTol3d2) { (extrloc.Point()).Parameter(u,v); Poles2d(i).SetCoord(u,v); myProjIsDone = Standard_True; @@ -1730,6 +1760,7 @@ Handle(Geom2d_BSplineCurve) } } if(TheTypeC == GeomAbs_BezierCurve) { + myTolReached = Tol3d; Handle(Geom_BezierCurve) BC = Curve->Bezier(); TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles()); for(i = 1;i <= Curve->NbPoles();i++) { @@ -1740,8 +1771,7 @@ Handle(Geom2d_BSplineCurve) if (extrloc.IsDone()) { Dist2Min = (Standard_Integer ) extrloc.SquareDistance(); - if (Dist2Min < DistTol3d * DistTol3d) { //OCC217 - //if (Dist2Min < myTolerance * myTolerance) { + if (Dist2Min < DistTol3d2) { (extrloc.Point()).Parameter(u,v); Poles2d(i).SetCoord(u,v); myProjIsDone = Standard_True; @@ -1773,8 +1803,7 @@ Handle(Geom2d_BSplineCurve) } } - ProjLib_PolarFunction F(Curve, Surf, InitCurve2d, Tol3d) ; //OCC217 - //ProjLib_PolarFunction F(Curve, Surf, InitCurve2d, myTolerance) ; + ProjLib_PolarFunction F(Curve, Surf, InitCurve2d, Tol3d) ; #ifdef OCCT_DEBUG Standard_Integer Nb = 50; @@ -1813,15 +1842,34 @@ Handle(Geom2d_BSplineCurve) #endif Standard_Integer Deg1,Deg2; -// Deg1 = 8; -// Deg2 = 8; - Deg1 = 2; //IFV - Deg2 = 8; //IFV + Deg1 = 2; + Deg2 = 8; + if(myDegMin > 0) + { + Deg1 = myDegMin; + } + if(myDegMax > 0) + { + Deg2 = myDegMax; + } + Standard_Integer aMaxSegments = 1000; + if(myMaxSegments > 0) + { + aMaxSegments = myMaxSegments; + } + AppParCurves_Constraint aFistC = AppParCurves_TangencyPoint, aLastC = AppParCurves_TangencyPoint; + if(myBndPnt != AppParCurves_TangencyPoint) + { + aFistC = myBndPnt; + aLastC = myBndPnt; + } - Approx_FitAndDivide2d Fit(F,Deg1,Deg2,Tol3d,Tol2d, //OCC217 - //Approx_FitAndDivide2d Fit(F,Deg1,Deg2,myTolerance,myTolerance, - Standard_True); + Approx_FitAndDivide2d Fit(Deg1, Deg2, Tol3d, Tol2d, Standard_True, aFistC, aLastC); + Fit.SetMaxSegments(aMaxSegments); + Fit.Perform(F); + Standard_Real anOldTol2d = Tol2d; + Standard_Real aNewTol2d = 0; if(Fit.IsAllApproximated()) { Standard_Integer j; Standard_Integer NbCurves = Fit.NbMultiCurves(); @@ -1832,8 +1880,12 @@ Handle(Geom2d_BSplineCurve) for (j = 1; j <= NbCurves; j++) { Standard_Integer Deg = Fit.Value(j).Degree(); MaxDeg = Max ( MaxDeg, Deg); + Fit.Error(j,Tol3d, Tol2d); + aNewTol2d = Max(aNewTol2d, Tol2d); } - + // + myTolReached = Max(myTolReached, myTolerance * (aNewTol2d / anOldTol2d)); + // NbPoles = MaxDeg * NbCurves + 1; //Tops on the BSpline TColgp_Array1OfPnt2d Poles( 1, NbPoles); @@ -1885,10 +1937,9 @@ Handle(Geom2d_BSplineCurve) // try to smoother the Curve GeomAbs_C1. Standard_Boolean OK = Standard_True; - + Standard_Real aSmoothTol = Max(Precision::Confusion(), aNewTol2d); for (Standard_Integer ij = 2; ij < NbKnots; ij++) { - OK = OK && Dummy->RemoveKnot(ij,MaxDeg-1,Tol3d); //OCC217 - //OK = OK && Dummy->RemoveKnot(ij,MaxDeg-1,myTolerance); + OK = OK && Dummy->RemoveKnot(ij,MaxDeg-1, aSmoothTol); } #ifdef OCCT_DEBUG if (!OK) { @@ -1909,11 +1960,6 @@ Handle(Geom2d_BSplineCurve) ProjLib_ComputeApproxOnPolarSurface::BSpline() const { -// Modified by Sergey KHROMOV - Thu Apr 18 11:16:46 2002 End -// Standard_NoSuchObject_Raise_if -// (!myProjIsDone, -// "ProjLib_ComputeApproxOnPolarSurface:BSpline"); -// Modified by Sergey KHROMOV - Thu Apr 18 11:16:47 2002 End return myBSpline ; } @@ -1943,3 +1989,65 @@ Standard_Boolean ProjLib_ComputeApproxOnPolarSurface::IsDone() const { return myProjIsDone; } +//======================================================================= +//function : SetTolerance +//purpose : +//======================================================================= + +void ProjLib_ComputeApproxOnPolarSurface::SetTolerance(const Standard_Real theTol) + +{ + myTolerance = theTol; +} +//======================================================================= +//function : SetDegree +//purpose : +//======================================================================= +void ProjLib_ComputeApproxOnPolarSurface::SetDegree( + const Standard_Integer theDegMin, + const Standard_Integer theDegMax) +{ + myDegMin = theDegMin; + myDegMax = theDegMax; +} +//======================================================================= +//function : SetMaxSegments +//purpose : +//======================================================================= +void ProjLib_ComputeApproxOnPolarSurface::SetMaxSegments( + const Standard_Integer theMaxSegments) +{ + myMaxSegments = theMaxSegments; +} + +//======================================================================= +//function : SetBndPnt +//purpose : +//======================================================================= +void ProjLib_ComputeApproxOnPolarSurface::SetBndPnt( + const AppParCurves_Constraint theBndPnt) +{ + myBndPnt = theBndPnt; +} + +//======================================================================= +//function : SetMaxDist +//purpose : +//======================================================================= +void ProjLib_ComputeApproxOnPolarSurface::SetMaxDist( + const Standard_Real theMaxDist) +{ + myMaxDist = theMaxDist; +} + +//======================================================================= +//function : Tolerance +//purpose : +//======================================================================= + +Standard_Real ProjLib_ComputeApproxOnPolarSurface::Tolerance() const + +{ + return myTolReached; +} + diff --git a/src/ProjLib/ProjLib_ComputeApproxOnPolarSurface.hxx b/src/ProjLib/ProjLib_ComputeApproxOnPolarSurface.hxx index 4e116eba9c..3927f2759c 100644 --- a/src/ProjLib/ProjLib_ComputeApproxOnPolarSurface.hxx +++ b/src/ProjLib/ProjLib_ComputeApproxOnPolarSurface.hxx @@ -23,6 +23,7 @@ #include #include +#include class Geom2d_BSplineCurve; class Geom2d_Curve; class Adaptor3d_HCurve; @@ -35,33 +36,89 @@ class Adaptor2d_HCurve2d; //! The result is a 2d curve. The evaluation of the //! current point of the 2d curve is done with the //! evaluation of the extrema P3d - Surface. +//! For approximation some parameters are used, including +//! required tolerance of approximation. +//! Tolerance is maximal possible value of 3d deviation of 3d projection of projected curve from +//! "exact" 3d projection. Since algorithm searches 2d curve on surface, required 2d tolerance is computed +//! from 3d tolerance with help of U,V resolutions of surface. +//! 3d and 2d tolerances have sence only for curves on surface, it defines precision of projecting and approximation +//! and have nothing to do with distance between the projected curve and the surface. class ProjLib_ComputeApproxOnPolarSurface { public: DEFINE_STANDARD_ALLOC - + //! Empty constructor, it only sets some initial values for class fields. Standard_EXPORT ProjLib_ComputeApproxOnPolarSurface(); - + + //! Constructor, which performs projecting. Standard_EXPORT ProjLib_ComputeApproxOnPolarSurface(const Handle(Adaptor3d_HCurve)& C, const Handle(Adaptor3d_HSurface)& S, const Standard_Real Tol = 1.0e-4); - + + + //! Constructor, which performs projecting, using initial curve 2d InitCurve2d, which is any rough approximation of result curve. + //! Parameter Tol is 3d tolerance of approximation. Standard_EXPORT ProjLib_ComputeApproxOnPolarSurface(const Handle(Adaptor2d_HCurve2d)& InitCurve2d, const Handle(Adaptor3d_HCurve)& C, const Handle(Adaptor3d_HSurface)& S, const Standard_Real Tol); + + //! Constructor, which performs projecting, using two initial curves 2d: InitCurve2d and InitCurve2dBis that are any rough approximations of result curves. + //! This constructor is used to get two pcurves for seem edge. + //! Parameter Tol is 3d tolerance of approximation. + Standard_EXPORT ProjLib_ComputeApproxOnPolarSurface(const Handle(Adaptor2d_HCurve2d)& InitCurve2d, const Handle(Adaptor2d_HCurve2d)& InitCurve2dBis, const Handle(Adaptor3d_HCurve)& C, + const Handle(Adaptor3d_HSurface)& S, const Standard_Real Tol); + - Standard_EXPORT ProjLib_ComputeApproxOnPolarSurface(const Handle(Adaptor2d_HCurve2d)& InitCurve2d, const Handle(Adaptor2d_HCurve2d)& InitCurve2dBis, const Handle(Adaptor3d_HCurve)& C, const Handle(Adaptor3d_HSurface)& S, const Standard_Real Tol); - + //! Set min and max possible degree of result BSpline curve2d, which is got by approximation. + //! If theDegMin/Max < 0, algorithm uses values min = 2, max = 8. + Standard_EXPORT void SetDegree(const Standard_Integer theDegMin, const Standard_Integer theDegMax); + + //! Set the parameter, which defines maximal value of parametric intervals the projected + //! curve can be cut for approximation. If theMaxSegments < 0, algorithm uses default + //! value = 1000. + Standard_EXPORT void SetMaxSegments(const Standard_Integer theMaxSegments); + + //! Set the parameter, which defines type of boundary condition between segments during approximation. + //! It can be AppParCurves_PassPoint or AppParCurves_TangencyPoint. + //! Default value is AppParCurves_TangencyPoint. + Standard_EXPORT void SetBndPnt(const AppParCurves_Constraint theBndPnt); + + //! Set the parameter, which defines maximal possible distance between projected curve and surface. + //! It is used only for projecting on not analytical surfaces. + //! If theMaxDist < 0, algoritm uses default value 100.*Tolerance. + //! If real distance between curve and surface more then theMaxDist, algorithm stops working. + Standard_EXPORT void SetMaxDist(const Standard_Real theMaxDist); + + //! Set the tolerance used to project + //! the curve on the surface. + //! Default value is Precision::Approximation(). + Standard_EXPORT void SetTolerance (const Standard_Real theTolerance); + + //! Method, which performs projecting, using default values of parameters or + //! they must be set by corresponding methods before using. + Standard_EXPORT void Perform (const Handle(Adaptor3d_HCurve)& C, const Handle(Adaptor3d_HSurface)& S); + + //! Method, which performs projecting, using default values of parameters or + //! they must be set by corresponding methods before using. + //! Parameter InitCurve2d is any rough estimation of 2d result curve. Standard_EXPORT Handle(Geom2d_BSplineCurve) Perform (const Handle(Adaptor2d_HCurve2d)& InitCurve2d, const Handle(Adaptor3d_HCurve)& C, const Handle(Adaptor3d_HSurface)& S); - + + //! Builds initial 2d curve as BSpline with degree = 1 using Extrema algoritm. + //! Method is used in method Perform(...). Standard_EXPORT Handle(Adaptor2d_HCurve2d) BuildInitialCurve2d (const Handle(Adaptor3d_HCurve)& Curve, const Handle(Adaptor3d_HSurface)& S); - + + + //! Method, which performs projecting. + //! Method is used in method Perform(...). Standard_EXPORT Handle(Geom2d_BSplineCurve) ProjectUsingInitialCurve2d (const Handle(Adaptor3d_HCurve)& Curve, const Handle(Adaptor3d_HSurface)& S, const Handle(Adaptor2d_HCurve2d)& InitCurve2d); - + + //! Returns result curve 2d. Standard_EXPORT Handle(Geom2d_BSplineCurve) BSpline() const; - + //! Returns second 2d curve. Standard_EXPORT Handle(Geom2d_Curve) Curve2d() const; Standard_EXPORT Standard_Boolean IsDone() const; + //! returns the reached Tolerance. + Standard_EXPORT Standard_Real Tolerance() const; @@ -79,6 +136,12 @@ private: Standard_Real myTolerance; Handle(Geom2d_BSplineCurve) myBSpline; Handle(Geom2d_Curve) my2ndCurve; + Standard_Real myTolReached; + Standard_Integer myDegMin; + Standard_Integer myDegMax; + Standard_Integer myMaxSegments; + Standard_Real myMaxDist; + AppParCurves_Constraint myBndPnt; }; diff --git a/src/ProjLib/ProjLib_ProjectedCurve.cxx b/src/ProjLib/ProjLib_ProjectedCurve.cxx index 03ac507ca6..656e99be76 100644 --- a/src/ProjLib/ProjLib_ProjectedCurve.cxx +++ b/src/ProjLib/ProjLib_ProjectedCurve.cxx @@ -55,6 +55,39 @@ #include #include #include +//======================================================================= +//function : ComputeTolU +//purpose : +//======================================================================= + +static Standard_Real ComputeTolU(const Handle(Adaptor3d_HSurface)& theSurf, + const Standard_Real theTolerance) +{ + Standard_Real aTolU = theSurf->UResolution(theTolerance); + if (theSurf->IsUPeriodic()) + { + aTolU = Min(aTolU, 0.01*theSurf->UPeriod()); + } + + return aTolU; +} + +//======================================================================= +//function : ComputeTolV +//purpose : +//======================================================================= + +static Standard_Real ComputeTolV(const Handle(Adaptor3d_HSurface)& theSurf, + const Standard_Real theTolerance) +{ + Standard_Real aTolV = theSurf->VResolution(theTolerance); + if (theSurf->IsVPeriodic()) + { + aTolV = Min(aTolV, 0.01*theSurf->VPeriod()); + } + + return aTolV; +} //======================================================================= //function : IsoIsDeg @@ -259,10 +292,13 @@ static void Project(ProjLib_Projector& P, Handle(Adaptor3d_HCurve)& C) //purpose : //======================================================================= -ProjLib_ProjectedCurve::ProjLib_ProjectedCurve() - +ProjLib_ProjectedCurve::ProjLib_ProjectedCurve() : + myTolerance(Precision::Confusion()), + myDegMin(-1), myDegMax(-1), + myMaxSegments(-1), + myMaxDist(-1.), + myBndPnt(AppParCurves_TangencyPoint) { - myTolerance = Precision::Confusion(); } @@ -272,9 +308,13 @@ ProjLib_ProjectedCurve::ProjLib_ProjectedCurve() //======================================================================= ProjLib_ProjectedCurve::ProjLib_ProjectedCurve -(const Handle(Adaptor3d_HSurface)& S) +(const Handle(Adaptor3d_HSurface)& S) : + myTolerance(Precision::Confusion()), + myDegMin(-1), myDegMax(-1), + myMaxSegments(-1), + myMaxDist(-1.), + myBndPnt(AppParCurves_TangencyPoint) { - myTolerance = Precision::Confusion(); Load(S); } @@ -286,11 +326,15 @@ ProjLib_ProjectedCurve::ProjLib_ProjectedCurve ProjLib_ProjectedCurve::ProjLib_ProjectedCurve (const Handle(Adaptor3d_HSurface)& S, - const Handle(Adaptor3d_HCurve)& C) + const Handle(Adaptor3d_HCurve)& C) : + myTolerance(Precision::Confusion()), + myDegMin(-1), myDegMax(-1), + myMaxSegments(-1), + myMaxDist(-1.), + myBndPnt(AppParCurves_TangencyPoint) { - myTolerance = Precision::Confusion(); Load(S); - Load(C); + Perform(C); } @@ -302,11 +346,15 @@ ProjLib_ProjectedCurve::ProjLib_ProjectedCurve ProjLib_ProjectedCurve::ProjLib_ProjectedCurve (const Handle(Adaptor3d_HSurface)& S, const Handle(Adaptor3d_HCurve)& C, - const Standard_Real Tol) + const Standard_Real Tol) : + myTolerance(Max(Tol, Precision::Confusion())), + myDegMin(-1), myDegMax(-1), + myMaxSegments(-1), + myMaxDist(-1.), + myBndPnt(AppParCurves_TangencyPoint) { - myTolerance = Max(Tol, Precision::Confusion()); Load(S); - Load(C); + Perform(C); } @@ -320,13 +368,22 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HSurface)& S) mySurface = S ; } - //======================================================================= //function : Load //purpose : //======================================================================= -void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C) +void ProjLib_ProjectedCurve::Load(const Standard_Real theTol) +{ + myTolerance = theTol; +} + +//======================================================================= +//function : Perform +//purpose : +//======================================================================= + +void ProjLib_ProjectedCurve::Perform(const Handle(Adaptor3d_HCurve)& C) { myTolerance = Max(myTolerance, Precision::Confusion()); myCurve = C; @@ -431,12 +488,19 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C) TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 4); } - ProjLib_ComputeApproxOnPolarSurface polar(myCurve, mySurface, myTolerance); + ProjLib_ComputeApproxOnPolarSurface polar; + polar.SetTolerance(myTolerance); + polar.SetDegree(myDegMin, myDegMax); + polar.SetMaxSegments(myMaxSegments); + polar.SetBndPnt(myBndPnt); + polar.SetMaxDist(myMaxDist); + polar.Perform(myCurve, mySurface); Handle(Geom2d_BSplineCurve) aRes = polar.BSpline(); if (!aRes.IsNull()) { + myTolerance = polar.Tolerance(); if( (IsTrimmed[0] || IsTrimmed[1])) { if(IsTrimmed[0]) @@ -538,7 +602,16 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C) } } - ProjLib_CompProjectedCurve Projector(mySurface,myCurve, myTolerance, myTolerance, 100 * myTolerance); + Standard_Real aTolU = Max(ComputeTolU(mySurface, myTolerance), Precision::Confusion()); + Standard_Real aTolV = Max(ComputeTolV(mySurface, myTolerance), Precision::Confusion()); + Standard_Real aTol2d = Sqrt(aTolU*aTolU + aTolV*aTolV); + + Standard_Real aMaxDist = 100. * myTolerance; + if(myMaxDist > 0.) + { + aMaxDist = myMaxDist; + } + ProjLib_CompProjectedCurve Projector(mySurface,myCurve, aTolU, aTolV, aMaxDist); Handle(ProjLib_HCompProjectedCurve) HProjector = new ProjLib_HCompProjectedCurve(); HProjector->Set(Projector); @@ -559,8 +632,20 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C) Standard_Boolean Only3d = Standard_False; Standard_Boolean Only2d = Standard_True; GeomAbs_Shape Continuity = GeomAbs_C1; + if(myBndPnt == AppParCurves_PassPoint) + { + Continuity = GeomAbs_C0; + } Standard_Integer MaxDegree = 14; + if(myDegMax > 0) + { + MaxDegree = myDegMax; + } Standard_Integer MaxSeg = 16; + if(myMaxSegments > 0) + { + MaxSeg = myMaxSegments; + } Approx_CurveOnSurface appr(HProjector, mySurface, Udeb, Ufin, myTolerance, Continuity, MaxDegree, MaxSeg, @@ -570,6 +655,10 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C) if (!aRes.IsNull()) { + aTolU = appr.MaxError2dU(); + aTolV = appr.MaxError2dV(); + Standard_Real aNewTol2d = Sqrt(aTolU*aTolU + aTolV*aTolV); + myTolerance *= (aNewTol2d / aTol2d); if(IsTrimmed[0] || IsTrimmed[1]) { // Treatment only for surface of revolution @@ -594,6 +683,16 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C) aRes->FirstParameter(), aRes->LastParameter(), FirstPar, LastPar, NewCurve2d); aRes = Handle(Geom2d_BSplineCurve)::DownCast(NewCurve2d); + if(Continuity == GeomAbs_C0) + { + // try to smoother the Curve GeomAbs_C1. + Standard_Integer aDeg = aRes->Degree(); + Standard_Boolean OK = Standard_True; + Standard_Real aSmoothTol = Max(Precision::Confusion(), aNewTol2d); + for (Standard_Integer ij = 2; ij < aRes->NbKnots(); ij++) { + OK = OK && aRes->RemoveKnot(ij, aDeg-1, aSmoothTol); + } + } } myResult.SetBSpline(aRes); @@ -606,7 +705,12 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C) if ( !myResult.IsDone() && isAnalyticalSurf) { // Use advanced analytical projector if base analytical projection failed. - ProjLib_ComputeApprox Comp( myCurve, mySurface, myTolerance); + ProjLib_ComputeApprox Comp; + Comp.SetTolerance(myTolerance); + Comp.SetDegree(myDegMin, myDegMax); + Comp.SetMaxSegments(myMaxSegments); + Comp.SetBndPnt(myBndPnt); + Comp.Perform( myCurve, mySurface); if (Comp.Bezier().IsNull() && Comp.BSpline().IsNull()) return; // advanced projector has been failed too myResult.Done(); @@ -723,6 +827,42 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C) } } +//======================================================================= +//function : SetDegree +//purpose : +//======================================================================= +void ProjLib_ProjectedCurve::SetDegree(const Standard_Integer theDegMin, + const Standard_Integer theDegMax) +{ + myDegMin = theDegMin; + myDegMax = theDegMax; +} +//======================================================================= +//function : SetMaxSegments +//purpose : +//======================================================================= +void ProjLib_ProjectedCurve::SetMaxSegments(const Standard_Integer theMaxSegments) +{ + myMaxSegments = theMaxSegments; +} + +//======================================================================= +//function : SetBndPnt +//purpose : +//======================================================================= +void ProjLib_ProjectedCurve::SetBndPnt(const AppParCurves_Constraint theBndPnt) +{ + myBndPnt = theBndPnt; +} + +//======================================================================= +//function : SetMaxDist +//purpose : +//======================================================================= +void ProjLib_ProjectedCurve::SetMaxDist(const Standard_Real theMaxDist) +{ + myMaxDist = theMaxDist; +} //======================================================================= //function : GetSurface diff --git a/src/ProjLib/ProjLib_ProjectedCurve.hxx b/src/ProjLib/ProjLib_ProjectedCurve.hxx index 0e3196d430..c788587cd3 100644 --- a/src/ProjLib/ProjLib_ProjectedCurve.hxx +++ b/src/ProjLib/ProjLib_ProjectedCurve.hxx @@ -29,6 +29,7 @@ #include #include #include +#include class Adaptor3d_HSurface; class Adaptor3d_HCurve; class Standard_OutOfRange; @@ -49,20 +50,32 @@ class Geom2d_BSplineCurve; //! Compute the 2d-curve. Try to solve the particular //! case if possible. Otherwize, an approximation is -//! done. +//! done. For approximation some parameters are used, including +//! required tolerance of approximation. +//! Tolerance is maximal possible value of 3d deviation of 3d projection of projected curve from +//! "exact" 3d projection. Since algorithm searches 2d curve on surface, required 2d tolerance is computed +//! from 3d tolerance with help of U,V resolutions of surface. +//! 3d and 2d tolerances have sence only for curves on surface, it defines precision of projecting and approximation +//! and have nothing to do with distance between the projected curve and the surface. class ProjLib_ProjectedCurve : public Adaptor2d_Curve2d { public: DEFINE_STANDARD_ALLOC - + //! Empty constructor, it only sets some initial values for class fields. Standard_EXPORT ProjLib_ProjectedCurve(); + //! Constructor with initialisation field mySurface Standard_EXPORT ProjLib_ProjectedCurve(const Handle(Adaptor3d_HSurface)& S); - + + //! Constructor, which performs projecting. + //! If projecting uses approximation, default parameters are used, in particular, 3d tolerance of approximation + //! is Precision::Confusion() Standard_EXPORT ProjLib_ProjectedCurve(const Handle(Adaptor3d_HSurface)& S, const Handle(Adaptor3d_HCurve)& C); + //! Constructor, which performs projecting. + //! If projecting uses approximation, 3d tolerance is Tol, default parameters are used, Standard_EXPORT ProjLib_ProjectedCurve(const Handle(Adaptor3d_HSurface)& S, const Handle(Adaptor3d_HCurve)& C, const Standard_Real Tol); //! Changes the tolerance used to project @@ -72,9 +85,33 @@ public: //! Changes the Surface. Standard_EXPORT void Load (const Handle(Adaptor3d_HSurface)& S); - //! Changes the Curve. - Standard_EXPORT void Load (const Handle(Adaptor3d_HCurve)& C); + //! Performs projecting for given curve. + //! If projecting uses approximation, + //! approximation parameters can be set before by corresponding methods + //! SetDegree(...), SetMaxSegmets(...), SetBndPnt(...), SetMaxDist(...) + Standard_EXPORT void Perform (const Handle(Adaptor3d_HCurve)& C); + //! Set min and max possible degree of result BSpline curve2d, which is got by approximation. + //! If theDegMin/Max < 0, algorithm uses values that are chosen depending of types curve 3d + //! and surface. + Standard_EXPORT void SetDegree(const Standard_Integer theDegMin, const Standard_Integer theDegMax); + + //! Set the parameter, which defines maximal value of parametric intervals the projected + //! curve can be cut for approximation. If theMaxSegments < 0, algorithm uses default + //! value = 1000. + Standard_EXPORT void SetMaxSegments(const Standard_Integer theMaxSegments); + + //! Set the parameter, which defines type of boundary condition between segments during approximation. + //! It can be AppParCurves_PassPoint or AppParCurves_TangencyPoint. + //! Default value is AppParCurves_TangencyPoint; + Standard_EXPORT void SetBndPnt(const AppParCurves_Constraint theBndPnt); + + //! Set the parameter, which degines maximal possible distance between projected curve and surface. + //! It uses only for projecting on not analytical surfaces. + //! If theMaxDist < 0, algoritm uses default value 100.*Tolerance. + //! If real distance between curve and surface more then theMaxDist, algorithm stops working. + Standard_EXPORT void SetMaxDist(const Standard_Real theMaxDist); + Standard_EXPORT const Handle(Adaptor3d_HSurface)& GetSurface() const; Standard_EXPORT const Handle(Adaptor3d_HCurve)& GetCurve() const; @@ -203,8 +240,11 @@ private: Handle(Adaptor3d_HSurface) mySurface; Handle(Adaptor3d_HCurve) myCurve; ProjLib_Projector myResult; - - + Standard_Integer myDegMin; + Standard_Integer myDegMax; + Standard_Integer myMaxSegments; + Standard_Real myMaxDist; + AppParCurves_Constraint myBndPnt; }; diff --git a/tests/bugs/modalg_6/bug26130 b/tests/bugs/modalg_6/bug26130 index e2ff8b4da7..ade41c53bf 100644 --- a/tests/bugs/modalg_6/bug26130 +++ b/tests/bugs/modalg_6/bug26130 @@ -1,4 +1,3 @@ -puts "TODO OCC26130 ALL: Standard_ConstructionError" puts "==========" puts "OCC26130" puts "==========" diff --git a/tests/bugs/modalg_7/bug28909 b/tests/bugs/modalg_7/bug28909 new file mode 100644 index 0000000000..c0a3d9d453 --- /dev/null +++ b/tests/bugs/modalg_7/bug28909 @@ -0,0 +1,23 @@ +puts "=======" +puts "OCC28909" +puts "=======" +puts "" +################################################## +# Algorithm of BO is stuck while fusing shell and edges +################################################## + +restore [locate_data_file bug28909_shell.brep] ss +restore [locate_data_file bug28909_edges.brep] edges + +bclearobjects +bcleartools +baddobjects ss +baddcompound edges +#Algorithm gets stuck in command bfillds +bfillds +bbuild result + +checkshape result +checknbshapes result -edge 28 -face 6 +checkprops result -l 13568.8 + diff --git a/tests/de/step_4/D9 b/tests/de/step_4/D9 index b5f9c05841..cde37af173 100644 --- a/tests/de/step_4/D9 +++ b/tests/de/step_4/D9 @@ -10,7 +10,7 @@ TPSTAT : Faulties = 0 ( 0 ) Warnings = 308 ( 115 ) Summary = 308 ( 11 CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) NBSHAPES : Solid = 1 ( 1 ) Shell = 1 ( 1 ) Face = 742 ( 742 ) Summary = 5060 ( 5060 ) STATSHAPE : Solid = 1 ( 1 ) Shell = 1 ( 1 ) Face = 742 ( 742 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 2108 ( 2108 ) -TOLERANCE : MaxTol = 0.008481946718 ( 0.01167681549 ) AvgTol = 0.0001367132065 ( 0.0002869491135 ) +TOLERANCE : MaxTol = 0.008481946718 ( 0.01609778278 ) AvgTol = 0.0001367132065 ( 0.0002869491135 ) LABELS : N0Labels = 1 ( 1 ) N1Labels = 0 ( 0 ) N2Labels = 0 ( 0 ) TotalLabels = 1 ( 1 ) NameLabels = 1 ( 1 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) NCOLORS : NColors = 0 ( 0 ) diff --git a/tests/de/step_4/E1 b/tests/de/step_4/E1 index a6476b3cd4..8bdba3b427 100644 --- a/tests/de/step_4/E1 +++ b/tests/de/step_4/E1 @@ -9,7 +9,7 @@ TPSTAT : Faulties = 0 ( 0 ) Warnings = 317 ( 158 ) Summary = 317 ( 15 CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) NBSHAPES : Solid = 1 ( 1 ) Shell = 1 ( 1 ) Face = 956 ( 956 ) Summary = 6474 ( 6474 ) STATSHAPE : Solid = 1 ( 1 ) Shell = 1 ( 1 ) Face = 956 ( 956 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 2681 ( 2681 ) -TOLERANCE : MaxTol = 0.008481946718 ( 0.01167681549 ) AvgTol = 0.0001210014254 ( 0.0003580069299 ) +TOLERANCE : MaxTol = 0.008481946718 ( 0.01609778278 ) AvgTol = 0.0001210014254 ( 0.0003580069299 ) LABELS : N0Labels = 1 ( 1 ) N1Labels = 0 ( 0 ) N2Labels = 0 ( 0 ) TotalLabels = 1 ( 1 ) NameLabels = 1 ( 1 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) NCOLORS : NColors = 0 ( 0 )