From bae1df0463cc8367ae837fd44ee20b5db6bc4f7d Mon Sep 17 00:00:00 2001
From: asuraven <asuraven@opencascade.com>
Date: Wed, 28 Apr 2021 12:06:39 +0300
Subject: [PATCH] 0029059: It is necessary to have a unique way of checking of
 the validity of the edge and its 2D curves

Add new class BRepLib_ValidateEdge to edge checking to use instead function:
- Validate() from BOPTools_AlgoTools.cxx
- Validate() from BRepCheck_Edge.cxx
- ShapeAnalysis_Edge::ComputeDeviation()
Also BRepLib_ValidateEdge provides exact validating (as option) using GeomLib_CheckCurveOnSurface class
Perform(const Standard_Boolean isTheMultyTheradDisabled = Standard_False) parameter changed for better understanding to (const Standard_Boolean isMultyThread = Standard_True) in BRepLib_CheckCurveOnSurface & GeomLib_CheckCurveOnSurface classes
Interfaces of BRepLib_CheckCurveOnSurface & GeomLib_CheckCurveOnSurface classes changed from geometry to adaptors
---
 src/BOPTools/BOPTools_AlgoTools_1.cxx       | 169 +++----------
 src/BRepCheck/BRepCheck_Edge.cxx            | 208 ++--------------
 src/BRepFill/BRepFill_AdvancedEvolved.cxx   |   3 +-
 src/BRepLib/BRepLib_CheckCurveOnSurface.cxx |  63 +++--
 src/BRepLib/BRepLib_CheckCurveOnSurface.hxx |  53 +----
 src/BRepLib/BRepLib_ValidateEdge.cxx        | 248 ++++++++++++++++++++
 src/BRepLib/BRepLib_ValidateEdge.hxx        |  98 ++++++++
 src/BRepLib/FILES                           |   2 +
 src/BRepOffset/BRepOffset_SimpleOffset.cxx  |  18 +-
 src/BRepTools/BRepTools.cxx                 |  13 +-
 src/GeomLib/GeomLib_CheckCurveOnSurface.cxx | 128 +++-------
 src/GeomLib/GeomLib_CheckCurveOnSurface.hxx |  47 +---
 src/IntTools/IntTools_Tools.cxx             |  13 +-
 src/ShapeAnalysis/ShapeAnalysis_Edge.cxx    |  88 ++-----
 src/ShapeAnalysis/ShapeAnalysis_Edge.hxx    |   7 -
 15 files changed, 544 insertions(+), 614 deletions(-)
 create mode 100644 src/BRepLib/BRepLib_ValidateEdge.cxx
 create mode 100644 src/BRepLib/BRepLib_ValidateEdge.hxx

diff --git a/src/BOPTools/BOPTools_AlgoTools_1.cxx b/src/BOPTools/BOPTools_AlgoTools_1.cxx
index d020740e1f..97ae92e5ee 100644
--- a/src/BOPTools/BOPTools_AlgoTools_1.cxx
+++ b/src/BOPTools/BOPTools_AlgoTools_1.cxx
@@ -19,6 +19,7 @@
 #include <BRep_Builder.hxx>
 #include <BRep_CurveRepresentation.hxx>
 #include <BRep_GCurve.hxx>
+#include <BRepLib.hxx>
 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
 #include <BRep_PointRepresentation.hxx>
@@ -29,6 +30,7 @@
 #include <BRepAdaptor_Surface.hxx>
 #include <BRepAdaptor_Curve.hxx>
 #include <BRepLib_CheckCurveOnSurface.hxx>
+#include <BRepLib_ValidateEdge.hxx>
 #include <BRepTools_WireExplorer.hxx>
 #include <Extrema_LocateExtPC.hxx>
 #include <Geom2d_Curve.hxx>
@@ -82,12 +84,6 @@ static
                              const TopoDS_Face& S,
                              const Standard_Real aMaxTol,
                              const TopTools_IndexedMapOfShape& aMapToAvoid);
-static 
-  Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
-                            const Adaptor3d_Curve& Other,
-                            const Standard_Real Tol,
-                            const Standard_Boolean SameParameter,
-                            Standard_Real& aNewTolerance);
 
 static
   void CorrectVertexTolerance(const TopoDS_Edge& aE,
@@ -808,17 +804,15 @@ void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
   {
     if (myCref.IsNull()) 
       return;
-    Standard_Boolean ok = Standard_True;
 
     Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape());
     Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Edge(myShape));
-    Standard_Real aNewTol=Tol;
+    Standard_Real aNewTolerance = Tol;
 
     Standard_Boolean SameParameter = TE->SameParameter();
     Standard_Boolean SameRange = TE->SameRange();
     Standard_Real First = myHCurve->FirstParameter();
     Standard_Real Last  = myHCurve->LastParameter();
-    Standard_Real Delta = BOPTools_AlgoTools::DTolerance();
 
     Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape());
     const TopLoc_Location& Floc = S.Location();
@@ -847,23 +841,30 @@ void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
           new GeomAdaptor_Surface(Sb);
         Handle(Geom2dAdaptor_Curve) GHPC = 
           new Geom2dAdaptor_Curve(PC,f,l);
