0029151: GCC 7.1 warnings "this statement may fall through" [-Wimplicit-fallthrough=]
[occt.git] / src / IntTools / IntTools_EdgeEdge.cxx
old mode 100755 (executable)
new mode 100644 (file)
index 5d257e5..8837919
-// File:       IntTools_EdgeEdge.cxx
-// Created:    Thu Oct 26 10:14:32 2000
-// Author:     Peter KURNEV
-//             <pkv@irinox>
+// Created by: Eugeny MALTCHIKOV
+// Copyright (c) 2013-2014 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 <IntTools_EdgeEdge.ixx>
 
+#include <Bnd_Box.hxx>
+#include <BndLib_Add3dCurve.hxx>
+#include <BOPCol_MapOfInteger.hxx>
 #include <BRep_Tool.hxx>
-
-#include <GCPnts_QuasiUniformDeflection.hxx>
-
+#include <BRepAdaptor_Curve.hxx>
+#include <ElCLib.hxx>
+#include <Geom_BezierCurve.hxx>
+#include <Geom_BSplineCurve.hxx>
+#include <Geom_Line.hxx>
+#include <Geom_Circle.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_Ellipse.hxx>
+#include <Geom_OffsetCurve.hxx>
 #include <GeomAPI_ProjectPointOnCurve.hxx>
-#include <GeomAPI_ExtremaCurveCurve.hxx>
-
-#include <TColStd_ListOfReal.hxx>
-#include <TColStd_ListIteratorOfListOfReal.hxx>
-#include <TColStd_MapOfInteger.hxx>
-#include <TColStd_ListOfReal.hxx>
-#include <TColStd_SequenceOfReal.hxx>
-
-#include <IntTools.hxx>
-#include <IntTools_Range.hxx>
-#include <IntTools_CArray1OfInteger.hxx>
-#include <IntTools_CArray1OfReal.hxx>
-#include <IntTools_Array1OfRange.hxx>
-#include <IntTools_QuickSortRange.hxx>
-#include <IntTools_CompareRange.hxx>
-#include <IntTools_Root.hxx>
-#include <IntTools_Array1OfRoots.hxx>
-#include <IntTools_Compare.hxx>
-#include <IntTools_QuickSort.hxx>
-#include <IntTools_Root.hxx>
-#include <IntTools_CommonPrt.hxx>
-#include <IntTools_SequenceOfRanges.hxx>
-
-#include <gp_Circ.hxx>
-#include <gp_Ax1.hxx>
-#include <gp_Lin.hxx>
 #include <gp_Dir.hxx>
-#include <gp_Pnt.hxx>
-
-#include <gce_MakeCirc.hxx>
-#include <Precision.hxx>
-#include <IntTools.hxx>
-//
-#include <Bnd_Box.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <TopExp.hxx>
-#include <BndLib_Add3dCurve.hxx>
-#include <IntTools_BeanBeanIntersector.hxx>
+#include <gp_Lin.hxx>
+#include <IntTools_CommonPrt.hxx>
+#include <IntTools_EdgeEdge.hxx>
+#include <IntTools_Range.hxx>
 #include <IntTools_Tools.hxx>
-
-#include <CPnts_AbscissaPoint.hxx>
-#include <gp_Circ.hxx>
-#include <Extrema_ExtElC.hxx>
-#include <Extrema_POnCurv.hxx>
-
-//=======================================================================
-//function : IntTools_EdgeEdge::IntTools_EdgeEdge
-//purpose  : 
-//=======================================================================
-  IntTools_EdgeEdge::IntTools_EdgeEdge()
-{
-  myTol1=1.e-7;
-  myTol2=1.e-7;
-  myDiscret=30;
-  myEpsT=1e-12;
-  myEpsNull=1e-12;
-  myDeflection=0.01;
-  myIsDone=Standard_False;
-  myErrorStatus=1;
-  myOrder=Standard_False;
-
-  myPar1=0.;
-  myParallel=Standard_False;
-}
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Iterator.hxx>
+
+static 
+  void BndBuildBox(const BRepAdaptor_Curve& theBAC,
+                   const Standard_Real aT1,
+                   const Standard_Real aT2,
+                   const Standard_Real theTol,
+                   Bnd_Box& theBox);
+static
+  Standard_Real PointBoxDistance(const Bnd_Box& aB,
+                                 const gp_Pnt& aP);
+static 
+  Standard_Integer SplitRangeOnSegments(const Standard_Real aT1, 
+                                        const Standard_Real aT2,
+                                        const Standard_Real theResolution,
+                                        const Standard_Integer theNbSeg,
+                                        IntTools_SequenceOfRanges& theSegments);
+static
+ Standard_Integer DistPC(const Standard_Real aT1, 
+                         const Handle(Geom_Curve)& theC1,
+                         const Standard_Real theCriteria, 
+                         GeomAPI_ProjectPointOnCurve& theProjector,
+                         Standard_Real& aD, 
+                         Standard_Real& aT2,
+                         const Standard_Integer iC = 1);
+static
+ Standard_Integer DistPC(const Standard_Real aT1, 
+                         const Handle(Geom_Curve)& theC1,
+                         const Standard_Real theCriteria,
+                         GeomAPI_ProjectPointOnCurve& theProjector, 
+                         Standard_Real& aD, 
+                         Standard_Real& aT2,
+                         Standard_Real& aDmax,
+                         Standard_Real& aT1max,
+                         Standard_Real& aT2max,
+                         const Standard_Integer iC = 1);
+static
+  Standard_Integer FindDistPC(const Standard_Real aT1A, 
+                              const Standard_Real aT1B,
+                              const Handle(Geom_Curve)& theC1,
+                              const Standard_Real theCriteria,
+                              const Standard_Real theEps,
+                              GeomAPI_ProjectPointOnCurve& theProjector,
+                              Standard_Real& aDmax, 
+                              Standard_Real& aT1max,
+                              Standard_Real& aT2max,
+                              const Standard_Boolean bMaxDist = Standard_True);
+static
+  Standard_Real ResolutionCoeff(const BRepAdaptor_Curve& theBAC,
+                                const IntTools_Range& theRange);
+static
+  Standard_Real Resolution(const Handle(Geom_Curve)& theCurve,
+                           const GeomAbs_CurveType theCurveType,
+                           const Standard_Real theResCoeff,
+                           const Standard_Real theR3D);
+static
+  Standard_Real CurveDeflection(const BRepAdaptor_Curve& theBAC,
+                                const IntTools_Range& theRange);
+static 
+  Standard_Boolean IsClosed(const Handle(Geom_Curve)& theCurve,
+                            const Standard_Real aT1,
+                            const Standard_Real aT2,
+                            const Standard_Real theTol,
+                            const Standard_Real theRes);
+static 
+  Standard_Integer TypeToInteger(const GeomAbs_CurveType theCType);
 
 //=======================================================================
-//function : SetEdge1
-//purpose  : 
-//=======================================================================
-  void IntTools_EdgeEdge::SetEdge1(const TopoDS_Edge& anEdge)
-{
-  myEdge1=anEdge;
-}
-//=======================================================================
-//function : SetEdge2
-//purpose  : 
-//=======================================================================
-  void IntTools_EdgeEdge::SetEdge2(const TopoDS_Edge& anEdge)
-{
-  myEdge2=anEdge;
-}
-
-//=======================================================================
-//function : SetTolerance1
-//purpose  : 
-//=======================================================================
-  void IntTools_EdgeEdge::SetTolerance1(const Standard_Real aTol) 
-{
-  myTol1=aTol;
-} 
-//=======================================================================
-//function : SetTolerance2
-//purpose  : 
-//=======================================================================
-  void IntTools_EdgeEdge::SetTolerance2(const Standard_Real aTol) 
-{
-  myTol2=aTol;
-} 
-
-//=======================================================================
-//function : SetDiscretize
+//function : Prepare
 //purpose  : 
 //=======================================================================
-  void IntTools_EdgeEdge::SetDiscretize(const Standard_Integer aDiscret)
+void IntTools_EdgeEdge::Prepare()
 {
-  myDiscret=aDiscret;
+  GeomAbs_CurveType aCT1, aCT2;
+  Standard_Integer iCT1, iCT2;
+  //
+  myCurve1.Initialize(myEdge1);
+  myCurve2.Initialize(myEdge2);
+  //
+  if (myRange1.First() == 0. && myRange1.Last() == 0.) {
+    myRange1.SetFirst(myCurve1.FirstParameter());
+    myRange1.SetLast (myCurve1.LastParameter());
+  }
+  //
+  if (myRange2.First() == 0. && myRange2.Last() == 0.) {
+    myRange2.SetFirst(myCurve2.FirstParameter());
+    myRange2.SetLast (myCurve2.LastParameter());
+  }
+  //
+  aCT1 = myCurve1.GetType();
+  aCT2 = myCurve2.GetType();
+  //
+  iCT1 = TypeToInteger(aCT1);
+  iCT2 = TypeToInteger(aCT2);
+  //
+  if (iCT1 == iCT2) {
+    if (iCT1 != 0) {
+      //compute deflection
+      Standard_Real aC1, aC2;
+      //
+      aC2 = CurveDeflection(myCurve2, myRange2);
+      aC1 = (aC2 > Precision::Confusion()) ? 
+        CurveDeflection(myCurve1, myRange1) : 1.;
+      //
+      if (aC1 < aC2) {
+        --iCT1;
+      }
+    }
+  }
+  //
+  if (iCT1 < iCT2) {
+    TopoDS_Edge tmpE = myEdge1;
+    myEdge1 = myEdge2;
+    myEdge2 = tmpE;
+    //
+    BRepAdaptor_Curve tmpC = myCurve1;
+    myCurve1 = myCurve2;
+    myCurve2 = tmpC;
+    //
+    IntTools_Range tmpR = myRange1;
+    myRange1 = myRange2;
+    myRange2 = tmpR;
+    //
+    mySwap = Standard_True;
+  }
+  //
+  Standard_Real aTolAdd = myFuzzyValue / 2.;
+  myTol1 = myCurve1.Tolerance() + aTolAdd;
+  myTol2 = myCurve2.Tolerance() + aTolAdd;
+  myTol = myTol1 + myTol2;
+  //
+  if (iCT1 != 0 || iCT2 != 0) {
+    Standard_Real f, l, aTM;
+    //
+    myGeom1 = BRep_Tool::Curve(myEdge1, f, l);
+    myGeom2 = BRep_Tool::Curve(myEdge2, f, l);
+    //
+    myResCoeff1 = ResolutionCoeff(myCurve1, myRange1);
+    myResCoeff2 = ResolutionCoeff(myCurve2, myRange2);
+    //
+    myRes1 = Resolution(myCurve1.Curve().Curve(), myCurve1.GetType(), myResCoeff1, myTol1);
+    myRes2 = Resolution(myCurve2.Curve().Curve(), myCurve2.GetType(), myResCoeff2, myTol2);
+    //
+    myPTol1 = 5.e-13;
+    aTM = Max(fabs(myRange1.First()), fabs(myRange1.Last()));
+    if (aTM > 999.) {
+      myPTol1 = 5.e-16 * aTM;
+    }
+    //
+    myPTol2 = 5.e-13;
+    aTM = Max(fabs(myRange2.First()), fabs(myRange2.Last()));
+    if (aTM > 999.) {
+      myPTol2 = 5.e-16 * aTM;
+    }
+  }
 }
-//=======================================================================
-//function : SetDeflection
-//purpose  : 
-//=======================================================================
-  void IntTools_EdgeEdge::SetDeflection(const Standard_Real aDefl) 
-{
-  myDeflection=aDefl;
-} 
-//=======================================================================
-//function : SetEpsilonT
-//purpose  : 
-//=======================================================================
-  void IntTools_EdgeEdge::SetEpsilonT(const Standard_Real anEpsT) 
-{
-  myEpsT=anEpsT;
-} 
-//=======================================================================
-//function : SetEpsilonNull
-//purpose  : 
-//=======================================================================
-  void IntTools_EdgeEdge::SetEpsilonNull(const Standard_Real anEpsNull) 
-{
-  myEpsNull=anEpsNull;
-} 
-
-//=======================================================================
-//function : SetRange1
-//purpose  : 
-//=======================================================================
-  void IntTools_EdgeEdge::SetRange1(const Standard_Real aFirst,
-                                   const Standard_Real aLast) 
-{
-  myRange1.SetFirst (aFirst);
-  myRange1.SetLast  (aLast);
-} 
-//=======================================================================
-//function : SetRange2
-//purpose  : 
-//=======================================================================
-  void IntTools_EdgeEdge::SetRange2(const Standard_Real aFirst,
-                                   const Standard_Real aLast) 
-{
-  myRange2.SetFirst (aFirst);
-  myRange2.SetLast  (aLast);
-} 
-
-//=======================================================================
-//function : SetRange1
-//purpose  : 
-//=======================================================================
-  void IntTools_EdgeEdge::SetRange1(const IntTools_Range& aRange) 
-{
-  myRange1.SetFirst (aRange.First());
-  myRange1.SetLast  (aRange.Last());
-} 
-//=======================================================================
-//function : SetRange2
-//purpose  : 
-//=======================================================================
-  void IntTools_EdgeEdge::SetRange2(const IntTools_Range& aRange) 
-{
-  myRange2.SetFirst (aRange.First());
-  myRange2.SetLast  (aRange.Last());
-} 
 
-//=======================================================================
-//function : Order
-//purpose  : 
-//=======================================================================
-  Standard_Boolean IntTools_EdgeEdge::Order()const 
-{
-  return myOrder;
-} 
-//=======================================================================
-//function : IsDone
-//purpose  : 
-//=======================================================================
-  Standard_Boolean IntTools_EdgeEdge::IsDone()const 
-{
-  return myIsDone;
-} 
-//=======================================================================
-//function : ErrorStatus
-//purpose  : 
-//=======================================================================
-  Standard_Integer IntTools_EdgeEdge::ErrorStatus()const 
-{
-  return myErrorStatus;
-} 
-
-//=======================================================================
-//function : CommonParts
-//purpose  : 
-//=======================================================================
-  const IntTools_SequenceOfCommonPrts& IntTools_EdgeEdge::CommonParts() const 
-{
-  return mySeqOfCommonPrts;
-}
-//=======================================================================
-//function : Range1
-//purpose  : 
-//=======================================================================
-  const IntTools_Range&  IntTools_EdgeEdge::Range1() const
-{
-  return myRange1;
-} 
-//=======================================================================
-//function : Range2
-//purpose  : 
-//=======================================================================
-  const IntTools_Range&  IntTools_EdgeEdge::Range2() const
-{
-  return myRange2;
-}
 //=======================================================================
 //function : Perform
 //purpose  : 
 //=======================================================================
