0028909: Algorithm of BO is stuck while fusing shell and edges
authorifv <ifv@opencascade.com>
Tue, 11 Jul 2017 07:15:28 +0000 (10:15 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 6 Oct 2017 07:28:17 +0000 (10:28 +0300)
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

17 files changed:
src/Approx/Approx_ComputeCLine.gxx
src/Approx/Approx_FitAndDivide.hxx
src/Approx/Approx_FitAndDivide2d.hxx
src/BOPTools/BOPTools_AlgoTools2D.cxx
src/BRepFill/BRepFill_ComputeCLine.hxx
src/ProjLib/ProjLib.cxx
src/ProjLib/ProjLib.hxx
src/ProjLib/ProjLib_ComputeApprox.cxx
src/ProjLib/ProjLib_ComputeApprox.hxx
src/ProjLib/ProjLib_ComputeApproxOnPolarSurface.cxx
src/ProjLib/ProjLib_ComputeApproxOnPolarSurface.hxx
src/ProjLib/ProjLib_ProjectedCurve.cxx
src/ProjLib/ProjLib_ProjectedCurve.hxx
tests/bugs/modalg_6/bug26130
tests/bugs/modalg_7/bug28909 [new file with mode: 0644]
tests/de/step_4/D9
tests/de/step_4/E1

index f2fc63c..9e21aad 100644 (file)
@@ -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,
index 81a5565..f33f83e 100644 (file)
@@ -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;
 
 
 };
index 646f45a..829bd82 100644 (file)
@@ -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;
 
 
 };
index 9697b92..20efb35 100644 (file)
@@ -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())
index 2b43800..5391c41 100644 (file)
@@ -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;
 
 };
 
index c9f380b..36ee34d 100644 (file)
@@ -48,6 +48,7 @@
 #include <Geom2d_BSplineCurve.hxx>
 #include <Geom2d_BezierCurve.hxx>
 #include <Standard_NotImplemented.hxx>
+#include <Adaptor3d_HSurface.hxx>
 
 //=======================================================================
 //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;
+  }
+}
index b5fa7ac..f533479 100644 (file)
@@ -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 <aC> of relevant to <PC> 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);
+
 
 
 
index 9fc50d3..5090998 100644 (file)
@@ -17,6 +17,7 @@
 // modified by NIZHNY-OFV  Thu Jan 20 11:04:19 2005
 
 #include <ProjLib_ComputeApprox.hxx>
+#include <ProjLib.hxx>
 
 #include <GeomAbs_SurfaceType.hxx>
 #include <GeomAbs_CurveType.hxx>
@@ -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
index 6bb6d54..c1aeda6 100644 (file)
@@ -22,6 +22,8 @@
 #include <Standard_Handle.hxx>
 
 #include <Standard_Real.hxx>
+#include <AppParCurves_Constraint.hxx>
+
 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();
+   
   //! <Tol>    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;
 
 };
 
index 82f567c..14185a3 100644 (file)
@@ -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;
+}
+
index 4e116eb..3927f27 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <Standard_Boolean.hxx>
 #include <Standard_Real.hxx>
+#include <AppParCurves_Constraint.hxx>
 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;
 
 
 };
index 03ac507..656e99b 100644 (file)
 #include <GeomLib.hxx>
 #include <Extrema_ExtPC.hxx>
 #include <NCollection_DataMap.hxx>
+//=======================================================================
+//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
index 0e3196d..c788587 100644 (file)
@@ -29,6 +29,7 @@
 #include <TColStd_Array1OfReal.hxx>
 #include <Standard_Boolean.hxx>
 #include <GeomAbs_CurveType.hxx>
+#include <AppParCurves_Constraint.hxx>
 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;
 };
 
 
index e2ff8b4..ade41c5 100644 (file)
@@ -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 (file)
index 0000000..c0a3d9d
--- /dev/null
@@ -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
+
index b5f9c05..cde37af 100644 (file)
@@ -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 )
index a6476b3..8bdba3b 100644 (file)
@@ -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 )