-        Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
-        ok = Validate (*myHCurve, ACS,  Tol, SameParameter, aNewTol);
-        if (ok) {
-          if (aNewTol<aMaxTol) {
-            UpdateShape(myShape, aNewTol+Delta, aMapToAvoid);
+        Handle(Adaptor3d_CurveOnSurface) ACS = new Adaptor3d_CurveOnSurface(GHPC,GAHS);
+
+        BRepLib_ValidateEdge aValidateEdge(myHCurve, ACS, SameParameter);
+        aValidateEdge.Process();
+        aValidateEdge.UpdateTolerance(aNewTolerance);
+        if (aValidateEdge.IsDone() && !aValidateEdge.CheckTolerance(Tol))
+        {
+          if (aNewTolerance<aMaxTol) {
+            UpdateShape(myShape, aNewTolerance, aMapToAvoid);
             CorrectVertexTolerance(myShape, aMapToAvoid);
           }
         }
         
         if (cr->IsCurveOnClosedSurface()) {
-          //checkclosed = Standard_True;
           GHPC->Load(cr->PCurve2(),f,l); // same bounds
-          ACS.Load(GHPC, GAHS); // sans doute inutile
-          ok = Validate (*myHCurve, ACS, Tol, SameParameter, aNewTol);
-          if (ok) {
-            if (aNewTol<aMaxTol) {
-              UpdateShape(myShape, aNewTol+Delta, aMapToAvoid);
+          ACS->Load(GHPC, GAHS); // sans doute inutile
+
+          BRepLib_ValidateEdge aValidateEdgeOnClosedSurf(myHCurve, ACS, SameParameter);
+          aValidateEdgeOnClosedSurf.Process();
+          aValidateEdgeOnClosedSurf.UpdateTolerance(aNewTolerance);
+          if (aValidateEdgeOnClosedSurf.IsDone() && !aValidateEdgeOnClosedSurf.CheckTolerance(Tol))
+          {
+            if (aNewTolerance<aMaxTol) {
+              UpdateShape(myShape, aNewTolerance, aMapToAvoid);
               CorrectVertexTolerance(myShape, aMapToAvoid);
             } 
           }
@@ -912,13 +913,15 @@ void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
                                    myHCurve->FirstParameter(), 
                                    myHCurve->LastParameter());
         
-        Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
+        Handle(Adaptor3d_CurveOnSurface) ACS = new Adaptor3d_CurveOnSurface(GHPC,GAHS);
         
-        Standard_Boolean okx = Validate(*myHCurve, ACS,
-                                        Tol,Standard_True, aNewTol); 
-        if (okx) {
-          if (aNewTol<aMaxTol) {
-            UpdateShape(myShape, aNewTol+Delta, aMapToAvoid);
+        BRepLib_ValidateEdge aValidateProjEdge(myHCurve, ACS, Standard_True);
+        aValidateProjEdge.Process();
+        aValidateProjEdge.UpdateTolerance(aNewTolerance);
+        if (aValidateProjEdge.IsDone() && !aValidateProjEdge.CheckTolerance(Tol))
+        {
+          if (aNewTolerance<aMaxTol) {
+            UpdateShape(myShape, aNewTolerance, aMapToAvoid);
             CorrectVertexTolerance(myShape, aMapToAvoid);
           }
         }
@@ -947,120 +950,6 @@ void CorrectVertexTolerance(const TopoDS_Edge& aE,
   }
 }
 //=======================================================================
-//function : Validate
-//purpose  : 
-//=======================================================================
-Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
-                          const Adaptor3d_Curve& Other,
-                          const Standard_Real Tol,
-                          const Standard_Boolean SameParameter,
-                          Standard_Real& aNewTolerance)
-{
-  Standard_Real First, Last, MaxDistance, aD, Tol2;
-
-  First = CRef.FirstParameter();
-  Last  = CRef.LastParameter();
-  MaxDistance = 0.;
-  Tol2 = Tol*Tol;
-  //
-  Standard_Integer NCONTROL=23;
-  Standard_Integer i, aNC1=NCONTROL-1;
-
-  Standard_Boolean aFlag=Standard_False;
-  Standard_Boolean proj = (!SameParameter || 
-                           First != Other.FirstParameter() ||
-                           Last  != Other.LastParameter());
-  //
-  // 1. 
-  if (!proj) {
-    for (i = 0; i < NCONTROL; i++) {
-      Standard_Real prm = ((aNC1-i)*First + i*Last)/aNC1;
-      gp_Pnt pref   = CRef.Value(prm);
-      gp_Pnt pother = Other.Value(prm);
-      
-      aD=pref.SquareDistance(pother);
-
-      if (aD > Tol2) {
-        if (aD>MaxDistance) {
-          MaxDistance=aD;
-        }
-        aFlag=Standard_True;
-      }
-    }
-
-    if (aFlag) {
-      aNewTolerance=sqrt(MaxDistance);
-    }
-    return aFlag;
-  }
-  
-  //
-  // 2.
-  else {
-    Extrema_LocateExtPC refd,otherd;
-    Standard_Real OFirst, OLast;
-    OFirst = Other.FirstParameter();
-    OLast  = Other.LastParameter();
-    
-    gp_Pnt pd  = CRef.Value(First);
-    gp_Pnt pdo = Other.Value(OFirst);
-    
-    aD = pd.SquareDistance(pdo);
-    if (aD > Tol2) {
-      if (aD>MaxDistance) {
-        MaxDistance=aD;
-      }
-      aFlag=Standard_True;
-    }
-
-    pd  = CRef.Value(Last);
-    pdo = Other.Value(OLast);
-    aD = pd.SquareDistance(pdo);
-    if (aD > Tol2 && aD > MaxDistance) {
-      MaxDistance=aD;
-      aFlag=Standard_True;
-    }
-
-    refd.Initialize(CRef, First, Last, CRef.Resolution(Tol));
-    otherd.Initialize(Other, OFirst, OLast, Other.Resolution(Tol));
-    
-    for (i = 2; i< aNC1; i++) {
-      Standard_Real rprm = ((aNC1-i)*First + i*Last)/aNC1;
-      gp_Pnt pref = CRef.Value(rprm);
-
-      Standard_Real oprm = ((aNC1-i)*OFirst + i*OLast)/aNC1;
-      gp_Pnt pother = Other.Value(oprm);
-
-      refd.Perform(pother,rprm);
-      if (!refd.IsDone() || refd.SquareDistance() > Tol2) {
-        if (refd.IsDone()) {
-          aD=refd.SquareDistance();
-          if (aD > Tol2 && aD>MaxDistance) {
-            aFlag=Standard_True;
-            MaxDistance=aD;
-          }
-        }
-      }
-
-      otherd.Perform(pref,oprm);
-      if (!otherd.IsDone() || otherd.SquareDistance() > Tol2) {
-        
-        if (otherd.IsDone()) {
-          aD=otherd.SquareDistance();
-          if (aD > Tol2 && aD>MaxDistance) {
-            aFlag=Standard_True;
-            MaxDistance=aD;
-          }
-        }
-      }
-    }
-  }
-  
-  aD=sqrt (MaxDistance);
-  aNewTolerance=aD;
-  return aFlag;
-}
-//=======================================================================
 // Function : UpdateEdges
 // purpose : 
 //=======================================================================
diff --git a/src/BRepCheck/BRepCheck_Edge.cxx b/src/BRepCheck/BRepCheck_Edge.cxx
index 72c322ab88..4b263da371 100644
--- a/src/BRepCheck/BRepCheck_Edge.cxx
+++ b/src/BRepCheck/BRepCheck_Edge.cxx
@@ -22,6 +22,8 @@
 #include <BRep_CurveOnSurface.hxx>
 #include <BRep_CurveRepresentation.hxx>
 #include <BRep_GCurve.hxx>
+#include <BRepLib.hxx>
+#include <BRepLib_ValidateEdge.hxx>
 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
 #include <BRep_ListOfCurveRepresentation.hxx>
 #include <BRep_PolygonOnTriangulation.hxx>
@@ -63,27 +65,6 @@
 
 IMPLEMENT_STANDARD_RTTIEXT(BRepCheck_Edge,BRepCheck_Result)
 
-//modified by NIZNHY-PKV Thu May 05 09:01:57 2011f
-static 
-  Standard_Boolean Validate(const Adaptor3d_Curve&,
-  const Adaptor3d_CurveOnSurface&,
-  const Standard_Real,
-  const Standard_Boolean);
-static
-  void PrintProblematicPoint(const gp_Pnt&,
-  const Standard_Real,
-  const Standard_Real);
-
-static
-  Standard_Real Prec(const Adaptor3d_Curve& aAC3D,
-  const Adaptor3d_CurveOnSurface& aACS);
-
-//static Standard_Boolean Validate(const Adaptor3d_Curve&,
-//				 const Adaptor3d_Curve&,
-//				 const Standard_Real,
-//				 const Standard_Boolean);
-//modified by NIZNHY-PKV Thu May 05 09:02:01 2011t
-
 static const Standard_Integer NCONTROL=23;
 
 //=======================================================================
@@ -310,7 +291,6 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S)
 
   case TopAbs_FACE:
     if (!myCref.IsNull()) {
-
       Standard_Boolean SameParameter = TE->SameParameter();
       Standard_Boolean SameRange = TE->SameRange();
       //  Modified by skv - Tue Apr 27 11:48:13 2004 Begin
@@ -397,9 +377,13 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S)
             Handle(Geom2d_Curve) PC = cr->PCurve();
             Handle(GeomAdaptor_Surface) GAHS = new GeomAdaptor_Surface(Sb);
             Handle(Geom2dAdaptor_Curve) GHPC = new Geom2dAdaptor_Curve(PC,f,l);
-            Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
-            Standard_Boolean ok = Validate (*myHCurve, ACS, Tol, SameParameter);
-            if (!ok) {
+            Handle(Adaptor3d_CurveOnSurface) ACS = new Adaptor3d_CurveOnSurface(GHPC,GAHS);
+
+            BRepLib_ValidateEdge aValidateEdge(myHCurve, ACS, SameParameter);
+            aValidateEdge.SetExitIfToleranceExceeded(Tol);
+            aValidateEdge.Process();
+            if (!aValidateEdge.IsDone() || !aValidateEdge.CheckTolerance(Tol))
+            {
               if (cr->IsCurveOnClosedSurface()) {
                 BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface);
               }
@@ -415,9 +399,13 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S)
             }
             if (cr->IsCurveOnClosedSurface()) {
               GHPC->Load(cr->PCurve2(),f,l); // same bounds
-              ACS.Load(GHPC, GAHS); // sans doute inutile
-              ok = Validate(*myHCurve,ACS,Tol,SameParameter);
-              if (!ok) {
+              ACS->Load(GHPC, GAHS); // sans doute inutile
+
+              BRepLib_ValidateEdge aValidateEdgeOnClosedSurf(myHCurve, ACS, SameParameter);
+              aValidateEdgeOnClosedSurf.SetExitIfToleranceExceeded(Tol);
+              aValidateEdgeOnClosedSurf.Process();
+              if (!aValidateEdgeOnClosedSurf.IsDone() || !aValidateEdgeOnClosedSurf.CheckTolerance(Tol))
+              {
                 BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface);
                 //  Modified by skv - Tue Apr 27 11:53:20 2004 Begin
                 if (SameParameter) {
@@ -470,10 +458,13 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S)
               myHCurve->FirstParameter(),
               myHCurve->LastParameter());
 
-            Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
+            Handle(Adaptor3d_CurveOnSurface) ACS = new Adaptor3d_CurveOnSurface(GHPC,GAHS);
 
-            Standard_Boolean ok = Validate (*myHCurve, ACS, Tol,Standard_True); // voir dub...
-            if (!ok) {
+            BRepLib_ValidateEdge aValidateEdgeProj(myHCurve, ACS, SameParameter);
+            aValidateEdgeProj.SetExitIfToleranceExceeded(Tol);
+            aValidateEdgeProj.Process();
+            if (!aValidateEdgeProj.IsDone() || !aValidateEdgeProj.CheckTolerance(Tol))
+            {
               BRepCheck::Add(lst,BRepCheck_InvalidCurveOnSurface);
             }
           }
@@ -778,158 +769,3 @@ BRepCheck_Status BRepCheck_Edge::
   return BRepCheck_NoError;
 }
 
-//=======================================================================
-//function : Validate
-//purpose  : 
-//=======================================================================
-Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
-  const Adaptor3d_CurveOnSurface& Other,
-  const Standard_Real Tol,
-  const Standard_Boolean SameParameter)
-{
-  Standard_Boolean  Status, proj; 
-  Standard_Real aPC, First, Last, Error;
-  gp_Pnt  problematic_point ;
-  //
-  Status = Standard_True;
-  Error = 0.;
-  First = CRef.FirstParameter();
-  Last  = CRef.LastParameter();
-
-  aPC=Precision::PConfusion();
-  proj = (!SameParameter || 
-    Abs(Other.FirstParameter()-First) > aPC || 
-    Abs( Other.LastParameter()-Last) > aPC);
-  if (!proj)
-  {
-    Standard_Integer i;
-    Standard_Real Tol2, prm, dD;
-    gp_Pnt pref, pother;
-    //modified by NIZNHY-PKV Thu May 05 09:06:41 2011f
-    //OCC22428
-    dD=Prec(CRef, Other);//3.e-15;
-    Tol2=Tol+dD;
-    Tol2=Tol2*Tol2;
-    //Tol2=Tol*Tol;
-    //modified by NIZNHY-PKV Thu May 05 09:06:47 2011t
-
-    for (i = 0; i < NCONTROL; ++i) {
-      prm = ((NCONTROL-1-i)*First + i*Last)/(NCONTROL-1);
-      pref = CRef.Value(prm);
-      pother = Other.Value(prm);
-      if (pref.SquareDistance(pother) > Tol2) {
-        problematic_point = pref ;
-        Status = Standard_False;
-        Error  = pref.Distance(pother);
-        PrintProblematicPoint(problematic_point, Error, Tol);
-        return Status;
-        //goto FINISH ;
-      }
-    }
-  }
-  else {
-    Extrema_LocateExtPC refd,otherd;
-    Standard_Real OFirst = Other.FirstParameter();
-    Standard_Real OLast  = Other.LastParameter();
-    gp_Pnt pd = CRef.Value(First);
-    gp_Pnt pdo = Other.Value(OFirst);
-    Standard_Real distt = pd.SquareDistance(pdo);
-    if (distt > Tol*Tol) {
-      problematic_point = pd ;
-      Status = Standard_False ;
-      Error = Sqrt(distt);
-      PrintProblematicPoint(problematic_point, Error, Tol);
-      return Status;
-      //goto FINISH ;
-    }
-    pd = CRef.Value(Last);
-    pdo = Other.Value(OLast);
-    distt = pd.SquareDistance(pdo);
-    if (distt > Tol*Tol) {
-      problematic_point = pd ;
-      Status = Standard_False ;
-      Error = Sqrt(distt);
-      PrintProblematicPoint(problematic_point, Error, Tol);
-      return Status;
-      //goto FINISH ;
-    }
-
-    refd.Initialize(CRef,First,Last,CRef.Resolution(Tol));
-    otherd.Initialize(Other,OFirst,OLast,Other.Resolution(Tol));
-    for (Standard_Integer i = 2; i< NCONTROL-1; i++) {
-      Standard_Real rprm = ((NCONTROL-1-i)*First + i*Last)/(NCONTROL-1);
-      gp_Pnt pref = CRef.Value(rprm);
-      Standard_Real oprm = ((NCONTROL-1-i)*OFirst + i*OLast)/(NCONTROL-1);
-      gp_Pnt pother = Other.Value(oprm);
-      refd.Perform(pother,rprm);
-      if (!refd.IsDone() || refd.SquareDistance() > Tol * Tol) {
-        problematic_point = pref ;
-        Status = Standard_False ;
-        if (refd.IsDone()) {
-          Error = sqrt (refd.SquareDistance());
-        }
-        else {
-          Error = RealLast();
-        }
-        PrintProblematicPoint(problematic_point, Error, Tol);
-        return Status;
-        //goto FINISH ;
-      }
-      otherd.Perform(pref,oprm);
-      if (!otherd.IsDone() || otherd.SquareDistance() > Tol * Tol) {
-        problematic_point = pref ;
-        Status = Standard_False ;
-        if (otherd.IsDone()) {
-          Error = sqrt (otherd.SquareDistance());
-        }
-        else {
-          Error = RealLast();
-        }
-        PrintProblematicPoint(problematic_point, Error, Tol);
-        return Status;
-        //goto FINISH ;
-      }
-    }
-  }
-
-  return Status ;
-
-}
-
-//=======================================================================
-//function : Prec
-//purpose  : 
-//=======================================================================
-Standard_Real Prec(const Adaptor3d_Curve& aAC3D,
-                   const Adaptor3d_CurveOnSurface& aACS)
-{
-  Standard_Real aXEmax, aXC, aXS;
-  const Handle(Adaptor3d_Surface)& aAHS = aACS.GetSurface();
-  //
-  aXC = BRepCheck::PrecCurve(aAC3D);
-  aXS = BRepCheck::PrecSurface(aAHS);
-  aXEmax = (aXC>aXS) ? aXC: aXS;
-  return aXEmax;
-}
-
-//=======================================================================
-//function : PrintProblematicPoint
-//purpose  : 
-//=======================================================================
-#ifdef OCCT_DEBUG
-void PrintProblematicPoint(const gp_Pnt& problematic_point,
-  const Standard_Real Error,
-  const Standard_Real Tol)
-{
-  std::cout << " **** probleme de SameParameter au point :" << std::endl;
-  std::cout << "         " << problematic_point.Coord(1) << " " 
-    << problematic_point.Coord(2) << " " << problematic_point.Coord(3) << std::endl ;
-  std::cout << "   Erreur detectee :" << Error << " Tolerance :" << Tol << std::endl;
-}
-#else
-void PrintProblematicPoint(const gp_Pnt&,
-  const Standard_Real,
-  const Standard_Real)
-{
-}
-#endif
diff --git a/src/BRepFill/BRepFill_AdvancedEvolved.cxx b/src/BRepFill/BRepFill_AdvancedEvolved.cxx
index b5eb9b8fa2..70f4b2bb16 100644
--- a/src/BRepFill/BRepFill_AdvancedEvolved.cxx
+++ b/src/BRepFill/BRepFill_AdvancedEvolved.cxx
@@ -2007,7 +2007,8 @@ void ProcessVertex(const TopoDS_Vertex& aV,
   }
   //
   // Update Tolerance
-  TV->Tolerance(aTolMax2);
+  // with a small margin
+  TV->Tolerance(aTolMax2 + aTolMax2 * 0.0001);
 }
 
 //=======================================================================