-  void IntTools_EdgeEdge::Perform() 
+void IntTools_EdgeEdge::Perform()
 {
-  Standard_Integer i, pri;
-  IntTools_CommonPrt aCommonPrt;
-  GeomAbs_CurveType   aCTFrom, aCTTo;
-  
-  myErrorStatus=0;
+  //1. Check data
   CheckData();
-  if (myErrorStatus)
-    return;
-  //
-  // ProjectableRanges, etc
-  Prepare();
   if (myErrorStatus) {
     return;
   }
   //
-
-  if(myCFrom.GetType() == GeomAbs_Line && myCTo.GetType() == GeomAbs_Line) {
+  //2. Prepare Data
+  Prepare();
+  //
+  //3.1. Check Line/Line case
+  if (myCurve1.GetType() == GeomAbs_Line &&
+      myCurve2.GetType() == GeomAbs_Line) {
     ComputeLineLine();
-    if (myOrder) {
-      TopoDS_Edge aTmp;
-      aTmp=myEdge1;
-      myEdge1=myEdge2;
-      myEdge2=aTmp;
-    }
-    return;
-  }
-
-  IntTools_BeanBeanIntersector anIntersector(myCFrom, myCTo, myTolFrom, myTolTo);
-  anIntersector.SetBeanParameters(Standard_True, myTminFrom, myTmaxFrom);
-  anIntersector.SetBeanParameters(Standard_False, myTminTo, myTmaxTo);
-  anIntersector.Perform();
-  
-  if(!anIntersector.IsDone()) {
-    myIsDone = Standard_False;
     return;
   }
-  aCTFrom = myCFrom.GetType();
-  aCTTo   = myCTo.GetType();
-  
-  aCommonPrt.SetEdge1(myCFrom.Edge());
-  aCommonPrt.SetEdge2(myCTo.Edge());
-
-  for(Standard_Integer r = 1; r <= anIntersector.Result().Length(); r++) {
-    const IntTools_Range& aRange = anIntersector.Result().Value(r);
-    
-    if(IsProjectable(IntTools_Tools::IntermediatePoint(aRange.First(), aRange.Last()))) {
-      aCommonPrt.SetRange1(aRange.First(), aRange.Last());
-
-      if(((aRange.First() - myTminFrom) < Precision::PConfusion()) &&
-        ((myTmaxFrom  - aRange.Last()) < Precision::PConfusion())) {
-       aCommonPrt.SetAllNullFlag(Standard_True);
-      }
-      mySeqOfCommonPrts.Append(aCommonPrt);
-    }
-  }
-  
-  Standard_Integer aNbCommonPrts;
-  aNbCommonPrts=mySeqOfCommonPrts.Length();
-  
-  for (i=1; i<=aNbCommonPrts; i++) {
-    IntTools_CommonPrt& aCmnPrt=mySeqOfCommonPrts.ChangeValue(i);
-    pri=FindRangeOnCurve2 (aCmnPrt); 
-    
-    if (pri) {
-      myErrorStatus=10;
+  //
+  if (myQuickCoincidenceCheck) {
+    if (IsCoincident()) {
+      Standard_Real aT11, aT12, aT21, aT22;
+      //
+      myRange1.Range(aT11, aT12);
+      myRange2.Range(aT21, aT22);
+      AddSolution(aT11, aT12, aT21, aT22, TopAbs_EDGE);
       return;
     }
   }
   //
-  
-  {
-    // Line Circle's Common Parts treatement
-    if ((aCTFrom==GeomAbs_Line   && aCTTo==GeomAbs_Circle) || 
-       (aCTFrom==GeomAbs_Circle && aCTTo==GeomAbs_Line) ||
-       (aCTFrom==GeomAbs_Ellipse && aCTTo==GeomAbs_Ellipse) ||
-       (aCTFrom==GeomAbs_Circle && aCTTo==GeomAbs_Circle))  {
-      for (i=1; i<=aNbCommonPrts; i++) {
-       IntTools_CommonPrt& aCP=mySeqOfCommonPrts(i);
-       TopAbs_ShapeEnum aType=aCP.Type();
-       Standard_Boolean bIsTouch;
-       Standard_Real aTx1, aTx2;
-       //
-       if ((aType==TopAbs_EDGE) && !aCommonPrt.AllNullFlag()) {
-         bIsTouch=CheckTouch (aCP, aTx1, aTx2);
-         if (bIsTouch) {
-           aCP.SetType(TopAbs_VERTEX);
-           aCP.SetVertexParameter1(aTx1);
-           aCP.SetRange1 (aTx1, aTx1);
-           IntTools_Range& aRange2=(aCP.ChangeRanges2()).ChangeValue(1);
-           aRange2.SetFirst(aTx2);
-           aRange2.SetLast (aTx2);
-         }
-       }
-       //
-       if (aType==TopAbs_VERTEX) {
-         if(aCTFrom==GeomAbs_Line || aCTTo==GeomAbs_Line) {
-           bIsTouch=CheckTouchVertex (aCP, aTx1, aTx2);
-           if (bIsTouch) {
-             aCP.SetVertexParameter1(aTx1);
-             aCP.SetRange1 (aTx1, aTx1);
-             IntTools_Range& aRange2=(aCP.ChangeRanges2()).ChangeValue(1);
-             aRange2.SetFirst(aTx2);
-             aRange2.SetLast (aTx2);
-           }
-         }
-       }
-      }
-    }
-  }
+  IntTools_SequenceOfRanges aRanges1, aRanges2;
+  //
+  //3.2. Find ranges containig solutions
+  Standard_Boolean bSplit2;
+  FindSolutions(aRanges1, aRanges2, bSplit2);
+  //
+  //4. Merge solutions and save common parts
+  MergeSolutions(aRanges1, aRanges2, bSplit2);
+}
 
-  if (myOrder) {
-    TopoDS_Edge aTmp;
-    aTmp=myEdge1;
-    myEdge1=myEdge2;
-    myEdge2=aTmp;
-  }
-    
-  myIsDone=Standard_True;
-} 
 //=======================================================================
-//function : CheckData
+//function :  IsCoincident
 //purpose  : 
 //=======================================================================
-  void IntTools_EdgeEdge::CheckData()
+Standard_Boolean IntTools_EdgeEdge::IsCoincident() 
 {
-  if (BRep_Tool::Degenerated(myEdge1)) {
-    myErrorStatus=2;
-  }
-  if (!BRep_Tool::IsGeometric(myEdge1)) { 
-     myErrorStatus=3;
-  }
-  if (BRep_Tool::Degenerated(myEdge2)) {
-    myErrorStatus=4;
+  Standard_Integer i, iCnt, aNbSeg, aNbP2;
+  Standard_Real dT, aT1, aCoeff, aTresh, aD;
+  Standard_Real aT11, aT12, aT21, aT22;
+  GeomAPI_ProjectPointOnCurve aProjPC;
+  gp_Pnt aP1;
+  //
+  aTresh=0.5;
+  aNbSeg=23;
+  myRange1.Range(aT11, aT12);
+  myRange2.Range(aT21, aT22);
+  //
+  aProjPC.Init(myGeom2, aT21, aT22);
+  //
+  dT=(aT12-aT11)/aNbSeg;
+  //
+  iCnt=0;
+  for(i=0; i <= aNbSeg; ++i) {
+    aT1 = aT11+i*dT;
+    myGeom1->D0(aT1, aP1);
+    //
+    aProjPC.Perform(aP1);
+    aNbP2=aProjPC.NbPoints();
+    if (!aNbP2) {
+      continue;
+    }
+    //
+    aD=aProjPC.LowerDistance();
+    if(aD < myTol) {
+      ++iCnt; 
+    }
   }
-  if (!BRep_Tool::IsGeometric(myEdge2)) { 
-     myErrorStatus=5;
-  } 
+  //
+  aCoeff=(Standard_Real)iCnt/((Standard_Real)aNbSeg+1);
+  return aCoeff > aTresh;
 }
 //=======================================================================
-//function : Prepare
+//function : FindSolutions
 //purpose  : 
 //=======================================================================
-  void IntTools_EdgeEdge::Prepare() 
+void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
+                                      IntTools_SequenceOfRanges& theRanges2,
+                                      Standard_Boolean& bSplit2)
 {
-  Standard_Real aLE1, aLE2;
-  
+  Standard_Boolean bIsClosed2;
+  Standard_Real aT11, aT12, aT21, aT22;
+  Bnd_Box aB2;
   //
-  // 1.Prepare Curves' data
-  aLE1 = 0.;
-
-  if (!BRep_Tool::Degenerated(myEdge1) &&
-      BRep_Tool::IsGeometric(myEdge1)) {
-    Standard_Real f, l;
-    const Handle(Geom_Curve)&  aCurve   =BRep_Tool::Curve  (myEdge1, f, l);
-    GeomAdaptor_Curve   aGACurve   (aCurve, myRange1.First(), myRange1.Last());
-    aLE1 = CPnts_AbscissaPoint::Length(aGACurve, myRange1.First(), myRange1.Last());
+  bSplit2 = Standard_False;
+  myRange1.Range(aT11, aT12);
+  myRange2.Range(aT21, aT22);
+  //
+  bIsClosed2 = IsClosed(myGeom2, aT21, aT22, myTol2, myRes2);
+  //
+  if (bIsClosed2) {
+    Bnd_Box aB1;
+    BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
+    //
+    gp_Pnt aP = myGeom2->Value(aT21);
+    bIsClosed2 = !aB1.IsOut(aP);
   }
-  aLE2 = 0.;
-
-  if (!BRep_Tool::Degenerated(myEdge2) &&
-      BRep_Tool::IsGeometric(myEdge2)) {
-    Standard_Real f, l;
-    const Handle(Geom_Curve)&  aCurve   =BRep_Tool::Curve  (myEdge2, f, l);
-    GeomAdaptor_Curve   aGACurve   (aCurve, myRange2.First(), myRange2.Last());
-    aLE2 = CPnts_AbscissaPoint::Length(aGACurve, myRange2.First(), myRange2.Last());
+  //
+  if (!bIsClosed2) {
+    BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
+    FindSolutions(myRange1, myRange2, aB2, theRanges1, theRanges2);
+    return;
   }
-  
-  if (aLE1 <= aLE2) {
-    myCFrom.Initialize(myEdge1);
-    myCTo  .Initialize(myEdge2);
-    myTolFrom=myTol1;
-    myTolTo=myTol2;
-    myTminFrom=myRange1.First();
-    myTmaxFrom=myRange1.Last ();
-    myTminTo  =myRange2.First();
-    myTmaxTo  =myRange2.Last ();
+  //
+  if (!CheckCoincidence(aT11, aT12, aT21, aT22, myTol, myRes1)) {
+    theRanges1.Append(myRange1);
+    theRanges2.Append(myRange2);
+    return;
   }
-  else {
-    myCFrom.Initialize(myEdge2);
-    myCTo  .Initialize(myEdge1);
-    myTolFrom=myTol2;
-    myTolTo=myTol1;
-    myTminFrom=myRange2.First();
-    myTmaxFrom=myRange2.Last ();
-    myTminTo  =myRange1.First();
-    myTmaxTo  =myRange1.Last ();
-
-    myOrder=Standard_True; // revesed order
+  //
+  Standard_Integer i, j, aNb1, aNb2;
+  IntTools_SequenceOfRanges aSegments1, aSegments2;
+  //
+  aNb1 = IsClosed(myGeom1, aT11, aT12, myTol1, myRes1) ? 2 : 1;
+  aNb2 = 2;
+  //
+  aNb1 = SplitRangeOnSegments(aT11, aT12, myRes1, aNb1, aSegments1);
+  aNb2 = SplitRangeOnSegments(aT21, aT22, myRes2, aNb2, aSegments2);
+  //
+  for (i = 1; i <= aNb1; ++i) {
+    const IntTools_Range& aR1 = aSegments1(i);
+    for (j = 1; j <= aNb2; ++j) {
+      const IntTools_Range& aR2 = aSegments2(j);
+      BndBuildBox(myCurve2, aR2.First(), aR2.Last(), myTol2, aB2);
+      FindSolutions(aR1, aR2, aB2, theRanges1, theRanges2);
+    }
   }
   //
-  // 2.Prepare myCriteria
-  GeomAbs_CurveType aCT1, aCT2;
-  aCT1=myCFrom.GetType();
-  aCT2=myCTo.GetType()  ;
-  
-  Standard_Real aTol1, aTol2;
-  aTol1=(aCT1==GeomAbs_BSplineCurve||
-        aCT1==GeomAbs_BezierCurve) ? 1.20*myTol1 : myTol1;
-  
-  aTol2=(aCT2==GeomAbs_BSplineCurve||
-        aCT2==GeomAbs_BezierCurve) ? 1.20*myTol2 : myTol2;
-  
-  myCriteria=aTol1+aTol2;
+  bSplit2 = aNb2 > 1;
 }
 
 //=======================================================================
-//function : FindProjectableRoot
+//function : FindSolutions
 //purpose  : 
 //=======================================================================
-  void IntTools_EdgeEdge::FindProjectableRoot (const Standard_Real tt1,
-                                              const Standard_Real tt2,
-                                              const Standard_Integer ff1,
-                                              const Standard_Integer ff2,
-                                              Standard_Real& tRoot)
+void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
+                                      const IntTools_Range& theR2,
+                                      const Bnd_Box& theBox2,
+                                      IntTools_SequenceOfRanges& theRanges1,
+                                      IntTools_SequenceOfRanges& theRanges2)
 {
-  Standard_Real tm, t1, t2;
-  Standard_Integer anIsProj1, anIsProj2, anIsProjm;
+  Standard_Boolean bOut, bStop, bThin;
+  Standard_Real aT11, aT12, aT21, aT22;
+  Standard_Real aTB11, aTB12, aTB21, aTB22;
+  Standard_Real aSmallStep1, aSmallStep2;
+  Standard_Integer iCom;
+  Bnd_Box aB1, aB2;
   //
-  // Root can be on the ends of [tt1, tt2]
-  Standard_Integer anOldErrorStatus=myErrorStatus;
-
-  t1=DistanceFunction(tt1);
-  myErrorStatus=anOldErrorStatus;
-  if (fabs(t1)<myCriteria) {
-    tRoot=tt1;
-    return;
-  }
-
-  t1=DistanceFunction(tt2);
-  myErrorStatus=anOldErrorStatus;
-  if (fabs(t1)<myCriteria) {
-    tRoot=tt2;
+  theR1.Range(aT11, aT12);
+  theR2.Range(aT21, aT22);
+  //
+  aB2 = theBox2;
+  //
+  bThin = Standard_False;
+  bStop = Standard_False;
+  iCom  = 1;
+  //
+  do {
+    aTB11 = aT11;
+    aTB12 = aT12;
+    aTB21 = aT21;
+    aTB22 = aT22;
+    //
+    //1. Build box for first edge and find parameters 
+    //   of the second one in that box
+    BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
+    bOut = aB1.IsOut(aB2);
+    if (bOut) {
+      break;
+    }
+    //
+    bThin = ((aT12 - aT11) < myRes1) ||
+      (aB1.IsXThin(myTol) && aB1.IsYThin(myTol) && aB1.IsZThin(myTol));
+    //
+    bOut = !FindParameters(myCurve2, aTB21, aTB22, myTol2, myRes2, myPTol2, 
+                           myResCoeff2, aB1, aT21, aT22);
+    if (bOut || bThin) {
+      break;
+    }
+    //
+    //2. Build box for second edge and find parameters 
+    //   of the first one in that box
+    BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
+    bOut = aB1.IsOut(aB2);
+    if (bOut) {
+      break;
+    }
+    //
+    bThin = ((aT22 - aT21) < myRes2) ||
+      (aB2.IsXThin(myTol) && aB2.IsYThin(myTol) && aB2.IsZThin(myTol));
+    //
+    bOut = !FindParameters(myCurve1, aTB11, aTB12, myTol1, myRes1, myPTol1,
+                           myResCoeff1, aB2, aT11, aT12);
+    //
+    if (bOut || bThin) {
+      break;
+    }
+    //
+    //3. Check if it makes sense to continue
+    aSmallStep1 = (aTB12 - aTB11) / 250.;
+    aSmallStep2 = (aTB22 - aTB21) / 250.;
+    //
+    if (aSmallStep1 < myRes1) {
+      aSmallStep1 = myRes1;
+    }
+    if (aSmallStep2 < myRes2) {
+      aSmallStep2 = myRes2;
+    }
+    //
+    if (((aT11 - aTB11) < aSmallStep1) && ((aTB12 - aT12) < aSmallStep1) &&
+        ((aT21 - aTB21) < aSmallStep2) && ((aTB22 - aT22) < aSmallStep2)) {
+      bStop = Standard_True;
+    }
+    //
+  } while (!bStop);
+  //
+  if (bOut) {
+    //no intersection;
     return;
   }
-  
-  
-  //
-  // Root is inside [tt1, tt2]
-  t1=tt1;  
-  t2=tt2;
-  anIsProj1=ff1;
-  anIsProj2=ff2;
-  
-  while (1) {
-    if (fabs(t1-t2) < myEpsT) {
-      tRoot=.5*(t1+t2);
-      return;
-    }
-    tm=.5*(t1+t2);
-    anIsProjm=IsProjectable(tm);
-    
-    if (anIsProjm != anIsProj1) {
-      t2=tm;
-      anIsProj2=anIsProjm;
+  //
+  if (!bThin) {
+    //check curves for coincidence on the ranges
+    iCom = CheckCoincidence(aT11, aT12, aT21, aT22, myTol, myRes1);
+    if (!iCom) {
+      bThin = Standard_True;
     }
-    else {
-      t1=tm;
-      anIsProj1=anIsProjm;
+  }
+  //
+  if (bThin) {
+    if (iCom != 0) {
+      //check intermediate points
+      Standard_Boolean bSol;
+      Standard_Real aT1;
+      gp_Pnt aP1;
+      GeomAPI_ProjectPointOnCurve aProjPC;
+      //
+      aT1 = (aT11 + aT12) * .5;
+      myGeom1->D0(aT1, aP1);
+      //
+      aProjPC.Init(myGeom2, aT21, aT22);
+      aProjPC.Perform(aP1);
+      //
+      if (aProjPC.NbPoints()) {
+        bSol = aProjPC.LowerDistance() <= myTol;
+      }
+      else {
+        Standard_Real aT2;
+        gp_Pnt aP2;
+        //
+        aT2 = (aT21 + aT22) * .5;
+        myGeom2->D0(aT2, aP2);
+        //
+        bSol = aP1.IsEqual(aP2, myTol);
+      }
+      //
+      if (!bSol) {
+        return;
+      }
     }
+    //add common part
+    IntTools_Range aR1(aT11, aT12), aR2(aT21, aT22);
+    //
+    theRanges1.Append(aR1);
+    theRanges2.Append(aR2);
+    return;
+  }
+  //
+  if (!IsIntersection(aT11, aT12, aT21, aT22)) {
+    return;
+  }
+  //
+  //split ranges on segments and repeat
+  Standard_Integer i, aNb1;
+  IntTools_SequenceOfRanges aSegments1;
+  //
+  IntTools_Range aR2(aT21, aT22);
+  BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
+  //
+  aNb1 = SplitRangeOnSegments(aT11, aT12, myRes1, 3, aSegments1);
+  for (i = 1; i <= aNb1; ++i) {
+    const IntTools_Range& aR1 = aSegments1(i);
+    FindSolutions(aR1, aR2, aB2, theRanges1, theRanges2);
   }
 }
 
 //=======================================================================
-//function : IsProjectable
+//function : FindParameters
 //purpose  : 
 //=======================================================================
-  Standard_Integer IntTools_EdgeEdge::IsProjectable(const Standard_Real t) const
-{ 
-  Standard_Integer aNbProj;
-  Standard_Real f, l;
-  gp_Pnt aPFrom;
-
-  GeomAPI_ProjectPointOnCurve aProjector;
-  const TopoDS_Edge& aEFrom=myCFrom.Edge();
-  Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (aEFrom, f, l);
-  aCurveFrom->D0(t, aPFrom);
-  
-  Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (myCTo.Edge(), f, l);
-  //modified by NIZNHY-PKV Mon Jun  8 09:52:09 2009f
-  //aProjector.Init(aPFrom, aCurveTo, myTminTo, myTmaxTo);
-  aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
-  aProjector.Perform(aPFrom);
-  //modified by NIZNHY-PKV Mon Jun  8 09:53:00 2009t
-  aNbProj=aProjector.NbPoints();
-  //
-  if (myCTo.GetType()==GeomAbs_Circle) {
-    gp_Circ aCirc=myCTo.Circle();
-    const gp_Pnt& aCenter=aCirc.Location();
-    if (aCenter.SquareDistance(aPFrom) < 1.e-7) {
-      aNbProj=1;
+Standard_Boolean IntTools_EdgeEdge::FindParameters(const BRepAdaptor_Curve& theBAC,
+                                                   const Standard_Real aT1, 
+                                                   const Standard_Real aT2,
+                                                   const Standard_Real theTol,
+                                                   const Standard_Real theRes,
+                                                   const Standard_Real thePTol,
+                                                   const Standard_Real theResCoeff,
+                                                   const Bnd_Box& theCBox,
+                                                   Standard_Real& aTB1, 
+                                                   Standard_Real& aTB2)
+{
+  Standard_Boolean bRet;
+  Standard_Integer aC, i;
+  Standard_Real aCf, aDiff, aDt, aT, aTB, aTOut, aTIn;
+  Standard_Real aDist, aDistP;
+  gp_Pnt aP;
+  Bnd_Box aCBx;
+  //
+  bRet = Standard_False;
+  aCf = 0.6180339887498948482045868343656;// =0.5*(1.+sqrt(5.))/2.;
+  aCBx = theCBox;
+  aCBx.SetGap(aCBx.GetGap() + theTol);
+  //
+  const Handle(Geom_Curve)& aCurve = theBAC.Curve().Curve();
+  const GeomAbs_CurveType aCurveType = theBAC.GetType();
+  Standard_Real aMaxDt = (aT2 - aT1) * 0.01;
+  //
+  for (i = 0; i < 2; ++i) {
+    aTB = !i ? aT1 : aT2;
+    aT = !i ? aT2 : aTB1;
+    aC = !i ? 1 : -1;
+    aDt = theRes;
+    aDistP = 0.;
+    bRet = Standard_False;
+    Standard_Real k = 1;
+    //looking for the point on the edge which is in the box;
+    while (aC*(aT-aTB) >= 0) {
+      theBAC.D0(aTB, aP);
+      aDist = PointBoxDistance(theCBox, aP);
+      if (aDist > theTol) {
+        if (aDistP > 0.) {
+          Standard_Boolean toGrow = Standard_False;
+          if (Abs(aDistP - aDist) / aDistP < 0.1) {
+            aDt = Resolution(aCurve, aCurveType, theResCoeff, k*aDist);
+            if (aDt < aMaxDt)
+            {
+              toGrow = Standard_True;
+              k *= 2;
+            }
+          }
+          if (!toGrow) {
+            k = 1;
+            aDt = Resolution(aCurve, aCurveType, theResCoeff, aDist);
+          }
+        }
+        aTB += aC*aDt;
+      } else {
+        bRet = Standard_True;
+        break;
+      }
+      aDistP = aDist;
+    }
+    //
+    if (!bRet) {
+      if (!i) {
+        //edge is out of the box;
+        return bRet;
+      } else {
+        bRet = !bRet;
+        aTB = aTB1;
+        aDt = aT2 - aTB1;
+      }
+    }
+    //
+    aT = !i ? aT1 : aT2;
+    if (aTB != aT) {
+      //one point IN, one point OUT; looking for the bounding point;
+      aTIn = aTB;
+      aTOut = aTB - aC*aDt;
+      aDiff = aTIn - aTOut;
+      while (fabs(aDiff) > thePTol) {
+        aTB = aTOut + aDiff*aCf;
+        theBAC.D0(aTB, aP);
+        if (aCBx.IsOut(aP)) {
+          aTOut = aTB;
+        } else {
+          aTIn = aTB;
+        }
+        aDiff = aTIn - aTOut;
+      }
+    }
+    if (!i) {
+      aTB1 = aTB;
+    } else {
+      aTB2 = aTB;
     }
   }
-  return aNbProj;
+  return bRet;
 }
 
 //=======================================================================
-//function : DistanceFunction
+//function : MergeSolutions
 //purpose  : 
 //=======================================================================
-  Standard_Real IntTools_EdgeEdge::DistanceFunction(const Standard_Real t)//const
+void IntTools_EdgeEdge::MergeSolutions(const IntTools_SequenceOfRanges& theRanges1, 
+                                       const IntTools_SequenceOfRanges& theRanges2,
+                                       const Standard_Boolean bSplit2)
 {
-  Standard_Real aD, f, l;
-  GeomAPI_ProjectPointOnCurve aProjector;
-  gp_Pnt aPFrom; //ZZ , aPTo;
-
-  const TopoDS_Edge& aEFrom=myCFrom.Edge();
-  const TopoDS_Edge& aETo  =myCTo.Edge();
-  
-  Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (aEFrom, f, l);
-  aCurveFrom->D0 (t, aPFrom);
-  Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (aETo, f, l);
-
-  if (myCTo.GetType()==GeomAbs_Circle) {
-    gp_Circ aCirc=myCTo.Circle();
-    const gp_Pnt& aCenter=aCirc.Location();
-    const gp_Ax1& anAx1  =aCirc.Axis();
-    const gp_Dir& aDir   =anAx1.Direction();
-    gp_Lin aLin(aCenter, aDir);
-    Standard_Real dPFromLin=aLin.Distance(aPFrom);
-    if (dPFromLin < 1.e-7) {
-      gp_Pnt anAnyPTo;
-      aCurveTo->D0 (myTminTo, anAnyPTo);
-      aD=aPFrom.Distance(anAnyPTo);
-      
-      aD=aD-myCriteria;
-      return aD; 
-    }
+  Standard_Integer aNbCP = theRanges1.Length();
+  if (aNbCP == 0) {
+    return;
   }
-  
-  //modified by NIZNHY-PKV Mon Jun  8 09:54:19 2009f
-  //aProjector.Init(aPFrom, aCurveTo, myTminTo, myTmaxTo);
-  aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
-  aProjector.Perform(aPFrom);
-  //modified by NIZNHY-PKV Mon Jun  8 09:55:11 2009t
-  //
-  Standard_Integer j, aNbPoints;
-  //
-  aNbPoints =aProjector.NbPoints();
-  if (!aNbPoints) {
-    for (j=0; j<=1; j++) {
-      Standard_Real tt;
-      tt=t+myEpsT;
-      if (j) {
-       tt=t-myEpsT;
+  //
+  IntTools_Range aRi1, aRi2, aRj1, aRj2;
+  Standard_Boolean bCond;
+  Standard_Integer i, j;
+  TopAbs_ShapeEnum aType;
+  Standard_Real aT11, aT12, aT21, aT22;
+  Standard_Real aTi11, aTi12, aTi21, aTi22;
+  Standard_Real aTj11, aTj12, aTj21, aTj22;
+  Standard_Real aRes1, aRes2, dTR1, dTR2;
+  BOPCol_MapOfInteger aMI;
+  //
+  aRes1 = Resolution(myCurve1.Curve().Curve(), 
+                     myCurve1.GetType(), myResCoeff1, myTol);
+  aRes2 = Resolution(myCurve2.Curve().Curve(), 
+                     myCurve2.GetType(), myResCoeff2, myTol);
+  //
+  myRange1.Range(aT11, aT12);
+  myRange2.Range(aT21, aT22);
+  dTR1 = 20*aRes1;
+  dTR2 = 20*aRes2;
+  aType = TopAbs_VERTEX;
+  //
+  for (i = 1; i <= aNbCP;) {
+    if (aMI.Contains(i)) {
+      ++i;
+      continue;
+    }
+    //
+    aRi1 = theRanges1(i);
+    aRi2 = theRanges2(i);
+    //
+    aRi1.Range(aTi11, aTi12);
+    aRi2.Range(aTi21, aTi22);
+    //
+    aMI.Add(i);
+    //
+    for (j = i+1; j <= aNbCP; ++j) {
+      if (aMI.Contains(j)) {
+        continue;
       }
-       
-      aCurveFrom->D0 (tt, aPFrom);
-      //modified by NIZNHY-PKV Mon Jun  8 09:54:52 2009f
-      //aProjector.Init(aPFrom, aCurveTo, myTminTo, myTmaxTo);
-      aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
-      aProjector.Perform(aPFrom);
-      //modified by NIZNHY-PKV Mon Jun  8 09:55:07 2009t
-      aNbPoints=aProjector.NbPoints();
-      if (aNbPoints) {
-       break;
+      //
+      aRj1 = theRanges1(j);
+      aRj2 = theRanges2(j);
+      //
+      aRj1.Range(aTj11, aTj12);
+      aRj2.Range(aTj21, aTj22);
+      //
+      bCond = (fabs(aTi12 - aTj11) < dTR1) ||
+        (bSplit2 && (fabs(aTj12 - aTi11) < dTR1));
+      if (bCond && bSplit2) {
+        bCond = (fabs((Max(aTi22, aTj22) - Min(aTi21, aTj21)) - 
+                      ((aTi22 - aTi21) + (aTj22 - aTj21))) < dTR2);
+      }
+      //
+      if (bCond) {
+        aTi11 = Min(aTi11, aTj11);
+        aTi12 = Max(aTi12, aTj12);
+        aTi21 = Min(aTi21, aTj21);
+        aTi22 = Max(aTi22, aTj22);
+        aMI.Add(j);
+      }
+      else if (!bSplit2) {
+        i = j;
+        break;
       }
     }
+    //
+    if (((fabs(aT11 - aTi11) < myRes1) && (fabs(aT12 - aTi12) < myRes1)) ||
+        ((fabs(aT21 - aTi21) < myRes2) && (fabs(aT22 - aTi22) < myRes2))) {
+      aType = TopAbs_EDGE;
+      myCommonParts.Clear();
+    }
+    //
+    AddSolution(aTi11, aTi12, aTi21, aTi22, aType);
+    if (aType == TopAbs_EDGE) {
+      break;
+    }
+    //
+    if (bSplit2) {
+      ++i;
+    }
   }
-  
-
-  if (!aNbPoints) {
-    // Can't find projection.
-    myErrorStatus=11;
-    aD=100.;
-    return aD;
-  }
-    
-  aD=aProjector.LowerDistance();
-  //
-  aD=aD-myCriteria;
-  return aD; 
 }
 
 //=======================================================================
-//function : DerivativeFunction
+//function : AddSolution
 //purpose  : 
 //=======================================================================
-  Standard_Real IntTools_EdgeEdge::DerivativeFunction(const Standard_Real t2)
+void IntTools_EdgeEdge::AddSolution(const Standard_Real aT11,
+                                    const Standard_Real aT12,
+                                    const Standard_Real aT21,
+                                    const Standard_Real aT22,
+                                    const TopAbs_ShapeEnum theType)
 {
-  Standard_Real t1, t3, aD1, aD2, aD3;
-  Standard_Real dt=1.e-7;
-  t1=t2-dt;
-  aD1=DistanceFunction(t1);
-  t3=t2+dt;
-  aD3=DistanceFunction(t3);
-  
-  aD2=.5*(aD3-aD1)/dt;
-  return aD2; 
+  IntTools_CommonPrt aCPart;
+  //
+  aCPart.SetType(theType);
+  if (!mySwap) {
+    aCPart.SetEdge1(myEdge1);
+    aCPart.SetEdge2(myEdge2);
+    aCPart.SetRange1(aT11, aT12);
+    aCPart.AppendRange2(aT21, aT22);
+  } else {
+    aCPart.SetEdge1(myEdge2);
+    aCPart.SetEdge2(myEdge1);
+    aCPart.SetRange1(aT21, aT22);
+    aCPart.AppendRange2(aT11, aT12);
+  }
+  //
+  if (theType == TopAbs_VERTEX) {
+    Standard_Real aT1, aT2;
+    //
+    FindBestSolution(aT11, aT12, aT21, aT22, aT1, aT2);
+    //
+    if (!mySwap) {
+      aCPart.SetVertexParameter1(aT1);
+      aCPart.SetVertexParameter2(aT2);
+    } else {
+      aCPart.SetVertexParameter1(aT2);
+      aCPart.SetVertexParameter2(aT1);
+    }
+  }
+  myCommonParts.Append(aCPart);
 }
 
 //=======================================================================
-//function : FindGoldRoot
-//purpose  : [private]
+//function : FindBestSolution
+//purpose  : 
 //=======================================================================
-  Standard_Real IntTools_EdgeEdge::FindGoldRoot (const Standard_Real tA,
-                                                const Standard_Real tB,
-                                                const Standard_Real coeff)
+void IntTools_EdgeEdge::FindBestSolution(const Standard_Real aT11,
+                                         const Standard_Real aT12,
+                                         const Standard_Real aT21,
+                                         const Standard_Real aT22,
+                                         Standard_Real& aT1,
+                                         Standard_Real& aT2)
 {
-  Standard_Real gs=0.61803399;
-  Standard_Real a, b, xp, xl, yp, yl;
-
-  a=tA;  b=tB;
-  
-  xp=a+(b-a)*gs;
-  xl=b-(b-a)*gs;
-  yp=coeff*DistanceFunction(xp);
-  yl=coeff*DistanceFunction(xl);
-  
-  while (1) {
-    
-    if (fabs(b-a) < myEpsT) {
-      return .5*(b+a);
-    }
-    
-    if (yp < yl) {
-      a=xl;
-      xl=xp;
-      xp=a+(b-a)*gs;
-      yp=coeff*DistanceFunction(xp);
+  Standard_Integer i, aNbS, iErr;
+  Standard_Real aDMin, aD, aRes1, aSolCriteria, aTouchCriteria;
+  Standard_Real aT1A, aT1B, aT1Min, aT2Min;
+  GeomAPI_ProjectPointOnCurve aProjPC;
+  IntTools_SequenceOfRanges aRanges;
+  //
+  aDMin = Precision::Infinite();
+  aSolCriteria   = 5.e-16;
+  aTouchCriteria = 5.e-13;
+  Standard_Boolean bTouch = Standard_False;
+  Standard_Boolean bTouchConfirm = Standard_False;
+  //
+  aRes1 = Resolution(myCurve1.Curve().Curve(), 
+                     myCurve1.GetType(), myResCoeff1, myTol);
+  aNbS = 10;
+  aNbS = SplitRangeOnSegments(aT11, aT12, 3*aRes1, aNbS, aRanges);
+  //
+  aProjPC.Init(myGeom2, aT21, aT22);
+  //
+  Standard_Real aT11Touch = aT11, aT12Touch = aT12;
+  Standard_Real aT21Touch = aT21, aT22Touch = aT22;
+  Standard_Boolean isSolFound = Standard_False;
+  for (i = 1; i <= aNbS; ++i) {
+    const IntTools_Range& aR1 = aRanges(i);
+    aR1.Range(aT1A, aT1B);
+    //
+    aD = myTol;
+    iErr = FindDistPC(aT1A, aT1B, myGeom1, aSolCriteria, myPTol1,
+                      aProjPC, aD, aT1Min, aT2Min, Standard_False);
+    if (iErr != 1) {
+      if (aD < aDMin) {
+        aT1 = aT1Min;
+        aT2 = aT2Min;
+        aDMin = aD;
+        isSolFound = Standard_True;
+      }
+      //
+      if (aD < aTouchCriteria) {
+        if (bTouch) {
+          aT12Touch = aT1Min;
+          aT22Touch = aT2Min;
+          bTouchConfirm = Standard_True;
+        }
+        else {
+          aT11Touch = aT1Min;
+          aT21Touch = aT2Min;
+          bTouch = Standard_True;
+        }
+      }
     }
-    
-    else {
-      b=xp;
-      xp=xl;
-      yp=yl;
-      xl=b-(b-a)*gs;
-      yl=coeff*DistanceFunction(xl);
+  }
+  if (!isSolFound || bTouchConfirm)
+  {
+    aT1 = (aT11Touch + aT12Touch) * 0.5;
+    iErr = DistPC(aT1, myGeom1, aSolCriteria, aProjPC, aD, aT2, -1);
+    if (iErr == 1) {
+      aT2 = (aT21Touch + aT22Touch) * 0.5;
     }
   }
-}  
+}
+
 //=======================================================================
-//function : FindSimpleRoot
-//purpose  : [private]
+//function : ComputeLineLine
+//purpose  : 
 //=======================================================================
-  Standard_Real IntTools_EdgeEdge::FindSimpleRoot (const Standard_Integer IP,
-                                                  const Standard_Real tA,
-                                                  const Standard_Real tB,
-                                                  const Standard_Real fA)
+void IntTools_EdgeEdge::ComputeLineLine()
 {
-  Standard_Real r, a, b, y, x0, s;
-  
-  a=tA; b=tB; r=fA;
-
-  Standard_Integer step = 1, stepcheck = 1000, steplimit = 100000;
-  Standard_Real value = (IP==1) ? DistanceFunction(0.5*(a+b)) : DerivativeFunction(0.5*(a+b));
-  
-  while (1) {
-    x0=.5*(a+b);
-
-    if (IP==1)
-      y=DistanceFunction(x0);
-    else 
-      y=DerivativeFunction(x0);
-
-    Standard_Real aMaxAB100 = 100.*Max(a, b);
-    Standard_Real anEps     = Epsilon(aMaxAB100);
-    Standard_Real anEpsT    = Max(anEps, myEpsT);
-//    if (fabs(b-a) < myEpsT || y==0.) {
-    if (fabs(b-a) < anEpsT || y==0.) {
-      return x0;
+  Standard_Boolean IsParallel, IsCoincide;
+  Standard_Real aSin, aCos, aAng, aTol;
+  Standard_Real aT1, aT2, aT11, aT12, aT21, aT22;
+  gp_Pnt aP11, aP12;
+  gp_Lin aL1, aL2;
+  gp_Dir aD1, aD2;
+  IntTools_CommonPrt aCommonPrt;
+  //
+  IsParallel = Standard_False;
+  IsCoincide = Standard_False;
+  aTol = myTol*myTol;
+  aL1 = myCurve1.Line();
+  aL2 = myCurve2.Line();
+  aD1 = aL1.Position().Direction();
+  aD2 = aL2.Position().Direction();
+  myRange1.Range(aT11, aT12);
+  myRange2.Range(aT21, aT22);
+  //
+  aCommonPrt.SetEdge1(myEdge1);
+  aCommonPrt.SetEdge2(myEdge2);
+  //
+  aCos = aD1.Dot(aD2);
+  aAng = (aCos >= 0.) ? 2.*(1. - aCos) : 2.*(1. + aCos);
+  //
+  if(aAng <= Precision::Angular()) {
+    IsParallel = Standard_True;
+    if(aL1.SquareDistance(aL2.Location()) <= aTol) {
+      IsCoincide = Standard_True;
+      aP11 = ElCLib::Value(aT11, aL1);
+      aP12 = ElCLib::Value(aT12, aL1);
+    }
+  }
+  else {
+    aP11 = ElCLib::Value(aT11, aL1);
+    aP12 = ElCLib::Value(aT12, aL1);
+    if(aL2.SquareDistance(aP11) <= aTol && aL2.SquareDistance(aP12) <= aTol) {
+      IsCoincide = Standard_True;
+    }
+  }
+  //
+  if (IsCoincide) {
+    Standard_Real t21, t22;
+    //
+    t21 = ElCLib::Parameter(aL2, aP11);
+    t22 = ElCLib::Parameter(aL2, aP12);
+    if((t21 > aT22 && t22 > aT22) || (t21 < aT21 && t22 < aT21)) {
+      return;
+    }
+    //
+    Standard_Real temp;
+    if(t21 > t22) {
+      temp = t21;
+      t21 = t22;
+      t22 = temp;
     }
-    
-    if( step == stepcheck ) {
-      if( Abs(value - y) <= 1.e-9 ) {
-       return x0;
+    //
+    if(t21 >= aT21) {
+      if(t22 <= aT22) {
+        aCommonPrt.SetRange1(aT11, aT12);
+        aCommonPrt.SetAllNullFlag(Standard_True);
+        aCommonPrt.AppendRange2(t21, t22);
       }
       else {
-       value = y;
-       step = 1;
+        aCommonPrt.SetRange1(aT11, aT12 - (t22 - aT22));
+        aCommonPrt.AppendRange2(t21, aT22);
       }
     }
-
-    if( step == steplimit ) {
-      return x0;
-    }
-
-    s=y*r;
-
-    if (s<0.) {
-      b=x0;
-      continue;
-    }
-
-    if (s>0.) {
-      a=x0; r=y;
+    else {
+      aCommonPrt.SetRange1(aT11 + (aT21 - t21), aT12);
+      aCommonPrt.AppendRange2(aT21, t22);
     }
-
-    step++;
-
+    aCommonPrt.SetType(TopAbs_EDGE);  
+    myCommonParts.Append(aCommonPrt);
+    return;
   }
-}
-
-//=======================================================================
-//function : FindRangeOnCurve2
-//purpose  : 
-//=======================================================================
-  Standard_Integer IntTools_EdgeEdge::FindRangeOnCurve2(IntTools_CommonPrt&  aCommonPrt)
-{
-  Standard_Real ttmp, f, l, af1, al1, am1, af2, al2, am2;
-  Standard_Integer pri;
-  gp_Pnt aPf1, aPl1, aPm1, aPf2, aPl2, aPm2;
-  GeomAPI_ProjectPointOnCurve aProjector;
-
-  aCommonPrt.Range1(af1, al1);
-  am1=.5*(af1+al1);
-
-  const TopoDS_Edge& anEdgeTo=myCTo.Edge();
-  Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (anEdgeTo, f, l);
-
-  const TopoDS_Edge& anEdgeFrom=myCFrom.Edge();
-  Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (anEdgeFrom, f, l);
   //
-  // af2, aPf2
-  aCurveFrom->D0 (af1, aPf1); 
-  pri=GetParameterOnCurve2 (af1, af2);
-  if (pri) {
-    return 1;
+  if (IsParallel) {
+    return;
   }
-  aCurveTo->D0(af2, aPf2);
   //
-  // al2, aPl2
-  aCurveFrom->D0 (al1, aPl1);
-  pri=GetParameterOnCurve2 (al1, al2);
-  if (pri) {
-    return 1;
+  {
+    TopoDS_Iterator aIt1, aIt2;
+    aIt1.Initialize(myEdge1);
+    for (; aIt1.More(); aIt1.Next()) {
+      const TopoDS_Shape& aV1 = aIt1.Value();
+      aIt2.Initialize(myEdge2);
+      for (; aIt2.More(); aIt2.Next()) {
+        const TopoDS_Shape& aV2 = aIt2.Value();
+        if (aV2.IsSame(aV1)) {
+          return;
+        }
+      }
+    }
   }
-  aCurveTo->D0(al2, aPl2);
   //
-  // am2, aPm2
-  aCurveFrom->D0 (am1, aPm1);
-  pri=GetParameterOnCurve2 (am1, am2);
-  if (pri) {
-    return 1;
+  aSin = 1. - aCos*aCos;
+  gp_Pnt O1 = aL1.Location();
+  gp_Pnt O2 = aL2.Location();
+  gp_Vec O1O2 (O1, O2);
+  //
+  aT2 = (aD1.XYZ()*(O1O2.Dot(aD1))-(O1O2.XYZ())).Dot(aD2.XYZ());
+  aT2 /= aSin;
+  //
+  if(aT2 < aT21 || aT2 > aT22) {
+    return;
   }
-  aCurveTo->D0(am2, aPm2);
   //
-  // Reverse C2 points if it is necessary  
-  Standard_Boolean reverse = (af2 > al2);
-
-  if (reverse) {
-    ttmp=af2;
-    af2=al2;
-    al2=ttmp;
-    gp_Pnt aPTmp;
-    aPTmp=aPf2;
-    aPf2=aPl2;
-    aPl2=aPTmp;
+  gp_Pnt aP2(ElCLib::Value(aT2, aL2));
+  aT1 = (gp_Vec(O1, aP2)).Dot(aD1);
+  //
+  if(aT1 < aT11 || aT1 > aT12) {
+    return;
   }
-
-  if((Abs(af2 - myTminTo) < Precision::PConfusion()) &&
-     (Abs(al2 - myTmaxTo) < Precision::PConfusion())) {
-    aCommonPrt.SetAllNullFlag(Standard_True);
+  //
+  gp_Pnt aP1(ElCLib::Value(aT1, aL1));
+  Standard_Real aDist = aP1.SquareDistance(aP2);
+  //
+  if (aDist > aTol) {
+    return;
   }
   //
+  // compute correct range on the edges
+  Standard_Real anAngle, aDt1, aDt2;
   //
-  Standard_Boolean aVFlag1, aVFlag2, aGeomFlag1, aGeomFlag2;
-  Standard_Real Df2m2, Dm2l2, Df2l2, df2m2, dm2l2, df2l2, df1m1, dm1l1, df1l1;
-  Standard_Real tV1, tV2;
+  anAngle = aD1.Angle(aD2);
   //
-  // parametric differences for C2
-  Df2m2=fabs(af2-am2);
-  Dm2l2=fabs(am2-al2);
-  Df2l2=fabs(af2-al2);
+  aDt1 = IntTools_Tools::ComputeIntRange(myTol1, myTol2, anAngle);
+  aDt2 = IntTools_Tools::ComputeIntRange(myTol2, myTol1, anAngle);
   //
-  // geometric distances for C2
-  df2m2=aPf2.Distance(aPm2);
-  dm2l2=aPm2.Distance(aPl2);
-  df2l2=aPf2.Distance(aPl2);
-
-  aVFlag1=(Df2m2<myEpsT && Dm2l2<myEpsT);
-  aVFlag2=(df2m2 < myCriteria && dm2l2 < myCriteria);
+  aCommonPrt.SetRange1(aT1 - aDt1, aT1 + aDt1);
+  aCommonPrt.AppendRange2(aT2 - aDt2, aT2 + aDt2);
+  aCommonPrt.SetType(TopAbs_VERTEX);
+  aCommonPrt.SetVertexParameter1(aT1);
+  aCommonPrt.SetVertexParameter2(aT2);
+  myCommonParts.Append(aCommonPrt);
+}
 
+//=======================================================================
+//function : IsIntersection
+//purpose  : 
+//=======================================================================
+Standard_Boolean IntTools_EdgeEdge::IsIntersection(const Standard_Real aT11,
+                                                   const Standard_Real aT12,
+                                                   const Standard_Real aT21,
+                                                   const Standard_Real aT22)
+{
+  Standard_Boolean bRet;
+  gp_Pnt aP11, aP12, aP21, aP22;
+  gp_Vec aV11, aV12, aV21, aV22;
+  Standard_Real aD11_21, aD11_22, aD12_21, aD12_22, aCriteria, aCoef;
+  Standard_Boolean bSmall_11_21, bSmall_11_22, bSmall_12_21, bSmall_12_22;
   //
-  //  Two perpendicular lines => VERTEX
-  if ( aVFlag1 && aVFlag2) { 
-    // V e r t e x
-    aCommonPrt.SetType(TopAbs_VERTEX);
-    pri=TreatVertexType(am1, am2, aCommonPrt);
-    
-    if (pri) { 
-      tV2=.5*(af2+al2);
-      aCommonPrt.SetVertexParameter2(tV2);
-      aCommonPrt.AppendRange2 (af2, al2);
-      
-      tV1=.5*(af1+al1);
-      aCommonPrt.SetVertexParameter1(tV1);
-      aCommonPrt.SetRange1 (af1, al1);
+  bRet = Standard_True;
+  aCoef = 1.e+5;
+  if (((aT12 - aT11) > aCoef*myRes1) && ((aT22 - aT21) > aCoef*myRes2)) {
+    aCoef = 5000;
+  } else {
+    Standard_Real aTRMin = Min((aT12 - aT11)/myRes1, (aT22 - aT21)/myRes2);
+    aCoef = aTRMin / 100.;
+    if (aCoef < 1.) {
+      aCoef = 1.;
     }
-    return 0;
   }
+  aCriteria = aCoef * myTol;
+  aCriteria *= aCriteria;
   //
-  // geometric distances for C1
-  df1m1=aPf1.Distance(aPm1);
-  dm1l1=aPm1.Distance(aPl1);
-  df1l1=aPf1.Distance(aPl1);
-  //
-  // if geometric distances between boundaries is less than myCriteria
-  // we have VERTEX
-  aGeomFlag1=(df1l1 < myCriteria);
-  aGeomFlag2=(df2l2 < myCriteria);
-  if (aGeomFlag1 && aGeomFlag2) { 
-    aCommonPrt.SetType(TopAbs_VERTEX);
-    
-    tV2=.5*(af2+al2);
-    aCommonPrt.SetVertexParameter2(tV2);
-    aCommonPrt.AppendRange2 (af2, al2);
-      
-    tV1=.5*(af1+al1);
-    aCommonPrt.SetVertexParameter1(tV1);
-    aCommonPrt.SetRange1 (af1, al1);
-    return 0;
-  }
+  myGeom1->D1(aT11, aP11, aV11);
+  myGeom1->D1(aT12, aP12, aV12);
+  myGeom2->D1(aT21, aP21, aV21);
+  myGeom2->D1(aT22, aP22, aV22);
   //
-  //  ???
-  if (Df2l2 < myEpsT &&  !aVFlag1) { 
-    if (aPf1.Distance(aPl1) < myCriteria && aPf2.Distance(aPl2) < myCriteria) { 
-      af1=myTminTo;
-      al2=myTmaxTo;
-      aCommonPrt.AppendRange2 (af1, al2);
-      aCommonPrt.SetType(TopAbs_EDGE);
-      return 0;
-    }
-  }
+  aD11_21 = aP11.SquareDistance(aP21);
+  aD11_22 = aP11.SquareDistance(aP22);
+  aD12_21 = aP12.SquareDistance(aP21);
+  aD12_22 = aP12.SquareDistance(aP22);
   //
-  //modified by NIZNHY-PKV Mon Jun  8 09:55:42 2009f
-  //aProjector.Init(aPm2, aCurveFrom, myTminFrom, myTmaxFrom);
-  aProjector.Init(aCurveFrom, myTminFrom, myTmaxFrom);
-  aProjector.Perform(aPm2);
-  //modified by NIZNHY-PKV Mon Jun  8 09:56:12 2009t
-  Standard_Integer aNbPoints=aProjector.NbPoints();
-  if (aNbPoints) { 
-    Standard_Real aDD=aProjector.LowerDistance();
-    if (aDD > myCriteria) { 
-      // Passed through 0
-      aCommonPrt.SetType(TopAbs_EDGE);
-      aCommonPrt.AppendRange2 (myTminTo, af2);
-      aCommonPrt.AppendRange2 (al2, myTmaxTo);
-      return 0;
-    }
-  }
-  else {
-    // Passed through 0
-    aCommonPrt.SetType(TopAbs_EDGE); 
-    aCommonPrt.AppendRange2 (myTminTo, af2);
-    aCommonPrt.AppendRange2 (al2, myTmaxTo);
-    return 0;
-  }
-
-  IsIntersection (af1, al1);
-  if (!myParallel && !aCommonPrt.AllNullFlag()) {
-    Standard_Real aPar2;
-    GetParameterOnCurve2 (myPar1, aPar2);
-    aCommonPrt.SetType(TopAbs_VERTEX);
-
-    Standard_Boolean IsmyPar1 = Standard_True;
-
-    if(Abs(af1-myTminFrom) < Precision::PConfusion()) {
-      IsmyPar1 = Standard_False;
-      aCommonPrt.SetVertexParameter1(af1);
-      if(reverse)
-       aCommonPrt.SetVertexParameter2(al2);
-      else
-       aCommonPrt.SetVertexParameter2(af2);
-    }
-
-    if(Abs(al1-myTmaxFrom) < Precision::PConfusion()) {
-      IsmyPar1 = Standard_False;
-      aCommonPrt.SetVertexParameter1(al1);
-
-      if(reverse)
-       aCommonPrt.SetVertexParameter2(af2);
-      else
-       aCommonPrt.SetVertexParameter2(al2);
-    }
-
-    if(Abs(af2-myTminTo) < Precision::PConfusion()) {
-      IsmyPar1 = Standard_False;
-      aCommonPrt.SetVertexParameter2(af2);
-
-      if(reverse)
-       aCommonPrt.SetVertexParameter1(al1);
-      else
-       aCommonPrt.SetVertexParameter1(af1);
+  bSmall_11_21 = aD11_21 < aCriteria;
+  bSmall_11_22 = aD11_22 < aCriteria;
+  bSmall_12_21 = aD12_21 < aCriteria;
+  bSmall_12_22 = aD12_22 < aCriteria;
+  //
+  if ((bSmall_11_21 && bSmall_12_22) ||
+      (bSmall_11_22 && bSmall_12_21)) {
+    if (aCoef == 1.) {
+      return bRet;
     }
-
-    if(Abs(al2-myTmaxTo) < Precision::PConfusion()) {
-      IsmyPar1 = Standard_False;
-      aCommonPrt.SetVertexParameter2(al2);
-
-      if(reverse)
-       aCommonPrt.SetVertexParameter1(af1);
-      else
-       aCommonPrt.SetVertexParameter1(al1);
+    //
+    Standard_Real anAngleCriteria;
+    Standard_Real anAngle1, anAngle2;
+    //
+    anAngleCriteria = 5.e-3;
+    if (bSmall_11_21 && bSmall_12_22) {
+      anAngle1 = aV11.Angle(aV21);
+      anAngle2 = aV12.Angle(aV22);
+    } else {
+      anAngle1 = aV11.Angle(aV22);
+      anAngle2 = aV12.Angle(aV21);
     }
-    //     aCommonPrt.SetVertexParameter1(myPar1);
-    //     aCommonPrt.SetRange1 (af1, al1);
-    
-    //     aCommonPrt.SetVertexParameter2(aPar2);
-    if(IsmyPar1) {
-      aCommonPrt.SetVertexParameter1(myPar1);
-      aCommonPrt.SetRange1 (af1, al1);
-      
-      aCommonPrt.SetVertexParameter2(aPar2);
+    //
+    if (((anAngle1 < anAngleCriteria) || ((M_PI - anAngle1) < anAngleCriteria)) ||
+        ((anAngle2 < anAngleCriteria) || ((M_PI - anAngle2) < anAngleCriteria))) {
+      GeomAPI_ProjectPointOnCurve aProjPC;
+      Standard_Integer iErr;
+      Standard_Real aD, aT1Min, aT2Min;
+      //
+      aD = Precision::Infinite();
+      aProjPC.Init(myGeom2, aT21, aT22);
+      iErr = FindDistPC(aT11, aT12, myGeom1, myTol, myRes1, 
+                        aProjPC, aD, aT1Min, aT2Min, Standard_False);
+      bRet = (iErr == 2);
     }
-    aCommonPrt.AppendRange2 (af2, al2);
-    return 0;
   }
-
-  
-
-  aCommonPrt.SetType(TopAbs_EDGE);
-  aCommonPrt.AppendRange2 (af2, al2);
-  return 0;
+  return bRet;
 }
+
 //=======================================================================
-//function : IsIntersection
+//function : CheckCoincidence
 //purpose  : 
 //=======================================================================
-  void IntTools_EdgeEdge::IsIntersection (const Standard_Real ta, 
-                                         const Standard_Real tb) 
+Standard_Integer IntTools_EdgeEdge::CheckCoincidence(const Standard_Real aT11,
+                                                     const Standard_Real aT12,
+                                                     const Standard_Real aT21,
+                                                     const Standard_Real aT22,
+                                                     const Standard_Real theCriteria,
+                                                     const Standard_Real theCurveRes1)
 {
-  Standard_Integer i, aNb, pri;
-  Standard_Real t, f;
-  GeomAbs_CurveType aCT1, aCT2;
-  IntTools_CArray1OfReal anArgs, aFunc;
-  //
-  aCT1=myCFrom.GetType();
-  aCT2=myCTo.GetType();
-  if((aCT1==GeomAbs_Line) && (aCT2==GeomAbs_Line)) {
-    const Handle(Geom_Curve)&  Curve1=BRep_Tool::Curve  (myCFrom.Edge(), t, f);
-    const Handle(Geom_Curve)&  Curve2=BRep_Tool::Curve  (myCTo.Edge()  , t, f);
-    
-    GeomAdaptor_Curve   TheCurve1   (Curve1);
-    GeomAdaptor_Curve   TheCurve2   (Curve2);
-    Extrema_ExtCC anExtrema (TheCurve1, TheCurve2);
-
-    if(anExtrema.IsDone() && anExtrema.IsParallel()) {
-      myParallel = Standard_True;
-      return;
-    }
-  }
+  Standard_Integer iErr, aNb, aNb1, i;
+  Standard_Real aT1A, aT1B, aT1max, aT2max, aDmax;
+  GeomAPI_ProjectPointOnCurve aProjPC;
+  IntTools_SequenceOfRanges aRanges;
   //
-  //modified by NIZNHY-PKV Wed May 13 11:08:46 2009f
-  if (aCT1==GeomAbs_Circle && aCT2==GeomAbs_Circle) {
-    Standard_Boolean bIsDone, bIsParallel;
-    Standard_Integer aNbExt;
-    Standard_Real aD2, aCriteria2, aT1;
-    gp_Circ aCirc1, aCirc2;
-    Extrema_POnCurv aPC1, aPC2;
-    //
-    aCirc1=myCFrom.Circle();
-    aCirc2=myCTo.Circle();
-    //
-    Extrema_ExtElC aExtElC(aCirc1, aCirc2);
+  iErr  = 0;
+  aDmax = -1.;
+  aProjPC.Init(myGeom2, aT21, aT22);
+  //
+  // 1. Express evaluation
+  aNb = 10; // Number of intervals on the curve #1
+  aNb1 = SplitRangeOnSegments(aT11, aT12, theCurveRes1, aNb, aRanges);
+  for (i = 1; i < aNb1; ++i) {
+    const IntTools_Range& aR1 = aRanges(i);
+    aR1.Range(aT1A, aT1B);
     //
-    bIsDone=aExtElC.IsDone();
-    if (bIsDone) {
-      bIsParallel=aExtElC.IsParallel();
-      if (!bIsParallel) {
-       aCriteria2=myCriteria*myCriteria;
-       aNbExt=aExtElC.NbExt();
-       for (i=1; i<=aNbExt; ++i) {
-         aD2=aExtElC.SquareDistance(i);
-         if (aD2<aCriteria2) {
-           aExtElC.Points(i, aPC1, aPC2);
-           aT1=aPC1.Parameter();
-           if (aT1>ta && aT1<tb) {
-             myPar1=aT1;
-             myParallel=Standard_False;
-             return;
-           }
-         }
-       }
-      }
+    iErr = DistPC(aT1B, myGeom1, theCriteria, aProjPC, aDmax, aT2max);
+    if (iErr) {
+      return iErr;
     }
   }
-  //modified by NIZNHY-PKV Wed May 13 11:08:51 2009t
   //
-  // Prepare values of arguments for the interval [ta, tb]
-  pri=IntTools::PrepareArgs (myCFrom, tb, ta, myDiscret, myDeflection, anArgs);
-  aNb=anArgs.Length();
-
-  aFunc.Resize(aNb);
-  for (i=0; i<aNb; i++) {
-    t=anArgs(i);
-    f=DistanceFunction(t);
-    if (fabs(f) < myEpsNull) { 
-      f=0.;
+  // if the ranges in aRanges are less than theCurveRes1,
+  // there is no need to do step 2 (deep evaluation)
+  if (aNb1 < aNb) {
+    return iErr;
+  }
+  //
+  // 2. Deep evaluation
+  for (i = 2; i < aNb1; ++i) {
+    const IntTools_Range& aR1 = aRanges(i);
+    aR1.Range(aT1A, aT1B);
+    //
+    iErr = FindDistPC(aT1A, aT1B, myGeom1, theCriteria, theCurveRes1, 
+                      aProjPC, aDmax, aT1max, aT2max);
+    if (iErr) {
+      return iErr;
     }
-    aFunc(i)=f;
   }
-  FindDerivativeRoot(anArgs, aFunc);
-  return ;
+  // Possible values:
+  // iErr == 0 - the patches are coincided
+  // iErr == 1 - a point from aC1 can not be projected on aC2
+  // iErr == 2 - the distance is too big
+  return iErr;
 }
 
 //=======================================================================
-//function : FindDerivativeRoot
+//function : FindDistPC
 //purpose  : 
 //=======================================================================
-  void IntTools_EdgeEdge::FindDerivativeRoot(const IntTools_CArray1OfReal& t,
-                                            const IntTools_CArray1OfReal& f)  
+Standard_Integer FindDistPC(const Standard_Real aT1A, 
+                            const Standard_Real aT1B,
+                            const Handle(Geom_Curve)& theC1,
+                            const Standard_Real theCriteria,
+                            const Standard_Real theEps,
+                            GeomAPI_ProjectPointOnCurve& theProjPC,
+                            Standard_Real& aDmax, 
+                            Standard_Real& aT1max,
+                            Standard_Real& aT2max,
+                            const Standard_Boolean bMaxDist) 
 {
-  Standard_Integer i, n, k;
-  Standard_Real fr, tr, anEpsNull;
-  IntTools_CArray1OfReal fd;
-  TColStd_SequenceOfReal aTSeq, aFSeq;
-  
-  anEpsNull=100.*myEpsNull;
-  myPar1=0.;
-  myParallel=Standard_True;
-  
-  n=t.Length();
-  fd.Resize(n+1);
-  //
-  // Table of derivatives
-  fd(0)=(f(1)-f(0))/(t(1)-t(0));
-  if (fabs(fd(0)) < anEpsNull) {
-    fd(0)=0.;
+  Standard_Integer iErr, iC;
+  Standard_Real aGS, aXP, aA, aB, aXL, aYP, aYL, aT2P, aT2L;
+  //
+  iC = bMaxDist ? 1 : -1;
+  iErr = 0;
+  aT1max = aT2max = 0.; // silence GCC warning
+  //
+  aGS = 0.6180339887498948482045868343656;// =0.5*(1.+sqrt(5.))-1.;
+  aA = aT1A;
+  aB = aT1B;
+  //
+  // check bounds
+  iErr = DistPC(aA, theC1, theCriteria, theProjPC, 
+                aYP, aT2P, aDmax, aT1max, aT2max, iC);
+  if (iErr == 2) {
+    return iErr;
   }
-  k=n-1;
-  for (i=1; i<k; i++) {
-    fd(i)=.5*(f(i+1)-f(i-1))/(t(i)-t(i-1));
-    if (fabs(fd(i)) < anEpsNull) {
-      fd(i)=0.;
-    }
+  //
+  iErr = DistPC(aB, theC1, theCriteria, theProjPC, 
+                aYL, aT2L, aDmax, aT1max, aT2max, iC);
+  if (iErr == 2) {
+    return iErr;
   }
-  fd(n-1)=(f(n-1)-f(n-2))/(t(n-1)-t(n-2));
-  if (fabs(fd(n-1)) < anEpsNull) {
-    fd(n-1)=0.;
+  //
+  aXP = aA + (aB - aA)*aGS;
+  aXL = aB - (aB - aA)*aGS;
+  //
+  iErr = DistPC(aXP, theC1, theCriteria, theProjPC, 
+                aYP, aT2P, aDmax, aT1max, aT2max, iC);
+  if (iErr) {
+    return iErr;
   }
   //
-  // Finding the range where the derivatives have different signs
-  // for neighbouring points
-  for (i=1; i<n; i++) {
-    Standard_Real fd1, fd2, t1, t2, fabsfd1, fabsfd2;
-    Standard_Boolean bF1, bF2;
-    t1 =t(i-1);
-    t2 =t(i);
-    fd1=fd(i-1);
-    fd2=fd(i);
-
-    fabsfd1=fabs(fd1);
-    bF1=fabsfd1 < myEpsNull;
-    
-    fabsfd2=fabs(fd2);
-    bF2=fabsfd2 < myEpsNull;
-
-    //aa
-    if (fd1*fd2 < 0.) {
-      tr=FindSimpleRoot(2, t1, t2, fd1);
-      fr=DistanceFunction(tr);
-      myPar1=tr;
-      myParallel=Standard_False;
-      break;
+  iErr = DistPC(aXL, theC1, theCriteria, theProjPC, 
+                aYL, aT2L, aDmax, aT1max, aT2max, iC);
+  if (iErr) {
+    return iErr;
+  }
+  //
+  Standard_Real anEps = Max(theEps, Epsilon(Max(Abs(aA), Abs(aB))) * 10.);
+  for (;;) {
+    if (iC*(aYP - aYL) > 0) {
+      aA = aXL;
+      aXL = aXP;
+      aYL = aYP;
+      aXP = aA + (aB - aA)*aGS;
+      iErr = DistPC(aXP, theC1, theCriteria, theProjPC, 
+                    aYP, aT2P, aDmax, aT1max, aT2max, iC);
     }
-    
-    if (!bF1 && bF2) {
-      tr=t2;
-      fr=fd2;
-      myPar1=tr;
-      myParallel=Standard_False;
-      break;
+    else {
+      aB = aXP;
+      aXP = aXL;
+      aYP = aYL;
+      aXL = aB - (aB - aA)*aGS;
+      iErr = DistPC(aXL, theC1, theCriteria, theProjPC, 
+                    aYL, aT2L, aDmax, aT1max, aT2max, iC);
+    }
+    //
+    if (iErr) {
+      if ((iErr == 2) && !bMaxDist) {
+        aXP = (aA + aB) * 0.5;
+        DistPC(aXP, theC1, theCriteria, theProjPC, 
+               aYP, aT2P, aDmax, aT1max, aT2max, iC);
+      }
+      return iErr;
     }
-    
-    if (bF1 && !bF2) {
-      tr=t1;
-      fr=fd1;
-      myPar1=tr;
-      myParallel=Standard_False;
+    //
+    if ((aB - aA) < anEps) {
       break;
     }
-
-  }
+  }// for (;;) {
+  //
+  return iErr;
 }
-
 //=======================================================================
-//function : GetParameterOnCurve2
+//function : DistPC
 //purpose  : 
 //=======================================================================
-  Standard_Integer IntTools_EdgeEdge::GetParameterOnCurve2(const Standard_Real aT1, 
-                                                          Standard_Real& aT2) const
+Standard_Integer DistPC(const Standard_Real aT1, 
+                        const Handle(Geom_Curve)& theC1,
+                        const Standard_Real theCriteria,
+                        GeomAPI_ProjectPointOnCurve& theProjPC, 
+                        Standard_Real& aD, 
+                        Standard_Real& aT2,
+                        Standard_Real& aDmax,
+                        Standard_Real& aT1max,
+                        Standard_Real& aT2max,
+                        const Standard_Integer iC)
 {
-  Standard_Real f, l;
-  Standard_Integer j, found, aNbPoints;
-  const TopoDS_Edge& anEdgeTo=myCTo.Edge();
-  const TopoDS_Edge& anEdgeFrom=myCFrom.Edge();
-  
-  Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (anEdgeFrom, f, l);
-  Handle(Geom_Curve)aCurveTo  =BRep_Tool::Curve (anEdgeTo,   f, l);
-
-  gp_Pnt aP1;
-  aCurveFrom->D0 (aT1, aP1);
-  GeomAPI_ProjectPointOnCurve aProjector;
-  //modified by NIZNHY-PKV Mon Jun  8 09:56:53 2009f
-  //aProjector.Init(aP1, aCurveTo, myTminTo, myTmaxTo);
-  aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
-  aProjector.Perform(aP1);
-  //modified by NIZNHY-PKV Mon Jun  8 09:57:12 2009t
-  aNbPoints=aProjector.NbPoints();
-  found=1;
-  if (!aNbPoints) {
-    found=0;
-    for (j=0; j<=1; j++) {
-      Standard_Real tt;
-      tt=aT1+myEpsT;
-      if (j) {
-       tt=aT1-myEpsT;
-      }
-      aCurveFrom->D0 (tt, aP1);
-      //modified by NIZNHY-PKV Mon Jun  8 09:57:34 2009f
-      //aProjector.Init(aP1, aCurveTo, myTminTo, myTmaxTo);
-      aProjector.Init(aCurveTo, myTminTo, myTmaxTo);
-      aProjector.Perform(aP1);
-      //modified by NIZNHY-PKV Mon Jun  8 09:57:51 2009t
-      aNbPoints=aProjector.NbPoints();
-      if (aNbPoints) {
-       found=1;
-       break;
-      }
-    }
-  }
-
-  if (!found) {
-    aCurveFrom->D0 (aT1, aP1);
-    Standard_Real aDistance = RealLast();
-
-    for(Standard_Integer pIt=0; pIt < 2; pIt++) {
-      Standard_Real adist = aDistance;
-      if(pIt)
-       adist = aP1.Distance(aCurveTo->Value(myTminTo));
-      else
-       adist = aP1.Distance(aCurveTo->Value(myTmaxTo));
-      
-      if(adist < myCriteria) {
-       found = Standard_True;
-
-       if(adist < aDistance) {
-         aT2 = (pIt) ? myTminTo : myTmaxTo;
-         aDistance = adist;
-       }
-      }      
-    }
-    if(found)
-      return 0;
-  }
-
-  if (!found) {
-    aT2=0.;
-    return 1;
-  }
-
-  for (j=1; j<=aNbPoints; j++) {
-    aT2=aProjector.Parameter(j);
-    f=aProjector.Distance(j);
-  }
-
-  aT2=aProjector.LowerDistanceParameter();
-  if (aT2 < myTminTo) {
-    aT2=myTminTo;
+  Standard_Integer iErr;
+  //
+  iErr = DistPC(aT1, theC1, theCriteria, theProjPC, aD, aT2, iC);
+  if (iErr == 1) {
+    return iErr;
   }
-  if (aT2 > myTmaxTo) {
-    aT2=myTmaxTo;
+  //
+  if (iC*(aD - aDmax) > 0) {
+    aDmax = aD;
+    aT1max = aT1;
+    aT2max = aT2;
   }
-  return 0;
+  //
+  return iErr;
 }
 //=======================================================================
-//function : TreatVertexType
+//function : DistPC
 //purpose  : 
 //=======================================================================
-  Standard_Integer IntTools_EdgeEdge::TreatVertexType(const Standard_Real am1,
-                                                     const Standard_Real am2,
-                                                     IntTools_CommonPrt&  aCommonPrt) 
+Standard_Integer DistPC(const Standard_Real aT1, 
+                        const Handle(Geom_Curve)& theC1,
+                        const Standard_Real theCriteria, 
+                        GeomAPI_ProjectPointOnCurve& theProjPC,
+                        Standard_Real& aD, 
+                        Standard_Real& aT2,
+                        const Standard_Integer iC) 
 {
-  Standard_Real  f1, l1, f2, l2, Alfa , aPeriod;
-  gp_Pnt aPm1, aPm2, aP;
-  gp_Vec aVm1, aVm2;
-  
-
-  const TopoDS_Edge& anEdgeFrom=myCFrom.Edge();
-  Handle(Geom_Curve)aCurveFrom=BRep_Tool::Curve (anEdgeFrom, f1, l1);
-  aCurveFrom->D1 (am1, aPm1, aVm1);
-  aVm1.Normalize();
-
-  const TopoDS_Edge& anEdgeTo=myCTo.Edge();
-  Handle(Geom_Curve)aCurveTo=BRep_Tool::Curve (anEdgeTo, f2, l2);
-  aCurveTo->D1 (am2, aPm2, aVm2);
-  aVm2.Normalize();
-
-  Alfa=aVm1.Angle(aVm2);
-
-  if (Alfa < Precision::Angular()) {
-    return 1;
-  }
-
-  Standard_Real sinAlfa, cosAlfa, dd, tf1, tl1, tf2, tl2, aL1, aL2;
-  Standard_Integer ip;
-  
-  sinAlfa=sin(Alfa);
-  cosAlfa=cos(Alfa);
-    
-  dd=aPm1.Distance(aPm2);
-  // aL2
-  if (dd>myCriteria) {
-    return 1;
-  }
-  aL2=(myTolTo*cosAlfa+myTolFrom)/sinAlfa;
-  // left point
-  aP.SetXYZ(aPm2.XYZ()-aVm2.XYZ()*aL2);
-  ip=IntTools::Parameter (aP, aCurveTo, tf2);
-  if (ip){
-    return ip;
-  }
-  // 
-  if(aP.Distance(aCurveTo->Value(tf2)) > myTolTo)
-    return 1;
-
-  // right point
-  aP.SetXYZ(aPm2.XYZ()+aVm2.XYZ()*aL2);
-  ip=IntTools::Parameter (aP, aCurveTo, tl2);
-  if (ip){
-    return ip;
-  }
-
-  if(aP.Distance(aCurveTo->Value(tl2)) > myTolTo)
-    return 1;
-  
-  // aL1
-  if (dd>myCriteria) {
-    return 1;
-  }
-  aL1=(myTolFrom*cosAlfa+myTolTo)/sinAlfa;
-  // left point
-  aP.SetXYZ(aPm1.XYZ()-aVm1.XYZ()*aL1);
-  ip=IntTools::Parameter (aP, aCurveFrom, tf1);
-  if (ip){
-    return ip;
-  }
-
-  if(aP.Distance(aCurveFrom->Value(tf1)) > myTolFrom)
-    return 1;
-
-  // right point
-  aP.SetXYZ(aPm1.XYZ()+aVm1.XYZ()*aL1);
-  ip=IntTools::Parameter (aP, aCurveFrom, tl1);
-  if (ip){
-    return ip;
-  }
-
-  if(aP.Distance(aCurveFrom->Value(tl1)) > myTolFrom)
-    return 1;
-
+  Standard_Integer iErr, aNbP2;
+  gp_Pnt aP1;
   //
-  if (aCurveFrom->IsPeriodic()) {
-    aPeriod=aCurveFrom->Period();
-    if (tf1<f1 || tf1>l1) {
-      tf1=tf1+aPeriod;
-    }
-    if (tl1<f1 || tl1>l1) {
-      tl1=tl1+aPeriod;
-    }
-  }
+  iErr = 0;
+  theC1->D0(aT1, aP1);
   //
-  // First range
-  aCommonPrt.SetRange1    (tf1, tl1);
-  aCommonPrt.SetVertexParameter1((tf1 + tl1) * 0.5);
-  //
-  // Second Range(s) 
-  if (aCurveTo->IsPeriodic() && tf2 > tl2) {
-    // aCurveTo is periodic curve and we pass through 0.
-    
-    aPeriod=aCurveTo->Period();
-    aCommonPrt.AppendRange2 (tf2, aPeriod);
-    aCommonPrt.AppendRange2 (0., tl2);
-    aCommonPrt.SetVertexParameter2((tf2 + aPeriod) * 0.5);
+  theProjPC.Perform(aP1);
+  aNbP2 = theProjPC.NbPoints();
+  if (!aNbP2) {
+    iErr = 1;// the point from aC1 can not be projected on aC2
+    return iErr;
   }
-  else {
-    // usual cases 
-    return 1;
-    //
+  //
+  aD  = theProjPC.LowerDistance();
+  aT2 = theProjPC.LowerDistanceParameter();
+  if (iC*(aD - theCriteria) > 0) {
+    iErr = 2;// the distance is too big or small
   }
-  return 0;
+  //
+  return iErr;
 }
-
-//
-//
-// Print block
 
-// myErrorStatus
-// 1 - the method Perform() is not invoked  
-// 2,3,4,5 -the method CheckData() fails
-// 6 - PrepareArgs() problems
-// 7 - No Projectable ranges
-// 8,9 - PrepareArgs() problems occured inside  projectable Ranges
-// 10 - problems in FindRange2
-// 11 - can't fill array  aFunc(i) in PrepareArgsFuncArrays: 
-//      possible reason is that no points on myCFrom that could be projected
-//      on myCTo
-//   
-
-#include <Precision.hxx>
-#include <Geom_Curve.hxx>
-#include <GeomAdaptor_Curve.hxx>
-#include <BRep_Tool.hxx>
-#include <Extrema_ExtCC.hxx>
-#include <ElCLib.hxx>
 //=======================================================================
-//function : CheckTouchVertex 
-//purpose  : line/Circle refinement
+//function : SplitRangeOnSegments
+//purpose  : 
 //=======================================================================
-  Standard_Boolean IntTools_EdgeEdge::CheckTouchVertex (const IntTools_CommonPrt& aCP,
-                                                       Standard_Real& aTx1,
-                                                       Standard_Real& aTx2) const
+Standard_Integer SplitRangeOnSegments(const Standard_Real aT1, 
+                                      const Standard_Real aT2,
+                                      const Standard_Real theResolution,
+                                      const Standard_Integer theNbSeg,
+                                      IntTools_SequenceOfRanges& theSegments)
 {
-  Standard_Boolean bFlag;
-  Standard_Real aTFR1, aTLR1, aTFR2, aTLR2;
-  Standard_Real aTL1, aTL2, aTC1, aTC2;
-  Standard_Real aRC, aDLC, aD2, aC2, aTLx, aTCx;
-  GeomAbs_CurveType aTFrom, aTTo;
-  gp_Circ aCirc;
-  gp_Lin  aLine;
-  gp_Pnt aPC, aPLx, aPCx;
-  //
-  bFlag=Standard_False;
-  aCP.Range1(aTFR1, aTLR1);
-  (aCP.Ranges2())(1).Range(aTFR2, aTLR2);
-  //
-  aTFrom=myCFrom.GetType();
-  aTTo  =myCTo.GetType();
-  //
-  aTL1=aTFR1;
-  aTL2=aTLR1;
-  aTC1=aTFR2;
-  aTC2=aTLR2;
-  if (aTFrom==GeomAbs_Circle) {
-    aCirc=myCFrom.Circle();
-    aLine=myCTo.Line();
-    aTL1=aTFR2;
-    aTL2=aTLR2;
-    aTC1=aTFR1;
-    aTC2=aTLR1;
-  }
-  else {
-    aCirc=myCTo.Circle();
-    aLine=myCFrom.Line();
+  Standard_Real aDiff = aT2 - aT1;
+  if (aDiff < theResolution || theNbSeg == 1) {
+    theSegments.Append(IntTools_Range(aT1, aT2));
+    return 1;
   }
   //
-  aPC=aCirc.Location();
-  aRC=aCirc.Radius();
-  //
-  aDLC=aLine.Distance(aPC);
-  if (fabs(aDLC-aRC)>myCriteria) {
-    return bFlag;
-  }
+  Standard_Real aDt, aT1x, aT2x, aSeg;
+  Standard_Integer aNbSegments, i;
   //
-  aTLx=ElCLib::Parameter(aLine, aPC);
-  aPLx=ElCLib::Value(aTLx, aLine);
-  aTCx=ElCLib::Parameter(aCirc, aPLx);
-  aPCx=ElCLib::Value(aTCx, aCirc);
-  aD2=aPLx.SquareDistance(aPCx);
-  aC2=myCriteria*myCriteria;
-  if (aD2>aC2) {
-    return bFlag;
+  aNbSegments = theNbSeg;
+  aDt = aDiff / aNbSegments;
+  if (aDt < theResolution) {
+    aSeg = aDiff / theResolution;
+    aNbSegments = Standard_Integer(aSeg) + 1;
+    aDt = aDiff / aNbSegments;
   }
   //
-  if (aTLx<aTL1 || aTLx>aTL2) {
-    return bFlag;
-  }
-  if (aTCx<aTC1 || aTCx>aTC2) {
-    return bFlag;
+  aT1x = aT1;
+  for (i = 1; i < aNbSegments; ++i) {
+    aT2x = aT1x + aDt;
+    //
+    IntTools_Range aR(aT1x, aT2x);
+    theSegments.Append(aR);
+    //
+    aT1x = aT2x;
   }
   //
-  aTx1=aTLx;
-  aTx2=aTCx;
-  if (aTFrom==GeomAbs_Circle) {
-    aTx1=aTCx;
-    aTx2=aTLx;
-  }
+  IntTools_Range aR(aT1x, aT2);
+  theSegments.Append(aR);
   //
-  return !bFlag;
+  return aNbSegments;
 }
+
 //=======================================================================
-//function : CheckTouch 
+//function : BndBuildBox
 //purpose  : 
 //=======================================================================
-  Standard_Boolean IntTools_EdgeEdge::CheckTouch(const IntTools_CommonPrt& aCP,
-                                                Standard_Real& aTx1,
-                                                Standard_Real& aTx2) 
+void BndBuildBox(const BRepAdaptor_Curve& theBAC,
+                 const Standard_Real aT1,
+                 const Standard_Real aT2,
+                 const Standard_Real theTol,
+                 Bnd_Box& theBox)
 {
-  Standard_Real aTF1, aTL1, aTF2, aTL2, Tol, af, al,aDist2, aMinDist2;
-  Standard_Boolean theflag=Standard_False;
-  Standard_Integer aNbExt, i, iLower;
-
-  aCP.Range1(aTF1, aTL1);
-  (aCP.Ranges2())(1).Range(aTF2, aTL2);
-
-  Tol = Precision::PConfusion();
-
-  const Handle(Geom_Curve)&  Curve1   =BRep_Tool::Curve  (myCFrom.Edge(), af, al);
-  const Handle(Geom_Curve)&  Curve2   =BRep_Tool::Curve  (myCTo.Edge()  , af, al);
-  
-  GeomAdaptor_Curve   TheCurve1   (Curve1, aTF1, aTL1);
-  GeomAdaptor_Curve   TheCurve2   (Curve2, aTF2, aTL2);
-
-  {
-    Standard_Real aTol1 = TheCurve1.Resolution(myCriteria);
-    aTol1 = (Tol < aTol1) ? Tol : aTol1;
-    
-    Standard_Boolean isfirst = (Abs(myTminFrom - aTF1) < aTol1);
-    Standard_Boolean islast  = (Abs(myTmaxFrom - aTL1) < aTol1);
-    
-    if(!isfirst || !islast) {
-      if(isfirst) {
-       aTx1 = aTF1;
-       //modified by NIZNHY-PKV Mon Jun  8 09:59:27 2009f
-       //GeomAPI_ProjectPointOnCurve aProjector(Curve1->Value(aTx1), Curve2, aTF2, aTL2);      
-       GeomAPI_ProjectPointOnCurve aProjector;
-       aProjector.Init(Curve2, aTF2, aTL2);
-       aProjector.Perform(Curve1->Value(aTx1));
-       //modified by NIZNHY-PKV Mon Jun  8 10:00:12 2009t
-       //
-       if(aProjector.NbPoints() > 0)
-         aTx2 = aProjector.LowerDistanceParameter();
-       else {
-         if(Curve1->Value(aTx1).Distance(Curve2->Value(aTF2)) < myCriteria)
-           aTx2 = aTF2;
-         else
-           aTx2 = aTL2;
-       }
-       return !theflag;
-      }
-      
-      if(islast) {
-       aTx1 = aTL1;
-       //modified by NIZNHY-PKV Mon Jun  8 10:00:24 2009f
-       //GeomAPI_ProjectPointOnCurve aProjector(Curve1->Value(aTx1), Curve2, aTF2, aTL2);
-       GeomAPI_ProjectPointOnCurve aProjector;
-       aProjector.Init(Curve2, aTF2, aTL2);
-       aProjector.Perform(Curve1->Value(aTx1));
-       //modified by NIZNHY-PKV Mon Jun  8 10:00:26 2009t
-       if(aProjector.NbPoints() > 0)
-         aTx2 = aProjector.LowerDistanceParameter();
-       else {
-         if(Curve1->Value(aTx1).Distance(Curve2->Value(aTL2)) < myCriteria)
-           aTx2 = aTL2;
-         else
-           aTx2 = aTF2;
-       }
-       return !theflag;
-      }
-    }
-  }
-                                
-  Extrema_ExtCC anExtrema (TheCurve1, TheCurve2, aTF1-Tol, aTL1+Tol, aTF2-Tol, aTL2+Tol, Tol, Tol);
-  
-  if(!anExtrema.IsDone()) {
-    return theflag;
-  }
-  if (anExtrema.IsParallel()) {
-    return theflag;
-  }
-  
-  aNbExt=anExtrema.NbExt() ;
-  if (!aNbExt) {
-     return theflag;
-  }
-
-  Standard_Boolean istouch = Standard_True;
-  Standard_Integer avalidindex = 0;
-
-  iLower=1;
-  aMinDist2=1.e100;
-  for (i=1; i<=aNbExt; ++i) {
-    aDist2=anExtrema.SquareDistance(i);
-    if (aDist2 < aMinDist2) {
-      aMinDist2=aDist2;
-      iLower=i;
-    }
-
-    if(aDist2 < myCriteria * myCriteria) {
-      if(avalidindex) {
-       Extrema_POnCurv aPOnC1, aPOnC2;
-       anExtrema.Points(i, aPOnC1, aPOnC2);
-       Standard_Real aPar1 = aPOnC1.Parameter();
-       anExtrema.Points(avalidindex, aPOnC1, aPOnC2);
-       Standard_Real aPar2 = aPOnC1.Parameter();
-       
-       if(Abs(aPar1 - aPar2) > Precision::PConfusion()) {
-         istouch = Standard_False;
-       }
-      }
-      avalidindex = i;
-    }
-  }
-
-  aDist2=anExtrema.SquareDistance(iLower);
-  if (aDist2 > myCriteria * myCriteria) {
-    return theflag;
-  }
-
-  Extrema_POnCurv aPOnC1, aPOnC2;
-  anExtrema.Points(iLower, aPOnC1, aPOnC2);
-  
-  aTx1=aPOnC1.Parameter();
-  aTx2=aPOnC2.Parameter();
-
-  if((myCFrom.GetType() == GeomAbs_Line   && myCTo.GetType() == GeomAbs_Circle) || 
-     (myCFrom.GetType() == GeomAbs_Circle && myCTo.GetType() == GeomAbs_Line))
-  {
-    Standard_Real aRadius;
-    GeomAbs_CurveType aTFrom, aTTo;
-    gp_Circ aCirc;
-    gp_Lin  aLine;
-    gp_Pnt aPCenter, aPOnLine;
-
-    aTFrom=myCFrom.GetType();
-    aTTo  =myCTo.GetType();
-    
-    if (aTFrom==GeomAbs_Circle) {
-      aCirc=myCFrom.Circle();
-      aLine=myCTo.Line();
-      Curve2->D0(aTx2, aPOnLine);
-    }
-
-    else {
-      aCirc=myCTo.Circle();
-      aLine=myCFrom.Line();
-      Curve1->D0(aTx1, aPOnLine);
-    }
-    
-
-    aPCenter=aCirc.Location();
-    aRadius =aCirc.Radius();
-  
-    aDist2=aPOnLine.SquareDistance(aPCenter);
-    aDist2=fabs (sqrt(aDist2)-aRadius);
-    aDist2 *= aDist2;
-    if (aDist2 < Tol * Tol) {
-      return !theflag;
-    }
-  }
-  
-  GeomAPI_ProjectPointOnCurve aProjector;
-  Standard_Real aMidPar, aMidDist;   
-  aMidPar = (aTF1 + aTL1) * 0.5;  
-  //modified by NIZNHY-PKV Mon Jun  8 10:01:32 2009f
-  //aProjector.Init(Curve1->Value(aMidPar), Curve2, aTF2, aTL2);
-  aProjector.Init(Curve2, aTF2, aTL2);
-  aProjector.Perform(Curve1->Value(aMidPar));
-  //modified by NIZNHY-PKV Mon Jun  8 10:02:09 2009t
-  if(aProjector.NbPoints() > 0) {
-    aMidDist=aProjector.LowerDistance();
-    if(aMidDist * aMidDist < aDist2 || !istouch) {
-      aTx1 = aMidPar;
-      aTx2 = aProjector.LowerDistanceParameter();
-    }
-  }
-  
-  if (fabs (aTx1-aTF1) < Tol) {
-    return !theflag;
-  }
-
-  if (fabs (aTx1-aTL1) < Tol) {
-    return !theflag;
-  }
-
-  if (aTx1 > (aTF1-Tol) && aTx1 < (aTL1+Tol) ) {
-    return !theflag;
-  }
-
-  return theflag;
+  Bnd_Box aB;
+  BndLib_Add3dCurve::Add(theBAC, aT1, aT2, theTol, aB);
+  theBox = aB;
 }
+
 //=======================================================================
-//function :  CheckInterval
+//function : PointBoxDistance
 //purpose  : 
 //=======================================================================
-  Standard_Boolean IntTools_EdgeEdge::CheckInterval(const Standard_Real aT1,
-                                                   const Standard_Real aT2)
+Standard_Real PointBoxDistance(const Bnd_Box& aB,
+                               const gp_Pnt& aP)
 {
-  Standard_Boolean bFlag=Standard_False;
-  Standard_Integer i, aNb=4;
-  Standard_Real aT, dT, aDist;
-  
-  dT=(aT2-aT1)/aNb;
-  
-  for (i=1; i<aNb; ++i) {
-    aT=aT1+i*dT;
-    aDist=DistanceFunction(aT);
-    if (aDist>myEpsNull) {
-      return bFlag;
+  Standard_Real aPCoord[3];
+  Standard_Real aBMinCoord[3], aBMaxCoord[3];
+  Standard_Real aDist, aR1, aR2;
+  Standard_Integer i;
+  //
+  aP.Coord(aPCoord[0], aPCoord[1], aPCoord[2]);
+  aB.Get(aBMinCoord[0], aBMinCoord[1], aBMinCoord[2], 
+         aBMaxCoord[0], aBMaxCoord[1], aBMaxCoord[2]);
+  //
+  aDist = 0.;
+  for (i = 0; i < 3; ++i) {
+    aR1 = aBMinCoord[i] - aPCoord[i];
+    if (aR1 > 0.) {
+      aDist += aR1*aR1;
+      continue;
+    }
+    //
+    aR2 = aPCoord[i] - aBMaxCoord[i];
+    if (aR2 > 0.) {
+      aDist += aR2*aR2;
     }
   }
-  return !bFlag;
+  //
+  aDist = Sqrt(aDist);
+  return aDist;
 }
 
 //=======================================================================
-//function : RemoveIdenticalRoots 
+//function : TypeToInteger
 //purpose  : 
 //=======================================================================
-  void IntTools_EdgeEdge::RemoveIdenticalRoots()
+Standard_Integer TypeToInteger(const GeomAbs_CurveType theCType)
 {
-  Standard_Integer aNbRoots, j, k;
-
-  aNbRoots=mySequenceOfRoots.Length();
-  for (j=1; j<=aNbRoots; j++) { 
-    const IntTools_Root& aRj=mySequenceOfRoots(j);
-    for (k=j+1; k<=aNbRoots; k++) {
-      const IntTools_Root& aRk=mySequenceOfRoots(k);
-      
-      Standard_Real aTj, aTk, aDistance;
-      gp_Pnt aPj, aPk;
-
-      aTj=aRj.Root();
-      aTk=aRk.Root();
-
-      myCFrom.D0(aTj, aPj);
-      myCFrom.D0(aTk, aPk);
-
-      aDistance=aPj.Distance(aPk);
-      if (aDistance < myCriteria) {
-       mySequenceOfRoots.Remove(k);
-       aNbRoots=mySequenceOfRoots.Length();
-      }
-    }
-  }
+  Standard_Integer iRet;
+  //
+  switch(theCType) {
+  case GeomAbs_Line:
+    iRet=0;
+    break;
+  case GeomAbs_Hyperbola:
+  case GeomAbs_Parabola:
+    iRet=1;
+    break;
+  case GeomAbs_Circle:
+  case GeomAbs_Ellipse:
+    iRet=2;
+    break;
+  case GeomAbs_BezierCurve:
+  case GeomAbs_BSplineCurve:
+    iRet=3;
+    break;
+  default:
+    iRet=4;
+    break;
+  }
+  return iRet;
 }
 
 //=======================================================================
-//function : ComputeLineLine 
+//function : ResolutionCoeff
 //purpose  : 
 //=======================================================================
-  void IntTools_EdgeEdge::ComputeLineLine()
+Standard_Real ResolutionCoeff(const BRepAdaptor_Curve& theBAC,
+                              const IntTools_Range& theRange)
 {
-  Standard_Real Tolang2 = 1.e-16; 
-  Standard_Real Tol2 = myCriteria*myCriteria; 
-  Standard_Boolean IsParallel = Standard_False, IsCoincide = Standard_False;
-  myIsDone = Standard_True;
-
-  gp_Pnt P11, P12, P21, P22;
-
-  gp_Lin C1 = myCFrom.Line();
-  gp_Lin C2 = myCTo.Line();
-  const gp_Dir& D1 = C1.Position().Direction();
-  const gp_Dir& D2 = C2.Position().Direction();
-  Standard_Real aCos = D1.Dot(D2);
-  Standard_Real Ang2;
-  if(aCos >= 0. ) {
-    Ang2 = 2.*(1. - aCos);
-  }
-  else {
-    Ang2 = 2.*(1. + aCos);
-  }
-
-  if(Ang2 <= Tolang2) {
-    IsParallel = Standard_True;
-    if(C2.SquareDistance(C1.Location()) <= Tol2) {
-      IsCoincide = Standard_True;
-      P11 = ElCLib::Value(myTminFrom, C1);
-      P12 = ElCLib::Value(myTmaxFrom, C1);
-    }
-  }
-  else {
-    //Check coincidence of extremity points;
-    //Check only shortest line
-    P11 = ElCLib::Value(myTminFrom, C1);
-    P12 = ElCLib::Value(myTmaxFrom, C1);
-    if(C2.SquareDistance(P11) <= Tol2 && C2.SquareDistance(P12) <= Tol2) {
-      IsCoincide = Standard_True;
+  Standard_Real aResCoeff = 0.;
+  //
+  const Handle(Geom_Curve)& aCurve = theBAC.Curve().Curve();
+  const GeomAbs_CurveType aCurveType = theBAC.GetType();
+  //
+  switch (aCurveType) {
+  case GeomAbs_Circle :
+    aResCoeff = 1. / (2 * Handle(Geom_Circle)::DownCast (aCurve)->Circ().Radius());
+    break;
+  case GeomAbs_Ellipse :
+    aResCoeff =  1. / Handle(Geom_Ellipse)::DownCast (aCurve)->MajorRadius();
+    break;
+  case GeomAbs_OffsetCurve : {
+    const Handle(Geom_OffsetCurve)& anOffsetCurve = Handle(Geom_OffsetCurve)::DownCast(aCurve);
+    const Handle(Geom_Curve)& aBasisCurve = anOffsetCurve->BasisCurve();
+    GeomAdaptor_Curve aGBasisCurve(aBasisCurve);
+    const GeomAbs_CurveType aBCType = aGBasisCurve.GetType();
+    if (aBCType == GeomAbs_Line) {
+      break;
     }
-  }
-
-  if(IsCoincide) {
-    Standard_Real t21, t22;
-    t21 = ElCLib::Parameter(C2, P11);
-    t22 = ElCLib::Parameter(C2, P12);
-
-    if((t21 > myTmaxTo && t22 > myTmaxTo) || (t21 < myTminTo && t22 < myTminTo)) {
-      return;
+    else if (aBCType == GeomAbs_Circle) {
+      aResCoeff = 1. / (2 * (anOffsetCurve->Offset() + aGBasisCurve.Circle().Radius()));
+      break;
     }
-
-    Standard_Real temp;
-    if(t21 > t22) {
-      temp = t21;
-      t21 = t22;
-      t22 = temp;
+    else if (aBCType == GeomAbs_Ellipse) {
+      aResCoeff = 1. / (anOffsetCurve->Offset() + aGBasisCurve.Ellipse().MajorRadius());
+      break;
     }
-
-    IntTools_CommonPrt aCommonPrt;
-    aCommonPrt.SetEdge1(myCFrom.Edge());
-    aCommonPrt.SetEdge2(myCTo.Edge());
-    if(t21 >= myTminTo) {
-      if(t22 <= myTmaxTo) {
-       aCommonPrt.SetRange1(myTminFrom, myTmaxFrom);
-       aCommonPrt.SetAllNullFlag(Standard_True);
-       aCommonPrt.AppendRange2(t21, t22);
-      }
-      else {
-       aCommonPrt.SetRange1(myTminFrom, myTmaxFrom - (t22 - myTmaxTo));
-       aCommonPrt.AppendRange2(t21, myTmaxTo);
+  }
+  Standard_FALLTHROUGH
+  case GeomAbs_Hyperbola :
+  case GeomAbs_Parabola : 
+  case GeomAbs_OtherCurve :{
+    Standard_Real k, kMin, aDist, aDt, aT1, aT2, aT;
+    Standard_Integer aNbP, i;
+    gp_Pnt aP1, aP2;
+    //
+    aNbP = 30;
+    theRange.Range(aT1, aT2);
+    aDt = (aT2 - aT1) / aNbP;
+    aT = aT1;
+    kMin = 10.;
+    //
+    theBAC.D0(aT1, aP1);
+    for (i = 1; i <= aNbP; ++i) {
+      aT += aDt;
+      theBAC.D0(aT, aP2);
+      aDist = aP1.Distance(aP2);
+      k = aDt / aDist;
+      if (k < kMin) {
+        kMin = k;
       }
+      aP1 = aP2;
     }
-    else {
-      aCommonPrt.SetRange1(myTminFrom + (myTminTo - t21), myTmaxFrom);
-      aCommonPrt.AppendRange2(myTminTo, t22);
-    }
-    aCommonPrt.SetType(TopAbs_EDGE);  
-    mySeqOfCommonPrts.Append(aCommonPrt);
-    return;
-
-  }
-
-  if(IsParallel) {
-    return;
-  }
-
-  Standard_Real aSin2 = 1. - aCos*aCos;
-  gp_Pnt O1 = C1.Location();
-  gp_Pnt O2 = C2.Location();
-  gp_Vec O1O2 (O1,O2);
-  Standard_Real U2 = (D1.XYZ()*(O1O2.Dot(D1))-(O1O2.XYZ())).Dot(D2.XYZ());
-  U2 /= aSin2;
-  if(U2 < myTminTo || U2 > myTmaxTo) {
-    return;
-  }
-  
-  gp_Pnt P2(ElCLib::Value(U2,C2));
-  Standard_Real U1 = (gp_Vec(O1,P2)).Dot(D1);
-  if(U1 < myTminFrom || U1 > myTmaxFrom) {
-    return;
+    //
+    aResCoeff = kMin;
+    break;
   }
-
-  gp_Pnt P1(ElCLib::Value(U1,C1));
-  Standard_Real d2 = P1.SquareDistance(P2);
-
-  if(d2 > Tol2) {
-    return;
+  default:
+    break;
   }
-
-  IntTools_CommonPrt aCommonPrt;
-  aCommonPrt.SetEdge1(myCFrom.Edge());
-  aCommonPrt.SetEdge2(myCTo.Edge());
-  aCommonPrt.SetRange1(U1 - myCriteria, U1 + myCriteria);
-  aCommonPrt.AppendRange2(U2 - myCriteria, U2 + myCriteria);
-  aCommonPrt.SetType(TopAbs_VERTEX);
-  aCommonPrt.SetVertexParameter1(U1);
-  aCommonPrt.SetVertexParameter2(U2);
-  mySeqOfCommonPrts.Append(aCommonPrt);
-  
+  //
+  return aResCoeff;
 }
-/*
+
 //=======================================================================
-//function : CheckTouchVertex 
+//function : Resolution
 //purpose  : 
 //=======================================================================
-  Standard_Boolean IntTools_EdgeEdge::CheckTouchVertex (const IntTools_CommonPrt& aCP,
-                                                       Standard_Real& aTx1,
-                                                       Standard_Real& aTx2) const
+Standard_Real Resolution(const Handle(Geom_Curve)& theCurve,
+                         const GeomAbs_CurveType theCurveType,
+                         const Standard_Real theResCoeff,
+                         const Standard_Real theR3D)
 {
-  Standard_Real aTF1, aTL1, aTF2, aTL2, Tol, af, al, aDist, aDistNew;
-  Standard_Real aTFR1, aTLR1, aTFR2, aTLR2;
-  Standard_Boolean theflag=Standard_False;
-  Standard_Integer iNb, aNbExt, i;
-
-  aCP.Range1(aTFR1, aTLR1);
-  (aCP.Ranges2())(1).Range(aTFR2, aTLR2);
-  
-  Tol = Precision::PConfusion();
-  
-  GeomAbs_CurveType aTFrom, aTTo;
-
-  aTFrom=myCFrom.GetType();
-  aTTo  =myCTo.GetType();
-  gp_Circ aCirc;
-  gp_Lin  aLine;
-
-  if (aTFrom==GeomAbs_Circle) {
-    aCirc=myCFrom.Circle();
-    aLine=myCTo.Line();
-  }
-  else {
-    aCirc=myCTo.Circle();
-    aLine=myCFrom.Line();
+  Standard_Real aRes;
+  //
+  switch (theCurveType) {
+  case GeomAbs_Line :
+    aRes = theR3D;
+    break;
+  case GeomAbs_Circle: {
+    Standard_Real aDt = theResCoeff * theR3D;
+    aRes = (aDt <= 1.) ? 2*ASin(aDt) : 2*M_PI;
+    break;
+  }
+  case GeomAbs_BezierCurve:
+    Handle(Geom_BezierCurve)::DownCast (theCurve)->Resolution(theR3D, aRes);
+    break;
+  case GeomAbs_BSplineCurve:
+    Handle(Geom_BSplineCurve)::DownCast (theCurve)->Resolution(theR3D, aRes);
+    break;
+  case GeomAbs_OffsetCurve: {
+    const Handle(Geom_Curve)& aBasisCurve = 
+      Handle(Geom_OffsetCurve)::DownCast(theCurve)->BasisCurve();
+    const GeomAbs_CurveType aBCType = GeomAdaptor_Curve(aBasisCurve).GetType();
+    if (aBCType == GeomAbs_Line) {
+      aRes = theR3D;
+      break;
+    }
+    else if (aBCType == GeomAbs_Circle) {
+      Standard_Real aDt = theResCoeff * theR3D;
+      aRes = (aDt <= 1.) ? 2*ASin(aDt) : 2*M_PI;
+      break;
+    }
   }
-  
-  Standard_Real aRadius;
-  gp_Pnt aPCenter;
-  aPCenter=aCirc.Location();
-  aRadius =aCirc.Radius();
-  
-  aDist=aLine.Distance(aPCenter);
-  aDist=fabs (aDist-aRadius);
-  if (aDist > Tol) {
-    return theflag;
+  Standard_FALLTHROUGH
+  default:
+    aRes = theResCoeff * theR3D;
+    break;
   }
   //
-  aTF1=myTminFrom;
-  aTL1=myTmaxFrom;
-  aTF2=myTminTo;
-  aTL2=myTmaxTo;
+  return aRes;
+}
 
-  const Handle(Geom_Curve)&  Curve1   =BRep_Tool::Curve  (myCFrom.Edge(), af, al);
-  const Handle(Geom_Curve)&  Curve2   =BRep_Tool::Curve  (myCTo.Edge()  , af, al);
-  
-  GeomAdaptor_Curve   TheCurve1   (Curve1, aTF1, aTL1);
-  GeomAdaptor_Curve   TheCurve2   (Curve2, aTF2, aTL2);
-                                
-  Extrema_ExtCC anExtrema (TheCurve1, 
-                          TheCurve2, 
-                          aTF1-Tol, 
-                          aTL1+Tol, 
-                          aTF2-Tol, 
-                          aTL2+Tol, 
-                          Tol, Tol);
-  
-  if(!anExtrema.IsDone()) {
-    return theflag;
-  }
-  if (anExtrema.IsParallel()) {
-    return theflag;
-  }
-  
-  aNbExt=anExtrema.NbExt() ;
-  if (!aNbExt) {
-     return theflag;
-  }
+//=======================================================================
+//function : CurveDeflection
+//purpose  : 
+//=======================================================================
+Standard_Real CurveDeflection(const BRepAdaptor_Curve& theBAC,
+                              const IntTools_Range& theRange)
+{
+  Standard_Real aDt, aT, aT1, aT2, aDefl;
+  Standard_Integer i, aNbP;
+  gp_Vec aV1, aV2;
+  gp_Pnt aP;
   //
-  iNb=0;
-  Standard_Real aTx1Av=0., aTx2Av=0.;
-  
-  gp_Pnt aPC1, aPC2;
-  
-  for (i=1; i<=aNbExt; ++i) {
-    Extrema_POnCurv aPOnC1, aPOnC2;
-    anExtrema.Points(i, aPOnC1, aPOnC2);
-    
-    aTx1=aPOnC1.Parameter();
-    aTx2=aPOnC2.Parameter();
-    if (fabs (aTx1-aTFR1) < 1.e-4 && fabs (aTx2-aTFR2) < 1.e-4) {
-      aTx1Av=aTx1Av+aTx1;
-      aTx2Av=aTx2Av+aTx2;
-      iNb++;
+  aDefl = 0;
+  aNbP = 10;
+  theRange.Range(aT1, aT2);
+  aDt = (aT2 - aT1) / aNbP;
+  aT = aT1;
+  //
+  theBAC.D1(aT1, aP, aV1);
+  for (i = 1; i <= aNbP; ++i) {
+    aT += aDt;
+    theBAC.D1(aT, aP, aV2);
+    if (aV1.Magnitude() > gp::Resolution() &&
+        aV2.Magnitude() > gp::Resolution()) {
+      gp_Dir aD1(aV1), aD2(aV2);
+      aDefl += aD1.Angle(aD2);
     }
-  }
-
-  if (!iNb) {
-    return theflag;
-  }
-
-  aTx1=aTx1Av/iNb;
-  aTx2=aTx2Av/iNb;
-  
-  Curve1->D0(aTx1, aPC1);
-  Curve2->D0(aTx2, aPC2);
-  //
-  aDistNew=aPC1.Distance(aPC2);
-  if (aDistNew > aDist) {
-    aTx1=0.5*(aTFR1+aTLR1);
-    aTx2=0.5*(aTFR2+aTLR2);
-    return !theflag;
+    aV1 = aV2;
   }
   //
+  return aDefl;
+}
 
-  aDist=aDistNew;
-  if (aDist > myCriteria) {
-    return theflag;
-  }
-  
-  if (fabs (aTx1-aTF1) < Tol) {
-    return !theflag;
-  }
-
-  if (fabs (aTx1-aTL1) < Tol) {
-    return !theflag;
-  }
-
-  if (aTx1 > (aTF1-Tol) && aTx1 < (aTL1+Tol) ) {
-    return !theflag;
+//=======================================================================
+//function : IsClosed
+//purpose  : 
+//=======================================================================
+Standard_Boolean IsClosed(const Handle(Geom_Curve)& theCurve,
+                          const Standard_Real aT1,
+                          const Standard_Real aT2,
+                          const Standard_Real theTol,
+                          const Standard_Real theRes)
+{
+  if (Abs(aT1 - aT2) < theRes)
+  {
+    return Standard_False;
   }
 
-  return theflag;
+  gp_Pnt aP1, aP2;
+  theCurve->D0(aT1, aP1);
+  theCurve->D0(aT2, aP2);
+  //
+  Standard_Real aD = aP1.Distance(aP2);
+  return aD < theTol;
 }
-
-*/