diff --git a/src/BRepLib/BRepLib_CheckCurveOnSurface.cxx b/src/BRepLib/BRepLib_CheckCurveOnSurface.cxx
index d14f2f17b4..87f3b8d35e 100644
--- a/src/BRepLib/BRepLib_CheckCurveOnSurface.cxx
+++ b/src/BRepLib/BRepLib_CheckCurveOnSurface.cxx
@@ -12,8 +12,13 @@
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <Adaptor3d_CurveOnSurface.hxx>
 #include <BRep_Tool.hxx>
+#include <BRepAdaptor_Curve.hxx>
 #include <BRepLib_CheckCurveOnSurface.hxx>
+#include <GeomAdaptor_Surface.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <Geom2dAdaptor_Curve.hxx>
 #include <Geom_Surface.hxx>
 #include <Standard_ErrorHandler.hxx>
 #include <TopoDS.hxx>
@@ -36,9 +41,7 @@ BRepLib_CheckCurveOnSurface::BRepLib_CheckCurveOnSurface
 //function : Init
 //purpose  : 
 //=======================================================================
-void BRepLib_CheckCurveOnSurface::Init
-  (const TopoDS_Edge& theEdge,
-   const TopoDS_Face& theFace)
+void BRepLib_CheckCurveOnSurface::Init(const TopoDS_Edge& theEdge, const TopoDS_Face& theFace)
 {
   myCOnSurfGeom.Init();
 
@@ -53,46 +56,54 @@ void BRepLib_CheckCurveOnSurface::Init
     return;
   }
   
-  //
-  TopLoc_Location aLocE, aLocF, aLocC2D;
-  Standard_Real aFirst = 0.0, aLast = 0.0;
-  //
   // 3D curve initialization
-  const Handle(Geom_Curve)& aC3dTmp = BRep_Tool::Curve(theEdge, aLocE, aFirst, aLast);
-  const Handle(Geom_Curve) aC3d(Handle(Geom_Curve)::DownCast(aC3dTmp->Transformed(aLocE.Transformation())));
+  const Handle(Adaptor3d_Curve) anAdaptor3dCurve = new BRepAdaptor_Curve(theEdge);
 
   // Surface initialization
-  const Handle(Geom_Surface)& aSTmp = BRep_Tool::Surface(theFace, aLocF);
-  const Handle(Geom_Surface) aS(Handle(Geom_Surface)::DownCast(aSTmp->Transformed(aLocF.Transformation())));
-  //
-  // 2D curves initialization 
-  myPCurve = BRep_Tool::CurveOnSurface(theEdge, theFace, aFirst, aLast);
 
-  if(BRep_Tool::IsClosed(theEdge, theFace))
-    myPCurve2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(theEdge.Reversed()),
-                                          theFace, aFirst, aLast);
+  TopLoc_Location aLocation;
+  Standard_Real aFirstParam, aLastParam;
+
+  Handle(Geom2d_Curve) aGeom2dCurve = BRep_Tool::CurveOnSurface(theEdge, theFace, aFirstParam, aLastParam);
+  Handle(Geom_Surface) aGeomSurface = BRep_Tool::Surface(theFace);
+
+  // 2D curves initialization
+  Handle(Adaptor2d_Curve2d) anAdaptorCurve = 
+    new Geom2dAdaptor_Curve(aGeom2dCurve, aFirstParam, aLastParam);
+  Handle(GeomAdaptor_Surface) aGeomAdaptorSurface = new GeomAdaptor_Surface(aGeomSurface);
+
+  myAdaptorCurveOnSurface = new Adaptor3d_CurveOnSurface(anAdaptorCurve, aGeomAdaptorSurface);
+
+  if (BRep_Tool::IsClosed(theEdge, theFace))
+  {
+    Handle(Geom2d_Curve) aGeom2dReversedCurve = 
+      BRep_Tool::CurveOnSurface(TopoDS::Edge(theEdge.Reversed()), theFace, aFirstParam, aLastParam);
+    Handle(Adaptor2d_Curve2d) anAdaptorReversedCurve =
+      new Geom2dAdaptor_Curve(aGeom2dReversedCurve, aFirstParam, aLastParam);
+     myAdaptorCurveOnSurface2 = new Adaptor3d_CurveOnSurface(anAdaptorReversedCurve, aGeomAdaptorSurface);
+  }
 
-  myCOnSurfGeom.Init(aC3d, aS, aFirst, aLast);
+  myCOnSurfGeom.Init(anAdaptor3dCurve);
 }
 
 //=======================================================================
 //function : Perform
 //purpose  : if isTheMTDisabled == TRUE parallelization is not used
 //=======================================================================
-void BRepLib_CheckCurveOnSurface::Perform(const Standard_Boolean isTheMTDisabled)
+void BRepLib_CheckCurveOnSurface::Perform(const Standard_Boolean isMultyThread)
 {
   // Compute the max distance
-  Compute(myPCurve, isTheMTDisabled);
+  Compute(myAdaptorCurveOnSurface, isMultyThread);
   if (ErrorStatus())
   {
     return;
   }
   //
-  if (!myPCurve2.IsNull())
+  if (!myAdaptorCurveOnSurface2.IsNull())
   {
-    // compute max distance for myPCurve2
+    // compute max distance for myAdaptorCurveOnSurface2
     // (for the second curve on closed surface)
-    Compute(myPCurve2, isTheMTDisabled);
+    Compute(myAdaptorCurveOnSurface2, isMultyThread);
   }
 }
 
@@ -100,8 +111,8 @@ void BRepLib_CheckCurveOnSurface::Perform(const Standard_Boolean isTheMTDisabled
 //function : Compute
 //purpose  : if isTheMTDisabled == TRUE parallelization is not used
 //=======================================================================
-void BRepLib_CheckCurveOnSurface::Compute(const Handle(Geom2d_Curve)& thePCurve,
-                                          const Standard_Boolean isTheMTDisabled)
+void BRepLib_CheckCurveOnSurface::Compute(const Handle(Adaptor3d_CurveOnSurface)& theCurveOnSurface,
+                                          const Standard_Boolean isMultyThread)
 {
-  myCOnSurfGeom.Perform(thePCurve, isTheMTDisabled);
+  myCOnSurfGeom.Perform(theCurveOnSurface, isMultyThread);
 }
diff --git a/src/BRepLib/BRepLib_CheckCurveOnSurface.hxx b/src/BRepLib/BRepLib_CheckCurveOnSurface.hxx
index 160ec35dd7..a53fd11e23 100644
--- a/src/BRepLib/BRepLib_CheckCurveOnSurface.hxx
+++ b/src/BRepLib/BRepLib_CheckCurveOnSurface.hxx
@@ -17,8 +17,8 @@
 
 #include <GeomLib_CheckCurveOnSurface.hxx>
 
-//! Computes the max distance between edge and its
-//! 2d representation on the face.
+//! Computes the max distance between edge and its 2d representation on the face.
+//! This class is not intended to process non-sameparameter edges.
 
 class BRepLib_CheckCurveOnSurface 
 {
@@ -37,41 +37,9 @@ public:
   Standard_EXPORT void Init (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace);
 
   //! Performs the calculation
-  //! If isTheMultyTheadDisabled == TRUE then computation will be made
-  //! without any parallelization.
-  Standard_EXPORT void Perform (const Standard_Boolean isTheMultyTheradDisabled = Standard_False);
-  
-  //! Returns source 3D-Curve
-  const Handle(Geom_Curve)& Curve() const
-  {
-    return myCOnSurfGeom.Curve();
-  }  
-
-  //! Returns mine 2D-Curve
-  const Handle(Geom2d_Curve)& PCurve() const
-  {
-    return myPCurve;
-  }
-  
-  //! Returns 2nd 2D-Curve (if it exists, e.g. for seam-edge)
-  const Handle(Geom2d_Curve)& PCurve2() const
-  {
-    return myPCurve2;
-  }
-  
-  //! Returns source surface
-  const Handle(Geom_Surface)& Surface() const
-  {
-    return myCOnSurfGeom.Surface();
-  }
-  
-  //! Returns first and last parameter of the curves
-  //! (2D- and 3D-curves are considered to have same range)
-  void Range (Standard_Real& theFirst, Standard_Real& theLast)
-  {
-    myCOnSurfGeom.Range(theFirst, theLast);
-  }
-  
+  //! If isMultyThread == Standard_True then computation will be performed in parallel.
+  Standard_EXPORT void Perform (const Standard_Boolean isMultyThread = Standard_True);
+   
   //! Returns true if the max distance has been found
   Standard_Boolean IsDone() const
   {
@@ -105,16 +73,15 @@ protected:
 
   //! Computes the max distance for the 3d curve of <myCOnSurfGeom>
   //! and 2d curve <thePCurve>
-  //! If isTheMultyTheadDisabled == TRUE then computation will be made
-  //! without any parallelization.
-  Standard_EXPORT void Compute (const Handle(Geom2d_Curve)& thePCurve, 
-                                const Standard_Boolean isTheMultyTheradDisabled);
+  //! If isMultyThread == Standard_True then computation will be performed in parallel.
+  Standard_EXPORT void Compute (const Handle(Adaptor3d_CurveOnSurface)& theCurveOnSurface,
+                                const Standard_Boolean isMultyThread);
 
 private:
 
   GeomLib_CheckCurveOnSurface myCOnSurfGeom;
-  Handle(Geom2d_Curve) myPCurve;
-  Handle(Geom2d_Curve) myPCurve2;
+  Handle(Adaptor3d_CurveOnSurface) myAdaptorCurveOnSurface;
+  Handle(Adaptor3d_CurveOnSurface) myAdaptorCurveOnSurface2;
 };
 
 #endif // _BRepLib_CheckCurveOnSurface_HeaderFile
diff --git a/src/BRepLib/BRepLib_ValidateEdge.cxx b/src/BRepLib/BRepLib_ValidateEdge.cxx
new file mode 100644
index 0000000000..207de2534d
--- /dev/null
+++ b/src/BRepLib/BRepLib_ValidateEdge.cxx
@@ -0,0 +1,248 @@
+
+// Copyright (c) 2021 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+
+#include <Adaptor3d_Curve.hxx>
+#include <Adaptor3d_CurveOnSurface.hxx>
+#include <BRepCheck.hxx>
+#include <BRepLib_ValidateEdge.hxx>
+#include <Extrema_LocateExtPC.hxx>
+#include <GeomLib_CheckCurveOnSurface.hxx>
+
+//=============================================================================
+//function : BRepLib_ValidateEdge
+//purpose  : Constructor
+//=============================================================================
+BRepLib_ValidateEdge::BRepLib_ValidateEdge(Handle(Adaptor3d_Curve) theReferenceCurve, 
+                                           Handle(Adaptor3d_CurveOnSurface) theOtherCurve, 
+                                           Standard_Boolean theSameParameter):
+  myReferenceCurve(theReferenceCurve),
+  myOtherCurve(theOtherCurve),
+  mySameParameter(theSameParameter),
+  myControlPointsNumber(22),
+  myToleranceForChecking(0),
+  myCalculatedDistance(0),
+  myExitIfToleranceExceeded(Standard_False),
+  myIsDone(Standard_False),
+  myIsExactMethod(Standard_False)
+{ }
+
+//=============================================================================
+//function : CheckTolerance
+//purpose  : 
+//=============================================================================
+Standard_Boolean BRepLib_ValidateEdge::CheckTolerance(Standard_Real theToleranceToCheck)
+{
+  return CorrectTolerance(theToleranceToCheck) > myCalculatedDistance;
+}
+
+//=============================================================================
+//function : GetMaxDistance
+//purpose  : 
+//=============================================================================
+Standard_Real BRepLib_ValidateEdge::GetMaxDistance()
+{
+  Standard_Real aCorrectedTolerance = myCalculatedDistance * 1.00001;
+  return aCorrectedTolerance;
+}
+
+//=============================================================================
+//function : UpdateTolerance
+//purpose  : 
+//=============================================================================
+void BRepLib_ValidateEdge::UpdateTolerance(Standard_Real& theToleranceToUpdate)
+{
+  Standard_Real aCorrectedTolerance = myCalculatedDistance * 1.00001;
+  if (aCorrectedTolerance > theToleranceToUpdate)
+  {
+    theToleranceToUpdate = aCorrectedTolerance;
+  }
+}
+
+//=============================================================================
+//function : CorrectTolerance
+//purpose  : 
+//=============================================================================
+Standard_Real BRepLib_ValidateEdge::CorrectTolerance(Standard_Real theTolerance)
+{
+  const Handle(Adaptor3d_Surface)& aSurface = myOtherCurve->GetSurface();
+  Standard_Real aCurvePrecition = BRepCheck::PrecCurve(*myReferenceCurve);
+  Standard_Real aSurfacePrecition = BRepCheck::PrecSurface(aSurface);
+  Standard_Real aToleranceDelta = (aCurvePrecition > aSurfacePrecition) ? aCurvePrecition : aSurfacePrecition;
+  Standard_Real aCorrectedTolerance = theTolerance + aToleranceDelta;
+  return aCorrectedTolerance;
+}
+
+//=============================================================================
+//function : SetExitIfToleranceExceeded
+//purpose  : 
+//=============================================================================
+void BRepLib_ValidateEdge::SetExitIfToleranceExceeded(Standard_Real theToleranceForChecking)
+{
+  myExitIfToleranceExceeded = Standard_True;
+  myToleranceForChecking = CorrectTolerance(theToleranceForChecking);
+}
+
+//=============================================================================
+//function : Process
+//purpose  : 
+//=============================================================================
+void BRepLib_ValidateEdge::Process()
+{
+  if (myIsExactMethod && mySameParameter)
+  {
+    ProcessExact();
+  }
+  else
+  {
+    ProcessApprox();
+  }
+}
+
+//=============================================================================
+//function : ProcessApprox
+//purpose  : 
+//=============================================================================
+void BRepLib_ValidateEdge::ProcessApprox()
+{
+  myIsDone = Standard_True;
+  Standard_Real aSquareToleranceForChecking = myToleranceForChecking * myToleranceForChecking;
+  Standard_Real aReferenceFirstParam = myReferenceCurve->FirstParameter();
+  Standard_Real aReferenceLastParam = myReferenceCurve->LastParameter();
+  Standard_Real anOtherFirstParam = myOtherCurve->FirstParameter();
+  Standard_Real anOtherLastParam = myOtherCurve->LastParameter();
+  Standard_Real aMaxSquareDistance = 0.;
+
+  Standard_Integer aControlPointsNumber = (myControlPointsNumber < 1) ? 1 : myControlPointsNumber;
+  Standard_Boolean anIsProjection = (!mySameParameter ||
+    Abs(anOtherFirstParam - aReferenceFirstParam) > Precision::PConfusion() ||
+    Abs(anOtherLastParam - aReferenceLastParam) > Precision::PConfusion());
+
+  if (!anIsProjection)
+  {
+    for (Standard_Integer i = 0; i <= aControlPointsNumber; ++i)
+    {
+      Standard_Real aControlPointParam =
+        ((aControlPointsNumber - i) * aReferenceFirstParam + i * aReferenceLastParam) / aControlPointsNumber;
+      gp_Pnt aReferencePoint = myReferenceCurve->Value(aControlPointParam);
+      gp_Pnt anOtherPoint = myOtherCurve->Value(aControlPointParam);
+      Standard_Real aSquareDistance = aReferencePoint.SquareDistance(anOtherPoint);
+      if (aSquareDistance > aMaxSquareDistance)
+      {
+          aMaxSquareDistance = aSquareDistance;
+      }
+      // Stop process for best performance
+      if (myExitIfToleranceExceeded && aMaxSquareDistance > aSquareToleranceForChecking)
+      {
+        myCalculatedDistance = sqrt(aMaxSquareDistance);
+        return;
+      }
+    }
+  }
+  else
+  {
+    gp_Pnt aReferencePoint = myReferenceCurve->Value(aReferenceFirstParam);
+    gp_Pnt anOtherPoint = myOtherCurve->Value(anOtherFirstParam);
+    Standard_Real aSquareDistance = aReferencePoint.SquareDistance(anOtherPoint);
+    if (aSquareDistance > aMaxSquareDistance)
+    {
+        aMaxSquareDistance = aSquareDistance;
+    }
+    if (myExitIfToleranceExceeded && aMaxSquareDistance > aSquareToleranceForChecking)
+    {
+      myCalculatedDistance = sqrt(aMaxSquareDistance);
+      return;
+    }
+
+    aReferencePoint = myReferenceCurve->Value(aReferenceLastParam);
+    anOtherPoint = myOtherCurve->Value(anOtherLastParam);
+    aSquareDistance = aReferencePoint.SquareDistance(anOtherPoint);
+    if (aSquareDistance > aMaxSquareDistance)
+    {
+      aMaxSquareDistance = aSquareDistance;
+    }
+    if (myExitIfToleranceExceeded && aMaxSquareDistance > aSquareToleranceForChecking)
+    {
+      myCalculatedDistance = sqrt(aMaxSquareDistance);
+      return;
+    }
+
+    Extrema_LocateExtPC aReferenceExtrema, anOtherExtrema;
+    aReferenceExtrema.Initialize(*myReferenceCurve, aReferenceFirstParam, aReferenceLastParam, myReferenceCurve->Resolution(Precision::Confusion()));
+    anOtherExtrema.Initialize(*myOtherCurve, anOtherFirstParam, anOtherLastParam, myOtherCurve->Resolution(Precision::Confusion()));
+    for (Standard_Integer i = 1; i < aControlPointsNumber; i++)
+    {
+      Standard_Real aReferenceParam = ((aControlPointsNumber - i) * aReferenceFirstParam + i * aReferenceLastParam) / aControlPointsNumber;
+      gp_Pnt aReferencePoint = myReferenceCurve->Value(aReferenceParam);
+      Standard_Real anOtherParam = ((aControlPointsNumber - i) * anOtherFirstParam + i * anOtherLastParam) / aControlPointsNumber;
+      gp_Pnt anOtherPoint = myOtherCurve->Value(anOtherParam);
+
+      aReferenceExtrema.Perform(anOtherPoint, aReferenceParam);
+      if (aReferenceExtrema.IsDone())
+      {
+        if (aReferenceExtrema.SquareDistance() > aMaxSquareDistance)
+        {
+          aMaxSquareDistance = aReferenceExtrema.SquareDistance();
+        }
+        if (myExitIfToleranceExceeded && aMaxSquareDistance > aSquareToleranceForChecking)
+        {
+          myCalculatedDistance = sqrt(aMaxSquareDistance);
+          return;
+        }
+      }
+      else
+      {
+        myIsDone = Standard_False;
+        // Stop process for best performance
+        return;
+      }
+
+      anOtherExtrema.Perform(aReferencePoint, anOtherParam);
+      if (anOtherExtrema.IsDone())
+      {
+        if (anOtherExtrema.SquareDistance() > aMaxSquareDistance)
+        {
+          aMaxSquareDistance = anOtherExtrema.SquareDistance();
+        }
+        if (myExitIfToleranceExceeded && aMaxSquareDistance > aSquareToleranceForChecking)
+        {
+          myCalculatedDistance = sqrt(aMaxSquareDistance);
+          return;
+        }
+      }
+      else
+      {
+        myIsDone = Standard_False;
+        // Stop process for best performance
+        return;
+      }
+    }
+  }
+  myCalculatedDistance = sqrt(aMaxSquareDistance);
+}
+
+//=============================================================================
+//function : ProcessExact
+//purpose  : 
+//=============================================================================
+void BRepLib_ValidateEdge::ProcessExact()
+{
+  GeomLib_CheckCurveOnSurface aCheckCurveOnSurface(myReferenceCurve);
+  aCheckCurveOnSurface.Perform(myOtherCurve);
+  myIsDone = aCheckCurveOnSurface.IsDone();
+  if (myIsDone)
+  {
+    myCalculatedDistance = aCheckCurveOnSurface.MaxDistance();
+  }
+}
diff --git a/src/BRepLib/BRepLib_ValidateEdge.hxx b/src/BRepLib/BRepLib_ValidateEdge.hxx
new file mode 100644
index 0000000000..54fb88dc57
--- /dev/null
+++ b/src/BRepLib/BRepLib_ValidateEdge.hxx
@@ -0,0 +1,98 @@
+// Copyright (c) 2021 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+
+#ifndef _BRepLib_ValidateEdge_HeaderFile
+#define _BRepLib_ValidateEdge_HeaderFile
+
+#include<Standard_TypeDef.hxx>
+#include<Standard_Handle.hxx>
+
+class Adaptor3d_Curve;
+class Adaptor3d_CurveOnSurface;
+
+//! Computes the max distance between 3D-curve and curve on surface.
+//! This class uses 2 methods: approximate using finite
+//! number of points (default) and exact 
+class BRepLib_ValidateEdge
+{
+public:
+  //! Initialization constructor
+  Standard_EXPORT BRepLib_ValidateEdge(const Handle(Adaptor3d_Curve) theReferenceCurve,
+                                       const Handle(Adaptor3d_CurveOnSurface) theOtherCurve,
+                                       Standard_Boolean theSameParameter);
+
+  //! Set control points number (if you need a value other than 22)
+  Standard_EXPORT void SetControlPointsNumber(Standard_Integer theControlPointsNumber)
+  {
+    myControlPointsNumber = theControlPointsNumber;
+  }
+
+  //! Sets method to calculate distance: Calculating in finite number of points (if theIsExact
+  //! is false, faster, but possible not correct result) or exact calculating by using 
+  //! BRepLib_CheckCurveOnSurface class (if theIsExact is true, slowly, but more correctly. 
+  //! Default method is exact
+  void SetExactMathod(Standard_Boolean theIsExact)
+  {
+    myIsExactMethod = theIsExact;
+  }
+
+  //! Sets limit to compute a distance in the Process() function. If the distance greater than 
+  //! theToleranceForChecking the Process() function stopped. Use this in case checking of 
+  //! tolerance for best performcnce. Has no effect in case using exact method.
+  void SetExitIfToleranceExceeded(Standard_Real theToleranceForChecking);
+
+  //! Computes the max distance for the 3d curve <myReferenceCurve>
+  //! and curve on surface <myOtherCurve>. If the SetExitIfToleranceExceeded()
+  //! function was called before <myCalculatedDistance> containts first 
+  //! greater than SetExitIfToleranceExceeded() parameter value. In case 
+  //! using exact method always computes real max distance.
+  Standard_EXPORT void Process();
+
+  //! Returns true if the distance has been found for all points
+  Standard_EXPORT Standard_Boolean IsDone()
+  {
+    return myIsDone;
+  }
+
+  //! Returns true if compute distance less than <theToleranceToCheck>
+  Standard_EXPORT Standard_Boolean CheckTolerance(Standard_Real theToleranceToCheck);
+
+  //! Returns max distance
+  Standard_EXPORT Standard_Real GetMaxDistance();
+
+  //! Increace <theToleranceToUpdate> if max distance is greater than <theToleranceToUpdate>
+  Standard_EXPORT void UpdateTolerance(Standard_Real& theToleranceToUpdate);
+
+private:
+  //! Adds some margin for distance checking
+  Standard_Real CorrectTolerance(Standard_Real theTolerance);
+
+  //! Calculating in finite number of points
+  void ProcessApprox();
+
+  //! Calculating by using BRepLib_CheckCurveOnSurface class
+  void ProcessExact();
+
+  Handle(Adaptor3d_Curve) myReferenceCurve;
+  Handle(Adaptor3d_CurveOnSurface) myOtherCurve;
+  Standard_Boolean mySameParameter;
+  Standard_Integer myControlPointsNumber; 
+  Standard_Real myToleranceForChecking;
+  Standard_Real myCalculatedDistance;
+  Standard_Boolean myExitIfToleranceExceeded;
+  Standard_Boolean myIsDone;
+  Standard_Boolean myIsExactMethod;
+};
+
+#endif _BRepLib_ValidateEdge_HeaderFile
\ No newline at end of file
diff --git a/src/BRepLib/FILES b/src/BRepLib/FILES
index 6d7d2f98c3..cf455709cf 100755
--- a/src/BRepLib/FILES
+++ b/src/BRepLib/FILES
@@ -32,4 +32,6 @@ BRepLib_MakeWire.hxx
 BRepLib_MakeWire_1.cxx
 BRepLib_ShapeModification.hxx
 BRepLib_ShellError.hxx
+BRepLib_ValidateEdge.cxx
+BRepLib_ValidateEdge.hxx
 BRepLib_WireError.hxx
diff --git a/src/BRepOffset/BRepOffset_SimpleOffset.cxx b/src/BRepOffset/BRepOffset_SimpleOffset.cxx
index 82689904f4..bfb537d670 100644
--- a/src/BRepOffset/BRepOffset_SimpleOffset.cxx
+++ b/src/BRepOffset/BRepOffset_SimpleOffset.cxx
@@ -20,6 +20,7 @@
 #include <Adaptor3d_CurveOnSurface.hxx>
 #include <BRepBuilderAPI_MakeEdge.hxx>
 #include <BRepLib.hxx>
+#include <BRepLib_ValidateEdge.hxx>
 #include <BRep_Tool.hxx>
 #include <BRepOffset.hxx>
 #include <Geom_OffsetSurface.hxx>
@@ -35,9 +36,6 @@
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Vertex.hxx>
 
-static const Standard_Integer NCONTROL=22;
-
-
 //=============================================================================
 //function : BRepOffset_SimpleOffset
 //purpose  : Constructor
@@ -293,15 +291,19 @@ void BRepOffset_SimpleOffset::FillEdgeData(const TopoDS_Edge& theEdge,
     const Handle(Geom2d_Curve) aC2dNew = BRep_Tool::CurveOnSurface(theEdge, aCurFace, aF, aL);
     const Handle(Adaptor2d_Curve2d) aHCurve2d = new Geom2dAdaptor_Curve(aC2dNew, aF, aL);
     const Handle(Adaptor3d_Surface) aHSurface = new GeomAdaptor_Surface(myFaceInfo.Find(aCurFace).myOffsetS);
-    Adaptor3d_CurveOnSurface aCurveOnSurf(aHCurve2d, aHSurface);
+    const Handle(Adaptor3d_CurveOnSurface) aCurveOnSurf = new Adaptor3d_CurveOnSurface(aHCurve2d, aHSurface);
 
     // Extract 3d-curve (it is not null).
-    const GeomAdaptor_Curve aCurve3d(aNED.myOffsetC, aF, aL);
+    const Handle(Adaptor3d_Curve) aCurve3d = new GeomAdaptor_Curve(aNED.myOffsetC, aF, aL);
 
     // It is necessary to compute maximal deviation (tolerance).
-    Standard_Real aMaxTol = 0.0;
-    ShapeAnalysis_Edge::ComputeDeviation(aCurve3d, aCurveOnSurf, Standard_True, aMaxTol, NCONTROL);
-    anEdgeTol = Max (anEdgeTol, aMaxTol);
+    BRepLib_ValidateEdge aBRepLib_ValidateEdge(aCurve3d, aCurveOnSurf, Standard_True);
+    aBRepLib_ValidateEdge.Process();
+    Standard_Real aMaxTol1 = aBRepLib_ValidateEdge.GetMaxDistance();
+    if (aBRepLib_ValidateEdge.IsDone())
+    {
+      anEdgeTol = Max (anEdgeTol, aMaxTol1);
+    }
   }
   aNED.myTol = Max(BRep_Tool::Tolerance(aNewEdge), anEdgeTol);
 
diff --git a/src/BRepTools/BRepTools.cxx b/src/BRepTools/BRepTools.cxx
index 61e7a9035e..fe9fce6245 100644
--- a/src/BRepTools/BRepTools.cxx
+++ b/src/BRepTools/BRepTools.cxx
@@ -15,6 +15,7 @@
 // commercial license or contractual agreement.
 
 
+#include <Adaptor3d_CurveOnSurface.hxx>
 #include <Bnd_Box2d.hxx>
 #include <BndLib_Add2dCurve.hxx>
 #include <BRep_Builder.hxx>
@@ -30,6 +31,7 @@
 #include <ElCLib.hxx>
 #include <Geom2d_Curve.hxx>
 #include <Geom2dAdaptor_Curve.hxx>
+#include <GeomAdaptor_Curve.hxx>
 #include <Geom_BSplineSurface.hxx>
 #include <Geom_Curve.hxx>
 #include <Geom_RectangularTrimmedSurface.hxx>
@@ -1328,9 +1330,16 @@ Standard_Real BRepTools::EvalAndUpdateTol(const TopoDS_Edge& theE,
     first = Max(first, C2d->FirstParameter());
     last = Min(last, C2d->LastParameter());
   }
+  const Handle(Adaptor3d_Curve) aGeomAdaptorCurve = new GeomAdaptor_Curve(C3d, first, last);
 
-  GeomLib_CheckCurveOnSurface CT(C3d, S, first, last);
-  CT.Perform(C2d);
+  Handle(Adaptor2d_Curve2d) aGeom2dAdaptorCurve   = new Geom2dAdaptor_Curve(C2d, first, last);
+  Handle(GeomAdaptor_Surface) aGeomAdaptorSurface = new GeomAdaptor_Surface(S);
+
+  Handle(Adaptor3d_CurveOnSurface) anAdaptor3dCurveOnSurface =
+    new Adaptor3d_CurveOnSurface(aGeom2dAdaptorCurve, aGeomAdaptorSurface);
+
+  GeomLib_CheckCurveOnSurface CT(aGeomAdaptorCurve);
+  CT.Perform(anAdaptor3dCurveOnSurface);
   if(CT.IsDone())
   {
     newtol = CT.MaxDistance();
diff --git a/src/GeomLib/GeomLib_CheckCurveOnSurface.cxx b/src/GeomLib/GeomLib_CheckCurveOnSurface.cxx
index c8ad876b1e..befc5d5629 100644
--- a/src/GeomLib/GeomLib_CheckCurveOnSurface.cxx
+++ b/src/GeomLib/GeomLib_CheckCurveOnSurface.cxx
@@ -14,16 +14,16 @@
 
 #include <GeomLib_CheckCurveOnSurface.hxx>
 
-#include <Adaptor2d_Curve2d.hxx>
 #include <Adaptor3d_Curve.hxx>
 #include <Adaptor3d_CurveOnSurface.hxx>
 #include <Adaptor3d_Surface.hxx>
+#include <GeomAdaptor_Curve.hxx>
 #include <Geom_BSplineCurve.hxx>
 #include <Geom_TrimmedCurve.hxx>
+#include <Adaptor2d_Curve2d.hxx>
 #include <Geom2d_BSplineCurve.hxx>
 #include <Geom2d_TrimmedCurve.hxx>
 #include <Geom2dAdaptor_Curve.hxx>
-#include <GeomAdaptor_Curve.hxx>
 #include <GeomAdaptor_Surface.hxx>
 #include <gp_Pnt.hxx>
 #include <math_Matrix.hxx>
@@ -46,8 +46,8 @@ Standard_Boolean MinComputing(
                 Standard_Real& theBestValue,
                 Standard_Real& theBestParameter);
 
-static Standard_Integer FillSubIntervals( const Handle(Geom_Curve)& theCurve3d,
-                                          const Handle(Geom2d_Curve)& theCurve2d,
+static Standard_Integer FillSubIntervals( const Handle(Adaptor3d_Curve)& theCurve3d,
+                                          const Handle(Adaptor2d_Curve2d)& theCurve2d,
                                           const Standard_Real theFirst,
                                           const Standard_Real theLast,
                                           Standard_Integer &theNbParticles,
@@ -61,12 +61,12 @@ class GeomLib_CheckCurveOnSurface_TargetFunc :
   public math_MultipleVarFunctionWithHessian
 {
  public:
-  GeomLib_CheckCurveOnSurface_TargetFunc( const Adaptor3d_Curve& theC3D,
-                                          const Adaptor3d_Curve& theAdCS,
+  GeomLib_CheckCurveOnSurface_TargetFunc(const Handle(Adaptor3d_Curve)& theC3D,
+                                         const Handle(Adaptor3d_Curve)& theCurveOnSurface,
                                           const Standard_Real theFirst,
                                           const Standard_Real theLast):
   myCurve1(theC3D),
-  myCurve2(theAdCS),
+  myCurve2(theCurveOnSurface),
   myFirst(theFirst),
   myLast(theLast)
   {
@@ -96,8 +96,8 @@ class GeomLib_CheckCurveOnSurface_TargetFunc :
       if (!CheckParameter(theX))
         return Standard_False;
 
-      const gp_Pnt  aP1(myCurve1.Value(theX)),
-                    aP2(myCurve2.Value(theX));
+      const gp_Pnt  aP1(myCurve1->Value(theX)),
+                    aP2(myCurve2->Value(theX));
       
       theFVal = -1.0*aP1.SquareDistance(aP2);
     }
@@ -139,13 +139,13 @@ class GeomLib_CheckCurveOnSurface_TargetFunc :
       //
       if (!theDeriv2)
       {
-        myCurve1.D1(theX, aP1, aDC1);
-        myCurve2.D1(theX, aP2, aDC2);
+        myCurve1->D1(theX, aP1, aDC1);
+        myCurve2->D1(theX, aP2, aDC2);
       }
       else
       {
-        myCurve1.D2(theX, aP1, aDC1, aDCC1);
-        myCurve2.D2(theX, aP2, aDC2, aDCC2);
+        myCurve1->D2(theX, aP1, aDC1, aDCC1);
+        myCurve2->D2(theX, aP2, aDC2, aDCC2);
       }
 
       const gp_Vec aVec1(aP1, aP2), aVec2(aDC2-aDC1);
@@ -223,8 +223,8 @@ class GeomLib_CheckCurveOnSurface_TargetFunc :
      return ((myFirst <= theParam) && (theParam <= myLast));
    }
 
-   const Adaptor3d_Curve& myCurve1;
-   const Adaptor3d_Curve& myCurve2;
+   const Handle(Adaptor3d_Curve)& myCurve1;
+   const Handle(Adaptor3d_Curve)& myCurve2;
    const Standard_Real myFirst;
    const Standard_Real myLast;
 };
@@ -237,15 +237,13 @@ class GeomLib_CheckCurveOnSurface_Local
 {
 public:
   GeomLib_CheckCurveOnSurface_Local(
-              const Handle(Geom_Curve)& theCurve3D,
-              const Handle(Geom2d_Curve)& theCurve2D,
-              const Handle(Geom_Surface)& theSurface,
+              const Handle(Adaptor3d_Curve)& theCurve3D,
+              const Handle(Adaptor3d_Curve)& theCurveOnSurface,
               const TColStd_Array1OfReal& theIntervalsArr,
               const Standard_Real theEpsilonRange,
               const Standard_Integer theNbParticles):
   myCurve3D(theCurve3D),
-  myCurve2D(theCurve2D),
-  mySurface(theSurface),
+  myCurveOnSurface(theCurveOnSurface),
   mySubIntervals(theIntervalsArr),
   myEpsilonRange(theEpsilonRange),
   myNbParticles(theNbParticles),
@@ -261,13 +259,7 @@ public:
     //This optimal value will be put in corresponding (depending on theIndex - the
     //identificator of the current interval in mySubIntervals array) cell of 
     //myArrOfDist and myArrOfParam arrays.
-    const GeomAdaptor_Curve anAC(myCurve3D);
-    const Handle(Adaptor2d_Curve2d) anAd2dC = new Geom2dAdaptor_Curve(myCurve2D);
-    const Handle(Adaptor3d_Surface) anAdS = new GeomAdaptor_Surface(mySurface);
-
-    const Adaptor3d_CurveOnSurface anACS(anAd2dC, anAdS);
-
-    GeomLib_CheckCurveOnSurface_TargetFunc aFunc( anAC, anACS,
+    GeomLib_CheckCurveOnSurface_TargetFunc aFunc(myCurve3D, myCurveOnSurface,
                                                   mySubIntervals.Value(theIndex),
                                                   mySubIntervals.Value(theIndex+1));
 
@@ -303,9 +295,8 @@ public:
 
 private:
   GeomLib_CheckCurveOnSurface_Local operator=(GeomLib_CheckCurveOnSurface_Local&);
-  const Handle(Geom_Curve)& myCurve3D;
-  const Handle(Geom2d_Curve)& myCurve2D;
-  const Handle(Geom_Surface)& mySurface;
+  const Handle(Adaptor3d_Curve)& myCurve3D;
+  const Handle(Adaptor3d_Curve)& myCurveOnSurface;
 
   const TColStd_Array1OfReal& mySubIntervals;
   const Standard_Real myEpsilonRange;
@@ -320,8 +311,6 @@ private:
 //=======================================================================
 GeomLib_CheckCurveOnSurface::GeomLib_CheckCurveOnSurface()
 :
-  myFirst(0.),
-  myLast(0.),
   myErrorStatus(0),
   myMaxDistance(RealLast()),
   myMaxParameter(0.),
@@ -334,15 +323,9 @@ GeomLib_CheckCurveOnSurface::GeomLib_CheckCurveOnSurface()
 //purpose  : 
 //=======================================================================
 GeomLib_CheckCurveOnSurface::
-  GeomLib_CheckCurveOnSurface(const Handle(Geom_Curve)& theCurve,
-                              const Handle(Geom_Surface)& theSurface,
-                              const Standard_Real theFirst,
-                              const Standard_Real theLast,
+  GeomLib_CheckCurveOnSurface(const Handle(Adaptor3d_Curve)& theCurve,
                               const Standard_Real theTolRange):
   myCurve(theCurve),
-  mySurface(theSurface),
-  myFirst(theFirst),
-  myLast(theLast),
   myErrorStatus(0),
   myMaxDistance(RealLast()),
   myMaxParameter(0.),
@@ -357,9 +340,6 @@ GeomLib_CheckCurveOnSurface::
 void GeomLib_CheckCurveOnSurface::Init()
 {
   myCurve.Nullify();
-  mySurface.Nullify();
-  myFirst = 0.0;
-  myLast = 0.0;
   myErrorStatus = 0;
   myMaxDistance = RealLast();
   myMaxParameter = 0.0;
@@ -370,16 +350,10 @@ void GeomLib_CheckCurveOnSurface::Init()
 //function : Init
 //purpose  : 
 //=======================================================================
-void GeomLib_CheckCurveOnSurface::Init( const Handle(Geom_Curve)& theCurve,
-                                        const Handle(Geom_Surface)& theSurface,
-                                        const Standard_Real theFirst,
-                                        const Standard_Real theLast,
+void GeomLib_CheckCurveOnSurface::Init( const Handle(Adaptor3d_Curve)& theCurve,
                                         const Standard_Real theTolRange)
 {
   myCurve = theCurve;
-  mySurface = theSurface;
-  myFirst = theFirst;
-  myLast = theLast;
   myErrorStatus = 0;
   myMaxDistance = RealLast();
   myMaxParameter = 0.0;
@@ -390,26 +364,16 @@ void GeomLib_CheckCurveOnSurface::Init( const Handle(Geom_Curve)& theCurve,
 //function : Perform
 //purpose  : 
 //=======================================================================
-void GeomLib_CheckCurveOnSurface::Perform(const Handle(Geom2d_Curve)& thePCurve,
-                                          const Standard_Boolean isTheMTDisabled)
+void GeomLib_CheckCurveOnSurface::Perform(const Handle(Adaptor3d_CurveOnSurface)& theCurveOnSurface,
+                                          const Standard_Boolean isMultyThread)
 {
   if( myCurve.IsNull() ||
-      mySurface.IsNull() ||
-      thePCurve.IsNull())
+      theCurveOnSurface.IsNull())
   {
     myErrorStatus = 1;
     return;
   }
 
-  if(((myCurve->FirstParameter() - myFirst) > myTolRange) ||
-     ((myCurve->LastParameter() - myLast) < -myTolRange) ||
-     ((thePCurve->FirstParameter() - myFirst) > myTolRange) ||
-     ((thePCurve->LastParameter() - myLast) < -myTolRange))
-  {
-    myErrorStatus = 2;
-    return;
-  }
-
   const Standard_Real anEpsilonRange = 1.e-3;
 
   Standard_Integer aNbParticles = 3;
@@ -422,8 +386,8 @@ void GeomLib_CheckCurveOnSurface::Perform(const Handle(Geom2d_Curve)& thePCurve,
   //number of particles should be equal to n. 
 
   const Standard_Integer aNbSubIntervals = 
-                              FillSubIntervals( myCurve, thePCurve,
-                                                myFirst, myLast, aNbParticles);
+                              FillSubIntervals( myCurve, theCurveOnSurface->GetCurve(),
+                                myCurve->FirstParameter(), myCurve->LastParameter(), aNbParticles);
 
   if(!aNbSubIntervals)
   {
@@ -435,12 +399,13 @@ void GeomLib_CheckCurveOnSurface::Perform(const Handle(Geom2d_Curve)& thePCurve,
     OCC_CATCH_SIGNALS
 
     TColStd_Array1OfReal anIntervals(1, aNbSubIntervals+1);
-    FillSubIntervals(myCurve, thePCurve, myFirst, myLast, aNbParticles, &anIntervals);
+    FillSubIntervals(myCurve, theCurveOnSurface->GetCurve(), 
+      myCurve->FirstParameter(), myCurve->LastParameter(), aNbParticles, &anIntervals);
 
-    GeomLib_CheckCurveOnSurface_Local aComp(myCurve, thePCurve,
-                                mySurface, anIntervals, anEpsilonRange, aNbParticles);
+    GeomLib_CheckCurveOnSurface_Local aComp(myCurve,theCurveOnSurface, anIntervals, 
+                                            anEpsilonRange, aNbParticles);
 
-    OSD_Parallel::For(anIntervals.Lower(), anIntervals.Upper(), aComp, isTheMTDisabled);
+    OSD_Parallel::For(anIntervals.Lower(), anIntervals.Upper(), aComp, !isMultyThread);
 
     aComp.OptimalValues(myMaxDistance, myMaxParameter);
 
@@ -458,8 +423,8 @@ void GeomLib_CheckCurveOnSurface::Perform(const Handle(Geom2d_Curve)& thePCurve,
 //            (fills theSubIntervals array).
 //            Returns number of subintervals.
 //=======================================================================
-Standard_Integer FillSubIntervals(const Handle(Geom_Curve)& theCurve3d,
-                                  const Handle(Geom2d_Curve)& theCurve2d,
+Standard_Integer FillSubIntervals(const Handle(Adaptor3d_Curve)& theCurve3d,
+                                  const Handle(Adaptor2d_Curve2d)& theCurve2d,
                                   const Standard_Real theFirst,
                                   const Standard_Real theLast,
                                   Standard_Integer &theNbParticles,
@@ -475,28 +440,13 @@ Standard_Integer FillSubIntervals(const Handle(Geom_Curve)& theCurve3d,
   Standard_Boolean isTrimmed3D = Standard_False, isTrimmed2D = Standard_False;
 
   //
-  if (theCurve3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
-  {
-    aBS3DCurv = Handle(Geom_BSplineCurve)::
-                      DownCast(Handle(Geom_TrimmedCurve)::
-                      DownCast(theCurve3d)->BasisCurve());
-    isTrimmed3D = Standard_True;
-  }
-  else
+  if (theCurve3d->GetType() == GeomAbs_BSplineCurve)
   {
-    aBS3DCurv = Handle(Geom_BSplineCurve)::DownCast(theCurve3d);
+    aBS3DCurv = theCurve3d->BSpline();
   }
-
-  if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
-  {
-    aBS2DCurv = Handle(Geom2d_BSplineCurve)::
-                      DownCast(Handle(Geom2d_TrimmedCurve)::
-                      DownCast(theCurve2d)->BasisCurve());
-    isTrimmed2D = Standard_True;
-  }
-  else
+  if (theCurve2d->GetType() == GeomAbs_BSplineCurve)
   {
-    aBS2DCurv = Handle(Geom2d_BSplineCurve)::DownCast(theCurve2d);
+    aBS2DCurv = theCurve2d->BSpline();
   }
 
   Handle(TColStd_HArray1OfReal) anArrKnots3D,  anArrKnots2D; 
diff --git a/src/GeomLib/GeomLib_CheckCurveOnSurface.hxx b/src/GeomLib/GeomLib_CheckCurveOnSurface.hxx
index 6806b69aac..2b7fafc014 100644
--- a/src/GeomLib/GeomLib_CheckCurveOnSurface.hxx
+++ b/src/GeomLib/GeomLib_CheckCurveOnSurface.hxx
@@ -15,10 +15,13 @@
 #ifndef _GeomLib_CheckCurveOnSurface_HeaderFile
 #define _GeomLib_CheckCurveOnSurface_HeaderFile
 
-#include <Geom_Curve.hxx>
+#include <Adaptor3d_Curve.hxx>
 #include <Precision.hxx>
 #include <Standard.hxx>
 
+class GeomAdaptor_Curve;
+class Adaptor2d_Curve2d;
+class Adaptor3d_CurveOnSurface;
 class Geom_Surface;
 class Geom2d_Curve;
 
@@ -35,18 +38,12 @@ public:
   
   //! Constructor
   Standard_EXPORT
-    GeomLib_CheckCurveOnSurface(const Handle(Geom_Curve)& theCurve, 
-                                const Handle(Geom_Surface)& theSurface, 
-                                const Standard_Real theFirst, 
-                                const Standard_Real theLast,
+    GeomLib_CheckCurveOnSurface(const Handle(Adaptor3d_Curve)& theCurve,
                                 const Standard_Real theTolRange = 
                                                       Precision::PConfusion());
   
   //! Sets the data for the algorithm
-  Standard_EXPORT void Init (const Handle(Geom_Curve)& theCurve, 
-                             const Handle(Geom_Surface)& theSurface, 
-                             const Standard_Real theFirst, 
-                             const Standard_Real theLast,
+  Standard_EXPORT void Init (const Handle(Adaptor3d_Curve)& theCurve,
                              const Standard_Real theTolRange = Precision::PConfusion());
 
   //! Initializes all members by default values
@@ -54,30 +51,9 @@ public:
 
   //! Computes the max distance for the 3d curve <myCurve>
   //! and 2d curve <thePCurve>
-  //! If isTheMultyTheadDisabled == TRUE then computation will be made
-  //! without any parallelization.
-  Standard_EXPORT void Perform(const Handle(Geom2d_Curve)& thePCurve, 
-                               const Standard_Boolean isTheMultyTheradDisabled = Standard_False);
-
-  //! Returns my3DCurve
-  const Handle(Geom_Curve)& Curve() const
-  {
-    return myCurve;
-  }  
-
-  //! Returns mySurface
-  const Handle(Geom_Surface)& Surface() const
-  {
-    return mySurface;
-  }
-  
-  //! Returns first and last parameter of the curves
-  //! (2D- and 3D-curves are considered to have same range)
-  void Range (Standard_Real& theFirst, Standard_Real& theLast)
-  {
-    theFirst = myFirst;
-    theLast  = myLast;
-  }
+  //! If isMultyThread == Standard_True then computation will be performed in parallel.
+  Standard_EXPORT void Perform(const Handle(Adaptor3d_CurveOnSurface)& theCurveOnSurface,
+                               const Standard_Boolean isMultyThread = Standard_True);
 
   //! Returns true if the max distance has been found
   Standard_Boolean IsDone() const
@@ -110,10 +86,7 @@ public:
 
 private:
 
-  Handle(Geom_Curve) myCurve;
-  Handle(Geom_Surface) mySurface;
-  Standard_Real myFirst;
-  Standard_Real myLast;
+  Handle(Adaptor3d_Curve) myCurve;
   Standard_Integer myErrorStatus;
   Standard_Real myMaxDistance;
   Standard_Real myMaxParameter;
diff --git a/src/IntTools/IntTools_Tools.cxx b/src/IntTools/IntTools_Tools.cxx
index 5f3db88462..bf7b91e634 100644
--- a/src/IntTools/IntTools_Tools.cxx
+++ b/src/IntTools/IntTools_Tools.cxx
@@ -21,6 +21,7 @@
 #include <BRepAdaptor_Surface.hxx>
 #include <Geom2d_Curve.hxx>
 #include <Geom2d_TrimmedCurve.hxx>
+#include <Geom2dAdaptor_Curve.hxx>
 #include <Geom_BoundedCurve.hxx>
 #include <Geom_Curve.hxx>
 #include <Geom_Geometry.hxx>
@@ -797,8 +798,16 @@ Standard_Boolean IntTools_Tools::ComputeTolerance
 {
   GeomLib_CheckCurveOnSurface aCS;
   //
-  aCS.Init(theCurve3D, theSurf, theFirst, theLast, theTolRange);
-  aCS.Perform (theCurve2D, !theToRunParallel);
+  const Handle(Adaptor3d_Curve) aGeomAdaptorCurve = new GeomAdaptor_Curve(theCurve3D, theFirst, theLast);
+
+  Handle(Adaptor2d_Curve2d) aGeom2dAdaptorCurve = new Geom2dAdaptor_Curve(theCurve2D, theFirst, theLast);
+  Handle(GeomAdaptor_Surface) aGeomAdaptorSurface = new GeomAdaptor_Surface(theSurf);
+
+  Handle(Adaptor3d_CurveOnSurface) anAdaptor3dCurveOnSurface =
+    new Adaptor3d_CurveOnSurface(aGeom2dAdaptorCurve, aGeomAdaptorSurface);
+
+  aCS.Init(aGeomAdaptorCurve, theTolRange);
+  aCS.Perform(anAdaptor3dCurveOnSurface, theToRunParallel);
   if (!aCS.IsDone()) {
     return Standard_False;
   }
diff --git a/src/ShapeAnalysis/ShapeAnalysis_Edge.cxx b/src/ShapeAnalysis/ShapeAnalysis_Edge.cxx
index 22d0addd5f..e03a46a904 100644
--- a/src/ShapeAnalysis/ShapeAnalysis_Edge.cxx
+++ b/src/ShapeAnalysis/ShapeAnalysis_Edge.cxx
@@ -22,6 +22,7 @@
 #include <Adaptor3d_CurveOnSurface.hxx>
 #include <BRep_Builder.hxx>
 #include <BRep_GCurve.hxx>
+#include <BRepLib_ValidateEdge.hxx>
 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
 #include <BRep_TEdge.hxx>
 #include <BRep_Tool.hxx>
@@ -705,74 +706,6 @@ Standard_Boolean ShapeAnalysis_Edge::CheckVertexTolerance(const TopoDS_Edge& edg
   return Status ( ShapeExtend_DONE );
 }
 
-
-//=======================================================================
-//static : Validate
-//purpose: For SameParameter: compute it for two curves
-//note: This function is made from Validate() in BRepCheck_Edge.cxx
-//=======================================================================
-
-Standard_Boolean ShapeAnalysis_Edge::ComputeDeviation (const Adaptor3d_Curve& CRef,
-                                                       const Adaptor3d_Curve& Other,
-                                                       const Standard_Boolean SameParameter,
-                                                       Standard_Real &dev,
-                                                       const Standard_Integer NCONTROL)
-{
-  Standard_Boolean OK = Standard_True;
-  Standard_Real dev2 = dev*dev;
-  
-  Standard_Real First = CRef.FirstParameter(), Last = CRef.LastParameter();
-  Standard_Real OFirst = Other.FirstParameter(), OLast  = Other.LastParameter(); //szv#4:S4163:12Mar99 moved
-
-  Standard_Boolean proj = (!SameParameter || First != OFirst || Last != OLast); //szv#4:S4163:12Mar99 optimized
-
-  Standard_Integer NCtrl = ( NCONTROL < 1 )? 1 : NCONTROL; //szv#4:S4163:12Mar99 anti-exception
-
-  if (!proj) {
-    for (Standard_Integer i = 0; i <= NCtrl; i++) {
-      Standard_Real prm = ((NCtrl-i)*First + i*Last)/NCtrl;
-      gp_Pnt pref = CRef.Value(prm);
-      gp_Pnt pother = Other.Value(prm);
-      Standard_Real dist2 = pref.SquareDistance(pother);
-      if ( dev2 < dist2 ) dev2 = dist2; 
-    }
-    dev = Sqrt ( dev2 );
-  }
-  else {
-    gp_Pnt pd = CRef.Value(First);
-    gp_Pnt pdo = Other.Value(OFirst);
-    Standard_Real dist2 = pd.SquareDistance(pdo);
-    if ( dev2 < dist2 ) dev = Sqrt ( dev2 = dist2 );
-
-    pd = CRef.Value(Last);
-    pdo = Other.Value(OLast);
-    dist2 = pd.SquareDistance(pdo);
-    if ( dev2 < dist2 ) dev = Sqrt ( dev2 = dist2 );
-
-    Extrema_LocateExtPC refd, otherd; //szv#4:S4163:12Mar99 warning
-    refd.Initialize(CRef,First,Last,Precision::PConfusion());
-    otherd.Initialize(Other,OFirst,OLast,Precision::PConfusion());
-
-    for (Standard_Integer i = 1; i < NCtrl; i++) { //szv#4:S4163:12Mar99 was bug
-      Standard_Real rprm = ((NCtrl-i)*First + i*Last)/NCtrl;
-      gp_Pnt pref = CRef.Value(rprm);
-      Standard_Real oprm = ((NCtrl-i)*OFirst + i*OLast)/NCtrl;
-      gp_Pnt pother = Other.Value(oprm);
-
-      refd.Perform(pother,rprm);
-      if ( ! refd.IsDone() ) OK = Standard_False;
-      else if ( dev2 < refd.SquareDistance() ) {dev2 = refd.SquareDistance(); dev = sqrt (dev2);}
-
-      otherd.Perform(pref,oprm);
-      if ( ! otherd.IsDone() ) OK = Standard_False;
-      else if ( dev2 < otherd.SquareDistance() ) {dev2 = otherd.SquareDistance(); dev = sqrt (dev2);}
-    }
-  }
-  dev *= 1.00001;//ims007 entity 8067 edge 3; 1e-07USA60022 (4255, 4-th edge) SA_Check and BRepCh find distinct points001; // ensure that dev*dev >= dev2
-  
-  return OK;
-}
-
 //=======================================================================
 //function : CheckSameParameter
 //purpose  : 
@@ -824,7 +757,7 @@ Standard_Boolean ShapeAnalysis_Edge::CheckSameParameter (const TopoDS_Edge& edge
   }
 
   // Create adaptor for the curve
-  GeomAdaptor_Curve aGAC(aC3D, aFirst, aLast);
+  Handle(GeomAdaptor_Curve) aGAC = new GeomAdaptor_Curve(aC3D, aFirst, aLast);
 
   Handle(Geom_Surface) aFaceSurf;
   TopLoc_Location aFaceLoc;
@@ -869,8 +802,13 @@ Standard_Boolean ShapeAnalysis_Edge::CheckSameParameter (const TopoDS_Edge& edge
     Handle(Geom2dAdaptor_Curve) GHPC = new Geom2dAdaptor_Curve(aPC, f, l);
     Handle(GeomAdaptor_Surface) GAHS = new GeomAdaptor_Surface(aST);
 
-    Adaptor3d_CurveOnSurface ACS(GHPC, GAHS);
-    if (!ComputeDeviation(aGAC, ACS, SameParameter, maxdev, NbControl - 1))
+    Handle(Adaptor3d_CurveOnSurface) ACS = new Adaptor3d_CurveOnSurface(GHPC, GAHS);
+
+    BRepLib_ValidateEdge aBRepLib_ValidateEdge(aGAC, ACS, SameParameter);
+    aBRepLib_ValidateEdge.SetControlPointsNumber(NbControl-1);
+    aBRepLib_ValidateEdge.Process();
+    aBRepLib_ValidateEdge.UpdateTolerance(maxdev);
+    if (!aBRepLib_ValidateEdge.IsDone())
     {
       myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
     }
@@ -890,9 +828,13 @@ Standard_Boolean ShapeAnalysis_Edge::CheckSameParameter (const TopoDS_Edge& edge
         Handle(Geom_Surface)::DownCast(aFaceSurf->Transformed(aFaceLoc.Transformation()));
       Handle(GeomAdaptor_Surface) GAHS = new GeomAdaptor_Surface(aST);
 
-      Adaptor3d_CurveOnSurface ACS(GHPC, GAHS);
+      Handle(Adaptor3d_CurveOnSurface) ACS = new Adaptor3d_CurveOnSurface(GHPC, GAHS);
 
-      if (!ComputeDeviation(aGAC, ACS, SameParameter, maxdev, NbControl - 1))
+      BRepLib_ValidateEdge aBRepLib_ValidateEdge(aGAC, ACS, Standard_True);
+      aBRepLib_ValidateEdge.SetControlPointsNumber(NbControl - 1);
+      aBRepLib_ValidateEdge.Process();
+      aBRepLib_ValidateEdge.UpdateTolerance(maxdev);
+      if (!aBRepLib_ValidateEdge.IsDone())
       {
         myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL2);
       }
diff --git a/src/ShapeAnalysis/ShapeAnalysis_Edge.hxx b/src/ShapeAnalysis/ShapeAnalysis_Edge.hxx
index 7437b07d6d..392fc8ffc8 100644
--- a/src/ShapeAnalysis/ShapeAnalysis_Edge.hxx
+++ b/src/ShapeAnalysis/ShapeAnalysis_Edge.hxx
@@ -175,13 +175,6 @@ public:
   //! having respect to real first, last parameters of thePC 
   Standard_EXPORT Standard_Boolean CheckPCurveRange (const Standard_Real theFirst, const Standard_Real theLast,
                                                      const Handle(Geom2d_Curve)& thePC);
-
-  //! Computes the maximal deviation between the two curve
-  //! representations.
-  //! dev is an input/output parameter and contains the computed
-  //! deviation (should be initialized with 0. for the first call).
-  //! Used by CheckSameParameter().
-  Standard_EXPORT static Standard_Boolean ComputeDeviation (const Adaptor3d_Curve& CRef, const Adaptor3d_Curve& Other, const Standard_Boolean SameParameter, Standard_Real& dev, const Standard_Integer NCONTROL);
   
   //! Checks the first edge is overlapped with second edge.
   //! If distance between two edges is less then theTolOverlap
-- 
2.25.0.windows.1

