]> OCCT Git - occt.git/commitdiff
Coding - Combining multiple gxx IntWalk and IntPatch #222
authordpasukhi <dpasukhi@opencascade.com>
Sat, 28 Dec 2024 23:20:35 +0000 (23:20 +0000)
committerdpasukhi <dpasukhi@opencascade.com>
Sat, 28 Dec 2024 23:29:40 +0000 (23:29 +0000)
Refactor IntWalk and IntPatch to remove unused gxx files
  and combine to one with refactoring

19 files changed:
src/BRepFill/BRepFill_OffsetWire.cxx
src/GCPnts/GCPnts_QuasiUniformDeflection.cxx
src/IntPatch/FILES
src/IntPatch/IntPatch_ImpImpIntersection.cxx
src/IntPatch/IntPatch_ImpImpIntersection_0.gxx [deleted file]
src/IntPatch/IntPatch_ImpImpIntersection_1.gxx [deleted file]
src/IntPatch/IntPatch_ImpImpIntersection_2.gxx [deleted file]
src/IntPatch/IntPatch_ImpImpIntersection_3.gxx [deleted file]
src/IntPatch/IntPatch_ImpImpIntersection_4.gxx [deleted file]
src/IntPatch/IntPatch_ImpImpIntersection_5.gxx [deleted file]
src/IntPatch/IntPatch_ImpImpIntersection_6.gxx [deleted file]
src/IntWalk/FILES
src/IntWalk/IntWalk_IWalking.gxx
src/IntWalk/IntWalk_IWalking_1.gxx [deleted file]
src/IntWalk/IntWalk_IWalking_2.gxx [deleted file]
src/IntWalk/IntWalk_IWalking_3.gxx [deleted file]
src/IntWalk/IntWalk_IWalking_4.gxx [deleted file]
src/IntWalk/IntWalk_IWalking_5.gxx [deleted file]
src/IntWalk/IntWalk_IWalking_6.gxx [deleted file]

index a0ec2ad56f8b5fadb4279a15c68d3189fee63285..feea35cec88a022ad7264f939710d764c524fff2 100644 (file)
@@ -2675,7 +2675,7 @@ static void QuasiFleche(const Adaptor3d_Curve& C,
   Standard_Real theFleche=0;
   Standard_Boolean flecheok = Standard_False;
   if (Norme > Eps) { 
-    // Evaluation of the arrow by interpolation. See IntWalk_IWalking_5.gxx
+    // Evaluation of the arrow by interpolation. See IntWalk_IWalking::TestDeflection
     Standard_Real N1 = Vdeb.SquareMagnitude();
     Standard_Real N2 = Vdelta.SquareMagnitude();
     if (N1 > Eps && N2 > Eps) {
index 78a66eac801d8a6ebe9a9cd6299e293a9dea65dc..94fc8200f876285d03952024e7b2eaca2ca225f2 100644 (file)
@@ -109,7 +109,7 @@ static void QuasiFleche (const TheCurve& theC,
   Standard_Boolean isFlecheOk = Standard_False;
   if (aNorme > theEps && aNorme > 16. * theDeflection2)
   {
-    // Evaluation de la fleche par interpolation . Voir IntWalk_IWalking_5.gxx
+    // Evaluation de la fleche par interpolation . Voir IntWalk_IWalking::TestDeflection
     Standard_Real N1 = theVdeb.SquareMagnitude();
     Standard_Real N2 = aVdelta.SquareMagnitude();
     if (N1 > theEps && N2 > theEps)
index 725ea816b8a5f4b72f917a6aa359de9de3fc1c9e..e6be344b1e1f6b32e37601966d330044c033eba5 100755 (executable)
@@ -23,13 +23,6 @@ IntPatch_IType.hxx
 IntPatch_ImpImpIntersection.cxx
 IntPatch_ImpImpIntersection.hxx
 IntPatch_ImpImpIntersection.lxx
-IntPatch_ImpImpIntersection_0.gxx
-IntPatch_ImpImpIntersection_1.gxx
-IntPatch_ImpImpIntersection_2.gxx
-IntPatch_ImpImpIntersection_3.gxx
-IntPatch_ImpImpIntersection_4.gxx
-IntPatch_ImpImpIntersection_5.gxx
-IntPatch_ImpImpIntersection_6.gxx
 IntPatch_ImpPrmIntersection.cxx
 IntPatch_ImpPrmIntersection.hxx
 IntPatch_ImpPrmIntersection.lxx
index 371dfcf75e3b6ad2be8599dfb5394bd5af79166c..8be04e7c34e77132648eb258ae09fabb8cb6ae4f 100644 (file)
@@ -1,7 +1,5 @@
-// Created on: 1992-05-07
-// Created by: Jacques GOUSSARD
 // Copyright (c) 1992-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
+// Copyright (c) 1999-2024 OPEN CASCADE SAS
 //
 // This file is part of Open CASCADE Technology software library.
 //
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-
 #include <Adaptor2d_Curve2d.hxx>
-#include <Adaptor3d_Surface.hxx>
 #include <Adaptor3d_HVertex.hxx>
+#include <Adaptor3d_Surface.hxx>
 #include <Adaptor3d_TopolTool.hxx>
+#include <Bnd_Box2d.hxx>
+#include <Bnd_Range.hxx>
 #include <ElCLib.hxx>
 #include <ElSLib.hxx>
-#include <gp.hxx>
-#include <gp_Cone.hxx>
-#include <gp_Cylinder.hxx>
-#include <gp_Pln.hxx>
-#include <gp_Sphere.hxx>
+#include <Extrema_ExtPC.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <Geom_Ellipse.hxx>
+#include <Geom_Hyperbola.hxx>
+#include <Geom_Parabola.hxx>
 #include <IntAna_IntQuadQuad.hxx>
+#include <IntAna_ListOfCurve.hxx>
 #include <IntAna_QuadQuadGeo.hxx>
 #include <IntAna_Quadric.hxx>
 #include <IntPatch_ALine.hxx>
 #include <IntPatch_GLine.hxx>
 #include <IntPatch_HInterTool.hxx>
 #include <IntPatch_ImpImpIntersection.hxx>
-#include "../IntPatch/IntPatch_ImpImpIntersection_0.gxx"
-#include "../IntPatch/IntPatch_ImpImpIntersection_1.gxx"
-#include "../IntPatch/IntPatch_ImpImpIntersection_2.gxx"
-#include "../IntPatch/IntPatch_ImpImpIntersection_3.gxx"
-#include "../IntPatch/IntPatch_ImpImpIntersection_4.gxx"
-#include "../IntPatch/IntPatch_ImpImpIntersection_5.gxx"
-#include "../IntPatch/IntPatch_ImpImpIntersection_6.gxx"
-#include <IntPatch_Line.hxx>
-#include <IntPatch_Point.hxx>
 #include <IntPatch_RLine.hxx>
-#include <IntPatch_SequenceOfLine.hxx>
 #include <IntPatch_ThePathPointOfTheSOnBounds.hxx>
 #include <IntPatch_TheSegmentOfTheSOnBounds.hxx>
+#include <IntPatch_WLine.hxx>
 #include <IntSurf.hxx>
-#include <IntSurf_Quadric.hxx>
-#include <Standard_ConstructionError.hxx>
-#include <Standard_DomainError.hxx>
-#include <Standard_OutOfRange.hxx>
-#include <StdFail_NotDone.hxx>
-#include <TColgp_SequenceOfPnt.hxx>
+#include <NCollection_IncAllocator.hxx>
+#include <Standard_DivideByZero.hxx>
 #include <TColStd_Array1OfInteger.hxx>
 #include <TColStd_SequenceOfReal.hxx>
+#include <gce_MakeLin.hxx>
+#include <gp.hxx>
+#include <gp_Cone.hxx>
+#include <gp_Cylinder.hxx>
+#include <gp_Pln.hxx>
+#include <gp_Sphere.hxx>
+#include <math_Matrix.hxx>
+#include <math_Vector.hxx>
+
+#include <algorithm>
+
+static void PutPointsOnLine(const Handle(Adaptor3d_Surface)& S1,
+                            const Handle(Adaptor3d_Surface)& S2,
+                            const IntPatch_SequenceOfPathPointOfTheSOnBounds&,
+                            const IntPatch_SequenceOfLine&,
+                            const Standard_Boolean,
+                            const Handle(Adaptor3d_TopolTool)&,
+                            const IntSurf_Quadric&,
+                            const IntSurf_Quadric&,
+                            const Standard_Boolean,
+                            const Standard_Real);
+
+static Standard_Boolean MultiplePoint(const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
+                                      const Handle(Adaptor3d_TopolTool)&                Domain,
+                                      const IntSurf_Quadric&                            QuadSurf,
+                                      const gp_Vec&                                     Normale,
+                                      const IntPatch_SequenceOfLine&                    slin,
+                                      TColStd_Array1OfInteger&                          Done,
+                                      TColStd_Array1OfInteger&                          UsedLine,
+                                      const Standard_Integer                            Index,
+                                      const Standard_Boolean                            OnFirst,
+                                      const Standard_Real                               theToler);
+
+static Standard_Boolean PointOnSecondDom(const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
+                                         const Handle(Adaptor3d_TopolTool)&                Domain,
+                                         const IntSurf_Quadric&                            QuadSurf,
+                                         const gp_Vec&                                     Normale,
+                                         const gp_Vec&                                     Vtgint,
+                                         const Handle(IntPatch_Line)&                      lin,
+                                         TColStd_Array1OfInteger&                          Done,
+                                         const Standard_Integer                            Index,
+                                         const Standard_Real                               theToler);
+
+static Standard_Boolean SingleLine(const gp_Pnt&, const Handle(IntPatch_Line)&, const Standard_Real, Standard_Real&, gp_Vec&);
+
+static Standard_Boolean FindLine(gp_Pnt&                          Psurf,
+                                 const IntPatch_SequenceOfLine&   slin,
+                                 const Standard_Real              Tol,
+                                 TColStd_ListOfReal&              theLParams,
+                                 gp_Vec&                          Vtgtint,
+                                 Standard_Integer&                theLineIdx,
+                                 Standard_Integer                 OnlyThisLine,
+                                 const Handle(Adaptor2d_Curve2d)& thearc,
+                                 Standard_Real&                   theparameteronarc,
+                                 gp_Pnt&                          thepointonarc,
+                                 const IntSurf_Quadric&           QuadSurf1,
+                                 const IntSurf_Quadric&           QuadSurf2,
+                                 Standard_Real&                   theOutputToler);
+
+static void ProcessSegments(const IntPatch_SequenceOfSegmentOfTheSOnBounds&,
+                            IntPatch_SequenceOfLine&,
+                            const IntSurf_Quadric&,
+                            const IntSurf_Quadric&,
+                            const Standard_Boolean,
+                            const Standard_Real);
+
+static void ProcessRLine(IntPatch_SequenceOfLine&,
+                         const IntSurf_Quadric&,
+                         const IntSurf_Quadric&,
+                         const Standard_Real,
+                         const Standard_Boolean theIsReqToKeepRLine);
+
+//-- le calcul de dist est completement faux ds la routine ci dessous a revoir (lbr le 18 nov 97)
+Standard_Boolean IntersectionWithAnArc(gp_Pnt&                          PSurf,
+                                       const Handle(IntPatch_ALine)&    alin,
+                                       Standard_Real&                   para,
+                                       const Handle(Adaptor2d_Curve2d)& thearc,
+                                       Standard_Real&                   _theparameteronarc,
+                                       gp_Pnt&                          thepointonarc,
+                                       const IntSurf_Quadric&           QuadSurf,
+                                       const Standard_Real              u0alin,
+                                       const Standard_Real              u1alin)
+{
+  Standard_Real dtheta, theta;
+#ifdef OCCT_DEBUG
+  //Standard_Real u,v,A,B,C,cost,sint,sign;
+#endif
+  //-- recherche bete du point le plus proche de thearc->Value(...)
+  dtheta           = (u1alin - u0alin) * 0.01;
+  Standard_Real du = 0.000000001;
+  if (du >= dtheta)
+    du = dtheta / 2;
+  Standard_Real distmin           = RealLast();
+
+  Standard_Real thetamin          = 0.;
+
+  Standard_Real theparameteronarc = _theparameteronarc;
+  for (Standard_Real _theta = u0alin + dtheta; _theta <= u1alin - dtheta; _theta += dtheta)
+  {
+    gp_Pnt        P = alin->Value(_theta);
+    Standard_Real d = P.Distance(PSurf);
+    if (d < distmin)
+    {
+      thetamin = _theta;
+      distmin  = d;
+    }
+  }
+
+  Standard_Real bestpara = 0., besttheta = 0., bestdist = 0., distinit = 0.;
+
+  //-- Distance initiale
+  {
+    gp_Pnt        pp0 = alin->Value(thetamin);
+    Standard_Real ua0, va0;
+    QuadSurf.Parameters(pp0, ua0, va0);
+    gp_Pnt2d p2d;
+    gp_Vec2d d2d;
+    thearc->D1(theparameteronarc, p2d, d2d);
+    gp_Vec2d PaPr(gp_Pnt2d(ua0, va0), p2d);
+    distinit = PaPr.Magnitude();
+  }
+  theta                   = thetamin;
+  //-- recherche a partir de theta et theparameteronarc
+  Standard_Boolean cpasok = Standard_True;
+  Standard_Integer nbiter = 0;
+  Standard_Real    drmax  = (thearc->LastParameter() - thearc->FirstParameter()) * 0.05;
+  Standard_Real    damax  = (u1alin - u0alin) * 0.05;
+
+  bestdist                = RealLast();
+
+  do
+  {
+    Standard_Real ua0, va0, ua1, va1;
+    //-- alin->Curve().InternalUVValue(theta,ua0,va0,A,B,C,cost,sint,sign);
+    //-- alin->Curve().InternalUVValue(theta+du,ua1,va1,A,B,C,cost,sint,sign);
+    gp_Pnt pp0 = alin->Value(theta);
+    gp_Pnt pp1 = alin->Value(theta + du);
+    QuadSurf.Parameters(pp0, ua0, va0);
+    QuadSurf.Parameters(pp1, ua1, va1);
+
+    gp_Vec2d D1a((ua1 - ua0) / du, (va1 - va0) / du);
+    gp_Pnt2d p2d;
+    gp_Vec2d d2d;
+    thearc->D1(theparameteronarc, p2d, d2d);
+    gp_Vec2d PaPr(gp_Pnt2d(ua0, va0), p2d);
+
+    Standard_Real pbd = PaPr.Magnitude();
+    if (bestdist > pbd)
+    {
+      bestdist  = pbd;
+      bestpara  = theparameteronarc;
+      besttheta = theta;
+    }
+
+    D1a.SetCoord(-D1a.X(), -D1a.Y());
+
+    Standard_Real d  = D1a.X() * d2d.Y() - D1a.Y() * d2d.X();
+
+    Standard_Real da = (-PaPr.X()) * d2d.Y() - (-PaPr.Y()) * d2d.X();
+    Standard_Real dr = D1a.X() * (-PaPr.Y()) - D1a.Y() * (-PaPr.X());
+    if (Abs(d) > 1e-15)
+    {
+      da /= d;
+      dr /= d;
+    }
+    else
+    {
+      if (Abs(PaPr.X()) > Abs(PaPr.Y()))
+      {
+        Standard_Real xx = PaPr.X();
+        xx *= 0.5;
+        if (D1a.X())
+        {
+          da = -xx / D1a.X();
+        }
+        if (d2d.X())
+        {
+          dr = -xx / d2d.X();
+        }
+      }
+      else
+      {
+        Standard_Real yy = PaPr.Y();
+        yy *= 0.5;
+        if (D1a.Y())
+        {
+          da = -yy / D1a.Y();
+        }
+        if (d2d.Y())
+        {
+          dr = -yy / d2d.Y();
+        }
+      }
+    }
+    //--     Standard_Real da = -PaPr.Dot(D1a);
+    //--     Standard_Real dr = -PaPr.Dot(d2d);
+
+    if (da < -damax)
+      da = -damax;
+    else if (da > damax)
+      da = damax;
+    if (dr < -drmax)
+      dr = -drmax;
+    else if (dr > drmax)
+      dr = drmax;
+
+    if (Abs(da) < 1e-10 && Abs(dr) < 1e-10)
+    {
+      para               = theta;
+      PSurf              = alin->Value(para);
+      _theparameteronarc = theparameteronarc;
+      thepointonarc      = alin->Value(para);
+      cpasok             = Standard_False;
+      //--      printf("\nt:%d",nbiter);
+      return (Standard_True);
+    }
+    else
+    {
+      theta += da;
+      theparameteronarc += dr;
+      if (theparameteronarc > thearc->LastParameter())
+      {
+        theparameteronarc = thearc->LastParameter();
+      }
+      if (theparameteronarc < thearc->FirstParameter())
+      {
+        theparameteronarc = thearc->FirstParameter();
+      }
+      if (theta < u0alin)
+      {
+        theta = u0alin;
+      }
+      if (theta > u1alin - du)
+      {
+        theta = u1alin - du - du;
+      }
+    }
+    nbiter++;
+  } while (cpasok && nbiter < 20);
+  if (bestdist < distinit)
+  {
+    para               = besttheta;
+    PSurf              = alin->Value(para);
+    _theparameteronarc = bestpara;
+    thepointonarc      = alin->Value(para);
+    //--     printf("\nT:%d",nbiter);
+    return (Standard_True);
+  }
+  //--   printf("\nF:%d",nbiter);
+  return (Standard_False);
+}
+
+//-- ======================================================================
+static void Recadre(const Handle(Adaptor3d_Surface)& myHS1,
+                    const Handle(Adaptor3d_Surface)& myHS2,
+                    Standard_Real&                   u1,
+                    Standard_Real&                   v1,
+                    Standard_Real&                   u2,
+                    Standard_Real&                   v2)
+{
+  Standard_Real       f, l, lmf, fpls2;
+  GeomAbs_SurfaceType typs1 = myHS1->GetType();
+  GeomAbs_SurfaceType typs2 = myHS2->GetType();
+
+  Standard_Boolean myHS1IsUPeriodic, myHS1IsVPeriodic;
+  switch (typs1)
+  {
+    case GeomAbs_Cylinder:
+    case GeomAbs_Cone:
+    case GeomAbs_Sphere:
+    {
+      myHS1IsUPeriodic = Standard_True;
+      myHS1IsVPeriodic = Standard_False;
+      break;
+    }
+    case GeomAbs_Torus:
+    {
+      myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_True;
+      break;
+    }
+    default:
+    {
+      //-- Le cas de biparametrees periodiques est gere en amont
+      myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_False;
+      break;
+    }
+  }
+
+  Standard_Boolean myHS2IsUPeriodic, myHS2IsVPeriodic;
+  switch (typs2)
+  {
+    case GeomAbs_Cylinder:
+    case GeomAbs_Cone:
+    case GeomAbs_Sphere:
+    {
+      myHS2IsUPeriodic = Standard_True;
+      myHS2IsVPeriodic = Standard_False;
+      break;
+    }
+    case GeomAbs_Torus:
+    {
+      myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_True;
+      break;
+    }
+    default:
+    {
+      //-- Le cas de biparametrees periodiques est gere en amont
+      myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_False;
+      break;
+    }
+  }
+  if (myHS1IsUPeriodic)
+  {
+    lmf   = M_PI + M_PI; //-- myHS1->UPeriod();
+    f     = myHS1->FirstUParameter();
+    l     = myHS1->LastUParameter();
+    fpls2 = 0.5 * (f + l);
+    while ((u1 < f) && ((fpls2 - u1) > (u1 + lmf - fpls2)))
+    {
+      u1 += lmf;
+    }
+    while ((u1 > l) && ((u1 - fpls2) > (fpls2 - (u1 - lmf))))
+    {
+      u1 -= lmf;
+    }
+  }
+  if (myHS1IsVPeriodic)
+  {
+    lmf   = M_PI + M_PI; //-- myHS1->VPeriod();
+    f     = myHS1->FirstVParameter();
+    l     = myHS1->LastVParameter();
+    fpls2 = 0.5 * (f + l);
+    while ((v1 < f) && ((fpls2 - v1) > (v1 + lmf - fpls2)))
+    {
+      v1 += lmf;
+    }
+    while ((v1 > l) && ((v1 - fpls2) > (fpls2 - (v1 - lmf))))
+    {
+      v1 -= lmf;
+    }
+    //--    while(v1 < f) { v1+=lmf; }
+    //--    while(v1 > l) { v1-=lmf; }
+  }
+  if (myHS2IsUPeriodic)
+  {
+    lmf   = M_PI + M_PI; //-- myHS2->UPeriod();
+    f     = myHS2->FirstUParameter();
+    l     = myHS2->LastUParameter();
+    fpls2 = 0.5 * (f + l);
+    while ((u2 < f) && ((fpls2 - u2) > (u2 + lmf - fpls2)))
+    {
+      u2 += lmf;
+    }
+    while ((u2 > l) && ((u2 - fpls2) > (fpls2 - (u2 - lmf))))
+    {
+      u2 -= lmf;
+    }
+    //-- while(u2 < f) { u2+=lmf; }
+    //-- while(u2 > l) { u2-=lmf; }
+  }
+  if (myHS2IsVPeriodic)
+  {
+    lmf   = M_PI + M_PI; //-- myHS2->VPeriod();
+    f     = myHS2->FirstVParameter();
+    l     = myHS2->LastVParameter();
+    fpls2 = 0.5 * (f + l);
+    while ((v2 < f) && ((fpls2 - v2) > (v2 + lmf - fpls2)))
+    {
+      v2 += lmf;
+    }
+    while ((v2 > l) && ((v2 - fpls2) > (fpls2 - (v2 - lmf))))
+    {
+      v2 -= lmf;
+    }
+    //-- while(v2 < f) { v2+=lmf; }
+    //-- while(v2 > l) { v2-=lmf; }
+  }
+}
+//=======================================================================
+//function : PutPointsOnLine
+//purpose  :
+//=======================================================================
+void PutPointsOnLine(const Handle(Adaptor3d_Surface)&                  S1,
+                     const Handle(Adaptor3d_Surface)&                  S2,
+                     const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
+                     const IntPatch_SequenceOfLine&                    slin,
+                     const Standard_Boolean                            OnFirst,
+                     const Handle(Adaptor3d_TopolTool)&                Domain,
+                     const IntSurf_Quadric&                            QuadSurf,
+                     const IntSurf_Quadric&                            OtherQuad,
+                     const Standard_Boolean                            multpoint,
+                     const Standard_Real                               Tolarc)
+{
+  // Traitement des point (de listpnt) de depart. On les replace sur
+  // la ligne d intersection, en leur affectant la transition correcte sur
+  // cette ligne.
+  Standard_Integer nbpnt = listpnt.Length();
+  Standard_Integer nblin = slin.Length();
+
+  if (!slin.Length() || !nbpnt)
+  {
+    return;
+  }
+  //
+  Standard_Integer i, k;
+  Standard_Integer linenumber;
+  Standard_Real    currentparameter, tolerance;
+  Standard_Real    U1, V1, U2, V2;
+  Standard_Boolean goon;
+
+  gp_Pnt Psurf, ptbid;
+  gp_Vec Normale, Vtgint, Vtgrst;
+
+  gp_Vec   d1u, d1v;
+  gp_Pnt2d p2d;
+  gp_Vec2d d2d;
+
+  IntSurf_Transition Transline, Transarc;
+
+  Handle(Adaptor2d_Curve2d) currentarc;
+  Handle(Adaptor3d_HVertex) vtx, vtxbis;
+
+  IntPatch_Point                      solpnt;
+  IntPatch_ThePathPointOfTheSOnBounds currentpointonrst;
+  IntPatch_IType                      TheType;
+
+  TColStd_Array1OfInteger UsedLine(1, nblin);
+  TColStd_Array1OfInteger Done(1, nbpnt);
+  for (i = 1; i <= nbpnt; i++)
+    Done(i) = 0; //-- Initialisation a la main
+
+  for (i = 1; i <= nbpnt; i++)
+  {
+    if (Done(i) != 1)
+    {
+      currentpointonrst = listpnt.Value(i);
+      Psurf             = currentpointonrst.Value(); // Point dans l espace
+      tolerance         = currentpointonrst.Tolerance();
+
+      // On recherche d abord si on a correspondance avec un "point multiple"
+      UsedLine.Init(0);
+
+      goon = Standard_True;
+      if (multpoint)
+      {
+#if 1
+        Normale          = QuadSurf.Normale(Psurf); // Normale a la surface au point
+        currentarc       = currentpointonrst.Arc();
+        currentparameter = currentpointonrst.Parameter();
+        currentarc->D1(currentparameter, p2d, d2d);
+        QuadSurf.D1(p2d.X(), p2d.Y(), ptbid, d1u, d1v);
+        Vtgrst.SetLinearForm(d2d.X(), d1u, d2d.Y(), d1v);
+#endif
+        goon = MultiplePoint(listpnt, Domain, QuadSurf, Normale, slin, Done, UsedLine, i, OnFirst, Tolarc);
+      }
+      if (goon)
+      {
+        Standard_Boolean linefound = Standard_False;
+
+        for (Standard_Integer indiceline = 1; indiceline <= slin.Length(); indiceline++)
+        {
+          if (UsedLine(indiceline) != 0)
+            continue;
+          linenumber        = indiceline;
+
+          //-- Attention , les points peuvent etre deplaces
+          //-- il faut reprendre le point original
+          currentpointonrst = listpnt.Value(i);
+          currentarc        = currentpointonrst.Arc();
+          currentparameter  = currentpointonrst.Parameter();
+          Psurf             = currentpointonrst.Value(); // Point dans l espace
+          tolerance         = currentpointonrst.Tolerance();
+          //--
+
+          //  Modified by skv - Thu Jan 15 15:57:15 2004 OCC4455 Begin
+          if (!currentpointonrst.IsNew())
+          {
+            Handle(Adaptor3d_HVertex) aVtx    = currentpointonrst.Vertex();
+            Standard_Real             aVtxTol = aVtx->Resolution(currentarc);
+            Standard_Real             aTolAng = 0.01 * tolerance;
+
+            tolerance                         = Max(tolerance, aVtxTol);
+
+            gp_Vec aNorm1                     = QuadSurf.Normale(Psurf);
+            gp_Vec aNorm2                     = OtherQuad.Normale(Psurf);
+            //
+            if (aNorm1.Magnitude() > gp::Resolution() && aNorm2.Magnitude() > gp::Resolution())
+            {
+              if (aNorm1.IsParallel(aNorm2, aTolAng))
+                tolerance = Sqrt(tolerance);
+            } //
+          }
+          //  Modified by skv - Thu Jan 15 15:57:15 2004 OCC4455 End
+          gp_Pnt pointonarc;
+          Vtgint.SetCoord(0, 0, 0);
+          Standard_Real      aVertTol = Tolarc;
+          TColStd_ListOfReal aLParams;
+          linefound = FindLine(Psurf,
+                               slin,
+                               tolerance,
+                               aLParams,
+                               Vtgint,
+                               linenumber,
+                               indiceline,
+                               currentarc,
+                               currentparameter,
+                               pointonarc,
+                               QuadSurf,
+                               OtherQuad,
+                               aVertTol);
+          if (linefound)
+          {
+#if 1
+            Normale    = QuadSurf.Normale(Psurf); // Normale a la surface au point
+            currentarc = currentpointonrst.Arc();
+            //-- currentparameter = currentpointonrst.Parameter();
+            currentarc->D1(currentparameter, p2d, d2d);
+            QuadSurf.D1(p2d.X(), p2d.Y(), ptbid, d1u, d1v);
+            Vtgrst.SetLinearForm(d2d.X(), d1u, d2d.Y(), d1v);
+#endif
+
+            const Handle(IntPatch_Line)& lin = slin.Value(linenumber);
+            TheType                          = lin->ArcType();
+
+            if (!OnFirst)
+            { // on cherche la correspondance entre point sur domaine
+              // de la premiere surface et point sur domaine de la
+              // deuxieme surface
+
+              goon = PointOnSecondDom(listpnt, Domain, QuadSurf, Normale, Vtgint, lin, Done, i, aVertTol);
+            }
+
+            if (goon)
+            {
+              //-- Modification du 4 avril 97    tolerance->Tolarc
+              //-- on replace sur le vertex la tolerance d entree et
+              //-- non la tolerance qui a servi au FindLine
+              solpnt.SetValue(Psurf, aVertTol, Standard_False);
+
+              U1 = p2d.X();
+              V1 = p2d.Y();
+              OtherQuad.Parameters(Psurf, U2, V2);
+
+              if (OnFirst)
+              {
+                Recadre(S1, S2, U1, V1, U2, V2);
+                solpnt.SetParameters(U1, V1, U2, V2);
+              }
+              else
+              {
+                Recadre(S1, S2, U2, V2, U1, V1);
+                solpnt.SetParameters(U2, V2, U1, V1);
+              }
+
+              if (!currentpointonrst.IsNew())
+              {
+                vtx = currentpointonrst.Vertex();
+                solpnt.SetVertex(OnFirst, vtx);
+              }
+              else
+              {
+                //-- goon = Standard_False; ????
+              }
+
+              if (Normale.SquareMagnitude() < 1e-16)
+              {
+                Transline.SetValue(Standard_True, IntSurf_Undecided);
+                Transarc.SetValue(Standard_True, IntSurf_Undecided);
+              }
+              else
+              {
+                IntSurf::MakeTransition(Vtgint, Vtgrst, Normale, Transline, Transarc);
+              }
+              solpnt.SetArc(OnFirst, currentarc, currentparameter, Transline, Transarc);
+
+              for (TColStd_ListIteratorOfListOfReal anItr(aLParams); anItr.More(); anItr.Next())
+              {
+                solpnt.SetParameter(anItr.Value());
+                if (TheType == IntPatch_Analytic)
+                {
+                  Handle(IntPatch_ALine)::DownCast(lin)->AddVertex(solpnt);
+                }
+                else
+                {
+                  Handle(IntPatch_GLine)::DownCast(lin)->AddVertex(solpnt);
+                }
+              }
+
+              Done(i) = 1;
+
+              if (goon)
+              {
+                for (k = i + 1; k <= nbpnt; k++)
+                {
+                  if (Done(k) != 1)
+                  {
+                    currentpointonrst = listpnt.Value(k);
+                    if (!currentpointonrst.IsNew())
+                    {
+                      vtxbis = currentpointonrst.Vertex();
+                      if (vtx.IsNull())
+                      {
+                      }
+                      else if (Domain->Identical(vtx, vtxbis))
+                      {
+                        solpnt.SetVertex(OnFirst, vtxbis);
+                        solpnt.SetTolerance(Tolarc);
+                        currentarc       = currentpointonrst.Arc();
+                        currentparameter = currentpointonrst.Parameter();
+
+                        //                   currentarc->D1(currentparameter,ptbid,Vtgrst);
+                        currentarc->D1(currentparameter, p2d, d2d);
+                        Vtgrst.SetLinearForm(d2d.X(), d1u, d2d.Y(), d1v);
+                        if (Normale.SquareMagnitude() < 1e-16)
+                        {
+                          Transline.SetValue(Standard_True, IntSurf_Undecided);
+                          Transarc.SetValue(Standard_True, IntSurf_Undecided);
+                        }
+                        else
+                        {
+                          IntSurf::MakeTransition(Vtgint, Vtgrst, Normale, Transline, Transarc);
+                        }
+                        solpnt.SetArc(OnFirst, currentarc, currentparameter, Transline, Transarc);
+                        if (TheType == IntPatch_Analytic)
+                        {
+                          Handle(IntPatch_ALine)::DownCast(lin)->AddVertex(solpnt);
+                        }
+                        else
+                        {
+                          Handle(IntPatch_GLine)::DownCast(lin)->AddVertex(solpnt);
+                        }
+                        Done(k) = 1;
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+          else
+          {
+            Done(i) = 1; // il faudra tester si IsNew ou pas
+            // et traiter en consequence
+          }
+        }
+      }
+    }
+  }
+}
+
+Standard_Boolean MultiplePoint(const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
+                               const Handle(Adaptor3d_TopolTool)&                Domain,
+                               const IntSurf_Quadric&                            QuadSurf,
+                               const gp_Vec&                                     Normale,
+                               const IntPatch_SequenceOfLine&                    slin,
+                               TColStd_Array1OfInteger&                          Done,
+                               TColStd_Array1OfInteger&                          UsedLine,
+                               const Standard_Integer                            Index,
+                               const Standard_Boolean                            OnFirst,
+                               const Standard_Real                               theToler)
+{
+  // Traitement des points "multiples".
+
+  Standard_Integer k, ii, jj, nbvtx;
+  Standard_Integer nblin = slin.Length();
+  IntPatch_IType   TheType;
+
+  IntSurf_Transition Transline, Transarc;
+
+  IntPatch_Point            intpt;
+  Handle(Adaptor2d_Curve2d) currentarc;
+  Handle(Adaptor3d_HVertex) vtx, vtxbis;
+
+  Standard_Integer                    nbpnt             = listpnt.Length();
+  IntPatch_ThePathPointOfTheSOnBounds currentpointonrst = listpnt.Value(Index);
+  IntPatch_ThePathPointOfTheSOnBounds otherpt;
+  gp_Pnt                              Point = currentpointonrst.Value();
+  TColStd_Array1OfInteger             localdone(1, nbpnt);
+  localdone.Init(0);
+  for (ii = 1; ii <= nbpnt; ii++)
+  {
+    localdone(ii) = Done(ii);
+  }
+
+  Standard_Real currentparameter;
+  Standard_Real Paraint;
+  gp_Vec        Vtgint, Vtgrst;
+  gp_Pnt        ptbid;
+
+  gp_Vec   d1u, d1v;
+  gp_Pnt2d p2d;
+  gp_Vec2d d2d;
+
+  Standard_Boolean goon;
+
+  Standard_Boolean Retvalue = Standard_True;
+
+  for (ii = 1; ii <= nblin; ii++)
+  {
+    const Handle(IntPatch_Line)& slinValueii = slin.Value(ii);
+    TheType                                  = slinValueii->ArcType();
+    if (TheType == IntPatch_Analytic)
+    {
+      nbvtx = Handle(IntPatch_ALine)::DownCast(slinValueii)->NbVertex();
+    }
+    else
+    {
+      nbvtx = Handle(IntPatch_GLine)::DownCast(slinValueii)->NbVertex();
+    }
+    jj = 1;
+    while (jj <= nbvtx)
+    {
+      if (TheType == IntPatch_Analytic)
+      {
+        intpt = Handle(IntPatch_ALine)::DownCast(slinValueii)->Vertex(jj);
+      }
+      else
+      {
+        intpt = Handle(IntPatch_GLine)::DownCast(slinValueii)->Vertex(jj);
+      }
+      if (intpt.IsMultiple() && ((OnFirst && !intpt.IsOnDomS1()) || (!OnFirst && !intpt.IsOnDomS2())))
+      {
+        if (Point.Distance(intpt.Value()) <= intpt.Tolerance())
+        {
+          Retvalue             = Standard_False;
+          Standard_Boolean foo = SingleLine(Point, slinValueii, intpt.Tolerance(), Paraint, Vtgint);
+          if (!foo)
+          {
+            return Standard_False; // ne doit pas se produire
+          }
+
+          if (!currentpointonrst.IsNew())
+          {
+            goon = Standard_True;
+            vtx  = currentpointonrst.Vertex();
+            intpt.SetVertex(OnFirst, vtx);
+          }
+          else
+          {
+            goon = Standard_False;
+          }
+          currentarc       = currentpointonrst.Arc();
+          currentparameter = currentpointonrst.Parameter();
+          currentarc->D1(currentparameter, p2d, d2d);
+          QuadSurf.D1(p2d.X(), p2d.Y(), ptbid, d1u, d1v);
+          Vtgrst.SetLinearForm(d2d.X(), d1u, d2d.Y(), d1v);
+
+          //-- Si la normale est nulle (apex d un cone) On simule une transition UNKNOWN
+          if (Normale.SquareMagnitude() < 1e-16)
+          {
+            Transline.SetValue(Standard_True, IntSurf_Undecided);
+            Transarc.SetValue(Standard_True, IntSurf_Undecided);
+          }
+          else
+          {
+            IntSurf::MakeTransition(Vtgint, Vtgrst, Normale, Transline, Transarc);
+          }
+
+          //-- Avant, on ne mettait pas ce point (17 nov 97)
+          //--printf("\n ImpImp_0  : Point(%g,%g,%g)  intpt(%g,%g,%g) \n",
+          //--  Point.X(),Point.Y(),Point.Z(),intpt.Value().X(),intpt.Value().Y(),intpt.Value().Z());
+          intpt.SetValue(Point);
+
+          intpt.SetArc(OnFirst, currentarc, currentparameter, Transline, Transarc);
+          intpt.SetTolerance(theToler);
+
+          if (TheType == IntPatch_Analytic)
+          {
+            Handle(IntPatch_ALine)::DownCast(slinValueii)->Replace(jj, intpt);
+          }
+          else
+          {
+            Handle(IntPatch_GLine)::DownCast(slinValueii)->Replace(jj, intpt);
+          }
+          localdone(Index) = 1;
+          if (goon)
+          {
+            for (k = Index + 1; k <= nbpnt; k++)
+            {
+              if (Done(k) != 1)
+              {
+                otherpt = listpnt.Value(k);
+                if (!otherpt.IsNew())
+                {
+                  vtxbis = otherpt.Vertex();
+                  if (Domain->Identical(vtx, vtxbis))
+                  {
+                    intpt.SetVertex(OnFirst, vtxbis);
+                    currentarc       = otherpt.Arc();
+                    currentparameter = otherpt.Parameter();
+
+                    currentarc->D1(currentparameter, p2d, d2d);
+                    Vtgrst.SetLinearForm(d2d.X(), d1u, d2d.Y(), d1v);
+                    if (Normale.SquareMagnitude() < 1e-16)
+                    {
+                      Transline.SetValue(Standard_True, IntSurf_Undecided);
+                      Transarc.SetValue(Standard_True, IntSurf_Undecided);
+                    }
+                    else
+                    {
+                      IntSurf::MakeTransition(Vtgint, Vtgrst, Normale, Transline, Transarc);
+                    }
+                    intpt.SetArc(OnFirst, currentarc, currentparameter, Transline, Transarc);
+                    intpt.SetTolerance(theToler);
+                    if (TheType == IntPatch_Analytic)
+                    {
+                      Handle(IntPatch_ALine)::DownCast(slinValueii)->AddVertex(intpt);
+                    }
+                    else
+                    {
+                      Handle(IntPatch_GLine)::DownCast(slinValueii)->AddVertex(intpt);
+                    }
+                    UsedLine(ii) = 1;
+                    Retvalue     = Standard_True;
+                    localdone(k) = 1;
+                  }
+                }
+              }
+            }
+          }
+          //--           jj = nbvtx +1;
+        }
+        //--         else {
+        jj = jj + 1;
+        //--        }
+      }
+      else
+      {
+        jj = jj + 1;
+      }
+    }
+  }
+
+  for (ii = 1; ii <= nbpnt; ii++)
+  {
+    Done(ii) = localdone(ii);
+  }
+
+  return Retvalue;
+}
+
+Standard_Boolean PointOnSecondDom(const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
+                                  const Handle(Adaptor3d_TopolTool)&                Domain,
+                                  const IntSurf_Quadric&                            QuadSurf,
+                                  const gp_Vec&                                     Normale,
+                                  const gp_Vec&                                     Vtgint,
+                                  const Handle(IntPatch_Line)&                      lin,
+                                  TColStd_Array1OfInteger&                          Done,
+                                  const Standard_Integer                            Index,
+                                  const Standard_Real                               theToler)
+
+// Duplication des points sur domaine de l autre surface.
+// On sait que le vertex sous-jacent est PntRef
+
+{
+  Standard_Integer k, jj, nbvtx;
+  IntPatch_IType   TheType;
+
+  IntSurf_Transition        Transline, Transarc;
+  IntPatch_Point            intpt;
+  Handle(Adaptor2d_Curve2d) currentarc;
+  Handle(Adaptor3d_HVertex) vtx, vtxbis;
+  gp_Pnt                    ptbid;
+  gp_Vec                    Vtgrst;
+
+  gp_Vec   d1u, d1v;
+  gp_Pnt2d p2d;
+  gp_Vec2d d2d;
+
+  Standard_Integer                    nbpnt             = listpnt.Length();
+  IntPatch_ThePathPointOfTheSOnBounds currentpointonrst = listpnt.Value(Index);
+  Standard_Real                       currentparameter;
+
+  Standard_Boolean goon;
+  Standard_Boolean Retvalue = Standard_True;
+
+  TheType                   = lin->ArcType();
+  if (TheType == IntPatch_Analytic)
+  {
+    nbvtx = Handle(IntPatch_ALine)::DownCast(lin)->NbVertex();
+  }
+  else
+  {
+    nbvtx = Handle(IntPatch_GLine)::DownCast(lin)->NbVertex();
+  }
+  jj = 1;
+  while (jj <= nbvtx)
+  {
+    if (TheType == IntPatch_Analytic)
+    {
+      intpt = Handle(IntPatch_ALine)::DownCast(lin)->Vertex(jj);
+    }
+    else
+    {
+      intpt = Handle(IntPatch_GLine)::DownCast(lin)->Vertex(jj);
+    }
+    if (!intpt.IsOnDomS2())
+    {
+      if (currentpointonrst.Value().Distance(intpt.Value()) <= intpt.Tolerance())
+      {
+        Retvalue = Standard_False;
+        if (!currentpointonrst.IsNew())
+        {
+          goon = Standard_True;
+          vtx  = currentpointonrst.Vertex();
+          intpt.SetVertex(Standard_False, vtx);
+        }
+        else
+        {
+          goon = Standard_False;
+        }
+        currentarc       = currentpointonrst.Arc();
+        currentparameter = currentpointonrst.Parameter();
+        currentarc->D1(currentparameter, p2d, d2d);
+        QuadSurf.D1(p2d.X(), p2d.Y(), ptbid, d1u, d1v);
+        Vtgrst.SetLinearForm(d2d.X(), d1u, d2d.Y(), d1v);
+        if (Normale.SquareMagnitude() < 1e-16)
+        {
+          Transline.SetValue(Standard_True, IntSurf_Undecided);
+          Transarc.SetValue(Standard_True, IntSurf_Undecided);
+        }
+        else
+        {
+          IntSurf::MakeTransition(Vtgint, Vtgrst, Normale, Transline, Transarc);
+        }
+        intpt.SetArc(Standard_False, currentarc, currentparameter, Transline, Transarc);
+        intpt.SetTolerance(theToler);
+
+        if (TheType == IntPatch_Analytic)
+        {
+          Handle(IntPatch_ALine)::DownCast(lin)->Replace(jj, intpt);
+        }
+        else
+        {
+          Handle(IntPatch_GLine)::DownCast(lin)->Replace(jj, intpt);
+        }
+        Done(Index) = 1;
+
+        if (goon)
+        {
+          for (k = Index + 1; k <= nbpnt; k++)
+          {
+            if (Done(k) != 1)
+            {
+              currentpointonrst = listpnt.Value(k);
+              if (!currentpointonrst.IsNew())
+              {
+                vtxbis = currentpointonrst.Vertex();
+                if (Domain->Identical(vtx, vtxbis))
+                {
+                  intpt.SetVertex(Standard_False, vtxbis);
+                  currentarc       = currentpointonrst.Arc();
+                  currentparameter = currentpointonrst.Parameter();
+                  currentarc->D1(currentparameter, p2d, d2d);
+                  Vtgrst.SetLinearForm(d2d.X(), d1u, d2d.Y(), d1v);
+                  if (Normale.SquareMagnitude() < 1e-16)
+                  {
+                    Transline.SetValue(Standard_True, IntSurf_Undecided);
+                    Transarc.SetValue(Standard_True, IntSurf_Undecided);
+                  }
+                  else
+                  {
+                    IntSurf::MakeTransition(Vtgint, Vtgrst, Normale, Transline, Transarc);
+                  }
+                  intpt.SetArc(Standard_False, currentarc, currentparameter, Transline, Transarc);
+                  intpt.SetTolerance(theToler);
+                  if (TheType == IntPatch_Analytic)
+                  {
+                    Handle(IntPatch_ALine)::DownCast(lin)->AddVertex(intpt);
+                  }
+                  else
+                  {
+                    Handle(IntPatch_GLine)::DownCast(lin)->AddVertex(intpt);
+                  }
+                  Done(k) = 1;
+                }
+              }
+            }
+          }
+        }
+        //-- jj = nbvtx + 1;
+        jj++;
+      }
+      else
+      {
+        jj = jj + 1;
+      }
+    }
+    else
+    {
+      jj = jj + 1;
+    }
+    if (TheType == IntPatch_Analytic)
+    {
+      nbvtx = Handle(IntPatch_ALine)::DownCast(lin)->NbVertex();
+    }
+    else
+    {
+      nbvtx = Handle(IntPatch_GLine)::DownCast(lin)->NbVertex();
+    }
+  }
+  return Retvalue;
+}
+
+Standard_Boolean FindLine(gp_Pnt&                          Psurf,
+                          const IntPatch_SequenceOfLine&   slin,
+                          const Standard_Real              Tol,
+                          TColStd_ListOfReal&              theLParams,
+                          gp_Vec&                          Vtgtint,
+                          Standard_Integer&                theLineIdx,
+                          Standard_Integer                 OnlyThisLine,
+                          const Handle(Adaptor2d_Curve2d)& thearc,
+                          Standard_Real&                   theparameteronarc,
+                          gp_Pnt&                          thepointonarc,
+                          const IntSurf_Quadric&           QuadSurf1,
+                          const IntSurf_Quadric&           QuadSurf2,
+                          Standard_Real&                   theOutputToler)
+{
+  if ((QuadSurf1.Distance(Psurf) > Tol) || (QuadSurf2.Distance(Psurf) > Tol))
+    return Standard_False;
+
+  // Traitement du point de depart ayant pour representation Psurf
+  // dans l espace. On recherche la ligne d intersection contenant ce point.
+  // On a en sortie la ligne, et le parametre et sa tangente du point sur
+  // la ligne d intersection.
+  const Standard_Real aSqTol     = Tol * Tol;
+  Standard_Real       aSqDistMin = RealLast();
+  Standard_Real       aSqDist, para;
+  Standard_Real       lower, upper;
+  gp_Pnt              pt;
+  Standard_Integer    i;
+  IntPatch_IType      typarc;
+
+  Standard_Real    aParaInt = RealLast();
+  Standard_Integer nblin    = slin.Length();
+  for (i = 1; i <= nblin; i++)
+  {
+    if (OnlyThisLine)
+    {
+      i     = OnlyThisLine;
+      nblin = 0;
+    }
+    const Handle(IntPatch_Line)& lin = slin.Value(i);
+    typarc                           = lin->ArcType();
+    if (typarc == IntPatch_Analytic)
+    {
+      Standard_Boolean foo;
+      lower = Handle(IntPatch_ALine)::DownCast(lin)->FirstParameter(foo);
+      upper = Handle(IntPatch_ALine)::DownCast(lin)->LastParameter(foo);
+    }
+    else
+    {
+      if (Handle(IntPatch_GLine)::DownCast(lin)->HasFirstPoint())
+      {
+        lower = Handle(IntPatch_GLine)::DownCast(lin)->FirstPoint().ParameterOnLine();
+      }
+      else
+      {
+        lower = RealFirst();
+      }
+      if (Handle(IntPatch_GLine)::DownCast(lin)->HasLastPoint())
+      {
+        upper = Handle(IntPatch_GLine)::DownCast(lin)->LastPoint().ParameterOnLine();
+      }
+      else
+      {
+        upper = RealLast();
+      }
+    }
+
+    switch (typarc)
+    {
+      case IntPatch_Lin:
+      {
+        para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast(lin)->Line(), Psurf);
+        if (para <= upper && para >= lower)
+        {
+          pt      = ElCLib::Value(para, Handle(IntPatch_GLine)::DownCast(lin)->Line());
+          aSqDist = Psurf.SquareDistance(pt);
+          if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
+          {
+            aSqDistMin = aSqDist;
+            aParaInt   = para;
+            theLineIdx = i;
+          }
+        }
+      }
+      break;
+      case IntPatch_Circle:
+      {
+        para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast(lin)->Circle(), Psurf);
+        if ((para <= upper && para >= lower) || (para + 2. * M_PI <= upper && para + 2. * M_PI >= lower)
+            || (para - 2. * M_PI <= upper && para - 2. * M_PI >= lower))
+        {
+          pt      = ElCLib::Value(para, Handle(IntPatch_GLine)::DownCast(lin)->Circle());
+          aSqDist = Psurf.SquareDistance(pt);
+          if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
+          {
+            aSqDistMin = aSqDist;
+            aParaInt   = para;
+            theLineIdx = i;
+          }
+        }
+      }
+      break;
+      case IntPatch_Ellipse:
+      {
+        para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast(lin)->Ellipse(), Psurf);
+        if ((para <= upper && para >= lower) || (para + 2. * M_PI <= upper && para + 2. * M_PI >= lower)
+            || (para - 2. * M_PI <= upper && para - 2. * M_PI >= lower))
+        {
+          pt      = ElCLib::Value(para, Handle(IntPatch_GLine)::DownCast(lin)->Ellipse());
+          aSqDist = Psurf.SquareDistance(pt);
+          if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
+          {
+            aSqDistMin = aSqDist;
+            aParaInt   = para;
+            theLineIdx = i;
+          }
+        }
+      }
+      break;
+      case IntPatch_Parabola:
+      {
+#if 0  
+       para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Parabola(),Psurf);
+       if (para <= upper && para >= lower) {
+         pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Parabola());
+         dist = Psurf.Distance(pt);
+         if (dist< distmin) {
+           distmin = dist;
+           Paraint = para;
+           Range = i;
+         }
+       }
+#else
+        //-- Le calcul du parametre sur une parabole est mal fait ds ElCLib. Il ne tient pas compte
+        //-- de la meilleure facon de calculer (axe X ou axe Y). Bilan : Si la parabole est tres
+        //-- pointue (focal de l'ordre de 1e-2 et si le point est a un parametre grand, ca foire. )
+        //-- On ne peut pas modifier faciolement ds ElCLib car on ne passe pas la focale. ...
+        const gp_Parab& Parab = Handle(IntPatch_GLine)::DownCast(lin)->Parabola();
+        para                  = ElCLib::Parameter(Parab, Psurf);
+        if (para <= upper && para >= lower)
+        {
+          Standard_Integer amelioration = 0;
+          //-- cout<<"\n ****** \n";
+          do
+          {
+            Standard_Real parabis       = para + 0.0000001;
+
+            pt                          = ElCLib::Value(para, Parab);
+            aSqDist                     = Psurf.SquareDistance(pt);
+
+            const gp_Pnt        ptbis   = ElCLib::Value(parabis, Parab);
+            const Standard_Real distbis = Psurf.Distance(ptbis);
+            const Standard_Real aDist   = Sqrt(aSqDist);
+            const Standard_Real ddist   = distbis - aDist;
+
+            //--cout<<" para: "<<para<<"    dist:"<<dist<<"   ddist:"<<ddist<<endl;
+
+            if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
+            {
+              aSqDistMin = aSqDist;
+              aParaInt   = para;
+              theLineIdx = i;
+            }
+            if (aSqDist < Precision::SquarePConfusion())
+            {
+              amelioration = 100;
+            }
+
+            if (ddist > 1.0e-9 || ddist < -1.0e-9)
+            {
+              para = para - aDist * (parabis - para) / ddist;
+            }
+            else
+            {
+              amelioration = 100;
+            }
+          } while (++amelioration < 5);
+        }
+
+#endif
+      }
+      break;
+      case IntPatch_Hyperbola:
+      {
+        para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast(lin)->Hyperbola(), Psurf);
+        if (para <= upper && para >= lower)
+        {
+          pt      = ElCLib::Value(para, Handle(IntPatch_GLine)::DownCast(lin)->Hyperbola());
+          aSqDist = Psurf.SquareDistance(pt);
+          if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
+          {
+            aSqDistMin = aSqDist;
+            aParaInt   = para;
+            theLineIdx = i;
+          }
+        }
+      }
+      break;
+
+      case IntPatch_Analytic:
+      {
+        Handle(IntPatch_ALine) alin(Handle(IntPatch_ALine)::DownCast(lin));
+        TColStd_ListOfReal     aLParams;
+        alin->FindParameter(Psurf, aLParams);
+        if (!aLParams.IsEmpty())
+        {
+          // All found distances are already in some internal tolerance
+          // set in alin->FindParameter(...) method.
+
+          aSqDist = RealLast();
+          for (TColStd_ListIteratorOfListOfReal anItr(aLParams); anItr.More(); anItr.Next())
+          {
+            pt                       = alin->Value(anItr.Value());
+            const Standard_Real aSqD = Psurf.SquareDistance(pt);
+            if (aSqD < aSqDist)
+            {
+              aSqDist = aSqD;
+            }
+          }
+
+          if (aSqDist < aSqDistMin)
+          {
+            aSqDistMin = aSqDist;
+            theLParams = aLParams;
+            theLineIdx = i;
+          }
+        }
+        else
+        {
+          //-- le point n a pas ete trouve par bete projection.
+          //-- on essaie l intersection avec la restriction en 2d
+          Standard_Real theparamonarc = theparameteronarc;
+          //#ifdef OCCT_DEBUG
+          //     Standard_Real anpara=para;
+          //#endif
+          gp_Pnt           CopiePsurf = Psurf;
+          Standard_Boolean IntersectIsOk =
+            IntersectionWithAnArc(CopiePsurf, alin, para, thearc, theparamonarc, thepointonarc, QuadSurf1, lower, upper);
+          aSqDist = CopiePsurf.SquareDistance(Psurf);
+          if (IntersectIsOk)
+          {
+            if (aSqDist < aSqTol)
+            {
+              theparameteronarc = theparamonarc;
+              Psurf             = thepointonarc;
+              aSqDistMin        = aSqDist;
+              theLParams.Append(para);
+              theLineIdx = i;
+            }
+          }
+        }
+      }
+      break;
+
+      case IntPatch_Walking: // impossible . c est pour eviter les warnings
+      {
+      }
+      case IntPatch_Restriction: // impossible . c est pour eviter les warnings
+      {
+      }
+    }
+  }
+
+  if (aSqDistMin == RealLast())
+    return Standard_False;
+
+  theOutputToler = Max(theOutputToler, Sqrt(aSqDistMin));
+
+  typarc         = slin.Value(theLineIdx)->ArcType();
+
+  // Computation of tangent vector
+  switch (typarc)
+  {
+    case IntPatch_Lin:
+      theLParams.Append(aParaInt);
+      Vtgtint = (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Line().Direction();
+      break;
+    case IntPatch_Circle:
+      theLParams.Append(aParaInt);
+      Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Circle(), 1);
+      break;
+    case IntPatch_Ellipse:
+      theLParams.Append(aParaInt);
+      Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Ellipse(), 1);
+      break;
+    case IntPatch_Parabola:
+      theLParams.Append(aParaInt);
+      Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Parabola(), 1);
+      break;
+    case IntPatch_Hyperbola:
+      theLParams.Append(aParaInt);
+      Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Hyperbola(), 1);
+      break;
+
+    case IntPatch_Analytic:
+    {
+      if (!Handle(IntPatch_ALine)::DownCast(slin(theLineIdx))->D1(theLParams.Last(), pt, Vtgtint))
+      {
+        //Previously (before the fix #29807) this code tried to process case
+        //when Handle(IntPatch_ALine)::D1(...) method returns FALSE and
+        //computed Vtgtint input argument value. Currently, any singularities
+        //must be processed by high-level algorithms (IntPatch_SpecialPoints class).
+        //Therefore this code has been deleted as deprecated.
+
+        Vtgtint.SetCoord(0.0, 0.0, 0.0);
+      }
+    }
+    break;
+    case IntPatch_Walking: // impossible . c est pour eviter les warnings
+    {
+    }
+    case IntPatch_Restriction: // impossible . c est pour eviter les warnings
+    {
+    }
+  }
+  return Standard_True;
+}
+
+//=======================================================================
+//function : SingleLine
+//purpose  : Traitement du point de depart ayant pour representation Psurf
+//            dans l espace. On le replace sur la ligne d intersection; On a en sortie
+//            son parametre et sa tangente sur la ligne d intersection.
+//            La fonction renvoie False si le point projete est a une distance
+//            superieure a Tol du point a projeter.
+//=======================================================================
+Standard_Boolean SingleLine(const gp_Pnt&                Psurf,
+                            const Handle(IntPatch_Line)& lin,
+                            const Standard_Real          Tol,
+                            Standard_Real&               Paraint,
+                            gp_Vec&                      Vtgtint)
+{
+  IntPatch_IType typarc    = lin->ArcType();
+
+  Standard_Real    parproj = 0.;
+  gp_Vec           tgint;
+  gp_Pnt           ptproj;
+  Standard_Boolean retvalue;
+
+  switch (typarc)
+  {
+    case IntPatch_Lin:
+      parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast(lin)->Line(), Psurf);
+      ElCLib::D1(parproj, Handle(IntPatch_GLine)::DownCast(lin)->Line(), ptproj, tgint);
+      break;
+    case IntPatch_Circle:
+      parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast(lin)->Circle(), Psurf);
+      ElCLib::D1(parproj, Handle(IntPatch_GLine)::DownCast(lin)->Circle(), ptproj, tgint);
+      break;
+    case IntPatch_Ellipse:
+      parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast(lin)->Ellipse(), Psurf);
+      ElCLib::D1(parproj, Handle(IntPatch_GLine)::DownCast(lin)->Ellipse(), ptproj, tgint);
+      break;
+    case IntPatch_Parabola:
+      parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast(lin)->Parabola(), Psurf);
+      ElCLib::D1(parproj, Handle(IntPatch_GLine)::DownCast(lin)->Parabola(), ptproj, tgint);
+      break;
+    case IntPatch_Hyperbola:
+      parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast(lin)->Hyperbola(), Psurf);
+      ElCLib::D1(parproj, Handle(IntPatch_GLine)::DownCast(lin)->Hyperbola(), ptproj, tgint);
+      break;
+    case IntPatch_Analytic:
+    {
+      Handle(IntPatch_ALine) alin(Handle(IntPatch_ALine)::DownCast(lin));
+      TColStd_ListOfReal     aLParams;
+      alin->FindParameter(Psurf, aLParams);
+      if (!aLParams.IsEmpty())
+      {
+        ptproj  = Psurf;
+        parproj = aLParams.Last();
+        gp_Pnt aPtemp;
+        if (!alin->D1(parproj, aPtemp, tgint))
+        {
+          //Previously (before the fix #29807) this code tried to process case
+          //when Handle(IntPatch_ALine)::D1(...) method returns FALSE and
+          //computed Vtgtint input argument value. Currently, any singularities
+          //must be processed by high-level algorithms (IntPatch_SpecialPoints class).
+          //Therefore this code has been deleted as deprecated.
+
+          tgint.SetCoord(0.0, 0.0, 0.0);
+        }
+      }
+      else
+      {
+        //-- cout << "---- Pb sur ligne analytique dans SingleLine" << endl;
+        //-- cout << "     Find Parameter"<<endl;
+        return Standard_False;
+      }
+    }
+    break;
+    case IntPatch_Walking: // impossible . c est pour eviter les warnings
+    {
+    }
+    case IntPatch_Restriction: // impossible . c est pour eviter les warnings
+    {
+    }
+  }
+
+  if (Psurf.Distance(ptproj) <= Tol)
+  {
+    Paraint  = parproj;
+    Vtgtint  = tgint;
+    retvalue = Standard_True;
+  }
+  else
+  {
+    retvalue = Standard_False;
+  }
+  return retvalue;
+}
+
+void ProcessSegments(const IntPatch_SequenceOfSegmentOfTheSOnBounds& listedg,
+                     IntPatch_SequenceOfLine&                        slin,
+                     const IntSurf_Quadric&                          Quad1,
+                     const IntSurf_Quadric&                          Quad2,
+                     const Standard_Boolean                          OnFirst,
+                     const Standard_Real                             TolArc)
+{
+  Standard_Integer i, j, k;
+  Standard_Integer nbedg = listedg.Length();
+  Standard_Integer Nblines, Nbpts;
+
+  Handle(Adaptor2d_Curve2d) arcRef;
+  IntPatch_Point            ptvtx, newptvtx;
+
+  Handle(IntPatch_RLine) rline; //-- On fait rline = new ... par la suite
+
+  IntPatch_TheSegmentOfTheSOnBounds   thesegsol;
+  IntPatch_ThePathPointOfTheSOnBounds PStartf, PStartl;
+  Standard_Boolean                    dofirst, dolast, procf, procl;
+
+  Standard_Real paramf = 0., paraml = 0., U1 = 0., V1 = 0., U2 = 0., V2 = 0.;
+
+  IntPatch_IType     typ;
+  IntSurf_TypeTrans  trans1, trans2;
+  IntSurf_Transition TRest, TArc;
+  gp_Vec             tgline, norm1, norm2, tgarc;
+  gp_Pnt             valpt;
+
+  gp_Vec   d1u, d1v;
+  gp_Pnt2d p2d;
+  gp_Vec2d d2d;
+
+  for (i = 1; i <= nbedg; i++)
+  {
+    Standard_Boolean EdgeDegenere = Standard_False;
+    thesegsol                     = listedg.Value(i);
+    arcRef                        = thesegsol.Curve();
+
+    rline                         = new IntPatch_RLine(Standard_False);
+    if (OnFirst)
+    {
+      rline->SetArcOnS1(arcRef);
+    }
+    else
+    {
+      rline->SetArcOnS2(arcRef);
+    }
+
+    // Traitement des points debut/fin du segment solution.
+
+    dofirst = Standard_False;
+    dolast  = Standard_False;
+    procf   = Standard_False;
+    procl   = Standard_False;
+
+    if (thesegsol.HasFirstPoint())
+    {
+      dofirst = Standard_True;
+      PStartf = thesegsol.FirstPoint();
+      paramf  = PStartf.Parameter();
+    }
+    if (thesegsol.HasLastPoint())
+    {
+      dolast  = Standard_True;
+      PStartl = thesegsol.LastPoint();
+      paraml  = PStartl.Parameter();
+    }
+
+    if (dofirst && dolast)
+    { // determination de la transition de la ligne
+      arcRef->D1(0.5 * (paramf + paraml), p2d, d2d);
+      if (OnFirst)
+      {
+        Quad1.D1(p2d.X(), p2d.Y(), valpt, d1u, d1v);
+      }
+      else
+      {
+        Quad2.D1(p2d.X(), p2d.Y(), valpt, d1u, d1v);
+      }
+      tgline.SetLinearForm(d2d.X(), d1u, d2d.Y(), d1v);
+
+      if (d1u.Magnitude() < 1e-7)
+      { //-- edge degenere ?
+        EdgeDegenere = Standard_True;
+        for (Standard_Integer edg = 0; edg <= 10; edg++)
+        {
+          arcRef->D1(paramf + (paraml - paramf) * edg * 0.1, p2d, d2d);
+          if (OnFirst)
+          {
+            Quad1.D1(p2d.X(), p2d.Y(), valpt, d1u, d1v);
+          }
+          else
+          {
+            Quad2.D1(p2d.X(), p2d.Y(), valpt, d1u, d1v);
+          }
+
+          if (d1u.Magnitude() > 1e-7)
+          {
+            EdgeDegenere = Standard_False;
+          }
+        }
+        rline = new IntPatch_RLine(Standard_False);
+        if (OnFirst)
+        {
+          rline->SetArcOnS1(arcRef);
+        }
+        else
+        {
+          rline->SetArcOnS2(arcRef);
+        }
+      }
+      else
+      {
+        norm2 = Quad2.Normale(valpt);
+        norm1 = Quad1.Normale(valpt);
+
+        if (tgline.DotCross(norm2, norm1) > 0.000000001)
+        {
+          trans1 = IntSurf_Out;
+          trans2 = IntSurf_In;
+        }
+        else if (tgline.DotCross(norm2, norm1) < -0.000000001)
+        {
+          trans1 = IntSurf_In;
+          trans2 = IntSurf_Out;
+        }
+        else
+        {
+          trans1 = trans2 = IntSurf_Undecided;
+        }
+        rline = new IntPatch_RLine(Standard_False, trans1, trans2);
+        if (OnFirst)
+        {
+          rline->SetArcOnS1(arcRef);
+        }
+        else
+        {
+          rline->SetArcOnS2(arcRef);
+        }
+      }
+    }
+    else
+    {
+      rline = new IntPatch_RLine(Standard_False);
+      if (OnFirst)
+      {
+        rline->SetArcOnS1(arcRef);
+      }
+      else
+      {
+        rline->SetArcOnS2(arcRef);
+      }
+    }
+
+    if (dofirst || dolast)
+    {
+      Nblines = slin.Length();
+      for (j = 1; j <= Nblines; j++)
+      {
+        const Handle(IntPatch_Line)& slinj = slin(j);
+        typ                                = slinj->ArcType();
+        if (typ == IntPatch_Analytic)
+        {
+          Nbpts = Handle(IntPatch_ALine)::DownCast(slinj)->NbVertex();
+        }
+        else if (typ == IntPatch_Restriction)
+        {
+          Nbpts = Handle(IntPatch_RLine)::DownCast(slinj)->NbVertex();
+        }
+        else
+        {
+          Nbpts = Handle(IntPatch_GLine)::DownCast(slinj)->NbVertex();
+        }
+        for (k = 1; k <= Nbpts; k++)
+        {
+          if (typ == IntPatch_Analytic)
+          {
+            ptvtx = Handle(IntPatch_ALine)::DownCast(slinj)->Vertex(k);
+          }
+          else if (typ == IntPatch_Restriction)
+          {
+            ptvtx = Handle(IntPatch_RLine)::DownCast(slinj)->Vertex(k);
+          }
+          else
+          {
+            ptvtx = Handle(IntPatch_GLine)::DownCast(slinj)->Vertex(k);
+          }
+
+          if (EdgeDegenere == Standard_False && dofirst)
+          {
+            if (ptvtx.Value().Distance(PStartf.Value()) <= TolArc)
+            {
+              ptvtx.SetMultiple(Standard_True);
+              ptvtx.SetTolerance(TolArc);
+              if (typ == IntPatch_Analytic)
+              {
+                Handle(IntPatch_ALine)::DownCast(slinj)->Replace(k, ptvtx);
+              }
+              else if (typ == IntPatch_Restriction)
+              {
+                Handle(IntPatch_RLine)::DownCast(slinj)->Replace(k, ptvtx);
+              }
+              else
+              {
+                Handle(IntPatch_GLine)::DownCast(slinj)->Replace(k, ptvtx);
+              }
+              newptvtx = ptvtx;
+              newptvtx.SetParameter(paramf);
+              //Recalcul des  transitions si point sur restriction
+
+              arcRef->D1(paramf, p2d, d2d);
+              if (OnFirst)
+              {
+                Quad1.D1(p2d.X(), p2d.Y(), valpt, d1u, d1v);
+              }
+              else
+              {
+                Quad2.D1(p2d.X(), p2d.Y(), valpt, d1u, d1v);
+              }
+              tgline.SetLinearForm(d2d.X(), d1u, d2d.Y(), d1v);
+              if (ptvtx.IsOnDomS1())
+              {
+                const Handle(Adaptor2d_Curve2d)& thearc = ptvtx.ArcOnS1();
+                thearc->D1(ptvtx.ParameterOnArc1(), p2d, d2d);
+                Quad1.D1(p2d.X(), p2d.Y(), valpt, d1u, d1v);
+                tgarc.SetLinearForm(d2d.X(), d1u, d2d.Y(), d1v);
+                norm1 = d1u.Crossed(d1v);
+                if (norm1.SquareMagnitude() < 1e-16)
+                {
+                  TRest.SetValue(Standard_True, IntSurf_Undecided);
+                  TArc.SetValue(Standard_True, IntSurf_Undecided);
+                }
+                else
+                {
+                  IntSurf::MakeTransition(tgline, tgarc, norm1, TRest, TArc);
+                }
+                newptvtx.SetArc(Standard_True, thearc, ptvtx.ParameterOnArc1(), TRest, TArc);
+              }
+              if (ptvtx.IsOnDomS2())
+              {
+                const Handle(Adaptor2d_Curve2d)& thearc = ptvtx.ArcOnS2();
+                thearc->D1(ptvtx.ParameterOnArc2(), p2d, d2d);
+                Quad2.D1(p2d.X(), p2d.Y(), valpt, d1u, d1v);
+                tgarc.SetLinearForm(d2d.X(), d1u, d2d.Y(), d1v);
+                norm2 = d1u.Crossed(d1v);
+                if (norm2.SquareMagnitude() < 1e-16)
+                {
+                  TRest.SetValue(Standard_True, IntSurf_Undecided);
+                  TArc.SetValue(Standard_True, IntSurf_Undecided);
+                }
+                else
+                {
+                  IntSurf::MakeTransition(tgline, tgarc, norm2, TRest, TArc);
+                }
+                newptvtx.SetArc(Standard_False, thearc, ptvtx.ParameterOnArc2(), TRest, TArc);
+              }
+
+              rline->AddVertex(newptvtx);
+              if (!procf)
+              {
+                procf = Standard_True;
+                rline->SetFirstPoint(rline->NbVertex());
+              }
+            }
+          }
+          if (EdgeDegenere == Standard_False && dolast)
+          {
+            if (ptvtx.Value().Distance(PStartl.Value()) <= TolArc)
+            {
+              ptvtx.SetMultiple(Standard_True);
+              ptvtx.SetTolerance(TolArc);
+              if (typ == IntPatch_Analytic)
+              {
+                Handle(IntPatch_ALine)::DownCast(slinj)->Replace(k, ptvtx);
+              }
+              else if (typ == IntPatch_Restriction)
+              {
+                Handle(IntPatch_RLine)::DownCast(slinj)->Replace(k, ptvtx);
+              }
+              else
+              {
+                Handle(IntPatch_GLine)::DownCast(slinj)->Replace(k, ptvtx);
+              }
+
+              newptvtx = ptvtx;
+              newptvtx.SetParameter(paraml);
+              //Recalcul des  transitions si point sur restriction
+
+              arcRef->D1(paraml, p2d, d2d);
+              if (OnFirst)
+              {
+                Quad1.D1(p2d.X(), p2d.Y(), valpt, d1u, d1v);
+              }
+              else
+              {
+                Quad2.D1(p2d.X(), p2d.Y(), valpt, d1u, d1v);
+              }
+              tgline.SetLinearForm(d2d.X(), d1u, d2d.Y(), d1v);
+              if (ptvtx.IsOnDomS1())
+              {
+                const Handle(Adaptor2d_Curve2d)& thearc = ptvtx.ArcOnS1();
+                thearc->D1(ptvtx.ParameterOnArc1(), p2d, d2d);
+                Quad1.D1(p2d.X(), p2d.Y(), valpt, d1u, d1v);
+                tgarc.SetLinearForm(d2d.X(), d1u, d2d.Y(), d1v);
+                norm1 = d1u.Crossed(d1v);
+                if (norm1.SquareMagnitude() < 1e-16)
+                {
+                  TRest.SetValue(Standard_True, IntSurf_Undecided);
+                  TArc.SetValue(Standard_True, IntSurf_Undecided);
+                }
+                else
+                {
+                  IntSurf::MakeTransition(tgline, tgarc, norm1, TRest, TArc);
+                }
+                newptvtx.SetArc(Standard_True, thearc, ptvtx.ParameterOnArc1(), TRest, TArc);
+              }
+              if (ptvtx.IsOnDomS2())
+              {
+                const Handle(Adaptor2d_Curve2d)& thearc = ptvtx.ArcOnS2();
+                thearc->D1(ptvtx.ParameterOnArc2(), p2d, d2d);
+                Quad2.D1(p2d.X(), p2d.Y(), valpt, d1u, d1v);
+                tgarc.SetLinearForm(d2d.X(), d1u, d2d.Y(), d1v);
+                norm2 = d1u.Crossed(d1v);
+                if (norm2.SquareMagnitude() < 1e-16)
+                {
+                  TRest.SetValue(Standard_True, IntSurf_Undecided);
+                  TArc.SetValue(Standard_True, IntSurf_Undecided);
+                }
+                else
+                {
+                  IntSurf::MakeTransition(tgline, tgarc, norm2, TRest, TArc);
+                }
+                newptvtx.SetArc(Standard_False, thearc, ptvtx.ParameterOnArc2(), TRest, TArc);
+              }
+
+              rline->AddVertex(newptvtx);
+              if (!procl)
+              {
+                procl = Standard_True;
+                rline->SetLastPoint(rline->NbVertex());
+              }
+            }
+          }
+        }
+        // Si on a traite le pt debut et/ou fin, on ne doit pas recommencer si
+        // il (ils) correspond(ent) a un point multiple.
+
+        if (procf)
+        {
+          dofirst = Standard_False;
+        }
+        if (procl)
+        {
+          dolast = Standard_False;
+        }
+      }
+    }
+    // Si on n a pas trouve le point debut et./ou fin sur une des lignes
+    // d intersection, il faut quand-meme le placer sur la restriction solution
+
+    if (dofirst)
+    {
+      ptvtx.SetValue(PStartf.Value(), PStartf.Tolerance(), Standard_False);
+      Quad1.Parameters(PStartf.Value(), U1, V1);
+      Quad2.Parameters(PStartf.Value(), U2, V2);
+      ptvtx.SetParameters(U1, V1, U2, V2);
+      ptvtx.SetParameter(paramf);
+      if (!PStartf.IsNew())
+      {
+        IntSurf_Transition Transline;
+        IntSurf_Transition Transarc;
+        ptvtx.SetVertex(OnFirst, PStartf.Vertex());
+        ptvtx.SetArc(OnFirst, PStartf.Arc(), PStartf.Parameter(), Transline, Transarc);
+      }
+
+      rline->AddVertex(ptvtx);
+      rline->SetFirstPoint(rline->NbVertex());
+    }
+    if (dolast)
+    {
+      ptvtx.SetValue(PStartl.Value(), PStartl.Tolerance(), Standard_False);
+      Quad1.Parameters(PStartl.Value(), U1, V1);
+      Quad2.Parameters(PStartl.Value(), U2, V2);
+      ptvtx.SetParameters(U1, V1, U2, V2);
+      ptvtx.SetParameter(paraml);
+      if (!PStartl.IsNew())
+      {
+        IntSurf_Transition Transline;
+        IntSurf_Transition Transarc;
+
+        ptvtx.SetVertex(OnFirst, PStartl.Vertex());
+        ptvtx.SetArc(OnFirst, PStartl.Arc(), PStartl.Parameter(), Transline, Transarc);
+      }
+
+      rline->AddVertex(ptvtx);
+      rline->SetLastPoint(rline->NbVertex());
+    }
+    slin.Append(rline);
+  }
+}
+
+inline const gp_Pnt& PointValue(const Handle(IntPatch_RLine) theRLine, const Standard_Integer theIndex)
+{
+  return theRLine->Point(theIndex).Value();
+}
+
+inline const gp_Pnt& VertexValue(const Handle(IntPatch_RLine) theRLine, const Standard_Integer theIndex)
+{
+  return theRLine->Vertex(theIndex).Value();
+}
+
+static Standard_Real SquareDistance(const Handle(IntPatch_GLine)& theGLine, const gp_Pnt& theP, Extrema_ExtPC& theExtr)
+{
+  Standard_Real aSQDist = RealLast();
+  switch (theGLine->ArcType())
+  {
+    case IntPatch_Lin: aSQDist = theGLine->Line().SquareDistance(theP); break;
+    case IntPatch_Circle: aSQDist = theGLine->Circle().SquareDistance(theP); break;
+    default:
+      theExtr.Perform(theP);
+      if (!theExtr.IsDone() || !theExtr.NbExt())
+      {
+        //Lines are not overlapped
+        return aSQDist;
+      }
+
+      aSQDist                        = theExtr.SquareDistance(1);
+      const Standard_Integer aNbExtr = theExtr.NbExt();
+      for (Standard_Integer i = 2; i <= aNbExtr; i++)
+      {
+        const Standard_Real aSQD = theExtr.SquareDistance(i);
+        if (aSQD < aSQDist)
+        {
+          aSQDist = aSQD;
+        }
+      }
+  }
+
+  return aSQDist;
+}
+
+static Standard_Boolean IsRLineGood(const IntSurf_Quadric&       Quad1,
+                                    const IntSurf_Quadric&       Quad2,
+                                    const Handle(IntPatch_GLine) theGLine,
+                                    const Handle(IntPatch_RLine) theRLine,
+                                    const Standard_Real          theTol)
+{
+  const Standard_Real  aSQTol    = theTol * theTol;
+  const IntPatch_IType aGType    = theGLine->ArcType();
+  Standard_Integer     aNbPntsM1 = 0;
+
+  const gp_Pnt& (*Value)(const Handle(IntPatch_RLine), const Standard_Integer);
+
+  if (theRLine->HasPolygon())
+  {
+    aNbPntsM1 = theRLine->NbPnts() - 1;
+    Value     = PointValue;
+  }
+  else
+  {
+    aNbPntsM1 = theRLine->NbVertex() - 1;
+    Value     = VertexValue;
+  }
+
+  if (aNbPntsM1 < 1)
+    return Standard_False;
+
+  Extrema_ExtPC      anExtr;
+  GeomAdaptor_Curve  anAC;
+  Handle(Geom_Curve) aCurv;
+
+  if (aGType == IntPatch_Ellipse)
+    aCurv = new Geom_Ellipse(theGLine->Ellipse());
+  else if (aGType == IntPatch_Parabola)
+    aCurv = new Geom_Parabola(theGLine->Parabola());
+  else if (aGType == IntPatch_Hyperbola)
+    aCurv = new Geom_Hyperbola(theGLine->Hyperbola());
+
+  if (!aCurv.IsNull())
+  {
+    const Standard_Real anUinf = aCurv->FirstParameter(), anUsup = aCurv->LastParameter();
+    anAC.Load(aCurv, anUinf, anUsup);
+    anExtr.Initialize(anAC, anUinf, anUsup);
+  }
+
+  if (aNbPntsM1 == 1)
+  {
+    gp_Pnt aP1(Value(theRLine, 1)), aP2(Value(theRLine, 2));
+
+    if (aP1.SquareDistance(aP2) < aSQTol)
+    {
+      //RLine is degenerated
+      return Standard_False;
+    }
+
+    gp_Pnt aPMid;
+    if (theRLine->IsArcOnS1())
+    {
+      const Handle(Adaptor2d_Curve2d)& anAC2d = theRLine->ArcOnS1();
+      const Standard_Real              aParF = anAC2d->FirstParameter(), aParL = anAC2d->LastParameter();
+      gp_Pnt2d                         aP2d(anAC2d->Value(0.5 * (aParF + aParL)));
+      aPMid = Quad1.Value(aP2d.X(), aP2d.Y());
+    }
+    else
+    {
+      const Handle(Adaptor2d_Curve2d)& anAC2d = theRLine->ArcOnS2();
+      const Standard_Real              aParF = anAC2d->FirstParameter(), aParL = anAC2d->LastParameter();
+      gp_Pnt2d                         aP2d(anAC2d->Value(0.5 * (aParF + aParL)));
+      aPMid = Quad2.Value(aP2d.X(), aP2d.Y());
+    }
+
+    const Standard_Real aSQDist = SquareDistance(theGLine, aPMid, anExtr);
+    return (aSQDist > aSQTol);
+  }
+
+  for (Standard_Integer i = 2; i <= aNbPntsM1; i++)
+  {
+    const gp_Pnt        aP(Value(theRLine, i));
+    const Standard_Real aSQDist = SquareDistance(theGLine, aP, anExtr);
+
+    if (aSQDist > aSQTol)
+      return Standard_True;
+  }
+
+  return Standard_False;
+}
+
+void ProcessRLine(IntPatch_SequenceOfLine& slin,
+                  //              const Handle(Adaptor3d_Surface)& Surf1,
+                  //              const Handle(Adaptor3d_Surface)& Surf2,
+                  const IntSurf_Quadric& Quad1,
+                  const IntSurf_Quadric& Quad2,
+                  const Standard_Real    _TolArc,
+                  const Standard_Boolean theIsReqToKeepRLine)
+{
+  // On cherche a placer sur les restrictions solutions les points "multiples"
+  // des autres lignes d intersection
+  // Pas forcemment le plus efficace : on rique de projeter plusieurs fois
+  // le meme point sur la meme restriction...
+
+  Standard_Real TolArc = 100.0 * _TolArc;
+  if (TolArc > 0.1)
+    TolArc = 0.1;
+
+  Standard_Integer i, j, k;
+  Standard_Integer Nblin, Nbvtx, Nbpt;
+
+  Standard_Boolean OnFirst = Standard_False, project = Standard_False, keeppoint = Standard_False;
+
+  Handle(Adaptor2d_Curve2d) arcref;
+  Standard_Real             paramproj, paramf, paraml;
+
+  TColgp_SequenceOfPnt   seq_Pnt3d;
+  TColStd_SequenceOfReal seq_Real;
+
+  gp_Pnt ptproj, toproj, valpt;
+
+  gp_Pnt2d           p2d;
+  gp_Vec2d           d2d;
+  gp_Vec             d1u, d1v, tgrest, tgarc, norm;
+  IntSurf_Transition TRest, TArc;
+#ifndef OCCT_DEBUG
+  Standard_Real U = 0., V = 0.;
+#else
+  Standard_Real U, V;
+#endif
+  IntPatch_Point Ptvtx, newptvtx;
+
+  IntPatch_IType typ1, typ2;
+
+  Nblin = slin.Length();
+  for (i = 1; i <= Nblin; i++)
+  {
+    const Handle(IntPatch_Line)& slini = slin(i);
+    typ1                               = slini->ArcType();
+
+    Standard_Boolean HasToDeleteRLine  = Standard_False;
+    if (typ1 == IntPatch_Restriction)
+    {
+      seq_Pnt3d.Clear();
+      seq_Real.Clear();
+
+      for (j = 1; j <= Nblin; j++)
+      {
+        const Handle(IntPatch_Line)& slinj = slin(j);
+        Nbpt                               = seq_Pnt3d.Length(); // important que ce soit ici
+        typ2                               = slinj->ArcType();
+        if (typ2 != IntPatch_Restriction)
+        {
+          //-- arcref = Handle(IntPatch_RLine)::DownCast (slini)->Arc();
+          //-- OnFirst = Handle(IntPatch_RLine)::DownCast (slini)->IsOnFirstSurface();
+
+          //-- DES CHOSES A FAIRE ICI
+          if (Handle(IntPatch_RLine)::DownCast(slini)->IsArcOnS1())
+          {
+            OnFirst = Standard_True;
+            arcref  = Handle(IntPatch_RLine)::DownCast(slini)->ArcOnS1();
+          }
+          else if (Handle(IntPatch_RLine)::DownCast(slini)->IsArcOnS2())
+          {
+            arcref  = Handle(IntPatch_RLine)::DownCast(slini)->ArcOnS2();
+            OnFirst = Standard_False;
+          }
+          if (Handle(IntPatch_RLine)::DownCast(slini)->HasFirstPoint())
+          {
+            paramf = Handle(IntPatch_RLine)::DownCast(slini)->FirstPoint().ParameterOnLine();
+          }
+          else
+          {
+            // cout << "Pas de param debut sur rst solution" << endl;
+            paramf = RealFirst();
+          }
+          if (Handle(IntPatch_RLine)::DownCast(slini)->HasLastPoint())
+          {
+            paraml = Handle(IntPatch_RLine)::DownCast(slini)->LastPoint().ParameterOnLine();
+          }
+          else
+          {
+            // cout << "Pas de param debut sur rst solution" << endl;
+            paraml = RealLast();
+          }
+
+          if (typ2 == IntPatch_Analytic)
+          {
+            Nbvtx = Handle(IntPatch_ALine)::DownCast(slinj)->NbVertex();
+          }
+          else
+          {
+            Nbvtx = Handle(IntPatch_GLine)::DownCast(slinj)->NbVertex();
+          }
+
+          Standard_Boolean EdgeDegenere = Standard_True;
+          for (Standard_Integer edg = 0; EdgeDegenere && edg <= 10; edg++)
+          {
+            arcref->D1(paramf + (paraml - paramf) * edg * 0.1, p2d, d2d);
+            if (OnFirst)
+            {
+              Quad1.D1(p2d.X(), p2d.Y(), valpt, d1u, d1v);
+            }
+            else
+            {
+              Quad2.D1(p2d.X(), p2d.Y(), valpt, d1u, d1v);
+            }
+            if (d1u.Magnitude() > 1e-7)
+            {
+              EdgeDegenere = Standard_False;
+            }
+          }
+
+          for (k = 1; EdgeDegenere == Standard_False && k <= Nbvtx; k++)
+          {
+            if (typ2 == IntPatch_Analytic)
+            {
+              Ptvtx = Handle(IntPatch_ALine)::DownCast(slinj)->Vertex(k);
+            }
+            else
+            {
+              Ptvtx = Handle(IntPatch_GLine)::DownCast(slinj)->Vertex(k);
+            }
+            if ((OnFirst && !Ptvtx.IsOnDomS1()) || (!OnFirst && !Ptvtx.IsOnDomS2()))
+            {
+              // Si OnFirst && OnDomS1, c est qu on est a une extremite
+              // ca doit etre traite par Process Segment...
+              project   = Standard_True;
+              keeppoint = Standard_False;
+              toproj    = Ptvtx.Value();
+
+              Standard_Integer jj;
+              for (jj = 1; jj <= Nbpt; jj++)
+              {
+                //for (Standard_Integer jj = 1; jj <= Nbpt; jj++) {
+                if (toproj.Distance(seq_Pnt3d(jj)) < _TolArc)
+                {
+                  project = Standard_False;
+                  break;
+                }
+              }
+              if (project)
+              { //-- il faut projeter pour trouver le point sur la rline.
+                if (OnFirst)
+                {
+                  Ptvtx.ParametersOnS1(U, V);
+                }
+                else
+                {
+                  Ptvtx.ParametersOnS2(U, V);
+                }
+
+                project = IntPatch_HInterTool::Project(arcref, gp_Pnt2d(U, V), paramproj, p2d);
+
+                if (project)
+                {
+                  if (OnFirst)
+                  {
+                    ptproj = Quad1.Value(p2d.X(), p2d.Y());
+                  }
+                  else
+                  {
+                    ptproj = Quad2.Value(p2d.X(), p2d.Y());
+                  }
+                  if ((toproj.Distance(ptproj) <= 100 * TolArc) && (paramproj >= paramf) && (paramproj <= paraml))
+                  {
+                    newptvtx = Ptvtx;
+                    newptvtx.SetParameter(paramproj);
+                    keeppoint = Standard_True;
+                    seq_Pnt3d.Append(toproj);
+                    seq_Real.Append(paramproj);
+
+                    //-- verifier que si la restriction arcref est trouvee, elle porte ce vertex
+                    for (int ri = 1; ri <= Nblin; ri++)
+                    {
+                      const Handle(IntPatch_Line)& slinri = slin(ri);
+                      if (slinri->ArcType() == IntPatch_Restriction)
+                      {
+                        if (OnFirst && Handle(IntPatch_RLine)::DownCast(slinri)->IsArcOnS1())
+                        {
+                          if (arcref == Handle(IntPatch_RLine)::DownCast(slinri)->ArcOnS1())
+                          {
+                            Handle(IntPatch_RLine)::DownCast(slinri)->AddVertex(newptvtx);
+                            //printf("\n ImpImpIntersection_0.gxx CAS1 \n");
+                          }
+                        }
+                        else if (OnFirst == Standard_False && Handle(IntPatch_RLine)::DownCast(slinri)->IsArcOnS2())
+                        {
+                          if (arcref == Handle(IntPatch_RLine)::DownCast(slinri)->ArcOnS2())
+                          {
+                            Handle(IntPatch_RLine)::DownCast(slinri)->AddVertex(newptvtx);
+                            //printf("\n ImpImpIntersection_0.gxx CAS2 \n");
+                          }
+                        }
+                      }
+                    }
+                    // -- --------------------------------------------------
+                  }
+                }
+              }
+              else
+              {
+                keeppoint = Standard_True;
+                newptvtx  = Ptvtx;
+                newptvtx.SetParameter(seq_Real(jj));
+              }
+              if (keeppoint)
+              {
+                Ptvtx.SetMultiple(Standard_True);
+                Ptvtx.SetTolerance(_TolArc);
+                newptvtx.SetMultiple(Standard_True);
+
+                if (typ2 == IntPatch_Analytic)
+                {
+                  Handle(IntPatch_ALine)::DownCast(slinj)->Replace(k, Ptvtx);
+                }
+                else
+                {
+                  Handle(IntPatch_GLine)::DownCast(slinj)->Replace(k, Ptvtx);
+                }
+
+                if (Ptvtx.IsOnDomS1() || Ptvtx.IsOnDomS2())
+                {
+                  arcref->D1(newptvtx.ParameterOnLine(), p2d, d2d);
+
+                  if (OnFirst)
+                  { // donc OnDomS2
+                    Quad1.D1(p2d.X(), p2d.Y(), valpt, d1u, d1v);
+                    tgrest.SetLinearForm(d2d.X(), d1u, d2d.Y(), d1v);
+
+                    const Handle(Adaptor2d_Curve2d)& thearc = Ptvtx.ArcOnS2();
+                    thearc->D1(Ptvtx.ParameterOnArc2(), p2d, d2d);
+                    Quad2.D1(p2d.X(), p2d.Y(), valpt, d1u, d1v);
+                    tgarc.SetLinearForm(d2d.X(), d1u, d2d.Y(), d1v);
+                    norm = d1u.Crossed(d1v); //Quad2.Normale(valpt);
+                    if (norm.SquareMagnitude() < 1e-16)
+                    {
+                      TRest.SetValue(Standard_True, IntSurf_Undecided);
+                      TArc.SetValue(Standard_True, IntSurf_Undecided);
+                    }
+                    else
+                    {
+                      IntSurf::MakeTransition(tgrest, tgarc, norm, TRest, TArc);
+                    }
+                    newptvtx.SetArc(Standard_False, thearc, Ptvtx.ParameterOnArc2(), TRest, TArc);
+                  }
+                  else
+                  { // donc OnDomS1
+                    Quad2.D1(p2d.X(), p2d.Y(), valpt, d1u, d1v);
+                    tgrest.SetLinearForm(d2d.X(), d1u, d2d.Y(), d1v);
+
+                    const Handle(Adaptor2d_Curve2d)& thearc = Ptvtx.ArcOnS1();
+                    thearc->D1(Ptvtx.ParameterOnArc1(), p2d, d2d);
+                    Quad1.D1(p2d.X(), p2d.Y(), valpt, d1u, d1v);
+                    tgarc.SetLinearForm(d2d.X(), d1u, d2d.Y(), d1v);
+                    norm = d1u.Crossed(d1v); //Quad1.Normale(valpt);
+                    if (norm.SquareMagnitude() < 1e-16)
+                    {
+                      TRest.SetValue(Standard_True, IntSurf_Undecided);
+                      TArc.SetValue(Standard_True, IntSurf_Undecided);
+                    }
+                    else
+                    {
+                      IntSurf::MakeTransition(tgrest, tgarc, norm, TRest, TArc);
+                    }
+                    newptvtx.SetArc(Standard_True, thearc, Ptvtx.ParameterOnArc1(), TRest, TArc);
+                  }
+                } //-- if (Ptvtx.IsOnDomS1() || Ptvtx.IsOnDomS2())
+
+                Handle(IntPatch_RLine)::DownCast(slini)->AddVertex(newptvtx);
+
+              } //-- if (keeppoint)
+            } //-- if ((OnFirst && !Ptvtx.IsOnDomS1())||(!OnFirst && !Ptvtx.IsOnDomS2()))
+          } //-- boucle sur les vertex
+
+          if (!theIsReqToKeepRLine)
+          {
+            Handle(IntPatch_GLine) aGL = Handle(IntPatch_GLine)::DownCast(slinj);
+
+            if (!aGL.IsNull())
+            {
+              HasToDeleteRLine = !IsRLineGood(Quad1, Quad2, aGL, Handle(IntPatch_RLine)::DownCast(slini), TolArc);
+            }
+
+            if (HasToDeleteRLine)
+            {
+              break;
+            }
+          }
+        } //-- if (typ2 != IntPatch_Restriction)
+      } //-- for (j=1; j<=Nblin; j++)
+    } //-- if (typ1 == IntPatch_Restriction)
+
+    if (HasToDeleteRLine)
+    {
+      slin.Remove(i);
+      i--;
+      Nblin = slin.Length();
+      continue;
+    }
+  } //-- for (i=1; i<=Nblin; i++)
+}
+
+static Standard_Boolean IntPP(const IntSurf_Quadric&,
+                              const IntSurf_Quadric&,
+                              const Standard_Real,
+                              const Standard_Real,
+                              Standard_Boolean&,
+                              IntPatch_SequenceOfLine&);
+
+static Standard_Boolean IntPCy(const IntSurf_Quadric&,
+                               const IntSurf_Quadric&,
+                               const Standard_Real,
+                               const Standard_Real,
+                               const Standard_Boolean,
+                               Standard_Boolean&,
+                               IntPatch_SequenceOfLine&,
+                               const Standard_Real H = 0.);
+
+static Standard_Boolean IntPSp(const IntSurf_Quadric&,
+                               const IntSurf_Quadric&,
+                               //modified by NIZNHY-PKV Tue Sep 20 08:59:56 2011t
+                               const Standard_Real,
+                               //modified by NIZNHY-PKV Tue Sep 20 08:59:52 2011t
+                               const Standard_Real,
+                               const Standard_Boolean,
+                               Standard_Boolean&,
+                               IntPatch_SequenceOfLine&,
+                               IntPatch_SequenceOfPoint&);
+
+static Standard_Boolean IntPCo(const IntSurf_Quadric&,
+                               const IntSurf_Quadric&,
+                               const Standard_Real,
+                               const Standard_Real,
+                               const Standard_Boolean,
+                               Standard_Boolean&,
+                               Standard_Boolean&,
+                               IntPatch_SequenceOfLine&,
+                               IntPatch_SequenceOfPoint&);
+
+static void ProcessBounds(const Handle(IntPatch_ALine)&,
+                          const IntPatch_SequenceOfLine&,
+                          const IntSurf_Quadric&,
+                          const IntSurf_Quadric&,
+                          Standard_Boolean&,
+                          const gp_Pnt&,
+                          const Standard_Real,
+                          Standard_Boolean&,
+                          const gp_Pnt&,
+                          const Standard_Real,
+                          Standard_Boolean&,
+                          const Standard_Real);
+
+static IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric&    theQuad1,
+                                                      const IntSurf_Quadric&    theQuad2,
+                                                      const Standard_Real       theTol3D,
+                                                      const Standard_Real       theTol2D,
+                                                      const Bnd_Box2d&          theUVSurf1,
+                                                      const Bnd_Box2d&          theUVSurf2,
+                                                      Standard_Boolean&         isTheEmpty,
+                                                      Standard_Boolean&         isTheSameSurface,
+                                                      Standard_Boolean&         isTheMultiplePoint,
+                                                      IntPatch_SequenceOfLine&  theSlin,
+                                                      IntPatch_SequenceOfPoint& theSPnt);
+
+static Standard_Boolean IntCySp(const IntSurf_Quadric&,
+                                const IntSurf_Quadric&,
+                                const Standard_Real,
+                                const Standard_Boolean,
+                                Standard_Boolean&,
+                                Standard_Boolean&,
+                                IntPatch_SequenceOfLine&,
+                                IntPatch_SequenceOfPoint&);
+
+static Standard_Boolean IntCyCo(const IntSurf_Quadric&,
+                                const IntSurf_Quadric&,
+                                const Standard_Real,
+                                const Standard_Boolean,
+                                Standard_Boolean&,
+                                Standard_Boolean&,
+                                IntPatch_SequenceOfLine&,
+                                IntPatch_SequenceOfPoint&);
+
+static Standard_Boolean IntSpSp(const IntSurf_Quadric&,
+                                const IntSurf_Quadric&,
+                                const Standard_Real,
+                                Standard_Boolean&,
+                                Standard_Boolean&,
+                                IntPatch_SequenceOfLine&,
+                                IntPatch_SequenceOfPoint&);
+
+static Standard_Boolean IntCoSp(const IntSurf_Quadric&,
+                                const IntSurf_Quadric&,
+                                const Standard_Real,
+                                const Standard_Boolean,
+                                Standard_Boolean&,
+                                Standard_Boolean&,
+                                IntPatch_SequenceOfLine&,
+                                IntPatch_SequenceOfPoint&);
+
+static Standard_Boolean IntCoCo(const IntSurf_Quadric&,
+                                const IntSurf_Quadric&,
+                                const Standard_Real,
+                                Standard_Boolean&,
+                                Standard_Boolean&,
+                                Standard_Boolean&,
+                                IntPatch_SequenceOfLine&,
+                                IntPatch_SequenceOfPoint&);
+
+//torus
+static Standard_Boolean IntPTo(const IntSurf_Quadric&,
+                               const IntSurf_Quadric&,
+                               const Standard_Real,
+                               const Standard_Boolean,
+                               Standard_Boolean&,
+                               IntPatch_SequenceOfLine&);
+
+static Standard_Boolean IntCyTo(const IntSurf_Quadric&,
+                                const IntSurf_Quadric&,
+                                const Standard_Real,
+                                const Standard_Boolean,
+                                Standard_Boolean&,
+                                IntPatch_SequenceOfLine&);
+
+static Standard_Boolean IntCoTo(const IntSurf_Quadric&,
+                                const IntSurf_Quadric&,
+                                const Standard_Real,
+                                const Standard_Boolean,
+                                Standard_Boolean&,
+                                IntPatch_SequenceOfLine&);
+
+static Standard_Boolean IntSpTo(const IntSurf_Quadric&,
+                                const IntSurf_Quadric&,
+                                const Standard_Real,
+                                const Standard_Boolean,
+                                Standard_Boolean&,
+                                IntPatch_SequenceOfLine&);
+
+static Standard_Boolean IntToTo(const IntSurf_Quadric&,
+                                const IntSurf_Quadric&,
+                                const Standard_Real,
+                                Standard_Boolean&,
+                                Standard_Boolean&,
+                                IntPatch_SequenceOfLine&);
+
+static Standard_Integer SetQuad(const Handle(Adaptor3d_Surface)& theS, GeomAbs_SurfaceType& theTS, IntSurf_Quadric& theQuad);
+
+//=======================================================================
+//function : IntPatch_ImpImpIntersection
+//purpose  :
+//=======================================================================
+IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection()
+: myDone(IntStatus_Fail),
+  empt(Standard_True),
+  tgte(Standard_False),
+  oppo(Standard_False)
+{}
+//=======================================================================
+//function : IntPatch_ImpImpIntersection
+//purpose  :
+//=======================================================================
+IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection(const Handle(Adaptor3d_Surface)&   S1,
+                                                         const Handle(Adaptor3d_TopolTool)& D1,
+                                                         const Handle(Adaptor3d_Surface)&   S2,
+                                                         const Handle(Adaptor3d_TopolTool)& D2,
+                                                         const Standard_Real                TolArc,
+                                                         const Standard_Real                TolTang,
+                                                         const Standard_Boolean             theIsReqToKeepRLine)
+{
+  Perform(S1, D1, S2, D2, TolArc, TolTang, theIsReqToKeepRLine);
+}
+//=======================================================================
+//function : Perform
+//purpose  :
+//=======================================================================
+void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_Surface)&   S1,
+                                          const Handle(Adaptor3d_TopolTool)& D1,
+                                          const Handle(Adaptor3d_Surface)&   S2,
+                                          const Handle(Adaptor3d_TopolTool)& D2,
+                                          const Standard_Real                TolArc,
+                                          const Standard_Real                TolTang,
+                                          const Standard_Boolean             theIsReqToKeepRLine)
+{
+  myDone = IntStatus_Fail;
+  spnt.Clear();
+  slin.Clear();
+
+  Standard_Boolean isPostProcessingRequired = Standard_True;
+
+  empt                                      = Standard_True;
+  tgte                                      = Standard_False;
+  oppo                                      = Standard_False;
+
+  Standard_Boolean all1                     = Standard_False;
+  Standard_Boolean all2                     = Standard_False;
+  Standard_Boolean SameSurf                 = Standard_False;
+  Standard_Boolean multpoint                = Standard_False;
+
+  Standard_Boolean nosolonS1                = Standard_False;
+  // indique s il y a des points sur restriction du carreau 1
+  Standard_Boolean nosolonS2                = Standard_False;
+  // indique s il y a des points sur restriction du carreau 2
+  Standard_Integer                           i, nbpt, nbseg;
+  IntPatch_SequenceOfSegmentOfTheSOnBounds   edg1, edg2;
+  IntPatch_SequenceOfPathPointOfTheSOnBounds pnt1, pnt2;
+  //
+  // On commence par intersecter les supports des surfaces
+  IntSurf_Quadric      quad1, quad2;
+  IntPatch_ArcFunction AFunc;
+  const Standard_Real  Tolang = 1.e-8;
+  GeomAbs_SurfaceType  typs1, typs2;
+  Standard_Boolean     bEmpty = Standard_False;
+  //
+  const Standard_Integer iT1  = SetQuad(S1, typs1, quad1);
+  const Standard_Integer iT2  = SetQuad(S2, typs2, quad2);
+  //
+  if (!iT1 || !iT2)
+  {
+    throw Standard_ConstructionError();
+    return;
+  }
+  //
+  const Standard_Boolean bReverse = iT1 > iT2;
+  const Standard_Integer iTT      = iT1 * 10 + iT2;
+  //
+  switch (iTT)
+  {
+    case 11:
+    { // Plane/Plane
+      if (!IntPP(quad1, quad2, Tolang, TolTang, SameSurf, slin))
+      {
+        return;
+      }
+      break;
+    }
+    //
+    case 12:
+    case 21:
+    { // Plane/Cylinder
+      Standard_Real VMin, VMax, H;
+      //
+      const Handle(Adaptor3d_Surface)& aSCyl = bReverse ? S1 : S2;
+      VMin                                   = aSCyl->FirstVParameter();
+      VMax                                   = aSCyl->LastVParameter();
+      H = (Precision::IsNegativeInfinite(VMin) || Precision::IsPositiveInfinite(VMax)) ? 0 : (VMax - VMin);
+      //
+      if (!IntPCy(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, H))
+      {
+        return;
+      }
+      bEmpty = empt;
+      break;
+    }
+    //
+    case 13:
+    case 31:
+    { // Plane/Cone
+      if (!IntPCo(quad1, quad2, Tolang, TolTang, bReverse, empt, multpoint, slin, spnt))
+      {
+        return;
+      }
+      bEmpty = empt;
+      break;
+    }
+    //
+    case 14:
+    case 41:
+    { // Plane/Sphere
+      if (!IntPSp(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, spnt))
+      {
+        return;
+      }
+      bEmpty = empt;
+      break;
+    }
+    //
+    case 15:
+    case 51:
+    { // Plane/Torus
+      if (!IntPTo(quad1, quad2, TolTang, bReverse, empt, slin))
+      {
+        return;
+      }
+      bEmpty = empt;
+      break;
+    }
+    //
+    case 22:
+    { // Cylinder/Cylinder
+      Bnd_Box2d aBox1, aBox2;
+
+      const Standard_Real aU1f      = S1->FirstUParameter();
+      Standard_Real       aU1l      = S1->LastUParameter();
+      const Standard_Real aU2f      = S2->FirstUParameter();
+      Standard_Real       aU2l      = S2->LastUParameter();
+
+      const Standard_Real anUperiod = 2.0 * M_PI;
+
+      if (aU1l - aU1f > anUperiod)
+        aU1l = aU1f + anUperiod;
+
+      if (aU2l - aU2f > anUperiod)
+        aU2l = aU2f + anUperiod;
+
+      aBox1.Add(gp_Pnt2d(aU1f, S1->FirstVParameter()));
+      aBox1.Add(gp_Pnt2d(aU1l, S1->LastVParameter()));
+      aBox2.Add(gp_Pnt2d(aU2f, S2->FirstVParameter()));
+      aBox2.Add(gp_Pnt2d(aU2l, S2->LastVParameter()));
+
+      // Resolution is too big if the cylinder radius is
+      // too small. Therefore, we shall bind its value above.
+      // Here, we use simple constant.
+      const Standard_Real a2DTol = Min(1.0e-4, Min(S1->UResolution(TolTang), S2->UResolution(TolTang)));
+
+      myDone                     = IntCyCy(quad1, quad2, TolTang, a2DTol, aBox1, aBox2, empt, SameSurf, multpoint, slin, spnt);
+
+      if (myDone == IntPatch_ImpImpIntersection::IntStatus_Fail)
+      {
+        return;
+      }
+
+      bEmpty = empt;
+      if (!slin.IsEmpty())
+      {
+        const Handle(IntPatch_WLine)& aWLine = Handle(IntPatch_WLine)::DownCast(slin.Value(1));
+
+        if (!aWLine.IsNull())
+        { //No geometric solution
+          isPostProcessingRequired = Standard_False;
+        }
+      }
+
+      break;
+    }
+    //
+    case 23:
+    case 32:
+    { // Cylinder/Cone
+      if (!IntCyCo(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt))
+      {
+        return;
+      }
+      bEmpty = empt;
+      break;
+    }
+    //
+    case 24:
+    case 42:
+    { // Cylinder/Sphere
+      if (!IntCySp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt))
+      {
+        return;
+      }
+      bEmpty = empt;
+      break;
+    }
+    //
+    case 25:
+    case 52:
+    { // Cylinder/Torus
+      if (!IntCyTo(quad1, quad2, TolTang, bReverse, empt, slin))
+      {
+        return;
+      }
+      bEmpty = empt;
+      break;
+    }
+    //
+    case 33:
+    { // Cone/Cone
+      if (!IntCoCo(quad1, quad2, TolTang, empt, SameSurf, multpoint, slin, spnt))
+      {
+        return;
+      }
+      bEmpty = empt;
+      break;
+    }
+    //
+    case 34:
+    case 43:
+    { // Cone/Sphere
+      if (!IntCoSp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt))
+      {
+        return;
+      }
+      bEmpty = empt;
+      break;
+    }
+    //
+    case 35:
+    case 53:
+    { // Cone/Torus
+      if (!IntCoTo(quad1, quad2, TolTang, bReverse, empt, slin))
+      {
+        return;
+      }
+      break;
+    }
+    //
+    case 44:
+    { // Sphere/Sphere
+      if (!IntSpSp(quad1, quad2, TolTang, empt, SameSurf, slin, spnt))
+      {
+        return;
+      }
+      bEmpty = empt;
+      break;
+    }
+    //
+    case 45:
+    case 54:
+    { // Sphere/Torus
+      if (!IntSpTo(quad1, quad2, TolTang, bReverse, empt, slin))
+      {
+        return;
+      }
+      bEmpty = empt;
+      break;
+    }
+    //
+    case 55:
+    { // Torus/Torus
+      if (!IntToTo(quad1, quad2, TolTang, SameSurf, empt, slin))
+      {
+        return;
+      }
+      bEmpty = empt;
+      break;
+    }
+    //
+    default:
+    {
+      throw Standard_ConstructionError();
+      break;
+    }
+  }
+  //
+  if (bEmpty)
+  {
+    if (myDone == IntStatus_Fail)
+      myDone = IntStatus_OK;
+
+    return;
+  }
+  //
+
+  if (isPostProcessingRequired)
+  {
+    if (!SameSurf)
+    {
+      AFunc.SetQuadric(quad2);
+      AFunc.Set(S1);
+
+      solrst.Perform(AFunc, D1, TolArc, TolTang);
+      if (!solrst.IsDone())
+      {
+        return;
+      }
+
+      if (solrst.AllArcSolution() && typs1 == typs2)
+      {
+        all1 = Standard_True;
+      }
+      nbpt  = solrst.NbPoints();
+      nbseg = solrst.NbSegments();
+      for (i = 1; i <= nbpt; i++)
+      {
+        const IntPatch_ThePathPointOfTheSOnBounds& aPt = solrst.Point(i);
+        pnt1.Append(aPt);
+      }
+      for (i = 1; i <= nbseg; i++)
+      {
+        const IntPatch_TheSegmentOfTheSOnBounds& aSegm = solrst.Segment(i);
+        edg1.Append(aSegm);
+      }
+      nosolonS1 = (nbpt == 0) && (nbseg == 0);
+
+      if (nosolonS1 && all1)
+      { // cas de face sans restrictions
+        all1 = Standard_False;
+      }
+    } //if (!SameSurf) {
+    else
+    {
+      nosolonS1 = Standard_True;
+    }
+
+    if (!SameSurf)
+    {
+      AFunc.SetQuadric(quad1);
+      AFunc.Set(S2);
+
+      solrst.Perform(AFunc, D2, TolArc, TolTang);
+      if (!solrst.IsDone())
+      {
+        return;
+      }
+
+      if (solrst.AllArcSolution() && typs1 == typs2)
+      {
+        all2 = Standard_True;
+      }
+
+      nbpt  = solrst.NbPoints();
+      nbseg = solrst.NbSegments();
+      for (i = 1; i <= nbpt; i++)
+      {
+        const IntPatch_ThePathPointOfTheSOnBounds& aPt = solrst.Point(i);
+        pnt2.Append(aPt);
+      }
+
+      for (i = 1; i <= nbseg; i++)
+      {
+        const IntPatch_TheSegmentOfTheSOnBounds& aSegm = solrst.Segment(i);
+        edg2.Append(aSegm);
+      }
+
+      nosolonS2 = (nbpt == 0) && (nbseg == 0);
+
+      if (nosolonS2 && all2)
+      { // cas de face sans restrictions
+        all2 = Standard_False;
+      }
+    } // if (!SameSurf) {
+    else
+    {
+      nosolonS2 = Standard_True;
+    }
+    //
+    if (SameSurf || (all1 && all2))
+    {
+      // faces "paralleles" parfaites
+      empt = Standard_False;
+      tgte = Standard_True;
+      slin.Clear();
+      spnt.Clear();
+
+      gp_Pnt Ptreference;
+
+      switch (typs1)
+      {
+        case GeomAbs_Plane:
+        {
+          Ptreference = (S1->Plane()).Location();
+        }
+        break;
+        case GeomAbs_Cylinder:
+        {
+          Ptreference = ElSLib::Value(0., 0., S1->Cylinder());
+        }
+        break;
+        case GeomAbs_Sphere:
+        {
+          Ptreference = ElSLib::Value(M_PI / 4., M_PI / 4., S1->Sphere());
+        }
+        break;
+        case GeomAbs_Cone:
+        {
+          Ptreference = ElSLib::Value(0., 10., S1->Cone());
+        }
+        break;
+        case GeomAbs_Torus:
+        {
+          Ptreference = ElSLib::Value(0., 0., S1->Torus());
+        }
+        break;
+        default: break;
+      }
+      //
+      oppo   = quad1.Normale(Ptreference).Dot(quad2.Normale(Ptreference)) < 0.0;
+      myDone = IntStatus_OK;
+      return;
+    } // if (SameSurf || (all1 && all2)) {
+
+    if (!nosolonS1 || !nosolonS2)
+    {
+      empt = Standard_False;
+      // C est la qu il faut commencer a bosser...
+      PutPointsOnLine(S1, S2, pnt1, slin, Standard_True, D1, quad1, quad2, multpoint, TolArc);
+
+      PutPointsOnLine(S1, S2, pnt2, slin, Standard_False, D2, quad2, quad1, multpoint, TolArc);
+
+      if (edg1.Length() != 0)
+      {
+        ProcessSegments(edg1, slin, quad1, quad2, Standard_True, TolArc);
+      }
+
+      if (edg2.Length() != 0)
+      {
+        ProcessSegments(edg2, slin, quad1, quad2, Standard_False, TolArc);
+      }
+
+      if (edg1.Length() != 0 || edg2.Length() != 0)
+      {
+        //      ProcessRLine(slin,S1,S2,TolArc);
+        ProcessRLine(slin, quad1, quad2, TolArc, theIsReqToKeepRLine);
+      }
+    } //if (!nosolonS1 || !nosolonS2) {
+    else
+    {
+      empt = ((slin.Length() == 0) && (spnt.Length() == 0));
+    }
+  }
+
+  Standard_Integer nblin = slin.Length(), aNbPnt = spnt.Length();
+  //
+  //modified by NIZNHY-PKV Tue Sep 06 10:03:35 2011f
+  if (aNbPnt)
+  {
+    IntPatch_SequenceOfPoint aSIP;
+    //
+    for (i = 1; i <= aNbPnt; ++i)
+    {
+      Standard_Real aU1, aV1, aU2, aV2;
+      gp_Pnt2d      aP2D;
+      TopAbs_State  aState1, aState2;
+      //
+      const IntPatch_Point& aIP = spnt(i);
+      aIP.Parameters(aU1, aV1, aU2, aV2);
+      //
+      aP2D.SetCoord(aU1, aV1);
+      aState1 = D1->Classify(aP2D, TolArc);
+      //
+      aP2D.SetCoord(aU2, aV2);
+      aState2 = D2->Classify(aP2D, TolArc);
+      //
+      if (aState1 != TopAbs_OUT && aState2 != TopAbs_OUT)
+      {
+        aSIP.Append(aIP);
+      }
+    }
+    //
+    spnt.Clear();
+    //
+    aNbPnt = aSIP.Length();
+    for (i = 1; i <= aNbPnt; ++i)
+    {
+      const IntPatch_Point& aIP = aSIP(i);
+      spnt.Append(aIP);
+    }
+    //
+  } //  if (aNbPnt) {
+  //modified by NIZNHY-PKV Tue Sep 06 10:18:20 2011t
+  //
+  for (i = 1; i <= nblin; i++)
+  {
+    IntPatch_IType thetype = slin.Value(i)->ArcType();
+    if ((thetype == IntPatch_Ellipse) || (thetype == IntPatch_Circle) || (thetype == IntPatch_Lin)
+        || (thetype == IntPatch_Parabola) || (thetype == IntPatch_Hyperbola))
+    {
+      Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
+      glin->ComputeVertexParameters(TolArc);
+    }
+    else if (thetype == IntPatch_Analytic)
+    {
+      Handle(IntPatch_ALine)& aligold = *((Handle(IntPatch_ALine)*)&slin.Value(i));
+      aligold->ComputeVertexParameters(TolArc);
+    }
+    else if (thetype == IntPatch_Restriction)
+    {
+      Handle(IntPatch_RLine)& rlig = *((Handle(IntPatch_RLine)*)&slin.Value(i));
+      rlig->ComputeVertexParameters(TolArc);
+    }
+  }
+  //
+  //----------------------------------------------------------------
+  //-- On place 2 vertex sur les courbes de GLine qui n en
+  //-- contiennent pas.
+  for (i = 1; i <= nblin; i++)
+  {
+    gp_Pnt         P;
+    IntPatch_Point point;
+    Standard_Real  u1, v1, u2, v2;
+    if (slin.Value(i)->ArcType() == IntPatch_Circle)
+    {
+      const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
+      if (glin->NbVertex() == 0)
+      {
+        gp_Circ Circ = glin->Circle();
+        P            = ElCLib::Value(0.0, Circ);
+        quad1.Parameters(P, u1, v1);
+        quad2.Parameters(P, u2, v2);
+        point.SetValue(P, TolArc, Standard_False);
+        point.SetParameters(u1, v1, u2, v2);
+        point.SetParameter(0.0);
+        glin->AddVertex(point);
+
+        P = ElCLib::Value(0.0, Circ);
+        quad1.Parameters(P, u1, v1);
+        quad2.Parameters(P, u2, v2);
+        point.SetValue(P, TolArc, Standard_False);
+        point.SetParameters(u1, v1, u2, v2);
+        point.SetParameter(M_PI + M_PI);
+        glin->AddVertex(point);
+      }
+    }
+
+    else if (slin.Value(i)->ArcType() == IntPatch_Ellipse)
+    {
+      const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
+      if (glin->NbVertex() == 0)
+      {
+        gp_Elips Elips = glin->Ellipse();
+        P              = ElCLib::Value(0.0, Elips);
+        quad1.Parameters(P, u1, v1);
+        quad2.Parameters(P, u2, v2);
+        point.SetValue(P, TolArc, Standard_False);
+        point.SetParameters(u1, v1, u2, v2);
+        point.SetParameter(0.0);
+        glin->AddVertex(point);
+
+        P = ElCLib::Value(0.0, Elips);
+        quad1.Parameters(P, u1, v1);
+        quad2.Parameters(P, u2, v2);
+        point.SetValue(P, TolArc, Standard_False);
+        point.SetParameters(u1, v1, u2, v2);
+        point.SetParameter(M_PI + M_PI);
+        glin->AddVertex(point);
+      }
+    }
+  }
+  myDone = IntStatus_OK;
+}
+
+//=======================================================================
+//function : SetQuad
+//purpose  :
+//=======================================================================
+Standard_Integer SetQuad(const Handle(Adaptor3d_Surface)& theS, GeomAbs_SurfaceType& theTS, IntSurf_Quadric& theQuad)
+{
+  theTS                 = theS->GetType();
+  Standard_Integer iRet = 0;
+  switch (theTS)
+  {
+    case GeomAbs_Plane:
+      theQuad.SetValue(theS->Plane());
+      iRet = 1;
+      break;
+    case GeomAbs_Cylinder:
+      theQuad.SetValue(theS->Cylinder());
+      iRet = 2;
+      break;
+    case GeomAbs_Cone:
+      theQuad.SetValue(theS->Cone());
+      iRet = 3;
+      break;
+    case GeomAbs_Sphere:
+      theQuad.SetValue(theS->Sphere());
+      iRet = 4;
+      break;
+    case GeomAbs_Torus:
+      theQuad.SetValue(theS->Torus());
+      iRet = 5;
+      break;
+    default: break;
+  }
+  //
+  return iRet;
+}
+
+static void SeamPosition(const gp_Pnt& aPLoc, const gp_Ax3& aPos, gp_Ax2& aSeamPos);
+static void AdjustToSeam(const gp_Cylinder& aQuad, gp_Circ& aCirc);
+static void AdjustToSeam(const gp_Sphere& aQuad, gp_Circ& aCirc, const Standard_Real aTolAng);
+static void AdjustToSeam(const gp_Cone& aQuad, gp_Circ& aCirc);
+static void AdjustToSeam(const gp_Torus& aQuad, gp_Circ& aCirc);
+//modified by NIZNHY-PKV Thu Sep 15 11:09:13 2011
+
+//=======================================================================
+//function : IntPP
+//purpose  :
+// Traitement du cas Plan/Plan
+//=======================================================================
+Standard_Boolean IntPP(const IntSurf_Quadric&   Quad1,
+                       const IntSurf_Quadric&   Quad2,
+                       const Standard_Real      Tolang,
+                       const Standard_Real      TolTang,
+                       Standard_Boolean&        Same,
+                       IntPatch_SequenceOfLine& slin)
+
+{
+  IntSurf_TypeTrans trans1, trans2;
+  IntAna_ResultType typint;
+  gp_Pln            pl1(Quad1.Plane());
+  gp_Pln            pl2(Quad2.Plane());
+
+  IntAna_QuadQuadGeo inter(pl1, pl2, Tolang, TolTang);
+  if (!inter.IsDone())
+  {
+    return Standard_False;
+  }
+  Same   = Standard_False;
+  typint = inter.TypeInter();
+  if (typint == IntAna_Same)
+  { // cas faces confondues
+    Same = Standard_True;
+  }
+  else if (typint != IntAna_Empty)
+  { // on a une ligne
+    gp_Lin        linsol = inter.Line(1);
+    Standard_Real discri = linsol.Direction().DotCross(Quad2.Normale(linsol.Location()), Quad1.Normale(linsol.Location()));
+
+    if (discri > 0.0)
+    {
+      trans1 = IntSurf_Out;
+      trans2 = IntSurf_In;
+    }
+    else
+    {
+      trans1 = IntSurf_In;
+      trans2 = IntSurf_Out;
+    }
+    Handle(IntPatch_GLine) glig = new IntPatch_GLine(linsol, Standard_False, trans1, trans2);
+    slin.Append(glig);
+  }
+  return Standard_True;
+}
+//=======================================================================
+//function : IntPCy
+//purpose  :
+// Traitement du cas Plan/Cylindre et reciproquement
+//=======================================================================
+Standard_Boolean IntPCy(const IntSurf_Quadric&   Quad1,
+                        const IntSurf_Quadric&   Quad2,
+                        const Standard_Real      Tolang,
+                        const Standard_Real      TolTang,
+                        const Standard_Boolean   Reversed,
+                        Standard_Boolean&        Empty,
+                        IntPatch_SequenceOfLine& slin,
+                        const Standard_Real      H)
+
+{
+  gp_Pln      Pl;
+  gp_Cylinder Cy;
+
+  IntSurf_TypeTrans trans1, trans2;
+  IntAna_ResultType typint;
+
+  IntAna_QuadQuadGeo inter;
+  if (!Reversed)
+  {
+    Pl = Quad1.Plane();
+    Cy = Quad2.Cylinder();
+  }
+  else
+  {
+    Pl = Quad2.Plane();
+    Cy = Quad1.Cylinder();
+  }
+  inter.Perform(Pl, Cy, Tolang, TolTang, H);
+  if (!inter.IsDone())
+  {
+    return Standard_False;
+  }
+  typint                 = inter.TypeInter();
+  Standard_Integer NbSol = inter.NbSolutions();
+  Empty                  = Standard_False;
+
+  switch (typint)
+  {
+    case IntAna_Empty:
+    {
+      Empty = Standard_True;
+    }
+    break;
+
+    case IntAna_Line:
+    {
+      gp_Lin linsol = inter.Line(1);
+      gp_Pnt orig(linsol.Location());
+      if (NbSol == 1)
+      { // ligne de tangence
+        gp_Vec TestCurvature(orig, Cy.Location());
+        gp_Vec Normp, Normcyl;
+        if (!Reversed)
+        {
+          Normp   = Quad1.Normale(orig);
+          Normcyl = Quad2.Normale(orig);
+        }
+        else
+        {
+          Normp   = Quad2.Normale(orig);
+          Normcyl = Quad1.Normale(orig);
+        }
+
+        IntSurf_Situation situcyl;
+        IntSurf_Situation situp;
+
+        if (Normp.Dot(TestCurvature) > 0.)
+        {
+          situcyl = IntSurf_Outside;
+          if (Normp.Dot(Normcyl) > 0.)
+          {
+            situp = IntSurf_Inside;
+          }
+          else
+          {
+            situp = IntSurf_Outside;
+          }
+        }
+        else
+        {
+          situcyl = IntSurf_Inside;
+          if (Normp.Dot(Normcyl) > 0.)
+          {
+            situp = IntSurf_Outside;
+          }
+          else
+          {
+            situp = IntSurf_Inside;
+          }
+        }
+        Handle(IntPatch_GLine) glig;
+        if (!Reversed)
+        {
+          glig = new IntPatch_GLine(linsol, Standard_True, situp, situcyl);
+        }
+        else
+        {
+          glig = new IntPatch_GLine(linsol, Standard_True, situcyl, situp);
+        }
+        slin.Append(glig);
+      }
+      else
+      {
+        // on a 2 droites. Il faut determiner les transitions
+        // de chacune.
+
+        if (linsol.Direction().DotCross(Quad2.Normale(orig), Quad1.Normale(orig)) > 0.)
+        {
+          trans1 = IntSurf_Out;
+          trans2 = IntSurf_In;
+        }
+        else
+        {
+          trans1 = IntSurf_In;
+          trans2 = IntSurf_Out;
+        }
+        Handle(IntPatch_GLine) glig = new IntPatch_GLine(linsol, Standard_False, trans1, trans2);
+        slin.Append(glig);
+
+        linsol = inter.Line(2);
+        orig   = linsol.Location();
+
+        if (linsol.Direction().DotCross(Quad2.Normale(orig), Quad1.Normale(orig)) > 0.)
+        {
+          trans1 = IntSurf_Out;
+          trans2 = IntSurf_In;
+        }
+        else
+        {
+          trans1 = IntSurf_In;
+          trans2 = IntSurf_Out;
+        }
+        glig = new IntPatch_GLine(linsol, Standard_False, trans1, trans2);
+        slin.Append(glig);
+      }
+    }
+    break;
+      //
+    case IntAna_Circle:
+    {
+      gp_Circ cirsol;
+      gp_Pnt  ptref;
+      gp_Vec  Tgt;
+      //
+      cirsol = inter.Circle(1);
+      //modified by NIZNHY-PKV Thu Sep 15 11:30:03 2011f
+      AdjustToSeam(Cy, cirsol);
+      //modified by NIZNHY-PKV Thu Sep 15 11:30:15 2011t
+      ElCLib::D1(0., cirsol, ptref, Tgt);
+
+      if (Tgt.DotCross(Quad2.Normale(ptref), Quad1.Normale(ptref)) > 0.0)
+      {
+        trans1 = IntSurf_Out;
+        trans2 = IntSurf_In;
+      }
+      else
+      {
+        trans1 = IntSurf_In;
+        trans2 = IntSurf_Out;
+      }
+      Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol, Standard_False, trans1, trans2);
+      slin.Append(glig);
+    }
+    break;
+      //
+    case IntAna_Ellipse:
+    {
+      gp_Elips elipsol = inter.Ellipse(1);
+      gp_Pnt   ptref;
+      gp_Vec   Tgt;
+      ElCLib::D1(0., elipsol, ptref, Tgt);
+
+      if (Tgt.DotCross(Quad2.Normale(ptref), Quad1.Normale(ptref)) > 0.0)
+      {
+        trans1 = IntSurf_Out;
+        trans2 = IntSurf_In;
+      }
+      else
+      {
+        trans1 = IntSurf_In;
+        trans2 = IntSurf_Out;
+      }
+      Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol, Standard_False, trans1, trans2);
+      slin.Append(glig);
+    }
+    break;
+      //
+    default:
+    {
+      return Standard_False; // on ne doit pas passer ici
+    }
+  }
+  return Standard_True;
+}
+//=======================================================================
+//function : IntPSp
+//purpose  :
+// Traitement du cas Plan/Sphere et reciproquement
+//=======================================================================
+Standard_Boolean IntPSp(const IntSurf_Quadric& Quad1,
+                        const IntSurf_Quadric& Quad2,
+                        //modified by NIZNHY-PKV Tue Sep 20 08:59:36 2011f
+                        const Standard_Real Tolang,
+                        //modified by NIZNHY-PKV Tue Sep 20 08:59:39 2011t
+                        const Standard_Real       TolTang,
+                        const Standard_Boolean    Reversed,
+                        Standard_Boolean&         Empty,
+                        IntPatch_SequenceOfLine&  slin,
+                        IntPatch_SequenceOfPoint& spnt)
+
+{
+  gp_Circ           cirsol;
+  gp_Pln            Pl;
+  gp_Sphere         Sp;
+  IntSurf_TypeTrans trans1, trans2;
+  IntAna_ResultType typint;
+
+  IntAna_QuadQuadGeo inter;
+  if (!Reversed)
+  {
+    Pl = Quad1.Plane();
+    Sp = Quad2.Sphere();
+  }
+  else
+  {
+    Pl = Quad2.Plane();
+    Sp = Quad1.Sphere();
+  }
+  inter.Perform(Pl, Sp);
+
+  if (!inter.IsDone())
+  {
+    return Standard_False;
+  }
+
+  typint = inter.TypeInter();
+  Empty  = Standard_False;
+
+  switch (typint)
+  {
+    case IntAna_Empty:
+    {
+      Empty = Standard_True;
+    }
+    break;
+      //
+    case IntAna_Point:
+    {
+      gp_Pnt        psol = inter.Point(1);
+      Standard_Real U1, V1, U2, V2;
+      Quad1.Parameters(psol, U1, V1);
+      Quad2.Parameters(psol, U2, V2);
+      IntPatch_Point ptsol;
+      ptsol.SetValue(psol, TolTang, Standard_True);
+      ptsol.SetParameters(U1, V1, U2, V2);
+      spnt.Append(ptsol);
+    }
+    break;
+      //
+    case IntAna_Circle:
+    {
+      cirsol = inter.Circle(1);
+      //modified by NIZNHY-PKV Thu Sep 15 11:30:03 2011f
+      AdjustToSeam(Sp, cirsol, Tolang);
+      //modified by NIZNHY-PKV Thu Sep 15 11:30:15 2011t
+      gp_Pnt ptref;
+      gp_Vec Tgt;
+      ElCLib::D1(0., cirsol, ptref, Tgt);
+
+      if (Tgt.DotCross(Quad2.Normale(ptref), Quad1.Normale(ptref)) > 0.)
+      {
+        trans1 = IntSurf_Out;
+        trans2 = IntSurf_In;
+      }
+      else
+      {
+        trans1 = IntSurf_In;
+        trans2 = IntSurf_Out;
+      }
+      Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol, Standard_False, trans1, trans2);
+      slin.Append(glig);
+    }
+    break;
+
+    default:
+    {
+      return Standard_False; // on ne doit pas passer ici
+    }
+  }
+  return Standard_True;
+}
+//=======================================================================
+//function : IntPCo
+//purpose  :
+// Traitement du cas Plan/Cone et reciproquement
+//=======================================================================
+Standard_Boolean IntPCo(const IntSurf_Quadric&    Quad1,
+                        const IntSurf_Quadric&    Quad2,
+                        const Standard_Real       Tolang,
+                        const Standard_Real       TolTang,
+                        const Standard_Boolean    Reversed,
+                        Standard_Boolean&         Empty,
+                        Standard_Boolean&         Multpoint,
+                        IntPatch_SequenceOfLine&  slin,
+                        IntPatch_SequenceOfPoint& spnt)
+
+{
+  gp_Pnt apex;
+
+  gp_Pln  Pl;
+  gp_Cone Co;
+
+  IntSurf_TypeTrans trans1, trans2;
+  IntAna_ResultType typint;
+
+  IntAna_QuadQuadGeo inter;
+  if (!Reversed)
+  {
+    Pl   = Quad1.Plane();
+    Co   = Quad2.Cone();
+    apex = Co.Apex();
+  }
+  else
+  {
+    Pl   = Quad2.Plane();
+    Co   = Quad1.Cone();
+    apex = Co.Apex();
+  }
+
+  inter.Perform(Pl, Co, Tolang, TolTang);
+  if (!inter.IsDone())
+  {
+    return Standard_False;
+  }
+  //
+  typint                 = inter.TypeInter();
+  Standard_Integer NbSol = inter.NbSolutions();
+  Empty                  = Standard_False;
+
+  switch (typint)
+  {
+    case IntAna_Point:
+    {
+      gp_Pnt        psol = inter.Point(1);
+      Standard_Real U1, V1, U2, V2;
+      Quad1.Parameters(psol, U1, V1);
+      Quad2.Parameters(psol, U2, V2);
+      IntPatch_Point ptsol;
+      ptsol.SetValue(psol, TolTang, Standard_False);
+      ptsol.SetParameters(U1, V1, U2, V2);
+      spnt.Append(ptsol);
+    }
+    break;
+
+    case IntAna_Line:
+    {
+      gp_Lin linsol = inter.Line(1);
+      if (linsol.Direction().Dot(Co.Axis().Direction()) < 0.)
+      {
+        linsol.SetDirection(linsol.Direction().Reversed());
+      }
+      Standard_Real para = ElCLib::Parameter(linsol, apex);
+      gp_Pnt        ptbid(ElCLib::Value(para + 5., linsol));
+      Standard_Real U1, V1, U2, V2;
+      Quad1.Parameters(apex, U1, V1);
+      Quad2.Parameters(apex, U2, V2);
+
+      if (NbSol == 1)
+      { // ligne de tangence
+        IntPatch_Point ptsol;
+        ptsol.SetValue(apex, TolTang, Standard_False);
+        ptsol.SetParameters(U1, V1, U2, V2);
+        ptsol.SetParameter(para);
+        gp_Pnt ptbid2(apex.XYZ() + 5. * Co.Axis().Direction().XYZ());
+        gp_Vec TestCurvature(ptbid, ptbid2);
+        gp_Vec Normp, Normco;
+        if (!Reversed)
+        {
+          Normp  = Quad1.Normale(ptbid);
+          Normco = Quad2.Normale(ptbid);
+        }
+        else
+        {
+          Normp  = Quad2.Normale(ptbid);
+          Normco = Quad1.Normale(ptbid);
+        }
+        IntSurf_Situation situco, situco_otherside;
+        IntSurf_Situation situp, situp_otherside;
+
+        if (Normp.Dot(TestCurvature) > 0.)
+        {
+          situco           = IntSurf_Outside;
+          situco_otherside = IntSurf_Inside;
+          if (Normp.Dot(Normco) > 0.)
+          {
+            situp           = IntSurf_Inside;
+            situp_otherside = IntSurf_Outside;
+          }
+          else
+          {
+            situp           = IntSurf_Outside;
+            situp_otherside = IntSurf_Inside;
+          }
+        }
+        else
+        {
+          situco           = IntSurf_Inside;
+          situco_otherside = IntSurf_Outside;
+          if (Normp.Dot(Normco) > 0.)
+          {
+            situp           = IntSurf_Outside;
+            situp_otherside = IntSurf_Inside;
+          }
+          else
+          {
+            situp           = IntSurf_Inside;
+            situp_otherside = IntSurf_Outside;
+          }
+        }
+        //----------------------------------------------------------
+        //--              Apex ---> Cone.Direction
+        //--
+        Handle(IntPatch_GLine) glig;
+        if (!Reversed)
+        {
+          glig = new IntPatch_GLine(linsol, Standard_True, situp, situco);
+        }
+        else
+        {
+          glig = new IntPatch_GLine(linsol, Standard_True, situco, situp);
+        }
+        glig->AddVertex(ptsol);
+        glig->SetFirstPoint(1);
+        slin.Append(glig);
+        //----------------------------------------------------------
+        //--   -Cone.Direction <------- Apex
+        //--
+        linsol.SetDirection(linsol.Direction().Reversed());
+        if (!Reversed)
+        {
+          glig = new IntPatch_GLine(linsol, Standard_True, situp_otherside, situco_otherside);
+        }
+        else
+        {
+          glig = new IntPatch_GLine(linsol, Standard_True, situco_otherside, situp_otherside);
+        }
+        glig->AddVertex(ptsol);
+        glig->SetFirstPoint(1);
+        slin.Append(glig);
+      }
+      else
+      {
+        // on a 2 droites. Il faut determiner les transitions
+        // de chacune. On oriente chaque ligne dans le sens
+        // de l axe du cone. Les transitions de chaque ligne seront
+        // inverses l une de l autre => on ne fait le calcul que sur
+        // la premiere.
+        if (linsol.Direction().DotCross(Quad2.Normale(ptbid), Quad1.Normale(ptbid)) > 0.)
+        {
+          trans1 = IntSurf_Out;
+          trans2 = IntSurf_In;
+        }
+        else
+        {
+          trans1 = IntSurf_In;
+          trans2 = IntSurf_Out;
+        }
+
+        Multpoint = Standard_True;
+        //------------------------------------------- Ligne 1 -------
+        IntPatch_Point ptsol;
+        ptsol.SetValue(apex, TolTang, Standard_False);
+        ptsol.SetParameters(U1, V1, U2, V2);
+        ptsol.SetParameter(para);
+        ptsol.SetMultiple(Standard_True);
+        Handle(IntPatch_GLine) glig;
+        glig = new IntPatch_GLine(linsol, Standard_False, trans1, trans2);
+        glig->AddVertex(ptsol);
+        glig->SetFirstPoint(1);
+        slin.Append(glig);
+        //-----------------------------------------------------------
+        //-- Other Side : Les transitions restent les memes
+        //--    linsol -> -linsol   et Quad1(2).N -> -Quad1(2).N
+        //--
+        linsol.SetDirection(linsol.Direction().Reversed());
+        glig = new IntPatch_GLine(linsol, Standard_False, trans1, trans2);
+        para = ElCLib::Parameter(linsol, apex);
+        ptsol.SetParameter(para);
+        glig->AddVertex(ptsol);
+        glig->SetFirstPoint(1);
+        slin.Append(glig);
+
+        //------------------------------------------- Ligne 2 -------
+        linsol = inter.Line(2);
+        if (linsol.Direction().Dot(Co.Axis().Direction()) < 0.)
+        {
+          linsol.SetDirection(linsol.Direction().Reversed());
+        }
+        para  = ElCLib::Parameter(linsol, apex);
+        ptbid = ElCLib::Value(para + 5., linsol);
+        if (linsol.Direction().DotCross(Quad2.Normale(ptbid), Quad1.Normale(ptbid)) > 0.)
+        {
+          trans1 = IntSurf_Out;
+          trans2 = IntSurf_In;
+        }
+        else
+        {
+          trans1 = IntSurf_In;
+          trans2 = IntSurf_Out;
+        }
+        ptsol.SetParameter(para);
+        glig = new IntPatch_GLine(linsol, Standard_False, trans1, trans2);
+        para = ElCLib::Parameter(linsol, apex);
+        ptsol.SetParameter(para);
+        glig->AddVertex(ptsol);
+        glig->SetFirstPoint(1);
+        slin.Append(glig);
+        //-----------------------------------------------------------
+        //-- Other Side : Les transitions restent les memes
+        //--    linsol -> -linsol   et Quad1(2).N -> -Quad1(2).N
+        //--
+        linsol.SetDirection(linsol.Direction().Reversed());
+        glig = new IntPatch_GLine(linsol, Standard_False, trans1, trans2);
+        para = ElCLib::Parameter(linsol, apex);
+        ptsol.SetParameter(para);
+        glig->AddVertex(ptsol);
+        glig->SetFirstPoint(1);
+        slin.Append(glig);
+      }
+    }
+    break;
+
+    case IntAna_Circle:
+    {
+      gp_Circ cirsol = inter.Circle(1);
+      //modified by NIZNHY-PKV Thu Sep 15 11:34:04 2011f
+      AdjustToSeam(Co, cirsol);
+      //modified by NIZNHY-PKV Thu Sep 15 11:36:08 2011t
+      gp_Pnt ptref;
+      gp_Vec Tgt;
+      ElCLib::D1(0., cirsol, ptref, Tgt);
+
+      if (Tgt.DotCross(Quad2.Normale(ptref), Quad1.Normale(ptref)) > 0.)
+      {
+        trans1 = IntSurf_Out;
+        trans2 = IntSurf_In;
+      }
+      else
+      {
+        trans1 = IntSurf_In;
+        trans2 = IntSurf_Out;
+      }
+      Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol, Standard_False, trans1, trans2);
+      slin.Append(glig);
+    }
+    break;
+
+    case IntAna_Ellipse:
+    {
+      gp_Elips elipsol = inter.Ellipse(1);
+      gp_Pnt   ptref;
+      gp_Vec   Tgt;
+      ElCLib::D1(0., elipsol, ptref, Tgt);
+
+      if (Tgt.DotCross(Quad2.Normale(ptref), Quad1.Normale(ptref)) > 0.)
+      {
+        trans1 = IntSurf_Out;
+        trans2 = IntSurf_In;
+      }
+      else
+      {
+        trans1 = IntSurf_In;
+        trans2 = IntSurf_Out;
+      }
+      Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol, Standard_False, trans1, trans2);
+      slin.Append(glig);
+    }
+    break;
+
+    case IntAna_Parabola:
+    {
+      gp_Parab parabsol = inter.Parabola(1);
+
+      gp_Vec        Tgtorig(parabsol.YAxis().Direction());
+      Standard_Real ptran = Tgtorig.DotCross(Quad2.Normale(parabsol.Location()), Quad1.Normale(parabsol.Location()));
+      if (ptran > 0.00000001)
+      {
+        trans1 = IntSurf_Out;
+        trans2 = IntSurf_In;
+      }
+      else if (ptran < -0.00000001)
+      {
+        trans1 = IntSurf_In;
+        trans2 = IntSurf_Out;
+      }
+      else
+      {
+        trans1 = trans2 = IntSurf_Undecided;
+      }
+      Handle(IntPatch_GLine) glig = new IntPatch_GLine(parabsol, Standard_False, trans1, trans2);
+      slin.Append(glig);
+    }
+    break;
+
+    case IntAna_Hyperbola:
+    {
+      gp_Pnt tophypr;
+      gp_Vec Tgttop;
+
+      for (Standard_Integer i = 1; i <= 2; i++)
+      {
+        gp_Hypr hyprsol   = inter.Hyperbola(i);
+        tophypr           = ElCLib::Value(hyprsol.MajorRadius(), hyprsol.XAxis());
+        Tgttop            = hyprsol.YAxis().Direction();
+        Standard_Real qwe = Tgttop.DotCross(Quad2.Normale(tophypr), Quad1.Normale(tophypr));
+
+        if (qwe > 0.00000001)
+        {
+          trans1 = IntSurf_Out;
+          trans2 = IntSurf_In;
+        }
+        else if (qwe < -0.00000001)
+        {
+          trans1 = IntSurf_In;
+          trans2 = IntSurf_Out;
+        }
+        else
+        {
+          trans1 = trans2 = IntSurf_Undecided;
+        }
+        Handle(IntPatch_GLine) glig = new IntPatch_GLine(hyprsol, Standard_False, trans1, trans2);
+        slin.Append(glig);
+      }
+    }
+    break;
+
+    default:
+    {
+      return Standard_False;
+    }
+  }
+  return Standard_True;
+}
+//=======================================================================
+//function : IntPTo
+//purpose  :
+//=======================================================================
+Standard_Boolean IntPTo(const IntSurf_Quadric&   theQuad1,
+                        const IntSurf_Quadric&   theQuad2,
+                        const Standard_Real      theTolTang,
+                        const Standard_Boolean   bReversed,
+                        Standard_Boolean&        bEmpty,
+                        IntPatch_SequenceOfLine& theSeqLin)
+{
+  const gp_Pln   aPln   = bReversed ? theQuad2.Plane() : theQuad1.Plane();
+  const gp_Torus aTorus = bReversed ? theQuad1.Torus() : theQuad2.Torus();
+  //
+  IntAna_QuadQuadGeo inter(aPln, aTorus, theTolTang);
+  Standard_Boolean   bRet = inter.IsDone();
+  //
+  if (!bRet)
+  {
+    return bRet;
+  }
+  //
+  IntAna_ResultType typint = inter.TypeInter();
+  Standard_Integer  NbSol  = inter.NbSolutions();
+  bEmpty                   = Standard_False;
+  //
+  switch (typint)
+  {
+    case IntAna_Empty: bEmpty = Standard_True; break;
+    //
+    case IntAna_Circle:
+    {
+      Standard_Integer  i;
+      IntSurf_TypeTrans trans1, trans2;
+      gp_Pnt            ptref;
+      gp_Vec            Tgt;
+      //
+      for (i = 1; i <= NbSol; ++i)
+      {
+        gp_Circ aC = inter.Circle(i);
+        if (!aPln.Axis().IsNormal(aTorus.Axis(), Precision::Angular()))
+        {
+          AdjustToSeam(aTorus, aC);
+        }
+        ElCLib::D1(0., aC, ptref, Tgt);
+        //
+        if (Tgt.DotCross(theQuad2.Normale(ptref), theQuad1.Normale(ptref)) > 0.0)
+        {
+          trans1 = IntSurf_Out;
+          trans2 = IntSurf_In;
+        }
+        else
+        {
+          trans1 = IntSurf_In;
+          trans2 = IntSurf_Out;
+        }
+        //
+        Handle(IntPatch_GLine) glig = new IntPatch_GLine(aC, Standard_False, trans1, trans2);
+        theSeqLin.Append(glig);
+      }
+    }
+    break;
+    //
+    case IntAna_NoGeometricSolution:
+    default: bRet = Standard_False; break;
+  }
+  //
+  return bRet;
+}
+//
+//modified by NIZNHY-PKV Thu Sep 15 10:53:39 2011f
+//=======================================================================
+//function : AdjustToSeam
+//purpose  :
+//=======================================================================
+void AdjustToSeam(const gp_Cone& aQuad, gp_Circ& aCirc)
+{
+  gp_Ax2 aAx2;
+  //
+  const gp_Pnt& aPLoc = aCirc.Location();
+  const gp_Ax3& aAx3  = aQuad.Position();
+  SeamPosition(aPLoc, aAx3, aAx2);
+  aCirc.SetPosition(aAx2);
+}
+//=======================================================================
+//function : AdjustToSeam
+//purpose  :
+//=======================================================================
+void AdjustToSeam(const gp_Sphere& aQuad, gp_Circ& aCirc, const Standard_Real aTolAng)
+{
+  gp_Ax2 aAx2;
+  //
+  const gp_Ax1& aAx1C = aCirc.Axis();
+  const gp_Ax3& aAx3  = aQuad.Position();
+  const gp_Ax1& aAx1Q = aAx3.Axis();
+  //
+  const gp_Dir& aDirC = aAx1C.Direction();
+  const gp_Dir& aDirQ = aAx1Q.Direction();
+  if (aDirC.IsParallel(aDirQ, aTolAng))
+  {
+    const gp_Pnt& aPLoc = aCirc.Location();
+    SeamPosition(aPLoc, aAx3, aAx2);
+    aCirc.SetPosition(aAx2);
+  }
+}
+//=======================================================================
+//function : AdjustToSeam
+//purpose  :
+//=======================================================================
+void AdjustToSeam(const gp_Cylinder& aQuad, gp_Circ& aCirc)
+{
+  gp_Ax2 aAx2;
+  //
+  const gp_Pnt& aPLoc = aCirc.Location();
+  const gp_Ax3& aAx3  = aQuad.Position();
+  SeamPosition(aPLoc, aAx3, aAx2);
+  aCirc.SetPosition(aAx2);
+}
+//=======================================================================
+//function : AdjustToSeam
+//purpose  :
+//=======================================================================
+void AdjustToSeam(const gp_Torus& aQuad, gp_Circ& aCirc)
+{
+  gp_Ax2 aAx2;
+  //
+  const gp_Pnt& aPLoc = aCirc.Location();
+  const gp_Ax3& aAx3  = aQuad.Position();
+  SeamPosition(aPLoc, aAx3, aAx2);
+  aCirc.SetPosition(aAx2);
+}
+//=======================================================================
+//function : SeamPosition
+//purpose  :
+//=======================================================================
+void SeamPosition(const gp_Pnt& aPLoc, const gp_Ax3& aPos, gp_Ax2& aSeamPos)
+{
+  const gp_Dir& aDZ = aPos.Direction();
+  const gp_Dir& aDX = aPos.XDirection();
+  gp_Ax2        aAx2(aPLoc, aDZ, aDX);
+  aSeamPos = aAx2;
+}
+
+//modified by NIZNHY-PKV Thu Sep 15 10:53:41 2011t
+
+//If Abs(a) <= aNulValue then it is considered that a = 0.
+static const Standard_Real aNulValue = 1.0e-11;
+
+static void ShortCosForm(const Standard_Real theCosFactor,
+                         const Standard_Real theSinFactor,
+                         Standard_Real&      theCoeff,
+                         Standard_Real&      theAngle);
+//
+static Standard_Boolean ExploreCurve(const gp_Cone& theCo, IntAna_Curve& aC, const Standard_Real aTol, IntAna_ListOfCurve& aLC);
+
+static Standard_Boolean InscribePoint(const Standard_Real    theUfTarget,
+                                      const Standard_Real    theUlTarget,
+                                      Standard_Real&         theUGiven,
+                                      const Standard_Real    theTol2D,
+                                      const Standard_Real    thePeriod,
+                                      const Standard_Boolean theFlForce);
+
+class ComputationMethods
+{
+  //Every cylinder can be represented by the following equation in parametric form:
+  //    S(U,V) = L + R*cos(U)*Xd+R*sin(U)*Yd+V*Zd,
+  //where location L, directions Xd, Yd and Zd have type gp_XYZ.
+
+  //Intersection points between two cylinders can be found from the following system:
+  //    S1(U1, V1) = S2(U2, V2)
+  //or
+  //    {X01 + R1*cos(U1)*Xx1 + R1*sin(U1)*Yx1 + V1*Zx1 = X02 + R2*cos(U2)*Xx2 + R2*sin(U2)*Yx2 + V2*Zx2
+  //    {Y01 + R1*cos(U1)*Xy1 + R1*sin(U1)*Yy1 + V1*Zy1 = Y02 + R2*cos(U2)*Xy2 + R2*sin(U2)*Yy2 + V2*Zy2   (1)
+  //    {Z01 + R1*cos(U1)*Xz1 + R1*sin(U1)*Yz1 + V1*Zz1 = Z02 + R2*cos(U2)*Xz2 + R2*sin(U2)*Yz2 + V2*Zz2
+
+  //The formula (1) can be rewritten as follows
+  //    {C11*V1+C21*V2=A11*cos(U1)+B11*sin(U1)+A21*cos(U2)+B21*sin(U2)+D1
+  //    {C12*V1+C22*V2=A12*cos(U1)+B12*sin(U1)+A22*cos(U2)+B22*sin(U2)+D2                                   (2)
+  //    {C13*V1+C23*V2=A13*cos(U1)+B13*sin(U1)+A23*cos(U2)+B23*sin(U2)+D3
+
+  //Hereafter we consider that in system
+  //    {C11*V1+C21*V2=A11*cos(U1)+B11*sin(U1)+A21*cos(U2)+B21*sin(U2)+D1                                   (3)
+  //    {C12*V1+C22*V2=A12*cos(U1)+B12*sin(U1)+A22*cos(U2)+B22*sin(U2)+D2
+  //variables V1 and V2 can be found unambiguously, i.e. determinant
+  //            |C11 C21|
+  //            |       | != 0
+  //            |C12 C22|
+  //
+  //In this case, variables V1 and V2 can be found as follows:
+  //    {V1 = K11*sin(U1)+K21*sin(U2)+L11*cos(U1)+L21*cos(U2)+M1 = K1*cos(U1-FIV1)+L1*cos(U2-PSIV1)+M1      (4)
+  //    {V2 = K12*sin(U1)+K22*sin(U2)+L12*cos(U1)+L22*cos(U2)+M2 = K2*cos(U2-FIV2)+L2*cos(U2-PSIV2)+M2
+
+  //Having substituted result of (4) to the 3rd equation of (2), we will obtain equation
+  //    cos(U2-FI2) = B*cos(U1-FI1)+C.                                                                      (5)
+
+  //I.e. when U1 is taken different given values (from domain), correspond U2 value can be computed
+  //from equation (5). After that, V1 and V2 can be computed from the system (4) (see
+  //CylCylComputeParameters(...) methods).
+
+  //It is important to remark that equation (5) (in general) has two solutions: U2=FI2 +/- f(U1).
+  //Therefore, we are getting here two intersection lines.
+
+public:
+  //Stores equations coefficients
+  struct stCoeffsValue
+  {
+    stCoeffsValue(const gp_Cylinder&, const gp_Cylinder&);
+
+    math_Vector mVecA1;
+    math_Vector mVecA2;
+    math_Vector mVecB1;
+    math_Vector mVecB2;
+    math_Vector mVecC1;
+    math_Vector mVecC2;
+    math_Vector mVecD;
+
+    Standard_Real mK21; //sinU2
+    Standard_Real mK11; //sinU1
+    Standard_Real mL21; //cosU2
+    Standard_Real mL11; //cosU1
+    Standard_Real mM1;  //Free member
+
+    Standard_Real mK22; //sinU2
+    Standard_Real mK12; //sinU1
+    Standard_Real mL22; //cosU2
+    Standard_Real mL12; //cosU1
+    Standard_Real mM2;  //Free member
+
+    Standard_Real mK1;
+    Standard_Real mL1;
+    Standard_Real mK2;
+    Standard_Real mL2;
+
+    Standard_Real mFIV1;
+    Standard_Real mPSIV1;
+    Standard_Real mFIV2;
+    Standard_Real mPSIV2;
+
+    Standard_Real mB;
+    Standard_Real mC;
+    Standard_Real mFI1;
+    Standard_Real mFI2;
+  };
+
+  //! Determines, if U2(U1) function is increasing.
+  static Standard_Boolean CylCylMonotonicity(const Standard_Real    theU1par,
+                                             const Standard_Integer theWLIndex,
+                                             const stCoeffsValue&   theCoeffs,
+                                             const Standard_Real    thePeriod,
+                                             Standard_Boolean&      theIsIncreasing);
+
+  //! Computes U2 (U-parameter of the 2nd cylinder) and, if theDelta != 0,
+  //! esimates the tolerance of U2-computing (estimation result is
+  //! assigned to *theDelta value).
+  static Standard_Boolean CylCylComputeParameters(const Standard_Real    theU1par,
+                                                  const Standard_Integer theWLIndex,
+                                                  const stCoeffsValue&   theCoeffs,
+                                                  Standard_Real&         theU2,
+                                                  Standard_Real* const   theDelta = 0);
+
+  static Standard_Boolean CylCylComputeParameters(const Standard_Real  theU1,
+                                                  const Standard_Real  theU2,
+                                                  const stCoeffsValue& theCoeffs,
+                                                  Standard_Real&       theV1,
+                                                  Standard_Real&       theV2);
+
+  static Standard_Boolean CylCylComputeParameters(const Standard_Real    theU1par,
+                                                  const Standard_Integer theWLIndex,
+                                                  const stCoeffsValue&   theCoeffs,
+                                                  Standard_Real&         theU2,
+                                                  Standard_Real&         theV1,
+                                                  Standard_Real&         theV2);
+};
+
+ComputationMethods::stCoeffsValue::stCoeffsValue(const gp_Cylinder& theCyl1, const gp_Cylinder& theCyl2)
+: mVecA1(-theCyl1.Radius() * theCyl1.XAxis().Direction().XYZ()),
+  mVecA2(theCyl2.Radius() * theCyl2.XAxis().Direction().XYZ()),
+  mVecB1(-theCyl1.Radius() * theCyl1.YAxis().Direction().XYZ()),
+  mVecB2(theCyl2.Radius() * theCyl2.YAxis().Direction().XYZ()),
+  mVecC1(theCyl1.Axis().Direction().XYZ()),
+  mVecC2(theCyl2.Axis().Direction().XYZ().Reversed()),
+  mVecD(theCyl2.Location().XYZ() - theCyl1.Location().XYZ())
+{
+  enum CoupleOfEquation
+  {
+    COENONE = 0,
+    COE12   = 1,
+    COE23   = 2,
+    COE13   = 3
+  } aFoundCouple              = COENONE;
+
+  Standard_Real aDetV1V2      = 0.0;
+
+  const Standard_Real aDelta1 = mVecC1(1) * mVecC2(2) - mVecC1(2) * mVecC2(1); //1-2
+  const Standard_Real aDelta2 = mVecC1(2) * mVecC2(3) - mVecC1(3) * mVecC2(2); //2-3
+  const Standard_Real aDelta3 = mVecC1(1) * mVecC2(3) - mVecC1(3) * mVecC2(1); //1-3
+  const Standard_Real anAbsD1 = Abs(aDelta1);                                  //1-2
+  const Standard_Real anAbsD2 = Abs(aDelta2);                                  //2-3
+  const Standard_Real anAbsD3 = Abs(aDelta3);                                  //1-3
+
+  if (anAbsD1 >= anAbsD2)
+  {
+    if (anAbsD3 > anAbsD1)
+    {
+      aFoundCouple = COE13;
+      aDetV1V2     = aDelta3;
+    }
+    else
+    {
+      aFoundCouple = COE12;
+      aDetV1V2     = aDelta1;
+    }
+  }
+  else
+  {
+    if (anAbsD3 > anAbsD2)
+    {
+      aFoundCouple = COE13;
+      aDetV1V2     = aDelta3;
+    }
+    else
+    {
+      aFoundCouple = COE23;
+      aDetV1V2     = aDelta2;
+    }
+  }
+
+  // In point of fact, every determinant (aDelta1, aDelta2 and aDelta3) is
+  // cross-product between directions (i.e. sine of angle).
+  // If sine is too small then sine is (approx.) equal to angle itself.
+  // Therefore, in this case we should compare sine with angular tolerance.
+  // This constant is used for check if axes are parallel (see constructor
+  // AxeOperator::AxeOperator(...) in IntAna_QuadQuadGeo.cxx file).
+  if (Abs(aDetV1V2) < Precision::Angular())
+  {
+    throw Standard_Failure("Error. Exception in divide by zerro (IntCyCyTrim)!!!!");
+  }
+
+  switch (aFoundCouple)
+  {
+    case COE12: break;
+    case COE23:
+    {
+      math_Vector aVTemp(mVecA1);
+      mVecA1(1) = aVTemp(2);
+      mVecA1(2) = aVTemp(3);
+      mVecA1(3) = aVTemp(1);
+
+      aVTemp    = mVecA2;
+      mVecA2(1) = aVTemp(2);
+      mVecA2(2) = aVTemp(3);
+      mVecA2(3) = aVTemp(1);
+
+      aVTemp    = mVecB1;
+      mVecB1(1) = aVTemp(2);
+      mVecB1(2) = aVTemp(3);
+      mVecB1(3) = aVTemp(1);
+
+      aVTemp    = mVecB2;
+      mVecB2(1) = aVTemp(2);
+      mVecB2(2) = aVTemp(3);
+      mVecB2(3) = aVTemp(1);
+
+      aVTemp    = mVecC1;
+      mVecC1(1) = aVTemp(2);
+      mVecC1(2) = aVTemp(3);
+      mVecC1(3) = aVTemp(1);
+
+      aVTemp    = mVecC2;
+      mVecC2(1) = aVTemp(2);
+      mVecC2(2) = aVTemp(3);
+      mVecC2(3) = aVTemp(1);
+
+      aVTemp    = mVecD;
+      mVecD(1)  = aVTemp(2);
+      mVecD(2)  = aVTemp(3);
+      mVecD(3)  = aVTemp(1);
+
+      break;
+    }
+    case COE13:
+    {
+      math_Vector aVTemp = mVecA1;
+      mVecA1(2)          = aVTemp(3);
+      mVecA1(3)          = aVTemp(2);
+
+      aVTemp             = mVecA2;
+      mVecA2(2)          = aVTemp(3);
+      mVecA2(3)          = aVTemp(2);
+
+      aVTemp             = mVecB1;
+      mVecB1(2)          = aVTemp(3);
+      mVecB1(3)          = aVTemp(2);
+
+      aVTemp             = mVecB2;
+      mVecB2(2)          = aVTemp(3);
+      mVecB2(3)          = aVTemp(2);
+
+      aVTemp             = mVecC1;
+      mVecC1(2)          = aVTemp(3);
+      mVecC1(3)          = aVTemp(2);
+
+      aVTemp             = mVecC2;
+      mVecC2(2)          = aVTemp(3);
+      mVecC2(3)          = aVTemp(2);
+
+      aVTemp             = mVecD;
+      mVecD(2)           = aVTemp(3);
+      mVecD(3)           = aVTemp(2);
+
+      break;
+    }
+    default: break;
+  }
+
+  //------- For V1 (begin)
+  //sinU2
+  mK21 = (mVecC2(2) * mVecB2(1) - mVecC2(1) * mVecB2(2)) / aDetV1V2;
+  //sinU1
+  mK11 = (mVecC2(2) * mVecB1(1) - mVecC2(1) * mVecB1(2)) / aDetV1V2;
+  //cosU2
+  mL21 = (mVecC2(2) * mVecA2(1) - mVecC2(1) * mVecA2(2)) / aDetV1V2;
+  //cosU1
+  mL11 = (mVecC2(2) * mVecA1(1) - mVecC2(1) * mVecA1(2)) / aDetV1V2;
+  //Free member
+  mM1  = (mVecC2(2) * mVecD(1) - mVecC2(1) * mVecD(2)) / aDetV1V2;
+  //------- For V1 (end)
+
+  //------- For V2 (begin)
+  //sinU2
+  mK22 = (mVecC1(1) * mVecB2(2) - mVecC1(2) * mVecB2(1)) / aDetV1V2;
+  //sinU1
+  mK12 = (mVecC1(1) * mVecB1(2) - mVecC1(2) * mVecB1(1)) / aDetV1V2;
+  //cosU2
+  mL22 = (mVecC1(1) * mVecA2(2) - mVecC1(2) * mVecA2(1)) / aDetV1V2;
+  //cosU1
+  mL12 = (mVecC1(1) * mVecA1(2) - mVecC1(2) * mVecA1(1)) / aDetV1V2;
+  //Free member
+  mM2  = (mVecC1(1) * mVecD(2) - mVecC1(2) * mVecD(1)) / aDetV1V2;
+  //------- For V1 (end)
+
+  ShortCosForm(mL11, mK11, mK1, mFIV1);
+  ShortCosForm(mL21, mK21, mL1, mPSIV1);
+  ShortCosForm(mL12, mK12, mK2, mFIV2);
+  ShortCosForm(mL22, mK22, mL2, mPSIV2);
+
+  const Standard_Real aA1 = mVecC1(3) * mK21 + mVecC2(3) * mK22 - mVecB2(3), //sinU2
+    aA2                   = mVecC1(3) * mL21 + mVecC2(3) * mL22 - mVecA2(3), //cosU2
+    aB1                   = mVecB1(3) - mVecC1(3) * mK11 - mVecC2(3) * mK12, //sinU1
+    aB2                   = mVecA1(3) - mVecC1(3) * mL11 - mVecC2(3) * mL12; //cosU1
+
+  mC                      = mVecD(3) - mVecC1(3) * mM1 - mVecC2(3) * mM2; //Free
+
+  Standard_Real aA        = 0.0;
+
+  ShortCosForm(aB2, aB1, mB, mFI1);
+  ShortCosForm(aA2, aA1, aA, mFI2);
+
+  mB /= aA;
+  mC /= aA;
+}
+
+class WorkWithBoundaries
+{
+public:
+  enum SearchBoundType
+  {
+    SearchNONE = 0,
+    SearchV1   = 1,
+    SearchV2   = 2
+  };
+
+  struct StPInfo
+  {
+    StPInfo()
+    {
+      mySurfID = 0;
+      myU1     = RealLast();
+      myV1     = RealLast();
+      myU2     = RealLast();
+      myV2     = RealLast();
+    }
+
+    //Equal to 0 for 1st surface non-zero for 2nd one.
+    Standard_Integer mySurfID;
+
+    Standard_Real myU1;
+    Standard_Real myV1;
+    Standard_Real myU2;
+    Standard_Real myV2;
+
+    bool operator>(const StPInfo& theOther) const { return myU1 > theOther.myU1; }
+
+    bool operator<(const StPInfo& theOther) const { return myU1 < theOther.myU1; }
+
+    bool operator==(const StPInfo& theOther) const { return myU1 == theOther.myU1; }
+  };
+
+  WorkWithBoundaries(const IntSurf_Quadric&                   theQuad1,
+                     const IntSurf_Quadric&                   theQuad2,
+                     const ComputationMethods::stCoeffsValue& theCoeffs,
+                     const Bnd_Box2d&                         theUVSurf1,
+                     const Bnd_Box2d&                         theUVSurf2,
+                     const Standard_Integer                   theNbWLines,
+                     const Standard_Real                      thePeriod,
+                     const Standard_Real                      theTol3D,
+                     const Standard_Real                      theTol2D,
+                     const Standard_Boolean                   isTheReverse)
+  : myQuad1(theQuad1),
+    myQuad2(theQuad2),
+    myCoeffs(theCoeffs),
+    myUVSurf1(theUVSurf1),
+    myUVSurf2(theUVSurf2),
+    myNbWLines(theNbWLines),
+    myPeriod(thePeriod),
+    myTol3D(theTol3D),
+    myTol2D(theTol2D),
+    myIsReverse(isTheReverse) {};
+
+  // Returns parameters of system solved while finding
+  // intersection line
+  const ComputationMethods::stCoeffsValue& SICoeffs() const { return myCoeffs; }
+
+  // Returns quadric correspond to the index theIdx.
+  const IntSurf_Quadric& GetQSurface(const Standard_Integer theIdx) const
+  {
+    if (theIdx <= 1)
+      return myQuad1;
+
+    return myQuad2;
+  }
+
+  // Returns TRUE in case of reverting surfaces
+  Standard_Boolean IsReversed() const { return myIsReverse; }
+
+  // Returns 2D-tolerance
+  Standard_Real Get2dTolerance() const { return myTol2D; }
+
+  // Returns 3D-tolerance
+  Standard_Real Get3dTolerance() const { return myTol3D; }
+
+  // Returns UV-bounds of 1st surface
+  const Bnd_Box2d& UVS1() const { return myUVSurf1; }
+
+  // Returns UV-bounds of 2nd surface
+  const Bnd_Box2d& UVS2() const { return myUVSurf2; }
+
+  void AddBoundaryPoint(const Handle(IntPatch_WLine)& theWL,
+                        const Standard_Real           theU1,
+                        const Standard_Real           theU1Min,
+                        const Standard_Real           theU2,
+                        const Standard_Real           theV1,
+                        const Standard_Real           theV1Prev,
+                        const Standard_Real           theV2,
+                        const Standard_Real           theV2Prev,
+                        const Standard_Integer        theWLIndex,
+                        const Standard_Boolean        theFlForce,
+                        Standard_Boolean&             isTheFound1,
+                        Standard_Boolean&             isTheFound2) const;
+
+  static Standard_Boolean BoundariesComputing(const ComputationMethods::stCoeffsValue& theCoeffs,
+                                              const Standard_Real                      thePeriod,
+                                              Bnd_Range                                theURange[]);
+
+  void BoundaryEstimation(const gp_Cylinder& theCy1,
+                          const gp_Cylinder& theCy2,
+                          Bnd_Range&         theOutBoxS1,
+                          Bnd_Range&         theOutBoxS2) const;
+
+protected:
+  //Solves equation (2) (see declaration of ComputationMethods class) in case,
+  //when V1 or V2 (is set by theSBType argument) is known (corresponds to the boundary
+  //and equal to theVzad) but U1 is unknown. Computation is made by numeric methods and
+  //requires initial values (theVInit, theInitU2 and theInitMainVar).
+  Standard_Boolean SearchOnVBounds(const SearchBoundType theSBType,
+                                   const Standard_Real   theVzad,
+                                   const Standard_Real   theVInit,
+                                   const Standard_Real   theInitU2,
+                                   const Standard_Real   theInitMainVar,
+                                   Standard_Real&        theMainVariableValue) const;
+
+  const WorkWithBoundaries& operator=(const WorkWithBoundaries&);
+
+private:
+  friend class ComputationMethods;
+
+  const IntSurf_Quadric&                   myQuad1;
+  const IntSurf_Quadric&                   myQuad2;
+  const ComputationMethods::stCoeffsValue& myCoeffs;
+  const Bnd_Box2d&                         myUVSurf1;
+  const Bnd_Box2d&                         myUVSurf2;
+  const Standard_Integer                   myNbWLines;
+  const Standard_Real                      myPeriod;
+  const Standard_Real                      myTol3D;
+  const Standard_Real                      myTol2D;
+  const Standard_Boolean                   myIsReverse;
+};
+
+static void SeekAdditionalPoints(const IntSurf_Quadric&                   theQuad1,
+                                 const IntSurf_Quadric&                   theQuad2,
+                                 const Handle(IntSurf_LineOn2S)&          theLine,
+                                 const ComputationMethods::stCoeffsValue& theCoeffs,
+                                 const Standard_Integer                   theWLIndex,
+                                 const Standard_Integer                   theMinNbPoints,
+                                 const Standard_Integer                   theStartPointOnLine,
+                                 const Standard_Integer                   theEndPointOnLine,
+                                 const Standard_Real                      theTol2D,
+                                 const Standard_Real                      thePeriodOfSurf2,
+                                 const Standard_Boolean                   isTheReverse);
+
+//=======================================================================
+//function : MinMax
+//purpose  : Replaces theParMIN = MIN(theParMIN, theParMAX),
+//                    theParMAX = MAX(theParMIN, theParMAX).
+//=======================================================================
+static inline void MinMax(Standard_Real& theParMIN, Standard_Real& theParMAX)
+{
+  if (theParMIN > theParMAX)
+  {
+    const Standard_Real aux = theParMAX;
+    theParMAX               = theParMIN;
+    theParMIN               = aux;
+  }
+}
+
+//=======================================================================
+//function : ExtremaLineLine
+//purpose  : Computes extrema between the given lines. Returns parameters
+//          on correspond curve (see correspond method for Extrema_ExtElC class).
+//=======================================================================
+static inline void ExtremaLineLine(const gp_Ax1&       theC1,
+                                   const gp_Ax1&       theC2,
+                                   const Standard_Real theCosA,
+                                   const Standard_Real theSqSinA,
+                                   Standard_Real&      thePar1,
+                                   Standard_Real&      thePar2)
+{
+  const gp_Dir &aD1 = theC1.Direction(), &aD2 = theC2.Direction();
+
+  const gp_XYZ        aL1L2 = theC2.Location().XYZ() - theC1.Location().XYZ();
+  const Standard_Real aD1L = aD1.XYZ().Dot(aL1L2), aD2L = aD2.XYZ().Dot(aL1L2);
+
+  thePar1 = (aD1L - theCosA * aD2L) / theSqSinA;
+  thePar2 = (theCosA * aD1L - aD2L) / theSqSinA;
+}
+
+//=======================================================================
+//function : VBoundaryPrecise
+//purpose  : By default, we shall consider, that V1 and V2 will be increased
+//            if U1 is increased. But if it is not, new V1set and/or V2set
+//            must be computed as [V1current - DeltaV1] (analogically
+//            for V2). This function processes this case.
+//=======================================================================
+static void VBoundaryPrecise(const math_Matrix&  theMatr,
+                             const Standard_Real theV1AfterDecrByDelta,
+                             const Standard_Real theV2AfterDecrByDelta,
+                             Standard_Real&      theV1Set,
+                             Standard_Real&      theV2Set)
+{
+  //Now we are going to define if V1 (and V2) increases
+  //(or decreases) when U1 will increase.
+  const Standard_Integer aNbDim = 3;
+  math_Matrix            aSyst(1, aNbDim, 1, aNbDim);
+
+  aSyst.SetCol(1, theMatr.Col(1));
+  aSyst.SetCol(2, theMatr.Col(2));
+  aSyst.SetCol(3, theMatr.Col(4));
+
+  //We have the system (see comment to StepComputing(...) function)
+  //    {a11*dV1 + a12*dV2 + a14*dU2 = -a13*dU1
+  //    {a21*dV1 + a22*dV2 + a24*dU2 = -a23*dU1
+  //    {a31*dV1 + a32*dV2 + a34*dU2 = -a33*dU1
+
+  const Standard_Real aDet = aSyst.Determinant();
+
+  aSyst.SetCol(1, theMatr.Col(3));
+  const Standard_Real aDet1 = aSyst.Determinant();
+
+  aSyst.SetCol(1, theMatr.Col(1));
+  aSyst.SetCol(2, theMatr.Col(3));
+
+  const Standard_Real aDet2 = aSyst.Determinant();
+
+  //Now,
+  //    dV1 = -dU1*aDet1/aDet
+  //    dV2 = -dU1*aDet2/aDet
+
+  //If U1 is increased then dU1 > 0.
+  //If (aDet1/aDet > 0) then dV1 < 0 and
+  //V1 will be decreased after increasing U1.
+
+  //We have analogical situation with V2-parameter.
+
+  if (aDet * aDet1 > 0.0)
+  {
+    theV1Set = theV1AfterDecrByDelta;
+  }
+
+  if (aDet * aDet2 > 0.0)
+  {
+    theV2Set = theV2AfterDecrByDelta;
+  }
+}
+
+//=======================================================================
+//function : DeltaU1Computing
+//purpose  : Computes new step for U1 parameter.
+//=======================================================================
+static inline Standard_Boolean DeltaU1Computing(const math_Matrix& theSyst,
+                                                const math_Vector& theFree,
+                                                Standard_Real&     theDeltaU1Found)
+{
+  Standard_Real aDet = theSyst.Determinant();
+
+  if (Abs(aDet) > aNulValue)
+  {
+    math_Matrix aSyst1(theSyst);
+    aSyst1.SetCol(2, theFree);
+
+    theDeltaU1Found = Abs(aSyst1.Determinant() / aDet);
+    return Standard_True;
+  }
+
+  return Standard_False;
+}
+
+//=======================================================================
+//function : StepComputing
+//purpose  :
+//
+//Attention!!!:
+//            theMatr must have 3*5-dimension strictly.
+//            For system
+//                {a11*V1+a12*V2+a13*dU1+a14*dU2=b1;
+//                {a21*V1+a22*V2+a23*dU1+a24*dU2=b2;
+//                {a31*V1+a32*V2+a33*dU1+a34*dU2=b3;
+//            theMatr must be following:
+//                (a11 a12 a13 a14 b1)
+//                (a21 a22 a23 a24 b2)
+//                (a31 a32 a33 a34 b3)
+//=======================================================================
+static Standard_Boolean StepComputing(const math_Matrix& theMatr,
+                                      const Standard_Real theV1Cur,
+                                      const Standard_Real theV2Cur,
+                                      const Standard_Real theDeltaV1,
+                                      const Standard_Real theDeltaV2,
+                                      Standard_Real& theDeltaU1Found/*,
+                                      Standard_Real& theDeltaU2Found,
+                                      Standard_Real& theV1Found,
+                                      Standard_Real& theV2Found*/)
+{
+#ifdef INTPATCH_IMPIMPINTERSECTION_DEBUG
+  bool flShow = false;
+
+  if (flShow)
+  {
+    printf("{%+10.20f*V1 + %+10.20f*V2 + %+10.20f*dU1 + %+10.20f*dU2 = %+10.20f\n",
+           theMatr(1, 1),
+           theMatr(1, 2),
+           theMatr(1, 3),
+           theMatr(1, 4),
+           theMatr(1, 5));
+    printf("{%+10.20f*V1 + %+10.20f*V2 + %+10.20f*dU1 + %+10.20f*dU2 = %+10.20f\n",
+           theMatr(2, 1),
+           theMatr(2, 2),
+           theMatr(2, 3),
+           theMatr(2, 4),
+           theMatr(2, 5));
+    printf("{%+10.20f*V1 + %+10.20f*V2 + %+10.20f*dU1 + %+10.20f*dU2 = %+10.20f\n",
+           theMatr(3, 1),
+           theMatr(3, 2),
+           theMatr(3, 3),
+           theMatr(3, 4),
+           theMatr(3, 5));
+  }
+#endif
+
+  Standard_Boolean isSuccess             = Standard_False;
+  theDeltaU1Found /* = theDeltaU2Found*/ = RealLast();
+  //theV1Found = theV1set;
+  //theV2Found = theV2Set;
+  const Standard_Integer aNbDim          = 3;
+
+  math_Matrix aSyst(1, aNbDim, 1, aNbDim);
+  math_Vector aFree(1, aNbDim);
+
+  //By default, increasing V1(U1) and V2(U1) functions is
+  //considered
+  Standard_Real aV1Set = theV1Cur + theDeltaV1, aV2Set = theV2Cur + theDeltaV2;
+
+  //However, what is indeed?
+  VBoundaryPrecise(theMatr, theV1Cur - theDeltaV1, theV2Cur - theDeltaV2, aV1Set, aV2Set);
+
+  aSyst.SetCol(2, theMatr.Col(3));
+  aSyst.SetCol(3, theMatr.Col(4));
+
+  for (Standard_Integer i = 0; i < 2; i++)
+  {
+    if (i == 0)
+    { //V1 is known
+      aSyst.SetCol(1, theMatr.Col(2));
+      aFree.Set(1, aNbDim, theMatr.Col(5) - aV1Set * theMatr.Col(1));
+    }
+    else
+    { //i==1 => V2 is known
+      aSyst.SetCol(1, theMatr.Col(1));
+      aFree.Set(1, aNbDim, theMatr.Col(5) - aV2Set * theMatr.Col(2));
+    }
+
+    Standard_Real aNewDU = theDeltaU1Found;
+    if (DeltaU1Computing(aSyst, aFree, aNewDU))
+    {
+      isSuccess = Standard_True;
+      if (aNewDU < theDeltaU1Found)
+      {
+        theDeltaU1Found = aNewDU;
+      }
+    }
+  }
+
+  if (!isSuccess)
+  {
+    aFree = theMatr.Col(5) - aV1Set * theMatr.Col(1) - aV2Set * theMatr.Col(2);
+    math_Matrix aSyst1(1, aNbDim, 1, 2);
+    aSyst1.SetCol(1, aSyst.Col(2));
+    aSyst1.SetCol(2, aSyst.Col(3));
+
+    //Now we have overdetermined system.
+
+    const Standard_Real aDet1   = theMatr(1, 3) * theMatr(2, 4) - theMatr(2, 3) * theMatr(1, 4);
+    const Standard_Real aDet2   = theMatr(1, 3) * theMatr(3, 4) - theMatr(3, 3) * theMatr(1, 4);
+    const Standard_Real aDet3   = theMatr(2, 3) * theMatr(3, 4) - theMatr(3, 3) * theMatr(2, 4);
+    const Standard_Real anAbsD1 = Abs(aDet1);
+    const Standard_Real anAbsD2 = Abs(aDet2);
+    const Standard_Real anAbsD3 = Abs(aDet3);
+
+    if (anAbsD1 >= anAbsD2)
+    {
+      if (anAbsD1 >= anAbsD3)
+      {
+        //Det1
+        if (anAbsD1 <= aNulValue)
+          return isSuccess;
+
+        theDeltaU1Found = Abs(aFree(1) * theMatr(2, 4) - aFree(2) * theMatr(1, 4)) / anAbsD1;
+        isSuccess       = Standard_True;
+      }
+      else
+      {
+        //Det3
+        if (anAbsD3 <= aNulValue)
+          return isSuccess;
+
+        theDeltaU1Found = Abs(aFree(2) * theMatr(3, 4) - aFree(3) * theMatr(2, 4)) / anAbsD3;
+        isSuccess       = Standard_True;
+      }
+    }
+    else
+    {
+      if (anAbsD2 >= anAbsD3)
+      {
+        //Det2
+        if (anAbsD2 <= aNulValue)
+          return isSuccess;
+
+        theDeltaU1Found = Abs(aFree(1) * theMatr(3, 4) - aFree(3) * theMatr(1, 4)) / anAbsD2;
+        isSuccess       = Standard_True;
+      }
+      else
+      {
+        //Det3
+        if (anAbsD3 <= aNulValue)
+          return isSuccess;
+
+        theDeltaU1Found = Abs(aFree(2) * theMatr(3, 4) - aFree(3) * theMatr(2, 4)) / anAbsD3;
+        isSuccess       = Standard_True;
+      }
+    }
+  }
+
+  return isSuccess;
+}
+
+//=======================================================================
+//function : ProcessBounds
+//purpose  :
+//=======================================================================
+void ProcessBounds(const Handle(IntPatch_ALine)&  alig, //-- ligne courante
+                   const IntPatch_SequenceOfLine& slin,
+                   const IntSurf_Quadric&         Quad1,
+                   const IntSurf_Quadric&         Quad2,
+                   Standard_Boolean&              procf,
+                   const gp_Pnt&                  ptf,   //-- Debut Ligne Courante
+                   const Standard_Real            first, //-- Paramf
+                   Standard_Boolean&              procl,
+                   const gp_Pnt&                  ptl,  //-- Fin Ligne courante
+                   const Standard_Real            last, //-- Paraml
+                   Standard_Boolean&              Multpoint,
+                   const Standard_Real            Tol)
+{
+  Standard_Integer j, k;
+  Standard_Real    U1, V1, U2, V2;
+  IntPatch_Point   ptsol;
+  Standard_Real    d;
+
+  if (procf && procl)
+  {
+    j = slin.Length() + 1;
+  }
+  else
+  {
+    j = 1;
+  }
+
+  //-- On prend les lignes deja enregistrees
+
+  while (j <= slin.Length())
+  {
+    if (slin.Value(j)->ArcType() == IntPatch_Analytic)
+    {
+      const Handle(IntPatch_ALine)& aligold = *((Handle(IntPatch_ALine)*)&slin.Value(j));
+      k                                     = 1;
+
+      //-- On prend les vertex des lignes deja enregistrees
+
+      while (k <= aligold->NbVertex())
+      {
+        ptsol = aligold->Vertex(k);
+        if (!procf)
+        {
+          d = ptf.Distance(ptsol.Value());
+          if (d <= Tol)
+          {
+            ptsol.SetTolerance(Tol);
+            if (!ptsol.IsMultiple())
+            {
+              //-- le point ptsol (de aligold) est declare multiple sur aligold
+              Multpoint = Standard_True;
+              ptsol.SetMultiple(Standard_True);
+              aligold->Replace(k, ptsol);
+            }
+            ptsol.SetParameter(first);
+            alig->AddVertex(ptsol);
+            alig->SetFirstPoint(alig->NbVertex());
+            procf = Standard_True;
+
+            //-- On restore le point avec son parametre sur aligold
+            ptsol = aligold->Vertex(k);
+          }
+        }
+        if (!procl)
+        {
+          if (ptl.Distance(ptsol.Value()) <= Tol)
+          {
+            ptsol.SetTolerance(Tol);
+            if (!ptsol.IsMultiple())
+            {
+              Multpoint = Standard_True;
+              ptsol.SetMultiple(Standard_True);
+              aligold->Replace(k, ptsol);
+            }
+            ptsol.SetParameter(last);
+            alig->AddVertex(ptsol);
+            alig->SetLastPoint(alig->NbVertex());
+            procl = Standard_True;
+
+            //-- On restore le point avec son parametre sur aligold
+            ptsol = aligold->Vertex(k);
+          }
+        }
+        if (procf && procl)
+        {
+          k = aligold->NbVertex() + 1;
+        }
+        else
+        {
+          k = k + 1;
+        }
+      }
+      if (procf && procl)
+      {
+        j = slin.Length() + 1;
+      }
+      else
+      {
+        j = j + 1;
+      }
+    }
+  }
+
+  ptsol.SetTolerance(Tol);
+  if (!procf && !procl)
+  {
+    Quad1.Parameters(ptf, U1, V1);
+    Quad2.Parameters(ptf, U2, V2);
+    ptsol.SetValue(ptf, Tol, Standard_False);
+    ptsol.SetParameters(U1, V1, U2, V2);
+    ptsol.SetParameter(first);
+    if (ptf.Distance(ptl) <= Tol)
+    {
+      ptsol.SetMultiple(Standard_True); // a voir
+      Multpoint = Standard_True;        // a voir de meme
+      alig->AddVertex(ptsol);
+      alig->SetFirstPoint(alig->NbVertex());
+
+      ptsol.SetParameter(last);
+      alig->AddVertex(ptsol);
+      alig->SetLastPoint(alig->NbVertex());
+    }
+    else
+    {
+      alig->AddVertex(ptsol);
+      alig->SetFirstPoint(alig->NbVertex());
+      Quad1.Parameters(ptl, U1, V1);
+      Quad2.Parameters(ptl, U2, V2);
+      ptsol.SetValue(ptl, Tol, Standard_False);
+      ptsol.SetParameters(U1, V1, U2, V2);
+      ptsol.SetParameter(last);
+      alig->AddVertex(ptsol);
+      alig->SetLastPoint(alig->NbVertex());
+    }
+  }
+  else if (!procf)
+  {
+    Quad1.Parameters(ptf, U1, V1);
+    Quad2.Parameters(ptf, U2, V2);
+    ptsol.SetValue(ptf, Tol, Standard_False);
+    ptsol.SetParameters(U1, V1, U2, V2);
+    ptsol.SetParameter(first);
+    alig->AddVertex(ptsol);
+    alig->SetFirstPoint(alig->NbVertex());
+  }
+  else if (!procl)
+  {
+    Quad1.Parameters(ptl, U1, V1);
+    Quad2.Parameters(ptl, U2, V2);
+    ptsol.SetValue(ptl, Tol, Standard_False);
+    ptsol.SetParameters(U1, V1, U2, V2);
+    ptsol.SetParameter(last);
+    alig->AddVertex(ptsol);
+    alig->SetLastPoint(alig->NbVertex());
+  }
+}
+
+//=======================================================================
+//function : CyCyAnalyticalIntersect
+//purpose  : Checks if intersection curve is analytical (line, circle, ellipse)
+//            and returns these curves.
+//=======================================================================
+Standard_Boolean CyCyAnalyticalIntersect(const IntSurf_Quadric&    Quad1,
+                                         const IntSurf_Quadric&    Quad2,
+                                         const IntAna_QuadQuadGeo& theInter,
+                                         const Standard_Real       Tol,
+                                         Standard_Boolean&         Empty,
+                                         Standard_Boolean&         Same,
+                                         Standard_Boolean&         Multpoint,
+                                         IntPatch_SequenceOfLine&  slin,
+                                         IntPatch_SequenceOfPoint& spnt)
+{
+  IntPatch_Point ptsol;
+
+  Standard_Integer i;
+
+  IntSurf_TypeTrans trans1, trans2;
+  IntAna_ResultType typint;
+
+  gp_Elips elipsol;
+  gp_Lin   linsol;
+
+  gp_Cylinder Cy1(Quad1.Cylinder());
+  gp_Cylinder Cy2(Quad2.Cylinder());
+
+  typint                 = theInter.TypeInter();
+  Standard_Integer NbSol = theInter.NbSolutions();
+  Empty                  = Standard_False;
+  Same                   = Standard_False;
+
+  switch (typint)
+  {
+    case IntAna_Empty:
+    {
+      Empty = Standard_True;
+    }
+    break;
+
+    case IntAna_Same:
+    {
+      Same = Standard_True;
+    }
+    break;
+
+    case IntAna_Point:
+    {
+      gp_Pnt psol(theInter.Point(1));
+      ptsol.SetValue(psol, Tol, Standard_True);
+
+      Standard_Real U1, V1, U2, V2;
+      Quad1.Parameters(psol, U1, V1);
+      Quad2.Parameters(psol, U2, V2);
+
+      ptsol.SetParameters(U1, V1, U2, V2);
+      spnt.Append(ptsol);
+    }
+    break;
+
+    case IntAna_Line:
+    {
+      gp_Pnt ptref;
+      if (NbSol == 1)
+      { // Cylinders are tangent to each other by line
+        linsol = theInter.Line(1);
+        ptref  = linsol.Location();
+
+        //Radius-vectors
+        gp_Dir crb1(gp_Vec(ptref, Cy1.Location()));
+        gp_Dir crb2(gp_Vec(ptref, Cy2.Location()));
+
+        //outer normal lines
+        gp_Vec            norm1(Quad1.Normale(ptref));
+        gp_Vec            norm2(Quad2.Normale(ptref));
+        IntSurf_Situation situcyl1;
+        IntSurf_Situation situcyl2;
+
+        if (crb1.Dot(crb2) < 0.)
+        { // centre de courbures "opposes"
+          //ATTENTION!!!
+          //        Normal and Radius-vector of the 1st(!) cylinder
+          //        is used for judging what the situation of the 2nd(!)
+          //        cylinder is.
+
+          if (norm1.Dot(crb1) > 0.)
+          {
+            situcyl2 = IntSurf_Inside;
+          }
+          else
+          {
+            situcyl2 = IntSurf_Outside;
+          }
+
+          if (norm2.Dot(crb2) > 0.)
+          {
+            situcyl1 = IntSurf_Inside;
+          }
+          else
+          {
+            situcyl1 = IntSurf_Outside;
+          }
+        }
+        else
+        {
+          if (Cy1.Radius() < Cy2.Radius())
+          {
+            if (norm1.Dot(crb1) > 0.)
+            {
+              situcyl2 = IntSurf_Inside;
+            }
+            else
+            {
+              situcyl2 = IntSurf_Outside;
+            }
+
+            if (norm2.Dot(crb2) > 0.)
+            {
+              situcyl1 = IntSurf_Outside;
+            }
+            else
+            {
+              situcyl1 = IntSurf_Inside;
+            }
+          }
+          else
+          {
+            if (norm1.Dot(crb1) > 0.)
+            {
+              situcyl2 = IntSurf_Outside;
+            }
+            else
+            {
+              situcyl2 = IntSurf_Inside;
+            }
+
+            if (norm2.Dot(crb2) > 0.)
+            {
+              situcyl1 = IntSurf_Inside;
+            }
+            else
+            {
+              situcyl1 = IntSurf_Outside;
+            }
+          }
+        }
+
+        Handle(IntPatch_GLine) glig = new IntPatch_GLine(linsol, Standard_True, situcyl1, situcyl2);
+        slin.Append(glig);
+      }
+      else
+      {
+        for (i = 1; i <= NbSol; i++)
+        {
+          linsol            = theInter.Line(i);
+          ptref             = linsol.Location();
+          gp_Vec lsd        = linsol.Direction();
+
+          //Theoretically, qwe = +/- 1.0.
+          Standard_Real qwe = lsd.DotCross(Quad2.Normale(ptref), Quad1.Normale(ptref));
+          if (qwe > 0.00000001)
+          {
+            trans1 = IntSurf_Out;
+            trans2 = IntSurf_In;
+          }
+          else if (qwe < -0.00000001)
+          {
+            trans1 = IntSurf_In;
+            trans2 = IntSurf_Out;
+          }
+          else
+          {
+            trans1 = trans2 = IntSurf_Undecided;
+          }
+
+          Handle(IntPatch_GLine) glig = new IntPatch_GLine(linsol, Standard_False, trans1, trans2);
+          slin.Append(glig);
+        }
+      }
+    }
+    break;
+
+    case IntAna_Ellipse:
+    {
+      gp_Vec         Tgt;
+      gp_Pnt         ptref;
+      IntPatch_Point pmult1, pmult2;
+
+      elipsol = theInter.Ellipse(1);
+
+      gp_Pnt pttang1(ElCLib::Value(0.5 * M_PI, elipsol));
+      gp_Pnt pttang2(ElCLib::Value(1.5 * M_PI, elipsol));
+
+      Multpoint = Standard_True;
+      pmult1.SetValue(pttang1, Tol, Standard_True);
+      pmult2.SetValue(pttang2, Tol, Standard_True);
+      pmult1.SetMultiple(Standard_True);
+      pmult2.SetMultiple(Standard_True);
+
+      Standard_Real oU1, oV1, oU2, oV2;
+      Quad1.Parameters(pttang1, oU1, oV1);
+      Quad2.Parameters(pttang1, oU2, oV2);
+
+      pmult1.SetParameters(oU1, oV1, oU2, oV2);
+      Quad1.Parameters(pttang2, oU1, oV1);
+      Quad2.Parameters(pttang2, oU2, oV2);
+
+      pmult2.SetParameters(oU1, oV1, oU2, oV2);
+
+      // on traite la premiere ellipse
+
+      //-- Calcul de la Transition de la ligne
+      ElCLib::D1(0., elipsol, ptref, Tgt);
+
+      //Theoretically, qwe = +/- |Tgt|.
+      Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref), Quad1.Normale(ptref));
+      if (qwe > 0.00000001)
+      {
+        trans1 = IntSurf_Out;
+        trans2 = IntSurf_In;
+      }
+      else if (qwe < -0.00000001)
+      {
+        trans1 = IntSurf_In;
+        trans2 = IntSurf_Out;
+      }
+      else
+      {
+        trans1 = trans2 = IntSurf_Undecided;
+      }
+
+      //-- Transition calculee au point 0 -> Trans2 , Trans1
+      //-- car ici, on devarit calculer en PI
+      Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol, Standard_False, trans2, trans1);
+      //
+      {
+        Standard_Real  aU1, aV1, aU2, aV2;
+        IntPatch_Point aIP;
+        gp_Pnt         aP(ElCLib::Value(0., elipsol));
+        //
+        aIP.SetValue(aP, Tol, Standard_False);
+        aIP.SetMultiple(Standard_False);
+        //
+        Quad1.Parameters(aP, aU1, aV1);
+        Quad2.Parameters(aP, aU2, aV2);
+
+        aIP.SetParameters(aU1, aV1, aU2, aV2);
+        //
+        aIP.SetParameter(0.);
+        glig->AddVertex(aIP);
+        glig->SetFirstPoint(1);
+        //
+        aIP.SetParameter(2. * M_PI);
+        glig->AddVertex(aIP);
+        glig->SetLastPoint(2);
+      }
+      //
+      pmult1.SetParameter(0.5 * M_PI);
+      glig->AddVertex(pmult1);
+      //
+      pmult2.SetParameter(1.5 * M_PI);
+      glig->AddVertex(pmult2);
+
+      //
+      slin.Append(glig);
+
+      //-- Transitions calculee au point 0    OK
+      //
+      // on traite la deuxieme ellipse
+      elipsol                           = theInter.Ellipse(2);
+
+      Standard_Real param1              = ElCLib::Parameter(elipsol, pttang1);
+      Standard_Real param2              = ElCLib::Parameter(elipsol, pttang2);
+      Standard_Real parampourtransition = 0.0;
+      if (param1 < param2)
+      {
+        pmult1.SetParameter(0.5 * M_PI);
+        pmult2.SetParameter(1.5 * M_PI);
+        parampourtransition = M_PI;
+      }
+      else
+      {
+        pmult1.SetParameter(1.5 * M_PI);
+        pmult2.SetParameter(0.5 * M_PI);
+        parampourtransition = 0.0;
+      }
+
+      //-- Calcul des transitions de ligne pour la premiere ligne
+      ElCLib::D1(parampourtransition, elipsol, ptref, Tgt);
+
+      //Theoretically, qwe = +/- |Tgt|.
+      qwe = Tgt.DotCross(Quad2.Normale(ptref), Quad1.Normale(ptref));
+      if (qwe > 0.00000001)
+      {
+        trans1 = IntSurf_Out;
+        trans2 = IntSurf_In;
+      }
+      else if (qwe < -0.00000001)
+      {
+        trans1 = IntSurf_In;
+        trans2 = IntSurf_Out;
+      }
+      else
+      {
+        trans1 = trans2 = IntSurf_Undecided;
+      }
+
+      //-- La transition a ete calculee sur un point de cette ligne
+      glig = new IntPatch_GLine(elipsol, Standard_False, trans1, trans2);
+      //
+      {
+        Standard_Real  aU1, aV1, aU2, aV2;
+        IntPatch_Point aIP;
+        gp_Pnt         aP(ElCLib::Value(0., elipsol));
+        //
+        aIP.SetValue(aP, Tol, Standard_False);
+        aIP.SetMultiple(Standard_False);
+        //
+
+        Quad1.Parameters(aP, aU1, aV1);
+        Quad2.Parameters(aP, aU2, aV2);
+
+        aIP.SetParameters(aU1, aV1, aU2, aV2);
+        //
+        aIP.SetParameter(0.);
+        glig->AddVertex(aIP);
+        glig->SetFirstPoint(1);
+        //
+        aIP.SetParameter(2. * M_PI);
+        glig->AddVertex(aIP);
+        glig->SetLastPoint(2);
+      }
+      //
+      glig->AddVertex(pmult1);
+      glig->AddVertex(pmult2);
+      //
+      slin.Append(glig);
+    }
+    break;
+
+    case IntAna_Parabola:
+    case IntAna_Hyperbola: throw Standard_Failure("IntCyCy(): Wrong intersection type!");
+
+    case IntAna_Circle:
+      // Circle is useful when we will work with trimmed surfaces
+      // (two cylinders can be tangent by their basises, e.g. circle)
+    case IntAna_NoGeometricSolution:
+    default: return Standard_False;
+  }
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : ShortCosForm
+//purpose  : Represents theCosFactor*cosA+theSinFactor*sinA as
+//            theCoeff*cos(A-theAngle) if it is possibly (all angles are
+//            in radians).
+//=======================================================================
+static void ShortCosForm(const Standard_Real theCosFactor,
+                         const Standard_Real theSinFactor,
+                         Standard_Real&      theCoeff,
+                         Standard_Real&      theAngle)
+{
+  theCoeff = sqrt(theCosFactor * theCosFactor + theSinFactor * theSinFactor);
+  theAngle = 0.0;
+  if (IsEqual(theCoeff, 0.0))
+  {
+    theAngle = 0.0;
+    return;
+  }
+
+  theAngle = acos(Abs(theCosFactor / theCoeff));
+
+  if (theSinFactor > 0.0)
+  {
+    if (IsEqual(theCosFactor, 0.0))
+    {
+      theAngle = M_PI / 2.0;
+    }
+    else if (theCosFactor < 0.0)
+    {
+      theAngle = M_PI - theAngle;
+    }
+  }
+  else if (IsEqual(theSinFactor, 0.0))
+  {
+    if (theCosFactor < 0.0)
+    {
+      theAngle = M_PI;
+    }
+  }
+  if (theSinFactor < 0.0)
+  {
+    if (theCosFactor > 0.0)
+    {
+      theAngle = 2.0 * M_PI - theAngle;
+    }
+    else if (IsEqual(theCosFactor, 0.0))
+    {
+      theAngle = 3.0 * M_PI / 2.0;
+    }
+    else if (theCosFactor < 0.0)
+    {
+      theAngle = M_PI + theAngle;
+    }
+  }
+}
+
+//=======================================================================
+//function : CylCylMonotonicity
+//purpose  : Determines, if U2(U1) function is increasing.
+//=======================================================================
+Standard_Boolean ComputationMethods::CylCylMonotonicity(const Standard_Real    theU1par,
+                                                        const Standard_Integer theWLIndex,
+                                                        const stCoeffsValue&   theCoeffs,
+                                                        const Standard_Real    thePeriod,
+                                                        Standard_Boolean&      theIsIncreasing)
+{
+  // U2(U1) = FI2 + (+/-)acos(B*cos(U1 - FI1) + C);
+  //Accordingly,
+  //Func. U2(X1) = FI2 + X1;
+  //Func. X1(X2) = anArccosFactor*X2;
+  //Func. X2(X3) = acos(X3);
+  //Func. X3(X4) = B*X4 + C;
+  //Func. X4(U1) = cos(U1 - FI1).
+  //
+  //Consequently,
+  //U2(X1) is always increasing.
+  //X1(X2) is increasing if anArccosFactor > 0.0 and
+  //is decreasing otherwise.
+  //X2(X3) is always decreasing.
+  //Therefore, U2(X3) is decreasing if anArccosFactor > 0.0 and
+  //is increasing otherwise.
+  //X3(X4) is increasing if B > 0 and is decreasing otherwise.
+  //X4(U1) is increasing if U1 - FI1 in [PI, 2*PI) and
+  //is decreasing U1 - FI1 in [0, PI) or if (U1 - FI1 == 2PI).
+  //After that, we can predict behaviour of U2(U1) function:
+  //if it is increasing or decreasing.
+
+  //For "+/-" sign. If isPlus == TRUE, "+" is chosen, otherwise, we choose "-".
+  Standard_Boolean isPlus = Standard_False;
+
+  switch (theWLIndex)
+  {
+    case 0: isPlus = Standard_True; break;
+    case 1: isPlus = Standard_False; break;
+    default:
+      //throw Standard_Failure("Error. Range Error!!!!");
+      return Standard_False;
+  }
+
+  Standard_Real aU1Temp = theU1par - theCoeffs.mFI1;
+  InscribePoint(0, thePeriod, aU1Temp, 0.0, thePeriod, Standard_False);
+
+  theIsIncreasing = Standard_True;
+
+  if (((M_PI - aU1Temp) < RealSmall()) && (aU1Temp < thePeriod))
+  {
+    theIsIncreasing = Standard_False;
+  }
+
+  if (theCoeffs.mB < 0.0)
+  {
+    theIsIncreasing = !theIsIncreasing;
+  }
+
+  if (!isPlus)
+  {
+    theIsIncreasing = !theIsIncreasing;
+  }
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : CylCylComputeParameters
+//purpose  : Computes U2 (U-parameter of the 2nd cylinder) and, if theDelta != 0,
+//            estimates the tolerance of U2-computing (estimation result is
+//            assigned to *theDelta value).
+//=======================================================================
+Standard_Boolean ComputationMethods::CylCylComputeParameters(const Standard_Real    theU1par,
+                                                             const Standard_Integer theWLIndex,
+                                                             const stCoeffsValue&   theCoeffs,
+                                                             Standard_Real&         theU2,
+                                                             Standard_Real* const   theDelta)
+{
+  //This formula is got from some experience and can be changed.
+  const Standard_Real aTol0 = Min(10.0 * Epsilon(1.0) * theCoeffs.mB, aNulValue);
+  const Standard_Real aTol  = 1.0 - aTol0;
+
+  if (theWLIndex < 0 || theWLIndex > 1)
+    return Standard_False;
+
+  const Standard_Real aSign = theWLIndex ? -1.0 : 1.0;
+
+  Standard_Real anArg       = cos(theU1par - theCoeffs.mFI1);
+  anArg                     = theCoeffs.mB * anArg + theCoeffs.mC;
+
+  if (anArg >= aTol)
+  {
+    if (theDelta)
+      *theDelta = 0.0;
+
+    anArg = 1.0;
+  }
+  else if (anArg <= -aTol)
+  {
+    if (theDelta)
+      *theDelta = 0.0;
+
+    anArg = -1.0;
+  }
+  else if (theDelta)
+  {
+    //There is a case, when
+    //  const double aPar = 0.99999999999721167;
+    //  const double aFI2 = 2.3593296083566181e-006;
+
+    //Then
+    //  aPar - cos(aFI2) == -5.10703e-015 ==> cos(aFI2) == aPar.
+    //Theoretically, in this case
+    //  aFI2 == +/- acos(aPar).
+    //However,
+    //  acos(aPar) - aFI2 == 2.16362e-009.
+    //Error is quite big.
+
+    //This error should be estimated. Let use following way, which is based
+    //on expanding to Taylor series.
+
+    //  acos(p)-acos(p+x) = x/sqrt(1-p*p).
+
+    //If p == (1-d) (when p > 0) or p == (-1+d) (when p < 0) then
+    //  acos(p)-acos(p+x) = x/sqrt(d*(2-d)).
+
+    //Here always aTol0 <= d <= 1. Max(x) is considered (!) to be equal to aTol0.
+    //In this case
+    //  8*aTol0 <= acos(p)-acos(p+x) <= sqrt(2/(2-aTol0)-1),
+    //                                              because 0 < aTol0 < 1.
+    //E.g. when aTol0 = 1.0e-11,
+    //   8.0e-11 <= acos(p)-acos(p+x) < 2.24e-6.
+
+    const Standard_Real aDelta = Min(1.0 - anArg, 1.0 + anArg);
+    Standard_DivideByZero_Raise_if((aDelta * aDelta < RealSmall()) || (aDelta >= 2.0),
+                                   "IntPatch_ImpImpIntersection_4.gxx, CylCylComputeParameters()");
+    *theDelta = aTol0 / sqrt(aDelta * (2.0 - aDelta));
+  }
+
+  theU2 = acos(anArg);
+  theU2 = theCoeffs.mFI2 + aSign * theU2;
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : CylCylComputeParameters
+//purpose  : Computes V1 and V2 (V-parameters of the 1st and 2nd cylinder respectively).
+//=======================================================================
+Standard_Boolean ComputationMethods::CylCylComputeParameters(const Standard_Real  theU1,
+                                                             const Standard_Real  theU2,
+                                                             const stCoeffsValue& theCoeffs,
+                                                             Standard_Real&       theV1,
+                                                             Standard_Real&       theV2)
+{
+  theV1 = theCoeffs.mK21 * sin(theU2) + theCoeffs.mK11 * sin(theU1) + theCoeffs.mL21 * cos(theU2) + theCoeffs.mL11 * cos(theU1)
+        + theCoeffs.mM1;
+
+  theV2 = theCoeffs.mK22 * sin(theU2) + theCoeffs.mK12 * sin(theU1) + theCoeffs.mL22 * cos(theU2) + theCoeffs.mL12 * cos(theU1)
+        + theCoeffs.mM2;
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : CylCylComputeParameters
+//purpose  : Computes U2 (U-parameter of the 2nd cylinder),
+//            V1 and V2 (V-parameters of the 1st and 2nd cylinder respectively).
+//=======================================================================
+Standard_Boolean ComputationMethods::CylCylComputeParameters(const Standard_Real    theU1par,
+                                                             const Standard_Integer theWLIndex,
+                                                             const stCoeffsValue&   theCoeffs,
+                                                             Standard_Real&         theU2,
+                                                             Standard_Real&         theV1,
+                                                             Standard_Real&         theV2)
+{
+  if (!CylCylComputeParameters(theU1par, theWLIndex, theCoeffs, theU2))
+    return Standard_False;
+
+  if (!CylCylComputeParameters(theU1par, theU2, theCoeffs, theV1, theV2))
+    return Standard_False;
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : SearchOnVBounds
+//purpose  :
+//=======================================================================
+Standard_Boolean WorkWithBoundaries::SearchOnVBounds(const SearchBoundType theSBType,
+                                                     const Standard_Real   theVzad,
+                                                     const Standard_Real   theVInit,
+                                                     const Standard_Real   theInitU2,
+                                                     const Standard_Real   theInitMainVar,
+                                                     Standard_Real&        theMainVariableValue) const
+{
+  const Standard_Integer aNbDim    = 3;
+  const Standard_Real    aMaxError = 4.0 * M_PI; // two periods
+
+  theMainVariableValue             = theInitMainVar;
+  const Standard_Real aTol2        = 1.0e-18;
+  Standard_Real       aMainVarPrev = theInitMainVar, aU2Prev = theInitU2, anOtherVar = theVInit;
+
+  //Structure of aMatr:
+  //  C_{1}*U_{1} & C_{2}*U_{2} & C_{3}*V_{*},
+  //where C_{1}, C_{2} and C_{3} are math_Vector.
+  math_Matrix aMatr(1, aNbDim, 1, aNbDim);
+
+  Standard_Real    anError     = RealLast();
+  Standard_Real    anErrorPrev = anError;
+  Standard_Integer aNbIter     = 0;
+  do
+  {
+    if (++aNbIter > 1000)
+      return Standard_False;
+
+    const Standard_Real aSinU1 = sin(aMainVarPrev), aCosU1 = cos(aMainVarPrev), aSinU2 = sin(aU2Prev), aCosU2 = cos(aU2Prev);
+
+    math_Vector aVecFreeMem = (myCoeffs.mVecA2 * aU2Prev + myCoeffs.mVecB2) * aSinU2
+                            - (myCoeffs.mVecB2 * aU2Prev - myCoeffs.mVecA2) * aCosU2
+                            + (myCoeffs.mVecA1 * aMainVarPrev + myCoeffs.mVecB1) * aSinU1
+                            - (myCoeffs.mVecB1 * aMainVarPrev - myCoeffs.mVecA1) * aCosU1 + myCoeffs.mVecD;
+
+    math_Vector aMSum(1, 3);
+
+    switch (theSBType)
+    {
+      case SearchV1:
+        aMatr.SetCol(3, myCoeffs.mVecC2);
+        aMSum = myCoeffs.mVecC1 * theVzad;
+        aVecFreeMem -= aMSum;
+        aMSum += myCoeffs.mVecC2 * anOtherVar;
+        break;
+
+      case SearchV2:
+        aMatr.SetCol(3, myCoeffs.mVecC1);
+        aMSum = myCoeffs.mVecC2 * theVzad;
+        aVecFreeMem -= aMSum;
+        aMSum += myCoeffs.mVecC1 * anOtherVar;
+        break;
+
+      default: return Standard_False;
+    }
+
+    aMatr.SetCol(1, myCoeffs.mVecA1 * aSinU1 - myCoeffs.mVecB1 * aCosU1);
+    aMatr.SetCol(2, myCoeffs.mVecA2 * aSinU2 - myCoeffs.mVecB2 * aCosU2);
+
+    Standard_Real aDetMainSyst = aMatr.Determinant();
+
+    if (Abs(aDetMainSyst) < aNulValue)
+    {
+      return Standard_False;
+    }
+
+    math_Matrix aM1(aMatr), aM2(aMatr), aM3(aMatr);
+    aM1.SetCol(1, aVecFreeMem);
+    aM2.SetCol(2, aVecFreeMem);
+    aM3.SetCol(3, aVecFreeMem);
+
+    const Standard_Real aDetMainVar = aM1.Determinant();
+    const Standard_Real aDetVar1    = aM2.Determinant();
+    const Standard_Real aDetVar2    = aM3.Determinant();
+
+    Standard_Real aDelta            = aDetMainVar / aDetMainSyst - aMainVarPrev;
+
+    if (Abs(aDelta) > aMaxError)
+      return Standard_False;
+
+    anError = aDelta * aDelta;
+    aMainVarPrev += aDelta;
+
+    ///
+    aDelta = aDetVar1 / aDetMainSyst - aU2Prev;
+
+    if (Abs(aDelta) > aMaxError)
+      return Standard_False;
+
+    anError += aDelta * aDelta;
+    aU2Prev += aDelta;
+
+    ///
+    aDelta = aDetVar2 / aDetMainSyst - anOtherVar;
+    anError += aDelta * aDelta;
+    anOtherVar += aDelta;
+
+    if (anError > anErrorPrev)
+    { //Method diverges. Keep the best result
+      const Standard_Real aSinU1Last = sin(aMainVarPrev), aCosU1Last = cos(aMainVarPrev), aSinU2Last = sin(aU2Prev),
+                          aCosU2Last = cos(aU2Prev);
+      aMSum -= (myCoeffs.mVecA1 * aCosU1Last + myCoeffs.mVecB1 * aSinU1Last + myCoeffs.mVecA2 * aCosU2Last
+                + myCoeffs.mVecB2 * aSinU2Last + myCoeffs.mVecD);
+      const Standard_Real aSQNorm = aMSum.Norm2();
+      return (aSQNorm < aTol2);
+    }
+    else
+    {
+      theMainVariableValue = aMainVarPrev;
+    }
+
+    anErrorPrev = anError;
+  } while (anError > aTol2);
+
+  theMainVariableValue = aMainVarPrev;
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : InscribePoint
+//purpose  : If theFlForce==TRUE theUGiven will be changed forcefully
+//            even if theUGiven is already inscibed in the boundary
+//            (if it is possible; i.e. if new theUGiven is inscribed
+//            in the boundary, too).
+//=======================================================================
+Standard_Boolean InscribePoint(const Standard_Real    theUfTarget,
+                               const Standard_Real    theUlTarget,
+                               Standard_Real&         theUGiven,
+                               const Standard_Real    theTol2D,
+                               const Standard_Real    thePeriod,
+                               const Standard_Boolean theFlForce)
+{
+  if (Precision::IsInfinite(theUGiven))
+  {
+    return Standard_False;
+  }
+
+  if ((theUfTarget - theUGiven <= theTol2D) && (theUGiven - theUlTarget <= theTol2D))
+  { //it has already inscribed
+
+    /*
+             Utf    U      Utl
+              +     *       +
+    */
+
+    if (theFlForce)
+    {
+      Standard_Real anUtemp = theUGiven + thePeriod;
+      if ((theUfTarget - anUtemp <= theTol2D) && (anUtemp - theUlTarget <= theTol2D))
+      {
+        theUGiven = anUtemp;
+        return Standard_True;
+      }
+
+      anUtemp = theUGiven - thePeriod;
+      if ((theUfTarget - anUtemp <= theTol2D) && (anUtemp - theUlTarget <= theTol2D))
+      {
+        theUGiven = anUtemp;
+      }
+    }
+
+    return Standard_True;
+  }
+
+  const Standard_Real aUf = theUfTarget - theTol2D;
+  const Standard_Real aUl = aUf + thePeriod;
+
+  theUGiven               = ElCLib::InPeriod(theUGiven, aUf, aUl);
+
+  return ((theUfTarget - theUGiven <= theTol2D) && (theUGiven - theUlTarget <= theTol2D));
+}
+
+//=======================================================================
+//function : InscribeInterval
+//purpose  : Shifts theRange in order to make at least one of its
+//            boundary in the range [theUfTarget, theUlTarget]
+//=======================================================================
+static Standard_Boolean InscribeInterval(const Standard_Real theUfTarget,
+                                         const Standard_Real theUlTarget,
+                                         Bnd_Range&          theRange,
+                                         const Standard_Real theTol2D,
+                                         const Standard_Real thePeriod)
+{
+  Standard_Real anUpar = 0.0;
+  if (!theRange.GetMin(anUpar))
+  {
+    return Standard_False;
+  }
+
+  const Standard_Real aDelta = theRange.Delta();
+  if (InscribePoint(theUfTarget, theUlTarget, anUpar, theTol2D, thePeriod, (Abs(theUlTarget - anUpar) < theTol2D)))
+  {
+    theRange.SetVoid();
+    theRange.Add(anUpar);
+    theRange.Add(anUpar + aDelta);
+  }
+  else
+  {
+    if (!theRange.GetMax(anUpar))
+    {
+      return Standard_False;
+    }
+
+    if (InscribePoint(theUfTarget, theUlTarget, anUpar, theTol2D, thePeriod, (Abs(theUfTarget - anUpar) < theTol2D)))
+    {
+      theRange.SetVoid();
+      theRange.Add(anUpar);
+      theRange.Add(anUpar - aDelta);
+    }
+    else
+    {
+      return Standard_False;
+    }
+  }
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : ExcludeNearElements
+//purpose  : Checks if theArr contains two almost equal elements.
+//            If it is true then one of equal elements will be excluded
+//            (made infinite).
+//           Returns TRUE if at least one element of theArr has been changed.
+//ATTENTION!!!
+//           1. Every not infinite element of theArr is considered to be
+//            in [0, T] interval (where T is the period);
+//           2. theArr must be sorted in ascending order.
+//=======================================================================
+static Standard_Boolean ExcludeNearElements(Standard_Real          theArr[],
+                                            const Standard_Integer theNOfMembers,
+                                            const Standard_Real    theUSurf1f,
+                                            const Standard_Real    theUSurf1l,
+                                            const Standard_Real    theTol)
+{
+  Standard_Boolean aRetVal = Standard_False;
+  for (Standard_Integer i = 1; i < theNOfMembers; i++)
+  {
+    Standard_Real &anA = theArr[i], &anB = theArr[i - 1];
+
+    //Here, anA >= anB
+
+    if (Precision::IsInfinite(anA))
+      break;
+
+    if ((anA - anB) < theTol)
+    {
+      if ((anB != 0.0) && (anB != theUSurf1f) && (anB != theUSurf1l))
+        anA = (anA + anB) / 2.0;
+      else
+        anA = anB;
+
+      //Make this element infinite an forget it
+      //(we will not use it in next iterations).
+      anB     = Precision::Infinite();
+      aRetVal = Standard_True;
+    }
+  }
+
+  return aRetVal;
+}
+
+//=======================================================================
+//function : AddPointIntoWL
+//purpose  : Surf1 is a surface, whose U-par is variable.
+//           If theFlBefore == TRUE then we enable the U1-parameter
+//            of the added point to be less than U1-parameter of
+//           previously added point (in general U1-parameter is
+//           always increased; therefore, this situation is abnormal).
+//           If theOnlyCheck==TRUE then no point will be added to theLine.
+//=======================================================================
+static Standard_Boolean AddPointIntoWL(const IntSurf_Quadric&                   theQuad1,
+                                       const IntSurf_Quadric&                   theQuad2,
+                                       const ComputationMethods::stCoeffsValue& theCoeffs,
+                                       const Standard_Boolean                   isTheReverse,
+                                       const Standard_Boolean                   isThePrecise,
+                                       const gp_Pnt2d&                          thePntOnSurf1,
+                                       const gp_Pnt2d&                          thePntOnSurf2,
+                                       const Standard_Real                      theUfSurf1,
+                                       const Standard_Real                      theUlSurf1,
+                                       const Standard_Real                      theUfSurf2,
+                                       const Standard_Real                      theUlSurf2,
+                                       const Standard_Real                      theVfSurf1,
+                                       const Standard_Real                      theVlSurf1,
+                                       const Standard_Real                      theVfSurf2,
+                                       const Standard_Real                      theVlSurf2,
+                                       const Standard_Real                      thePeriodOfSurf1,
+                                       const Handle(IntSurf_LineOn2S)&          theLine,
+                                       const Standard_Integer                   theWLIndex,
+                                       const Standard_Real                      theTol3D,
+                                       const Standard_Real                      theTol2D,
+                                       const Standard_Boolean                   theFlBefore  = Standard_False,
+                                       const Standard_Boolean                   theOnlyCheck = Standard_False)
+{
+  //Check if the point is in the domain or can be inscribed in the domain after adjusting.
+
+  gp_Pnt aPt1(theQuad1.Value(thePntOnSurf1.X(), thePntOnSurf1.Y())), aPt2(theQuad2.Value(thePntOnSurf2.X(), thePntOnSurf2.Y()));
+
+  Standard_Real aU1par = thePntOnSurf1.X();
+
+  // aU1par always increases. Therefore, we must reduce its
+  // value in order to continue creation of WLine.
+  if (!InscribePoint(theUfSurf1, theUlSurf1, aU1par, theTol2D, thePeriodOfSurf1, aU1par > 0.5 * (theUfSurf1 + theUlSurf1)))
+    return Standard_False;
+
+  if ((theLine->NbPoints() > 0) && ((theUlSurf1 - theUfSurf1) >= (thePeriodOfSurf1 - theTol2D))
+      && (((aU1par + thePeriodOfSurf1 - theUlSurf1) <= theTol2D) || ((aU1par - thePeriodOfSurf1 - theUfSurf1) >= theTol2D)))
+  {
+    // aU1par can be adjusted to both theUlSurf1 and theUfSurf1
+    // with equal possibilities. This code fragment allows choosing
+    // correct parameter from these two variants.
+
+    Standard_Real aU1 = 0.0, aV1 = 0.0;
+    if (isTheReverse)
+    {
+      theLine->Value(theLine->NbPoints()).ParametersOnS2(aU1, aV1);
+    }
+    else
+    {
+      theLine->Value(theLine->NbPoints()).ParametersOnS1(aU1, aV1);
+    }
+
+    const Standard_Real aDelta = aU1 - aU1par;
+    if (2.0 * Abs(aDelta) > thePeriodOfSurf1)
+    {
+      aU1par += Sign(thePeriodOfSurf1, aDelta);
+    }
+  }
+
+  Standard_Real aU2par = thePntOnSurf2.X();
+  if (!InscribePoint(theUfSurf2, theUlSurf2, aU2par, theTol2D, thePeriodOfSurf1, Standard_False))
+    return Standard_False;
+
+  Standard_Real aV1par = thePntOnSurf1.Y();
+  if ((aV1par - theVlSurf1 > theTol2D) || (theVfSurf1 - aV1par > theTol2D))
+    return Standard_False;
+
+  Standard_Real aV2par = thePntOnSurf2.Y();
+  if ((aV2par - theVlSurf2 > theTol2D) || (theVfSurf2 - aV2par > theTol2D))
+    return Standard_False;
+
+  //Get intersection point and add it in the WL
+  IntSurf_PntOn2S aPnt;
+
+  if (isTheReverse)
+  {
+    aPnt.SetValue((aPt1.XYZ() + aPt2.XYZ()) / 2.0, aU2par, aV2par, aU1par, aV1par);
+  }
+  else
+  {
+    aPnt.SetValue((aPt1.XYZ() + aPt2.XYZ()) / 2.0, aU1par, aV1par, aU2par, aV2par);
+  }
+
+  Standard_Integer aNbPnts = theLine->NbPoints();
+  if (aNbPnts > 0)
+  {
+    Standard_Real         aUl = 0.0, aVl = 0.0;
+    const IntSurf_PntOn2S aPlast = theLine->Value(aNbPnts);
+    if (isTheReverse)
+      aPlast.ParametersOnS2(aUl, aVl);
+    else
+      aPlast.ParametersOnS1(aUl, aVl);
+
+    if (!theFlBefore && (aU1par <= aUl))
+    {
+      //Parameter value must be increased if theFlBefore == FALSE.
+
+      aU1par += thePeriodOfSurf1;
+
+      //The condition is as same as in
+      //InscribePoint(...) function
+      if ((theUfSurf1 - aU1par > theTol2D) || (aU1par - theUlSurf1 > theTol2D))
+      {
+        //New aU1par is out of target interval.
+        //Go back to old value.
+
+        return Standard_False;
+      }
+    }
+
+    if (theOnlyCheck)
+      return Standard_True;
+
+    //theTol2D is minimal step along parameter changed.
+    //Therefore, if we apply this minimal step two
+    //neighbour points will be always "same". Consequently,
+    //we should reduce tolerance for IsSame checking.
+    const Standard_Real aDTol = 1.0 - Epsilon(1.0);
+    if (aPnt.IsSame(aPlast, theTol3D * aDTol, theTol2D * aDTol))
+    {
+      theLine->RemovePoint(aNbPnts);
+    }
+  }
+
+  if (theOnlyCheck)
+    return Standard_True;
+
+  theLine->Add(aPnt);
+
+  if (!isThePrecise)
+    return Standard_True;
+
+  //Try to precise existing WLine
+  aNbPnts = theLine->NbPoints();
+  if (aNbPnts >= 3)
+  {
+    Standard_Real aU1 = 0.0, aU2 = 0.0, aU3 = 0.0, aV = 0.0;
+    if (isTheReverse)
+    {
+      theLine->Value(aNbPnts).ParametersOnS2(aU3, aV);
+      theLine->Value(aNbPnts - 1).ParametersOnS2(aU2, aV);
+      theLine->Value(aNbPnts - 2).ParametersOnS2(aU1, aV);
+    }
+    else
+    {
+      theLine->Value(aNbPnts).ParametersOnS1(aU3, aV);
+      theLine->Value(aNbPnts - 1).ParametersOnS1(aU2, aV);
+      theLine->Value(aNbPnts - 2).ParametersOnS1(aU1, aV);
+    }
+
+    const Standard_Real aStepPrev     = aU2 - aU1;
+    const Standard_Real aStep         = aU3 - aU2;
+
+    const Standard_Integer aDeltaStep = RealToInt(aStepPrev / aStep);
+
+    if ((1 < aDeltaStep) && (aDeltaStep < 2000))
+    {
+      //Add new points in case of non-uniform distribution of existing points
+      SeekAdditionalPoints(theQuad1,
+                           theQuad2,
+                           theLine,
+                           theCoeffs,
+                           theWLIndex,
+                           aDeltaStep,
+                           aNbPnts - 2,
+                           aNbPnts - 1,
+                           theTol2D,
+                           thePeriodOfSurf1,
+                           isTheReverse);
+    }
+  }
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : AddBoundaryPoint
+//purpose  : Find intersection point on V-boundary.
+//=======================================================================
+void WorkWithBoundaries::AddBoundaryPoint(const Handle(IntPatch_WLine)& theWL,
+                                          const Standard_Real           theU1,
+                                          const Standard_Real           theU1Min,
+                                          const Standard_Real           theU2,
+                                          const Standard_Real           theV1,
+                                          const Standard_Real           theV1Prev,
+                                          const Standard_Real           theV2,
+                                          const Standard_Real           theV2Prev,
+                                          const Standard_Integer        theWLIndex,
+                                          const Standard_Boolean        theFlForce,
+                                          Standard_Boolean&             isTheFound1,
+                                          Standard_Boolean&             isTheFound2) const
+{
+  Standard_Real aUSurf1f = 0.0, //const
+    aUSurf1l = 0.0, aVSurf1f = 0.0, aVSurf1l = 0.0;
+  Standard_Real aUSurf2f = 0.0, //const
+    aUSurf2l = 0.0, aVSurf2f = 0.0, aVSurf2l = 0.0;
+
+  myUVSurf1.Get(aUSurf1f, aVSurf1f, aUSurf1l, aVSurf1l);
+  myUVSurf2.Get(aUSurf2f, aVSurf2f, aUSurf2l, aVSurf2l);
+
+  const Standard_Integer aSize            = 4;
+  const Standard_Real    anArrVzad[aSize] = {aVSurf1f, aVSurf1l, aVSurf2f, aVSurf2l};
+
+  StPInfo aUVPoint[aSize];
+
+  for (Standard_Integer anIDSurf = 0; anIDSurf < 4; anIDSurf += 2)
+  {
+    const Standard_Real aVf = (anIDSurf == 0) ? theV1 : theV2, aVl = (anIDSurf == 0) ? theV1Prev : theV2Prev;
+
+    const SearchBoundType aTS = (anIDSurf == 0) ? SearchV1 : SearchV2;
+
+    for (Standard_Integer anIDBound = 0; anIDBound < 2; anIDBound++)
+    {
+      const Standard_Integer anIndex = anIDSurf + anIDBound;
+
+      aUVPoint[anIndex].mySurfID     = anIDSurf;
+
+      if ((Abs(aVf - anArrVzad[anIndex]) > myTol2D) && ((aVf - anArrVzad[anIndex]) * (aVl - anArrVzad[anIndex]) > 0.0))
+      {
+        continue;
+      }
+
+      //Segment [aVf, aVl] intersects at least one V-boundary (first or last)
+      // (in general, case is possible, when aVf > aVl).
+
+      // Precise intersection point
+      const Standard_Boolean aRes =
+        SearchOnVBounds(aTS, anArrVzad[anIndex], (anIDSurf == 0) ? theV2 : theV1, theU2, theU1, aUVPoint[anIndex].myU1);
+
+      // aUVPoint[anIndex].myU1 is considered to be nearer to theU1 than
+      // to theU1+/-Period
+      if (!aRes || (aUVPoint[anIndex].myU1 >= theU1) || (aUVPoint[anIndex].myU1 < theU1Min))
+      {
+        //Intersection point is not found or out of the domain
+        aUVPoint[anIndex].myU1 = RealLast();
+        continue;
+      }
+      else
+      {
+        //intersection point is found
+
+        Standard_Real &aU1 = aUVPoint[anIndex].myU1, &aU2 = aUVPoint[anIndex].myU2, &aV1 = aUVPoint[anIndex].myV1,
+                      &aV2 = aUVPoint[anIndex].myV2;
+        aU2                = theU2;
+        aV1                = theV1;
+        aV2                = theV2;
+
+        if (!ComputationMethods::CylCylComputeParameters(aU1, theWLIndex, myCoeffs, aU2, aV1, aV2))
+        {
+          // Found point is wrong
+          aU1 = RealLast();
+          continue;
+        }
+
+        //Point on true V-boundary.
+        if (aTS == SearchV1)
+          aV1 = anArrVzad[anIndex];
+        else //if(aTS[anIndex] == SearchV2)
+          aV2 = anArrVzad[anIndex];
+      }
+    }
+  }
+
+  // Sort with acceding U1-parameter.
+  std::sort(aUVPoint, aUVPoint + aSize);
+
+  isTheFound1 = isTheFound2 = Standard_False;
+
+  //Adding found points on boundary in the WLine.
+  for (Standard_Integer i = 0; i < aSize; i++)
+  {
+    if (aUVPoint[i].myU1 == RealLast())
+      break;
+
+    if (!AddPointIntoWL(myQuad1,
+                        myQuad2,
+                        myCoeffs,
+                        myIsReverse,
+                        Standard_False,
+                        gp_Pnt2d(aUVPoint[i].myU1, aUVPoint[i].myV1),
+                        gp_Pnt2d(aUVPoint[i].myU2, aUVPoint[i].myV2),
+                        aUSurf1f,
+                        aUSurf1l,
+                        aUSurf2f,
+                        aUSurf2l,
+                        aVSurf1f,
+                        aVSurf1l,
+                        aVSurf2f,
+                        aVSurf2l,
+                        myPeriod,
+                        theWL->Curve(),
+                        theWLIndex,
+                        myTol3D,
+                        myTol2D,
+                        theFlForce))
+    {
+      continue;
+    }
+
+    if (aUVPoint[i].mySurfID == 0)
+    {
+      isTheFound1 = Standard_True;
+    }
+    else
+    {
+      isTheFound2 = Standard_True;
+    }
+  }
+}
+
+//=======================================================================
+//function : SeekAdditionalPoints
+//purpose  : Inserts additional intersection points between neighbor points.
+//            This action is bone with several iterations. During every iteration,
+//          new point is inserted in middle of every interval.
+//            The process will be finished if NbPoints >= theMinNbPoints.
+//=======================================================================
+static void SeekAdditionalPoints(const IntSurf_Quadric&                   theQuad1,
+                                 const IntSurf_Quadric&                   theQuad2,
+                                 const Handle(IntSurf_LineOn2S)&          theLine,
+                                 const ComputationMethods::stCoeffsValue& theCoeffs,
+                                 const Standard_Integer                   theWLIndex,
+                                 const Standard_Integer                   theMinNbPoints,
+                                 const Standard_Integer                   theStartPointOnLine,
+                                 const Standard_Integer                   theEndPointOnLine,
+                                 const Standard_Real                      theTol2D,
+                                 const Standard_Real                      thePeriodOfSurf2,
+                                 const Standard_Boolean                   isTheReverse)
+{
+  if (theLine.IsNull())
+    return;
+
+  Standard_Integer aNbPoints   = theEndPointOnLine - theStartPointOnLine + 1;
+
+  Standard_Real aMinDeltaParam = theTol2D;
+
+  {
+    Standard_Real u1 = 0.0, v1 = 0.0, u2 = 0.0, v2 = 0.0;
+
+    if (isTheReverse)
+    {
+      theLine->Value(theStartPointOnLine).ParametersOnS2(u1, v1);
+      theLine->Value(theEndPointOnLine).ParametersOnS2(u2, v2);
+    }
+    else
+    {
+      theLine->Value(theStartPointOnLine).ParametersOnS1(u1, v1);
+      theLine->Value(theEndPointOnLine).ParametersOnS1(u2, v2);
+    }
+
+    aMinDeltaParam = Max(Abs(u2 - u1) / IntToReal(theMinNbPoints), aMinDeltaParam);
+  }
+
+  Standard_Integer aLastPointIndex = theEndPointOnLine;
+  Standard_Real    U1prec = 0.0, V1prec = 0.0, U2prec = 0.0, V2prec = 0.0;
+
+  Standard_Integer aNbPointsPrev = 0;
+  do
+  {
+    aNbPointsPrev = aNbPoints;
+    for (Standard_Integer fp = theStartPointOnLine, lp = 0; fp < aLastPointIndex; fp = lp + 1)
+    {
+      Standard_Real U1f = 0.0, V1f = 0.0; //first point in 1st suraface
+      Standard_Real U1l = 0.0, V1l = 0.0; //last  point in 1st suraface
+
+      Standard_Real U2f = 0.0, V2f = 0.0; //first point in 2nd suraface
+      Standard_Real U2l = 0.0, V2l = 0.0; //last  point in 2nd suraface
+
+      lp = fp + 1;
+
+      if (isTheReverse)
+      {
+        theLine->Value(fp).ParametersOnS2(U1f, V1f);
+        theLine->Value(lp).ParametersOnS2(U1l, V1l);
+
+        theLine->Value(fp).ParametersOnS1(U2f, V2f);
+        theLine->Value(lp).ParametersOnS1(U2l, V2l);
+      }
+      else
+      {
+        theLine->Value(fp).ParametersOnS1(U1f, V1f);
+        theLine->Value(lp).ParametersOnS1(U1l, V1l);
+
+        theLine->Value(fp).ParametersOnS2(U2f, V2f);
+        theLine->Value(lp).ParametersOnS2(U2l, V2l);
+      }
+
+      if (Abs(U1l - U1f) <= aMinDeltaParam)
+      {
+        //Step is minimal. It is not necessary to divide it.
+        continue;
+      }
+
+      U1prec = 0.5 * (U1f + U1l);
+
+      if (!ComputationMethods::CylCylComputeParameters(U1prec, theWLIndex, theCoeffs, U2prec, V1prec, V2prec))
+      {
+        continue;
+      }
+
+      MinMax(U2f, U2l);
+      if (!InscribePoint(U2f, U2l, U2prec, theTol2D, thePeriodOfSurf2, Standard_False))
+      {
+        continue;
+      }
+
+      const gp_Pnt aP1(theQuad1.Value(U1prec, V1prec)), aP2(theQuad2.Value(U2prec, V2prec));
+      const gp_Pnt aPInt(0.5 * (aP1.XYZ() + aP2.XYZ()));
+
+#ifdef INTPATCH_IMPIMPINTERSECTION_DEBUG
+      std::cout << "|P1Pi| = " << aP1.SquareDistance(aPInt) << "; |P2Pi| = " << aP2.SquareDistance(aPInt) << std::endl;
+#endif
+
+      IntSurf_PntOn2S anIP;
+      if (isTheReverse)
+      {
+        anIP.SetValue(aPInt, U2prec, V2prec, U1prec, V1prec);
+      }
+      else
+      {
+        anIP.SetValue(aPInt, U1prec, V1prec, U2prec, V2prec);
+      }
+
+      theLine->InsertBefore(lp, anIP);
+
+      aNbPoints++;
+      aLastPointIndex++;
+    }
+
+    if (aNbPoints >= theMinNbPoints)
+    {
+      return;
+    }
+  } while (aNbPoints < theMinNbPoints && (aNbPoints != aNbPointsPrev));
+}
+
+//=======================================================================
+//function : BoundariesComputing
+//purpose  : Computes true domain of future intersection curve (allows
+//            avoiding excess iterations)
+//=======================================================================
+Standard_Boolean WorkWithBoundaries::BoundariesComputing(const ComputationMethods::stCoeffsValue& theCoeffs,
+                                                         const Standard_Real                      thePeriod,
+                                                         Bnd_Range                                theURange[])
+{
+  //All comments to this method is related to the comment
+  //to ComputationMethods class
+
+  //So, we have the equation
+  //    cos(U2-FI2)=B*cos(U1-FI1)+C
+  //Evidently,
+  //    -1 <= B*cos(U1-FI1)+C <= 1
+
+  if (theCoeffs.mB > 0.0)
+  {
+    // -(1+C)/B <= cos(U1-FI1) <= (1-C)/B
+
+    if (theCoeffs.mB + Abs(theCoeffs.mC) < -1.0)
+    {
+      //(1-C)/B < -1 or -(1+C)/B > 1  ==> No solution
+
+      return Standard_False;
+    }
+    else if (theCoeffs.mB + Abs(theCoeffs.mC) <= 1.0)
+    {
+      //(1-C)/B >= 1 and -(1+C)/B <= -1 ==> U=[0;2*PI]+aFI1
+      theURange[0].Add(theCoeffs.mFI1);
+      theURange[0].Add(thePeriod + theCoeffs.mFI1);
+    }
+    else if ((1 + theCoeffs.mC <= theCoeffs.mB) && (theCoeffs.mB <= 1 - theCoeffs.mC))
+    {
+      //(1-C)/B >= 1 and -(1+C)/B >= -1 ==>
+      //(U=[0;aDAngle]+aFI1) || (U=[2*PI-aDAngle;2*PI]+aFI1),
+      //where aDAngle = acos(-(myCoeffs.mC + 1) / myCoeffs.mB)
+
+      Standard_Real anArg = -(theCoeffs.mC + 1) / theCoeffs.mB;
+      if (anArg > 1.0)
+        anArg = 1.0;
+      if (anArg < -1.0)
+        anArg = -1.0;
+
+      const Standard_Real aDAngle = acos(anArg);
+      theURange[0].Add(theCoeffs.mFI1);
+      theURange[0].Add(aDAngle + theCoeffs.mFI1);
+      theURange[1].Add(thePeriod - aDAngle + theCoeffs.mFI1);
+      theURange[1].Add(thePeriod + theCoeffs.mFI1);
+    }
+    else if ((1 - theCoeffs.mC <= theCoeffs.mB) && (theCoeffs.mB <= 1 + theCoeffs.mC))
+    {
+      //(1-C)/B <= 1 and -(1+C)/B <= -1 ==> U=[aDAngle;2*PI-aDAngle]+aFI1
+      //where aDAngle = acos((1 - myCoeffs.mC) / myCoeffs.mB)
+
+      Standard_Real anArg = (1 - theCoeffs.mC) / theCoeffs.mB;
+      if (anArg > 1.0)
+        anArg = 1.0;
+      if (anArg < -1.0)
+        anArg = -1.0;
+
+      const Standard_Real aDAngle = acos(anArg);
+      theURange[0].Add(aDAngle + theCoeffs.mFI1);
+      theURange[0].Add(thePeriod - aDAngle + theCoeffs.mFI1);
+    }
+    else if (theCoeffs.mB - Abs(theCoeffs.mC) >= 1.0)
+    {
+      //(1-C)/B <= 1 and -(1+C)/B >= -1 ==>
+      //(U=[aDAngle1;aDAngle2]+aFI1) ||
+      //(U=[2*PI-aDAngle2;2*PI-aDAngle1]+aFI1)
+      //where aDAngle1 = acos((1 - myCoeffs.mC) / myCoeffs.mB),
+      //      aDAngle2 = acos(-(myCoeffs.mC + 1) / myCoeffs.mB).
+
+      Standard_Real anArg1 = (1 - theCoeffs.mC) / theCoeffs.mB, anArg2 = -(theCoeffs.mC + 1) / theCoeffs.mB;
+      if (anArg1 > 1.0)
+        anArg1 = 1.0;
+      if (anArg1 < -1.0)
+        anArg1 = -1.0;
+
+      if (anArg2 > 1.0)
+        anArg2 = 1.0;
+      if (anArg2 < -1.0)
+        anArg2 = -1.0;
+
+      const Standard_Real aDAngle1 = acos(anArg1), aDAngle2 = acos(anArg2);
+      //(U=[aDAngle1;aDAngle2]+aFI1) ||
+      //(U=[2*PI-aDAngle2;2*PI-aDAngle1]+aFI1)
+      theURange[0].Add(aDAngle1 + theCoeffs.mFI1);
+      theURange[0].Add(aDAngle2 + theCoeffs.mFI1);
+      theURange[1].Add(thePeriod - aDAngle2 + theCoeffs.mFI1);
+      theURange[1].Add(thePeriod - aDAngle1 + theCoeffs.mFI1);
+    }
+    else
+    {
+      return Standard_False;
+    }
+  }
+  else if (theCoeffs.mB < 0.0)
+  {
+    // (1-C)/B <= cos(U1-FI1) <= -(1+C)/B
+
+    if (theCoeffs.mB + Abs(theCoeffs.mC) > 1.0)
+    {
+      // -(1+C)/B < -1 or (1-C)/B > 1 ==> No solutions
+      return Standard_False;
+    }
+    else if (-theCoeffs.mB + Abs(theCoeffs.mC) <= 1.0)
+    {
+      //  -(1+C)/B >= 1 and (1-C)/B <= -1 ==> U=[0;2*PI]+aFI1
+      theURange[0].Add(theCoeffs.mFI1);
+      theURange[0].Add(thePeriod + theCoeffs.mFI1);
+    }
+    else if ((-theCoeffs.mC - 1 <= theCoeffs.mB) && (theCoeffs.mB <= theCoeffs.mC - 1))
+    {
+      //  -(1+C)/B >= 1 and (1-C)/B >= -1 ==>
+      //(U=[0;aDAngle]+aFI1) || (U=[2*PI-aDAngle;2*PI]+aFI1),
+      //where aDAngle = acos((1 - myCoeffs.mC) / myCoeffs.mB)
+
+      Standard_Real anArg = (1 - theCoeffs.mC) / theCoeffs.mB;
+      if (anArg > 1.0)
+        anArg = 1.0;
+      if (anArg < -1.0)
+        anArg = -1.0;
+
+      const Standard_Real aDAngle = acos(anArg);
+      theURange[0].Add(theCoeffs.mFI1);
+      theURange[0].Add(aDAngle + theCoeffs.mFI1);
+      theURange[1].Add(thePeriod - aDAngle + theCoeffs.mFI1);
+      theURange[1].Add(thePeriod + theCoeffs.mFI1);
+    }
+    else if ((theCoeffs.mC - 1 <= theCoeffs.mB) && (theCoeffs.mB <= -theCoeffs.mB - 1))
+    {
+      //  -(1+C)/B <= 1 and (1-C)/B <= -1 ==> U=[aDAngle;2*PI-aDAngle]+aFI1,
+      //where aDAngle = acos(-(myCoeffs.mC + 1) / myCoeffs.mB).
+
+      Standard_Real anArg = -(theCoeffs.mC + 1) / theCoeffs.mB;
+      if (anArg > 1.0)
+        anArg = 1.0;
+      if (anArg < -1.0)
+        anArg = -1.0;
+
+      const Standard_Real aDAngle = acos(anArg);
+      theURange[0].Add(aDAngle + theCoeffs.mFI1);
+      theURange[0].Add(thePeriod - aDAngle + theCoeffs.mFI1);
+    }
+    else if (-theCoeffs.mB - Abs(theCoeffs.mC) >= 1.0)
+    {
+      //  -(1+C)/B <= 1 and (1-C)/B >= -1 ==>
+      //(U=[aDAngle1;aDAngle2]+aFI1) || (U=[2*PI-aDAngle2;2*PI-aDAngle1]+aFI1),
+      //where aDAngle1 = acos(-(myCoeffs.mC + 1) / myCoeffs.mB),
+      //      aDAngle2 = acos((1 - myCoeffs.mC) / myCoeffs.mB)
+
+      Standard_Real anArg1 = -(theCoeffs.mC + 1) / theCoeffs.mB, anArg2 = (1 - theCoeffs.mC) / theCoeffs.mB;
+      if (anArg1 > 1.0)
+        anArg1 = 1.0;
+      if (anArg1 < -1.0)
+        anArg1 = -1.0;
+
+      if (anArg2 > 1.0)
+        anArg2 = 1.0;
+      if (anArg2 < -1.0)
+        anArg2 = -1.0;
+
+      const Standard_Real aDAngle1 = acos(anArg1), aDAngle2 = acos(anArg2);
+      theURange[0].Add(aDAngle1 + theCoeffs.mFI1);
+      theURange[0].Add(aDAngle2 + theCoeffs.mFI1);
+      theURange[1].Add(thePeriod - aDAngle2 + theCoeffs.mFI1);
+      theURange[1].Add(thePeriod - aDAngle1 + theCoeffs.mFI1);
+    }
+    else
+    {
+      return Standard_False;
+    }
+  }
+  else
+  {
+    return Standard_False;
+  }
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : CriticalPointsComputing
+//purpose  : theNbCritPointsMax contains true number of critical points.
+//            It must be initialized correctly before function calling
+//=======================================================================
+static void CriticalPointsComputing(const ComputationMethods::stCoeffsValue& theCoeffs,
+                                    const Standard_Real                      theUSurf1f,
+                                    const Standard_Real                      theUSurf1l,
+                                    const Standard_Real                      theUSurf2f,
+                                    const Standard_Real                      theUSurf2l,
+                                    const Standard_Real                      thePeriod,
+                                    const Standard_Real                      theTol2D,
+                                    Standard_Integer&                        theNbCritPointsMax,
+                                    Standard_Real                            theU1crit[])
+{
+  //[0...1] - in these points parameter U1 goes through
+  //          the seam-edge of the first cylinder.
+  //[2...3] - First and last U1 parameter.
+  //[4...5] - in these points parameter U2 goes through
+  //          the seam-edge of the second cylinder.
+  //[6...9] - in these points an intersection line goes through
+  //          U-boundaries of the second surface.
+  //[10...11] - Boundary of monotonicity interval of U2(U1) function
+  //            (see CylCylMonotonicity() function)
+
+  theU1crit[0]             = 0.0;
+  theU1crit[1]             = thePeriod;
+  theU1crit[2]             = theUSurf1f;
+  theU1crit[3]             = theUSurf1l;
+
+  const Standard_Real aCOS = cos(theCoeffs.mFI2);
+  const Standard_Real aBSB = Abs(theCoeffs.mB);
+  if ((theCoeffs.mC - aBSB <= aCOS) && (aCOS <= theCoeffs.mC + aBSB))
+  {
+    Standard_Real anArg = (aCOS - theCoeffs.mC) / theCoeffs.mB;
+    if (anArg > 1.0)
+      anArg = 1.0;
+    if (anArg < -1.0)
+      anArg = -1.0;
+
+    theU1crit[4] = -acos(anArg) + theCoeffs.mFI1;
+    theU1crit[5] = acos(anArg) + theCoeffs.mFI1;
+  }
+
+  Standard_Real aSf = cos(theUSurf2f - theCoeffs.mFI2);
+  Standard_Real aSl = cos(theUSurf2l - theCoeffs.mFI2);
+  MinMax(aSf, aSl);
+
+  //In accorance with pure mathematic, theU1crit[6] and [8]
+  //must be -Precision::Infinite() instead of used +Precision::Infinite()
+  theU1crit[6]  = Abs((aSl - theCoeffs.mC) / theCoeffs.mB) < 1.0 ? -acos((aSl - theCoeffs.mC) / theCoeffs.mB) + theCoeffs.mFI1
+                                                                 : Precision::Infinite();
+  theU1crit[7]  = Abs((aSf - theCoeffs.mC) / theCoeffs.mB) < 1.0 ? -acos((aSf - theCoeffs.mC) / theCoeffs.mB) + theCoeffs.mFI1
+                                                                 : Precision::Infinite();
+  theU1crit[8]  = Abs((aSf - theCoeffs.mC) / theCoeffs.mB) < 1.0 ? acos((aSf - theCoeffs.mC) / theCoeffs.mB) + theCoeffs.mFI1
+                                                                 : Precision::Infinite();
+  theU1crit[9]  = Abs((aSl - theCoeffs.mC) / theCoeffs.mB) < 1.0 ? acos((aSl - theCoeffs.mC) / theCoeffs.mB) + theCoeffs.mFI1
+                                                                 : Precision::Infinite();
+
+  theU1crit[10] = theCoeffs.mFI1;
+  theU1crit[11] = M_PI + theCoeffs.mFI1;
+
+  //preparative treatment of array. This array must have faled to contain negative
+  //infinity number
+
+  for (Standard_Integer i = 0; i < theNbCritPointsMax; i++)
+  {
+    if (Precision::IsInfinite(theU1crit[i]))
+    {
+      continue;
+    }
+
+    theU1crit[i] = fmod(theU1crit[i], thePeriod);
+    if (theU1crit[i] < 0.0)
+      theU1crit[i] += thePeriod;
+  }
+
+  //Here all not infinite elements of theU1crit are in [0, thePeriod) range
+
+  do
+  {
+    std::sort(theU1crit, theU1crit + theNbCritPointsMax);
+  } while (ExcludeNearElements(theU1crit, theNbCritPointsMax, theUSurf1f, theUSurf1l, theTol2D));
+
+  //Here all not infinite elements in theU1crit are different and sorted.
+
+  while (theNbCritPointsMax > 0)
+  {
+    Standard_Real& anB = theU1crit[theNbCritPointsMax - 1];
+    if (Precision::IsInfinite(anB))
+    {
+      theNbCritPointsMax--;
+      continue;
+    }
+
+    //1st not infinte element is found
+
+    if (theNbCritPointsMax == 1)
+      break;
+
+    //Here theNbCritPointsMax > 1
+
+    Standard_Real& anA = theU1crit[0];
+
+    //Compare 1st and last significant elements of theU1crit
+    //They may still differs by period.
+
+    if (Abs(anB - anA - thePeriod) < theTol2D)
+    { //E.g. anA == 2.0e-17, anB == (thePeriod-1.0e-18)
+      anA = (anA + anB - thePeriod) / 2.0;
+      anB = Precision::Infinite();
+      theNbCritPointsMax--;
+    }
+
+    //Out of "while(theNbCritPointsMax > 0)" cycle.
+    break;
+  }
+
+  //Attention! Here theU1crit may be unsorted.
+}
+
+//=======================================================================
+//function : BoundaryEstimation
+//purpose  : Rough estimation of the parameter range.
+//=======================================================================
+void WorkWithBoundaries::BoundaryEstimation(const gp_Cylinder& theCy1,
+                                            const gp_Cylinder& theCy2,
+                                            Bnd_Range&         theOutBoxS1,
+                                            Bnd_Range&         theOutBoxS2) const
+{
+  const gp_Dir &      aD1 = theCy1.Axis().Direction(), &aD2 = theCy2.Axis().Direction();
+  const Standard_Real aR1 = theCy1.Radius(), aR2 = theCy2.Radius();
+
+  //Let consider a parallelogram. Its edges are parallel to aD1 and aD2.
+  //Its altitudes are equal to 2*aR1 and 2*aR2 (diameters of the cylinders).
+  //In fact, this parallelogram is a projection of the cylinders to the plane
+  //created by the intersected axes aD1 and aD2 (if the axes are skewed then
+  //one axis can be translated by parallel shifting till intersection).
+
+  const Standard_Real aCosA   = aD1.Dot(aD2);
+  const Standard_Real aSqSinA = aD1.XYZ().CrossSquareMagnitude(aD2.XYZ());
+
+  //If sine is small then it can be compared with angle.
+  if (aSqSinA < Precision::Angular() * Precision::Angular())
+    return;
+
+  //Half of delta V. Delta V is a distance between
+  //projections of two opposite parallelogram vertices
+  //(joined by the maximal diagonal) to the cylinder axis.
+  const Standard_Real aSinA     = sqrt(aSqSinA);
+  const Standard_Real anAbsCosA = Abs(aCosA);
+  const Standard_Real aHDV1 = (aR1 * anAbsCosA + aR2) / aSinA, aHDV2 = (aR2 * anAbsCosA + aR1) / aSinA;
+
+#ifdef INTPATCH_IMPIMPINTERSECTION_DEBUG
+  //The code in this block is created for test only.It is stupidly to create
+  //OCCT-test for the method, which will be changed possibly never.
+  std::cout << "Reference values: aHDV1 = " << aHDV1 << "; aHDV2 = " << aHDV2 << std::endl;
+#endif
+
+  //V-parameters of intersection point of the axes (in case of skewed axes,
+  //see comment above).
+  Standard_Real aV01 = 0.0, aV02 = 0.0;
+  ExtremaLineLine(theCy1.Axis(), theCy2.Axis(), aCosA, aSqSinA, aV01, aV02);
+
+  theOutBoxS1.Add(aV01 - aHDV1);
+  theOutBoxS1.Add(aV01 + aHDV1);
+
+  theOutBoxS2.Add(aV02 - aHDV2);
+  theOutBoxS2.Add(aV02 + aHDV2);
+
+  theOutBoxS1.Enlarge(Precision::Confusion());
+  theOutBoxS2.Enlarge(Precision::Confusion());
+
+  Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
+  myUVSurf1.Get(aU1, aV1, aU2, aV2);
+  theOutBoxS1.Common(Bnd_Range(aV1, aV2));
+
+  myUVSurf2.Get(aU1, aV1, aU2, aV2);
+  theOutBoxS2.Common(Bnd_Range(aV1, aV2));
+}
+
+//=======================================================================
+//function : CyCyNoGeometric
+//purpose  :
+//=======================================================================
+static IntPatch_ImpImpIntersection::IntStatus CyCyNoGeometric(const gp_Cylinder&        theCyl1,
+                                                              const gp_Cylinder&        theCyl2,
+                                                              const WorkWithBoundaries& theBW,
+                                                              Bnd_Range                 theRange[],
+                                                              const Standard_Integer    theNbOfRanges /*=2*/,
+                                                              Standard_Boolean&         isTheEmpty,
+                                                              IntPatch_SequenceOfLine&  theSlin,
+                                                              IntPatch_SequenceOfPoint& theSPnt)
+{
+  Standard_Real aUSurf1f = 0.0, aUSurf1l = 0.0, aUSurf2f = 0.0, aUSurf2l = 0.0, aVSurf1f = 0.0, aVSurf1l = 0.0, aVSurf2f = 0.0,
+                aVSurf2l = 0.0;
+
+  theBW.UVS1().Get(aUSurf1f, aVSurf1f, aUSurf1l, aVSurf1l);
+  theBW.UVS2().Get(aUSurf2f, aVSurf2f, aUSurf2l, aVSurf2l);
+
+  Bnd_Range aRangeS1, aRangeS2;
+  theBW.BoundaryEstimation(theCyl1, theCyl2, aRangeS1, aRangeS2);
+  if (aRangeS1.IsVoid() || aRangeS2.IsVoid())
+    return IntPatch_ImpImpIntersection::IntStatus_OK;
+
+  {
+    //Quotation of the message from issue #26894 (author MSV):
+    //"We should return fail status from intersector if the result should be an
+    //infinite curve of non-analytical type... I propose to define the limit for the
+    //extent as the radius divided by 1e+2 and multiplied by 1e+7.
+    //Thus, taking into account the number of valuable digits (15), we provide reliable
+    //computations with an error not exceeding R/100."
+    const Standard_Real aF          = 1.0e+5;
+    const Standard_Real aMaxV1Range = aF * theCyl1.Radius(), aMaxV2Range = aF * theCyl2.Radius();
+    if ((aRangeS1.Delta() > aMaxV1Range) || (aRangeS2.Delta() > aMaxV2Range))
+      return IntPatch_ImpImpIntersection::IntStatus_InfiniteSectionCurve;
+  }
+  //
+  Standard_Boolean isGoodIntersection = Standard_False;
+  Standard_Real    anOptdu            = 0.;
+  for (;;)
+  {
+    //Checking parameters of cylinders in order to define "good intersection"
+    //"Good intersection" means that axes of cylinders are almost perpendicular and
+    // one radius is much smaller than the other and small cylinder is "inside" big one.
+    const Standard_Real aToMuchCoeff = 3.;
+    const Standard_Real aCritAngle   = M_PI / 18.; // 10 degree
+    Standard_Real       anR1         = theCyl1.Radius();
+    Standard_Real       anR2         = theCyl2.Radius();
+    Standard_Real       anRmin = 0., anRmax = 0.;
+    //Radius criterion
+    if (anR1 > aToMuchCoeff * anR2)
+    {
+      anRmax = anR1;
+      anRmin = anR2;
+    }
+    else if (anR2 > aToMuchCoeff * anR1)
+    {
+      anRmax = anR2;
+      anRmin = anR1;
+    }
+    else
+    {
+      break;
+    }
+    //Angle criterion
+    const gp_Ax1& anAx1 = theCyl1.Axis();
+    const gp_Ax1& anAx2 = theCyl2.Axis();
+    if (!anAx1.IsNormal(anAx2, aCritAngle))
+    {
+      break;
+    }
+    //Placement criterion
+    gp_Lin        anL1(anAx1), anL2(anAx2);
+    Standard_Real aDist = anL1.Distance(anL2);
+    if (aDist > anRmax / 2.)
+    {
+      break;
+    }
+
+    isGoodIntersection           = Standard_True;
+    //Estimation of "optimal" du
+    //Relative deflection, absolut deflection is Rmin*aDeflection
+    Standard_Real    aDeflection = 0.001;
+    Standard_Integer aNbP        = 3;
+    if (anRmin * aDeflection > 1.e-3)
+    {
+      Standard_Real anAngle = 1.0e0 - aDeflection;
+      anAngle               = 2.0e0 * ACos(anAngle);
+      aNbP                  = (Standard_Integer)(2. * M_PI / anAngle) + 1;
+    }
+    anOptdu = 2. * M_PI_2 / (Standard_Real)(aNbP - 1);
+    break;
+  }
+  //
+  const ComputationMethods::stCoeffsValue& anEquationCoeffs = theBW.SICoeffs();
+  const IntSurf_Quadric&                   aQuad1           = theBW.GetQSurface(1);
+  const IntSurf_Quadric&                   aQuad2           = theBW.GetQSurface(2);
+  const Standard_Boolean                   isReversed       = theBW.IsReversed();
+  const Standard_Real                      aTol2D           = theBW.Get2dTolerance();
+  const Standard_Real                      aTol3D           = theBW.Get3dTolerance();
+  const Standard_Real                      aPeriod          = 2.0 * M_PI;
+  Standard_Integer                         aNbMaxPoints     = 1000;
+  Standard_Integer                         aNbMinPoints     = 200;
+  Standard_Real                            du;
+  if (isGoodIntersection)
+  {
+    du           = anOptdu;
+    aNbMaxPoints = 200;
+    aNbMinPoints = 50;
+  }
+  else
+  {
+    du = 2. * M_PI / aNbMaxPoints;
+  }
+  Standard_Integer       aNbPts    = Min(RealToInt((aUSurf1l - aUSurf1f) / du) + 1, RealToInt(20.0 * theCyl1.Radius()));
+  const Standard_Integer aNbPoints = Min(Max(aNbMinPoints, aNbPts), aNbMaxPoints);
+  const Standard_Real    aStepMin = Max(aTol2D, Precision::PConfusion()), aStepMax = (aUSurf1l - aUSurf1f > M_PI / 100.0)
+                                                                                     ? (aUSurf1l - aUSurf1f) / IntToReal(aNbPoints)
+                                                                                     : aUSurf1l - aUSurf1f;
+
+  //The main idea of the algorithm is to change U1-parameter
+  //(U-parameter of theCyl1) from aU1f to aU1l with some step
+  //(step is adaptive) and to obtain set of intersection points.
+
+  for (Standard_Integer i = 0; i < theNbOfRanges; i++)
+  {
+    if (theRange[i].IsVoid())
+      continue;
+
+    InscribeInterval(aUSurf1f, aUSurf1l, theRange[i], aTol2D, aPeriod);
+  }
+
+  if (theRange[0].Union(theRange[1]))
+  {
+    // Works only if (theNbOfRanges == 2).
+    theRange[1].SetVoid();
+  }
+
+  //Critical points are the value of U1-parameter in the points
+  //where WL must be decomposed.
+
+  //When U1 goes through critical points its value is set up to this
+  //parameter forcefully and the intersection point is added in the line.
+  //After that, the WL is broken (next U1 value will be correspond to the new WL).
+
+  //See CriticalPointsComputing(...) function to get detail information about this array.
+  const Standard_Integer aNbCritPointsMax           = 12;
+  Standard_Real          anU1crit[aNbCritPointsMax] = {Precision::Infinite(),
+                                                       Precision::Infinite(),
+                                                       Precision::Infinite(),
+                                                       Precision::Infinite(),
+                                                       Precision::Infinite(),
+                                                       Precision::Infinite(),
+                                                       Precision::Infinite(),
+                                                       Precision::Infinite(),
+                                                       Precision::Infinite(),
+                                                       Precision::Infinite(),
+                                                       Precision::Infinite(),
+                                                       Precision::Infinite()};
+
+  //This list of critical points is not full because it does not contain any points
+  //which intersection line goes through V-bounds of cylinders in.
+  //They are computed by numerical methods on - line (during algorithm working).
+  //The moment is caught, when intersection line goes through V-bounds of any cylinder.
+
+  Standard_Integer aNbCritPoints                    = aNbCritPointsMax;
+  CriticalPointsComputing(anEquationCoeffs, aUSurf1f, aUSurf1l, aUSurf2f, aUSurf2l, aPeriod, aTol2D, aNbCritPoints, anU1crit);
+
+  //Getting Walking-line
+
+  enum WLFStatus
+  {
+    // No points have been added in WL
+    WLFStatus_Absent = 0,
+    // WL contains at least one point
+    WLFStatus_Exist  = 1,
+    // WL has been finished in some critical point
+    // We should start new line
+    WLFStatus_Broken = 2
+  };
+
+  const Standard_Integer aNbWLines = 2;
+  for (Standard_Integer aCurInterval = 0; aCurInterval < theNbOfRanges; aCurInterval++)
+  {
+    //Process every continuous region
+    Standard_Boolean isAddedIntoWL[aNbWLines];
+    for (Standard_Integer i = 0; i < aNbWLines; i++)
+      isAddedIntoWL[i] = Standard_False;
+
+    Standard_Real anUf = 1.0, anUl = 0.0;
+    if (!theRange[aCurInterval].GetBounds(anUf, anUl))
+      continue;
+
+    const Standard_Boolean isDeltaPeriod = IsEqual(anUl - anUf, aPeriod);
+
+    //Inscribe and sort critical points
+    for (Standard_Integer i = 0; i < aNbCritPoints; i++)
+    {
+      InscribePoint(anUf, anUl, anU1crit[i], 0.0, aPeriod, Standard_False);
+    }
+
+    std::sort(anU1crit, anU1crit + aNbCritPoints);
+
+    while (anUf < anUl)
+    {
+      //Change value of U-parameter on the 1st surface from anUf to anUl
+      //(anUf will be modified in the cycle body).
+      //Step is computed adaptively (see comments below).
+
+      Standard_Real    aU2[aNbWLines], aV1[aNbWLines], aV2[aNbWLines];
+      WLFStatus        aWLFindStatus[aNbWLines];
+      Standard_Real    aV1Prev[aNbWLines], aV2Prev[aNbWLines];
+      Standard_Real    anUexpect[aNbWLines];
+      Standard_Boolean isAddingWLEnabled[aNbWLines];
+
+      Handle(IntSurf_LineOn2S) aL2S[aNbWLines];
+      Handle(IntPatch_WLine)   aWLine[aNbWLines];
+      for (Standard_Integer i = 0; i < aNbWLines; i++)
+      {
+        aL2S[i]   = new IntSurf_LineOn2S();
+        aWLine[i] = new IntPatch_WLine(aL2S[i], Standard_False);
+        aWLine[i]->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLImpImp);
+        aWLFindStatus[i]     = WLFStatus_Absent;
+        isAddingWLEnabled[i] = Standard_True;
+        aU2[i] = aV1[i] = aV2[i] = 0.0;
+        aV1Prev[i] = aV2Prev[i] = 0.0;
+        anUexpect[i]            = anUf;
+      }
+
+      Standard_Real aCriticalDelta[aNbCritPointsMax] = {0};
+      for (Standard_Integer aCritPID = 0; aCritPID < aNbCritPoints; aCritPID++)
+      { //We are not interested in elements of aCriticalDelta array
+        //if their index is greater than or equal to aNbCritPoints
+
+        aCriticalDelta[aCritPID] = anUf - anU1crit[aCritPID];
+      }
+
+      Standard_Real    anU1 = anUf, aMinCriticalParam = anUf;
+      Standard_Boolean isFirst = Standard_True;
+
+      while (anU1 <= anUl)
+      {
+        //Change value of U-parameter on the 1st surface from anUf to anUl
+        //(anUf will be modified in the cycle body). However, this cycle
+        //can be broken if WL goes though some critical point.
+        //Step is computed adaptively (see comments below).
+
+        for (Standard_Integer i = 0; i < aNbCritPoints; i++)
+        {
+          if ((anU1 - anU1crit[i]) * aCriticalDelta[i] < 0.0)
+          {
+            //WL has gone through i-th critical point
+            anU1 = anU1crit[i];
+
+            for (Standard_Integer j = 0; j < aNbWLines; j++)
+            {
+              aWLFindStatus[j] = WLFStatus_Broken;
+              anUexpect[j]     = anU1;
+            }
+
+            break;
+          }
+        }
+
+        if (IsEqual(anU1, anUl))
+        {
+          for (Standard_Integer i = 0; i < aNbWLines; i++)
+          {
+            aWLFindStatus[i] = WLFStatus_Broken;
+            anUexpect[i]     = anU1;
+
+            if (isDeltaPeriod)
+            {
+              //if isAddedIntoWL[i] == TRUE WLine contains only one point
+              //(which was end point of previous WLine). If we will
+              //add point found on the current step WLine will contain only
+              //two points. At that both these points will be equal to the
+              //points found earlier. Therefore, new WLine will repeat
+              //already existing WLine. Consequently, it is necessary
+              //to forbid building new line in this case.
+
+              isAddingWLEnabled[i] = (!isAddedIntoWL[i]);
+            }
+            else
+            {
+              isAddingWLEnabled[i] = ((aTol2D >= (anUexpect[i] - anU1)) || (aWLFindStatus[i] == WLFStatus_Absent));
+            }
+          } //for(Standard_Integer i = 0; i < aNbWLines; i++)
+        }
+        else
+        {
+          for (Standard_Integer i = 0; i < aNbWLines; i++)
+          {
+            isAddingWLEnabled[i] = ((aTol2D >= (anUexpect[i] - anU1)) || (aWLFindStatus[i] == WLFStatus_Absent));
+          } //for(Standard_Integer i = 0; i < aNbWLines; i++)
+        }
+
+        for (Standard_Integer i = 0; i < aNbWLines; i++)
+        {
+          const Standard_Integer aNbPntsWL = aWLine[i].IsNull() ? 0 : aWLine[i]->Curve()->NbPoints();
+
+          if ((aWLFindStatus[i] == WLFStatus_Broken) || (aWLFindStatus[i] == WLFStatus_Absent))
+          { //Begin and end of WLine must be on boundary point
+            //or on seam-edge strictly (if it is possible).
+
+            Standard_Real aTol = aTol2D;
+            ComputationMethods::CylCylComputeParameters(anU1, i, anEquationCoeffs, aU2[i], &aTol);
+            InscribePoint(aUSurf2f, aUSurf2l, aU2[i], aTol2D, aPeriod, Standard_False);
+
+            aTol = Max(aTol, aTol2D);
+
+            if (Abs(aU2[i]) <= aTol)
+              aU2[i] = 0.0;
+            else if (Abs(aU2[i] - aPeriod) <= aTol)
+              aU2[i] = aPeriod;
+            else if (Abs(aU2[i] - aUSurf2f) <= aTol)
+              aU2[i] = aUSurf2f;
+            else if (Abs(aU2[i] - aUSurf2l) <= aTol)
+              aU2[i] = aUSurf2l;
+          }
+          else
+          {
+            ComputationMethods::CylCylComputeParameters(anU1, i, anEquationCoeffs, aU2[i]);
+            InscribePoint(aUSurf2f, aUSurf2l, aU2[i], aTol2D, aPeriod, Standard_False);
+          }
+
+          if (aNbPntsWL == 0)
+          { //the line has not contained any points yet
+            if (((aUSurf2f + aPeriod - aUSurf2l) <= 2.0 * aTol2D)
+                && ((Abs(aU2[i] - aUSurf2f) < aTol2D) || (Abs(aU2[i] - aUSurf2l) < aTol2D)))
+            {
+              //In this case aU2[i] can have two values: current aU2[i] or
+              //aU2[i]+aPeriod (aU2[i]-aPeriod). It is necessary to choose
+              //correct value.
+
+              Standard_Boolean isIncreasing = Standard_True;
+              ComputationMethods::CylCylMonotonicity(anU1 + aStepMin, i, anEquationCoeffs, aPeriod, isIncreasing);
+
+              //If U2(U1) is increasing and U2 is considered to be equal aUSurf2l
+              //then after the next step (when U1 will be increased) U2 will be
+              //increased too. And we will go out of surface boundary.
+              //Therefore, If U2(U1) is increasing then U2 must be equal aUSurf2f.
+              //Analogically, if U2(U1) is decreasing.
+              if (isIncreasing)
+              {
+                aU2[i] = aUSurf2f;
+              }
+              else
+              {
+                aU2[i] = aUSurf2l;
+              }
+            }
+          }
+          else
+          { //aNbPntsWL > 0
+            if (((aUSurf2l - aUSurf2f) >= aPeriod) && ((Abs(aU2[i] - aUSurf2f) < aTol2D) || (Abs(aU2[i] - aUSurf2l) < aTol2D)))
+            { //end of the line
+              Standard_Real aU2prev = 0.0, aV2prev = 0.0;
+              if (isReversed)
+                aWLine[i]->Curve()->Value(aNbPntsWL).ParametersOnS1(aU2prev, aV2prev);
+              else
+                aWLine[i]->Curve()->Value(aNbPntsWL).ParametersOnS2(aU2prev, aV2prev);
+
+              if (2.0 * Abs(aU2prev - aU2[i]) > aPeriod)
+              {
+                if (aU2prev > aU2[i])
+                  aU2[i] += aPeriod;
+                else
+                  aU2[i] -= aPeriod;
+              }
+            }
+          }
+
+          ComputationMethods::CylCylComputeParameters(anU1, aU2[i], anEquationCoeffs, aV1[i], aV2[i]);
+
+          if (isFirst)
+          {
+            aV1Prev[i] = aV1[i];
+            aV2Prev[i] = aV2[i];
+          }
+        } //for(Standard_Integer i = 0; i < aNbWLines; i++)
+
+        isFirst                   = Standard_False;
+
+        //Looking for points into WLine
+        Standard_Boolean isBroken = Standard_False;
+        for (Standard_Integer i = 0; i < aNbWLines; i++)
+        {
+          if (!isAddingWLEnabled[i])
+          {
+            Standard_Boolean isBoundIntersect = Standard_False;
+            if ((Abs(aV1[i] - aVSurf1f) <= aTol2D) || ((aV1[i] - aVSurf1f) * (aV1Prev[i] - aVSurf1f) < 0.0))
+            {
+              isBoundIntersect = Standard_True;
+            }
+            else if ((Abs(aV1[i] - aVSurf1l) <= aTol2D) || ((aV1[i] - aVSurf1l) * (aV1Prev[i] - aVSurf1l) < 0.0))
+            {
+              isBoundIntersect = Standard_True;
+            }
+            else if ((Abs(aV2[i] - aVSurf2f) <= aTol2D) || ((aV2[i] - aVSurf2f) * (aV2Prev[i] - aVSurf2f) < 0.0))
+            {
+              isBoundIntersect = Standard_True;
+            }
+            else if ((Abs(aV2[i] - aVSurf2l) <= aTol2D) || ((aV2[i] - aVSurf2l) * (aV2Prev[i] - aVSurf2l) < 0.0))
+            {
+              isBoundIntersect = Standard_True;
+            }
+
+            if (aWLFindStatus[i] == WLFStatus_Broken)
+              isBroken = Standard_True;
+
+            if (!isBoundIntersect)
+            {
+              continue;
+            }
+            else
+            {
+              anUexpect[i] = anU1;
+            }
+          }
+
+          // True if the current point already in the domain
+          const Standard_Boolean isInscribe = ((aUSurf2f - aU2[i]) <= aTol2D) && ((aU2[i] - aUSurf2l) <= aTol2D)
+                                           && ((aVSurf1f - aV1[i]) <= aTol2D) && ((aV1[i] - aVSurf1l) <= aTol2D)
+                                           && ((aVSurf2f - aV2[i]) <= aTol2D) && ((aV2[i] - aVSurf2l) <= aTol2D);
+
+          //isVIntersect == TRUE if intersection line intersects two (!)
+          //V-bounds of cylinder (1st or 2nd - no matter)
+          const Standard_Boolean isVIntersect = (((aVSurf1f - aV1[i]) * (aVSurf1f - aV1Prev[i]) < RealSmall())
+                                                 && ((aVSurf1l - aV1[i]) * (aVSurf1l - aV1Prev[i]) < RealSmall()))
+                                             || (((aVSurf2f - aV2[i]) * (aVSurf2f - aV2Prev[i]) < RealSmall())
+                                                 && ((aVSurf2l - aV2[i]) * (aVSurf2l - aV2Prev[i]) < RealSmall()));
+
+          //isFound1 == TRUE if intersection line intersects V-bounds
+          //  (First or Last - no matter) of the 1st cylynder
+          //isFound2 == TRUE if intersection line intersects V-bounds
+          //  (First or Last - no matter) of the 2nd cylynder
+          Standard_Boolean isFound1 = Standard_False, isFound2 = Standard_False;
+          Standard_Boolean isForce = Standard_False;
+
+          if (aWLFindStatus[i] == WLFStatus_Absent)
+          {
+            if (((aUSurf2l - aUSurf2f) >= aPeriod) && (Abs(anU1 - aUSurf1l) < aTol2D))
+            {
+              isForce = Standard_True;
+            }
+          }
+
+          theBW.AddBoundaryPoint(aWLine[i],
+                                 anU1,
+                                 aMinCriticalParam,
+                                 aU2[i],
+                                 aV1[i],
+                                 aV1Prev[i],
+                                 aV2[i],
+                                 aV2Prev[i],
+                                 i,
+                                 isForce,
+                                 isFound1,
+                                 isFound2);
+
+          const Standard_Boolean isPrevVBound = !isVIntersect
+                                             && ((Abs(aV1Prev[i] - aVSurf1f) <= aTol2D)
+                                                 || (Abs(aV1Prev[i] - aVSurf1l) <= aTol2D)
+                                                 || (Abs(aV2Prev[i] - aVSurf2f) <= aTol2D)
+                                                 || (Abs(aV2Prev[i] - aVSurf2l) <= aTol2D));
+
+          aV1Prev[i] = aV1[i];
+          aV2Prev[i] = aV2[i];
+
+          if ((aWLFindStatus[i] == WLFStatus_Exist) && (isFound1 || isFound2) && !isPrevVBound)
+          {
+            aWLFindStatus[i] = WLFStatus_Broken; //start a new line
+          }
+          else if (isInscribe)
+          {
+            if ((aWLFindStatus[i] == WLFStatus_Absent) && (isFound1 || isFound2))
+            {
+              aWLFindStatus[i] = WLFStatus_Exist;
+            }
+
+            if ((aWLFindStatus[i] != WLFStatus_Broken) || (aWLine[i]->NbPnts() >= 1) || IsEqual(anU1, anUl))
+            {
+              if (aWLine[i]->NbPnts() > 0)
+              {
+                Standard_Real aU2p = 0.0, aV2p = 0.0;
+                if (isReversed)
+                  aWLine[i]->Point(aWLine[i]->NbPnts()).ParametersOnS1(aU2p, aV2p);
+                else
+                  aWLine[i]->Point(aWLine[i]->NbPnts()).ParametersOnS2(aU2p, aV2p);
+
+                const Standard_Real aDelta = aU2[i] - aU2p;
+
+                if (2.0 * Abs(aDelta) > aPeriod)
+                {
+                  if (aDelta > 0.0)
+                  {
+                    aU2[i] -= aPeriod;
+                  }
+                  else
+                  {
+                    aU2[i] += aPeriod;
+                  }
+                }
+              }
+
+              if (AddPointIntoWL(aQuad1,
+                                 aQuad2,
+                                 anEquationCoeffs,
+                                 isReversed,
+                                 Standard_True,
+                                 gp_Pnt2d(anU1, aV1[i]),
+                                 gp_Pnt2d(aU2[i], aV2[i]),
+                                 aUSurf1f,
+                                 aUSurf1l,
+                                 aUSurf2f,
+                                 aUSurf2l,
+                                 aVSurf1f,
+                                 aVSurf1l,
+                                 aVSurf2f,
+                                 aVSurf2l,
+                                 aPeriod,
+                                 aWLine[i]->Curve(),
+                                 i,
+                                 aTol3D,
+                                 aTol2D,
+                                 isForce))
+              {
+                if (aWLFindStatus[i] == WLFStatus_Absent)
+                {
+                  aWLFindStatus[i] = WLFStatus_Exist;
+                }
+              }
+              else if (!isFound1 && !isFound2)
+              { //We do not add any point while doing this iteration
+                if (aWLFindStatus[i] == WLFStatus_Exist)
+                {
+                  aWLFindStatus[i] = WLFStatus_Broken;
+                }
+              }
+            }
+          }
+          else
+          { //We do not add any point while doing this iteration
+            if (aWLFindStatus[i] == WLFStatus_Exist)
+            {
+              aWLFindStatus[i] = WLFStatus_Broken;
+            }
+          }
+
+          if (aWLFindStatus[i] == WLFStatus_Broken)
+            isBroken = Standard_True;
+        } //for(Standard_Integer i = 0; i < aNbWLines; i++)
+
+        if (isBroken)
+        { //current lines are filled. Go to the next lines
+          anUf                     = anU1;
+
+          Standard_Boolean isAdded = Standard_True;
+
+          for (Standard_Integer i = 0; i < aNbWLines; i++)
+          {
+            if (isAddingWLEnabled[i])
+            {
+              continue;
+            }
+
+            isAdded                   = Standard_False;
+
+            Standard_Boolean isFound1 = Standard_False, isFound2 = Standard_False;
+
+            theBW.AddBoundaryPoint(aWLine[i],
+                                   anU1,
+                                   aMinCriticalParam,
+                                   aU2[i],
+                                   aV1[i],
+                                   aV1Prev[i],
+                                   aV2[i],
+                                   aV2Prev[i],
+                                   i,
+                                   Standard_False,
+                                   isFound1,
+                                   isFound2);
+
+            if (isFound1 || isFound2)
+            {
+              isAdded = Standard_True;
+            }
+
+            if (aWLine[i]->NbPnts() > 0)
+            {
+              Standard_Real aU2p = 0.0, aV2p = 0.0;
+              if (isReversed)
+                aWLine[i]->Point(aWLine[i]->NbPnts()).ParametersOnS1(aU2p, aV2p);
+              else
+                aWLine[i]->Point(aWLine[i]->NbPnts()).ParametersOnS2(aU2p, aV2p);
+
+              const Standard_Real aDelta = aU2[i] - aU2p;
+
+              if (2 * Abs(aDelta) > aPeriod)
+              {
+                if (aDelta > 0.0)
+                {
+                  aU2[i] -= aPeriod;
+                }
+                else
+                {
+                  aU2[i] += aPeriod;
+                }
+              }
+            }
+
+            if (AddPointIntoWL(aQuad1,
+                               aQuad2,
+                               anEquationCoeffs,
+                               isReversed,
+                               Standard_True,
+                               gp_Pnt2d(anU1, aV1[i]),
+                               gp_Pnt2d(aU2[i], aV2[i]),
+                               aUSurf1f,
+                               aUSurf1l,
+                               aUSurf2f,
+                               aUSurf2l,
+                               aVSurf1f,
+                               aVSurf1l,
+                               aVSurf2f,
+                               aVSurf2l,
+                               aPeriod,
+                               aWLine[i]->Curve(),
+                               i,
+                               aTol3D,
+                               aTol2D,
+                               Standard_False))
+            {
+              isAdded = Standard_True;
+            }
+          }
+
+          if (!isAdded)
+          {
+            //Before breaking WL, we must complete it correctly
+            //(e.g. to prolong to the surface boundary).
+            //Therefore, we take the point last added in some WL
+            //(have maximal U1-parameter) and try to add it in
+            //the current WL.
+            Standard_Real anUmaxAdded = RealFirst();
+
+            {
+              Standard_Boolean isChanged = Standard_False;
+              for (Standard_Integer i = 0; i < aNbWLines; i++)
+              {
+                if ((aWLFindStatus[i] == WLFStatus_Absent) || (aWLine[i]->NbPnts() == 0))
+                  continue;
+
+                Standard_Real aU1c = 0.0, aV1c = 0.0;
+                if (isReversed)
+                  aWLine[i]->Curve()->Value(aWLine[i]->NbPnts()).ParametersOnS2(aU1c, aV1c);
+                else
+                  aWLine[i]->Curve()->Value(aWLine[i]->NbPnts()).ParametersOnS1(aU1c, aV1c);
+
+                anUmaxAdded = Max(anUmaxAdded, aU1c);
+                isChanged   = Standard_True;
+              }
+
+              if (!isChanged)
+              { //If anUmaxAdded were not changed in previous cycle then
+                //we would break existing WLines.
+                break;
+              }
+            }
+
+            for (Standard_Integer i = 0; i < aNbWLines; i++)
+            {
+              if (isAddingWLEnabled[i])
+              {
+                continue;
+              }
+
+              ComputationMethods::CylCylComputeParameters(anUmaxAdded, i, anEquationCoeffs, aU2[i], aV1[i], aV2[i]);
+
+              AddPointIntoWL(aQuad1,
+                             aQuad2,
+                             anEquationCoeffs,
+                             isReversed,
+                             Standard_True,
+                             gp_Pnt2d(anUmaxAdded, aV1[i]),
+                             gp_Pnt2d(aU2[i], aV2[i]),
+                             aUSurf1f,
+                             aUSurf1l,
+                             aUSurf2f,
+                             aUSurf2l,
+                             aVSurf1f,
+                             aVSurf1l,
+                             aVSurf2f,
+                             aVSurf2l,
+                             aPeriod,
+                             aWLine[i]->Curve(),
+                             i,
+                             aTol3D,
+                             aTol2D,
+                             Standard_False);
+            }
+          }
+
+          break;
+        }
+
+        //Step computing
+
+        {
+          //Step of aU1-parameter is computed adaptively. The algorithm
+          //aims to provide given aDeltaV1 and aDeltaV2 values (if it is
+          //possible because the intersection line can go along V-isoline)
+          //in every iteration. It allows avoiding "flying" intersection
+          //points too far each from other (see issue #24915).
+
+          const Standard_Real aDeltaV1 = aRangeS1.Delta() / IntToReal(aNbPoints),
+                              aDeltaV2 = aRangeS2.Delta() / IntToReal(aNbPoints);
+
+          math_Matrix aMatr(1, 3, 1, 5);
+
+          Standard_Real aMinUexp = RealLast();
+
+          for (Standard_Integer i = 0; i < aNbWLines; i++)
+          {
+            if (aTol2D < (anUexpect[i] - anU1))
+            {
+              continue;
+            }
+
+            if (aWLFindStatus[i] == WLFStatus_Absent)
+            {
+              anUexpect[i] += aStepMax;
+              aMinUexp = Min(aMinUexp, anUexpect[i]);
+              continue;
+            }
+            //
+            if (isGoodIntersection)
+            {
+              //Use constant step
+              anUexpect[i] += aStepMax;
+              aMinUexp = Min(aMinUexp, anUexpect[i]);
+
+              continue;
+            }
+            //
+
+            Standard_Real aStepTmp     = aStepMax;
+
+            const Standard_Real aSinU1 = sin(anU1), aCosU1 = cos(anU1), aSinU2 = sin(aU2[i]), aCosU2 = cos(aU2[i]);
+
+            aMatr.SetCol(1, anEquationCoeffs.mVecC1);
+            aMatr.SetCol(2, anEquationCoeffs.mVecC2);
+            aMatr.SetCol(3, anEquationCoeffs.mVecA1 * aSinU1 - anEquationCoeffs.mVecB1 * aCosU1);
+            aMatr.SetCol(4, anEquationCoeffs.mVecA2 * aSinU2 - anEquationCoeffs.mVecB2 * aCosU2);
+            aMatr.SetCol(5,
+                         anEquationCoeffs.mVecA1 * aCosU1 + anEquationCoeffs.mVecB1 * aSinU1 + anEquationCoeffs.mVecA2 * aCosU2
+                           + anEquationCoeffs.mVecB2 * aSinU2 + anEquationCoeffs.mVecD);
+
+            //The main idea is in solving of linearized system (2)
+            //(see description to ComputationMethods class) in order to find new U1-value
+            //to provide new value V1 or V2, which differs from current one by aDeltaV1 or
+            //aDeltaV2 respectively.
+
+            //While linearizing, following Taylor formulas are used:
+            //    cos(x0+dx) = cos(x0) - sin(x0)*dx
+            //    sin(x0+dx) = sin(x0) + cos(x0)*dx
+
+            //Consequently cos(U1), cos(U2), sin(U1) and sin(U2) in the system (2)
+            //must be substituted by corresponding values.
+
+            //ATTENTION!!!
+            //The solution is approximate. More over, all requirements to the
+            //linearization must be satisfied in order to obtain quality result.
+
+            if (!StepComputing(aMatr, aV1[i], aV2[i], aDeltaV1, aDeltaV2, aStepTmp))
+            {
+              //To avoid cycling-up
+              anUexpect[i] += aStepMax;
+              aMinUexp = Min(aMinUexp, anUexpect[i]);
+
+              continue;
+            }
+
+            if (aStepTmp < aStepMin)
+              aStepTmp = aStepMin;
+
+            if (aStepTmp > aStepMax)
+              aStepTmp = aStepMax;
+
+            anUexpect[i] = anU1 + aStepTmp;
+            aMinUexp     = Min(aMinUexp, anUexpect[i]);
+          }
+
+          anU1 = aMinUexp;
+        }
+
+        if (Precision::PConfusion() >= (anUl - anU1))
+          anU1 = anUl;
+
+        anUf = anU1;
+
+        for (Standard_Integer i = 0; i < aNbWLines; i++)
+        {
+          if (aWLine[i]->NbPnts() != 1)
+            isAddedIntoWL[i] = Standard_False;
+
+          if (anU1 == anUl)
+          { //strictly equal. Tolerance is considered above.
+            anUexpect[i] = anUl;
+          }
+        }
+      }
+
+      for (Standard_Integer i = 0; i < aNbWLines; i++)
+      {
+        if ((aWLine[i]->NbPnts() == 1) && (!isAddedIntoWL[i]))
+        {
+          isTheEmpty = Standard_False;
+          Standard_Real u1, v1, u2, v2;
+          aWLine[i]->Point(1).Parameters(u1, v1, u2, v2);
+          IntPatch_Point aP;
+          aP.SetParameter(u1);
+          aP.SetParameters(u1, v1, u2, v2);
+          aP.SetTolerance(aTol3D);
+          aP.SetValue(aWLine[i]->Point(1).Value());
+
+          //Check whether the added point exists.
+          //It is enough to check the last point.
+          if (theSPnt.IsEmpty() || !theSPnt.Last().PntOn2S().IsSame(aP.PntOn2S(), Precision::Confusion()))
+          {
+            theSPnt.Append(aP);
+          }
+        }
+        else if (aWLine[i]->NbPnts() > 1)
+        {
+          Standard_Boolean isGood = Standard_True;
+
+          if (aWLine[i]->NbPnts() == 2)
+          {
+            const IntSurf_PntOn2S& aPf = aWLine[i]->Point(1);
+            const IntSurf_PntOn2S& aPl = aWLine[i]->Point(2);
+
+            if (aPf.IsSame(aPl, Precision::Confusion()))
+              isGood = Standard_False;
+          }
+          else if (aWLine[i]->NbPnts() > 2)
+          {
+            // Sometimes points of the WLine are distributed
+            // linearly and uniformly. However, such position
+            // of the points does not always describe the real intersection
+            // curve. I.e. real tangents at the ends of the intersection
+            // curve can significantly deviate from this "line" direction.
+            // Here we are processing this case by inserting additional points
+            // to the beginning/end of the WLine to make it more precise.
+            // See description to the issue #30082.
+
+            const Standard_Real aSqTol3D = aTol3D * aTol3D;
+            for (Standard_Integer j = 0; j < 2; j++)
+            {
+              // If j == 0 ==> add point at begin of WLine.
+              // If j == 1 ==> add point at end of WLine.
+
+              for (;;)
+              {
+                if (aWLine[i]->NbPnts() >= aNbMaxPoints)
+                {
+                  break;
+                }
+
+                // Take 1st and 2nd point to compute the "line" direction.
+                // For our convenience, we make 2nd point be the ends of the WLine
+                // because it will be used for computation of the normals
+                // to the surfaces.
+                const Standard_Integer anIdx1 = j ? aWLine[i]->NbPnts() - 1 : 2;
+                const Standard_Integer anIdx2 = j ? aWLine[i]->NbPnts() : 1;
+
+                const gp_Pnt& aP1             = aWLine[i]->Point(anIdx1).Value();
+                const gp_Pnt& aP2             = aWLine[i]->Point(anIdx2).Value();
+
+                const gp_Vec aDir(aP1, aP2);
+
+                if (aDir.SquareMagnitude() < aSqTol3D)
+                {
+                  break;
+                }
+
+                // Compute tangent in first/last point of the WLine.
+                // We do not take into account the flag "isReversed"
+                // because strict direction of the tangent is not
+                // important here (we are interested in the tangent
+                // line itself and nothing to fear if its direction
+                // is reversed).
+                const gp_Vec aN1 = aQuad1.Normale(aP2);
+                const gp_Vec aN2 = aQuad2.Normale(aP2);
+                const gp_Vec aTg(aN1.Crossed(aN2));
+
+                if (aTg.SquareMagnitude() < Precision::SquareConfusion())
+                {
+                  // Tangent zone
+                  break;
+                }
+
+                // Check of the bending
+                Standard_Real anAngle = aDir.Angle(aTg);
+
+                if (anAngle > M_PI_2)
+                  anAngle -= M_PI;
+
+                if (Abs(anAngle) > 0.25) // ~ 14deg.
+                {
+                  const Standard_Integer aNbPntsPrev = aWLine[i]->NbPnts();
+                  SeekAdditionalPoints(aQuad1,
+                                       aQuad2,
+                                       aWLine[i]->Curve(),
+                                       anEquationCoeffs,
+                                       i,
+                                       3,
+                                       anIdx1,
+                                       anIdx2,
+                                       aTol2D,
+                                       aPeriod,
+                                       isReversed);
+
+                  if (aWLine[i]->NbPnts() == aNbPntsPrev)
+                  {
+                    // No points have been added. ==> Exit from a loop.
+                    break;
+                  }
+                }
+                else
+                {
+                  // Good result has been achieved. ==> Exit from a loop.
+                  break;
+                }
+              } // for (;;)
+            }
+          }
+
+          if (isGood)
+          {
+            isTheEmpty       = Standard_False;
+            isAddedIntoWL[i] = Standard_True;
+            SeekAdditionalPoints(aQuad1,
+                                 aQuad2,
+                                 aWLine[i]->Curve(),
+                                 anEquationCoeffs,
+                                 i,
+                                 aNbPoints,
+                                 1,
+                                 aWLine[i]->NbPnts(),
+                                 aTol2D,
+                                 aPeriod,
+                                 isReversed);
+
+            aWLine[i]->ComputeVertexParameters(aTol3D);
+            theSlin.Append(aWLine[i]);
+          }
+        }
+        else
+        {
+          isAddedIntoWL[i] = Standard_False;
+        }
+
+#ifdef INTPATCH_IMPIMPINTERSECTION_DEBUG
+        aWLine[i]->Dump(0);
+#endif
+      }
+    }
+  }
+
+  //Delete the points in theSPnt, which
+  //lie at least in one of the line in theSlin.
+  for (Standard_Integer aNbPnt = 1; aNbPnt <= theSPnt.Length(); aNbPnt++)
+  {
+    for (Standard_Integer aNbLin = 1; aNbLin <= theSlin.Length(); aNbLin++)
+    {
+      Handle(IntPatch_WLine) aWLine1(Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNbLin)));
+
+      const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1);
+      const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aWLine1->NbPnts());
+
+      const IntSurf_PntOn2S aPntCur   = theSPnt.Value(aNbPnt).PntOn2S();
+      if (aPntCur.IsSame(aPntFWL1, aTol3D) || aPntCur.IsSame(aPntLWL1, aTol3D))
+      {
+        theSPnt.Remove(aNbPnt);
+        aNbPnt--;
+        break;
+      }
+    }
+  }
+
+  //Try to add new points in the neighborhood of existing point
+  for (Standard_Integer aNbPnt = 1; aNbPnt <= theSPnt.Length(); aNbPnt++)
+  {
+    // Standard algorithm (implemented above) could not find any
+    // continuous curve in neighborhood of aPnt2S (e.g. because
+    // this curve is too small; see tests\bugs\modalg_5\bug25292_35 and _36).
+    // Here, we will try to find several new points nearer to aPnt2S.
+
+    // The algorithm below tries to find two points in every
+    // intervals [u1 - aStepMax, u1] and [u1, u1 + aStepMax]
+    // and every new point will be in maximal distance from
+    // u1. If these two points exist they will be joined
+    // by the intersection curve.
+
+    const IntPatch_Point& aPnt2S = theSPnt.Value(aNbPnt);
+
+    Standard_Real u1, v1, u2, v2;
+    aPnt2S.Parameters(u1, v1, u2, v2);
+
+    Handle(IntSurf_LineOn2S) aL2S   = new IntSurf_LineOn2S();
+    Handle(IntPatch_WLine)   aWLine = new IntPatch_WLine(aL2S, Standard_False);
+    aWLine->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLImpImp);
+
+    //Define the index of WLine, which lies the point aPnt2S in.
+    Standard_Integer anIndex = 0;
+
+    Standard_Real anUf = 0.0, anUl = 0.0, aCurU2 = 0.0;
+    if (isReversed)
+    {
+      anUf   = Max(u2 - aStepMax, aUSurf1f);
+      anUl   = Min(u2 + aStepMax, aUSurf1l);
+      aCurU2 = u1;
+    }
+    else
+    {
+      anUf   = Max(u1 - aStepMax, aUSurf1f);
+      anUl   = Min(u1 + aStepMax, aUSurf1l);
+      aCurU2 = u2;
+    }
+
+    const Standard_Real anUinf = anUf, anUsup = anUl, anUmid = 0.5 * (anUf + anUl);
+
+    {
+      //Find the value of anIndex variable.
+      Standard_Real aDelta = RealLast();
+      for (Standard_Integer i = 0; i < aNbWLines; i++)
+      {
+        Standard_Real anU2t = 0.0;
+        if (!ComputationMethods::CylCylComputeParameters(anUmid, i, anEquationCoeffs, anU2t))
+          continue;
+
+        Standard_Real aDU2 = fmod(Abs(anU2t - aCurU2), aPeriod);
+        aDU2               = Min(aDU2, Abs(aDU2 - aPeriod));
+        if (aDU2 < aDelta)
+        {
+          aDelta  = aDU2;
+          anIndex = i;
+        }
+      }
+    }
+
+    // Bisection method is used in order to find every new point.
+    // I.e. if we need to find intersection point in the interval [anUinf, anUmid]
+    // we check the point anUC = 0.5*(anUinf+anUmid). If it is an intersection point
+    // we try to find another point in the interval [anUinf, anUC] (because we find the point in
+    // maximal distance from anUmid). If it is not then we try to find another point in the
+    // interval [anUC, anUmid]. Next iterations will be made analogically.
+    // When we find intersection point in the interval [anUmid, anUsup] we try to find
+    // another point in the interval [anUC, anUsup] if anUC is intersection point and
+    // in the interval [anUmid, anUC], otherwise.
+
+    Standard_Real anAddedPar[2] = {isReversed ? u2 : u1, isReversed ? u2 : u1};
+
+    for (Standard_Integer aParID = 0; aParID < 2; aParID++)
+    {
+      if (aParID == 0)
+      {
+        anUf = anUinf;
+        anUl = anUmid;
+      }
+      else // if(aParID == 1)
+      {
+        anUf = anUmid;
+        anUl = anUsup;
+      }
+
+      Standard_Real &aPar1 = (aParID == 0) ? anUf : anUl, &aPar2 = (aParID == 0) ? anUl : anUf;
+
+      while (Abs(aPar2 - aPar1) > aStepMin)
+      {
+        Standard_Real    anUC = 0.5 * (anUf + anUl);
+        Standard_Real    aU2 = 0.0, aV1 = 0.0, aV2 = 0.0;
+        Standard_Boolean isDone = ComputationMethods::CylCylComputeParameters(anUC, anIndex, anEquationCoeffs, aU2, aV1, aV2);
+
+        if (isDone)
+        {
+          if (Abs(aV1 - aVSurf1f) <= aTol2D)
+            aV1 = aVSurf1f;
+
+          if (Abs(aV1 - aVSurf1l) <= aTol2D)
+            aV1 = aVSurf1l;
+
+          if (Abs(aV2 - aVSurf2f) <= aTol2D)
+            aV2 = aVSurf2f;
+
+          if (Abs(aV2 - aVSurf2l) <= aTol2D)
+            aV2 = aVSurf2l;
+
+          isDone = AddPointIntoWL(aQuad1,
+                                  aQuad2,
+                                  anEquationCoeffs,
+                                  isReversed,
+                                  Standard_True,
+                                  gp_Pnt2d(anUC, aV1),
+                                  gp_Pnt2d(aU2, aV2),
+                                  aUSurf1f,
+                                  aUSurf1l,
+                                  aUSurf2f,
+                                  aUSurf2l,
+                                  aVSurf1f,
+                                  aVSurf1l,
+                                  aVSurf2f,
+                                  aVSurf2l,
+                                  aPeriod,
+                                  aWLine->Curve(),
+                                  anIndex,
+                                  aTol3D,
+                                  aTol2D,
+                                  Standard_False,
+                                  Standard_True);
+        }
+
+        if (isDone)
+        {
+          anAddedPar[0] = Min(anAddedPar[0], anUC);
+          anAddedPar[1] = Max(anAddedPar[1], anUC);
+          aPar2         = anUC;
+        }
+        else
+        {
+          aPar1 = anUC;
+        }
+      }
+    }
+
+    //Fill aWLine by additional points
+    if (anAddedPar[1] - anAddedPar[0] > aStepMin)
+    {
+      for (Standard_Integer aParID = 0; aParID < 2; aParID++)
+      {
+        Standard_Real aU2 = 0.0, aV1 = 0.0, aV2 = 0.0;
+        ComputationMethods::CylCylComputeParameters(anAddedPar[aParID], anIndex, anEquationCoeffs, aU2, aV1, aV2);
+
+        AddPointIntoWL(aQuad1,
+                       aQuad2,
+                       anEquationCoeffs,
+                       isReversed,
+                       Standard_True,
+                       gp_Pnt2d(anAddedPar[aParID], aV1),
+                       gp_Pnt2d(aU2, aV2),
+                       aUSurf1f,
+                       aUSurf1l,
+                       aUSurf2f,
+                       aUSurf2l,
+                       aVSurf1f,
+                       aVSurf1l,
+                       aVSurf2f,
+                       aVSurf2l,
+                       aPeriod,
+                       aWLine->Curve(),
+                       anIndex,
+                       aTol3D,
+                       aTol2D,
+                       Standard_False,
+                       Standard_False);
+      }
+
+      SeekAdditionalPoints(aQuad1,
+                           aQuad2,
+                           aWLine->Curve(),
+                           anEquationCoeffs,
+                           anIndex,
+                           aNbMinPoints,
+                           1,
+                           aWLine->NbPnts(),
+                           aTol2D,
+                           aPeriod,
+                           isReversed);
+
+      aWLine->ComputeVertexParameters(aTol3D);
+      theSlin.Append(aWLine);
+
+      theSPnt.Remove(aNbPnt);
+      aNbPnt--;
+    }
+  }
+
+  return IntPatch_ImpImpIntersection::IntStatus_OK;
+}
+
+//=======================================================================
+//function : IntCyCy
+//purpose  :
+//=======================================================================
+IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric&    theQuad1,
+                                               const IntSurf_Quadric&    theQuad2,
+                                               const Standard_Real       theTol3D,
+                                               const Standard_Real       theTol2D,
+                                               const Bnd_Box2d&          theUVSurf1,
+                                               const Bnd_Box2d&          theUVSurf2,
+                                               Standard_Boolean&         isTheEmpty,
+                                               Standard_Boolean&         isTheSameSurface,
+                                               Standard_Boolean&         isTheMultiplePoint,
+                                               IntPatch_SequenceOfLine&  theSlin,
+                                               IntPatch_SequenceOfPoint& theSPnt)
+{
+  isTheEmpty         = Standard_True;
+  isTheSameSurface   = Standard_False;
+  isTheMultiplePoint = Standard_False;
+  theSlin.Clear();
+  theSPnt.Clear();
+
+  const gp_Cylinder aCyl1 = theQuad1.Cylinder(), aCyl2 = theQuad2.Cylinder();
+
+  IntAna_QuadQuadGeo anInter(aCyl1, aCyl2, theTol3D);
+
+  if (!anInter.IsDone())
+  {
+    return IntPatch_ImpImpIntersection::IntStatus_Fail;
+  }
+
+  if (anInter.TypeInter() != IntAna_NoGeometricSolution)
+  {
+    if (CyCyAnalyticalIntersect(theQuad1,
+                                theQuad2,
+                                anInter,
+                                theTol3D,
+                                isTheEmpty,
+                                isTheSameSurface,
+                                isTheMultiplePoint,
+                                theSlin,
+                                theSPnt))
+    {
+      return IntPatch_ImpImpIntersection::IntStatus_OK;
+    }
+  }
+
+  //Here, intersection line is not an analytical curve(line, circle, ellipsis etc.)
+
+  Standard_Real aUSBou[2][2], aVSBou[2][2]; //const
+
+  theUVSurf1.Get(aUSBou[0][0], aVSBou[0][0], aUSBou[0][1], aVSBou[0][1]);
+  theUVSurf2.Get(aUSBou[1][0], aVSBou[1][0], aUSBou[1][1], aVSBou[1][1]);
+
+  const Standard_Real    aPeriod   = 2.0 * M_PI;
+  const Standard_Integer aNbWLines = 2;
+
+  const ComputationMethods::stCoeffsValue anEquationCoeffs1(aCyl1, aCyl2);
+  const ComputationMethods::stCoeffsValue anEquationCoeffs2(aCyl2, aCyl1);
+
+  //Boundaries.
+  //Intersection result can include two non-connected regions
+  //(see WorkWithBoundaries::BoundariesComputing(...) method).
+  const Standard_Integer aNbOfBoundaries = 2;
+  Bnd_Range              anURange[2][aNbOfBoundaries]; //const
+
+  if (!WorkWithBoundaries::BoundariesComputing(anEquationCoeffs1, aPeriod, anURange[0]))
+    return IntPatch_ImpImpIntersection::IntStatus_OK;
+
+  if (!WorkWithBoundaries::BoundariesComputing(anEquationCoeffs2, aPeriod, anURange[1]))
+    return IntPatch_ImpImpIntersection::IntStatus_OK;
+
+  //anURange[*] can be in different periodic regions in
+  //compare with First-Last surface. E.g. the surface
+  //is full cylinder [0, 2*PI] but anURange is [5, 7].
+  //Trivial common range computation returns [5, 2*PI] and
+  //its summary length is 2*PI-5 == 1.28... only. That is wrong.
+  //This problem can be solved by the following
+  //algorithm:
+  // 1. split anURange[*] by the surface boundary;
+  // 2. shift every new range in order to inscribe it
+  //      in [Ufirst, Ulast] of cylinder;
+  // 3. consider only common ranges between [Ufirst, Ulast]
+  //    and new ranges.
+  //
+  // In above example, we obtain following:
+  // 1. two ranges: [5, 2*PI] and [2*PI, 7];
+  // 2. after shifting: [5, 2*PI] and [0, 7-2*PI];
+  // 3. Common ranges: ([5, 2*PI] and [0, 2*PI]) == [5, 2*PI],
+  //                   ([0, 7-2*PI] and [0, 2*PI]) == [0, 7-2*PI];
+  // 4. Their summary length is (2*PI-5)+(7-2*PI-0)==7-5==2 ==> GOOD.
+
+  Standard_Real                    aSumRange[2] = {0.0, 0.0};
+  Handle(NCollection_IncAllocator) anAlloc      = new NCollection_IncAllocator;
+  for (Standard_Integer aCID = 0; aCID < 2; aCID++)
+  {
+    anAlloc->Reset(false);
+    NCollection_List<Bnd_Range> aListOfRng(anAlloc);
+
+    aListOfRng.Append(anURange[aCID][0]);
+    aListOfRng.Append(anURange[aCID][1]);
+
+    const Standard_Real aSplitArr[3] = {aUSBou[aCID][0], aUSBou[aCID][1], 0.0};
+
+    NCollection_List<Bnd_Range>::Iterator anITrRng;
+    for (Standard_Integer aSInd = 0; aSInd < 3; aSInd++)
+    {
+      NCollection_List<Bnd_Range> aLstTemp(aListOfRng);
+      aListOfRng.Clear();
+      for (anITrRng.Init(aLstTemp); anITrRng.More(); anITrRng.Next())
+      {
+        Bnd_Range& aRng = anITrRng.ChangeValue();
+        aRng.Split(aSplitArr[aSInd], aListOfRng, aPeriod);
+      }
+    }
+
+    anITrRng.Init(aListOfRng);
+    for (; anITrRng.More(); anITrRng.Next())
+    {
+      Bnd_Range& aCurrRange = anITrRng.ChangeValue();
+
+      Bnd_Range aBoundR;
+      aBoundR.Add(aUSBou[aCID][0]);
+      aBoundR.Add(aUSBou[aCID][1]);
+
+      if (!InscribeInterval(aUSBou[aCID][0], aUSBou[aCID][1], aCurrRange, theTol2D, aPeriod))
+      {
+        //If aCurrRange does not have common block with
+        //[Ufirst, Ulast] of cylinder then we will try
+        //to inscribe [Ufirst, Ulast] in the boundaries of aCurrRange.
+        Standard_Real aF = 1.0, aL = 0.0;
+        if (!aCurrRange.GetBounds(aF, aL))
+          continue;
+
+        if ((aL < aUSBou[aCID][0]))
+        {
+          aCurrRange.Shift(aPeriod);
+        }
+        else if (aF > aUSBou[aCID][1])
+        {
+          aCurrRange.Shift(-aPeriod);
+        }
+      }
+
+      aBoundR.Common(aCurrRange);
+
+      const Standard_Real aDelta = aBoundR.Delta();
+
+      if (aDelta > 0.0)
+      {
+        aSumRange[aCID] += aDelta;
+      }
+    }
+  }
+
+  //The bigger range the bigger number of points in Walking-line (WLine)
+  //we will be able to add and consequently we will obtain more
+  //precise intersection line.
+  //Every point of WLine is determined as function from U1-parameter,
+  //where U1 is U-parameter on 1st quadric.
+  //Therefore, we should use quadric with bigger range as 1st parameter
+  //in IntCyCy() function.
+  //On the other hand, there is no point in reversing in case of
+  //analytical intersection (when result is line, ellipse, point...).
+  //This result is independent of the arguments order.
+  const Standard_Boolean isToReverse = (aSumRange[1] > aSumRange[0]);
+
+  if (isToReverse)
+  {
+    const WorkWithBoundaries aBoundWork(theQuad2,
+                                        theQuad1,
+                                        anEquationCoeffs2,
+                                        theUVSurf2,
+                                        theUVSurf1,
+                                        aNbWLines,
+                                        aPeriod,
+                                        theTol3D,
+                                        theTol2D,
+                                        Standard_True);
+
+    return CyCyNoGeometric(aCyl2, aCyl1, aBoundWork, anURange[1], aNbOfBoundaries, isTheEmpty, theSlin, theSPnt);
+  }
+  else
+  {
+    const WorkWithBoundaries aBoundWork(theQuad1,
+                                        theQuad2,
+                                        anEquationCoeffs1,
+                                        theUVSurf1,
+                                        theUVSurf2,
+                                        aNbWLines,
+                                        aPeriod,
+                                        theTol3D,
+                                        theTol2D,
+                                        Standard_False);
+
+    return CyCyNoGeometric(aCyl1, aCyl2, aBoundWork, anURange[0], aNbOfBoundaries, isTheEmpty, theSlin, theSPnt);
+  }
+}
+
+//=======================================================================
+//function : IntCySp
+//purpose  :
+//=======================================================================
+Standard_Boolean IntCySp(const IntSurf_Quadric&    Quad1,
+                         const IntSurf_Quadric&    Quad2,
+                         const Standard_Real       Tol,
+                         const Standard_Boolean    Reversed,
+                         Standard_Boolean&         Empty,
+                         Standard_Boolean&         Multpoint,
+                         IntPatch_SequenceOfLine&  slin,
+                         IntPatch_SequenceOfPoint& spnt)
+
+{
+  Standard_Integer i;
+
+  IntSurf_TypeTrans trans1, trans2;
+  IntAna_ResultType typint;
+  IntPatch_Point    ptsol;
+  gp_Circ           cirsol;
+
+  gp_Cylinder Cy;
+  gp_Sphere   Sp;
+
+  if (!Reversed)
+  {
+    Cy = Quad1.Cylinder();
+    Sp = Quad2.Sphere();
+  }
+  else
+  {
+    Cy = Quad2.Cylinder();
+    Sp = Quad1.Sphere();
+  }
+  IntAna_QuadQuadGeo inter(Cy, Sp, Tol);
+
+  if (!inter.IsDone())
+  {
+    return Standard_False;
+  }
+
+  typint                 = inter.TypeInter();
+  Standard_Integer NbSol = inter.NbSolutions();
+  Empty                  = Standard_False;
+
+  switch (typint)
+  {
+    case IntAna_Empty:
+    {
+      Empty = Standard_True;
+    }
+    break;
+
+    case IntAna_Point:
+    {
+      gp_Pnt        psol(inter.Point(1));
+      Standard_Real U1, V1, U2, V2;
+      Quad1.Parameters(psol, U1, V1);
+      Quad2.Parameters(psol, U2, V2);
+      ptsol.SetValue(psol, Tol, Standard_True);
+      ptsol.SetParameters(U1, V1, U2, V2);
+      spnt.Append(ptsol);
+    }
+    break;
+
+    case IntAna_Circle:
+    {
+      cirsol = inter.Circle(1);
+      gp_Vec Tgt;
+      gp_Pnt ptref;
+      ElCLib::D1(0., cirsol, ptref, Tgt);
+
+      if (NbSol == 1)
+      {
+        gp_Vec TestCurvature(ptref, Sp.Location());
+        gp_Vec Normsp, Normcyl;
+        if (!Reversed)
+        {
+          Normcyl = Quad1.Normale(ptref);
+          Normsp  = Quad2.Normale(ptref);
+        }
+        else
+        {
+          Normcyl = Quad2.Normale(ptref);
+          Normsp  = Quad1.Normale(ptref);
+        }
+
+        IntSurf_Situation situcyl;
+        IntSurf_Situation situsp;
+
+        if (Normcyl.Dot(TestCurvature) > 0.)
+        {
+          situsp = IntSurf_Outside;
+          if (Normsp.Dot(Normcyl) > 0.)
+          {
+            situcyl = IntSurf_Inside;
+          }
+          else
+          {
+            situcyl = IntSurf_Outside;
+          }
+        }
+        else
+        {
+          situsp = IntSurf_Inside;
+          if (Normsp.Dot(Normcyl) > 0.)
+          {
+            situcyl = IntSurf_Outside;
+          }
+          else
+          {
+            situcyl = IntSurf_Inside;
+          }
+        }
+        Handle(IntPatch_GLine) glig;
+        if (!Reversed)
+        {
+          glig = new IntPatch_GLine(cirsol, Standard_True, situcyl, situsp);
+        }
+        else
+        {
+          glig = new IntPatch_GLine(cirsol, Standard_True, situsp, situcyl);
+        }
+        slin.Append(glig);
+      }
+      else
+      {
+        if (Tgt.DotCross(Quad2.Normale(ptref), Quad1.Normale(ptref)) > 0.0)
+        {
+          trans1 = IntSurf_Out;
+          trans2 = IntSurf_In;
+        }
+        else
+        {
+          trans1 = IntSurf_In;
+          trans2 = IntSurf_Out;
+        }
+        Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol, Standard_False, trans1, trans2);
+        slin.Append(glig);
+
+        cirsol = inter.Circle(2);
+        ElCLib::D1(0., cirsol, ptref, Tgt);
+        Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref), Quad1.Normale(ptref));
+        if (qwe > 0.0000001)
+        {
+          trans1 = IntSurf_Out;
+          trans2 = IntSurf_In;
+        }
+        else if (qwe < -0.0000001)
+        {
+          trans1 = IntSurf_In;
+          trans2 = IntSurf_Out;
+        }
+        else
+        {
+          trans1 = trans2 = IntSurf_Undecided;
+        }
+        glig = new IntPatch_GLine(cirsol, Standard_False, trans1, trans2);
+        slin.Append(glig);
+      }
+    }
+    break;
+
+    case IntAna_NoGeometricSolution:
+    {
+      gp_Pnt             psol;
+      Standard_Real      U1, V1, U2, V2;
+      IntAna_IntQuadQuad anaint(Cy, Sp, Tol);
+      if (!anaint.IsDone())
+      {
+        return Standard_False;
+      }
+
+      if (anaint.NbPnt() == 0 && anaint.NbCurve() == 0)
+      {
+        Empty = Standard_True;
+      }
+      else
+      {
+        NbSol = anaint.NbPnt();
+        for (i = 1; i <= NbSol; i++)
+        {
+          psol = anaint.Point(i);
+          Quad1.Parameters(psol, U1, V1);
+          Quad2.Parameters(psol, U2, V2);
+          ptsol.SetValue(psol, Tol, Standard_True);
+          ptsol.SetParameters(U1, V1, U2, V2);
+          spnt.Append(ptsol);
+        }
+
+        gp_Pnt           ptvalid, ptf, ptl;
+        gp_Vec           tgvalid;
+        Standard_Real    first, last, para;
+        IntAna_Curve     curvsol;
+        Standard_Boolean tgfound;
+        Standard_Integer kount;
+
+        NbSol = anaint.NbCurve();
+        for (i = 1; i <= NbSol; i++)
+        {
+          curvsol = anaint.Curve(i);
+          curvsol.Domain(first, last);
+          ptf     = curvsol.Value(first);
+          ptl     = curvsol.Value(last);
+
+          para    = last;
+          kount   = 1;
+          tgfound = Standard_False;
+
+          while (!tgfound)
+          {
+            para    = (1.123 * first + para) / 2.123;
+            tgfound = curvsol.D1u(para, ptvalid, tgvalid);
+            if (!tgfound)
+            {
+              kount++;
+              tgfound = kount > 5;
+            }
+          }
+          Handle(IntPatch_ALine) alig;
+          if (kount <= 5)
+          {
+            Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid), Quad1.Normale(ptvalid));
+            if (qwe > 0.00000001)
+            {
+              trans1 = IntSurf_Out;
+              trans2 = IntSurf_In;
+            }
+            else if (qwe < -0.00000001)
+            {
+              trans1 = IntSurf_In;
+              trans2 = IntSurf_Out;
+            }
+            else
+            {
+              trans1 = trans2 = IntSurf_Undecided;
+            }
+            alig = new IntPatch_ALine(curvsol, Standard_False, trans1, trans2);
+          }
+          else
+          {
+            alig = new IntPatch_ALine(curvsol, Standard_False);
+          }
+          Standard_Boolean TempFalse1a = Standard_False;
+          Standard_Boolean TempFalse2a = Standard_False;
+
+          //-- ptf et ptl : points debut et fin de alig
+
+          ProcessBounds(alig, slin, Quad1, Quad2, TempFalse1a, ptf, first, TempFalse2a, ptl, last, Multpoint, Tol);
+          slin.Append(alig);
+        } //-- boucle sur les lignes
+      } //-- solution avec au moins une lihne
+    }
+    break;
+
+    default:
+    {
+      return Standard_False;
+    }
+  }
+  return Standard_True;
+}
+//=======================================================================
+//function : IntCyCo
+//purpose  :
+//=======================================================================
+Standard_Boolean IntCyCo(const IntSurf_Quadric&    Quad1,
+                         const IntSurf_Quadric&    Quad2,
+                         const Standard_Real       Tol,
+                         const Standard_Boolean    Reversed,
+                         Standard_Boolean&         Empty,
+                         Standard_Boolean&         Multpoint,
+                         IntPatch_SequenceOfLine&  slin,
+                         IntPatch_SequenceOfPoint& spnt)
+
+{
+  IntPatch_Point ptsol;
+
+  Standard_Integer i;
+
+  IntSurf_TypeTrans trans1, trans2;
+  IntAna_ResultType typint;
+  gp_Circ           cirsol;
+
+  gp_Cylinder Cy;
+  gp_Cone     Co;
+
+  if (!Reversed)
+  {
+    Cy = Quad1.Cylinder();
+    Co = Quad2.Cone();
+  }
+  else
+  {
+    Cy = Quad2.Cylinder();
+    Co = Quad1.Cone();
+  }
+  IntAna_QuadQuadGeo inter(Cy, Co, Tol);
+
+  if (!inter.IsDone())
+  {
+    return Standard_False;
+  }
+
+  typint                 = inter.TypeInter();
+  Standard_Integer NbSol = inter.NbSolutions();
+  Empty                  = Standard_False;
+
+  switch (typint)
+  {
+    case IntAna_Empty:
+    {
+      Empty = Standard_True;
+    }
+    break;
+
+    case IntAna_Point:
+    {
+      gp_Pnt        psol(inter.Point(1));
+      Standard_Real U1, V1, U2, V2;
+      Quad1.Parameters(psol, U1, V1);
+      Quad1.Parameters(psol, U2, V2);
+      ptsol.SetValue(psol, Tol, Standard_True);
+      ptsol.SetParameters(U1, V1, U2, V2);
+      spnt.Append(ptsol);
+    }
+    break;
+
+    case IntAna_Circle:
+    {
+      gp_Vec           Tgt;
+      gp_Pnt           ptref;
+      Standard_Integer j;
+      Standard_Real    qwe;
+      //
+      for (j = 1; j <= 2; ++j)
+      {
+        cirsol = inter.Circle(j);
+        ElCLib::D1(0., cirsol, ptref, Tgt);
+        qwe = Tgt.DotCross(Quad2.Normale(ptref), Quad1.Normale(ptref));
+        if (qwe > 0.00000001)
+        {
+          trans1 = IntSurf_Out;
+          trans2 = IntSurf_In;
+        }
+        else if (qwe < -0.00000001)
+        {
+          trans1 = IntSurf_In;
+          trans2 = IntSurf_Out;
+        }
+        else
+        {
+          trans1 = trans2 = IntSurf_Undecided;
+        }
+        Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol, Standard_False, trans1, trans2);
+        slin.Append(glig);
+      }
+    }
+    break;
+
+    case IntAna_NoGeometricSolution:
+    {
+      gp_Pnt             psol;
+      Standard_Real      U1, V1, U2, V2;
+      IntAna_IntQuadQuad anaint(Cy, Co, Tol);
+      if (!anaint.IsDone())
+      {
+        return Standard_False;
+      }
+
+      if (anaint.NbPnt() == 0 && anaint.NbCurve() == 0)
+      {
+        Empty = Standard_True;
+      }
+      else
+      {
+        NbSol = anaint.NbPnt();
+        for (i = 1; i <= NbSol; i++)
+        {
+          psol = anaint.Point(i);
+          Quad1.Parameters(psol, U1, V1);
+          Quad2.Parameters(psol, U2, V2);
+          ptsol.SetValue(psol, Tol, Standard_True);
+          ptsol.SetParameters(U1, V1, U2, V2);
+          spnt.Append(ptsol);
+        }
+
+        gp_Pnt ptvalid, ptf, ptl;
+        gp_Vec tgvalid;
+        //
+        Standard_Real    first, last, para;
+        Standard_Boolean tgfound, firstp, lastp, kept;
+        Standard_Integer kount;
+        //
+        //
+        //IntAna_Curve curvsol;
+        IntAna_Curve                     aC;
+        IntAna_ListOfCurve               aLC;
+        IntAna_ListIteratorOfListOfCurve aIt;
+
+        //
+        NbSol = anaint.NbCurve();
+        for (i = 1; i <= NbSol; ++i)
+        {
+          kept = Standard_False;
+          //curvsol = anaint.Curve(i);
+          aC   = anaint.Curve(i);
+          aLC.Clear();
+          ExploreCurve(Co, aC, 10. * Tol, aLC);
+          //
+          aIt.Initialize(aLC);
+          for (; aIt.More(); aIt.Next())
+          {
+            IntAna_Curve& curvsol = aIt.ChangeValue();
+            //
+            curvsol.Domain(first, last);
+            firstp = !curvsol.IsFirstOpen();
+            lastp  = !curvsol.IsLastOpen();
+            if (firstp)
+            {
+              ptf = curvsol.Value(first);
+            }
+            if (lastp)
+            {
+              ptl = curvsol.Value(last);
+            }
+            para    = last;
+            kount   = 1;
+            tgfound = Standard_False;
+
+            while (!tgfound)
+            {
+              para    = (1.123 * first + para) / 2.123;
+              tgfound = curvsol.D1u(para, ptvalid, tgvalid);
+              if (!tgfound)
+              {
+                kount++;
+                tgfound = kount > 5;
+              }
+            }
+            Handle(IntPatch_ALine) alig;
+            if (kount <= 5)
+            {
+              Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid), Quad1.Normale(ptvalid));
+              if (qwe > 0.00000001)
+              {
+                trans1 = IntSurf_Out;
+                trans2 = IntSurf_In;
+              }
+              else if (qwe < -0.00000001)
+              {
+                trans1 = IntSurf_In;
+                trans2 = IntSurf_Out;
+              }
+              else
+              {
+                trans1 = trans2 = IntSurf_Undecided;
+              }
+              alig = new IntPatch_ALine(curvsol, Standard_False, trans1, trans2);
+              kept = Standard_True;
+            }
+            else
+            {
+              ptvalid = curvsol.Value(para);
+              alig    = new IntPatch_ALine(curvsol, Standard_False);
+              kept    = Standard_True;
+              //-- std::cout << "Transition indeterminee" << std::endl;
+            }
+            if (kept)
+            {
+              Standard_Boolean Nfirstp = !firstp;
+              Standard_Boolean Nlastp  = !lastp;
+              ProcessBounds(alig, slin, Quad1, Quad2, Nfirstp, ptf, first, Nlastp, ptl, last, Multpoint, Tol);
+              slin.Append(alig);
+            }
+          } // for (; aIt.More(); aIt.Next())
+        } // for (i = 1; i <= NbSol; ++i)
+      }
+    }
+    break;
+
+    default: return Standard_False;
+
+  } // switch (typint)
+
+  return Standard_True;
+}
+//=======================================================================
+//function : ExploreCurve
+//purpose  : Splits aC on several curves in the cone apex points.
+//=======================================================================
+Standard_Boolean ExploreCurve(const gp_Cone& theCo, IntAna_Curve& theCrv, const Standard_Real theTol, IntAna_ListOfCurve& theLC)
+{
+  const Standard_Real aSqTol = theTol * theTol;
+  const gp_Pnt        aPapx(theCo.Apex());
+
+  Standard_Real aT1, aT2;
+  theCrv.Domain(aT1, aT2);
+
+  theLC.Clear();
+  //
+  TColStd_ListOfReal aLParams;
+  theCrv.FindParameter(aPapx, aLParams);
+  if (aLParams.IsEmpty())
+  {
+    theLC.Append(theCrv);
+    return Standard_False;
+  }
+
+  for (TColStd_ListIteratorOfListOfReal anItr(aLParams); anItr.More(); anItr.Next())
+  {
+    Standard_Real aPrm = anItr.Value();
+
+    if ((aPrm - aT1) < Precision::PConfusion())
+      continue;
+
+    Standard_Boolean isLast = Standard_False;
+    if ((aT2 - aPrm) < Precision::PConfusion())
+    {
+      aPrm   = aT2;
+      isLast = Standard_True;
+    }
+
+    const gp_Pnt        aP   = theCrv.Value(aPrm);
+    const Standard_Real aSqD = aP.SquareDistance(aPapx);
+    if (aSqD < aSqTol)
+    {
+      IntAna_Curve aC1 = theCrv;
+      aC1.SetDomain(aT1, aPrm);
+      aT1 = aPrm;
+      theLC.Append(aC1);
+    }
+
+    if (isLast)
+      break;
+  }
+
+  if (theLC.IsEmpty())
+  {
+    theLC.Append(theCrv);
+    return Standard_False;
+  }
+
+  if ((aT2 - aT1) > Precision::PConfusion())
+  {
+    IntAna_Curve aC1 = theCrv;
+    aC1.SetDomain(aT1, aT2);
+    theLC.Append(aC1);
+  }
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : IntCoCo
+//purpose  :
+//=======================================================================
+Standard_Boolean IntCoCo(const IntSurf_Quadric&    Quad1,
+                         const IntSurf_Quadric&    Quad2,
+                         const Standard_Real       Tol,
+                         Standard_Boolean&         Empty,
+                         Standard_Boolean&         Same,
+                         Standard_Boolean&         Multpoint,
+                         IntPatch_SequenceOfLine&  slin,
+                         IntPatch_SequenceOfPoint& spnt)
+
+{
+  Standard_Integer  i, NbSol;
+  Standard_Real     U1, V1, U2, V2;
+  IntSurf_TypeTrans trans1, trans2;
+  IntAna_ResultType typint;
+  //
+  gp_Cone Co1(Quad1.Cone());
+  gp_Cone Co2(Quad2.Cone());
+  //
+  IntAna_QuadQuadGeo inter(Co1, Co2, Tol);
+  if (!inter.IsDone())
+  {
+    return Standard_False;
+  }
+  //
+  typint = inter.TypeInter();
+  NbSol  = inter.NbSolutions();
+  Empty  = Standard_False;
+  Same   = Standard_False;
+
+  switch (typint)
+  {
+    case IntAna_Empty:
+    {
+      Empty = Standard_True;
+    }
+    break;
+
+    case IntAna_Same:
+    {
+      Same = Standard_True;
+    }
+    break;
+
+      //modified by NIZNHY-PKV Wed Nov 30 12:56:06 2005f
+    case IntAna_Line:
+    {
+      Standard_Real          para, aDot;
+      gp_Pnt                 aPApex1, aPApex2, ptbid;
+      gp_Lin                 linsol;
+      gp_Vec                 NormC1, NormC2;
+      IntPatch_Point         aPtsol;
+      Handle(IntPatch_GLine) glig;
+      //
+      aPApex1 = Co1.Apex();
+      aPApex2 = Co2.Apex();
+      //
+      if (NbSol == 1)
+      {
+        IntSurf_Situation situC1, situC2;
+        //
+        linsol = inter.Line(1);
+        para   = ElCLib::Parameter(linsol, aPApex1);
+        ptbid  = ElCLib::Value(para + 5., linsol);
+        Quad1.Parameters(aPApex1, U1, V1);
+        Quad2.Parameters(aPApex1, U2, V2);
+        //
+        aPtsol.SetValue(aPApex1, Tol, Standard_False);
+        aPtsol.SetParameters(U1, V1, U2, V2);
+        aPtsol.SetParameter(para);
+        //
+        NormC1 = Quad1.Normale(ptbid);
+        NormC2 = Quad2.Normale(ptbid);
+        aDot   = NormC1.Dot(NormC2);
+        if (aDot < 0.)
+        {
+          situC1 = IntSurf_Outside;
+          situC2 = IntSurf_Outside;
+        }
+        else
+        {
+          Standard_Real aR1, aR2;
+          gp_Lin        aLAx1(aPApex1, Co1.Axis().Direction());
+          gp_Lin        aLAx2(aPApex2, Co2.Axis().Direction());
+          //
+          aR1    = aLAx1.Distance(ptbid);
+          aR2    = aLAx2.Distance(ptbid);
+          //
+          situC1 = IntSurf_Inside;
+          situC2 = IntSurf_Outside;
+          if (aR1 > aR2)
+          {                           // Intersection line parametrizes from Apex1 to Apex2,
+            situC1 = IntSurf_Outside; // So the distance between ptbid and aLAx1 is greater than the
+            situC2 = IntSurf_Inside;  // distance between ptbid and aLAx2 and in that case Cone2
+                                      // is inside Cone 1
+          }
+        }
+        // 1
+        glig = new IntPatch_GLine(linsol, Standard_True, situC1, situC2);
+        glig->AddVertex(aPtsol);
+        glig->SetFirstPoint(1);
+        slin.Append(glig);
+        // 2
+        linsol.SetDirection(linsol.Direction().Reversed());
+        para = ElCLib::Parameter(linsol, aPApex1);
+        aPtsol.SetParameter(para);
+
+        glig = new IntPatch_GLine(linsol, Standard_True, situC2, situC1);
+        glig->AddVertex(aPtsol);
+        glig->SetFirstPoint(1);
+        slin.Append(glig);
+      } // if (NbSol==1) {
+      //////////////////////
+      else if (NbSol == 2)
+      {
+        //
+        for (i = 1; i <= 2; ++i)
+        {
+          linsol = inter.Line(i);
+          para   = ElCLib::Parameter(linsol, aPApex1);
+          ptbid  = ElCLib::Value(para + 5., linsol);
+          Quad1.Parameters(aPApex1, U1, V1);
+          Quad2.Parameters(aPApex1, U2, V2);
+          //
+          trans1 = IntSurf_In;
+          trans2 = IntSurf_Out;
+          if (linsol.Direction().DotCross(Quad2.Normale(ptbid), Quad1.Normale(ptbid)) > 0.)
+          {
+            trans1 = IntSurf_Out;
+            trans2 = IntSurf_In;
+          }
+          //
+          Multpoint = Standard_True;
+          // 1,3
+          aPtsol.SetValue(aPApex1, Tol, Standard_False);
+          aPtsol.SetParameters(U1, V1, U2, V2);
+          aPtsol.SetParameter(para);
+          aPtsol.SetMultiple(Standard_True);
+
+          glig = new IntPatch_GLine(linsol, Standard_False, trans1, trans2);
+          glig->AddVertex(aPtsol);
+          glig->SetFirstPoint(1);
+          slin.Append(glig);
+          // 2,4
+          linsol.SetDirection(linsol.Direction().Reversed());
+          para = ElCLib::Parameter(linsol, aPApex1);
+          aPtsol.SetParameter(para);
+          glig = new IntPatch_GLine(linsol, Standard_False, trans1, trans2);
+          glig->AddVertex(aPtsol);
+          glig->SetFirstPoint(1);
+          slin.Append(glig);
+          //
+        } //for (i=1; i<=2; ++i)
+      } //else if (NbSol==2)
+    }
+    break;
+      //modified by NIZNHY-PKV Wed Nov 30 12:56:10 2005t
+
+    case IntAna_Point:
+    {
+      gp_Pnt        ptcontact;
+      gp_Pnt        apex1(Co1.Apex());
+      gp_Pnt        apex2(Co2.Apex());
+      Standard_Real param1, param2;
+      Standard_Real paramapex1 = ElCLib::LineParameter(Co1.Axis(), apex1);
+      Standard_Real paramapex2 = ElCLib::LineParameter(Co2.Axis(), apex2);
+      for (i = 1; i <= NbSol; i++)
+      {
+        ptcontact = inter.Point(i);
+        param1    = ElCLib::LineParameter(Co1.Axis(), ptcontact);
+        param2    = ElCLib::LineParameter(Co2.Axis(), ptcontact);
+
+        Quad1.Parameters(ptcontact, U1, V1);
+        Quad2.Parameters(ptcontact, U2, V2);
+
+        if (apex1.Distance(ptcontact) <= Tol && apex2.Distance(ptcontact) <= Tol)
+        {
+          IntPatch_Point ptsol;
+          ptsol.SetValue(ptcontact, Tol, Standard_False);
+          ptsol.SetParameters(U1, V1, U2, V2);
+          spnt.Append(ptsol);
+        }
+        else if (param1 >= paramapex1 && param2 >= paramapex2)
+        {
+          IntPatch_Point ptsol;
+          ptsol.SetValue(ptcontact, Tol, Standard_True);
+          ptsol.SetParameters(U1, V1, U2, V2);
+          spnt.Append(ptsol);
+        }
+      }
+    }
+    break;
+
+    case IntAna_Circle:
+    {
+      IntPatch_Point aPtsol;
+      gp_Vec         Tgt;
+      gp_Pnt         ptref;
+      for (i = 1; i <= NbSol; i++)
+      {
+        gp_Circ cirsol = inter.Circle(i);
+        ElCLib::D1(0., cirsol, ptref, Tgt);
+        Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref), Quad1.Normale(ptref));
+        if (qwe > 0.00000001)
+        {
+          trans1 = IntSurf_Out;
+          trans2 = IntSurf_In;
+        }
+        else if (qwe < -0.00000001)
+        {
+          trans1 = IntSurf_In;
+          trans2 = IntSurf_Out;
+        }
+        else
+        {
+          trans1 = trans2 = IntSurf_Undecided;
+        }
+        Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol, Standard_False, trans1, trans2);
+        if (inter.HasCommonGen())
+        {
+          const gp_Pnt& aPChar = inter.PChar();
+          Quad1.Parameters(aPChar, U1, V1);
+          Quad2.Parameters(aPChar, U2, V2);
+          aPtsol.SetValue(aPChar, Tol, Standard_False);
+          aPtsol.SetParameters(U1, V1, U2, V2);
+          aPtsol.SetParameter(0.);
+          glig->AddVertex(aPtsol);
+        }
+        slin.Append(glig);
+      }
+    }
+    break;
+
+    case IntAna_Ellipse:
+    {
+      IntPatch_Point aPtsol;
+      gp_Elips       elipsol = inter.Ellipse(1);
+
+      gp_Vec Tgt;
+      gp_Pnt ptref;
+      ElCLib::D1(0., elipsol, ptref, Tgt);
+
+      Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref), Quad1.Normale(ptref));
+      if (qwe > 0.00000001)
+      {
+        trans1 = IntSurf_Out;
+        trans2 = IntSurf_In;
+      }
+      else if (qwe < -0.00000001)
+      {
+        trans1 = IntSurf_In;
+        trans2 = IntSurf_Out;
+      }
+      else
+      {
+        trans1 = trans2 = IntSurf_Undecided;
+      }
+      Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol, Standard_False, trans1, trans2);
+      if (inter.HasCommonGen())
+      {
+        const gp_Pnt& aPChar = inter.PChar();
+        Quad1.Parameters(aPChar, U1, V1);
+        Quad2.Parameters(aPChar, U2, V2);
+        aPtsol.SetValue(aPChar, Tol, Standard_False);
+        aPtsol.SetParameters(U1, V1, U2, V2);
+        aPtsol.SetParameter(0.);
+        glig->AddVertex(aPtsol);
+      }
+      slin.Append(glig);
+    }
+    break;
+
+    case IntAna_Hyperbola:
+    {
+      IntPatch_Point aPtsol;
+      gp_Vec         Tgt;
+      gp_Pnt         ptref;
+      for (i = 1; i <= 2; i++)
+      {
+        gp_Hypr hyprsol = inter.Hyperbola(i);
+        ElCLib::D1(0., hyprsol, ptref, Tgt);
+        Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref), Quad1.Normale(ptref));
+        if (qwe > 0.00000001)
+        {
+          trans1 = IntSurf_Out;
+          trans2 = IntSurf_In;
+        }
+        else if (qwe < -0.00000001)
+        {
+          trans1 = IntSurf_In;
+          trans2 = IntSurf_Out;
+        }
+        else
+        {
+          trans1 = trans2 = IntSurf_Undecided;
+        }
+        Handle(IntPatch_GLine) glig = new IntPatch_GLine(hyprsol, Standard_False, trans1, trans2);
+        if (inter.HasCommonGen())
+        {
+          const gp_Pnt& aPChar = inter.PChar();
+          Quad1.Parameters(aPChar, U1, V1);
+          Quad2.Parameters(aPChar, U2, V2);
+          aPtsol.SetValue(aPChar, Tol, Standard_False);
+          aPtsol.SetParameters(U1, V1, U2, V2);
+          aPtsol.SetParameter(0.);
+          glig->AddVertex(aPtsol);
+        }
+        slin.Append(glig);
+      }
+    }
+    break;
+
+    case IntAna_Parabola:
+    {
+      IntPatch_Point aPtsol;
+      gp_Parab       parabsol = inter.Parabola(1);
+
+      gp_Vec        Tgtorig(parabsol.YAxis().Direction());
+      Standard_Real ptran = Tgtorig.DotCross(Quad2.Normale(parabsol.Location()), Quad1.Normale(parabsol.Location()));
+      if (ptran > 0.00000001)
+      {
+        trans1 = IntSurf_Out;
+        trans2 = IntSurf_In;
+      }
+      else if (ptran < -0.00000001)
+      {
+        trans1 = IntSurf_In;
+        trans2 = IntSurf_Out;
+      }
+      else
+      {
+        trans1 = trans2 = IntSurf_Undecided;
+      }
+
+      Handle(IntPatch_GLine) glig = new IntPatch_GLine(parabsol, Standard_False, trans1, trans2);
+      if (inter.HasCommonGen())
+      {
+        const gp_Pnt& aPChar = inter.PChar();
+        Quad1.Parameters(aPChar, U1, V1);
+        Quad2.Parameters(aPChar, U2, V2);
+        aPtsol.SetValue(aPChar, Tol, Standard_False);
+        aPtsol.SetParameters(U1, V1, U2, V2);
+        aPtsol.SetParameter(0.);
+        glig->AddVertex(aPtsol);
+      }
+      slin.Append(glig);
+    }
+    break;
+
+    case IntAna_NoGeometricSolution:
+    {
+      gp_Pnt             psol;
+      IntAna_IntQuadQuad anaint(Co1, Co2, Tol);
+      if (!anaint.IsDone())
+      {
+        return Standard_False;
+      }
+
+      if (anaint.NbPnt() == 0 && anaint.NbCurve() == 0)
+      {
+        Empty = Standard_True;
+      }
+      else
+      {
+        NbSol = anaint.NbPnt();
+        for (i = 1; i <= NbSol; i++)
+        {
+          psol = anaint.Point(i);
+          Quad1.Parameters(psol, U1, V1);
+          Quad2.Parameters(psol, U2, V2);
+          IntPatch_Point ptsol;
+          ptsol.SetValue(psol, Tol, Standard_True);
+          ptsol.SetParameters(U1, V1, U2, V2);
+          spnt.Append(ptsol);
+        }
+
+        gp_Pnt ptvalid, ptf, ptl;
+        gp_Vec tgvalid;
+
+        Standard_Real    first, last, para;
+        Standard_Boolean tgfound, firstp, lastp, kept;
+        Standard_Integer kount;
+
+        NbSol = anaint.NbCurve();
+        for (i = 1; i <= NbSol; i++)
+        {
+          Handle(IntPatch_ALine) alig;
+          kept                 = Standard_False;
+          IntAna_Curve curvsol = anaint.Curve(i);
+          curvsol.Domain(first, last);
+          firstp = !curvsol.IsFirstOpen();
+          lastp  = !curvsol.IsLastOpen();
+          if (firstp)
+          {
+            ptf = curvsol.Value(first);
+          }
+          if (lastp)
+          {
+            ptl = curvsol.Value(last);
+          }
+          para    = last;
+          kount   = 1;
+          tgfound = Standard_False;
+
+          while (!tgfound)
+          {
+            para    = (1.123 * first + para) / 2.123;
+            tgfound = curvsol.D1u(para, ptvalid, tgvalid);
+            if (tgvalid.SquareMagnitude() < 1e-14)
+            {
+              //-- on se trouve ds un cas ou les normales n'auront pas de sens
+              tgfound = Standard_False;
+            }
+
+            if (!tgfound)
+            {
+              kount++;
+              tgfound = kount > 5;
+            }
+          }
+          if (kount <= 5)
+          {
+            Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid), Quad1.Normale(ptvalid));
+            if (qwe > 0.000000001)
+            {
+              trans1 = IntSurf_Out;
+              trans2 = IntSurf_In;
+            }
+            else if (qwe < -0.000000001)
+            {
+              trans1 = IntSurf_In;
+              trans2 = IntSurf_Out;
+            }
+            else
+            {
+              trans1 = trans2 = IntSurf_Undecided;
+            }
+            alig = new IntPatch_ALine(curvsol, Standard_False, trans1, trans2);
+            kept = Standard_True;
+          }
+          else
+          {
+            ptvalid = curvsol.Value(para);
+            alig    = new IntPatch_ALine(curvsol, Standard_False);
+            kept    = Standard_True;
+            //-- cout << "Transition indeterminee" << endl;
+          }
+          if (kept)
+          {
+            Standard_Boolean Nfirstp = !firstp;
+            Standard_Boolean Nlastp  = !lastp;
+            ProcessBounds(alig, slin, Quad1, Quad2, Nfirstp, ptf, first, Nlastp, ptl, last, Multpoint, Tol);
+            slin.Append(alig);
+          }
+        }
+      }
+    }
+    break;
+
+    default:
+    {
+      return Standard_False;
+    }
+  }
+
+  //When two cones have common generatrix passing through apexes
+  //it is necessary to add it is solution
+  if (inter.HasCommonGen())
+  {
+    Standard_Real  para;
+    IntPatch_Point aPtsol;
+    gp_Pnt         aPApex1, aPApex2;
+    aPApex1 = Co1.Apex();
+    aPApex2 = Co2.Apex();
+    //common generatrix of cones
+    gce_MakeLin            aMkLin(aPApex1, aPApex2);
+    const gp_Lin&          linsol = aMkLin.Value();
+    Handle(IntPatch_GLine) glig   = new IntPatch_GLine(linsol, Standard_True, IntSurf_Undecided, IntSurf_Undecided);
+
+    const gp_Pnt& aPChar          = inter.PChar();
+    Quad1.Parameters(aPChar, U1, V1);
+    Quad2.Parameters(aPChar, U2, V2);
+    aPtsol.SetValue(aPChar, Tol, Standard_False);
+    aPtsol.SetParameters(U1, V1, U2, V2);
+    para = ElCLib::Parameter(linsol, aPChar);
+    aPtsol.SetParameter(para);
+    glig->AddVertex(aPtsol);
+
+    slin.Append(glig);
+  }
+
+  return Standard_True;
+}
+//=======================================================================
+//function : IntCoSp
+//purpose  :
+//=======================================================================
+Standard_Boolean IntCoSp(const IntSurf_Quadric&    Quad1,
+                         const IntSurf_Quadric&    Quad2,
+                         const Standard_Real       Tol,
+                         const Standard_Boolean    Reversed,
+                         Standard_Boolean&         Empty,
+                         Standard_Boolean&         Multpoint,
+                         IntPatch_SequenceOfLine&  slin,
+                         IntPatch_SequenceOfPoint& spnt)
+
+{
+  Standard_Integer i;
+
+  IntSurf_TypeTrans trans1, trans2;
+  IntAna_ResultType typint;
+
+  gp_Sphere     Sp;
+  gp_Cone       Co;
+  Standard_Real U1, V1, U2, V2;
+
+  if (!Reversed)
+  {
+    Co = Quad1.Cone();
+    Sp = Quad2.Sphere();
+  }
+  else
+  {
+    Co = Quad2.Cone();
+    Sp = Quad1.Sphere();
+  }
+  IntAna_QuadQuadGeo inter(Sp, Co, Tol);
+
+  if (!inter.IsDone())
+  {
+    return Standard_False;
+  }
+
+  typint                 = inter.TypeInter();
+  Standard_Integer NbSol = inter.NbSolutions();
+  Empty                  = Standard_False;
+
+  switch (typint)
+  {
+    case IntAna_Empty:
+    {
+      Empty = Standard_True;
+    }
+    break;
+
+    case IntAna_Point:
+    {
+      gp_Pnt        ptcontact;
+      gp_Pnt        apex(Co.Apex());
+      Standard_Real param;
+      Standard_Real paramapex = ElCLib::LineParameter(Co.Axis(), apex);
+      for (i = 1; i <= NbSol; i++)
+      {
+        ptcontact = inter.Point(i);
+        param     = ElCLib::LineParameter(Co.Axis(), ptcontact);
+        Quad1.Parameters(ptcontact, U1, V1);
+        Quad2.Parameters(ptcontact, U2, V2);
+
+        if (apex.Distance(ptcontact) <= Tol)
+        {
+          IntPatch_Point ptsol;
+          ptsol.SetValue(ptcontact, Tol, Standard_False);
+          ptsol.SetParameters(U1, V1, U2, V2);
+          spnt.Append(ptsol);
+        }
+        else if (param >= paramapex)
+        {
+          IntPatch_Point ptsol;
+          ptsol.SetValue(ptcontact, Tol, Standard_True);
+          ptsol.SetParameters(U1, V1, U2, V2);
+          spnt.Append(ptsol);
+        }
+      }
+    }
+    break;
+
+    case IntAna_Circle:
+    {
+      gp_Vec Tgt;
+      gp_Pnt ptref;
+
+      for (i = 1; i <= NbSol; i++)
+      {
+        gp_Circ cirsol = inter.Circle(i);
+        //-- param = ElCLib::LineParameter(Co.Axis(),
+        //--                         cirsol.Location());
+        //-- if (param >= paramapex) {
+
+        ElCLib::D1(0., cirsol, ptref, Tgt);
+        Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref), Quad1.Normale(ptref));
+        if (qwe > 0.00000001)
+        {
+          trans1 = IntSurf_Out;
+          trans2 = IntSurf_In;
+        }
+        else if (qwe < -0.00000001)
+        {
+          trans1 = IntSurf_In;
+          trans2 = IntSurf_Out;
+        }
+        else
+        {
+          trans1 = trans2 = IntSurf_Undecided;
+        }
+        Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol, Standard_False, trans1, trans2);
+        slin.Append(glig);
+        //-- }
+      }
+    }
+    break;
+
+    case IntAna_PointAndCircle:
+    {
+      gp_Vec        Tgt;
+      gp_Pnt        ptref;
+      gp_Pnt        apex(Co.Apex());
+      Standard_Real param;
+      Standard_Real paramapex = ElCLib::LineParameter(Co.Axis(), apex);
+
+      // le point est necessairement l apex
+      Quad1.Parameters(apex, U1, V1);
+      Quad2.Parameters(apex, U2, V2);
+      IntPatch_Point ptsol;
+      ptsol.SetValue(apex, Tol, Standard_False);
+      ptsol.SetParameters(U1, V1, U2, V2);
+      spnt.Append(ptsol);
+
+      gp_Circ cirsol = inter.Circle(1);
+      param          = ElCLib::LineParameter(Co.Axis(), cirsol.Location());
+      ElCLib::D1(0., cirsol, ptref, Tgt);
+      Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref), Quad1.Normale(ptref));
+
+      if (param >= paramapex)
+      {
+        if (qwe > Precision::PConfusion())
+        {
+          trans1 = IntSurf_Out;
+          trans2 = IntSurf_In;
+        }
+        else if (qwe < -Precision::PConfusion())
+        {
+          trans1 = IntSurf_In;
+          trans2 = IntSurf_Out;
+        }
+        else
+        {
+          trans1 = trans2 = IntSurf_Undecided;
+        }
+      }
+      else
+      {
+        if (qwe < -Precision::PConfusion())
+        {
+          trans1 = IntSurf_Out;
+          trans2 = IntSurf_In;
+        }
+        else if (qwe > Precision::PConfusion())
+        {
+          trans1 = IntSurf_In;
+          trans2 = IntSurf_Out;
+        }
+        else
+        {
+          trans1 = trans2 = IntSurf_Undecided;
+        }
+      }
+      Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol, Standard_False, trans1, trans2);
+      slin.Append(glig);
+    }
+    break;
+
+    case IntAna_NoGeometricSolution:
+    {
+      gp_Pnt             psol;
+      IntAna_IntQuadQuad anaint(Co, Sp, Tol);
+      if (!anaint.IsDone())
+      {
+        return Standard_False;
+      }
+
+      if (anaint.NbPnt() == 0 && anaint.NbCurve() == 0)
+      {
+        Empty = Standard_True;
+      }
+      else
+      {
+        NbSol = anaint.NbPnt();
+        for (i = 1; i <= NbSol; i++)
+        {
+          psol = anaint.Point(i);
+          Quad1.Parameters(psol, U1, V1);
+          Quad2.Parameters(psol, U2, V2);
+          IntPatch_Point ptsol;
+          ptsol.SetValue(psol, Tol, Standard_True);
+          ptsol.SetParameters(U1, V1, U2, V2);
+          spnt.Append(ptsol);
+        }
+
+        gp_Pnt           ptvalid, ptf, ptl;
+        gp_Vec           tgvalid;
+        Standard_Real    first, last, para;
+        Standard_Boolean tgfound, firstp, lastp, kept;
+        Standard_Integer kount;
+
+        NbSol = anaint.NbCurve();
+        for (i = 1; i <= NbSol; i++)
+        {
+          Handle(IntPatch_ALine) alig;
+          kept                 = Standard_False;
+          IntAna_Curve curvsol = anaint.Curve(i);
+          curvsol.Domain(first, last);
+          firstp = !curvsol.IsFirstOpen();
+          lastp  = !curvsol.IsLastOpen();
+          if (firstp)
+          {
+            ptf = curvsol.Value(first);
+          }
+          if (lastp)
+          {
+            ptl = curvsol.Value(last);
+          }
+          para    = last;
+          kount   = 1;
+          tgfound = Standard_False;
+
+          while (!tgfound)
+          {
+            para    = (1.123 * first + para) / 2.123;
+            tgfound = curvsol.D1u(para, ptvalid, tgvalid);
+            if (!tgfound)
+            {
+              kount++;
+              tgfound = kount > 5;
+            }
+          }
+          if (kount <= 5)
+          {
+            para              = ElCLib::LineParameter(Co.Axis(), ptvalid);
+            Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid), Quad1.Normale(ptvalid));
+            if (qwe > 0.000000001)
+            {
+              trans1 = IntSurf_Out;
+              trans2 = IntSurf_In;
+            }
+            else if (qwe < -0.000000001)
+            {
+              trans1 = IntSurf_In;
+              trans2 = IntSurf_Out;
+            }
+            else
+            {
+              trans1 = trans2 = IntSurf_Undecided;
+            }
+            alig = new IntPatch_ALine(curvsol, Standard_False, trans1, trans2);
+            kept = Standard_True;
+          }
+          else
+          {
+            ptvalid = curvsol.Value(para);
+            para    = ElCLib::LineParameter(Co.Axis(), ptvalid);
+            alig    = new IntPatch_ALine(curvsol, Standard_False);
+            kept    = Standard_True;
+            //-- cout << "Transition indeterminee" << endl;
+          }
+          if (kept)
+          {
+            Standard_Boolean Nfirstp = !firstp;
+            Standard_Boolean Nlastp  = !lastp;
+            ProcessBounds(alig, slin, Quad1, Quad2, Nfirstp, ptf, first, Nlastp, ptl, last, Multpoint, Tol);
+            slin.Append(alig);
+          }
+        }
+      }
+    }
+    break;
+
+    default:
+    {
+      return Standard_False;
+    }
+  }
+
+  return Standard_True;
+}
+//=======================================================================
+//function : IntSpSp
+//purpose  :
+//=======================================================================
+Standard_Boolean IntSpSp(const IntSurf_Quadric&    Quad1,
+                         const IntSurf_Quadric&    Quad2,
+                         const Standard_Real       Tol,
+                         Standard_Boolean&         Empty,
+                         Standard_Boolean&         Same,
+                         IntPatch_SequenceOfLine&  slin,
+                         IntPatch_SequenceOfPoint& spnt)
+
+// Traitement du cas Sphere/Sphere
+
+{
+  IntSurf_TypeTrans trans1, trans2;
+  IntAna_ResultType typint;
+  gp_Sphere         sph1(Quad1.Sphere());
+  gp_Sphere         sph2(Quad2.Sphere());
+
+  IntAna_QuadQuadGeo inter(sph1, sph2, Tol);
+  if (!inter.IsDone())
+  {
+    return Standard_False;
+  }
+
+  typint = inter.TypeInter();
+  Empty  = Standard_False;
+  Same   = Standard_False;
+
+  switch (typint)
+  {
+    case IntAna_Empty:
+    {
+      Empty = Standard_True;
+    }
+    break;
+
+    case IntAna_Same:
+    {
+      Same = Standard_True;
+    }
+    break;
+
+    case IntAna_Point:
+    {
+      gp_Pnt        psol(inter.Point(1));
+      Standard_Real U1, V1, U2, V2;
+      Quad1.Parameters(psol, U1, V1);
+      Quad2.Parameters(psol, U2, V2);
+      IntPatch_Point ptsol;
+      ptsol.SetValue(psol, Tol, Standard_True);
+      ptsol.SetParameters(U1, V1, U2, V2);
+      spnt.Append(ptsol);
+    }
+    break;
+
+    case IntAna_Circle:
+    {
+      gp_Circ cirsol = inter.Circle(1);
+      gp_Pnt  ptref;
+      gp_Vec  Tgt;
+      ElCLib::D1(0., cirsol, ptref, Tgt);
+
+      Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref), Quad1.Normale(ptref));
+      if (qwe > 0.00000001)
+      {
+        trans1 = IntSurf_Out;
+        trans2 = IntSurf_In;
+      }
+      else if (qwe < -0.00000001)
+      {
+        trans1 = IntSurf_In;
+        trans2 = IntSurf_Out;
+      }
+      else
+      {
+        trans1 = trans2 = IntSurf_Undecided;
+      }
+      Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol, Standard_False, trans1, trans2);
+      slin.Append(glig);
+    }
+    break;
+
+    default:
+    {
+      return Standard_False; // on ne doit pas passer ici
+    }
+  }
+  return Standard_True;
+}
+
+static Standard_Boolean TreatResultTorus(const IntSurf_Quadric&    theQuad1,
+                                         const IntSurf_Quadric&    theQuad2,
+                                         const IntAna_QuadQuadGeo& anInt,
+                                         Standard_Boolean&         bEmpty,
+                                         IntPatch_SequenceOfLine&  theSeqLin);
+
+//=======================================================================
+//function : IntCyTo
+//purpose  :
+//=======================================================================
+Standard_Boolean IntCyTo(const IntSurf_Quadric&   theQuad1,
+                         const IntSurf_Quadric&   theQuad2,
+                         const Standard_Real      theTolTang,
+                         const Standard_Boolean   bReversed,
+                         Standard_Boolean&        bEmpty,
+                         IntPatch_SequenceOfLine& theSeqLin)
+{
+  const gp_Cylinder aCyl   = bReversed ? theQuad2.Cylinder() : theQuad1.Cylinder();
+  const gp_Torus    aTorus = bReversed ? theQuad1.Torus() : theQuad2.Torus();
+  //
+  IntAna_QuadQuadGeo anInt(aCyl, aTorus, theTolTang);
+  Standard_Boolean   bRet = TreatResultTorus(theQuad1, theQuad2, anInt, bEmpty, theSeqLin);
+  //
+  return bRet;
+}
+
+//=======================================================================
+//function : IntCoTo
+//purpose  :
+//=======================================================================
+Standard_Boolean IntCoTo(const IntSurf_Quadric&   theQuad1,
+                         const IntSurf_Quadric&   theQuad2,
+                         const Standard_Real      theTolTang,
+                         const Standard_Boolean   bReversed,
+                         Standard_Boolean&        bEmpty,
+                         IntPatch_SequenceOfLine& theSeqLin)
+{
+  const gp_Cone  aCone  = bReversed ? theQuad2.Cone() : theQuad1.Cone();
+  const gp_Torus aTorus = bReversed ? theQuad1.Torus() : theQuad2.Torus();
+  //
+  IntAna_QuadQuadGeo anInt(aCone, aTorus, theTolTang);
+  Standard_Boolean   bRet = TreatResultTorus(theQuad1, theQuad2, anInt, bEmpty, theSeqLin);
+  //
+  return bRet;
+}
+
+//=======================================================================
+//function : IntSpTo
+//purpose  :
+//=======================================================================
+Standard_Boolean IntSpTo(const IntSurf_Quadric&   theQuad1,
+                         const IntSurf_Quadric&   theQuad2,
+                         const Standard_Real      theTolTang,
+                         const Standard_Boolean   bReversed,
+                         Standard_Boolean&        bEmpty,
+                         IntPatch_SequenceOfLine& theSeqLin)
+{
+  const gp_Sphere aSphere = bReversed ? theQuad2.Sphere() : theQuad1.Sphere();
+  const gp_Torus  aTorus  = bReversed ? theQuad1.Torus() : theQuad2.Torus();
+  //
+  IntAna_QuadQuadGeo anInt(aSphere, aTorus, theTolTang);
+  Standard_Boolean   bRet = TreatResultTorus(theQuad1, theQuad2, anInt, bEmpty, theSeqLin);
+  //
+  return bRet;
+}
+
+//=======================================================================
+//function : IntToTo
+//purpose  :
+//=======================================================================
+Standard_Boolean IntToTo(const IntSurf_Quadric&   theQuad1,
+                         const IntSurf_Quadric&   theQuad2,
+                         const Standard_Real      theTolTang,
+                         Standard_Boolean&        bSameSurf,
+                         Standard_Boolean&        bEmpty,
+                         IntPatch_SequenceOfLine& theSeqLin)
+{
+  const gp_Torus aTorus1 = theQuad1.Torus();
+  const gp_Torus aTorus2 = theQuad2.Torus();
+  //
+  IntAna_QuadQuadGeo anInt(aTorus1, aTorus2, theTolTang);
+  Standard_Boolean   bRet = anInt.IsDone();
+  if (bRet)
+  {
+    if (anInt.TypeInter() == IntAna_Same)
+    {
+      bEmpty    = Standard_False;
+      bSameSurf = Standard_True;
+    }
+    else
+    {
+      bRet = TreatResultTorus(theQuad1, theQuad2, anInt, bEmpty, theSeqLin);
+    }
+  }
+  //
+  return bRet;
+}
+
+//=======================================================================
+//function : TreatResultTorus
+//purpose  :
+//=======================================================================
+static Standard_Boolean TreatResultTorus(const IntSurf_Quadric&    theQuad1,
+                                         const IntSurf_Quadric&    theQuad2,
+                                         const IntAna_QuadQuadGeo& anInt,
+                                         Standard_Boolean&         bEmpty,
+                                         IntPatch_SequenceOfLine&  theSeqLin)
+{
+  Standard_Boolean bRet = anInt.IsDone();
+  //
+  if (!bRet)
+  {
+    return bRet;
+  }
+  //
+  IntAna_ResultType typint = anInt.TypeInter();
+  Standard_Integer  NbSol  = anInt.NbSolutions();
+  bEmpty                   = Standard_False;
+  //
+  switch (typint)
+  {
+    case IntAna_Empty: bEmpty = Standard_True; break;
+    //
+    case IntAna_Circle:
+    {
+      Standard_Integer  i;
+      IntSurf_TypeTrans trans1, trans2;
+      gp_Vec            Tgt;
+      gp_Pnt            ptref;
+      //
+      for (i = 1; i <= NbSol; ++i)
+      {
+        gp_Circ aC = anInt.Circle(i);
+        if (theQuad1.TypeQuadric() == theQuad2.TypeQuadric())
+        {
+          AdjustToSeam(theQuad1.Torus(), aC);
+        }
+        ElCLib::D1(0., aC, ptref, Tgt);
+        Standard_Real qwe = Tgt.DotCross(theQuad2.Normale(ptref), theQuad1.Normale(ptref));
+        if (qwe > 0.00000001)
+        {
+          trans1 = IntSurf_Out;
+          trans2 = IntSurf_In;
+        }
+        else if (qwe < -0.00000001)
+        {
+          trans1 = IntSurf_In;
+          trans2 = IntSurf_Out;
+        }
+        else
+        {
+          trans1 = trans2 = IntSurf_Undecided;
+        }
+        //
+        Handle(IntPatch_GLine) glig = new IntPatch_GLine(aC, Standard_False, trans1, trans2);
+        theSeqLin.Append(glig);
+      }
+    }
+    break;
+    //
+    case IntAna_NoGeometricSolution:
+    default: bRet = Standard_False; break;
+  }
+  //
+  return bRet;
+}
diff --git a/src/IntPatch/IntPatch_ImpImpIntersection_0.gxx b/src/IntPatch/IntPatch_ImpImpIntersection_0.gxx
deleted file mode 100644 (file)
index f7ed758..0000000
+++ /dev/null
@@ -1,2075 +0,0 @@
-// Created on: 1992-05-07
-// Created by: Jacques GOUSSARD
-// Copyright (c) 1992-1999 Matra Datavision
-// Copyright (c) 1999-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.
-
-//  Modified by skv - Thu Jan 15 15:57:15 2004 OCC4455
-
-#include <IntPatch_ThePathPointOfTheSOnBounds.hxx>
-#include <IntPatch_TheSegmentOfTheSOnBounds.hxx>
-#include <IntPatch_RLine.hxx>
-#include <IntSurf.hxx>
-#include <TColStd_Array1OfInteger.hxx>
-#include <TColStd_SequenceOfReal.hxx>
-#include <IntPatch_GLine.hxx>
-#include <Extrema_ExtPC.hxx>
-#include <GeomAdaptor_Curve.hxx>
-#include <Geom_Ellipse.hxx>
-#include <Geom_Parabola.hxx>
-#include <Geom_Hyperbola.hxx>
-#include <IntPatch_ALine.hxx>
-
-
-static void PutPointsOnLine(const Handle(Adaptor3d_Surface)& S1,
-                           const Handle(Adaptor3d_Surface)& S2,
-                           const IntPatch_SequenceOfPathPointOfTheSOnBounds&,
-                           const IntPatch_SequenceOfLine&,
-                           const Standard_Boolean,
-                           const Handle(Adaptor3d_TopolTool)&,
-                           const IntSurf_Quadric&,
-                           const IntSurf_Quadric&,
-                           const Standard_Boolean,
-                           const Standard_Real);
-
-static Standard_Boolean MultiplePoint(const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
-                                      const Handle(Adaptor3d_TopolTool)& Domain,
-                                      const IntSurf_Quadric& QuadSurf,
-                                      const gp_Vec&    Normale,
-                                      const IntPatch_SequenceOfLine& slin,
-                                      TColStd_Array1OfInteger& Done,
-                                      TColStd_Array1OfInteger& UsedLine,
-                                      const Standard_Integer Index,
-                                      const Standard_Boolean OnFirst,
-                                      const Standard_Real theToler);
-
-static Standard_Boolean PointOnSecondDom(const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
-                                         const Handle(Adaptor3d_TopolTool)& Domain,
-                                         const IntSurf_Quadric& QuadSurf,
-                                         const gp_Vec&    Normale,
-                                         const gp_Vec&    Vtgint,
-                                         const Handle(IntPatch_Line)& lin,
-                                         TColStd_Array1OfInteger& Done,
-                                         const Standard_Integer Index,
-                                         const Standard_Real theToler);
-
-static Standard_Boolean SingleLine (const gp_Pnt&,
-                                   const Handle(IntPatch_Line)&,
-                                   const Standard_Real,
-                                   Standard_Real&,
-                                   gp_Vec&);
-
-
-static Standard_Boolean FindLine(gp_Pnt& Psurf,
-                                 const IntPatch_SequenceOfLine& slin,
-                                 const Standard_Real Tol,
-                                 TColStd_ListOfReal& theLParams,
-                                 gp_Vec& Vtgtint,
-                                 Standard_Integer& theLineIdx,
-                                 Standard_Integer OnlyThisLine,
-                                 const Handle(Adaptor2d_Curve2d)& thearc,
-                                 Standard_Real& theparameteronarc,
-                                 gp_Pnt& thepointonarc,
-                                 const IntSurf_Quadric& QuadSurf1,
-                                 const IntSurf_Quadric& QuadSurf2,
-                                 Standard_Real& theOutputToler);
-
-static void ProcessSegments (const IntPatch_SequenceOfSegmentOfTheSOnBounds&,
-                            IntPatch_SequenceOfLine&,
-                            const IntSurf_Quadric&,
-                            const IntSurf_Quadric&,
-                            const Standard_Boolean,
-                            const Standard_Real);
-
-static void ProcessRLine (IntPatch_SequenceOfLine&,
-                         const IntSurf_Quadric&,
-                         const IntSurf_Quadric&,
-                         const Standard_Real,
-                          const Standard_Boolean theIsReqToKeepRLine);
-
-//-- le calcul de dist est completement faux ds la routine ci dessous a revoir (lbr le 18 nov 97)
-Standard_Boolean IntersectionWithAnArc(gp_Pnt& PSurf,
-                                      const Handle(IntPatch_ALine)& alin,
-                                      Standard_Real& para,
-                                      const Handle(Adaptor2d_Curve2d)& thearc,
-                                      Standard_Real& _theparameteronarc,
-                                      gp_Pnt& thepointonarc,
-                                      const IntSurf_Quadric& QuadSurf,
-                                      const Standard_Real u0alin,
-                                      const Standard_Real u1alin) { 
-  Standard_Real dtheta,theta;
-#ifdef OCCT_DEBUG
-  //Standard_Real u,v,A,B,C,cost,sint,sign;
-#endif
-  //-- recherche bete du point le plus proche de thearc->Value(...)
-  dtheta = (u1alin-u0alin)*0.01;
-  Standard_Real du=0.000000001;
-  if (du >= dtheta)
-    du = dtheta/2;
-  Standard_Real distmin = RealLast();
-
-  Standard_Real thetamin = 0.;
-
-  Standard_Real theparameteronarc = _theparameteronarc;
-  for(Standard_Real _theta=u0alin+dtheta; _theta<=u1alin-dtheta; _theta+=dtheta) { 
-    gp_Pnt P=alin->Value(_theta);
-    Standard_Real d=P.Distance(PSurf);
-    if(d<distmin) { 
-      thetamin=_theta;
-      distmin=d;
-    }
-  }
-
-  Standard_Real bestpara =0., besttheta =0., bestdist =0., distinit =0. ;
-
-  //-- Distance initiale
-  {
-    gp_Pnt pp0 = alin->Value(thetamin);
-    Standard_Real ua0,va0;
-    QuadSurf.Parameters(pp0,ua0,va0);
-    gp_Pnt2d p2d;
-    gp_Vec2d d2d;
-    thearc->D1(theparameteronarc,p2d,d2d);
-    gp_Vec2d PaPr(gp_Pnt2d(ua0,va0),p2d);
-    distinit=PaPr.Magnitude();
-  }
-  theta = thetamin;
-  //-- recherche a partir de theta et theparameteronarc
-  Standard_Boolean cpasok=Standard_True;
-  Standard_Integer nbiter=0;
-  Standard_Real drmax = (thearc->LastParameter() - thearc->FirstParameter())*0.05;
-  Standard_Real damax = (u1alin-u0alin)*0.05;
-
-
-  
-  bestdist = RealLast();
-
-  do { 
-    Standard_Real ua0,va0,ua1,va1;
-    //-- alin->Curve().InternalUVValue(theta,ua0,va0,A,B,C,cost,sint,sign);
-    //-- alin->Curve().InternalUVValue(theta+du,ua1,va1,A,B,C,cost,sint,sign);
-    gp_Pnt pp0 = alin->Value(theta);
-    gp_Pnt pp1 = alin->Value(theta+du);
-    QuadSurf.Parameters(pp0,ua0,va0);
-    QuadSurf.Parameters(pp1,ua1,va1);
-    
-    
-    gp_Vec2d D1a((ua1-ua0)/du,(va1-va0)/du);
-    gp_Pnt2d p2d;
-    gp_Vec2d d2d;
-    thearc->D1(theparameteronarc,p2d,d2d);
-    gp_Vec2d PaPr(gp_Pnt2d(ua0,va0),p2d);
-    
-    Standard_Real pbd=PaPr.Magnitude();
-    if(bestdist>pbd) {
-      bestdist = pbd;
-      bestpara = theparameteronarc;
-      besttheta = theta;
-    }
-
-    D1a.SetCoord(-D1a.X(),-D1a.Y());
-    
-    Standard_Real d  = D1a.X()    *   d2d.Y()   -   D1a.Y()     * d2d.X();
-    
-    Standard_Real da = (-PaPr.X())*   d2d.Y()   -   (-PaPr.Y()) * d2d.X();
-    Standard_Real dr =  D1a.X()   * (-PaPr.Y()) -   D1a.Y()     * (-PaPr.X());
-    if(Abs(d)>1e-15) { 
-      da/=d;
-      dr/=d;
-    }
-    else { 
-      if(Abs(PaPr.X())>Abs(PaPr.Y())) { 
-       Standard_Real xx=PaPr.X();
-       xx*=0.5;
-       if(D1a.X()) { 
-         da = -xx/D1a.X();
-       }
-       if(d2d.X()) { 
-         dr = -xx/d2d.X();
-       }
-      }
-      else { 
-       Standard_Real yy=PaPr.Y();
-       yy*=0.5;
-       if(D1a.Y()) { 
-         da = -yy/D1a.Y();
-       }
-       if(d2d.Y()) { 
-         dr = -yy/d2d.Y();
-       }       
-      }
-    } 
-//--     Standard_Real da = -PaPr.Dot(D1a);
-//--     Standard_Real dr = -PaPr.Dot(d2d);
-    
-    if(da<-damax) da=-damax;
-    else if(da>damax) da=damax;
-    if(dr<-drmax) dr=-drmax;
-    else if(dr>drmax) dr=drmax;
-
-    if(Abs(da)<1e-10 && Abs(dr)<1e-10) { 
-      para = theta; 
-      PSurf = alin->Value(para);
-      _theparameteronarc=theparameteronarc;
-      thepointonarc = alin->Value(para);
-      cpasok=Standard_False;
-//--      printf("\nt:%d",nbiter);
-      return(Standard_True);
-    }
-    else { 
-      theta+=da;
-      theparameteronarc+=dr;
-      if(   theparameteronarc>thearc->LastParameter() ) { 
-       theparameteronarc = thearc->LastParameter();
-      }
-      if(  theparameteronarc<thearc->FirstParameter() ) { 
-       theparameteronarc = thearc->FirstParameter();
-      }
-      if( theta < u0alin) { 
-       theta = u0alin;
-      }
-      if( theta > u1alin-du) { 
-       theta = u1alin-du-du; 
-      }
-    }
-    nbiter++;
-  }
-  while(cpasok && nbiter<20);
-  if(bestdist < distinit) { 
-    para = besttheta; 
-    PSurf = alin->Value(para);
-    _theparameteronarc=bestpara;
-    thepointonarc = alin->Value(para);
-//--     printf("\nT:%d",nbiter);
-    return(Standard_True);
-  }
-//--   printf("\nF:%d",nbiter);
-  return(Standard_False);
-}
-
-
-
-
-
-//-- ======================================================================
-static void Recadre(const Handle(Adaptor3d_Surface)& myHS1,
-                   const Handle(Adaptor3d_Surface)& myHS2,
-                   Standard_Real& u1,
-                   Standard_Real& v1,
-                   Standard_Real& u2,
-                   Standard_Real& v2) { 
-  Standard_Real f,l,lmf,fpls2;
-  GeomAbs_SurfaceType typs1 = myHS1->GetType();
-  GeomAbs_SurfaceType typs2 = myHS2->GetType();
-
-  Standard_Boolean myHS1IsUPeriodic,myHS1IsVPeriodic;
-  switch (typs1) { 
-  case GeomAbs_Cylinder:
-  case GeomAbs_Cone:
-  case GeomAbs_Sphere: 
-    { 
-      myHS1IsUPeriodic = Standard_True;
-      myHS1IsVPeriodic = Standard_False;
-      break;
-    }
-  case GeomAbs_Torus:
-    {
-      myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_True;
-      break;
-    }
-  default:
-     {
-       //-- Le cas de biparametrees periodiques est gere en amont
-       myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_False;
-       break;
-     }
-  }
-
-  Standard_Boolean myHS2IsUPeriodic,myHS2IsVPeriodic;
-  switch (typs2) { 
-  case GeomAbs_Cylinder:
-  case GeomAbs_Cone:
-  case GeomAbs_Sphere: 
-    { 
-      myHS2IsUPeriodic = Standard_True;
-      myHS2IsVPeriodic = Standard_False;
-      break;
-    }
-  case GeomAbs_Torus:
-    {
-      myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_True;
-      break;
-    }
-  default:
-     {
-       //-- Le cas de biparametrees periodiques est gere en amont
-       myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_False;
-       break;
-     }
-  }
-  if(myHS1IsUPeriodic) {
-    lmf = M_PI+M_PI; //-- myHS1->UPeriod();
-    f = myHS1->FirstUParameter();
-    l = myHS1->LastUParameter();
-    fpls2=0.5*(f+l);
-    while((u1 < f)&&((fpls2-u1) > (u1+lmf-fpls2)   )) { u1+=lmf; } 
-    while((u1 > l)&&((u1-fpls2) > (fpls2-(u1-lmf)) )) { u1-=lmf; }
-    
-  }
-  if(myHS1IsVPeriodic) {
-    lmf = M_PI+M_PI; //-- myHS1->VPeriod(); 
-    f = myHS1->FirstVParameter();
-    l = myHS1->LastVParameter();
-    fpls2=0.5*(f+l);
-    while((v1 < f)&&((fpls2-v1) > (v1+lmf-fpls2)   )) { v1+=lmf; } 
-    while((v1 > l)&&((v1-fpls2) > (fpls2-(v1-lmf)) )) { v1-=lmf; }
-    //--    while(v1 < f) { v1+=lmf; } 
-    //--    while(v1 > l) { v1-=lmf; }
-  }
-  if(myHS2IsUPeriodic) { 
-    lmf = M_PI+M_PI; //-- myHS2->UPeriod();
-    f = myHS2->FirstUParameter();
-    l = myHS2->LastUParameter();
-    fpls2=0.5*(f+l);
-    while((u2 < f)&&((fpls2-u2) > (u2+lmf-fpls2)   )) { u2+=lmf; } 
-    while((u2 > l)&&((u2-fpls2) > (fpls2-(u2-lmf)) )) { u2-=lmf; }
-    //-- while(u2 < f) { u2+=lmf; } 
-    //-- while(u2 > l) { u2-=lmf; }
-  }
-  if(myHS2IsVPeriodic) { 
-    lmf = M_PI+M_PI; //-- myHS2->VPeriod();
-    f = myHS2->FirstVParameter();
-    l = myHS2->LastVParameter();
-    fpls2=0.5*(f+l);
-    while((v2 < f)&&((fpls2-v2) > (v2+lmf-fpls2)   )) { v2+=lmf; } 
-    while((v2 > l)&&((v2-fpls2) > (fpls2-(v2-lmf)) )) { v2-=lmf; }
-    //-- while(v2 < f) { v2+=lmf; } 
-    //-- while(v2 > l) { v2-=lmf; }
-  }
-}
-//=======================================================================
-//function : PutPointsOnLine
-//purpose  : 
-//=======================================================================
-void PutPointsOnLine(const Handle(Adaptor3d_Surface)& S1,
-                    const Handle(Adaptor3d_Surface)& S2, 
-                    const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
-                    const IntPatch_SequenceOfLine& slin,
-                    const Standard_Boolean OnFirst,
-                    const Handle(Adaptor3d_TopolTool)& Domain,
-                    const IntSurf_Quadric& QuadSurf,
-                    const IntSurf_Quadric& OtherQuad,
-                    const Standard_Boolean multpoint,
-                    const Standard_Real Tolarc) { 
-  
-  // Traitement des point (de listpnt) de depart. On les replace sur
-  // la ligne d intersection, en leur affectant la transition correcte sur
-  // cette ligne.
-  Standard_Integer nbpnt = listpnt.Length();
-  Standard_Integer nblin=slin.Length();
-
-  if (!slin.Length() || !nbpnt) {
-    return;
-  }
-  //
-  Standard_Integer i,k;
-  Standard_Integer linenumber;
-  Standard_Real currentparameter,tolerance;
-  Standard_Real U1,V1,U2,V2;
-  Standard_Boolean goon;
-  
-  
-  gp_Pnt Psurf, ptbid;
-  gp_Vec Normale, Vtgint, Vtgrst;
-  
-  gp_Vec d1u,d1v;
-  gp_Pnt2d p2d;
-  gp_Vec2d d2d;
-  
-  IntSurf_Transition Transline,Transarc;
-
-  Handle(Adaptor2d_Curve2d) currentarc;
-  Handle(Adaptor3d_HVertex) vtx,vtxbis;
-  
-  IntPatch_Point solpnt;
-  IntPatch_ThePathPointOfTheSOnBounds currentpointonrst;
-  IntPatch_IType TheType;
-
-  TColStd_Array1OfInteger UsedLine(1,nblin);
-  TColStd_Array1OfInteger Done(1,nbpnt);
-  for(i=1;i<=nbpnt;i++) Done(i) = 0; //-- Initialisation a la main 
-  
-  for (i=1; i<=nbpnt; i++) {
-    
-    if (Done(i) != 1) {
-      currentpointonrst = listpnt.Value(i);
-      Psurf   = currentpointonrst.Value();   // Point dans l espace
-      tolerance = currentpointonrst.Tolerance();
-      
-      // On recherche d abord si on a correspondance avec un "point multiple"
-      UsedLine.Init(0);
-
-      goon = Standard_True;
-      if (multpoint) {
-#if 1 
-       Normale = QuadSurf.Normale(Psurf);     // Normale a la surface au point      
-       currentarc = currentpointonrst.Arc();
-       currentparameter = currentpointonrst.Parameter();
-       currentarc->D1(currentparameter,p2d,d2d);
-       QuadSurf.D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
-       Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
-#endif      
-        goon = MultiplePoint(listpnt,Domain,QuadSurf,Normale,slin,Done, UsedLine,
-                             i, OnFirst, Tolarc);
-      }
-      if (goon) {
-        Standard_Boolean linefound = Standard_False;
-       
-       for(Standard_Integer indiceline = 1; indiceline <=slin.Length(); indiceline++) { 
-         if( UsedLine(indiceline) != 0 )
-            continue;
-         linenumber = indiceline;
-
-         //-- Attention , les points peuvent etre deplaces 
-         //-- il faut reprendre le point original
-         currentpointonrst = listpnt.Value(i);
-         currentarc = currentpointonrst.Arc();
-         currentparameter = currentpointonrst.Parameter();
-         Psurf   = currentpointonrst.Value();   // Point dans l espace
-         tolerance = currentpointonrst.Tolerance();
-         //-- 
-
-
-         //  Modified by skv - Thu Jan 15 15:57:15 2004 OCC4455 Begin
-         if (! currentpointonrst.IsNew()) {
-           Handle(Adaptor3d_HVertex) aVtx    = currentpointonrst.Vertex();
-           Standard_Real aVtxTol = aVtx->Resolution(currentarc);
-           Standard_Real aTolAng = 0.01*tolerance;
-
-           tolerance = Max(tolerance, aVtxTol);
-
-           gp_Vec aNorm1  = QuadSurf.Normale(Psurf);
-           gp_Vec aNorm2  = OtherQuad.Normale(Psurf);
-           //
-           if (aNorm1.Magnitude()>gp::Resolution() &&
-               aNorm2.Magnitude()>gp::Resolution()) { 
-           
-             if (aNorm1.IsParallel(aNorm2, aTolAng))
-               tolerance = Sqrt(tolerance);
-           }//
-         }
-         //  Modified by skv - Thu Jan 15 15:57:15 2004 OCC4455 End
-         gp_Pnt pointonarc;
-         Vtgint.SetCoord(0,0,0);
-          Standard_Real aVertTol = Tolarc;
-          TColStd_ListOfReal aLParams;
-          linefound = FindLine(Psurf, slin, tolerance, aLParams, Vtgint, linenumber,
-                               indiceline, currentarc, currentparameter,
-                               pointonarc, QuadSurf, OtherQuad, aVertTol);
-         if (linefound) {
-           
-#if 1 
-           Normale = QuadSurf.Normale(Psurf);     // Normale a la surface au point      
-           currentarc = currentpointonrst.Arc();
-           //-- currentparameter = currentpointonrst.Parameter();
-           currentarc->D1(currentparameter,p2d,d2d);
-           QuadSurf.D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
-           Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
-#endif      
-           
-           
-           
-           const Handle(IntPatch_Line)& lin = slin.Value(linenumber);
-           TheType = lin->ArcType();
-           
-           if (!OnFirst) { // on cherche la correspondance entre point sur domaine
-             // de la premiere surface et point sur domaine de la
-             // deuxieme surface
-             
-             goon = PointOnSecondDom (listpnt, Domain, QuadSurf, Normale, 
-                                       Vtgint, lin, Done, i, aVertTol);
-           }
-           
-           if (goon) {
-             //-- Modification du 4 avril 97    tolerance->Tolarc
-             //-- on replace sur le vertex la tolerance d entree et 
-             //-- non la tolerance qui a servi au FindLine
-              solpnt.SetValue(Psurf, aVertTol, Standard_False);
-             
-             U1 = p2d.X(); V1 = p2d.Y();
-             OtherQuad.Parameters(Psurf,U2,V2);
-             
-             if (OnFirst) {
-               Recadre(S1,S2,U1,V1,U2,V2);
-               solpnt.SetParameters(U1,V1,U2,V2);
-             }
-             else {
-               Recadre(S1,S2,U2,V2,U1,V1);
-               solpnt.SetParameters(U2,V2,U1,V1);
-             }
-             
-             if (! currentpointonrst.IsNew()) {
-               vtx = currentpointonrst.Vertex();
-               solpnt.SetVertex(OnFirst,vtx);
-             }
-             else {
-               //-- goon = Standard_False; ???? 
-             }
-             
-             if(Normale.SquareMagnitude()<1e-16) { 
-               Transline.SetValue(Standard_True,IntSurf_Undecided);
-               Transarc.SetValue(Standard_True,IntSurf_Undecided);         
-             }
-             else {                            
-               IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,Transline,Transarc);
-             }
-             solpnt.SetArc(OnFirst,currentarc, currentparameter,
-                           Transline,Transarc);
-
-              for (TColStd_ListIteratorOfListOfReal anItr(aLParams);
-                   anItr.More(); anItr.Next())
-              {
-                solpnt.SetParameter(anItr.Value());
-                if (TheType == IntPatch_Analytic)
-                {
-                  Handle(IntPatch_ALine)::DownCast(lin)->AddVertex(solpnt);
-                }
-                else
-                {
-                  Handle(IntPatch_GLine)::DownCast(lin)->AddVertex(solpnt);
-                }
-              }
-
-             Done(i) = 1;
-             
-             if (goon) {
-               for (k=i+1; k<= nbpnt; k++) {
-                 if (Done(k) != 1) {
-                   currentpointonrst = listpnt.Value(k);
-                   if (!currentpointonrst.IsNew()) {
-                     vtxbis = currentpointonrst.Vertex();
-                     if(vtx.IsNull()) { 
-                     }               
-                     else if (Domain->Identical(vtx, vtxbis)) {
-                       solpnt.SetVertex(OnFirst,vtxbis);
-                        solpnt.SetTolerance(Tolarc);
-                       currentarc = currentpointonrst.Arc();
-                       currentparameter = currentpointonrst.Parameter();
-                       
-                       //                    currentarc->D1(currentparameter,ptbid,Vtgrst);
-                       currentarc->D1(currentparameter,p2d,d2d);
-                       Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
-                       if(Normale.SquareMagnitude()<1e-16) { 
-                         Transline.SetValue(Standard_True,IntSurf_Undecided);
-                         Transarc.SetValue(Standard_True,IntSurf_Undecided);       
-                       }
-                       else {                                    
-                         IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,
-                                                 Transline,Transarc);
-                       }
-                       solpnt.SetArc(OnFirst,currentarc,currentparameter,
-                                     Transline,Transarc);
-                       if (TheType == IntPatch_Analytic) {
-                         Handle(IntPatch_ALine)::DownCast (lin)->AddVertex(solpnt);
-                       }
-                       else {
-                         Handle(IntPatch_GLine)::DownCast (lin)->AddVertex(solpnt);
-                       }
-                       Done(k) = 1;
-                     }
-                   }
-                 }
-               }
-             }
-           }
-         }
-         else {
-           Done(i) = 1; // il faudra tester si IsNew ou pas
-           // et traiter en consequence
-         }
-       }
-      }
-    }
-  }
-}
-
-
-Standard_Boolean  MultiplePoint (const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
-                                const Handle(Adaptor3d_TopolTool)& Domain,
-                                const IntSurf_Quadric& QuadSurf,
-                                const gp_Vec&    Normale,
-                                const IntPatch_SequenceOfLine& slin,
-                                 TColStd_Array1OfInteger& Done,
-                                 TColStd_Array1OfInteger& UsedLine,
-                                 const Standard_Integer Index,
-                                const Standard_Boolean OnFirst,
-                                 const Standard_Real theToler) {
-
-// Traitement des points "multiples".
-
-  
-  Standard_Integer k,ii,jj,nbvtx;
-  Standard_Integer nblin = slin.Length();
-  IntPatch_IType TheType;
-  
-  
-  IntSurf_Transition Transline,Transarc;
-
-
-  IntPatch_Point intpt;
-  Handle(Adaptor2d_Curve2d) currentarc;
-  Handle(Adaptor3d_HVertex) vtx,vtxbis;
-
-  Standard_Integer nbpnt = listpnt.Length();
-  IntPatch_ThePathPointOfTheSOnBounds currentpointonrst = listpnt.Value(Index);
-  IntPatch_ThePathPointOfTheSOnBounds otherpt;
-  gp_Pnt Point = currentpointonrst.Value();
-  TColStd_Array1OfInteger localdone(1,nbpnt); localdone.Init(0);
-  for (ii=1; ii<=nbpnt; ii++) {
-    localdone(ii)=Done(ii);
-  }
-
-  Standard_Real currentparameter;
-  Standard_Real Paraint;
-  gp_Vec Vtgint,Vtgrst;
-  gp_Pnt ptbid;
-
-  gp_Vec d1u,d1v;
-  gp_Pnt2d p2d;
-  gp_Vec2d d2d;
-
-  Standard_Boolean goon;
-
-  Standard_Boolean Retvalue = Standard_True;
-
-  for (ii = 1; ii <= nblin; ii++) {
-    const Handle(IntPatch_Line)& slinValueii = slin.Value(ii);
-    TheType = slinValueii->ArcType();
-    if (TheType == IntPatch_Analytic) {
-      nbvtx = Handle(IntPatch_ALine)::DownCast (slinValueii)->NbVertex();
-    }
-    else {
-      nbvtx = Handle(IntPatch_GLine)::DownCast (slinValueii)->NbVertex();
-    }
-    jj = 1;
-    while (jj <= nbvtx) {
-      if (TheType == IntPatch_Analytic) {
-       intpt = Handle(IntPatch_ALine)::DownCast (slinValueii)->Vertex(jj);
-      }
-      else {
-       intpt = Handle(IntPatch_GLine)::DownCast (slinValueii)->Vertex(jj);
-      }
-      if (intpt.IsMultiple() && 
-          (( OnFirst && !intpt.IsOnDomS1()) ||
-           (!OnFirst && !intpt.IsOnDomS2()))) {
-       if (Point.Distance(intpt.Value()) <= intpt.Tolerance()) {
-         Retvalue = Standard_False;
-         Standard_Boolean foo = SingleLine(Point,slinValueii,
-                                           intpt.Tolerance(),Paraint,Vtgint);
-         if (!foo) {
-           return Standard_False;   // ne doit pas se produire
-         }
-
-         if (!currentpointonrst.IsNew()) {
-            goon = Standard_True;
-            vtx = currentpointonrst.Vertex();
-            intpt.SetVertex(OnFirst,vtx);
-          } 
-          else {
-            goon = Standard_False;
-          }
-          currentarc = currentpointonrst.Arc();
-         currentparameter = currentpointonrst.Parameter();
-         currentarc->D1(currentparameter,p2d,d2d);
-         QuadSurf.D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
-         Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
-
-         //-- Si la normale est nulle (apex d un cone) On simule une transition UNKNOWN
-         if(Normale.SquareMagnitude()<1e-16) { 
-           Transline.SetValue(Standard_True,IntSurf_Undecided);
-           Transarc.SetValue(Standard_True,IntSurf_Undecided);     
-         }
-         else { 
-           IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,Transline,Transarc);
-         }
-
-         //-- Avant, on ne mettait pas ce point (17 nov 97)
-         //--printf("\n ImpImp_0  : Point(%g,%g,%g)  intpt(%g,%g,%g) \n",
-         //--  Point.X(),Point.Y(),Point.Z(),intpt.Value().X(),intpt.Value().Y(),intpt.Value().Z());
-         intpt.SetValue(Point);
-
-         intpt.SetArc(OnFirst,currentarc,currentparameter,
-                      Transline,Transarc);
-          intpt.SetTolerance(theToler);
-
-         if (TheType == IntPatch_Analytic) {
-           Handle(IntPatch_ALine)::DownCast (slinValueii)->Replace(jj,intpt);
-         }
-         else {
-           Handle(IntPatch_GLine)::DownCast (slinValueii)->Replace(jj,intpt);
-         }
-          localdone(Index) = 1;
-         if (goon) {
-            for (k=Index+1; k<= nbpnt; k++) {
-              if (Done(k) != 1) {
-                otherpt= listpnt.Value(k);
-                if (!otherpt.IsNew()) {
-                 vtxbis = otherpt.Vertex();
-                 if (Domain->Identical(vtx, vtxbis)) {
-                   intpt.SetVertex(OnFirst,vtxbis);
-                    currentarc = otherpt.Arc();
-                   currentparameter = otherpt.Parameter();
-                   
-                   currentarc->D1(currentparameter,p2d,d2d);
-                   Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
-                   if(Normale.SquareMagnitude()<1e-16) { 
-                     Transline.SetValue(Standard_True,IntSurf_Undecided);
-                     Transarc.SetValue(Standard_True,IntSurf_Undecided);           
-                   }
-                   else {    
-                     IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,
-                                             Transline,Transarc);
-                   }
-                   intpt.SetArc(OnFirst,currentarc,currentparameter,
-                                 Transline,Transarc);
-                    intpt.SetTolerance(theToler);
-                   if (TheType == IntPatch_Analytic) {
-                     Handle(IntPatch_ALine)::DownCast (slinValueii)->AddVertex(intpt);
-                   }
-                   else {
-                     Handle(IntPatch_GLine)::DownCast (slinValueii)->AddVertex(intpt);
-                   }
-                   UsedLine(ii) = 1;
-                   Retvalue = Standard_True;
-                    localdone(k) = 1;
-                  }
-                }
-              }
-           }
-         }
-//--           jj = nbvtx +1;
-       }
-//--         else {
-          jj = jj+1;
-//--        }
-      }
-      else {
-        jj = jj+1;
-      }
-    }
-  }
-  
-  for (ii=1; ii<=nbpnt;ii++) {
-    Done(ii) = localdone(ii);
-  }
-  
-  return Retvalue;
-}
-    
-
-
-Standard_Boolean PointOnSecondDom (const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
-                                  const Handle(Adaptor3d_TopolTool)& Domain,
-                                  const IntSurf_Quadric& QuadSurf,
-                                  const gp_Vec&    Normale,
-                                  const gp_Vec&    Vtgint,
-                                  const Handle(IntPatch_Line)& lin,
-                                  TColStd_Array1OfInteger& Done,
-                                  const Standard_Integer Index,
-                                   const Standard_Real theToler)
-     
-
-// Duplication des points sur domaine de l autre surface.
-// On sait que le vertex sous-jacent est PntRef
-
-
-{
-
-  Standard_Integer k,jj,nbvtx;
-  IntPatch_IType TheType;
-
-  IntSurf_Transition Transline,Transarc;
-  IntPatch_Point intpt;
-  Handle(Adaptor2d_Curve2d) currentarc;
-  Handle(Adaptor3d_HVertex) vtx,vtxbis;
-  gp_Pnt ptbid;
-  gp_Vec Vtgrst;
-
-  gp_Vec d1u,d1v;
-  gp_Pnt2d p2d;
-  gp_Vec2d d2d;
-
-  Standard_Integer nbpnt = listpnt.Length();
-  IntPatch_ThePathPointOfTheSOnBounds currentpointonrst = listpnt.Value(Index);
-  Standard_Real currentparameter;
-
-  Standard_Boolean goon;
-  Standard_Boolean Retvalue = Standard_True;
-
-  TheType = lin->ArcType();
-  if (TheType == IntPatch_Analytic) {
-    nbvtx = Handle(IntPatch_ALine)::DownCast (lin)->NbVertex();
-  }
-  else {
-    nbvtx = Handle(IntPatch_GLine)::DownCast (lin)->NbVertex();
-  }
-  jj = 1;
-  while (jj <= nbvtx) {
-    if (TheType == IntPatch_Analytic) {
-      intpt = Handle(IntPatch_ALine)::DownCast (lin)->Vertex(jj);
-    }
-    else {
-      intpt = Handle(IntPatch_GLine)::DownCast (lin)->Vertex(jj);
-    }
-    if (!intpt.IsOnDomS2()) {
-      if (currentpointonrst.Value().Distance(intpt.Value()) <= 
-          intpt.Tolerance()) {
-        Retvalue = Standard_False;
-       if (!currentpointonrst.IsNew()) {
-          goon = Standard_True;
-          vtx = currentpointonrst.Vertex();
-          intpt.SetVertex(Standard_False,vtx);
-        }
-       else {
-          goon = Standard_False;
-        }
-       currentarc = currentpointonrst.Arc();
-       currentparameter = currentpointonrst.Parameter();
-       currentarc->D1(currentparameter,p2d,d2d);
-       QuadSurf.D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
-       Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
-       if(Normale.SquareMagnitude()<1e-16) { 
-         Transline.SetValue(Standard_True,IntSurf_Undecided);
-         Transarc.SetValue(Standard_True,IntSurf_Undecided);       
-       }
-       else {          
-         IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,Transline,Transarc);
-       }
-       intpt.SetArc(Standard_False,currentarc,currentparameter,
-                    Transline,Transarc);
-        intpt.SetTolerance(theToler);
-
-       if (TheType == IntPatch_Analytic) {
-         Handle(IntPatch_ALine)::DownCast (lin)->Replace(jj,intpt);
-       }
-       else {
-         Handle(IntPatch_GLine)::DownCast (lin)->Replace(jj,intpt);
-       }
-        Done(Index) = 1;
-
-       if (goon) {
-          for (k=Index+1; k<= nbpnt; k++) {
-            if (Done(k) != 1) {
-              currentpointonrst = listpnt.Value(k);
-              if (!currentpointonrst.IsNew()) {
-               vtxbis = currentpointonrst.Vertex();
-                  if (Domain->Identical(vtx, vtxbis)) {
-                 intpt.SetVertex(Standard_False,vtxbis);
-                  currentarc = currentpointonrst.Arc();
-                 currentparameter = currentpointonrst.Parameter();
-                 currentarc->D1(currentparameter,p2d,d2d);
-                 Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
-                 if(Normale.SquareMagnitude()<1e-16) { 
-                   Transline.SetValue(Standard_True,IntSurf_Undecided);
-                   Transarc.SetValue(Standard_True,IntSurf_Undecided);     
-                 }
-                 else {                                    
-                   IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,
-                                           Transline,Transarc);
-                 }
-                 intpt.SetArc(Standard_False,currentarc,currentparameter,
-                               Transline,Transarc);
-                  intpt.SetTolerance(theToler);
-                 if (TheType == IntPatch_Analytic) {
-                   Handle(IntPatch_ALine)::DownCast (lin)->AddVertex(intpt);
-                 }
-                 else {
-                   Handle(IntPatch_GLine)::DownCast (lin)->AddVertex(intpt);
-                 }
-                  Done(k) = 1;
-                }
-              }
-            }
-         }
-       }
-        //-- jj = nbvtx + 1;
-       jj++;
-      }
-      else {
-        jj = jj+1;
-      }
-    }
-    else {
-      jj = jj+1;
-    }
-    if (TheType == IntPatch_Analytic) {
-      nbvtx = Handle(IntPatch_ALine)::DownCast (lin)->NbVertex();
-    }
-    else {
-      nbvtx = Handle(IntPatch_GLine)::DownCast (lin)->NbVertex();
-    }
-  }
-  return Retvalue;
-}
-
-
-
-Standard_Boolean FindLine(gp_Pnt& Psurf,
-                          const IntPatch_SequenceOfLine& slin,
-                          const Standard_Real Tol,
-                          TColStd_ListOfReal& theLParams,
-                          gp_Vec& Vtgtint,
-                          Standard_Integer& theLineIdx,
-                          Standard_Integer OnlyThisLine,
-                          const Handle(Adaptor2d_Curve2d)& thearc,
-                          Standard_Real& theparameteronarc,
-                          gp_Pnt& thepointonarc,
-                          const IntSurf_Quadric& QuadSurf1,
-                          const IntSurf_Quadric& QuadSurf2,
-                          Standard_Real& theOutputToler)
-{
-  if ((QuadSurf1.Distance(Psurf) > Tol) || (QuadSurf2.Distance(Psurf) > Tol))
-    return Standard_False;
-
-// Traitement du point de depart ayant pour representation Psurf
-// dans l espace. On recherche la ligne d intersection contenant ce point.
-// On a en sortie la ligne, et le parametre et sa tangente du point sur
-// la ligne d intersection.
-  const Standard_Real aSqTol = Tol*Tol;
-  Standard_Real aSqDistMin = RealLast();
-  Standard_Real aSqDist, para;
-  Standard_Real lower,upper;
-  gp_Pnt pt;
-  Standard_Integer i;
-  IntPatch_IType typarc;
-
-  Standard_Real aParaInt = RealLast();
-  Standard_Integer nblin = slin.Length();
-  for (i=1; i<=nblin; i++) {
-    if(OnlyThisLine) { i=OnlyThisLine; nblin=0; }
-    const Handle(IntPatch_Line)& lin = slin.Value(i);
-    typarc = lin->ArcType();
-    if (typarc == IntPatch_Analytic) {
-      Standard_Boolean foo;
-      lower = Handle(IntPatch_ALine)::DownCast (lin)->FirstParameter(foo);
-      upper = Handle(IntPatch_ALine)::DownCast (lin)->LastParameter(foo);
-    }
-    else {
-      if (Handle(IntPatch_GLine)::DownCast (lin)->HasFirstPoint()) {
-       lower = Handle(IntPatch_GLine)::DownCast (lin)->FirstPoint().ParameterOnLine();
-      }
-      else {
-       lower = RealFirst();
-      }
-      if (Handle(IntPatch_GLine)::DownCast (lin)->HasLastPoint()) {
-       upper = Handle(IntPatch_GLine)::DownCast (lin)->LastPoint().ParameterOnLine();
-      }
-      else {
-       upper = RealLast();
-      }
-    }
-
-    switch (typarc) {
-    case IntPatch_Lin :
-      {
-       para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Line(),Psurf);
-       if (para <= upper && para >= lower) {
-         pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Line());
-          aSqDist = Psurf.SquareDistance(pt);
-          if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
-          {
-            aSqDistMin = aSqDist;
-            aParaInt = para;
-            theLineIdx = i;
-         }
-       }
-      }
-      break;
-    case IntPatch_Circle :
-      {
-       para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Circle(),Psurf);
-       if ((para <= upper && para >= lower) ||
-           (para + 2.*M_PI <=upper && para + 2.*M_PI >= lower) ||
-           (para - 2.*M_PI <=upper && para - 2.*M_PI >= lower)) {
-         pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Circle());
-          aSqDist = Psurf.SquareDistance(pt);
-          if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
-          {
-            aSqDistMin = aSqDist;
-            aParaInt = para;
-            theLineIdx = i;
-         }
-       }
-      }
-      break;
-    case IntPatch_Ellipse :
-      {
-       para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Ellipse(),Psurf);
-       if ((para <= upper && para >= lower) ||
-           (para + 2.*M_PI <=upper && para + 2.*M_PI >= lower) ||
-           (para - 2.*M_PI <=upper && para - 2.*M_PI >= lower)) {
-         pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Ellipse());
-          aSqDist = Psurf.SquareDistance(pt);
-          if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
-          {
-            aSqDistMin = aSqDist;
-            aParaInt = para;
-            theLineIdx = i;
-         }
-       }
-      }
-      break;
-    case IntPatch_Parabola :
-      {
-       
-#if 0  
-       para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Parabola(),Psurf);
-       if (para <= upper && para >= lower) {
-         pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Parabola());
-         dist = Psurf.Distance(pt);
-         if (dist< distmin) {
-           distmin = dist;
-           Paraint = para;
-           Range = i;
-         }
-       }
-#else 
-       //-- Le calcul du parametre sur une parabole est mal fait ds ElCLib. Il ne tient pas compte
-       //-- de la meilleure facon de calculer (axe X ou axe Y). Bilan : Si la parabole est tres 
-       //-- pointue (focal de l'ordre de 1e-2 et si le point est a un parametre grand, ca foire. )
-       //-- On ne peut pas modifier faciolement ds ElCLib car on ne passe pas la focale. ...
-       const gp_Parab& Parab=Handle(IntPatch_GLine)::DownCast (lin)->Parabola();
-       para = ElCLib::Parameter(Parab,Psurf);
-       if (para <= upper && para >= lower) {
-         Standard_Integer amelioration=0;
-         //-- cout<<"\n ****** \n";
-         do { 
-           Standard_Real parabis = para+0.0000001;
-           
-           pt = ElCLib::Value(para,Parab);
-            aSqDist = Psurf.SquareDistance(pt);
-           
-           const gp_Pnt ptbis = ElCLib::Value(parabis,Parab);
-           const Standard_Real distbis = Psurf.Distance(ptbis);
-            const Standard_Real aDist = Sqrt(aSqDist);
-            const Standard_Real ddist = distbis - aDist;
-           
-           //--cout<<" para: "<<para<<"    dist:"<<dist<<"   ddist:"<<ddist<<endl;
-           
-            if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
-            {
-              aSqDistMin = aSqDist;
-              aParaInt = para;
-              theLineIdx = i;
-           }
-            if (aSqDist < Precision::SquarePConfusion())
-            {
-              amelioration = 100;
-            }
-             
-           if(ddist>1.0e-9 || ddist<-1.0e-9 ) { 
-              para = para - aDist*(parabis - para) / ddist;
-           }
-           else { 
-             amelioration=100;
-           }
-         }
-         while(++amelioration < 5);
-       }
-
-
-#endif
-      }
-      break;
-    case IntPatch_Hyperbola :
-      {
-       para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola(),Psurf);
-       if (para <= upper && para >= lower) {
-         pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola());
-          aSqDist = Psurf.SquareDistance(pt);
-          if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
-          {
-            aSqDistMin = aSqDist;
-            aParaInt = para;
-            theLineIdx = i;
-         }
-       }
-      }
-      break;
-
-    case IntPatch_Analytic :
-      {
-        Handle(IntPatch_ALine) alin(Handle(IntPatch_ALine)::DownCast(lin));
-        TColStd_ListOfReal aLParams;
-        alin->FindParameter(Psurf, aLParams);
-        if (!aLParams.IsEmpty())
-        {
-          // All found distances are already in some internal tolerance
-          // set in alin->FindParameter(...) method.
-
-          aSqDist = RealLast();
-          for (TColStd_ListIteratorOfListOfReal anItr(aLParams);
-               anItr.More(); anItr.Next())
-          {
-            pt = alin->Value(anItr.Value());
-            const Standard_Real aSqD = Psurf.SquareDistance(pt);
-            if (aSqD < aSqDist)
-            {
-              aSqDist = aSqD;
-            }
-          }
-
-          if (aSqDist < aSqDistMin)
-          {
-            aSqDistMin = aSqDist;
-            theLParams = aLParams;
-            theLineIdx = i;
-          }
-        }
-       else { 
-         //-- le point n a pas ete trouve par bete projection.
-         //-- on essaie l intersection avec la restriction en 2d
-         Standard_Real theparamonarc = theparameteronarc;
-//#ifdef OCCT_DEBUG
-//       Standard_Real anpara=para;
-//#endif
-         gp_Pnt CopiePsurf=Psurf;
-          Standard_Boolean IntersectIsOk = IntersectionWithAnArc(CopiePsurf, alin, para, 
-                                                                 thearc, theparamonarc,
-                                                                 thepointonarc,
-                                                                 QuadSurf1,
-                                                                 lower, upper);
-          aSqDist = CopiePsurf.SquareDistance(Psurf);
-         if(IntersectIsOk) {
-            if (aSqDist < aSqTol)
-            {
-             theparameteronarc = theparamonarc;
-             Psurf = thepointonarc;
-              aSqDistMin = aSqDist;
-              theLParams.Append(para);
-              theLineIdx = i;
-           }
-         }
-       }
-      }
-      break;
-
-    case IntPatch_Walking: // impossible . c est pour eviter les warnings
-      {
-      }
-    case IntPatch_Restriction: // impossible . c est pour eviter les warnings
-      {
-      }
-    }
-  }
-
-  if (aSqDistMin == RealLast())
-    return Standard_False;
-
-  theOutputToler = Max(theOutputToler, Sqrt(aSqDistMin));
-
-  typarc = slin.Value(theLineIdx)->ArcType();
-
-  // Computation of tangent vector
-  switch (typarc) {
-  case IntPatch_Lin :
-    theLParams.Append(aParaInt);
-    Vtgtint = (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Line().Direction();
-    break;
-  case IntPatch_Circle :
-    theLParams.Append(aParaInt);
-    Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Circle(), 1);
-    break;
-  case IntPatch_Ellipse :
-    theLParams.Append(aParaInt);
-    Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Ellipse(), 1);
-    break;
-  case IntPatch_Parabola :
-    theLParams.Append(aParaInt);
-    Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Parabola(), 1);
-    break;
-  case IntPatch_Hyperbola :
-    theLParams.Append(aParaInt);
-    Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Hyperbola(), 1);
-    break;
-
-  case IntPatch_Analytic:
-    {
-      if (!Handle(IntPatch_ALine)::DownCast(slin(theLineIdx))->D1(theLParams.Last(), pt, Vtgtint))
-      {
-        //Previously (before the fix #29807) this code tried to process case
-        //when Handle(IntPatch_ALine)::D1(...) method returns FALSE and
-        //computed Vtgtint input argument value. Currently, any singularities
-        //must be processed by high-level algorithms (IntPatch_SpecialPoints class).
-        //Therefore this code has been deleted as deprecated.
-
-        Vtgtint.SetCoord(0.0, 0.0, 0.0);
-      }
-    }
-    break;
-  case IntPatch_Walking: // impossible . c est pour eviter les warnings
-    {
-    }
-  case IntPatch_Restriction: // impossible . c est pour eviter les warnings
-    {
-    }
-    
-  }
-  return Standard_True;
-}
-
-//=======================================================================
-//function : SingleLine
-//purpose  : Traitement du point de depart ayant pour representation Psurf
-//            dans l espace. On le replace sur la ligne d intersection; On a en sortie
-//            son parametre et sa tangente sur la ligne d intersection.
-//            La fonction renvoie False si le point projete est a une distance
-//            superieure a Tol du point a projeter.
-//=======================================================================
-Standard_Boolean  SingleLine(const gp_Pnt& Psurf,
-                             const Handle(IntPatch_Line)& lin,
-                             const Standard_Real Tol,
-                             Standard_Real& Paraint,
-                             gp_Vec& Vtgtint)
-{
-  IntPatch_IType typarc = lin->ArcType();
-
-  Standard_Real parproj = 0.;
-  gp_Vec tgint;
-  gp_Pnt ptproj;
-  Standard_Boolean retvalue;
-
-  switch (typarc) {
-  case IntPatch_Lin :
-    parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Line(),Psurf);
-    ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Line(),ptproj,tgint);
-    break;
-  case IntPatch_Circle :
-    parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Circle(),Psurf);
-    ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Circle(),ptproj,tgint);
-    break;
-  case IntPatch_Ellipse :
-    parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Ellipse(),Psurf);
-    ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Ellipse(),ptproj,tgint);
-    break;
-  case IntPatch_Parabola :
-    parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Parabola(),Psurf);
-    ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Parabola(),ptproj,tgint);
-    break;
-  case IntPatch_Hyperbola :
-    parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola(),Psurf);
-    ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola(),ptproj,tgint);
-    break;
-  case IntPatch_Analytic :
-    {
-      Handle(IntPatch_ALine) alin(Handle(IntPatch_ALine)::DownCast(lin));
-      TColStd_ListOfReal aLParams;
-      alin->FindParameter(Psurf, aLParams);
-      if (!aLParams.IsEmpty())
-      {
-        ptproj = Psurf;
-        parproj = aLParams.Last();
-        gp_Pnt aPtemp;
-        if (!alin->D1(parproj, aPtemp, tgint))
-        {
-          //Previously (before the fix #29807) this code tried to process case
-          //when Handle(IntPatch_ALine)::D1(...) method returns FALSE and
-          //computed Vtgtint input argument value. Currently, any singularities
-          //must be processed by high-level algorithms (IntPatch_SpecialPoints class).
-          //Therefore this code has been deleted as deprecated.
-
-          tgint.SetCoord(0.0, 0.0, 0.0);
-        }
-      }
-      else
-      {
-        //-- cout << "---- Pb sur ligne analytique dans SingleLine" << endl;
-        //-- cout << "     Find Parameter"<<endl;
-        return Standard_False;
-      }
-    }
-    break;
-  case IntPatch_Walking: // impossible . c est pour eviter les warnings
-    {
-    }
-  case IntPatch_Restriction: // impossible . c est pour eviter les warnings
-    {
-    }
-  }
-
-  if (Psurf.Distance(ptproj) <= Tol) {
-    Paraint = parproj;
-    Vtgtint = tgint;
-    retvalue = Standard_True;
-  }
-  else {
-    retvalue = Standard_False;
-  }
-  return retvalue;
-}
-
-
-void ProcessSegments (const IntPatch_SequenceOfSegmentOfTheSOnBounds& listedg,
-                     IntPatch_SequenceOfLine& slin,
-                     const IntSurf_Quadric& Quad1,
-                     const IntSurf_Quadric& Quad2,
-                     const Standard_Boolean OnFirst,
-                     const Standard_Real TolArc) {
-     
-  Standard_Integer i,j,k;
-  Standard_Integer nbedg = listedg.Length();
-  Standard_Integer Nblines,Nbpts;
-
-  Handle(Adaptor2d_Curve2d) arcRef;
-  IntPatch_Point ptvtx, newptvtx;
-
-  Handle(IntPatch_RLine)  rline; //-- On fait rline = new ... par la suite 
-
-  IntPatch_TheSegmentOfTheSOnBounds thesegsol;
-  IntPatch_ThePathPointOfTheSOnBounds PStartf,PStartl;
-  Standard_Boolean dofirst,dolast,procf,procl;
-
-  Standard_Real paramf =0.,paraml =0.,U1 =0.,V1 =0.,U2 =0.,V2 =0.;
-
-  IntPatch_IType typ;
-  IntSurf_TypeTrans trans1,trans2;
-  IntSurf_Transition TRest,TArc;
-  gp_Vec tgline,norm1,norm2,tgarc;
-  gp_Pnt valpt;
-
-  gp_Vec d1u,d1v;
-  gp_Pnt2d p2d;
-  gp_Vec2d d2d;
-
-
-  for (i = 1; i <= nbedg; i++) {
-    Standard_Boolean EdgeDegenere=Standard_False;
-    thesegsol = listedg.Value(i);
-    arcRef = thesegsol.Curve();
-
-
-    rline = new IntPatch_RLine(Standard_False);
-    if(OnFirst) { 
-      rline->SetArcOnS1(arcRef);
-    }
-    else { 
-      rline->SetArcOnS2(arcRef);
-    }
-
-// Traitement des points debut/fin du segment solution.
-
-    dofirst = Standard_False;
-    dolast  = Standard_False;
-    procf = Standard_False;
-    procl = Standard_False;
-
-    if (thesegsol.HasFirstPoint()) {
-      dofirst = Standard_True;
-      PStartf = thesegsol.FirstPoint();
-      paramf = PStartf.Parameter();
-    }
-    if (thesegsol.HasLastPoint()) {
-      dolast = Standard_True;
-      PStartl = thesegsol.LastPoint();
-      paraml = PStartl.Parameter();
-    }
-
-    if (dofirst && dolast) { // determination de la transition de la ligne
-      arcRef->D1(0.5*(paramf+paraml),p2d,d2d);
-      if (OnFirst) {
-       Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
-      }
-      else {
-       Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
-      }
-      tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
-
-      if(d1u.Magnitude()<1e-7) { //-- edge degenere ?
-        EdgeDegenere=Standard_True;
-       for(Standard_Integer edg=0;edg<=10;edg++) {
-         arcRef->D1(paramf+(paraml-paramf)*edg*0.1,p2d,d2d);
-         if (OnFirst) {
-           Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
-         }
-         else {
-           Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
-         }
-         
-         if(d1u.Magnitude()>1e-7) {
-           EdgeDegenere=Standard_False;
-         }
-       }
-       rline = new IntPatch_RLine(Standard_False);     
-       if(OnFirst) { 
-         rline->SetArcOnS1(arcRef);
-       }
-       else { 
-         rline->SetArcOnS2(arcRef);
-       }       
-      }
-      else { 
-       norm2 = Quad2.Normale(valpt);
-       norm1 = Quad1.Normale(valpt);
-       
-       if (tgline.DotCross(norm2,norm1) > 0.000000001) {
-         trans1 = IntSurf_Out;
-         trans2 = IntSurf_In;
-       }
-       else if (tgline.DotCross(norm2,norm1) < -0.000000001){
-         trans1 = IntSurf_In;
-         trans2 = IntSurf_Out;
-       }
-       else { 
-         trans1 = trans2 = IntSurf_Undecided;
-       }
-       rline = new IntPatch_RLine(Standard_False,trans1,trans2);
-       if(OnFirst) { 
-         rline->SetArcOnS1(arcRef);
-       }
-       else { 
-         rline->SetArcOnS2(arcRef);
-       }       
-      }
-    }
-    else {
-      rline = new IntPatch_RLine(Standard_False);
-      if(OnFirst) { 
-       rline->SetArcOnS1(arcRef);
-      }
-      else { 
-       rline->SetArcOnS2(arcRef);
-      }        
-    }
-
-    if (dofirst || dolast) {
-      Nblines = slin.Length();
-      for (j=1; j<=Nblines; j++) {
-       const Handle(IntPatch_Line)& slinj = slin(j);
-       typ = slinj->ArcType();
-       if (typ == IntPatch_Analytic) {
-         Nbpts = Handle(IntPatch_ALine)::DownCast (slinj)->NbVertex();
-       }
-       else if (typ == IntPatch_Restriction) {
-         Nbpts = Handle(IntPatch_RLine)::DownCast (slinj)->NbVertex();
-       }
-       else {
-         Nbpts = Handle(IntPatch_GLine)::DownCast (slinj)->NbVertex();
-       }
-       for (k=1; k<=Nbpts;k++) {
-         if (typ == IntPatch_Analytic) {
-           ptvtx = Handle(IntPatch_ALine)::DownCast (slinj)->Vertex(k);
-         }
-         else if (typ == IntPatch_Restriction) {
-           ptvtx = Handle(IntPatch_RLine)::DownCast (slinj)->Vertex(k);
-         }
-         else {
-           ptvtx = Handle(IntPatch_GLine)::DownCast (slinj)->Vertex(k);
-         }
-         
-         if (EdgeDegenere==Standard_False && dofirst) {
-           if (ptvtx.Value().Distance(PStartf.Value()) <=TolArc) {
-             ptvtx.SetMultiple(Standard_True);
-              ptvtx.SetTolerance(TolArc);
-             if (typ == IntPatch_Analytic) {
-               Handle(IntPatch_ALine)::DownCast (slinj)->Replace(k,ptvtx);
-             }
-             else if (typ == IntPatch_Restriction) {
-               Handle(IntPatch_RLine)::DownCast (slinj)->Replace(k,ptvtx);
-             }
-             else {
-               Handle(IntPatch_GLine)::DownCast (slinj)->Replace(k,ptvtx);
-             }
-             newptvtx = ptvtx;
-             newptvtx.SetParameter(paramf);
-             //Recalcul des  transitions si point sur restriction
-
-             arcRef->D1(paramf,p2d,d2d);
-             if (OnFirst) {
-               Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
-             }
-             else {
-               Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
-             }
-             tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
-             if (ptvtx.IsOnDomS1()) {
-               const Handle(Adaptor2d_Curve2d)& thearc = ptvtx.ArcOnS1();
-               thearc->D1(ptvtx.ParameterOnArc1(),p2d,d2d);
-               Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
-               tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v); 
-               norm1 = d1u.Crossed(d1v); 
-               if(norm1.SquareMagnitude()<1e-16) { 
-                 TRest.SetValue(Standard_True,IntSurf_Undecided);
-                 TArc.SetValue(Standard_True,IntSurf_Undecided);           
-               }
-               else {          
-                 IntSurf::MakeTransition(tgline,tgarc,norm1,TRest,TArc);
-               }
-               newptvtx.SetArc(Standard_True,thearc,ptvtx.ParameterOnArc1(),
-                               TRest,TArc);
-             }
-             if (ptvtx.IsOnDomS2()) {
-               const Handle(Adaptor2d_Curve2d)& thearc = ptvtx.ArcOnS2();
-               thearc->D1(ptvtx.ParameterOnArc2(),p2d,d2d);
-               Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
-               tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v); 
-               norm2 = d1u.Crossed(d1v);
-               if(norm2.SquareMagnitude()<1e-16) { 
-                 TRest.SetValue(Standard_True,IntSurf_Undecided);
-                 TArc.SetValue(Standard_True,IntSurf_Undecided);           
-               }
-               else {                            
-                 IntSurf::MakeTransition(tgline,tgarc,norm2,TRest,TArc);
-               }
-               newptvtx.SetArc(Standard_False,thearc,ptvtx.ParameterOnArc2(),
-                               TRest,TArc);
-             }
-
-             rline->AddVertex(newptvtx);
-             if (!procf){
-               procf=Standard_True;
-               rline->SetFirstPoint(rline->NbVertex());
-             }
-           }
-         }
-         if (EdgeDegenere==Standard_False && dolast) {
-           if (ptvtx.Value().Distance(PStartl.Value()) <=TolArc) {
-             ptvtx.SetMultiple(Standard_True);
-              ptvtx.SetTolerance(TolArc);
-             if (typ == IntPatch_Analytic) {
-               Handle(IntPatch_ALine)::DownCast (slinj)->Replace(k,ptvtx);
-             }
-             else if (typ == IntPatch_Restriction) {
-               Handle(IntPatch_RLine)::DownCast (slinj)->Replace(k,ptvtx);
-             }
-             else {
-               Handle(IntPatch_GLine)::DownCast (slinj)->Replace(k,ptvtx);
-             }
-
-             newptvtx = ptvtx;
-             newptvtx.SetParameter(paraml);
-             //Recalcul des  transitions si point sur restriction
-
-             arcRef->D1(paraml,p2d,d2d);
-             if (OnFirst) {
-               Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
-             }
-             else {
-               Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
-             }
-             tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
-             if (ptvtx.IsOnDomS1()) {
-               const Handle(Adaptor2d_Curve2d)& thearc = ptvtx.ArcOnS1();
-               thearc->D1(ptvtx.ParameterOnArc1(),p2d,d2d);
-               Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
-               tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v); 
-               norm1 = d1u.Crossed(d1v);
-               if(norm1.SquareMagnitude()<1e-16) { 
-                 TRest.SetValue(Standard_True,IntSurf_Undecided);
-                 TArc.SetValue(Standard_True,IntSurf_Undecided);           
-               }
-               else {          
-                 IntSurf::MakeTransition(tgline,tgarc,norm1,TRest,TArc);
-               }
-               newptvtx.SetArc(Standard_True,thearc,ptvtx.ParameterOnArc1(),
-                               TRest,TArc);
-             }
-             if (ptvtx.IsOnDomS2()) {
-               const Handle(Adaptor2d_Curve2d)& thearc = ptvtx.ArcOnS2();
-               thearc->D1(ptvtx.ParameterOnArc2(),p2d,d2d);
-               Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
-               tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v); 
-               norm2 = d1u.Crossed(d1v);
-               if(norm2.SquareMagnitude()<1e-16) { 
-                 TRest.SetValue(Standard_True,IntSurf_Undecided);
-                 TArc.SetValue(Standard_True,IntSurf_Undecided);           
-               }
-               else {                        
-                 IntSurf::MakeTransition(tgline,tgarc,norm2,TRest,TArc);
-               }
-               newptvtx.SetArc(Standard_False,thearc,ptvtx.ParameterOnArc2(),
-                               TRest,TArc);
-             }
-
-             rline->AddVertex(newptvtx);
-             if (!procl){
-               procl=Standard_True;
-               rline->SetLastPoint(rline->NbVertex());
-             }
-           }
-         }
-       }
-// Si on a traite le pt debut et/ou fin, on ne doit pas recommencer si
-// il (ils) correspond(ent) a un point multiple.
-
-       if (procf) {
-         dofirst = Standard_False;
-       }
-       if (procl) {
-         dolast  = Standard_False;
-       }
-      }
-    }
-// Si on n a pas trouve le point debut et./ou fin sur une des lignes
-// d intersection, il faut quand-meme le placer sur la restriction solution
-
-    if (dofirst) {
-      ptvtx.SetValue(PStartf.Value(),PStartf.Tolerance(),Standard_False);
-      Quad1.Parameters(PStartf.Value(),U1,V1);
-      Quad2.Parameters(PStartf.Value(),U2,V2);
-      ptvtx.SetParameters(U1,V1,U2,V2);
-      ptvtx.SetParameter(paramf);
-      if (! PStartf.IsNew()) {
-       IntSurf_Transition Transline;
-       IntSurf_Transition Transarc;
-       ptvtx.SetVertex(OnFirst,PStartf.Vertex());
-       ptvtx.SetArc(OnFirst,PStartf.Arc(),PStartf.Parameter(),
-                    Transline,Transarc);
-      }
-
-      rline->AddVertex(ptvtx);
-      rline->SetFirstPoint(rline->NbVertex());
-    }
-    if (dolast) {
-      ptvtx.SetValue(PStartl.Value(),PStartl.Tolerance(),Standard_False);
-      Quad1.Parameters(PStartl.Value(),U1,V1);
-      Quad2.Parameters(PStartl.Value(),U2,V2);
-      ptvtx.SetParameters(U1,V1,U2,V2);
-      ptvtx.SetParameter(paraml);
-      if (! PStartl.IsNew()) {
-       IntSurf_Transition Transline;
-       IntSurf_Transition Transarc;
-
-       ptvtx.SetVertex(OnFirst,PStartl.Vertex());
-       ptvtx.SetArc(OnFirst,PStartl.Arc(),PStartl.Parameter(),
-                    Transline,Transarc);
-      }
-
-      rline->AddVertex(ptvtx);
-      rline->SetLastPoint(rline->NbVertex());
-    }
-    slin.Append(rline);
-  }
-}
-
-inline const gp_Pnt& PointValue(const Handle(IntPatch_RLine) theRLine,
-                                const Standard_Integer theIndex)
-{
-  return theRLine->Point(theIndex).Value();
-}
-
-inline const gp_Pnt& VertexValue( const Handle(IntPatch_RLine) theRLine,
-                                  const Standard_Integer theIndex)
-{
-  return theRLine->Vertex(theIndex).Value();
-}
-
-static Standard_Real SquareDistance(const Handle(IntPatch_GLine)& theGLine,
-                                    const gp_Pnt& theP,
-                                    Extrema_ExtPC& theExtr)
-{
-  Standard_Real aSQDist = RealLast();
-  switch(theGLine->ArcType())
-  {
-  case IntPatch_Lin:
-    aSQDist = theGLine->Line().SquareDistance(theP);
-    break;
-  case IntPatch_Circle:
-    aSQDist = theGLine->Circle().SquareDistance(theP);
-    break;
-  default:
-    theExtr.Perform(theP);
-    if(!theExtr.IsDone() || !theExtr.NbExt())
-    {
-      //Lines are not overlapped
-      return aSQDist;
-    }
-
-    aSQDist = theExtr.SquareDistance(1);
-    const Standard_Integer aNbExtr = theExtr.NbExt();
-    for ( Standard_Integer i = 2; i <= aNbExtr; i++)
-    {
-      const Standard_Real aSQD = theExtr.SquareDistance(i);
-      if (aSQD < aSQDist)
-      {
-        aSQDist = aSQD;
-      }
-    }
-  }
-
-  return aSQDist;
-}
-
-static Standard_Boolean IsRLineGood(const IntSurf_Quadric& Quad1,
-                                    const IntSurf_Quadric& Quad2,
-                                    const Handle(IntPatch_GLine) theGLine,
-                                    const Handle(IntPatch_RLine) theRLine,
-                                    const Standard_Real theTol)
-{
-  const Standard_Real aSQTol = theTol*theTol;
-  const IntPatch_IType aGType = theGLine->ArcType();
-  Standard_Integer aNbPntsM1 = 0;
-  
-  const gp_Pnt& (*Value) (const Handle(IntPatch_RLine), const Standard_Integer);
-
-  if(theRLine->HasPolygon())
-  {
-    aNbPntsM1 = theRLine->NbPnts()-1;
-    Value = PointValue;
-  }
-  else
-  {
-    aNbPntsM1 = theRLine->NbVertex()-1;
-    Value = VertexValue;
-  }
-  
-  if(aNbPntsM1 < 1)
-    return Standard_False;
-
-  Extrema_ExtPC anExtr;
-  GeomAdaptor_Curve anAC;
-  Handle(Geom_Curve) aCurv;
-
-  if(aGType == IntPatch_Ellipse)
-    aCurv = new Geom_Ellipse(theGLine->Ellipse());
-  else if(aGType == IntPatch_Parabola)
-    aCurv = new Geom_Parabola(theGLine->Parabola());
-  else if(aGType == IntPatch_Hyperbola)
-    aCurv = new Geom_Hyperbola(theGLine->Hyperbola());
-  
-  if(!aCurv.IsNull())
-  {
-    const Standard_Real anUinf = aCurv->FirstParameter(),
-                        anUsup = aCurv->LastParameter();
-    anAC.Load(aCurv, anUinf, anUsup);
-    anExtr.Initialize(anAC, anUinf, anUsup);
-  }
-
-  if(aNbPntsM1 == 1)
-  {
-    gp_Pnt aP1(Value(theRLine, 1)), aP2(Value(theRLine, 2));
-
-    if(aP1.SquareDistance(aP2) < aSQTol)
-    {
-      //RLine is degenerated
-      return Standard_False;
-    }
-
-    gp_Pnt aPMid;
-    if(theRLine->IsArcOnS1())
-    {
-      const Handle(Adaptor2d_Curve2d)& anAC2d = theRLine->ArcOnS1();
-      const Standard_Real aParF = anAC2d->FirstParameter(),
-                          aParL = anAC2d->LastParameter();
-      gp_Pnt2d aP2d(anAC2d->Value(0.5*(aParF+aParL)));
-      aPMid = Quad1.Value(aP2d.X(), aP2d.Y());
-    }
-    else
-    {
-      const Handle(Adaptor2d_Curve2d)& anAC2d = theRLine->ArcOnS2();
-      const Standard_Real aParF = anAC2d->FirstParameter(),
-                          aParL = anAC2d->LastParameter();
-      gp_Pnt2d aP2d(anAC2d->Value(0.5*(aParF+aParL)));
-      aPMid = Quad2.Value(aP2d.X(), aP2d.Y());
-    }
-
-    const Standard_Real aSQDist = SquareDistance(theGLine, aPMid, anExtr);
-    return (aSQDist > aSQTol);
-  }
-
-  for(Standard_Integer i = 2; i <= aNbPntsM1; i++)
-  {
-    const gp_Pnt aP(Value(theRLine, i));
-    const Standard_Real aSQDist = SquareDistance(theGLine, aP, anExtr);
-
-    if(aSQDist > aSQTol)
-      return Standard_True;
-  }
-
-  return Standard_False;
-}
-                                      
-
-void ProcessRLine (IntPatch_SequenceOfLine& slin,
-//                const Handle(Adaptor3d_Surface)& Surf1,
-//                const Handle(Adaptor3d_Surface)& Surf2,
-                  const IntSurf_Quadric& Quad1,
-                  const IntSurf_Quadric& Quad2,
-                  const Standard_Real _TolArc,
-                   const Standard_Boolean theIsReqToKeepRLine) {
-
-// On cherche a placer sur les restrictions solutions les points "multiples"
-// des autres lignes d intersection
-// Pas forcemment le plus efficace : on rique de projeter plusieurs fois
-// le meme point sur la meme restriction...
-
-  Standard_Real TolArc=100.0*_TolArc;
-  if(TolArc>0.1) TolArc=0.1;
-  
-  Standard_Integer i,j,k;
-  Standard_Integer Nblin,Nbvtx, Nbpt;
-
-  Standard_Boolean OnFirst = Standard_False,project = Standard_False,keeppoint = Standard_False;
-
-  Handle(Adaptor2d_Curve2d) arcref;
-  Standard_Real paramproj,paramf,paraml;
-
-  TColgp_SequenceOfPnt seq_Pnt3d;
-  TColStd_SequenceOfReal seq_Real;
-
-  gp_Pnt ptproj,toproj,valpt;
-
-  gp_Pnt2d p2d;
-  gp_Vec2d d2d;
-  gp_Vec d1u,d1v,tgrest,tgarc,norm;
-  IntSurf_Transition TRest,TArc;
-#ifndef OCCT_DEBUG
-  Standard_Real U =0.,V =0.;
-#else
-  Standard_Real U,V;
-#endif
-  IntPatch_Point Ptvtx,newptvtx;
-
-  IntPatch_IType typ1,typ2;
-
-
-  Nblin = slin.Length();
-  for (i=1; i<=Nblin; i++) {
-    const Handle(IntPatch_Line)& slini = slin(i);
-    typ1 = slini->ArcType();
-
-    Standard_Boolean HasToDeleteRLine = Standard_False;
-    if (typ1 == IntPatch_Restriction) {
-      seq_Pnt3d.Clear();
-      seq_Real.Clear();
-      
-      for (j=1; j<=Nblin; j++) {
-       const  Handle(IntPatch_Line)& slinj = slin(j);
-       Nbpt = seq_Pnt3d.Length();      // important que ce soit ici
-       typ2 = slinj->ArcType();
-       if (typ2 != IntPatch_Restriction) {
-         //-- arcref = Handle(IntPatch_RLine)::DownCast (slini)->Arc();
-         //-- OnFirst = Handle(IntPatch_RLine)::DownCast (slini)->IsOnFirstSurface();
-
-         //-- DES CHOSES A FAIRE ICI 
-         if(Handle(IntPatch_RLine)::DownCast (slini)->IsArcOnS1()) { 
-           OnFirst=Standard_True;
-           arcref= Handle(IntPatch_RLine)::DownCast (slini)->ArcOnS1();
-         }
-         else if(Handle(IntPatch_RLine)::DownCast (slini)->IsArcOnS2()) { 
-           arcref= Handle(IntPatch_RLine)::DownCast (slini)->ArcOnS2();
-           OnFirst=Standard_False;
-         }
-         if (Handle(IntPatch_RLine)::DownCast (slini)->HasFirstPoint()) {
-           paramf = Handle(IntPatch_RLine)::DownCast (slini)->FirstPoint().ParameterOnLine();
-         }
-         else {
-           // cout << "Pas de param debut sur rst solution" << endl;
-           paramf = RealFirst();
-         }
-         if (Handle(IntPatch_RLine)::DownCast (slini)->HasLastPoint()) {
-           paraml = Handle(IntPatch_RLine)::DownCast (slini)->LastPoint().ParameterOnLine();
-         }
-         else {
-           // cout << "Pas de param debut sur rst solution" << endl;
-           paraml = RealLast();
-         }
-
-         if (typ2 == IntPatch_Analytic) {
-           Nbvtx = Handle(IntPatch_ALine)::DownCast (slinj)->NbVertex();
-         }
-         else {
-           Nbvtx = Handle(IntPatch_GLine)::DownCast (slinj)->NbVertex();
-         }
-
-         
-         Standard_Boolean EdgeDegenere=Standard_True;
-         for(Standard_Integer edg=0;EdgeDegenere && edg<=10;edg++) {
-           arcref->D1(paramf+(paraml-paramf)*edg*0.1,p2d,d2d);
-           if (OnFirst) {
-             Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
-           }
-           else {
-             Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
-           }
-           if(d1u.Magnitude()>1e-7) {
-             EdgeDegenere=Standard_False;
-           }
-         } 
-
-         for (k=1; EdgeDegenere==Standard_False && k<=Nbvtx; k++) {
-           if (typ2 == IntPatch_Analytic) {
-             Ptvtx = Handle(IntPatch_ALine)::DownCast (slinj)->Vertex(k);
-           }
-           else {
-             Ptvtx = Handle(IntPatch_GLine)::DownCast (slinj)->Vertex(k);
-           }
-           if ((OnFirst && !Ptvtx.IsOnDomS1()) ||
-               (!OnFirst && !Ptvtx.IsOnDomS2())) {
-             // Si OnFirst && OnDomS1, c est qu on est a une extremite
-             // ca doit etre traite par Process Segment...
-             project = Standard_True;
-             keeppoint = Standard_False;
-             toproj = Ptvtx.Value();
-             
-             Standard_Integer jj;
-             for (jj = 1; jj <= Nbpt; jj++) {
-              //for (Standard_Integer jj = 1; jj <= Nbpt; jj++) {
-               if (toproj.Distance(seq_Pnt3d(jj)) < _TolArc) {
-                 project = Standard_False; 
-                 break;
-               }
-             }
-             if (project) { //-- il faut projeter pour trouver le point sur la rline. 
-               if (OnFirst) {   
-                 Ptvtx.ParametersOnS1(U,V); 
-               }
-               else {
-                 Ptvtx.ParametersOnS2(U,V);
-               }
-
-               project = IntPatch_HInterTool::Project(arcref,gp_Pnt2d(U,V),
-                                               paramproj,p2d);
-               
-               if (project) {
-                 if (OnFirst) {
-                   ptproj = Quad1.Value(p2d.X(),p2d.Y());
-                 }
-                 else {
-                   ptproj = Quad2.Value(p2d.X(),p2d.Y());
-                 }
-                 if ((toproj.Distance(ptproj) <=100*TolArc) &&
-                     (paramproj >= paramf) && (paramproj <= paraml)){
-                   newptvtx = Ptvtx;
-                   newptvtx.SetParameter(paramproj);
-                   keeppoint = Standard_True;
-                   seq_Pnt3d.Append(toproj);
-                   seq_Real.Append(paramproj);
-                   
-                   //-- verifier que si la restriction arcref est trouvee, elle porte ce vertex
-                   for (int ri=1; ri<=Nblin; ri++) {
-                     const Handle(IntPatch_Line)& slinri = slin(ri);
-                     if (slinri->ArcType() == IntPatch_Restriction) {
-                       if(OnFirst && Handle(IntPatch_RLine)::DownCast (slinri)->IsArcOnS1()) { 
-                         if(arcref == Handle(IntPatch_RLine)::DownCast (slinri)->ArcOnS1()) { 
-                           Handle(IntPatch_RLine)::DownCast (slinri)->AddVertex(newptvtx);
-                           //printf("\n ImpImpIntersection_0.gxx CAS1 \n");
-                         }
-                       }
-                       else if(OnFirst==Standard_False && Handle(IntPatch_RLine)::DownCast (slinri)->IsArcOnS2()) { 
-                         if(arcref == Handle(IntPatch_RLine)::DownCast (slinri)->ArcOnS2()) { 
-                           Handle(IntPatch_RLine)::DownCast (slinri)->AddVertex(newptvtx);
-                           //printf("\n ImpImpIntersection_0.gxx CAS2 \n");
-                         }
-                       }
-                     }
-                   }
-                   // -- --------------------------------------------------
-                 }
-               }
-             }
-             else {
-               keeppoint = Standard_True;
-               newptvtx = Ptvtx;
-               newptvtx.SetParameter(seq_Real(jj));
-             }
-             if (keeppoint) {
-               Ptvtx.SetMultiple(Standard_True);
-                Ptvtx.SetTolerance(_TolArc);
-               newptvtx.SetMultiple(Standard_True);
-               
-               if (typ2 == IntPatch_Analytic) {
-                 Handle(IntPatch_ALine)::DownCast (slinj)->Replace(k,Ptvtx);
-               }
-               else {
-                 Handle(IntPatch_GLine)::DownCast (slinj)->Replace(k,Ptvtx);
-               }
-
-               if (Ptvtx.IsOnDomS1() || Ptvtx.IsOnDomS2()) {
-               
-                 arcref->D1(newptvtx.ParameterOnLine(),p2d,d2d);
-               
-                 if (OnFirst) { // donc OnDomS2
-                   Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
-                   tgrest.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
-
-                   const Handle(Adaptor2d_Curve2d)& thearc = Ptvtx.ArcOnS2();
-                   thearc->D1(Ptvtx.ParameterOnArc2(),p2d,d2d);
-                   Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
-                   tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v); 
-                   norm = d1u.Crossed(d1v); //Quad2.Normale(valpt);
-                   if(norm.SquareMagnitude()<1e-16) { 
-                     TRest.SetValue(Standard_True,IntSurf_Undecided);
-                     TArc.SetValue(Standard_True,IntSurf_Undecided);       
-                   }
-                   else {                                    
-                     IntSurf::MakeTransition(tgrest,tgarc,norm,TRest,TArc);
-                   }
-                   newptvtx.SetArc(Standard_False,thearc,
-                                   Ptvtx.ParameterOnArc2(),TRest,TArc);
-
-                 }
-                 else { // donc OnDomS1
-                   Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
-                   tgrest.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
-
-                   const Handle(Adaptor2d_Curve2d)& thearc = Ptvtx.ArcOnS1();
-                   thearc->D1(Ptvtx.ParameterOnArc1(),p2d,d2d);
-                   Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
-                   tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v); 
-                   norm = d1u.Crossed(d1v); //Quad1.Normale(valpt);
-                   if(norm.SquareMagnitude()<1e-16) { 
-                     TRest.SetValue(Standard_True,IntSurf_Undecided);
-                     TArc.SetValue(Standard_True,IntSurf_Undecided);       
-                   }
-                   else {              
-                     IntSurf::MakeTransition(tgrest,tgarc,norm,TRest,TArc);
-                   }
-                   newptvtx.SetArc(Standard_True,thearc,
-                                   Ptvtx.ParameterOnArc1(),TRest,TArc);
-                 }
-               } //-- if (Ptvtx.IsOnDomS1() || Ptvtx.IsOnDomS2())
-
-               Handle(IntPatch_RLine)::DownCast (slini)->AddVertex(newptvtx);
-
-             } //-- if (keeppoint)
-           } //-- if ((OnFirst && !Ptvtx.IsOnDomS1())||(!OnFirst && !Ptvtx.IsOnDomS2()))
-         } //-- boucle sur les vertex
-
-          if(!theIsReqToKeepRLine)
-          {
-            Handle(IntPatch_GLine) aGL = Handle(IntPatch_GLine)::DownCast(slinj);
-
-            if(!aGL.IsNull())
-            {
-              HasToDeleteRLine = !IsRLineGood(Quad1, Quad2, aGL, 
-                                        Handle(IntPatch_RLine)::DownCast(slini), TolArc);
-            }
-
-            if(HasToDeleteRLine)
-            {
-              break;
-            }
-          }
-       } //-- if (typ2 != IntPatch_Restriction)
-      } //-- for (j=1; j<=Nblin; j++) 
-    } //-- if (typ1 == IntPatch_Restriction)
-
-    if(HasToDeleteRLine)
-    {
-      slin.Remove(i);
-      i--;
-      Nblin = slin.Length();
-      continue;
-    }
-  } //-- for (i=1; i<=Nblin; i++)
-}
diff --git a/src/IntPatch/IntPatch_ImpImpIntersection_1.gxx b/src/IntPatch/IntPatch_ImpImpIntersection_1.gxx
deleted file mode 100644 (file)
index 9ab3fd0..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-// Created on: 1992-05-07
-// Created by: Jacques GOUSSARD
-// Copyright (c) 1992-1999 Matra Datavision
-// Copyright (c) 1999-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 <Bnd_Box2d.hxx>
-
-static Standard_Boolean IntPP (const IntSurf_Quadric&,
-                              const IntSurf_Quadric&,
-                              const Standard_Real,
-                              const Standard_Real,
-                              Standard_Boolean&,
-                              IntPatch_SequenceOfLine&);
-
-static Standard_Boolean IntPCy (const IntSurf_Quadric&,
-                               const IntSurf_Quadric&,
-                               const Standard_Real,
-                               const Standard_Real,
-                               const Standard_Boolean,
-                               Standard_Boolean&,
-                               IntPatch_SequenceOfLine&,
-                                const Standard_Real H=0.);
-
-
-static Standard_Boolean IntPSp (const IntSurf_Quadric&,
-                               const IntSurf_Quadric&,
-                               //modified by NIZNHY-PKV Tue Sep 20 08:59:56 2011t
-                               const Standard_Real,
-                               //modified by NIZNHY-PKV Tue Sep 20 08:59:52 2011t
-                               const Standard_Real,
-                               const Standard_Boolean,
-                               Standard_Boolean&,
-                               IntPatch_SequenceOfLine&,
-                               IntPatch_SequenceOfPoint&);
-
-
-static Standard_Boolean IntPCo (const IntSurf_Quadric&,
-                               const IntSurf_Quadric&,
-                               const Standard_Real,
-                               const Standard_Real,
-                               const Standard_Boolean,
-                               Standard_Boolean&,
-                               Standard_Boolean&,
-                               IntPatch_SequenceOfLine&,
-                               IntPatch_SequenceOfPoint&);
-
-
-static void ProcessBounds(const Handle(IntPatch_ALine)&,
-                         const IntPatch_SequenceOfLine&,
-                         const IntSurf_Quadric&,
-                         const IntSurf_Quadric&,
-                         Standard_Boolean&,
-                         const gp_Pnt&,
-                         const Standard_Real,
-                         Standard_Boolean&,
-                         const gp_Pnt&,
-                         const Standard_Real,
-                         Standard_Boolean&,
-                         const Standard_Real);
-
-
-static 
-  IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
-                                                 const IntSurf_Quadric& theQuad2,
-                                                 const Standard_Real theTol3D,
-                                                 const Standard_Real theTol2D,
-                                                 const Bnd_Box2d& theUVSurf1,
-                                                 const Bnd_Box2d& theUVSurf2,
-                                                 Standard_Boolean& isTheEmpty,
-                                                 Standard_Boolean& isTheSameSurface,
-                                                 Standard_Boolean& isTheMultiplePoint,
-                                                 IntPatch_SequenceOfLine& theSlin,
-                                                 IntPatch_SequenceOfPoint& theSPnt);
-
-static Standard_Boolean IntCySp(const IntSurf_Quadric&,
-                               const IntSurf_Quadric&,
-                               const Standard_Real,
-                               const Standard_Boolean,
-                               Standard_Boolean&,
-                               Standard_Boolean&,
-                               IntPatch_SequenceOfLine&,
-                               IntPatch_SequenceOfPoint&);
-
-static Standard_Boolean IntCyCo(const IntSurf_Quadric&,
-                               const IntSurf_Quadric&,
-                               const Standard_Real,
-                               const Standard_Boolean,
-                               Standard_Boolean&,
-                               Standard_Boolean&,
-                               IntPatch_SequenceOfLine&,
-                               IntPatch_SequenceOfPoint&);
-
-static Standard_Boolean IntSpSp(const IntSurf_Quadric&,
-                               const IntSurf_Quadric&,
-                               const Standard_Real,
-                               Standard_Boolean&,
-                               Standard_Boolean&,
-                               IntPatch_SequenceOfLine&,
-                               IntPatch_SequenceOfPoint&);
-
-static Standard_Boolean IntCoSp(const IntSurf_Quadric&,
-                               const IntSurf_Quadric&,
-                               const Standard_Real,
-                               const Standard_Boolean,
-                               Standard_Boolean&,
-                               Standard_Boolean&,
-                               IntPatch_SequenceOfLine&,
-                               IntPatch_SequenceOfPoint&);
-
-static Standard_Boolean IntCoCo(const IntSurf_Quadric&,
-                               const IntSurf_Quadric&,
-                               const Standard_Real,
-                               Standard_Boolean&,
-                               Standard_Boolean&,
-                               Standard_Boolean&,
-                               IntPatch_SequenceOfLine&,
-                               IntPatch_SequenceOfPoint&);
-
-//torus
-static Standard_Boolean IntPTo(const IntSurf_Quadric&,
-                               const IntSurf_Quadric&,
-                               const Standard_Real,
-                               const Standard_Boolean,
-                               Standard_Boolean&,
-                               IntPatch_SequenceOfLine&);
-
-static Standard_Boolean IntCyTo(const IntSurf_Quadric&,
-                                const IntSurf_Quadric&,
-                                const Standard_Real,
-                                const Standard_Boolean,
-                                Standard_Boolean&,
-                                IntPatch_SequenceOfLine&);
-
-static Standard_Boolean IntCoTo(const IntSurf_Quadric&,
-                                const IntSurf_Quadric&,
-                                const Standard_Real,
-                                const Standard_Boolean,
-                                Standard_Boolean&,
-                                IntPatch_SequenceOfLine&);
-
-static Standard_Boolean IntSpTo(const IntSurf_Quadric&,
-                                const IntSurf_Quadric&,
-                                const Standard_Real,
-                                const Standard_Boolean,
-                                Standard_Boolean&,
-                                IntPatch_SequenceOfLine&);
-
-static Standard_Boolean IntToTo(const IntSurf_Quadric&,
-                                const IntSurf_Quadric&,
-                                const Standard_Real,
-                                Standard_Boolean&,
-                                Standard_Boolean&,
-                                IntPatch_SequenceOfLine&);
diff --git a/src/IntPatch/IntPatch_ImpImpIntersection_2.gxx b/src/IntPatch/IntPatch_ImpImpIntersection_2.gxx
deleted file mode 100644 (file)
index d2f2589..0000000
+++ /dev/null
@@ -1,582 +0,0 @@
-// Created on: 1992-05-07
-// Created by: Jacques GOUSSARD
-// Copyright (c) 1992-1999 Matra Datavision
-// Copyright (c) 1999-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 <IntPatch_WLine.hxx>
-
-static 
-  Standard_Integer SetQuad(const Handle(Adaptor3d_Surface)& theS,
-                           GeomAbs_SurfaceType& theTS,
-                           IntSurf_Quadric& theQuad);
-
-//=======================================================================
-//function : IntPatch_ImpImpIntersection
-//purpose  : 
-//=======================================================================
-IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection ():
-myDone(IntStatus_Fail),
-empt(Standard_True),
-tgte(Standard_False),
-oppo(Standard_False)
-{
-}
-//=======================================================================
-//function : IntPatch_ImpImpIntersection
-//purpose  : 
-//=======================================================================
-IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection
-       (const Handle(Adaptor3d_Surface)&  S1,
-        const Handle(Adaptor3d_TopolTool)& D1,
-        const Handle(Adaptor3d_Surface)&  S2,
-        const Handle(Adaptor3d_TopolTool)& D2,
-        const Standard_Real TolArc,
-        const Standard_Real TolTang,
-        const Standard_Boolean theIsReqToKeepRLine)
-{
-  Perform(S1,D1,S2,D2,TolArc,TolTang, theIsReqToKeepRLine);
-}
-//=======================================================================
-//function : Perform
-//purpose  : 
-//=======================================================================
-void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_Surface)&  S1,
-                                          const Handle(Adaptor3d_TopolTool)& D1,
-                                          const Handle(Adaptor3d_Surface)&  S2,
-                                          const Handle(Adaptor3d_TopolTool)& D2,
-                                          const Standard_Real TolArc,
-                                          const Standard_Real TolTang,
-                                          const Standard_Boolean theIsReqToKeepRLine)
-{
-  myDone = IntStatus_Fail;
-  spnt.Clear();
-  slin.Clear();
-
-  Standard_Boolean isPostProcessingRequired = Standard_True;
-
-  empt = Standard_True;
-  tgte = Standard_False;
-  oppo = Standard_False;
-
-  Standard_Boolean all1 = Standard_False;
-  Standard_Boolean all2 = Standard_False;
-  Standard_Boolean SameSurf = Standard_False;
-  Standard_Boolean multpoint = Standard_False;
-
-  Standard_Boolean nosolonS1 = Standard_False;
-  // indique s il y a des points sur restriction du carreau 1
-  Standard_Boolean nosolonS2 = Standard_False;
-  // indique s il y a des points sur restriction du carreau 2
-  Standard_Integer i, nbpt, nbseg;
-  IntPatch_SequenceOfSegmentOfTheSOnBounds edg1,edg2;
-  IntPatch_SequenceOfPathPointOfTheSOnBounds pnt1,pnt2;
-  //
-  // On commence par intersecter les supports des surfaces
-  IntSurf_Quadric quad1, quad2;
-  IntPatch_ArcFunction AFunc;
-  const Standard_Real Tolang = 1.e-8;
-  GeomAbs_SurfaceType typs1, typs2;
-  Standard_Boolean bEmpty = Standard_False;
-  //
-  const Standard_Integer iT1 = SetQuad(S1, typs1, quad1);
-  const Standard_Integer iT2 = SetQuad(S2, typs2, quad2);
-  //
-  if (!iT1 || !iT2) {
-    throw Standard_ConstructionError();
-    return;
-  }
-  //
-  const Standard_Boolean bReverse = iT1 > iT2;
-  const Standard_Integer iTT = iT1*10 + iT2;
-  //
-  switch (iTT) {
-    case 11: { // Plane/Plane
-      if (!IntPP(quad1, quad2, Tolang, TolTang, SameSurf, slin)) {
-        return;
-      }
-      break;
-    }
-    //
-    case 12:
-    case 21: { // Plane/Cylinder
-      Standard_Real VMin, VMax, H;
-      //
-      const Handle(Adaptor3d_Surface)& aSCyl = bReverse ? S1 : S2;
-      VMin = aSCyl->FirstVParameter();
-      VMax = aSCyl->LastVParameter();
-      H = (Precision::IsNegativeInfinite(VMin) || 
-           Precision::IsPositiveInfinite(VMax)) ? 0 : (VMax - VMin);
-      //
-      if (!IntPCy(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, H)) {
-        return;
-      }
-      bEmpty = empt;
-      break;
-    }
-    //
-    case 13:
-    case 31: { // Plane/Cone
-      if (!IntPCo(quad1, quad2, Tolang, TolTang, bReverse, empt, multpoint, slin, spnt)) {
-        return;
-      }
-      bEmpty = empt;
-      break;
-    }
-    //
-    case 14:
-    case 41: { // Plane/Sphere
-      if (!IntPSp(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, spnt)) {
-        return;
-      }
-      bEmpty = empt;
-      break;
-    }
-    //
-    case 15:
-    case 51: { // Plane/Torus
-      if (!IntPTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
-        return;
-      }
-      bEmpty = empt;
-      break;
-    }
-    //
-    case 22:
-      { // Cylinder/Cylinder
-        Bnd_Box2d aBox1, aBox2;
-
-        const Standard_Real aU1f = S1->FirstUParameter();
-        Standard_Real aU1l = S1->LastUParameter();
-        const Standard_Real aU2f = S2->FirstUParameter();
-        Standard_Real aU2l = S2->LastUParameter();
-
-        const Standard_Real anUperiod = 2.0*M_PI;
-
-        if(aU1l - aU1f > anUperiod)
-          aU1l = aU1f + anUperiod;
-
-        if(aU2l - aU2f > anUperiod)
-          aU2l = aU2f + anUperiod;
-
-        aBox1.Add(gp_Pnt2d(aU1f, S1->FirstVParameter()));
-        aBox1.Add(gp_Pnt2d(aU1l, S1->LastVParameter()));
-        aBox2.Add(gp_Pnt2d(aU2f, S2->FirstVParameter()));
-        aBox2.Add(gp_Pnt2d(aU2l, S2->LastVParameter()));
-
-        // Resolution is too big if the cylinder radius is
-        // too small. Therefore, we shall bind its value above. 
-        // Here, we use simple constant.
-        const Standard_Real a2DTol = Min(1.0e-4, Min( S1->UResolution(TolTang),
-                                            S2->UResolution(TolTang)));
-
-        myDone = IntCyCy(quad1, quad2, TolTang, a2DTol, aBox1, aBox2,
-                                    empt, SameSurf, multpoint, slin, spnt);
-
-        if (myDone == IntPatch_ImpImpIntersection::IntStatus_Fail)
-        {
-          return;
-        }
-
-        bEmpty = empt;
-        if(!slin.IsEmpty())
-        {
-          const Handle(IntPatch_WLine)& aWLine = 
-                                    Handle(IntPatch_WLine)::DownCast(slin.Value(1));
-
-          if(!aWLine.IsNull())
-          {//No geometric solution
-            isPostProcessingRequired = Standard_False;
-          }
-        }
-
-        break;
-      }
-    //
-    case 23:
-    case 32: { // Cylinder/Cone
-      if (!IntCyCo(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
-        return;
-      }
-      bEmpty = empt;
-      break;
-    }
-    //
-    case 24:
-    case 42: { // Cylinder/Sphere
-      if (!IntCySp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
-        return;
-      }
-      bEmpty = empt;
-      break;
-    }
-    //
-    case 25:
-    case 52: { // Cylinder/Torus
-      if (!IntCyTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
-        return;
-      }
-      bEmpty = empt;
-      break;
-    }
-    //
-    case 33: { // Cone/Cone
-      if (!IntCoCo(quad1, quad2, TolTang, empt, SameSurf, multpoint, slin, spnt)) {
-        return;
-      }
-      bEmpty = empt;
-      break;
-    }
-    //
-    case 34:
-    case 43: { // Cone/Sphere
-      if (!IntCoSp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
-        return;
-      }
-      bEmpty = empt;
-      break;
-    }
-    //
-    case 35:
-    case 53: { // Cone/Torus
-      if (!IntCoTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
-        return;
-      }
-      break;
-    }
-    //
-    case 44: { // Sphere/Sphere
-      if (!IntSpSp(quad1, quad2, TolTang, empt, SameSurf, slin, spnt)) {
-        return;
-      }
-      bEmpty = empt;
-      break;
-    }
-    //
-    case 45:
-    case 54: { // Sphere/Torus
-      if (!IntSpTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
-        return;
-      }
-      bEmpty = empt;
-      break;
-    }
-    //
-    case 55: { // Torus/Torus
-      if (!IntToTo(quad1, quad2, TolTang, SameSurf, empt, slin)) {
-        return;
-      }
-      bEmpty = empt;
-      break;
-    }
-    //
-    default: {
-      throw Standard_ConstructionError();
-      break;
-    }
-  }
-  //
-  if (bEmpty) {
-    if (myDone == IntStatus_Fail)
-      myDone = IntStatus_OK;
-
-    return;
-  }
-  //
-
-  if(isPostProcessingRequired)
-  {
-    if (!SameSurf) {
-      AFunc.SetQuadric(quad2);
-      AFunc.Set(S1);
-    
-      solrst.Perform(AFunc, D1, TolArc, TolTang);
-      if (!solrst.IsDone()) {
-        return;
-      }
-
-      if (solrst.AllArcSolution() && typs1 == typs2) {
-        all1 = Standard_True;
-      }
-      nbpt = solrst.NbPoints();
-      nbseg= solrst.NbSegments();
-      for (i = 1; i <= nbpt; i++)
-      {
-        const IntPatch_ThePathPointOfTheSOnBounds& aPt = solrst.Point(i);
-        pnt1.Append(aPt);
-      }
-      for (i = 1; i <= nbseg; i++)
-      {
-        const IntPatch_TheSegmentOfTheSOnBounds& aSegm = solrst.Segment(i);
-        edg1.Append(aSegm);
-      }
-      nosolonS1 = (nbpt == 0) && (nbseg == 0);
-
-      if (nosolonS1 && all1) {  // cas de face sans restrictions
-        all1 = Standard_False;
-      }
-    }//if (!SameSurf) {
-    else {
-      nosolonS1 = Standard_True;
-    }
-
-    if (!SameSurf) {
-      AFunc.SetQuadric(quad1);
-      AFunc.Set(S2);
-
-      solrst.Perform(AFunc, D2, TolArc, TolTang);
-      if (!solrst.IsDone()) {
-        return;
-      }
-    
-      if (solrst.AllArcSolution() && typs1 == typs2) {
-        all2 = Standard_True;
-      }
-
-      nbpt = solrst.NbPoints();
-      nbseg= solrst.NbSegments();
-      for (i=1; i<= nbpt; i++) {
-        const IntPatch_ThePathPointOfTheSOnBounds& aPt = solrst.Point(i);
-        pnt2.Append(aPt);
-      }
-    
-      for (i=1; i<= nbseg; i++) {
-        const IntPatch_TheSegmentOfTheSOnBounds& aSegm = solrst.Segment(i);
-        edg2.Append(aSegm);
-      }
-      
-      nosolonS2 = (nbpt == 0) && (nbseg == 0);
-
-      if (nosolonS2 && all2) {  // cas de face sans restrictions
-        all2 = Standard_False;
-      }
-    }// if (!SameSurf) {
-    else {
-      nosolonS2 = Standard_True;
-    }
-    //
-    if (SameSurf || (all1 && all2)) {
-      // faces "paralleles" parfaites
-      empt = Standard_False;
-      tgte = Standard_True;
-      slin.Clear();
-      spnt.Clear();
-
-      gp_Pnt Ptreference;
-
-      switch (typs1) {
-      case GeomAbs_Plane:      {
-        Ptreference = (S1->Plane()).Location();
-      }
-        break;
-      case GeomAbs_Cylinder: {
-        Ptreference = ElSLib::Value(0.,0.,S1->Cylinder());
-      }
-        break;
-      case GeomAbs_Sphere:      {
-        Ptreference = ElSLib::Value(M_PI/4.,M_PI/4.,S1->Sphere());
-      }
-        break;
-      case GeomAbs_Cone:      {
-        Ptreference = ElSLib::Value(0.,10.,S1->Cone());
-      }
-        break;
-      case GeomAbs_Torus:      {
-        Ptreference = ElSLib::Value(0.,0.,S1->Torus());
-      }
-        break;
-      default: 
-        break;
-      }
-      //
-      oppo = quad1.Normale(Ptreference).Dot(quad2.Normale(Ptreference)) < 0.0;
-      myDone = IntStatus_OK;
-      return;
-    }// if (SameSurf || (all1 && all2)) {
-
-    if (!nosolonS1 || !nosolonS2) {
-      empt = Standard_False;
-      // C est la qu il faut commencer a bosser...
-      PutPointsOnLine(S1,S2,pnt1, slin, Standard_True, D1, quad1,quad2,
-                      multpoint,TolArc);
-    
-      PutPointsOnLine(S1,S2,pnt2, slin, Standard_False,D2, quad2,quad1,
-                      multpoint,TolArc);
-
-      if (edg1.Length() != 0) {
-        ProcessSegments(edg1,slin,quad1,quad2,Standard_True,TolArc);
-      }
-
-      if (edg2.Length() != 0) {
-        ProcessSegments(edg2,slin,quad1,quad2,Standard_False,TolArc);
-      }
-
-      if (edg1.Length() !=0 || edg2.Length() !=0) {
-        //      ProcessRLine(slin,S1,S2,TolArc);
-        ProcessRLine(slin,quad1,quad2,TolArc, theIsReqToKeepRLine);
-      }
-    }//if (!nosolonS1 || !nosolonS2) {
-    else {
-      empt = ((slin.Length()==0) && (spnt.Length()==0));
-    }
-  }
-  
-  Standard_Integer  nblin = slin.Length(),
-                    aNbPnt = spnt.Length();
-  //
-  //modified by NIZNHY-PKV Tue Sep 06 10:03:35 2011f
-  if (aNbPnt) {
-    IntPatch_SequenceOfPoint aSIP;
-    //
-    for(i=1; i<=aNbPnt; ++i) {
-      Standard_Real aU1, aV1, aU2, aV2;
-      gp_Pnt2d aP2D;
-      TopAbs_State aState1, aState2;
-      //
-      const IntPatch_Point& aIP=spnt(i);
-      aIP.Parameters(aU1, aV1, aU2, aV2);
-      //
-      aP2D.SetCoord(aU1, aV1);
-      aState1=D1->Classify(aP2D, TolArc);
-      //
-      aP2D.SetCoord(aU2, aV2);
-      aState2=D2->Classify(aP2D, TolArc);
-      //
-      if(aState1!=TopAbs_OUT && aState2!=TopAbs_OUT) {
-        aSIP.Append(aIP);
-      }
-    }
-    //
-    spnt.Clear();
-    //
-    aNbPnt=aSIP.Length();
-    for(i=1; i<=aNbPnt; ++i) {
-      const IntPatch_Point& aIP=aSIP(i);
-      spnt.Append(aIP);
-    }
-    //
-  }//  if (aNbPnt) {
-  //modified by NIZNHY-PKV Tue Sep 06 10:18:20 2011t
-  //
-  for(i=1; i<=nblin; i++) {
-    IntPatch_IType thetype = slin.Value(i)->ArcType();
-    if(  (thetype ==  IntPatch_Ellipse)
-       ||(thetype ==  IntPatch_Circle)
-       ||(thetype ==  IntPatch_Lin)
-       ||(thetype ==  IntPatch_Parabola)
-       ||(thetype ==  IntPatch_Hyperbola)) { 
-      Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
-    glin->ComputeVertexParameters(TolArc); 
-    }
-    else if(thetype == IntPatch_Analytic) { 
-      Handle(IntPatch_ALine)& aligold = *((Handle(IntPatch_ALine)*)&slin.Value(i));
-      aligold->ComputeVertexParameters(TolArc);
-    }
-    else if(thetype == IntPatch_Restriction) {
-      Handle(IntPatch_RLine)& rlig = *((Handle(IntPatch_RLine)*)&slin.Value(i));
-      rlig->ComputeVertexParameters(TolArc); 
-    }
-  }
-  //
-  //----------------------------------------------------------------
-  //-- On place 2 vertex sur les courbes de GLine qui n en 
-  //-- contiennent pas. 
-  for(i=1; i<=nblin; i++) {
-    gp_Pnt P;
-    IntPatch_Point point;
-    Standard_Real u1,v1,u2,v2; 
-    if(slin.Value(i)->ArcType() == IntPatch_Circle) { 
-      const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
-      if(glin->NbVertex() == 0) { 
-        gp_Circ Circ = glin->Circle();
-        P=ElCLib::Value(0.0,Circ);
-        quad1.Parameters(P,u1,v1);
-        quad2.Parameters(P,u2,v2);
-        point.SetValue(P,TolArc,Standard_False);
-        point.SetParameters(u1,v1,u2,v2);
-        point.SetParameter(0.0);
-        glin->AddVertex(point);
-
-        P=ElCLib::Value(0.0,Circ);
-        quad1.Parameters(P,u1,v1);
-        quad2.Parameters(P,u2,v2);
-        point.SetValue(P,TolArc,Standard_False);
-        point.SetParameters(u1,v1,u2,v2);
-        point.SetParameter(M_PI+M_PI);
-        glin->AddVertex(point);
-      }
-    }
-    
-    else if(slin.Value(i)->ArcType() == IntPatch_Ellipse) { 
-      const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
-      if(glin->NbVertex() == 0) { 
-        gp_Elips Elips = glin->Ellipse();
-        P=ElCLib::Value(0.0,Elips);
-        quad1.Parameters(P,u1,v1);
-        quad2.Parameters(P,u2,v2);
-        point.SetValue(P,TolArc,Standard_False);
-        point.SetParameters(u1,v1,u2,v2);
-        point.SetParameter(0.0);
-        glin->AddVertex(point);
-
-        P=ElCLib::Value(0.0,Elips);
-        quad1.Parameters(P,u1,v1);
-        quad2.Parameters(P,u2,v2);
-        point.SetValue(P,TolArc,Standard_False);
-        point.SetParameters(u1,v1,u2,v2);
-        point.SetParameter(M_PI+M_PI);
-        glin->AddVertex(point);
-      }
-    }
-  }
-  myDone = IntStatus_OK;
-}
-
-//=======================================================================
-//function : SetQuad
-//purpose  : 
-//=======================================================================
-Standard_Integer SetQuad(const Handle(Adaptor3d_Surface)& theS,
-                         GeomAbs_SurfaceType& theTS,
-                         IntSurf_Quadric& theQuad)
-{
-  theTS = theS->GetType();
-  Standard_Integer iRet = 0;
-  switch (theTS) {
-  case GeomAbs_Plane:
-    theQuad.SetValue(theS->Plane());
-    iRet = 1;
-    break;
-  case GeomAbs_Cylinder:
-    theQuad.SetValue(theS->Cylinder());
-    iRet = 2;
-    break;
-  case GeomAbs_Cone:
-    theQuad.SetValue(theS->Cone());
-    iRet = 3;
-    break;
-  case GeomAbs_Sphere:
-    theQuad.SetValue(theS->Sphere());
-    iRet = 4;
-    break;
-  case GeomAbs_Torus:
-    theQuad.SetValue(theS->Torus());
-    iRet = 5;
-    break;
-  default:
-    break;
-  }
-  //
-  return iRet;
-}
-
diff --git a/src/IntPatch/IntPatch_ImpImpIntersection_3.gxx b/src/IntPatch/IntPatch_ImpImpIntersection_3.gxx
deleted file mode 100644 (file)
index dd2770b..0000000
+++ /dev/null
@@ -1,803 +0,0 @@
-// Created on: 1992-05-07
-// Created by: Jacques GOUSSARD
-// Copyright (c) 1992-1999 Matra Datavision
-// Copyright (c) 1999-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.
-
-//modified by NIZNHY-PKV Thu Sep 15 11:09:12 2011
-static 
-  void SeamPosition(const gp_Pnt& aPLoc, 
-                    const gp_Ax3& aPos,
-                    gp_Ax2& aSeamPos);
-static
-  void AdjustToSeam (const gp_Cylinder& aQuad,
-                     gp_Circ& aCirc);
-static
-  void AdjustToSeam (const gp_Sphere& aQuad,
-                     gp_Circ& aCirc,
-                     const Standard_Real aTolAng);
-static
-  void AdjustToSeam (const gp_Cone& aQuad,
-                     gp_Circ& aCirc);
-static
-  void AdjustToSeam (const gp_Torus& aQuad,
-                     gp_Circ& aCirc);
-//modified by NIZNHY-PKV Thu Sep 15 11:09:13 2011
-
-//=======================================================================
-//function : IntPP
-//purpose  : 
-// Traitement du cas Plan/Plan
-//=======================================================================
-Standard_Boolean IntPP (const IntSurf_Quadric& Quad1,
-                        const IntSurf_Quadric& Quad2,
-                        const Standard_Real Tolang,
-                        const Standard_Real TolTang,
-                        Standard_Boolean& Same,
-                        IntPatch_SequenceOfLine& slin)
-
-{
-  IntSurf_TypeTrans trans1,trans2;
-  IntAna_ResultType typint;
-  gp_Pln pl1(Quad1.Plane());
-  gp_Pln pl2(Quad2.Plane());
-  
-  IntAna_QuadQuadGeo inter(pl1,pl2,Tolang,TolTang);
-  if (!inter.IsDone()) {return Standard_False;}
-  Same = Standard_False;
-  typint = inter.TypeInter();
-  if (typint == IntAna_Same) { // cas faces confondues
-    Same = Standard_True;
-  }
-  else if (typint != IntAna_Empty) { // on a une ligne
-    gp_Lin linsol = inter.Line(1);
-    Standard_Real discri = linsol.Direction().DotCross
-      (Quad2.Normale(linsol.Location()),
-       Quad1.Normale(linsol.Location()));
-    
-    if (discri>0.0) {
-      trans1 = IntSurf_Out;
-      trans2 = IntSurf_In;
-    }
-    else {
-      trans1 = IntSurf_In;
-      trans2 = IntSurf_Out;
-    }
-    Handle(IntPatch_GLine) glig = 
-      new IntPatch_GLine (linsol,Standard_False,trans1,trans2);
-    slin.Append(glig);
-  }
-  return Standard_True;
-}
-//=======================================================================
-//function : IntPCy
-//purpose  : 
-// Traitement du cas Plan/Cylindre et reciproquement
-//=======================================================================
-Standard_Boolean IntPCy (const IntSurf_Quadric& Quad1,
-                         const IntSurf_Quadric& Quad2,
-                         const Standard_Real Tolang,
-                         const Standard_Real TolTang,
-                         const Standard_Boolean Reversed,
-                         Standard_Boolean& Empty,
-                         IntPatch_SequenceOfLine& slin,
-                         const Standard_Real H)
-
-{
-  gp_Pln Pl;
-  gp_Cylinder Cy;
-
-  IntSurf_TypeTrans trans1,trans2;
-  IntAna_ResultType typint;
-
-  IntAna_QuadQuadGeo inter;
-  if (!Reversed) {
-    Pl = Quad1.Plane();
-    Cy = Quad2.Cylinder();
-  }
-  else {
-    Pl = Quad2.Plane();
-    Cy = Quad1.Cylinder();
-  }
-  inter.Perform(Pl,Cy,Tolang,TolTang,H);
-  if (!inter.IsDone()) {return Standard_False;}
-  typint = inter.TypeInter();
-  Standard_Integer NbSol = inter.NbSolutions();
-  Empty = Standard_False;
-
-  switch (typint) {
-            
-    case IntAna_Empty :    {
-      Empty = Standard_True;
-    }
-      break;
-
-    case IntAna_Line:    {
-      gp_Lin linsol = inter.Line(1);
-      gp_Pnt orig(linsol.Location());
-      if (NbSol == 1) {                 // ligne de tangence
-        gp_Vec TestCurvature(orig,Cy.Location());
-        gp_Vec Normp,Normcyl;
-        if (!Reversed) {
-          Normp = Quad1.Normale(orig);
-          Normcyl = Quad2.Normale(orig);
-        }
-        else {
-          Normp = Quad2.Normale(orig);
-          Normcyl = Quad1.Normale(orig);
-        }
-        
-        IntSurf_Situation situcyl;
-        IntSurf_Situation situp;
-
-        if (Normp.Dot(TestCurvature) > 0.) {
-          situcyl = IntSurf_Outside;
-          if (Normp.Dot(Normcyl) > 0.) {
-            situp = IntSurf_Inside;
-          }
-          else {
-            situp = IntSurf_Outside;
-          }
-        }
-        else {
-          situcyl = IntSurf_Inside;
-          if (Normp.Dot(Normcyl) > 0.) {
-            situp = IntSurf_Outside;
-          }
-          else {
-            situp = IntSurf_Inside;
-          }
-        }
-        Handle(IntPatch_GLine) glig;
-        if (!Reversed) {
-          glig = new IntPatch_GLine(linsol, Standard_True, situp, situcyl);
-        }
-        else {
-          glig = new IntPatch_GLine(linsol, Standard_True, situcyl, situp);
-        }
-        slin.Append(glig);
-      }
-      else {      
-        // on a 2 droites. Il faut determiner les transitions
-        // de chacune.
-        
-        if (linsol.Direction().DotCross(Quad2.Normale(orig),
-                                        Quad1.Normale(orig)) >0.) {
-          trans1 = IntSurf_Out;
-          trans2 = IntSurf_In;
-        }
-        else {
-          trans1 = IntSurf_In;
-          trans2 = IntSurf_Out;
-        }
-        Handle(IntPatch_GLine) glig = 
-          new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
-        slin.Append(glig);
-        
-        linsol = inter.Line(2);
-        orig = linsol.Location();
-
-        if (linsol.Direction().DotCross(Quad2.Normale(orig),
-                                        Quad1.Normale(orig)) >0.) {
-          trans1 = IntSurf_Out;
-          trans2 = IntSurf_In;
-        }
-        else {
-          trans1 = IntSurf_In;
-          trans2 = IntSurf_Out;
-        }
-        glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
-        slin.Append(glig);
-      }
-    }
-      break;
-      //
-    case IntAna_Circle:    {
-      gp_Circ cirsol;
-      gp_Pnt ptref;
-      gp_Vec Tgt;
-      //
-      cirsol = inter.Circle(1);
-      //modified by NIZNHY-PKV Thu Sep 15 11:30:03 2011f
-      AdjustToSeam(Cy, cirsol);
-      //modified by NIZNHY-PKV Thu Sep 15 11:30:15 2011t
-      ElCLib::D1(0.,cirsol,ptref,Tgt);
-      
-      if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) > 0.0) {
-        trans1 = IntSurf_Out;
-        trans2 = IntSurf_In;
-      }
-      else {
-        trans1 = IntSurf_In;
-        trans2 = IntSurf_Out;
-      }
-      Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
-      slin.Append(glig);
-    }
-      break;
-      // 
-    case IntAna_Ellipse:    {
-      gp_Elips elipsol = inter.Ellipse(1);
-      gp_Pnt ptref;
-      gp_Vec Tgt;
-      ElCLib::D1(0.,elipsol,ptref,Tgt);
-      
-      if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) > 0.0) {
-        trans1 = IntSurf_Out;
-        trans2 = IntSurf_In;
-      }
-      else {
-        trans1 = IntSurf_In;
-        trans2 = IntSurf_Out;
-      }
-      Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2);
-      slin.Append(glig);
-    }
-      break;
-      //
-    default:    {
-      return Standard_False; // on ne doit pas passer ici
-    }
-  }
-  return Standard_True;
-}
-//=======================================================================
-//function : IntPSp
-//purpose  : 
-// Traitement du cas Plan/Sphere et reciproquement
-//=======================================================================
-Standard_Boolean IntPSp (const IntSurf_Quadric& Quad1,
-                         const IntSurf_Quadric& Quad2,
-                         //modified by NIZNHY-PKV Tue Sep 20 08:59:36 2011f
-                         const Standard_Real Tolang,
-                         //modified by NIZNHY-PKV Tue Sep 20 08:59:39 2011t
-                         const Standard_Real TolTang,
-                         const Standard_Boolean Reversed,
-                         Standard_Boolean& Empty,
-                         IntPatch_SequenceOfLine& slin,
-                         IntPatch_SequenceOfPoint& spnt)
-
-
-{
-  gp_Circ cirsol;
-  gp_Pln Pl;
-  gp_Sphere Sp;
-  IntSurf_TypeTrans trans1,trans2;
-  IntAna_ResultType typint;
-
-  IntAna_QuadQuadGeo inter;
-  if (!Reversed) {
-    Pl = Quad1.Plane();
-    Sp = Quad2.Sphere();
-  }
-  else {
-    Pl = Quad2.Plane();
-    Sp = Quad1.Sphere();
-  }
-  inter.Perform(Pl,Sp);
-
-  if (!inter.IsDone()) {return Standard_False;}
-
-  typint = inter.TypeInter();
-  Empty = Standard_False;
-
-  switch (typint) {
-    case IntAna_Empty :    {
-      Empty = Standard_True;
-    }
-      break;
-      //
-    case IntAna_Point:    {
-      gp_Pnt psol = inter.Point(1);
-      Standard_Real U1,V1,U2,V2;
-      Quad1.Parameters(psol,U1,V1);
-      Quad2.Parameters(psol,U2,V2);
-      IntPatch_Point ptsol;
-      ptsol.SetValue(psol,TolTang,Standard_True);
-      ptsol.SetParameters(U1,V1,U2,V2);
-      spnt.Append(ptsol);
-    }
-      break;
-      //
-    case IntAna_Circle:    {
-      cirsol = inter.Circle(1);
-      //modified by NIZNHY-PKV Thu Sep 15 11:30:03 2011f
-      AdjustToSeam(Sp, cirsol, Tolang);
-      //modified by NIZNHY-PKV Thu Sep 15 11:30:15 2011t
-      gp_Pnt ptref;
-      gp_Vec Tgt;
-      ElCLib::D1(0.,cirsol,ptref,Tgt);
-
-      if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) >0.) {
-        trans1 = IntSurf_Out;
-        trans2 = IntSurf_In;
-      }
-      else {
-        trans1 = IntSurf_In;
-        trans2 = IntSurf_Out;
-      }
-      Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
-      slin.Append(glig);
-    }
-      break;
-      
-    default:    {
-      return Standard_False;  // on ne doit pas passer ici
-    }
-  }
-  return Standard_True;
-}
-//=======================================================================
-//function : IntPCo
-//purpose  : 
-// Traitement du cas Plan/Cone et reciproquement
-//=======================================================================
-Standard_Boolean IntPCo (const IntSurf_Quadric& Quad1,
-                         const IntSurf_Quadric& Quad2,
-                         const Standard_Real Tolang,
-                         const Standard_Real TolTang,
-                         const Standard_Boolean Reversed,
-                         Standard_Boolean& Empty,
-                         Standard_Boolean& Multpoint,
-                         IntPatch_SequenceOfLine& slin,
-                         IntPatch_SequenceOfPoint& spnt)
-
-
-{
-  gp_Pnt apex;
-
-  gp_Pln Pl;
-  gp_Cone Co;
-
-  IntSurf_TypeTrans trans1,trans2;
-  IntAna_ResultType typint;
-
-  IntAna_QuadQuadGeo inter;
-  if (!Reversed) {
-    Pl = Quad1.Plane();
-    Co = Quad2.Cone();
-    apex = Co.Apex();
-  }
-  else {
-    Pl = Quad2.Plane();
-    Co = Quad1.Cone();
-    apex = Co.Apex();
-  }
-
-  inter.Perform(Pl,Co,Tolang,TolTang);
-  if (!inter.IsDone()) {
-    return Standard_False;
-  }
-  //
-  typint = inter.TypeInter();
-  Standard_Integer NbSol = inter.NbSolutions();
-  Empty = Standard_False;
-
-  switch (typint) {
-    case IntAna_Point:    {
-      gp_Pnt psol = inter.Point(1);
-      Standard_Real U1,V1,U2,V2;
-      Quad1.Parameters(psol,U1,V1);
-      Quad2.Parameters(psol,U2,V2);
-      IntPatch_Point ptsol;
-      ptsol.SetValue(psol,TolTang,Standard_False);
-      ptsol.SetParameters(U1,V1,U2,V2);
-      spnt.Append(ptsol);
-    }
-      break;
-      
-    case IntAna_Line:    {
-      gp_Lin linsol = inter.Line(1);
-      if (linsol.Direction().Dot(Co.Axis().Direction()) <0.) {
-        linsol.SetDirection(linsol.Direction().Reversed());
-      }
-      Standard_Real para = ElCLib::Parameter(linsol, apex);
-      gp_Pnt ptbid (ElCLib::Value(para+5.,linsol));
-      Standard_Real U1,V1,U2,V2;
-      Quad1.Parameters(apex,U1,V1);
-      Quad2.Parameters(apex,U2,V2);
-      
-      if (NbSol == 1) {                 // ligne de tangence
-        IntPatch_Point ptsol;
-        ptsol.SetValue(apex,TolTang,Standard_False);
-        ptsol.SetParameters(U1,V1,U2,V2);
-        ptsol.SetParameter(para);
-        gp_Pnt ptbid2(apex.XYZ() + 5.*Co.Axis().Direction().XYZ());
-        gp_Vec TestCurvature(ptbid,ptbid2);
-        gp_Vec Normp,Normco;
-        if (!Reversed) {
-          Normp = Quad1.Normale(ptbid);
-          Normco = Quad2.Normale(ptbid);
-        }
-        else {
-          Normp = Quad2.Normale(ptbid);
-          Normco = Quad1.Normale(ptbid);
-        }
-        IntSurf_Situation situco,situco_otherside;
-        IntSurf_Situation situp,situp_otherside;
-        
-        if (Normp.Dot(TestCurvature) > 0.) {
-          situco           = IntSurf_Outside;
-          situco_otherside = IntSurf_Inside;
-          if (Normp.Dot(Normco) > 0.) {
-            situp           = IntSurf_Inside;
-            situp_otherside = IntSurf_Outside;
-          }
-          else {
-            situp           = IntSurf_Outside;
-            situp_otherside = IntSurf_Inside;
-          }
-        }
-        else {
-          situco           = IntSurf_Inside;
-          situco_otherside = IntSurf_Outside;
-          if (Normp.Dot(Normco) > 0.) {
-            situp           = IntSurf_Outside;
-            situp_otherside = IntSurf_Inside;
-          }
-          else {
-            situp           = IntSurf_Inside;
-            situp_otherside = IntSurf_Outside;
-          }
-        }
-        //----------------------------------------------------------
-        //--              Apex ---> Cone.Direction
-        //--
-        Handle(IntPatch_GLine) glig;
-        if (!Reversed) {
-          glig = new IntPatch_GLine(linsol, Standard_True, situp, situco);
-        }
-        else {
-          glig = new IntPatch_GLine(linsol, Standard_True, situco, situp);
-        }
-        glig->AddVertex(ptsol);
-        glig->SetFirstPoint(1);
-        slin.Append(glig);
-        //----------------------------------------------------------
-        //--   -Cone.Direction <------- Apex
-        //--
-        linsol.SetDirection(linsol.Direction().Reversed());
-        if (!Reversed) {
-          glig = new IntPatch_GLine(linsol, Standard_True, situp_otherside, situco_otherside);
-        }
-        else {
-          glig = new IntPatch_GLine(linsol, Standard_True, situco_otherside, situp_otherside);
-        }
-        glig->AddVertex(ptsol);
-        glig->SetFirstPoint(1);
-        slin.Append(glig);
-      }
-      else {      
-        // on a 2 droites. Il faut determiner les transitions
-        // de chacune. On oriente chaque ligne dans le sens
-        // de l axe du cone. Les transitions de chaque ligne seront
-        // inverses l une de l autre => on ne fait le calcul que sur
-        // la premiere.
-        if (linsol.Direction().DotCross
-            (Quad2.Normale(ptbid),Quad1.Normale(ptbid)) >0.) {
-          trans1 = IntSurf_Out;
-          trans2 = IntSurf_In;
-        }
-        else {
-          trans1 = IntSurf_In;
-          trans2 = IntSurf_Out;
-        }
-
-        Multpoint = Standard_True;
-        //------------------------------------------- Ligne 1 -------
-        IntPatch_Point ptsol;
-        ptsol.SetValue(apex,TolTang,Standard_False);
-        ptsol.SetParameters(U1,V1,U2,V2);
-        ptsol.SetParameter(para);
-        ptsol.SetMultiple(Standard_True);
-        Handle(IntPatch_GLine) glig;
-        glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
-        glig->AddVertex(ptsol);
-        glig->SetFirstPoint(1);
-        slin.Append(glig);
-        //-----------------------------------------------------------
-        //-- Other Side : Les transitions restent les memes
-        //--    linsol -> -linsol   et Quad1(2).N -> -Quad1(2).N
-        //-- 
-        linsol.SetDirection(linsol.Direction().Reversed());
-        glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
-        para = ElCLib::Parameter(linsol, apex);
-        ptsol.SetParameter(para);
-        glig->AddVertex(ptsol);
-        glig->SetFirstPoint(1);
-        slin.Append(glig);
-        
-        //------------------------------------------- Ligne 2 -------
-        linsol = inter.Line(2);
-        if (linsol.Direction().Dot(Co.Axis().Direction()) <0.) {
-          linsol.SetDirection(linsol.Direction().Reversed());
-        }
-        para = ElCLib::Parameter(linsol, apex);
-        ptbid  = ElCLib::Value(para+5.,linsol);
-        if (linsol.Direction().DotCross
-            (Quad2.Normale(ptbid),Quad1.Normale(ptbid)) >0.) {
-          trans1 = IntSurf_Out;
-          trans2 = IntSurf_In;
-        }
-        else {
-          trans1 = IntSurf_In;
-          trans2 = IntSurf_Out;
-        }
-        ptsol.SetParameter(para);
-        glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
-        para = ElCLib::Parameter(linsol, apex);
-        ptsol.SetParameter(para);
-        glig->AddVertex(ptsol);
-        glig->SetFirstPoint(1);
-        slin.Append(glig);
-        //-----------------------------------------------------------
-        //-- Other Side : Les transitions restent les memes
-        //--    linsol -> -linsol   et Quad1(2).N -> -Quad1(2).N
-        //-- 
-        linsol.SetDirection(linsol.Direction().Reversed());
-        glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
-        para = ElCLib::Parameter(linsol, apex);
-        ptsol.SetParameter(para);
-        glig->AddVertex(ptsol);
-        glig->SetFirstPoint(1);
-        slin.Append(glig);
-      }
-    }
-    break;
-      
-    case IntAna_Circle:    {
-      gp_Circ cirsol = inter.Circle(1);
-      //modified by NIZNHY-PKV Thu Sep 15 11:34:04 2011f
-      AdjustToSeam(Co, cirsol);
-      //modified by NIZNHY-PKV Thu Sep 15 11:36:08 2011t
-      gp_Pnt ptref;
-      gp_Vec Tgt;
-      ElCLib::D1(0.,cirsol,ptref,Tgt);
-      
-      if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) >0.) {
-        trans1 = IntSurf_Out;
-        trans2 = IntSurf_In;
-      }
-      else {
-        trans1 = IntSurf_In;
-        trans2 = IntSurf_Out;
-      }
-      Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
-      slin.Append(glig);
-    }
-      break;
-      
-    case IntAna_Ellipse:    {
-      gp_Elips  elipsol = inter.Ellipse(1);
-      gp_Pnt ptref;
-      gp_Vec Tgt;
-      ElCLib::D1(0.,elipsol,ptref,Tgt);
-      
-      if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) >0.) {
-        trans1 = IntSurf_Out;
-        trans2 = IntSurf_In;
-      }
-      else {
-        trans1 = IntSurf_In;
-        trans2 = IntSurf_Out;
-      }
-      Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2);
-      slin.Append(glig);
-    }
-      break;
-      
-    case IntAna_Parabola:    {
-      gp_Parab parabsol = inter.Parabola(1);
-      
-      gp_Vec Tgtorig(parabsol.YAxis().Direction());
-      Standard_Real ptran = Tgtorig.DotCross(Quad2.Normale(parabsol.Location()),
-                                             Quad1.Normale(parabsol.Location()));
-      if (ptran >0.00000001) {
-        trans1 = IntSurf_Out;
-        trans2 = IntSurf_In;
-      }
-      else if (ptran <-0.00000001) {
-        trans1 = IntSurf_In;
-        trans2 = IntSurf_Out;
-      }
-      else { 
-        trans1=trans2=IntSurf_Undecided; 
-      }
-      Handle(IntPatch_GLine) glig = new IntPatch_GLine(parabsol,Standard_False,trans1,trans2);
-      slin.Append(glig);
-    }
-      break;
-      
-    case IntAna_Hyperbola:    {
-      gp_Pnt tophypr;
-      gp_Vec Tgttop;
-      
-      for(Standard_Integer i=1; i<=2; i++) { 
-        gp_Hypr hyprsol = inter.Hyperbola(i);
-        tophypr = ElCLib::Value(hyprsol.MajorRadius(), 
-                                hyprsol.XAxis());
-        Tgttop = hyprsol.YAxis().Direction();
-        Standard_Real qwe = Tgttop.DotCross(Quad2.Normale(tophypr),
-                                            Quad1.Normale(tophypr));
-        
-        if (qwe>0.00000001) { 
-          trans1 = IntSurf_Out;
-          trans2 = IntSurf_In;
-        }
-        else if (qwe<-0.00000001){
-          trans1 = IntSurf_In;
-          trans2 = IntSurf_Out;
-        }
-        else { 
-          trans1=trans2=IntSurf_Undecided;
-        }
-        Handle(IntPatch_GLine) glig = new IntPatch_GLine(hyprsol,Standard_False,trans1,trans2);
-        slin.Append(glig);
-      }
-    }
-      break;
-      
-    default:    {
-      return Standard_False;
-    }
-  }
-  return Standard_True;
-}
-//=======================================================================
-//function : IntPTo
-//purpose  : 
-//=======================================================================
-Standard_Boolean IntPTo(const IntSurf_Quadric& theQuad1,
-                        const IntSurf_Quadric& theQuad2,
-                        const Standard_Real theTolTang,
-                        const Standard_Boolean bReversed,
-                        Standard_Boolean& bEmpty,
-                        IntPatch_SequenceOfLine& theSeqLin)
-{
-  const gp_Pln aPln = bReversed ? theQuad2.Plane() : theQuad1.Plane();
-  const gp_Torus aTorus = bReversed ? theQuad1.Torus() : theQuad2.Torus();
-  //
-  IntAna_QuadQuadGeo inter(aPln, aTorus, theTolTang);
-  Standard_Boolean bRet = inter.IsDone();
-  //
-  if (!bRet) {
-    return bRet;
-  }
-  //
-  IntAna_ResultType typint = inter.TypeInter();
-  Standard_Integer NbSol = inter.NbSolutions();
-  bEmpty = Standard_False;
-  //
-  switch (typint) {
-  case IntAna_Empty :
-    bEmpty = Standard_True;
-    break;
-  //
-  case IntAna_Circle : {
-    Standard_Integer i;
-    IntSurf_TypeTrans trans1, trans2;
-    gp_Pnt ptref;
-    gp_Vec Tgt;
-    //
-    for (i = 1; i <= NbSol; ++i) {
-      gp_Circ aC = inter.Circle(i);
-      if (!aPln.Axis().IsNormal(aTorus.Axis(), Precision::Angular())) {
-        AdjustToSeam(aTorus, aC);
-      }
-      ElCLib::D1(0., aC, ptref, Tgt);
-      //
-      if (Tgt.DotCross(theQuad2.Normale(ptref),theQuad1.Normale(ptref)) > 0.0) {
-        trans1 = IntSurf_Out;
-        trans2 = IntSurf_In;
-      }
-      else {
-        trans1 = IntSurf_In;
-        trans2 = IntSurf_Out;
-      }
-      //
-      Handle(IntPatch_GLine) glig = 
-        new IntPatch_GLine(aC, Standard_False, trans1, trans2);
-      theSeqLin.Append(glig);
-    }
-  }
-    break;
-  //
-  case IntAna_NoGeometricSolution:
-  default:
-    bRet = Standard_False;
-    break;
-  }
-  //
-  return bRet;
-}
-//
-//modified by NIZNHY-PKV Thu Sep 15 10:53:39 2011f
-//=======================================================================
-//function : AdjustToSeam
-//purpose  : 
-//=======================================================================
-void AdjustToSeam (const gp_Cone& aQuad,
-                   gp_Circ& aCirc)
-{
-   gp_Ax2 aAx2;
-   //
-   const gp_Pnt& aPLoc=aCirc.Location();
-   const gp_Ax3& aAx3=aQuad.Position();
-   SeamPosition(aPLoc, aAx3, aAx2);
-   aCirc.SetPosition(aAx2);
-} 
-//=======================================================================
-//function : AdjustToSeam
-//purpose  : 
-//=======================================================================
-void AdjustToSeam (const gp_Sphere& aQuad,
-                   gp_Circ& aCirc,
-                   const Standard_Real aTolAng)
-{
-   gp_Ax2 aAx2;
-   //
-   const gp_Ax1& aAx1C=aCirc.Axis();
-   const gp_Ax3& aAx3=aQuad.Position();
-   const gp_Ax1& aAx1Q=aAx3.Axis();
-   //
-   const gp_Dir& aDirC=aAx1C.Direction();
-   const gp_Dir& aDirQ=aAx1Q.Direction();
-   if (aDirC.IsParallel(aDirQ, aTolAng)) {
-     const gp_Pnt& aPLoc=aCirc.Location();
-     SeamPosition(aPLoc, aAx3, aAx2);
-     aCirc.SetPosition(aAx2);
-   }
-} 
-//=======================================================================
-//function : AdjustToSeam
-//purpose  : 
-//=======================================================================
-void AdjustToSeam (const gp_Cylinder& aQuad,
-                   gp_Circ& aCirc)
-{
-   gp_Ax2 aAx2;
-   //
-   const gp_Pnt& aPLoc=aCirc.Location();
-   const gp_Ax3& aAx3=aQuad.Position();
-   SeamPosition(aPLoc, aAx3, aAx2);
-   aCirc.SetPosition(aAx2);
-} 
-//=======================================================================
-//function : AdjustToSeam
-//purpose  : 
-//=======================================================================
-void AdjustToSeam (const gp_Torus& aQuad,
-                   gp_Circ& aCirc)
-{
-  gp_Ax2 aAx2;
-  //
-  const gp_Pnt& aPLoc=aCirc.Location();
-  const gp_Ax3& aAx3=aQuad.Position();
-  SeamPosition(aPLoc, aAx3, aAx2);
-  aCirc.SetPosition(aAx2);
-} 
-//=======================================================================
-//function : SeamPosition
-//purpose  : 
-//=======================================================================
-void SeamPosition(const gp_Pnt& aPLoc, 
-                  const gp_Ax3& aPos, 
-                  gp_Ax2& aSeamPos)
-{
-  const gp_Dir& aDZ=aPos.Direction();
-  const gp_Dir& aDX=aPos.XDirection();
-  gp_Ax2 aAx2(aPLoc, aDZ, aDX);
-  aSeamPos=aAx2;
-}
-    
-//modified by NIZNHY-PKV Thu Sep 15 10:53:41 2011t
diff --git a/src/IntPatch/IntPatch_ImpImpIntersection_4.gxx b/src/IntPatch/IntPatch_ImpImpIntersection_4.gxx
deleted file mode 100644 (file)
index 369d633..0000000
+++ /dev/null
@@ -1,4438 +0,0 @@
-// Created on: 1992-05-07
-// Created by: Jacques GOUSSARD
-// Copyright (c) 1992-1999 Matra Datavision
-// Copyright (c) 1999-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 <algorithm>
-#include <Bnd_Range.hxx>
-#include <IntAna_ListOfCurve.hxx>
-#include <math_Matrix.hxx>
-#include <NCollection_IncAllocator.hxx>
-#include <Standard_DivideByZero.hxx>
-#include <math_Vector.hxx>
-
-//If Abs(a) <= aNulValue then it is considered that a = 0.
-static const Standard_Real aNulValue = 1.0e-11;
-
-static void ShortCosForm( const Standard_Real theCosFactor,
-                          const Standard_Real theSinFactor,
-                          Standard_Real& theCoeff,
-                          Standard_Real& theAngle);
-//
-static Standard_Boolean ExploreCurve(const gp_Cone& theCo,
-                                     IntAna_Curve& aC,
-                                     const Standard_Real aTol,
-                                     IntAna_ListOfCurve& aLC);
-
-static Standard_Boolean InscribePoint(const Standard_Real theUfTarget,
-                                      const Standard_Real theUlTarget,
-                                      Standard_Real& theUGiven,
-                                      const Standard_Real theTol2D,
-                                      const Standard_Real thePeriod,
-                                      const Standard_Boolean theFlForce);
-
-
-class ComputationMethods
-{
-  //Every cylinder can be represented by the following equation in parametric form:
-  //    S(U,V) = L + R*cos(U)*Xd+R*sin(U)*Yd+V*Zd,
-  //where location L, directions Xd, Yd and Zd have type gp_XYZ.
-
-  //Intersection points between two cylinders can be found from the following system:
-  //    S1(U1, V1) = S2(U2, V2)
-  //or
-  //    {X01 + R1*cos(U1)*Xx1 + R1*sin(U1)*Yx1 + V1*Zx1 = X02 + R2*cos(U2)*Xx2 + R2*sin(U2)*Yx2 + V2*Zx2
-  //    {Y01 + R1*cos(U1)*Xy1 + R1*sin(U1)*Yy1 + V1*Zy1 = Y02 + R2*cos(U2)*Xy2 + R2*sin(U2)*Yy2 + V2*Zy2   (1)
-  //    {Z01 + R1*cos(U1)*Xz1 + R1*sin(U1)*Yz1 + V1*Zz1 = Z02 + R2*cos(U2)*Xz2 + R2*sin(U2)*Yz2 + V2*Zz2
-
-  //The formula (1) can be rewritten as follows
-  //    {C11*V1+C21*V2=A11*cos(U1)+B11*sin(U1)+A21*cos(U2)+B21*sin(U2)+D1
-  //    {C12*V1+C22*V2=A12*cos(U1)+B12*sin(U1)+A22*cos(U2)+B22*sin(U2)+D2                                   (2)
-  //    {C13*V1+C23*V2=A13*cos(U1)+B13*sin(U1)+A23*cos(U2)+B23*sin(U2)+D3
-
-  //Hereafter we consider that in system
-  //    {C11*V1+C21*V2=A11*cos(U1)+B11*sin(U1)+A21*cos(U2)+B21*sin(U2)+D1                                   (3)
-  //    {C12*V1+C22*V2=A12*cos(U1)+B12*sin(U1)+A22*cos(U2)+B22*sin(U2)+D2
-  //variables V1 and V2 can be found unambiguously, i.e. determinant
-  //            |C11 C21|
-  //            |       | != 0
-  //            |C12 C22|
-  //            
-  //In this case, variables V1 and V2 can be found as follows:
-  //    {V1 = K11*sin(U1)+K21*sin(U2)+L11*cos(U1)+L21*cos(U2)+M1 = K1*cos(U1-FIV1)+L1*cos(U2-PSIV1)+M1      (4)
-  //    {V2 = K12*sin(U1)+K22*sin(U2)+L12*cos(U1)+L22*cos(U2)+M2 = K2*cos(U2-FIV2)+L2*cos(U2-PSIV2)+M2
-
-  //Having substituted result of (4) to the 3rd equation of (2), we will obtain equation
-  //    cos(U2-FI2) = B*cos(U1-FI1)+C.                                                                      (5)
-
-  //I.e. when U1 is taken different given values (from domain), correspond U2 value can be computed
-  //from equation (5). After that, V1 and V2 can be computed from the system (4) (see
-  //CylCylComputeParameters(...) methods).
-
-  //It is important to remark that equation (5) (in general) has two solutions: U2=FI2 +/- f(U1).
-  //Therefore, we are getting here two intersection lines.
-
-public:
-  //Stores equations coefficients
-  struct stCoeffsValue
-  {
-    stCoeffsValue(const gp_Cylinder&, const gp_Cylinder&);
-
-    math_Vector mVecA1;
-    math_Vector mVecA2;
-    math_Vector mVecB1;
-    math_Vector mVecB2;
-    math_Vector mVecC1;
-    math_Vector mVecC2;
-    math_Vector mVecD;
-
-    Standard_Real mK21; //sinU2
-    Standard_Real mK11; //sinU1
-    Standard_Real mL21; //cosU2
-    Standard_Real mL11;  //cosU1
-    Standard_Real mM1;  //Free member
-
-    Standard_Real mK22; //sinU2
-    Standard_Real mK12; //sinU1
-    Standard_Real mL22; //cosU2
-    Standard_Real mL12; //cosU1
-    Standard_Real mM2; //Free member
-
-    Standard_Real mK1;
-    Standard_Real mL1;
-    Standard_Real mK2;
-    Standard_Real mL2;
-
-    Standard_Real mFIV1;
-    Standard_Real mPSIV1;
-    Standard_Real mFIV2;
-    Standard_Real mPSIV2;
-
-    Standard_Real mB;
-    Standard_Real mC;
-    Standard_Real mFI1;
-    Standard_Real mFI2;
-  };
-
-
-  //! Determines, if U2(U1) function is increasing.
-  static Standard_Boolean CylCylMonotonicity(const Standard_Real theU1par,
-                                             const Standard_Integer theWLIndex,
-                                             const stCoeffsValue& theCoeffs,
-                                             const Standard_Real thePeriod,
-                                             Standard_Boolean& theIsIncreasing);
-
-  //! Computes U2 (U-parameter of the 2nd cylinder) and, if theDelta != 0,
-  //! esimates the tolerance of U2-computing (estimation result is
-  //! assigned to *theDelta value).
-  static Standard_Boolean CylCylComputeParameters(const Standard_Real theU1par,
-                                                const Standard_Integer theWLIndex,
-                                                const stCoeffsValue& theCoeffs,
-                                                Standard_Real& theU2,
-                                                Standard_Real* const theDelta = 0);
-
-  static Standard_Boolean CylCylComputeParameters(const Standard_Real theU1,
-                                                  const Standard_Real theU2,
-                                                  const stCoeffsValue& theCoeffs,
-                                                  Standard_Real& theV1,
-                                                  Standard_Real& theV2);
-
-  static Standard_Boolean CylCylComputeParameters(const Standard_Real theU1par,
-                                                  const Standard_Integer theWLIndex,
-                                                  const stCoeffsValue& theCoeffs,
-                                                  Standard_Real& theU2,
-                                                  Standard_Real& theV1,
-                                                  Standard_Real& theV2);
-
-};
-
-ComputationMethods::stCoeffsValue::stCoeffsValue(const gp_Cylinder& theCyl1,
-                                                 const gp_Cylinder& theCyl2):
-  mVecA1(-theCyl1.Radius()*theCyl1.XAxis().Direction().XYZ()),
-  mVecA2(theCyl2.Radius()*theCyl2.XAxis().Direction().XYZ()),
-  mVecB1(-theCyl1.Radius()*theCyl1.YAxis().Direction().XYZ()),
-  mVecB2(theCyl2.Radius()*theCyl2.YAxis().Direction().XYZ()),
-  mVecC1(theCyl1.Axis().Direction().XYZ()),
-  mVecC2(theCyl2.Axis().Direction().XYZ().Reversed()),
-  mVecD(theCyl2.Location().XYZ() - theCyl1.Location().XYZ())
-{
-  enum CoupleOfEquation
-  {
-    COENONE = 0,
-    COE12 = 1,
-    COE23 = 2,
-    COE13 = 3
-  }aFoundCouple = COENONE;
-
-
-  Standard_Real aDetV1V2 = 0.0;
-
-  const Standard_Real aDelta1 = mVecC1(1)*mVecC2(2)-mVecC1(2)*mVecC2(1); //1-2
-  const Standard_Real aDelta2 = mVecC1(2)*mVecC2(3)-mVecC1(3)*mVecC2(2); //2-3
-  const Standard_Real aDelta3 = mVecC1(1)*mVecC2(3)-mVecC1(3)*mVecC2(1); //1-3
-  const Standard_Real anAbsD1 = Abs(aDelta1); //1-2
-  const Standard_Real anAbsD2 = Abs(aDelta2); //2-3
-  const Standard_Real anAbsD3 = Abs(aDelta3); //1-3
-
-  if(anAbsD1 >= anAbsD2)
-  {
-    if(anAbsD3 > anAbsD1)
-    {
-      aFoundCouple = COE13;
-      aDetV1V2 = aDelta3;
-    }
-    else
-    {
-      aFoundCouple = COE12;
-      aDetV1V2 = aDelta1;
-    }
-  }
-  else
-  {
-    if(anAbsD3 > anAbsD2)
-    {
-      aFoundCouple = COE13;
-      aDetV1V2 = aDelta3;
-    }
-    else
-    {
-      aFoundCouple = COE23;
-      aDetV1V2 = aDelta2;
-    }
-  }
-
-  // In point of fact, every determinant (aDelta1, aDelta2 and aDelta3) is
-  // cross-product between directions (i.e. sine of angle).
-  // If sine is too small then sine is (approx.) equal to angle itself.
-  // Therefore, in this case we should compare sine with angular tolerance. 
-  // This constant is used for check if axes are parallel (see constructor
-  // AxeOperator::AxeOperator(...) in IntAna_QuadQuadGeo.cxx file).
-  if(Abs(aDetV1V2) < Precision::Angular())
-  {
-    throw Standard_Failure("Error. Exception in divide by zerro (IntCyCyTrim)!!!!");
-  }
-
-  switch(aFoundCouple)
-  {
-  case COE12:
-    break;
-  case COE23:
-    {
-      math_Vector aVTemp(mVecA1);
-      mVecA1(1) = aVTemp(2);
-      mVecA1(2) = aVTemp(3);
-      mVecA1(3) = aVTemp(1);
-
-      aVTemp = mVecA2;
-      mVecA2(1) = aVTemp(2);
-      mVecA2(2) = aVTemp(3);
-      mVecA2(3) = aVTemp(1);
-
-      aVTemp = mVecB1;
-      mVecB1(1) = aVTemp(2);
-      mVecB1(2) = aVTemp(3);
-      mVecB1(3) = aVTemp(1);
-
-      aVTemp = mVecB2;
-      mVecB2(1) = aVTemp(2);
-      mVecB2(2) = aVTemp(3);
-      mVecB2(3) = aVTemp(1);
-
-      aVTemp = mVecC1;
-      mVecC1(1) = aVTemp(2);
-      mVecC1(2) = aVTemp(3);
-      mVecC1(3) = aVTemp(1);
-
-      aVTemp = mVecC2;
-      mVecC2(1) = aVTemp(2);
-      mVecC2(2) = aVTemp(3);
-      mVecC2(3) = aVTemp(1);
-
-      aVTemp = mVecD;
-      mVecD(1) = aVTemp(2);
-      mVecD(2) = aVTemp(3);
-      mVecD(3) = aVTemp(1);
-
-      break;
-    }
-  case COE13:
-    {
-      math_Vector aVTemp = mVecA1;
-      mVecA1(2) = aVTemp(3);
-      mVecA1(3) = aVTemp(2);
-
-      aVTemp = mVecA2;
-      mVecA2(2) = aVTemp(3);
-      mVecA2(3) = aVTemp(2);
-
-      aVTemp = mVecB1;
-      mVecB1(2) = aVTemp(3);
-      mVecB1(3) = aVTemp(2);
-
-      aVTemp = mVecB2;
-      mVecB2(2) = aVTemp(3);
-      mVecB2(3) = aVTemp(2);
-
-      aVTemp = mVecC1;
-      mVecC1(2) = aVTemp(3);
-      mVecC1(3) = aVTemp(2);
-
-      aVTemp = mVecC2;
-      mVecC2(2) = aVTemp(3);
-      mVecC2(3) = aVTemp(2);
-
-      aVTemp = mVecD;
-      mVecD(2) = aVTemp(3);
-      mVecD(3) = aVTemp(2);
-
-      break;
-    }
-  default:
-    break;
-  }
-
-  //------- For V1 (begin)
-  //sinU2
-  mK21 = (mVecC2(2)*mVecB2(1)-mVecC2(1)*mVecB2(2))/aDetV1V2;
-  //sinU1
-  mK11 = (mVecC2(2)*mVecB1(1)-mVecC2(1)*mVecB1(2))/aDetV1V2;
-  //cosU2
-  mL21 = (mVecC2(2)*mVecA2(1)-mVecC2(1)*mVecA2(2))/aDetV1V2;
-  //cosU1
-  mL11 = (mVecC2(2)*mVecA1(1)-mVecC2(1)*mVecA1(2))/aDetV1V2;
-  //Free member
-  mM1 =  (mVecC2(2)*mVecD(1)-mVecC2(1)*mVecD(2))/aDetV1V2;
-  //------- For V1 (end)
-
-  //------- For V2 (begin)
-  //sinU2
-  mK22 = (mVecC1(1)*mVecB2(2)-mVecC1(2)*mVecB2(1))/aDetV1V2;
-  //sinU1
-  mK12 = (mVecC1(1)*mVecB1(2)-mVecC1(2)*mVecB1(1))/aDetV1V2;
-  //cosU2
-  mL22 = (mVecC1(1)*mVecA2(2)-mVecC1(2)*mVecA2(1))/aDetV1V2;
-  //cosU1
-  mL12 = (mVecC1(1)*mVecA1(2)-mVecC1(2)*mVecA1(1))/aDetV1V2;
-  //Free member
-  mM2 = (mVecC1(1)*mVecD(2)-mVecC1(2)*mVecD(1))/aDetV1V2;
-  //------- For V1 (end)
-
-  ShortCosForm(mL11, mK11, mK1, mFIV1);
-  ShortCosForm(mL21, mK21, mL1, mPSIV1);
-  ShortCosForm(mL12, mK12, mK2, mFIV2);
-  ShortCosForm(mL22, mK22, mL2, mPSIV2);
-
-  const Standard_Real aA1=mVecC1(3)*mK21+mVecC2(3)*mK22-mVecB2(3), //sinU2
-    aA2=mVecC1(3)*mL21+mVecC2(3)*mL22-mVecA2(3), //cosU2
-    aB1=mVecB1(3)-mVecC1(3)*mK11-mVecC2(3)*mK12, //sinU1
-    aB2=mVecA1(3)-mVecC1(3)*mL11-mVecC2(3)*mL12; //cosU1
-
-  mC =mVecD(3) - mVecC1(3)*mM1 -mVecC2(3)*mM2;  //Free
-
-  Standard_Real aA = 0.0;
-
-  ShortCosForm(aB2,aB1,mB,mFI1);
-  ShortCosForm(aA2,aA1,aA,mFI2);
-
-  mB /= aA;
-  mC /= aA;
-}
-
-class WorkWithBoundaries
-{
-public:
-  enum SearchBoundType
-  {
-    SearchNONE = 0,
-    SearchV1 = 1,
-    SearchV2 = 2
-  };
-
-  struct StPInfo
-  {
-    StPInfo()
-    {
-      mySurfID = 0;
-      myU1 = RealLast();
-      myV1 = RealLast();
-      myU2 = RealLast();
-      myV2 = RealLast();
-    }
-
-    //Equal to 0 for 1st surface non-zero for 2nd one.
-    Standard_Integer mySurfID;
-
-    Standard_Real myU1;
-    Standard_Real myV1;
-    Standard_Real myU2;
-    Standard_Real myV2;
-
-    bool operator>(const StPInfo& theOther) const
-    {
-      return myU1 > theOther.myU1;
-    }
-
-    bool operator<(const StPInfo& theOther) const
-    {
-      return myU1 < theOther.myU1;
-    }
-
-    bool operator==(const StPInfo& theOther) const
-    {
-      return myU1 == theOther.myU1;
-    }
-  };
-
-  WorkWithBoundaries(const IntSurf_Quadric& theQuad1,
-                     const IntSurf_Quadric& theQuad2,
-                     const ComputationMethods::stCoeffsValue& theCoeffs,
-                     const Bnd_Box2d& theUVSurf1,
-                     const Bnd_Box2d& theUVSurf2,
-                     const Standard_Integer theNbWLines,
-                     const Standard_Real thePeriod,
-                     const Standard_Real theTol3D,
-                     const Standard_Real theTol2D,
-                     const Standard_Boolean isTheReverse) :
-      myQuad1(theQuad1), myQuad2(theQuad2), myCoeffs(theCoeffs),
-      myUVSurf1(theUVSurf1), myUVSurf2(theUVSurf2), myNbWLines(theNbWLines),
-      myPeriod(thePeriod), myTol3D(theTol3D), myTol2D(theTol2D),
-      myIsReverse(isTheReverse)
-  {
-  };
-
-  // Returns parameters of system solved while finding
-  // intersection line
-  const ComputationMethods::stCoeffsValue &SICoeffs() const
-  {
-    return myCoeffs;
-  }
-
-  // Returns quadric correspond to the index theIdx.
-  const IntSurf_Quadric& GetQSurface(const Standard_Integer theIdx) const
-  {
-    if (theIdx <= 1)
-      return myQuad1;
-
-    return myQuad2;
-  }
-
-  // Returns TRUE in case of reverting surfaces
-  Standard_Boolean IsReversed() const
-  {
-    return myIsReverse;
-  }
-
-  // Returns 2D-tolerance
-  Standard_Real Get2dTolerance() const
-  {
-    return myTol2D;
-  }
-
-  // Returns 3D-tolerance
-  Standard_Real Get3dTolerance() const
-  {
-    return myTol3D;
-  }
-
-  // Returns UV-bounds of 1st surface
-  const Bnd_Box2d& UVS1() const
-  {
-    return myUVSurf1;
-  }
-
-  // Returns UV-bounds of 2nd surface
-  const Bnd_Box2d& UVS2() const
-  {
-    return myUVSurf2;
-  }
-
-  void AddBoundaryPoint(const Handle(IntPatch_WLine)& theWL,
-                        const Standard_Real theU1,
-                        const Standard_Real theU1Min,
-                        const Standard_Real theU2,
-                        const Standard_Real theV1,
-                        const Standard_Real theV1Prev,
-                        const Standard_Real theV2,
-                        const Standard_Real theV2Prev,
-                        const Standard_Integer theWLIndex,
-                        const Standard_Boolean theFlForce,
-                        Standard_Boolean& isTheFound1,
-                        Standard_Boolean& isTheFound2) const;
-  
-  static Standard_Boolean BoundariesComputing(const ComputationMethods::stCoeffsValue &theCoeffs,
-                                              const Standard_Real thePeriod,
-                                              Bnd_Range theURange[]);
-  
-  void BoundaryEstimation(const gp_Cylinder& theCy1,
-                          const gp_Cylinder& theCy2,
-                          Bnd_Range& theOutBoxS1,
-                          Bnd_Range& theOutBoxS2) const;
-
-protected:
-
-  //Solves equation (2) (see declaration of ComputationMethods class) in case,
-  //when V1 or V2 (is set by theSBType argument) is known (corresponds to the boundary
-  //and equal to theVzad) but U1 is unknown. Computation is made by numeric methods and
-  //requires initial values (theVInit, theInitU2 and theInitMainVar).
-  Standard_Boolean
-              SearchOnVBounds(const SearchBoundType theSBType,
-                              const Standard_Real theVzad,
-                              const Standard_Real theVInit,
-                              const Standard_Real theInitU2,
-                              const Standard_Real theInitMainVar,
-                              Standard_Real& theMainVariableValue) const;
-
-  const WorkWithBoundaries& operator=(const WorkWithBoundaries&);
-
-private:
-  friend class ComputationMethods;
-
-  const IntSurf_Quadric& myQuad1;
-  const IntSurf_Quadric& myQuad2;
-  const ComputationMethods::stCoeffsValue& myCoeffs;
-  const Bnd_Box2d& myUVSurf1;
-  const Bnd_Box2d& myUVSurf2;
-  const Standard_Integer myNbWLines;
-  const Standard_Real myPeriod;
-  const Standard_Real myTol3D;
-  const Standard_Real myTol2D;
-  const Standard_Boolean myIsReverse;
-};
-
-static void SeekAdditionalPoints( const IntSurf_Quadric& theQuad1,
-                                  const IntSurf_Quadric& theQuad2,
-                                  const Handle(IntSurf_LineOn2S)& theLine,
-                                  const ComputationMethods::stCoeffsValue& theCoeffs,
-                                  const Standard_Integer theWLIndex,
-                                  const Standard_Integer theMinNbPoints,
-                                  const Standard_Integer theStartPointOnLine,
-                                  const Standard_Integer theEndPointOnLine,
-                                  const Standard_Real theTol2D,
-                                  const Standard_Real thePeriodOfSurf2,
-                                  const Standard_Boolean isTheReverse);
-
-//=======================================================================
-//function : MinMax
-//purpose  : Replaces theParMIN = MIN(theParMIN, theParMAX),
-//                    theParMAX = MAX(theParMIN, theParMAX).
-//=======================================================================
-static inline void MinMax(Standard_Real& theParMIN, Standard_Real& theParMAX)
-{
-  if(theParMIN > theParMAX)
-  {
-    const Standard_Real aux = theParMAX;
-    theParMAX = theParMIN;
-    theParMIN = aux;
-  }
-}
-
-//=======================================================================
-//function : ExtremaLineLine
-//purpose  : Computes extrema between the given lines. Returns parameters
-//          on correspond curve (see correspond method for Extrema_ExtElC class). 
-//=======================================================================
-static inline void ExtremaLineLine(const gp_Ax1& theC1,
-                                   const gp_Ax1& theC2,
-                                   const Standard_Real theCosA,
-                                   const Standard_Real theSqSinA,
-                                   Standard_Real& thePar1,
-                                   Standard_Real& thePar2)
-{
-  const gp_Dir &aD1 = theC1.Direction(),
-               &aD2 = theC2.Direction();
-
-  const gp_XYZ aL1L2 = theC2.Location().XYZ() - theC1.Location().XYZ();
-  const Standard_Real aD1L = aD1.XYZ().Dot(aL1L2),
-                      aD2L = aD2.XYZ().Dot(aL1L2);
-
-  thePar1 = (aD1L - theCosA * aD2L) / theSqSinA;
-  thePar2 = (theCosA * aD1L - aD2L) / theSqSinA;
-}
-
-//=======================================================================
-//function : VBoundaryPrecise
-//purpose  : By default, we shall consider, that V1 and V2 will be increased
-//            if U1 is increased. But if it is not, new V1set and/or V2set
-//            must be computed as [V1current - DeltaV1] (analogically
-//            for V2). This function processes this case.
-//=======================================================================
-static void VBoundaryPrecise( const math_Matrix& theMatr,
-                              const Standard_Real theV1AfterDecrByDelta,
-                              const Standard_Real theV2AfterDecrByDelta,
-                              Standard_Real& theV1Set,
-                              Standard_Real& theV2Set)
-{
-  //Now we are going to define if V1 (and V2) increases
-  //(or decreases) when U1 will increase.
-  const Standard_Integer aNbDim = 3;
-  math_Matrix aSyst(1, aNbDim, 1, aNbDim);
-
-  aSyst.SetCol(1, theMatr.Col(1));
-  aSyst.SetCol(2, theMatr.Col(2));
-  aSyst.SetCol(3, theMatr.Col(4));
-
-  //We have the system (see comment to StepComputing(...) function)
-  //    {a11*dV1 + a12*dV2 + a14*dU2 = -a13*dU1
-  //    {a21*dV1 + a22*dV2 + a24*dU2 = -a23*dU1
-  //    {a31*dV1 + a32*dV2 + a34*dU2 = -a33*dU1
-
-  const Standard_Real aDet = aSyst.Determinant();
-
-  aSyst.SetCol(1, theMatr.Col(3));
-  const Standard_Real aDet1 = aSyst.Determinant();
-
-  aSyst.SetCol(1, theMatr.Col(1));
-  aSyst.SetCol(2, theMatr.Col(3));
-
-  const Standard_Real aDet2 = aSyst.Determinant();
-
-  //Now,
-  //    dV1 = -dU1*aDet1/aDet
-  //    dV2 = -dU1*aDet2/aDet
-
-  //If U1 is increased then dU1 > 0.
-  //If (aDet1/aDet > 0) then dV1 < 0 and 
-  //V1 will be decreased after increasing U1.
-
-  //We have analogical situation with V2-parameter. 
-
-  if(aDet*aDet1 > 0.0)
-  {
-    theV1Set = theV1AfterDecrByDelta;
-  }
-
-  if(aDet*aDet2 > 0.0)
-  {
-    theV2Set = theV2AfterDecrByDelta;
-  }
-}
-
-//=======================================================================
-//function : DeltaU1Computing
-//purpose  : Computes new step for U1 parameter.
-//=======================================================================
-static inline 
-        Standard_Boolean DeltaU1Computing(const math_Matrix& theSyst,
-                                          const math_Vector& theFree,
-                                          Standard_Real& theDeltaU1Found)
-{
-  Standard_Real aDet = theSyst.Determinant();
-
-  if(Abs(aDet) > aNulValue)
-  {
-    math_Matrix aSyst1(theSyst);
-    aSyst1.SetCol(2, theFree);
-
-    theDeltaU1Found = Abs(aSyst1.Determinant()/aDet);
-    return Standard_True;
-  }
-
-  return Standard_False;
-}
-
-//=======================================================================
-//function : StepComputing
-//purpose  : 
-//
-//Attention!!!:
-//            theMatr must have 3*5-dimension strictly.
-//            For system
-//                {a11*V1+a12*V2+a13*dU1+a14*dU2=b1; 
-//                {a21*V1+a22*V2+a23*dU1+a24*dU2=b2; 
-//                {a31*V1+a32*V2+a33*dU1+a34*dU2=b3; 
-//            theMatr must be following:
-//                (a11 a12 a13 a14 b1) 
-//                (a21 a22 a23 a24 b2) 
-//                (a31 a32 a33 a34 b3) 
-//=======================================================================
-static Standard_Boolean StepComputing(const math_Matrix& theMatr,
-                                      const Standard_Real theV1Cur,
-                                      const Standard_Real theV2Cur,
-                                      const Standard_Real theDeltaV1,
-                                      const Standard_Real theDeltaV2,
-                                      Standard_Real& theDeltaU1Found/*,
-                                      Standard_Real& theDeltaU2Found,
-                                      Standard_Real& theV1Found,
-                                      Standard_Real& theV2Found*/)
-{
-#ifdef INTPATCH_IMPIMPINTERSECTION_DEBUG
-  bool flShow = false;
-
-  if(flShow)
-  {
-    printf("{%+10.20f*V1 + %+10.20f*V2 + %+10.20f*dU1 + %+10.20f*dU2 = %+10.20f\n",
-              theMatr(1,1), theMatr(1,2), theMatr(1,3), theMatr(1,4), theMatr(1,5));
-    printf("{%+10.20f*V1 + %+10.20f*V2 + %+10.20f*dU1 + %+10.20f*dU2 = %+10.20f\n",
-              theMatr(2,1), theMatr(2,2), theMatr(2,3), theMatr(2,4), theMatr(2,5));
-    printf("{%+10.20f*V1 + %+10.20f*V2 + %+10.20f*dU1 + %+10.20f*dU2 = %+10.20f\n",
-              theMatr(3,1), theMatr(3,2), theMatr(3,3), theMatr(3,4), theMatr(3,5));
-  }
-#endif
-
-  Standard_Boolean isSuccess = Standard_False;
-  theDeltaU1Found/* = theDeltaU2Found*/ = RealLast();
-  //theV1Found = theV1set;
-  //theV2Found = theV2Set;
-  const Standard_Integer aNbDim = 3;
-
-  math_Matrix aSyst(1, aNbDim, 1, aNbDim);
-  math_Vector aFree(1, aNbDim);
-
-  //By default, increasing V1(U1) and V2(U1) functions is
-  //considered
-  Standard_Real aV1Set = theV1Cur + theDeltaV1,
-                aV2Set = theV2Cur + theDeltaV2;
-
-  //However, what is indeed?
-  VBoundaryPrecise( theMatr, theV1Cur - theDeltaV1,
-                    theV2Cur - theDeltaV2, aV1Set, aV2Set);
-
-  aSyst.SetCol(2, theMatr.Col(3));
-  aSyst.SetCol(3, theMatr.Col(4));
-
-  for(Standard_Integer i = 0; i < 2; i++)
-  {
-    if(i == 0)
-    {//V1 is known
-      aSyst.SetCol(1, theMatr.Col(2));
-      aFree.Set(1, aNbDim, theMatr.Col(5)-aV1Set*theMatr.Col(1));
-    }
-    else
-    {//i==1 => V2 is known
-      aSyst.SetCol(1, theMatr.Col(1));
-      aFree.Set(1, aNbDim, theMatr.Col(5)-aV2Set*theMatr.Col(2));
-    }
-
-    Standard_Real aNewDU = theDeltaU1Found;
-    if(DeltaU1Computing(aSyst, aFree, aNewDU))
-    {
-      isSuccess = Standard_True;
-      if(aNewDU < theDeltaU1Found)
-      {
-        theDeltaU1Found = aNewDU;
-      }
-    }
-  }
-
-  if(!isSuccess)
-  {
-    aFree = theMatr.Col(5) - aV1Set*theMatr.Col(1) - aV2Set*theMatr.Col(2);
-    math_Matrix aSyst1(1, aNbDim, 1, 2);
-    aSyst1.SetCol(1, aSyst.Col(2));
-    aSyst1.SetCol(2, aSyst.Col(3));
-
-    //Now we have overdetermined system.
-
-    const Standard_Real aDet1 = theMatr(1,3)*theMatr(2,4) - theMatr(2,3)*theMatr(1,4);
-    const Standard_Real aDet2 = theMatr(1,3)*theMatr(3,4) - theMatr(3,3)*theMatr(1,4);
-    const Standard_Real aDet3 = theMatr(2,3)*theMatr(3,4) - theMatr(3,3)*theMatr(2,4);
-    const Standard_Real anAbsD1 = Abs(aDet1);
-    const Standard_Real anAbsD2 = Abs(aDet2);
-    const Standard_Real anAbsD3 = Abs(aDet3);
-
-    if(anAbsD1 >= anAbsD2)
-    {
-      if(anAbsD1 >= anAbsD3)
-      {
-        //Det1
-        if(anAbsD1 <= aNulValue)
-          return isSuccess;
-
-        theDeltaU1Found = Abs(aFree(1)*theMatr(2,4) - aFree(2)*theMatr(1,4))/anAbsD1;
-        isSuccess = Standard_True;
-      }
-      else
-      {
-        //Det3
-        if(anAbsD3 <= aNulValue)
-          return isSuccess;
-
-        theDeltaU1Found = Abs(aFree(2)*theMatr(3,4) - aFree(3)*theMatr(2,4))/anAbsD3;
-        isSuccess = Standard_True;
-      }
-    }
-    else
-    {
-      if(anAbsD2 >= anAbsD3)
-      {
-        //Det2
-        if(anAbsD2 <= aNulValue)
-          return isSuccess;
-
-        theDeltaU1Found = Abs(aFree(1)*theMatr(3,4) - aFree(3)*theMatr(1,4))/anAbsD2;
-        isSuccess = Standard_True;
-      }
-      else
-      {
-        //Det3
-        if(anAbsD3 <= aNulValue)
-          return isSuccess;
-
-        theDeltaU1Found = Abs(aFree(2)*theMatr(3,4) - aFree(3)*theMatr(2,4))/anAbsD3;
-        isSuccess = Standard_True;
-      }
-    }
-  }
-
-  return isSuccess;
-}
-
-//=======================================================================
-//function : ProcessBounds
-//purpose  : 
-//=======================================================================
-void ProcessBounds(const Handle(IntPatch_ALine)& alig,          //-- ligne courante
-                  const IntPatch_SequenceOfLine& slin,
-                  const IntSurf_Quadric& Quad1,
-                  const IntSurf_Quadric& Quad2,
-                  Standard_Boolean& procf,
-                  const gp_Pnt& ptf,                     //-- Debut Ligne Courante
-                  const Standard_Real first,             //-- Paramf
-                  Standard_Boolean& procl,
-                  const gp_Pnt& ptl,                     //-- Fin Ligne courante
-                  const Standard_Real last,              //-- Paraml
-                  Standard_Boolean& Multpoint,
-                  const Standard_Real Tol)
-{  
-  Standard_Integer j,k;
-  Standard_Real U1,V1,U2,V2;
-  IntPatch_Point ptsol;
-  Standard_Real d;
-  
-  if (procf && procl) {
-    j = slin.Length() + 1;
-  }
-  else {
-    j = 1;
-  }
-
-
-  //-- On prend les lignes deja enregistrees
-
-  while (j <= slin.Length()) {  
-    if(slin.Value(j)->ArcType() == IntPatch_Analytic) { 
-      const Handle(IntPatch_ALine)& aligold = *((Handle(IntPatch_ALine)*)&slin.Value(j));
-      k = 1;
-
-      //-- On prend les vertex des lignes deja enregistrees
-
-      while (k <= aligold->NbVertex()) {
-       ptsol = aligold->Vertex(k);            
-       if (!procf) {
-         d=ptf.Distance(ptsol.Value());
-         if (d <= Tol) {
-            ptsol.SetTolerance(Tol);
-           if (!ptsol.IsMultiple()) {
-             //-- le point ptsol (de aligold) est declare multiple sur aligold
-             Multpoint = Standard_True;
-             ptsol.SetMultiple(Standard_True);
-             aligold->Replace(k,ptsol);
-           }
-           ptsol.SetParameter(first);
-           alig->AddVertex(ptsol);
-           alig->SetFirstPoint(alig->NbVertex());
-           procf = Standard_True;
-
-           //-- On restore le point avec son parametre sur aligold
-           ptsol = aligold->Vertex(k); 
-                                        
-         }
-       }
-       if (!procl) {
-         if (ptl.Distance(ptsol.Value()) <= Tol) {
-            ptsol.SetTolerance(Tol);
-           if (!ptsol.IsMultiple()) {
-             Multpoint = Standard_True;
-             ptsol.SetMultiple(Standard_True);
-             aligold->Replace(k,ptsol);
-           }
-           ptsol.SetParameter(last);
-           alig->AddVertex(ptsol);
-           alig->SetLastPoint(alig->NbVertex());
-           procl = Standard_True;
-
-           //-- On restore le point avec son parametre sur aligold
-           ptsol = aligold->Vertex(k); 
-             
-         }
-       }
-       if (procf && procl) {
-         k = aligold->NbVertex()+1;
-       }
-       else {
-         k = k+1;
-       }
-      }
-      if (procf && procl) {
-       j = slin.Length()+1;
-      }
-      else {
-       j = j+1;
-      }
-    }
-  }
-  
-  ptsol.SetTolerance(Tol);
-  if (!procf && !procl) {
-    Quad1.Parameters(ptf,U1,V1);
-    Quad2.Parameters(ptf,U2,V2);
-    ptsol.SetValue(ptf,Tol,Standard_False);
-    ptsol.SetParameters(U1,V1,U2,V2);
-    ptsol.SetParameter(first);
-    if (ptf.Distance(ptl) <= Tol) {
-      ptsol.SetMultiple(Standard_True); // a voir
-      Multpoint = Standard_True;        // a voir de meme
-      alig->AddVertex(ptsol);
-      alig->SetFirstPoint(alig->NbVertex());
-      
-      ptsol.SetParameter(last);
-      alig->AddVertex(ptsol);
-      alig->SetLastPoint(alig->NbVertex());
-    }
-    else { 
-      alig->AddVertex(ptsol);
-      alig->SetFirstPoint(alig->NbVertex());
-      Quad1.Parameters(ptl,U1,V1);
-      Quad2.Parameters(ptl,U2,V2);
-      ptsol.SetValue(ptl,Tol,Standard_False);
-      ptsol.SetParameters(U1,V1,U2,V2);
-      ptsol.SetParameter(last);
-      alig->AddVertex(ptsol);
-      alig->SetLastPoint(alig->NbVertex());
-    }
-  }
-  else if (!procf) {
-    Quad1.Parameters(ptf,U1,V1);
-    Quad2.Parameters(ptf,U2,V2);
-    ptsol.SetValue(ptf,Tol,Standard_False);
-    ptsol.SetParameters(U1,V1,U2,V2);
-    ptsol.SetParameter(first);
-    alig->AddVertex(ptsol);
-    alig->SetFirstPoint(alig->NbVertex());
-  }
-  else if (!procl) {
-    Quad1.Parameters(ptl,U1,V1);
-    Quad2.Parameters(ptl,U2,V2);
-    ptsol.SetValue(ptl,Tol,Standard_False);
-    ptsol.SetParameters(U1,V1,U2,V2);
-    ptsol.SetParameter(last);
-    alig->AddVertex(ptsol);
-    alig->SetLastPoint(alig->NbVertex());
-  }
-}
-
-//=======================================================================
-//function : CyCyAnalyticalIntersect
-//purpose  : Checks if intersection curve is analytical (line, circle, ellipse)
-//            and returns these curves.
-//=======================================================================
-Standard_Boolean CyCyAnalyticalIntersect( const IntSurf_Quadric& Quad1,
-                                          const IntSurf_Quadric& Quad2,
-                                          const IntAna_QuadQuadGeo& theInter,
-                                          const Standard_Real Tol,
-                                          Standard_Boolean& Empty,
-                                          Standard_Boolean& Same,
-                                          Standard_Boolean& Multpoint,
-                                          IntPatch_SequenceOfLine& slin,
-                                          IntPatch_SequenceOfPoint& spnt)
-{
-  IntPatch_Point ptsol;
-  
-  Standard_Integer i;
-
-  IntSurf_TypeTrans trans1,trans2;
-  IntAna_ResultType typint;
-
-  gp_Elips elipsol;
-  gp_Lin linsol;
-
-  gp_Cylinder Cy1(Quad1.Cylinder());
-  gp_Cylinder Cy2(Quad2.Cylinder());
-
-  typint = theInter.TypeInter();
-  Standard_Integer NbSol = theInter.NbSolutions();
-  Empty = Standard_False;
-  Same  = Standard_False;
-
-  switch (typint)
-      {
-  case IntAna_Empty:
-    {
-      Empty = Standard_True;
-      }
-    break;
-
-  case IntAna_Same:
-      {
-      Same  = Standard_True;
-      }
-    break;
-
-  case IntAna_Point:
-    {
-      gp_Pnt psol(theInter.Point(1));
-      ptsol.SetValue(psol,Tol,Standard_True);
-
-      Standard_Real U1,V1,U2,V2;
-      Quad1.Parameters(psol, U1, V1);
-      Quad2.Parameters(psol, U2, V2);
-
-      ptsol.SetParameters(U1,V1,U2,V2);
-      spnt.Append(ptsol);
-    }
-    break;
-
-  case IntAna_Line:
-    {
-      gp_Pnt ptref;
-      if (NbSol == 1)
-      { // Cylinders are tangent to each other by line
-        linsol = theInter.Line(1);
-        ptref = linsol.Location();
-        
-        //Radius-vectors
-        gp_Dir crb1(gp_Vec(ptref,Cy1.Location()));
-        gp_Dir crb2(gp_Vec(ptref,Cy2.Location()));
-
-        //outer normal lines
-        gp_Vec norm1(Quad1.Normale(ptref));
-        gp_Vec norm2(Quad2.Normale(ptref));
-        IntSurf_Situation situcyl1;
-        IntSurf_Situation situcyl2;
-
-        if (crb1.Dot(crb2) < 0.)
-        { // centre de courbures "opposes"
-            //ATTENTION!!! 
-            //        Normal and Radius-vector of the 1st(!) cylinder
-            //        is used for judging what the situation of the 2nd(!)
-            //        cylinder is.
-
-          if (norm1.Dot(crb1) > 0.)
-          {
-            situcyl2 = IntSurf_Inside;
-          }
-          else
-          {
-            situcyl2 = IntSurf_Outside;
-          }
-
-          if (norm2.Dot(crb2) > 0.)
-          {
-            situcyl1 = IntSurf_Inside;
-          }
-          else
-          {
-            situcyl1 = IntSurf_Outside;
-          }
-        }
-        else
-          {
-          if (Cy1.Radius() < Cy2.Radius())
-          {
-            if (norm1.Dot(crb1) > 0.)
-            {
-              situcyl2 = IntSurf_Inside;
-            }
-            else
-            {
-              situcyl2 = IntSurf_Outside;
-            }
-
-            if (norm2.Dot(crb2) > 0.)
-            {
-              situcyl1 = IntSurf_Outside;
-            }
-            else
-            {
-              situcyl1 = IntSurf_Inside;
-            }
-          }
-          else
-          {
-            if (norm1.Dot(crb1) > 0.)
-            {
-              situcyl2 = IntSurf_Outside;
-            }
-            else
-            {
-              situcyl2 = IntSurf_Inside;
-            }
-
-            if (norm2.Dot(crb2) > 0.)
-            {
-              situcyl1 = IntSurf_Inside;
-            }
-            else
-            {
-              situcyl1 = IntSurf_Outside;
-            }
-          }
-        }
-
-        Handle(IntPatch_GLine) glig =  new IntPatch_GLine(linsol, Standard_True, situcyl1, situcyl2);
-        slin.Append(glig);
-      }
-      else
-      {
-        for (i=1; i <= NbSol; i++)
-        {
-          linsol = theInter.Line(i);
-          ptref = linsol.Location();
-          gp_Vec lsd = linsol.Direction();
-
-          //Theoretically, qwe = +/- 1.0.
-          Standard_Real qwe = lsd.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
-          if (qwe >0.00000001)
-          {
-            trans1 = IntSurf_Out;
-            trans2 = IntSurf_In;
-          }
-          else if (qwe <-0.00000001)
-          {
-            trans1 = IntSurf_In;
-            trans2 = IntSurf_Out;
-          }
-          else
-          {
-            trans1=trans2=IntSurf_Undecided;
-          }
-
-          Handle(IntPatch_GLine) glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
-          slin.Append(glig);
-        }
-      }
-    }
-    break;
-    
-  case IntAna_Ellipse:
-    {
-      gp_Vec Tgt;
-      gp_Pnt ptref;
-      IntPatch_Point pmult1, pmult2;
-
-      elipsol = theInter.Ellipse(1);
-
-      gp_Pnt pttang1(ElCLib::Value(0.5*M_PI, elipsol));
-      gp_Pnt pttang2(ElCLib::Value(1.5*M_PI, elipsol));
-
-      Multpoint = Standard_True;
-      pmult1.SetValue(pttang1,Tol,Standard_True);
-      pmult2.SetValue(pttang2,Tol,Standard_True);
-      pmult1.SetMultiple(Standard_True);
-      pmult2.SetMultiple(Standard_True);
-
-      Standard_Real oU1,oV1,oU2,oV2;
-      Quad1.Parameters(pttang1, oU1, oV1);
-      Quad2.Parameters(pttang1, oU2, oV2);
-
-      pmult1.SetParameters(oU1,oV1,oU2,oV2);
-      Quad1.Parameters(pttang2,oU1,oV1); 
-      Quad2.Parameters(pttang2,oU2,oV2);
-
-      pmult2.SetParameters(oU1,oV1,oU2,oV2);
-
-      // on traite la premiere ellipse
-        
-      //-- Calcul de la Transition de la ligne 
-      ElCLib::D1(0.,elipsol,ptref,Tgt);
-
-      //Theoretically, qwe = +/- |Tgt|.
-      Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
-      if (qwe>0.00000001)
-      {
-        trans1 = IntSurf_Out;
-        trans2 = IntSurf_In;
-      }
-      else if (qwe<-0.00000001)
-      {
-        trans1 = IntSurf_In;
-        trans2 = IntSurf_Out;
-      }
-      else
-      {
-        trans1=trans2=IntSurf_Undecided; 
-      }
-
-      //-- Transition calculee au point 0 -> Trans2 , Trans1 
-      //-- car ici, on devarit calculer en PI
-      Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol,Standard_False,trans2,trans1);
-      //
-      {
-        Standard_Real aU1, aV1, aU2, aV2;
-        IntPatch_Point aIP;
-        gp_Pnt aP (ElCLib::Value(0., elipsol));
-        //
-        aIP.SetValue(aP,Tol,Standard_False);
-        aIP.SetMultiple(Standard_False);
-        //
-        Quad1.Parameters(aP, aU1, aV1); 
-        Quad2.Parameters(aP, aU2, aV2);
-
-        aIP.SetParameters(aU1, aV1, aU2, aV2);
-        //
-        aIP.SetParameter(0.);
-        glig->AddVertex(aIP);
-        glig->SetFirstPoint(1);
-        //
-        aIP.SetParameter(2.*M_PI);
-        glig->AddVertex(aIP);
-        glig->SetLastPoint(2);
-      }
-      //
-      pmult1.SetParameter(0.5*M_PI);
-      glig->AddVertex(pmult1);
-      //
-      pmult2.SetParameter(1.5*M_PI);
-      glig->AddVertex(pmult2);
-     
-      //
-      slin.Append(glig);
-      
-      //-- Transitions calculee au point 0    OK
-      //
-      // on traite la deuxieme ellipse
-      elipsol = theInter.Ellipse(2);
-
-      Standard_Real param1 = ElCLib::Parameter(elipsol,pttang1);
-      Standard_Real param2 = ElCLib::Parameter(elipsol,pttang2);
-      Standard_Real parampourtransition = 0.0;
-      if (param1 < param2)
-      {
-        pmult1.SetParameter(0.5*M_PI);
-        pmult2.SetParameter(1.5*M_PI);
-        parampourtransition = M_PI;
-      }
-      else {
-        pmult1.SetParameter(1.5*M_PI);
-        pmult2.SetParameter(0.5*M_PI);
-        parampourtransition = 0.0;
-      }
-      
-      //-- Calcul des transitions de ligne pour la premiere ligne 
-      ElCLib::D1(parampourtransition,elipsol,ptref,Tgt);      
-
-      //Theoretically, qwe = +/- |Tgt|.
-      qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
-      if(qwe> 0.00000001)
-      {
-        trans1 = IntSurf_Out;
-        trans2 = IntSurf_In;
-      }
-      else if(qwe< -0.00000001)
-      {
-        trans1 = IntSurf_In;
-        trans2 = IntSurf_Out;
-      }
-      else
-      { 
-        trans1=trans2=IntSurf_Undecided;
-      }
-
-      //-- La transition a ete calculee sur un point de cette ligne 
-      glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2);
-      //
-      {
-        Standard_Real aU1, aV1, aU2, aV2;
-        IntPatch_Point aIP;
-        gp_Pnt aP (ElCLib::Value(0., elipsol));
-        //
-        aIP.SetValue(aP,Tol,Standard_False);
-        aIP.SetMultiple(Standard_False);
-        //
-
-        Quad1.Parameters(aP, aU1, aV1);
-        Quad2.Parameters(aP, aU2, aV2);
-
-        aIP.SetParameters(aU1, aV1, aU2, aV2);
-        //
-        aIP.SetParameter(0.);
-        glig->AddVertex(aIP);
-        glig->SetFirstPoint(1);
-        //
-        aIP.SetParameter(2.*M_PI);
-        glig->AddVertex(aIP);
-        glig->SetLastPoint(2);
-      }
-      //
-      glig->AddVertex(pmult1);
-      glig->AddVertex(pmult2);
-      //
-      slin.Append(glig);
-    }
-    break;
-
-  case IntAna_Parabola:
-  case IntAna_Hyperbola:
-    throw Standard_Failure("IntCyCy(): Wrong intersection type!");
-
-  case IntAna_Circle:
-    // Circle is useful when we will work with trimmed surfaces
-    // (two cylinders can be tangent by their basises, e.g. circle)
-  case IntAna_NoGeometricSolution:
-  default:
-    return Standard_False;
-  }
-
-  return Standard_True;
-}
-
-//=======================================================================
-//function : ShortCosForm
-//purpose  : Represents theCosFactor*cosA+theSinFactor*sinA as
-//            theCoeff*cos(A-theAngle) if it is possibly (all angles are
-//            in radians).
-//=======================================================================
-static void ShortCosForm( const Standard_Real theCosFactor,
-                          const Standard_Real theSinFactor,
-                          Standard_Real& theCoeff,
-                          Standard_Real& theAngle)
-{
-  theCoeff = sqrt(theCosFactor*theCosFactor+theSinFactor*theSinFactor);
-  theAngle = 0.0;
-  if(IsEqual(theCoeff, 0.0))
-  {
-    theAngle = 0.0;
-    return;
-  }
-
-  theAngle = acos(Abs(theCosFactor/theCoeff));
-
-  if(theSinFactor > 0.0)
-  {
-    if(IsEqual(theCosFactor, 0.0))
-    {
-      theAngle = M_PI/2.0;
-    }
-    else if(theCosFactor < 0.0)
-    {
-      theAngle = M_PI-theAngle;
-    }
-  }
-  else if(IsEqual(theSinFactor, 0.0))
-  {
-    if(theCosFactor < 0.0)
-    {
-      theAngle = M_PI;
-    }
-  }
-  if(theSinFactor < 0.0)
-  {
-    if(theCosFactor > 0.0)
-    {
-      theAngle = 2.0*M_PI-theAngle;
-    }
-    else if(IsEqual(theCosFactor, 0.0))
-    {
-      theAngle = 3.0*M_PI/2.0;
-    }
-    else if(theCosFactor < 0.0)
-    {
-      theAngle = M_PI+theAngle;
-    }
-  }
-}
-
-//=======================================================================
-//function : CylCylMonotonicity
-//purpose  : Determines, if U2(U1) function is increasing.
-//=======================================================================
-Standard_Boolean ComputationMethods::CylCylMonotonicity(const Standard_Real theU1par,
-                                                        const Standard_Integer theWLIndex,
-                                                        const stCoeffsValue& theCoeffs,
-                                                        const Standard_Real thePeriod,
-                                                        Standard_Boolean& theIsIncreasing)
-{
-  // U2(U1) = FI2 + (+/-)acos(B*cos(U1 - FI1) + C);
-  //Accordingly,
-  //Func. U2(X1) = FI2 + X1;
-  //Func. X1(X2) = anArccosFactor*X2;
-  //Func. X2(X3) = acos(X3);
-  //Func. X3(X4) = B*X4 + C;
-  //Func. X4(U1) = cos(U1 - FI1).
-  //
-  //Consequently,
-  //U2(X1) is always increasing.
-  //X1(X2) is increasing if anArccosFactor > 0.0 and
-  //is decreasing otherwise.
-  //X2(X3) is always decreasing.
-  //Therefore, U2(X3) is decreasing if anArccosFactor > 0.0 and
-  //is increasing otherwise.
-  //X3(X4) is increasing if B > 0 and is decreasing otherwise.
-  //X4(U1) is increasing if U1 - FI1 in [PI, 2*PI) and
-  //is decreasing U1 - FI1 in [0, PI) or if (U1 - FI1 == 2PI).
-  //After that, we can predict behaviour of U2(U1) function:
-  //if it is increasing or decreasing.
-
-  //For "+/-" sign. If isPlus == TRUE, "+" is chosen, otherwise, we choose "-".
-  Standard_Boolean isPlus = Standard_False;
-
-  switch(theWLIndex)
-  {
-  case 0: 
-    isPlus = Standard_True;
-    break;
-  case 1:
-    isPlus = Standard_False;
-    break;
-  default:
-    //throw Standard_Failure("Error. Range Error!!!!");
-    return Standard_False;
-  }
-
-  Standard_Real aU1Temp = theU1par - theCoeffs.mFI1;
-  InscribePoint(0, thePeriod, aU1Temp, 0.0, thePeriod, Standard_False);
-
-  theIsIncreasing = Standard_True;
-
-  if(((M_PI - aU1Temp) < RealSmall()) && (aU1Temp < thePeriod))
-  {
-    theIsIncreasing = Standard_False;
-  }
-
-  if(theCoeffs.mB < 0.0)
-  {
-    theIsIncreasing = !theIsIncreasing;
-  }
-
-  if(!isPlus)
-  {
-    theIsIncreasing = !theIsIncreasing;
-  }  
-
-  return Standard_True;
-}
-
-//=======================================================================
-//function : CylCylComputeParameters
-//purpose  : Computes U2 (U-parameter of the 2nd cylinder) and, if theDelta != 0,
-//            estimates the tolerance of U2-computing (estimation result is
-//            assigned to *theDelta value).
-//=======================================================================
-Standard_Boolean ComputationMethods::CylCylComputeParameters(const Standard_Real theU1par,
-                                                const Standard_Integer theWLIndex,
-                                                const stCoeffsValue& theCoeffs,
-                                                Standard_Real& theU2,
-                                                Standard_Real* const theDelta)
-{
-  //This formula is got from some experience and can be changed.
-  const Standard_Real aTol0 = Min(10.0*Epsilon(1.0)*theCoeffs.mB, aNulValue);
-  const Standard_Real aTol = 1.0 - aTol0;
-
-  if(theWLIndex < 0 || theWLIndex > 1)
-    return Standard_False;
-
-  const Standard_Real aSign = theWLIndex ? -1.0 : 1.0;
-
-  Standard_Real anArg = cos(theU1par - theCoeffs.mFI1);
-  anArg = theCoeffs.mB*anArg + theCoeffs.mC;
-
-  if(anArg >= aTol)
-  {
-    if(theDelta)
-      *theDelta = 0.0;
-
-    anArg = 1.0;
-  }
-  else if(anArg <= -aTol)
-  {
-    if(theDelta)
-      *theDelta = 0.0;
-
-    anArg = -1.0;
-  }
-  else if(theDelta)
-  {
-    //There is a case, when
-    //  const double aPar = 0.99999999999721167;
-    //  const double aFI2 = 2.3593296083566181e-006;
-
-    //Then
-    //  aPar - cos(aFI2) == -5.10703e-015 ==> cos(aFI2) == aPar. 
-    //Theoretically, in this case
-    //  aFI2 == +/- acos(aPar).
-    //However,
-    //  acos(aPar) - aFI2 == 2.16362e-009.
-    //Error is quite big.
-
-    //This error should be estimated. Let use following way, which is based
-    //on expanding to Taylor series.
-
-    //  acos(p)-acos(p+x) = x/sqrt(1-p*p).
-
-    //If p == (1-d) (when p > 0) or p == (-1+d) (when p < 0) then
-    //  acos(p)-acos(p+x) = x/sqrt(d*(2-d)).
-
-    //Here always aTol0 <= d <= 1. Max(x) is considered (!) to be equal to aTol0.
-    //In this case
-    //  8*aTol0 <= acos(p)-acos(p+x) <= sqrt(2/(2-aTol0)-1),
-    //                                              because 0 < aTol0 < 1.
-    //E.g. when aTol0 = 1.0e-11,
-    //   8.0e-11 <= acos(p)-acos(p+x) < 2.24e-6.
-
-    const Standard_Real aDelta = Min(1.0-anArg, 1.0+anArg);
-    Standard_DivideByZero_Raise_if((aDelta*aDelta < RealSmall()) || (aDelta >= 2.0), 
-          "IntPatch_ImpImpIntersection_4.gxx, CylCylComputeParameters()");
-    *theDelta = aTol0/sqrt(aDelta*(2.0-aDelta));
-  }
-
-  theU2 = acos(anArg);
-  theU2 = theCoeffs.mFI2 + aSign*theU2;
-
-  return Standard_True;
-}
-
-//=======================================================================
-//function : CylCylComputeParameters
-//purpose  : Computes V1 and V2 (V-parameters of the 1st and 2nd cylinder respectively).
-//=======================================================================
-Standard_Boolean ComputationMethods::CylCylComputeParameters(const Standard_Real theU1,
-                                                const Standard_Real theU2,
-                                                const stCoeffsValue& theCoeffs,
-                                                Standard_Real& theV1,
-                                                Standard_Real& theV2)
-{
-  theV1 = theCoeffs.mK21 * sin(theU2) + 
-          theCoeffs.mK11 * sin(theU1) +
-          theCoeffs.mL21 * cos(theU2) +
-          theCoeffs.mL11 * cos(theU1) + theCoeffs.mM1;
-
-  theV2 = theCoeffs.mK22 * sin(theU2) +
-          theCoeffs.mK12 * sin(theU1) +
-          theCoeffs.mL22 * cos(theU2) +
-          theCoeffs.mL12 * cos(theU1) + theCoeffs.mM2;
-
-  return Standard_True;
-}
-
-//=======================================================================
-//function : CylCylComputeParameters
-//purpose  : Computes U2 (U-parameter of the 2nd cylinder),
-//            V1 and V2 (V-parameters of the 1st and 2nd cylinder respectively).
-//=======================================================================
-Standard_Boolean ComputationMethods::CylCylComputeParameters(const Standard_Real theU1par,
-                                                const Standard_Integer theWLIndex,
-                                                const stCoeffsValue& theCoeffs,
-                                                Standard_Real& theU2,
-                                                Standard_Real& theV1,
-                                                Standard_Real& theV2)
-{
-  if(!CylCylComputeParameters(theU1par, theWLIndex, theCoeffs, theU2))
-    return Standard_False;
-
-  if(!CylCylComputeParameters(theU1par, theU2, theCoeffs, theV1, theV2))
-    return Standard_False;
-
-  return Standard_True;
-}
-
-//=======================================================================
-//function : SearchOnVBounds
-//purpose  : 
-//=======================================================================
-Standard_Boolean WorkWithBoundaries::
-                        SearchOnVBounds(const SearchBoundType theSBType,
-                                        const Standard_Real theVzad,
-                                        const Standard_Real theVInit,
-                                        const Standard_Real theInitU2,
-                                        const Standard_Real theInitMainVar,
-                                        Standard_Real& theMainVariableValue) const
-{
-  const Standard_Integer aNbDim = 3;
-  const Standard_Real aMaxError = 4.0*M_PI; // two periods
-  
-  theMainVariableValue = theInitMainVar;
-  const Standard_Real aTol2 = 1.0e-18;
-  Standard_Real aMainVarPrev = theInitMainVar, aU2Prev = theInitU2, anOtherVar = theVInit;
-  
-  //Structure of aMatr:
-  //  C_{1}*U_{1} & C_{2}*U_{2} & C_{3}*V_{*},
-  //where C_{1}, C_{2} and C_{3} are math_Vector.
-  math_Matrix aMatr(1, aNbDim, 1, aNbDim);
-
-  Standard_Real anError = RealLast();
-  Standard_Real anErrorPrev = anError;
-  Standard_Integer aNbIter = 0;
-  do
-  {
-    if(++aNbIter > 1000)
-      return Standard_False;
-
-    const Standard_Real aSinU1 = sin(aMainVarPrev),
-                        aCosU1 = cos(aMainVarPrev),
-                        aSinU2 = sin(aU2Prev),
-                        aCosU2 = cos(aU2Prev);
-
-    math_Vector aVecFreeMem = (myCoeffs.mVecA2 * aU2Prev +
-                                              myCoeffs.mVecB2) * aSinU2 -
-                              (myCoeffs.mVecB2 * aU2Prev -
-                                              myCoeffs.mVecA2) * aCosU2 +
-                              (myCoeffs.mVecA1 * aMainVarPrev +
-                                              myCoeffs.mVecB1) * aSinU1 -
-                              (myCoeffs.mVecB1 * aMainVarPrev -
-                                              myCoeffs.mVecA1) * aCosU1 +
-                                                            myCoeffs.mVecD;
-
-    math_Vector aMSum(1, 3);
-
-    switch(theSBType)
-    {
-    case SearchV1:
-      aMatr.SetCol(3, myCoeffs.mVecC2);
-      aMSum = myCoeffs.mVecC1 * theVzad;
-      aVecFreeMem -= aMSum;
-      aMSum += myCoeffs.mVecC2*anOtherVar;
-      break;
-
-    case SearchV2:
-      aMatr.SetCol(3, myCoeffs.mVecC1);
-      aMSum = myCoeffs.mVecC2 * theVzad;
-      aVecFreeMem -= aMSum;
-      aMSum += myCoeffs.mVecC1*anOtherVar;
-      break;
-
-    default:
-      return Standard_False;
-    }
-
-    aMatr.SetCol(1, myCoeffs.mVecA1 * aSinU1 - myCoeffs.mVecB1 * aCosU1);
-    aMatr.SetCol(2, myCoeffs.mVecA2 * aSinU2 - myCoeffs.mVecB2 * aCosU2);
-
-    Standard_Real aDetMainSyst = aMatr.Determinant();
-
-    if(Abs(aDetMainSyst) < aNulValue)
-    {
-      return Standard_False;
-    }
-
-    math_Matrix aM1(aMatr), aM2(aMatr), aM3(aMatr);
-    aM1.SetCol(1, aVecFreeMem);
-    aM2.SetCol(2, aVecFreeMem);
-    aM3.SetCol(3, aVecFreeMem);
-
-    const Standard_Real aDetMainVar = aM1.Determinant();
-    const Standard_Real aDetVar1    = aM2.Determinant();
-    const Standard_Real aDetVar2    = aM3.Determinant();
-
-    Standard_Real aDelta = aDetMainVar/aDetMainSyst-aMainVarPrev;
-
-    if(Abs(aDelta) > aMaxError)
-      return Standard_False;
-
-    anError = aDelta*aDelta;
-    aMainVarPrev += aDelta;
-        
-    ///
-    aDelta = aDetVar1/aDetMainSyst-aU2Prev;
-
-    if(Abs(aDelta) > aMaxError)
-      return Standard_False;
-
-    anError += aDelta*aDelta;
-    aU2Prev += aDelta;
-
-    ///
-    aDelta = aDetVar2/aDetMainSyst-anOtherVar;
-    anError += aDelta*aDelta;
-    anOtherVar += aDelta;
-
-    if(anError > anErrorPrev)
-    {//Method diverges. Keep the best result
-      const Standard_Real aSinU1Last = sin(aMainVarPrev),
-                          aCosU1Last = cos(aMainVarPrev),
-                          aSinU2Last = sin(aU2Prev),
-                          aCosU2Last = cos(aU2Prev);
-      aMSum -= (myCoeffs.mVecA1*aCosU1Last + 
-                myCoeffs.mVecB1*aSinU1Last +
-                myCoeffs.mVecA2*aCosU2Last +
-                myCoeffs.mVecB2*aSinU2Last +
-                myCoeffs.mVecD);
-      const Standard_Real aSQNorm = aMSum.Norm2();
-      return (aSQNorm < aTol2);
-    }
-    else
-    {
-      theMainVariableValue = aMainVarPrev;
-    }
-
-    anErrorPrev = anError;
-  }
-  while(anError > aTol2);
-
-  theMainVariableValue = aMainVarPrev;
-
-  return Standard_True;
-}
-
-//=======================================================================
-//function : InscribePoint
-//purpose  : If theFlForce==TRUE theUGiven will be changed forcefully
-//            even if theUGiven is already inscibed in the boundary
-//            (if it is possible; i.e. if new theUGiven is inscribed
-//            in the boundary, too).
-//=======================================================================
-Standard_Boolean InscribePoint( const Standard_Real theUfTarget,
-                                const Standard_Real theUlTarget,
-                                Standard_Real& theUGiven,
-                                const Standard_Real theTol2D,
-                                const Standard_Real thePeriod,
-                                const Standard_Boolean theFlForce)
-{
-  if(Precision::IsInfinite(theUGiven))
-  {
-    return Standard_False;
-  }
-
-  if((theUfTarget - theUGiven <= theTol2D) &&
-              (theUGiven - theUlTarget <= theTol2D))
-  {//it has already inscribed
-
-    /*
-             Utf    U      Utl
-              +     *       +
-    */
-    
-    if(theFlForce)
-    {
-      Standard_Real anUtemp = theUGiven + thePeriod;
-      if((theUfTarget - anUtemp <= theTol2D) &&
-                (anUtemp - theUlTarget <= theTol2D))
-      {
-        theUGiven = anUtemp;
-        return Standard_True;
-      }
-      
-      anUtemp = theUGiven - thePeriod;
-      if((theUfTarget - anUtemp <= theTol2D) &&
-                (anUtemp - theUlTarget <= theTol2D))
-      {
-        theUGiven = anUtemp;
-      }
-    }
-
-    return Standard_True;
-  }
-
-  const Standard_Real aUf = theUfTarget - theTol2D;
-  const Standard_Real aUl = aUf + thePeriod;
-
-  theUGiven = ElCLib::InPeriod(theUGiven, aUf, aUl);
-  
-  return ((theUfTarget - theUGiven <= theTol2D) &&
-          (theUGiven - theUlTarget <= theTol2D));
-}
-
-//=======================================================================
-//function : InscribeInterval
-//purpose  : Shifts theRange in order to make at least one of its 
-//            boundary in the range [theUfTarget, theUlTarget]
-//=======================================================================
-static Standard_Boolean InscribeInterval(const Standard_Real theUfTarget,
-                                         const Standard_Real theUlTarget,
-                                         Bnd_Range &theRange,
-                                         const Standard_Real theTol2D,
-                                         const Standard_Real thePeriod)
-{
-  Standard_Real anUpar = 0.0;
-  if (!theRange.GetMin(anUpar))
-  {
-    return Standard_False;
-  }
-
-  const Standard_Real aDelta = theRange.Delta();
-  if(InscribePoint(theUfTarget, theUlTarget, anUpar, 
-          theTol2D, thePeriod, (Abs(theUlTarget-anUpar) < theTol2D)))
-  {
-    theRange.SetVoid();
-    theRange.Add(anUpar);
-    theRange.Add(anUpar + aDelta);
-  }
-  else 
-  {
-    if (!theRange.GetMax (anUpar))
-    {
-      return Standard_False;
-    }
-
-    if(InscribePoint(theUfTarget, theUlTarget, anUpar,
-          theTol2D, thePeriod, (Abs(theUfTarget-anUpar) < theTol2D)))
-    {
-      theRange.SetVoid();
-      theRange.Add(anUpar);
-      theRange.Add(anUpar - aDelta);
-    }
-    else
-    {
-      return Standard_False;
-    }
-  }
-
-  return Standard_True;
-}
-
-//=======================================================================
-//function : ExcludeNearElements
-//purpose  : Checks if theArr contains two almost equal elements.
-//            If it is true then one of equal elements will be excluded
-//            (made infinite).
-//           Returns TRUE if at least one element of theArr has been changed.
-//ATTENTION!!!
-//           1. Every not infinite element of theArr is considered to be 
-//            in [0, T] interval (where T is the period);
-//           2. theArr must be sorted in ascending order.
-//=======================================================================
-static Standard_Boolean ExcludeNearElements(Standard_Real theArr[],
-                                            const Standard_Integer theNOfMembers,
-                                            const Standard_Real theUSurf1f,
-                                            const Standard_Real theUSurf1l,
-                                            const Standard_Real theTol)
-{
-  Standard_Boolean aRetVal = Standard_False;
-  for(Standard_Integer i = 1; i < theNOfMembers; i++)
-  {
-    Standard_Real &anA = theArr[i],
-                  &anB = theArr[i-1];
-
-    //Here, anA >= anB
-
-    if(Precision::IsInfinite(anA))
-      break;
-
-    if((anA-anB) < theTol)
-    {
-      if((anB != 0.0) && (anB != theUSurf1f) && (anB != theUSurf1l)) 
-      anA = (anA + anB)/2.0;
-      else
-        anA = anB;
-
-      //Make this element infinite an forget it
-      //(we will not use it in next iterations).
-      anB = Precision::Infinite();
-      aRetVal = Standard_True;
-    }
-  }
-
-  return aRetVal;
-}
-
-//=======================================================================
-//function : AddPointIntoWL
-//purpose  : Surf1 is a surface, whose U-par is variable.
-//           If theFlBefore == TRUE then we enable the U1-parameter
-//            of the added point to be less than U1-parameter of
-//           previously added point (in general U1-parameter is
-//           always increased; therefore, this situation is abnormal).
-//           If theOnlyCheck==TRUE then no point will be added to theLine.
-//=======================================================================
-static Standard_Boolean AddPointIntoWL( const IntSurf_Quadric& theQuad1,
-                                        const IntSurf_Quadric& theQuad2,
-                                        const ComputationMethods::stCoeffsValue& theCoeffs,
-                                        const Standard_Boolean isTheReverse,
-                                        const Standard_Boolean isThePrecise,
-                                        const gp_Pnt2d& thePntOnSurf1,
-                                        const gp_Pnt2d& thePntOnSurf2,
-                                        const Standard_Real theUfSurf1,
-                                        const Standard_Real theUlSurf1,
-                                        const Standard_Real theUfSurf2,
-                                        const Standard_Real theUlSurf2,
-                                        const Standard_Real theVfSurf1,
-                                        const Standard_Real theVlSurf1,
-                                        const Standard_Real theVfSurf2,
-                                        const Standard_Real theVlSurf2,
-                                        const Standard_Real thePeriodOfSurf1,
-                                        const Handle(IntSurf_LineOn2S)& theLine,
-                                        const Standard_Integer theWLIndex,
-                                        const Standard_Real theTol3D,
-                                        const Standard_Real theTol2D,
-                                        const Standard_Boolean theFlBefore = Standard_False,
-                                        const Standard_Boolean theOnlyCheck = Standard_False)
-{
-  //Check if the point is in the domain or can be inscribed in the domain after adjusting.
-  
-  gp_Pnt  aPt1(theQuad1.Value(thePntOnSurf1.X(), thePntOnSurf1.Y())),
-          aPt2(theQuad2.Value(thePntOnSurf2.X(), thePntOnSurf2.Y()));
-
-  Standard_Real aU1par = thePntOnSurf1.X();
-
-  // aU1par always increases. Therefore, we must reduce its
-  // value in order to continue creation of WLine.
-  if(!InscribePoint(theUfSurf1, theUlSurf1, aU1par, theTol2D,
-                  thePeriodOfSurf1, aU1par > 0.5*(theUfSurf1+theUlSurf1)))
-    return Standard_False;
-
-  if ((theLine->NbPoints() > 0) &&
-      ((theUlSurf1 - theUfSurf1) >= (thePeriodOfSurf1 - theTol2D)) &&      
-      (((aU1par + thePeriodOfSurf1 - theUlSurf1) <= theTol2D) ||
-       ((aU1par - thePeriodOfSurf1 - theUfSurf1) >= theTol2D)))
-  {
-    // aU1par can be adjusted to both theUlSurf1 and theUfSurf1
-    // with equal possibilities. This code fragment allows choosing
-    // correct parameter from these two variants.
-
-    Standard_Real aU1 = 0.0, aV1 = 0.0;
-    if (isTheReverse)
-    {
-      theLine->Value(theLine->NbPoints()).ParametersOnS2(aU1, aV1);
-    }
-    else
-    {
-      theLine->Value(theLine->NbPoints()).ParametersOnS1(aU1, aV1);
-    }
-
-    const Standard_Real aDelta = aU1 - aU1par;
-    if (2.0*Abs(aDelta) > thePeriodOfSurf1)
-    {
-      aU1par += Sign(thePeriodOfSurf1, aDelta);
-    }
-  }
-
-  Standard_Real aU2par = thePntOnSurf2.X();
-  if(!InscribePoint(theUfSurf2, theUlSurf2, aU2par, theTol2D,
-                                    thePeriodOfSurf1, Standard_False))
-    return Standard_False;
-
-  Standard_Real aV1par = thePntOnSurf1.Y();
-  if((aV1par - theVlSurf1 > theTol2D) || (theVfSurf1 - aV1par > theTol2D))
-    return Standard_False;
-
-  Standard_Real aV2par = thePntOnSurf2.Y();
-  if((aV2par -  theVlSurf2 > theTol2D) || (theVfSurf2 - aV2par > theTol2D))
-    return Standard_False;
-  
-  //Get intersection point and add it in the WL
-  IntSurf_PntOn2S aPnt;
-  
-  if(isTheReverse)
-  {
-    aPnt.SetValue((aPt1.XYZ()+aPt2.XYZ())/2.0,
-                        aU2par, aV2par,
-                        aU1par, aV1par);
-  }
-  else
-  {
-    aPnt.SetValue((aPt1.XYZ()+aPt2.XYZ())/2.0,
-                        aU1par, aV1par,
-                        aU2par, aV2par);
-  }
-
-  Standard_Integer aNbPnts = theLine->NbPoints();
-  if(aNbPnts > 0)
-  {
-    Standard_Real aUl = 0.0, aVl = 0.0;
-    const IntSurf_PntOn2S aPlast = theLine->Value(aNbPnts);
-    if(isTheReverse)
-      aPlast.ParametersOnS2(aUl, aVl);
-    else
-      aPlast.ParametersOnS1(aUl, aVl);
-
-    if(!theFlBefore && (aU1par <= aUl))
-    {
-      //Parameter value must be increased if theFlBefore == FALSE.
-
-      aU1par += thePeriodOfSurf1;
-
-      //The condition is as same as in
-      //InscribePoint(...) function
-      if((theUfSurf1 - aU1par > theTol2D) ||
-         (aU1par - theUlSurf1 > theTol2D))
-      {
-        //New aU1par is out of target interval.
-        //Go back to old value.
-
-        return Standard_False;
-      }
-    }
-
-    if (theOnlyCheck)
-      return Standard_True;
-
-    //theTol2D is minimal step along parameter changed. 
-    //Therefore, if we apply this minimal step two 
-    //neighbour points will be always "same". Consequently,
-    //we should reduce tolerance for IsSame checking.
-    const Standard_Real aDTol = 1.0-Epsilon(1.0);
-    if(aPnt.IsSame(aPlast, theTol3D*aDTol, theTol2D*aDTol))
-    {
-      theLine->RemovePoint(aNbPnts);
-    }
-  }
-
-  if (theOnlyCheck)
-    return Standard_True;
-
-  theLine->Add(aPnt);
-
-  if(!isThePrecise)
-    return Standard_True;
-
-  //Try to precise existing WLine
-  aNbPnts = theLine->NbPoints();
-  if(aNbPnts >= 3)
-  {
-    Standard_Real aU1 = 0.0, aU2 = 0.0, aU3 = 0.0, aV = 0.0;
-    if(isTheReverse)
-    {
-      theLine->Value(aNbPnts).ParametersOnS2(aU3, aV);
-      theLine->Value(aNbPnts-1).ParametersOnS2(aU2, aV);
-      theLine->Value(aNbPnts-2).ParametersOnS2(aU1, aV);
-    }
-    else
-    {
-      theLine->Value(aNbPnts).ParametersOnS1(aU3, aV);
-      theLine->Value(aNbPnts-1).ParametersOnS1(aU2, aV);
-      theLine->Value(aNbPnts-2).ParametersOnS1(aU1, aV);
-    }
-
-    const Standard_Real aStepPrev = aU2-aU1;
-    const Standard_Real aStep = aU3-aU2;
-
-    const Standard_Integer aDeltaStep = RealToInt(aStepPrev/aStep);
-
-    if((1 < aDeltaStep) && (aDeltaStep < 2000))
-    {
-      //Add new points in case of non-uniform distribution of existing points
-      SeekAdditionalPoints( theQuad1, theQuad2, theLine, 
-                            theCoeffs, theWLIndex, aDeltaStep, aNbPnts-2,
-                            aNbPnts-1, theTol2D, thePeriodOfSurf1, isTheReverse);
-    }
-  }
-
-  return Standard_True;
-}
-
-//=======================================================================
-//function : AddBoundaryPoint
-//purpose  : Find intersection point on V-boundary.
-//=======================================================================
-void WorkWithBoundaries::AddBoundaryPoint(const Handle(IntPatch_WLine)& theWL,
-                                          const Standard_Real theU1,
-                                          const Standard_Real theU1Min,
-                                          const Standard_Real theU2,
-                                          const Standard_Real theV1,
-                                          const Standard_Real theV1Prev,
-                                          const Standard_Real theV2,
-                                          const Standard_Real theV2Prev,
-                                          const Standard_Integer theWLIndex,
-                                          const Standard_Boolean theFlForce,
-                                          Standard_Boolean& isTheFound1,
-                                          Standard_Boolean& isTheFound2) const
-{
-  Standard_Real aUSurf1f = 0.0, //const
-                aUSurf1l = 0.0,
-                aVSurf1f = 0.0,
-                aVSurf1l = 0.0;
-  Standard_Real aUSurf2f = 0.0, //const
-                aUSurf2l = 0.0,
-                aVSurf2f = 0.0,
-                aVSurf2l = 0.0;
-
-  myUVSurf1.Get(aUSurf1f, aVSurf1f, aUSurf1l, aVSurf1l);
-  myUVSurf2.Get(aUSurf2f, aVSurf2f, aUSurf2l, aVSurf2l);
-  
-  const Standard_Integer aSize = 4;
-  const Standard_Real anArrVzad[aSize] = {aVSurf1f, aVSurf1l, aVSurf2f, aVSurf2l};
-
-  StPInfo aUVPoint[aSize];
-
-  for(Standard_Integer anIDSurf = 0; anIDSurf < 4; anIDSurf+=2)
-  {
-    const Standard_Real aVf = (anIDSurf == 0) ? theV1 : theV2,
-                        aVl = (anIDSurf == 0) ? theV1Prev : theV2Prev;
-
-    const SearchBoundType aTS = (anIDSurf == 0) ? SearchV1 : SearchV2;
-
-    for(Standard_Integer anIDBound = 0; anIDBound < 2; anIDBound++)
-    {
-      const Standard_Integer anIndex = anIDSurf+anIDBound;
-
-      aUVPoint[anIndex].mySurfID = anIDSurf;
-
-      if((Abs(aVf-anArrVzad[anIndex]) > myTol2D) &&
-          ((aVf-anArrVzad[anIndex])*(aVl-anArrVzad[anIndex]) > 0.0))
-      {
-        continue;
-      }
-
-      //Segment [aVf, aVl] intersects at least one V-boundary (first or last)
-      // (in general, case is possible, when aVf > aVl).
-
-      // Precise intersection point
-      const Standard_Boolean aRes = SearchOnVBounds(aTS, anArrVzad[anIndex],
-                                                    (anIDSurf == 0) ? theV2 : theV1,
-                                                    theU2, theU1,
-                                                    aUVPoint[anIndex].myU1);
-
-      // aUVPoint[anIndex].myU1 is considered to be nearer to theU1 than
-      // to theU1+/-Period
-      if (!aRes || (aUVPoint[anIndex].myU1 >= theU1) ||
-                              (aUVPoint[anIndex].myU1 < theU1Min))
-      {
-        //Intersection point is not found or out of the domain
-        aUVPoint[anIndex].myU1 = RealLast();
-        continue;
-      }
-      else
-      {
-        //intersection point is found
-
-        Standard_Real &aU1 = aUVPoint[anIndex].myU1,
-                      &aU2 = aUVPoint[anIndex].myU2,
-                      &aV1 = aUVPoint[anIndex].myV1,
-                      &aV2 = aUVPoint[anIndex].myV2;
-        aU2 = theU2;
-        aV1 = theV1;
-        aV2 = theV2;
-
-        if(!ComputationMethods::
-                  CylCylComputeParameters(aU1, theWLIndex, myCoeffs, aU2, aV1, aV2))
-        {
-          // Found point is wrong
-          aU1 = RealLast();
-          continue;
-        }
-
-        //Point on true V-boundary.
-        if(aTS == SearchV1)
-          aV1 = anArrVzad[anIndex];
-        else //if(aTS[anIndex] == SearchV2)
-          aV2 = anArrVzad[anIndex];
-      }
-    }
-  }
-
-  // Sort with acceding U1-parameter.
-  std::sort(aUVPoint, aUVPoint+aSize);
-    
-  isTheFound1 = isTheFound2 = Standard_False;
-
-  //Adding found points on boundary in the WLine.
-  for(Standard_Integer i = 0; i < aSize; i++)
-  {
-    if(aUVPoint[i].myU1 == RealLast())
-      break;
-
-    if(!AddPointIntoWL(myQuad1, myQuad2, myCoeffs, myIsReverse, Standard_False,
-                        gp_Pnt2d(aUVPoint[i].myU1, aUVPoint[i].myV1),
-                        gp_Pnt2d(aUVPoint[i].myU2, aUVPoint[i].myV2),
-                        aUSurf1f, aUSurf1l, aUSurf2f, aUSurf2l,
-                        aVSurf1f, aVSurf1l, aVSurf2f, aVSurf2l, myPeriod,
-                        theWL->Curve(), theWLIndex, myTol3D, myTol2D, theFlForce))
-    {
-      continue;
-    }
-
-    if(aUVPoint[i].mySurfID == 0)
-    {
-      isTheFound1 = Standard_True;
-    }
-    else
-    {
-      isTheFound2 = Standard_True;
-    }
-  }
-}
-
-//=======================================================================
-//function : SeekAdditionalPoints
-//purpose  : Inserts additional intersection points between neighbor points.
-//            This action is bone with several iterations. During every iteration,
-//          new point is inserted in middle of every interval.
-//            The process will be finished if NbPoints >= theMinNbPoints.
-//=======================================================================
-static void SeekAdditionalPoints( const IntSurf_Quadric& theQuad1,
-                                  const IntSurf_Quadric& theQuad2,
-                                  const Handle(IntSurf_LineOn2S)& theLine,
-                                  const ComputationMethods::stCoeffsValue& theCoeffs,
-                                  const Standard_Integer theWLIndex,
-                                  const Standard_Integer theMinNbPoints,
-                                  const Standard_Integer theStartPointOnLine,
-                                  const Standard_Integer theEndPointOnLine,
-                                  const Standard_Real theTol2D,
-                                  const Standard_Real thePeriodOfSurf2,
-                                  const Standard_Boolean isTheReverse)
-{
-  if(theLine.IsNull())
-    return;
-  
-  Standard_Integer aNbPoints = theEndPointOnLine - theStartPointOnLine + 1;
-
-  Standard_Real aMinDeltaParam = theTol2D;
-
-  {
-    Standard_Real u1 = 0.0, v1 = 0.0, u2 = 0.0, v2 = 0.0;
-
-    if(isTheReverse)
-    {
-      theLine->Value(theStartPointOnLine).ParametersOnS2(u1, v1);
-      theLine->Value(theEndPointOnLine).ParametersOnS2(u2, v2);
-    }
-    else
-    {
-      theLine->Value(theStartPointOnLine).ParametersOnS1(u1, v1);
-      theLine->Value(theEndPointOnLine).ParametersOnS1(u2, v2);
-    }
-    
-    aMinDeltaParam = Max(Abs(u2 - u1)/IntToReal(theMinNbPoints), aMinDeltaParam);
-  }
-
-  Standard_Integer aLastPointIndex = theEndPointOnLine;
-  Standard_Real U1prec = 0.0, V1prec = 0.0, U2prec = 0.0, V2prec = 0.0;
-
-  Standard_Integer aNbPointsPrev = 0;
-  do
-  {
-    aNbPointsPrev = aNbPoints;
-    for(Standard_Integer fp = theStartPointOnLine, lp = 0; fp < aLastPointIndex; fp = lp + 1)
-    {
-      Standard_Real U1f = 0.0, V1f = 0.0; //first point in 1st suraface
-      Standard_Real U1l = 0.0, V1l = 0.0; //last  point in 1st suraface
-
-      Standard_Real U2f = 0.0, V2f = 0.0; //first point in 2nd suraface
-      Standard_Real U2l = 0.0, V2l = 0.0; //last  point in 2nd suraface
-
-      lp = fp+1;
-      
-      if(isTheReverse)
-      {
-        theLine->Value(fp).ParametersOnS2(U1f, V1f);
-        theLine->Value(lp).ParametersOnS2(U1l, V1l);
-
-        theLine->Value(fp).ParametersOnS1(U2f, V2f);
-        theLine->Value(lp).ParametersOnS1(U2l, V2l);
-      }
-      else
-      {
-        theLine->Value(fp).ParametersOnS1(U1f, V1f);
-        theLine->Value(lp).ParametersOnS1(U1l, V1l);
-
-        theLine->Value(fp).ParametersOnS2(U2f, V2f);
-        theLine->Value(lp).ParametersOnS2(U2l, V2l);
-      }
-
-      if(Abs(U1l - U1f) <= aMinDeltaParam)
-      {
-        //Step is minimal. It is not necessary to divide it.
-        continue;
-      }
-
-      U1prec = 0.5*(U1f+U1l);
-      
-      if(!ComputationMethods::
-            CylCylComputeParameters(U1prec, theWLIndex, theCoeffs, U2prec, V1prec, V2prec))
-      {
-        continue;
-      }
-
-      MinMax(U2f, U2l);
-      if(!InscribePoint(U2f, U2l, U2prec, theTol2D, thePeriodOfSurf2, Standard_False))
-      {
-        continue;
-      }
-
-      const gp_Pnt aP1(theQuad1.Value(U1prec, V1prec)), aP2(theQuad2.Value(U2prec, V2prec));
-      const gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
-
-#ifdef INTPATCH_IMPIMPINTERSECTION_DEBUG
-      std::cout << "|P1Pi| = " << aP1.SquareDistance(aPInt) << "; |P2Pi| = " << aP2.SquareDistance(aPInt) << std::endl;
-#endif
-
-      IntSurf_PntOn2S anIP;
-      if(isTheReverse)
-      {
-        anIP.SetValue(aPInt, U2prec, V2prec, U1prec, V1prec);
-      }
-      else
-      {
-        anIP.SetValue(aPInt, U1prec, V1prec, U2prec, V2prec);
-      }
-
-      theLine->InsertBefore(lp, anIP);
-
-      aNbPoints++;
-      aLastPointIndex++;
-    }
-
-    if(aNbPoints >= theMinNbPoints)
-    {
-      return;
-    }
-  } while(aNbPoints < theMinNbPoints && (aNbPoints != aNbPointsPrev));
-}
-
-//=======================================================================
-//function : BoundariesComputing
-//purpose  : Computes true domain of future intersection curve (allows
-//            avoiding excess iterations)
-//=======================================================================
-Standard_Boolean WorkWithBoundaries::
-            BoundariesComputing(const ComputationMethods::stCoeffsValue &theCoeffs,
-                                const Standard_Real thePeriod,
-                                Bnd_Range theURange[])
-{
-  //All comments to this method is related to the comment
-  //to ComputationMethods class
-  
-  //So, we have the equation
-  //    cos(U2-FI2)=B*cos(U1-FI1)+C
-  //Evidently,
-  //    -1 <= B*cos(U1-FI1)+C <= 1
-
-  if (theCoeffs.mB > 0.0)
-  {
-    // -(1+C)/B <= cos(U1-FI1) <= (1-C)/B
-
-    if (theCoeffs.mB + Abs(theCoeffs.mC) < -1.0)
-    {
-      //(1-C)/B < -1 or -(1+C)/B > 1  ==> No solution
-      
-      return Standard_False;
-    }
-    else if (theCoeffs.mB + Abs(theCoeffs.mC) <= 1.0)
-    {
-      //(1-C)/B >= 1 and -(1+C)/B <= -1 ==> U=[0;2*PI]+aFI1
-      theURange[0].Add(theCoeffs.mFI1);
-      theURange[0].Add(thePeriod + theCoeffs.mFI1);
-    }
-    else if ((1 + theCoeffs.mC <= theCoeffs.mB) &&
-             (theCoeffs.mB <= 1 - theCoeffs.mC))
-    {
-      //(1-C)/B >= 1 and -(1+C)/B >= -1 ==> 
-      //(U=[0;aDAngle]+aFI1) || (U=[2*PI-aDAngle;2*PI]+aFI1),
-      //where aDAngle = acos(-(myCoeffs.mC + 1) / myCoeffs.mB)
-
-      Standard_Real anArg = -(theCoeffs.mC + 1) / theCoeffs.mB;
-      if(anArg > 1.0)
-        anArg = 1.0;
-      if(anArg < -1.0)
-        anArg = -1.0;
-
-      const Standard_Real aDAngle = acos(anArg);
-      theURange[0].Add(theCoeffs.mFI1);
-      theURange[0].Add(aDAngle + theCoeffs.mFI1);
-      theURange[1].Add(thePeriod - aDAngle + theCoeffs.mFI1);
-      theURange[1].Add(thePeriod + theCoeffs.mFI1);
-    }
-    else if ((1 - theCoeffs.mC <= theCoeffs.mB) &&
-             (theCoeffs.mB <= 1 + theCoeffs.mC))
-    {
-      //(1-C)/B <= 1 and -(1+C)/B <= -1 ==> U=[aDAngle;2*PI-aDAngle]+aFI1
-      //where aDAngle = acos((1 - myCoeffs.mC) / myCoeffs.mB)
-
-      Standard_Real anArg = (1 - theCoeffs.mC) / theCoeffs.mB;
-      if(anArg > 1.0)
-        anArg = 1.0;
-      if(anArg < -1.0)
-        anArg = -1.0;
-
-      const Standard_Real aDAngle = acos(anArg);
-      theURange[0].Add(aDAngle + theCoeffs.mFI1);
-      theURange[0].Add(thePeriod - aDAngle + theCoeffs.mFI1);
-    }
-    else if (theCoeffs.mB - Abs(theCoeffs.mC) >= 1.0)
-    {
-      //(1-C)/B <= 1 and -(1+C)/B >= -1 ==>
-      //(U=[aDAngle1;aDAngle2]+aFI1) ||
-      //(U=[2*PI-aDAngle2;2*PI-aDAngle1]+aFI1)
-      //where aDAngle1 = acos((1 - myCoeffs.mC) / myCoeffs.mB),
-      //      aDAngle2 = acos(-(myCoeffs.mC + 1) / myCoeffs.mB).
-
-      Standard_Real anArg1 = (1 - theCoeffs.mC) / theCoeffs.mB,
-                    anArg2 = -(theCoeffs.mC + 1) / theCoeffs.mB;
-      if(anArg1 > 1.0)
-        anArg1 = 1.0;
-      if(anArg1 < -1.0)
-        anArg1 = -1.0;
-
-      if(anArg2 > 1.0)
-        anArg2 = 1.0;
-      if(anArg2 < -1.0)
-        anArg2 = -1.0;
-
-      const Standard_Real aDAngle1 = acos(anArg1), aDAngle2 = acos(anArg2);
-      //(U=[aDAngle1;aDAngle2]+aFI1) ||
-      //(U=[2*PI-aDAngle2;2*PI-aDAngle1]+aFI1)
-      theURange[0].Add(aDAngle1 + theCoeffs.mFI1);
-      theURange[0].Add(aDAngle2 + theCoeffs.mFI1);
-      theURange[1].Add(thePeriod - aDAngle2 + theCoeffs.mFI1);
-      theURange[1].Add(thePeriod - aDAngle1 + theCoeffs.mFI1);
-    }
-    else
-    {
-      return Standard_False;
-    }
-  }
-  else if (theCoeffs.mB < 0.0)
-  {
-    // (1-C)/B <= cos(U1-FI1) <= -(1+C)/B
-
-    if (theCoeffs.mB + Abs(theCoeffs.mC) > 1.0)
-    {
-      // -(1+C)/B < -1 or (1-C)/B > 1 ==> No solutions
-      return Standard_False;
-    }
-    else if (-theCoeffs.mB + Abs(theCoeffs.mC) <= 1.0)
-    {
-      //  -(1+C)/B >= 1 and (1-C)/B <= -1 ==> U=[0;2*PI]+aFI1
-      theURange[0].Add(theCoeffs.mFI1);
-      theURange[0].Add(thePeriod + theCoeffs.mFI1);
-    }
-    else if ((-theCoeffs.mC - 1 <= theCoeffs.mB) &&
-             (theCoeffs.mB <= theCoeffs.mC - 1))
-    {
-      //  -(1+C)/B >= 1 and (1-C)/B >= -1 ==> 
-      //(U=[0;aDAngle]+aFI1) || (U=[2*PI-aDAngle;2*PI]+aFI1),
-      //where aDAngle = acos((1 - myCoeffs.mC) / myCoeffs.mB)
-
-      Standard_Real anArg = (1 - theCoeffs.mC) / theCoeffs.mB;
-      if(anArg > 1.0)
-        anArg = 1.0;
-      if(anArg < -1.0)
-        anArg = -1.0;
-
-      const Standard_Real aDAngle = acos(anArg);
-      theURange[0].Add(theCoeffs.mFI1);
-      theURange[0].Add(aDAngle + theCoeffs.mFI1);
-      theURange[1].Add(thePeriod - aDAngle + theCoeffs.mFI1);
-      theURange[1].Add(thePeriod + theCoeffs.mFI1);
-    }
-    else if ((theCoeffs.mC - 1 <= theCoeffs.mB) &&
-             (theCoeffs.mB <= -theCoeffs.mB - 1))
-    {
-      //  -(1+C)/B <= 1 and (1-C)/B <= -1 ==> U=[aDAngle;2*PI-aDAngle]+aFI1,
-      //where aDAngle = acos(-(myCoeffs.mC + 1) / myCoeffs.mB).
-
-      Standard_Real anArg = -(theCoeffs.mC + 1) / theCoeffs.mB;
-      if(anArg > 1.0)
-        anArg = 1.0;
-      if(anArg < -1.0)
-        anArg = -1.0;
-
-      const Standard_Real aDAngle = acos(anArg);
-      theURange[0].Add(aDAngle + theCoeffs.mFI1);
-      theURange[0].Add(thePeriod - aDAngle + theCoeffs.mFI1);
-    }
-    else if (-theCoeffs.mB - Abs(theCoeffs.mC) >= 1.0)
-    {
-      //  -(1+C)/B <= 1 and (1-C)/B >= -1 ==>
-      //(U=[aDAngle1;aDAngle2]+aFI1) || (U=[2*PI-aDAngle2;2*PI-aDAngle1]+aFI1),
-      //where aDAngle1 = acos(-(myCoeffs.mC + 1) / myCoeffs.mB),
-      //      aDAngle2 = acos((1 - myCoeffs.mC) / myCoeffs.mB)
-
-      Standard_Real anArg1 = -(theCoeffs.mC + 1) / theCoeffs.mB,
-                    anArg2 = (1 - theCoeffs.mC) / theCoeffs.mB;
-      if(anArg1 > 1.0)
-        anArg1 = 1.0;
-      if(anArg1 < -1.0)
-        anArg1 = -1.0;
-
-      if(anArg2 > 1.0)
-        anArg2 = 1.0;
-      if(anArg2 < -1.0)
-        anArg2 = -1.0;
-
-      const Standard_Real aDAngle1 = acos(anArg1), aDAngle2 = acos(anArg2);
-      theURange[0].Add(aDAngle1 + theCoeffs.mFI1);
-      theURange[0].Add(aDAngle2 + theCoeffs.mFI1);
-      theURange[1].Add(thePeriod - aDAngle2 + theCoeffs.mFI1);
-      theURange[1].Add(thePeriod - aDAngle1 + theCoeffs.mFI1);
-    }
-    else
-    {
-      return Standard_False;
-    }
-  }
-  else
-  {
-    return Standard_False;
-  }
-
-  return Standard_True;
-}
-
-//=======================================================================
-//function : CriticalPointsComputing
-//purpose  : theNbCritPointsMax contains true number of critical points.
-//            It must be initialized correctly before function calling
-//=======================================================================
-static void CriticalPointsComputing(const ComputationMethods::stCoeffsValue& theCoeffs,
-                                    const Standard_Real theUSurf1f,
-                                    const Standard_Real theUSurf1l,
-                                    const Standard_Real theUSurf2f,
-                                    const Standard_Real theUSurf2l,
-                                    const Standard_Real thePeriod,
-                                    const Standard_Real theTol2D,
-                                    Standard_Integer& theNbCritPointsMax,
-                                    Standard_Real theU1crit[])
-{
-  //[0...1] - in these points parameter U1 goes through
-  //          the seam-edge of the first cylinder.
-  //[2...3] - First and last U1 parameter.
-  //[4...5] - in these points parameter U2 goes through
-  //          the seam-edge of the second cylinder.
-  //[6...9] - in these points an intersection line goes through
-  //          U-boundaries of the second surface.
-  //[10...11] - Boundary of monotonicity interval of U2(U1) function
-  //            (see CylCylMonotonicity() function)
-
-  theU1crit[0] = 0.0;
-  theU1crit[1] = thePeriod;
-  theU1crit[2] = theUSurf1f;
-  theU1crit[3] = theUSurf1l;
-
-  const Standard_Real aCOS = cos(theCoeffs.mFI2);
-  const Standard_Real aBSB = Abs(theCoeffs.mB);
-  if((theCoeffs.mC - aBSB <= aCOS) && (aCOS <= theCoeffs.mC + aBSB))
-  {
-    Standard_Real anArg = (aCOS - theCoeffs.mC) / theCoeffs.mB;
-    if(anArg > 1.0)
-      anArg = 1.0;
-    if(anArg < -1.0)
-      anArg = -1.0;
-
-    theU1crit[4] = -acos(anArg) + theCoeffs.mFI1;
-    theU1crit[5] =  acos(anArg) + theCoeffs.mFI1;
-  }
-
-  Standard_Real aSf = cos(theUSurf2f - theCoeffs.mFI2);
-  Standard_Real aSl = cos(theUSurf2l - theCoeffs.mFI2);
-  MinMax(aSf, aSl);
-
-  //In accorance with pure mathematic, theU1crit[6] and [8]
-  //must be -Precision::Infinite() instead of used +Precision::Infinite()
-  theU1crit[6] = Abs((aSl - theCoeffs.mC) / theCoeffs.mB) < 1.0 ?
-                  -acos((aSl - theCoeffs.mC) / theCoeffs.mB) + theCoeffs.mFI1 :
-                  Precision::Infinite();
-  theU1crit[7] = Abs((aSf - theCoeffs.mC) / theCoeffs.mB) < 1.0 ?
-                  -acos((aSf - theCoeffs.mC) / theCoeffs.mB) + theCoeffs.mFI1 :
-                  Precision::Infinite();
-  theU1crit[8] = Abs((aSf - theCoeffs.mC) / theCoeffs.mB) < 1.0 ?
-                  acos((aSf - theCoeffs.mC) / theCoeffs.mB) + theCoeffs.mFI1 :
-                  Precision::Infinite();
-  theU1crit[9] = Abs((aSl - theCoeffs.mC) / theCoeffs.mB) < 1.0 ?
-                  acos((aSl - theCoeffs.mC) / theCoeffs.mB) + theCoeffs.mFI1 :
-                  Precision::Infinite();
-
-  theU1crit[10] = theCoeffs.mFI1;
-  theU1crit[11] = M_PI+theCoeffs.mFI1;
-
-  //preparative treatment of array. This array must have faled to contain negative
-  //infinity number
-
-  for(Standard_Integer i = 0; i < theNbCritPointsMax; i++)
-  {
-    if(Precision::IsInfinite(theU1crit[i]))
-    {
-      continue;
-    }
-
-    theU1crit[i] = fmod(theU1crit[i], thePeriod);
-    if(theU1crit[i] < 0.0)
-      theU1crit[i] += thePeriod;
-  }
-
-  //Here all not infinite elements of theU1crit are in [0, thePeriod) range
-
-  do
-  {
-    std::sort(theU1crit, theU1crit + theNbCritPointsMax);
-  }
-  while(ExcludeNearElements(theU1crit, theNbCritPointsMax,
-                            theUSurf1f, theUSurf1l, theTol2D));
-
-  //Here all not infinite elements in theU1crit are different and sorted.
-
-  while(theNbCritPointsMax > 0)
-  {
-    Standard_Real &anB = theU1crit[theNbCritPointsMax-1];
-    if(Precision::IsInfinite(anB))
-    {
-      theNbCritPointsMax--;
-      continue;
-    }
-
-    //1st not infinte element is found
-
-    if(theNbCritPointsMax == 1)
-      break;
-
-    //Here theNbCritPointsMax > 1
-
-    Standard_Real &anA = theU1crit[0];
-
-    //Compare 1st and last significant elements of theU1crit
-    //They may still differs by period.
-
-    if (Abs(anB - anA - thePeriod) < theTol2D)
-    {//E.g. anA == 2.0e-17, anB == (thePeriod-1.0e-18)
-      anA = (anA + anB - thePeriod)/2.0;
-      anB = Precision::Infinite();
-      theNbCritPointsMax--;
-    }
-
-    //Out of "while(theNbCritPointsMax > 0)" cycle.
-    break;
-  }
-
-  //Attention! Here theU1crit may be unsorted.
-}
-
-//=======================================================================
-//function : BoundaryEstimation
-//purpose  : Rough estimation of the parameter range.
-//=======================================================================
-void WorkWithBoundaries::BoundaryEstimation(const gp_Cylinder& theCy1,
-                                            const gp_Cylinder& theCy2,
-                                            Bnd_Range& theOutBoxS1,
-                                            Bnd_Range& theOutBoxS2) const
-{
-  const gp_Dir &aD1 = theCy1.Axis().Direction(),
-               &aD2 = theCy2.Axis().Direction();
-  const Standard_Real aR1 = theCy1.Radius(),
-                      aR2 = theCy2.Radius();
-
-  //Let consider a parallelogram. Its edges are parallel to aD1 and aD2.
-  //Its altitudes are equal to 2*aR1 and 2*aR2 (diameters of the cylinders).
-  //In fact, this parallelogram is a projection of the cylinders to the plane
-  //created by the intersected axes aD1 and aD2 (if the axes are skewed then
-  //one axis can be translated by parallel shifting till intersection).
-
-  const Standard_Real aCosA = aD1.Dot(aD2);
-  const Standard_Real aSqSinA = aD1.XYZ().CrossSquareMagnitude(aD2.XYZ());
-
-  //If sine is small then it can be compared with angle.
-  if (aSqSinA < Precision::Angular()*Precision::Angular())
-    return;
-
-  //Half of delta V. Delta V is a distance between 
-  //projections of two opposite parallelogram vertices
-  //(joined by the maximal diagonal) to the cylinder axis.
-  const Standard_Real aSinA = sqrt(aSqSinA);
-  const Standard_Real anAbsCosA = Abs(aCosA);
-  const Standard_Real aHDV1 = (aR1 * anAbsCosA + aR2) / aSinA,
-                      aHDV2 = (aR2 * anAbsCosA + aR1) / aSinA;
-
-#ifdef INTPATCH_IMPIMPINTERSECTION_DEBUG
-  //The code in this block is created for test only.It is stupidly to create
-  //OCCT-test for the method, which will be changed possibly never.
-  std::cout << "Reference values: aHDV1 = " << aHDV1 << "; aHDV2 = " << aHDV2 << std::endl;
-#endif
-
-  //V-parameters of intersection point of the axes (in case of skewed axes,
-  //see comment above).
-  Standard_Real aV01 = 0.0, aV02 = 0.0;
-  ExtremaLineLine(theCy1.Axis(), theCy2.Axis(), aCosA, aSqSinA, aV01, aV02);
-
-  theOutBoxS1.Add(aV01 - aHDV1);
-  theOutBoxS1.Add(aV01 + aHDV1);
-
-  theOutBoxS2.Add(aV02 - aHDV2);
-  theOutBoxS2.Add(aV02 + aHDV2);
-
-  theOutBoxS1.Enlarge(Precision::Confusion());
-  theOutBoxS2.Enlarge(Precision::Confusion());
-
-  Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
-  myUVSurf1.Get(aU1, aV1, aU2, aV2);
-  theOutBoxS1.Common(Bnd_Range(aV1, aV2));
-
-  myUVSurf2.Get(aU1, aV1, aU2, aV2);
-  theOutBoxS2.Common(Bnd_Range(aV1, aV2));
-}
-
-//=======================================================================
-//function : CyCyNoGeometric
-//purpose  : 
-//=======================================================================
-static IntPatch_ImpImpIntersection::IntStatus
-                    CyCyNoGeometric(const gp_Cylinder &theCyl1,
-                                    const gp_Cylinder &theCyl2,
-                                    const WorkWithBoundaries &theBW,
-                                    Bnd_Range theRange[],
-                                    const Standard_Integer theNbOfRanges /*=2*/,
-                                    Standard_Boolean& isTheEmpty,
-                                    IntPatch_SequenceOfLine& theSlin,
-                                    IntPatch_SequenceOfPoint& theSPnt)
-{
-  Standard_Real aUSurf1f = 0.0, aUSurf1l = 0.0,
-                aUSurf2f = 0.0, aUSurf2l = 0.0,
-                aVSurf1f = 0.0, aVSurf1l = 0.0,
-                aVSurf2f = 0.0, aVSurf2l = 0.0;
-
-  theBW.UVS1().Get(aUSurf1f, aVSurf1f, aUSurf1l, aVSurf1l);
-  theBW.UVS2().Get(aUSurf2f, aVSurf2f, aUSurf2l, aVSurf2l);
-
-  Bnd_Range aRangeS1, aRangeS2;
-  theBW.BoundaryEstimation(theCyl1, theCyl2, aRangeS1, aRangeS2);
-  if (aRangeS1.IsVoid() || aRangeS2.IsVoid())
-    return IntPatch_ImpImpIntersection::IntStatus_OK;
-
-  {
-    //Quotation of the message from issue #26894 (author MSV):
-    //"We should return fail status from intersector if the result should be an
-    //infinite curve of non-analytical type... I propose to define the limit for the
-    //extent as the radius divided by 1e+2 and multiplied by 1e+7.
-    //Thus, taking into account the number of valuable digits (15), we provide reliable
-    //computations with an error not exceeding R/100."
-    const Standard_Real aF = 1.0e+5;
-    const Standard_Real aMaxV1Range = aF*theCyl1.Radius(), aMaxV2Range = aF*theCyl2.Radius();
-    if ((aRangeS1.Delta() > aMaxV1Range) || (aRangeS2.Delta() > aMaxV2Range))
-      return IntPatch_ImpImpIntersection::IntStatus_InfiniteSectionCurve;
-  }
-  //
-  Standard_Boolean isGoodIntersection = Standard_False;
-  Standard_Real anOptdu = 0.;
-  for (;;)
-  {
-    //Checking parameters of cylinders in order to define "good intersection"
-    //"Good intersection" means that axes of cylinders are almost perpendicular and
-    // one radius is much smaller than the other and small cylinder is "inside" big one.
-    const Standard_Real aToMuchCoeff = 3.;
-    const Standard_Real aCritAngle = M_PI / 18.; // 10 degree
-    Standard_Real anR1 = theCyl1.Radius();
-    Standard_Real anR2 = theCyl2.Radius();
-    Standard_Real anRmin = 0., anRmax = 0.;
-    //Radius criterion
-    if (anR1 > aToMuchCoeff * anR2)
-    {
-      anRmax = anR1; anRmin = anR2;
-    }
-    else if (anR2 > aToMuchCoeff * anR1)
-    {
-      anRmax = anR2; anRmin = anR1;
-    }
-    else
-    {
-      break;
-    }
-    //Angle criterion
-    const gp_Ax1& anAx1 = theCyl1.Axis();
-    const gp_Ax1& anAx2 = theCyl2.Axis();
-    if (!anAx1.IsNormal(anAx2, aCritAngle))
-    {
-      break;
-    }
-    //Placement criterion
-    gp_Lin anL1(anAx1), anL2(anAx2);
-    Standard_Real aDist = anL1.Distance(anL2);
-    if (aDist > anRmax / 2.)
-    {
-      break;
-    }
-
-    isGoodIntersection = Standard_True;
-    //Estimation of "optimal" du
-    //Relative deflection, absolut deflection is Rmin*aDeflection
-    Standard_Real aDeflection = 0.001;
-    Standard_Integer aNbP = 3;
-    if (anRmin * aDeflection > 1.e-3)
-    {
-      Standard_Real anAngle = 1.0e0 - aDeflection;
-      anAngle = 2.0e0 * ACos(anAngle);
-      aNbP = (Standard_Integer)(2. * M_PI / anAngle) + 1;
-    }
-    anOptdu = 2. * M_PI_2 / (Standard_Real)(aNbP - 1);
-    break;
-  } 
-//
-  const ComputationMethods::stCoeffsValue &anEquationCoeffs = theBW.SICoeffs();
-  const IntSurf_Quadric& aQuad1 = theBW.GetQSurface(1);
-  const IntSurf_Quadric& aQuad2 = theBW.GetQSurface(2);
-  const Standard_Boolean isReversed = theBW.IsReversed();
-  const Standard_Real aTol2D = theBW.Get2dTolerance();
-  const Standard_Real aTol3D = theBW.Get3dTolerance();
-  const Standard_Real aPeriod = 2.0*M_PI;
-  Standard_Integer aNbMaxPoints = 1000;
-  Standard_Integer aNbMinPoints = 200;
-  Standard_Real du;
-  if (isGoodIntersection)
-  {
-    du = anOptdu;
-    aNbMaxPoints = 200;
-    aNbMinPoints = 50;
-  }
-  else
-  {
-    du = 2. * M_PI / aNbMaxPoints;
-  }
-  Standard_Integer aNbPts = Min(RealToInt((aUSurf1l - aUSurf1f) / du) + 1, 
-                                RealToInt(20.0*theCyl1.Radius()));
-  const Standard_Integer aNbPoints = Min(Max(aNbMinPoints, aNbPts), aNbMaxPoints);
-  const Standard_Real aStepMin = Max(aTol2D, Precision::PConfusion()), 
-    aStepMax = (aUSurf1l - aUSurf1f > M_PI / 100.0) ?
-    (aUSurf1l - aUSurf1f) / IntToReal(aNbPoints) : aUSurf1l - aUSurf1f;
-
-  //The main idea of the algorithm is to change U1-parameter
-  //(U-parameter of theCyl1) from aU1f to aU1l with some step
-  //(step is adaptive) and to obtain set of intersection points.
-
-  for (Standard_Integer i = 0; i < theNbOfRanges; i++)
-  {
-    if (theRange[i].IsVoid())
-      continue;
-
-    InscribeInterval(aUSurf1f, aUSurf1l, theRange[i], aTol2D, aPeriod);
-  }
-
-  if (theRange[0].Union(theRange[1]))
-  {
-    // Works only if (theNbOfRanges == 2).
-    theRange[1].SetVoid();
-  }
-
-  //Critical points are the value of U1-parameter in the points
-  //where WL must be decomposed.
-
-  //When U1 goes through critical points its value is set up to this
-  //parameter forcefully and the intersection point is added in the line.
-  //After that, the WL is broken (next U1 value will be correspond to the new WL).
-
-  //See CriticalPointsComputing(...) function to get detail information about this array.
-  const Standard_Integer aNbCritPointsMax = 12;
-  Standard_Real anU1crit[aNbCritPointsMax] = { Precision::Infinite(),
-                                               Precision::Infinite(),
-                                               Precision::Infinite(),
-                                               Precision::Infinite(),
-                                               Precision::Infinite(),
-                                               Precision::Infinite(),
-                                               Precision::Infinite(),
-                                               Precision::Infinite(),
-                                               Precision::Infinite(),
-                                               Precision::Infinite(),
-                                               Precision::Infinite(),
-                                               Precision::Infinite() };
-
-  //This list of critical points is not full because it does not contain any points
-  //which intersection line goes through V-bounds of cylinders in.
-  //They are computed by numerical methods on - line (during algorithm working).
-  //The moment is caught, when intersection line goes through V-bounds of any cylinder.
-
-  Standard_Integer aNbCritPoints = aNbCritPointsMax;
-  CriticalPointsComputing(anEquationCoeffs, aUSurf1f, aUSurf1l, aUSurf2f, aUSurf2l,
-                          aPeriod, aTol2D, aNbCritPoints, anU1crit);
-
-  //Getting Walking-line
-
-  enum WLFStatus
-  {
-    // No points have been added in WL
-    WLFStatus_Absent = 0,
-    // WL contains at least one point
-    WLFStatus_Exist = 1,
-    // WL has been finished in some critical point
-    // We should start new line
-    WLFStatus_Broken = 2
-  };
-
-  const Standard_Integer aNbWLines = 2;
-  for (Standard_Integer aCurInterval = 0; aCurInterval < theNbOfRanges; aCurInterval++)
-  {
-    //Process every continuous region
-    Standard_Boolean isAddedIntoWL[aNbWLines];
-    for (Standard_Integer i = 0; i < aNbWLines; i++)
-      isAddedIntoWL[i] = Standard_False;
-
-    Standard_Real anUf = 1.0, anUl = 0.0;
-    if (!theRange[aCurInterval].GetBounds(anUf, anUl))
-      continue;
-
-    const Standard_Boolean isDeltaPeriod = IsEqual(anUl - anUf, aPeriod);
-
-    //Inscribe and sort critical points
-    for (Standard_Integer i = 0; i < aNbCritPoints; i++)
-    {
-      InscribePoint(anUf, anUl, anU1crit[i], 0.0, aPeriod, Standard_False);
-    }
-
-    std::sort(anU1crit, anU1crit + aNbCritPoints);
-
-    while (anUf < anUl)
-    {
-      //Change value of U-parameter on the 1st surface from anUf to anUl
-      //(anUf will be modified in the cycle body).
-      //Step is computed adaptively (see comments below).
-
-      Standard_Real aU2[aNbWLines], aV1[aNbWLines], aV2[aNbWLines];
-      WLFStatus aWLFindStatus[aNbWLines];
-      Standard_Real aV1Prev[aNbWLines], aV2Prev[aNbWLines];
-      Standard_Real anUexpect[aNbWLines];
-      Standard_Boolean isAddingWLEnabled[aNbWLines];
-
-      Handle(IntSurf_LineOn2S) aL2S[aNbWLines];
-      Handle(IntPatch_WLine) aWLine[aNbWLines];
-      for (Standard_Integer i = 0; i < aNbWLines; i++)
-      {
-        aL2S[i] = new IntSurf_LineOn2S();
-        aWLine[i] = new IntPatch_WLine(aL2S[i], Standard_False);
-        aWLine[i]->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLImpImp);
-        aWLFindStatus[i] = WLFStatus_Absent;
-        isAddingWLEnabled[i] = Standard_True;
-        aU2[i] = aV1[i] = aV2[i] = 0.0;
-        aV1Prev[i] = aV2Prev[i] = 0.0;
-        anUexpect[i] = anUf;
-      }
-
-      Standard_Real aCriticalDelta[aNbCritPointsMax] = { 0 };
-      for (Standard_Integer aCritPID = 0; aCritPID < aNbCritPoints; aCritPID++)
-      { //We are not interested in elements of aCriticalDelta array
-        //if their index is greater than or equal to aNbCritPoints
-
-        aCriticalDelta[aCritPID] = anUf - anU1crit[aCritPID];
-      }
-
-      Standard_Real anU1 = anUf, aMinCriticalParam = anUf;
-      Standard_Boolean isFirst = Standard_True;
-
-      while (anU1 <= anUl)
-      {
-        //Change value of U-parameter on the 1st surface from anUf to anUl
-        //(anUf will be modified in the cycle body). However, this cycle
-        //can be broken if WL goes though some critical point.
-        //Step is computed adaptively (see comments below).
-
-        for (Standard_Integer i = 0; i < aNbCritPoints; i++)
-        {
-          if ((anU1 - anU1crit[i])*aCriticalDelta[i] < 0.0)
-          {
-            //WL has gone through i-th critical point
-            anU1 = anU1crit[i];
-
-            for (Standard_Integer j = 0; j < aNbWLines; j++)
-            {
-              aWLFindStatus[j] = WLFStatus_Broken;
-              anUexpect[j] = anU1;
-            }
-
-            break;
-          }
-        }
-
-        if (IsEqual(anU1, anUl))
-        {
-          for (Standard_Integer i = 0; i < aNbWLines; i++)
-          {
-            aWLFindStatus[i] = WLFStatus_Broken;
-            anUexpect[i] = anU1;
-
-            if (isDeltaPeriod)
-            {
-              //if isAddedIntoWL[i] == TRUE WLine contains only one point
-              //(which was end point of previous WLine). If we will
-              //add point found on the current step WLine will contain only
-              //two points. At that both these points will be equal to the
-              //points found earlier. Therefore, new WLine will repeat 
-              //already existing WLine. Consequently, it is necessary 
-              //to forbid building new line in this case.
-
-              isAddingWLEnabled[i] = (!isAddedIntoWL[i]);
-            }
-            else
-            {
-              isAddingWLEnabled[i] = ((aTol2D >= (anUexpect[i] - anU1)) ||
-                                      (aWLFindStatus[i] == WLFStatus_Absent));
-            }
-          }//for(Standard_Integer i = 0; i < aNbWLines; i++)
-        }
-        else
-        {
-          for (Standard_Integer i = 0; i < aNbWLines; i++)
-          {
-            isAddingWLEnabled[i] = ((aTol2D >= (anUexpect[i] - anU1)) ||
-                                    (aWLFindStatus[i] == WLFStatus_Absent));
-          }//for(Standard_Integer i = 0; i < aNbWLines; i++)
-        }
-
-        for (Standard_Integer i = 0; i < aNbWLines; i++)
-        {
-          const Standard_Integer aNbPntsWL = aWLine[i].IsNull() ? 0 :
-            aWLine[i]->Curve()->NbPoints();
-
-          if ((aWLFindStatus[i] == WLFStatus_Broken) ||
-            (aWLFindStatus[i] == WLFStatus_Absent))
-          {//Begin and end of WLine must be on boundary point
-           //or on seam-edge strictly (if it is possible).
-
-            Standard_Real aTol = aTol2D;
-            ComputationMethods::CylCylComputeParameters(anU1, i, anEquationCoeffs,
-                                                        aU2[i], &aTol);
-            InscribePoint(aUSurf2f, aUSurf2l, aU2[i], aTol2D, aPeriod, Standard_False);
-
-            aTol = Max(aTol, aTol2D);
-
-            if (Abs(aU2[i]) <= aTol)
-              aU2[i] = 0.0;
-            else if (Abs(aU2[i] - aPeriod) <= aTol)
-              aU2[i] = aPeriod;
-            else if (Abs(aU2[i] - aUSurf2f) <= aTol)
-              aU2[i] = aUSurf2f;
-            else if (Abs(aU2[i] - aUSurf2l) <= aTol)
-              aU2[i] = aUSurf2l;
-          }
-          else
-          {
-            ComputationMethods::CylCylComputeParameters(anU1, i, anEquationCoeffs, aU2[i]);
-            InscribePoint(aUSurf2f, aUSurf2l, aU2[i], aTol2D, aPeriod, Standard_False);
-          }
-
-          if (aNbPntsWL == 0)
-          {//the line has not contained any points yet
-            if (((aUSurf2f + aPeriod - aUSurf2l) <= 2.0*aTol2D) &&
-                ((Abs(aU2[i] - aUSurf2f) < aTol2D) ||
-                  (Abs(aU2[i] - aUSurf2l) < aTol2D)))
-            {
-              //In this case aU2[i] can have two values: current aU2[i] or
-              //aU2[i]+aPeriod (aU2[i]-aPeriod). It is necessary to choose
-              //correct value.
-
-              Standard_Boolean isIncreasing = Standard_True;
-              ComputationMethods::CylCylMonotonicity(anU1+aStepMin, i, anEquationCoeffs,
-                                                      aPeriod, isIncreasing);
-
-              //If U2(U1) is increasing and U2 is considered to be equal aUSurf2l
-              //then after the next step (when U1 will be increased) U2 will be
-              //increased too. And we will go out of surface boundary.
-              //Therefore, If U2(U1) is increasing then U2 must be equal aUSurf2f.
-              //Analogically, if U2(U1) is decreasing.
-              if (isIncreasing)
-              {
-                aU2[i] = aUSurf2f;
-              }
-              else
-              {
-                aU2[i] = aUSurf2l;
-              }
-            }
-          }
-          else
-          {//aNbPntsWL > 0
-            if (((aUSurf2l - aUSurf2f) >= aPeriod) &&
-                ((Abs(aU2[i] - aUSurf2f) < aTol2D) ||
-                  (Abs(aU2[i] - aUSurf2l) < aTol2D)))
-            {//end of the line
-              Standard_Real aU2prev = 0.0, aV2prev = 0.0;
-              if (isReversed)
-                aWLine[i]->Curve()->Value(aNbPntsWL).ParametersOnS1(aU2prev, aV2prev);
-              else
-                aWLine[i]->Curve()->Value(aNbPntsWL).ParametersOnS2(aU2prev, aV2prev);
-
-              if (2.0*Abs(aU2prev - aU2[i]) > aPeriod)
-              {
-                if (aU2prev > aU2[i])
-                  aU2[i] += aPeriod;
-                else
-                  aU2[i] -= aPeriod;
-              }
-            }
-          }
-
-          ComputationMethods::CylCylComputeParameters(anU1, aU2[i], anEquationCoeffs,
-                                                              aV1[i], aV2[i]);
-
-          if (isFirst)
-          {
-            aV1Prev[i] = aV1[i];
-            aV2Prev[i] = aV2[i];
-          }
-        }//for(Standard_Integer i = 0; i < aNbWLines; i++)
-
-        isFirst = Standard_False;
-
-        //Looking for points into WLine
-        Standard_Boolean isBroken = Standard_False;
-        for (Standard_Integer i = 0; i < aNbWLines; i++)
-        {
-          if (!isAddingWLEnabled[i])
-          {
-            Standard_Boolean isBoundIntersect = Standard_False;
-            if ((Abs(aV1[i] - aVSurf1f) <= aTol2D) ||
-                ((aV1[i] - aVSurf1f)*(aV1Prev[i] - aVSurf1f) < 0.0))
-            {
-              isBoundIntersect = Standard_True;
-            }
-            else if ((Abs(aV1[i] - aVSurf1l) <= aTol2D) ||
-                    ((aV1[i] - aVSurf1l)*(aV1Prev[i] - aVSurf1l) < 0.0))
-            {
-              isBoundIntersect = Standard_True;
-            }
-            else if ((Abs(aV2[i] - aVSurf2f) <= aTol2D) ||
-                    ((aV2[i] - aVSurf2f)*(aV2Prev[i] - aVSurf2f) < 0.0))
-            {
-              isBoundIntersect = Standard_True;
-            }
-            else if ((Abs(aV2[i] - aVSurf2l) <= aTol2D) ||
-                    ((aV2[i] - aVSurf2l)*(aV2Prev[i] - aVSurf2l) < 0.0))
-            {
-              isBoundIntersect = Standard_True;
-            }
-
-            if (aWLFindStatus[i] == WLFStatus_Broken)
-              isBroken = Standard_True;
-
-            if (!isBoundIntersect)
-            {
-              continue;
-            }
-            else
-            {
-              anUexpect[i] = anU1;
-            }
-          }
-
-          // True if the current point already in the domain
-          const Standard_Boolean isInscribe =
-              ((aUSurf2f - aU2[i]) <= aTol2D) && ((aU2[i] - aUSurf2l) <= aTol2D) &&
-              ((aVSurf1f - aV1[i]) <= aTol2D) && ((aV1[i] - aVSurf1l) <= aTol2D) &&
-              ((aVSurf2f - aV2[i]) <= aTol2D) && ((aV2[i] - aVSurf2l) <= aTol2D);
-
-          //isVIntersect == TRUE if intersection line intersects two (!)
-          //V-bounds of cylinder (1st or 2nd - no matter)
-          const Standard_Boolean isVIntersect =
-              (((aVSurf1f - aV1[i])*(aVSurf1f - aV1Prev[i]) < RealSmall()) &&
-                ((aVSurf1l - aV1[i])*(aVSurf1l - aV1Prev[i]) < RealSmall())) ||
-              (((aVSurf2f - aV2[i])*(aVSurf2f - aV2Prev[i]) < RealSmall()) &&
-                ((aVSurf2l - aV2[i])*(aVSurf2l - aV2Prev[i]) < RealSmall()));
-
-          //isFound1 == TRUE if intersection line intersects V-bounds
-          //  (First or Last - no matter) of the 1st cylynder
-          //isFound2 == TRUE if intersection line intersects V-bounds
-          //  (First or Last - no matter) of the 2nd cylynder
-          Standard_Boolean isFound1 = Standard_False, isFound2 = Standard_False;
-          Standard_Boolean isForce = Standard_False;
-
-          if (aWLFindStatus[i] == WLFStatus_Absent)
-          {
-            if (((aUSurf2l - aUSurf2f) >= aPeriod) && (Abs(anU1 - aUSurf1l) < aTol2D))
-            {
-              isForce = Standard_True;
-            }
-          }
-
-          theBW.AddBoundaryPoint(aWLine[i], anU1, aMinCriticalParam, aU2[i],
-                                 aV1[i], aV1Prev[i], aV2[i], aV2Prev[i], i, isForce,
-                                 isFound1, isFound2);
-
-          const Standard_Boolean isPrevVBound = !isVIntersect &&
-                                                ((Abs(aV1Prev[i] - aVSurf1f) <= aTol2D) ||
-                                                 (Abs(aV1Prev[i] - aVSurf1l) <= aTol2D) ||
-                                                 (Abs(aV2Prev[i] - aVSurf2f) <= aTol2D) ||
-                                                 (Abs(aV2Prev[i] - aVSurf2l) <= aTol2D));
-
-          aV1Prev[i] = aV1[i];
-          aV2Prev[i] = aV2[i];
-
-          if ((aWLFindStatus[i] == WLFStatus_Exist) && (isFound1 || isFound2) && !isPrevVBound)
-          {
-            aWLFindStatus[i] = WLFStatus_Broken; //start a new line
-          }
-          else if (isInscribe)
-          {
-            if ((aWLFindStatus[i] == WLFStatus_Absent) && (isFound1 || isFound2))
-            {
-              aWLFindStatus[i] = WLFStatus_Exist;
-            }
-
-            if ((aWLFindStatus[i] != WLFStatus_Broken) ||
-              (aWLine[i]->NbPnts() >= 1) || IsEqual(anU1, anUl))
-            {
-              if (aWLine[i]->NbPnts() > 0)
-              {
-                Standard_Real aU2p = 0.0, aV2p = 0.0;
-                if (isReversed)
-                  aWLine[i]->Point(aWLine[i]->NbPnts()).ParametersOnS1(aU2p, aV2p);
-                else
-                  aWLine[i]->Point(aWLine[i]->NbPnts()).ParametersOnS2(aU2p, aV2p);
-
-                const Standard_Real aDelta = aU2[i] - aU2p;
-
-                if (2.0 * Abs(aDelta) > aPeriod)
-                {
-                  if (aDelta > 0.0)
-                  {
-                    aU2[i] -= aPeriod;
-                  }
-                  else
-                  {
-                    aU2[i] += aPeriod;
-                  }
-                }
-              }
-
-              if(AddPointIntoWL(aQuad1, aQuad2, anEquationCoeffs, isReversed, Standard_True,
-                                gp_Pnt2d(anU1, aV1[i]), gp_Pnt2d(aU2[i], aV2[i]),
-                                aUSurf1f, aUSurf1l, aUSurf2f, aUSurf2l,
-                                aVSurf1f, aVSurf1l, aVSurf2f, aVSurf2l, aPeriod,
-                                aWLine[i]->Curve(), i, aTol3D, aTol2D, isForce))
-              {
-                if (aWLFindStatus[i] == WLFStatus_Absent)
-                {
-                  aWLFindStatus[i] = WLFStatus_Exist;
-                }
-              }
-              else if (!isFound1 && !isFound2)
-              {//We do not add any point while doing this iteration
-                if (aWLFindStatus[i] == WLFStatus_Exist)
-                {
-                  aWLFindStatus[i] = WLFStatus_Broken;
-                }
-              }
-            }
-          }
-          else
-          {//We do not add any point while doing this iteration
-            if (aWLFindStatus[i] == WLFStatus_Exist)
-            {
-              aWLFindStatus[i] = WLFStatus_Broken;
-            }
-          }
-
-          if (aWLFindStatus[i] == WLFStatus_Broken)
-            isBroken = Standard_True;
-        }//for(Standard_Integer i = 0; i < aNbWLines; i++)
-
-        if (isBroken)
-        {//current lines are filled. Go to the next lines
-          anUf = anU1;
-
-          Standard_Boolean isAdded = Standard_True;
-
-          for (Standard_Integer i = 0; i < aNbWLines; i++)
-          {
-            if (isAddingWLEnabled[i])
-            {
-              continue;
-            }
-
-            isAdded = Standard_False;
-
-            Standard_Boolean isFound1 = Standard_False, isFound2 = Standard_False;
-
-            theBW.AddBoundaryPoint(aWLine[i], anU1, aMinCriticalParam, aU2[i],
-                                   aV1[i], aV1Prev[i], aV2[i], aV2Prev[i], i,
-                                   Standard_False, isFound1, isFound2);
-
-            if (isFound1 || isFound2)
-            {
-              isAdded = Standard_True;
-            }
-
-            if (aWLine[i]->NbPnts() > 0)
-            {
-              Standard_Real aU2p = 0.0, aV2p = 0.0;
-              if (isReversed)
-                aWLine[i]->Point(aWLine[i]->NbPnts()).ParametersOnS1(aU2p, aV2p);
-              else
-                aWLine[i]->Point(aWLine[i]->NbPnts()).ParametersOnS2(aU2p, aV2p);
-
-              const Standard_Real aDelta = aU2[i] - aU2p;
-
-              if (2 * Abs(aDelta) > aPeriod)
-              {
-                if (aDelta > 0.0)
-                {
-                  aU2[i] -= aPeriod;
-                }
-                else
-                {
-                  aU2[i] += aPeriod;
-                }
-              }
-            }
-
-            if(AddPointIntoWL(aQuad1, aQuad2, anEquationCoeffs, isReversed,
-                              Standard_True, gp_Pnt2d(anU1, aV1[i]),
-                              gp_Pnt2d(aU2[i], aV2[i]), aUSurf1f, aUSurf1l,
-                              aUSurf2f, aUSurf2l, aVSurf1f, aVSurf1l,
-                              aVSurf2f, aVSurf2l, aPeriod, aWLine[i]->Curve(),
-                              i, aTol3D, aTol2D, Standard_False))
-            {
-              isAdded = Standard_True;
-            }
-          }
-
-          if (!isAdded)
-          {
-            //Before breaking WL, we must complete it correctly
-            //(e.g. to prolong to the surface boundary).
-            //Therefore, we take the point last added in some WL
-            //(have maximal U1-parameter) and try to add it in
-            //the current WL.
-            Standard_Real anUmaxAdded = RealFirst();
-
-            {
-              Standard_Boolean isChanged = Standard_False;
-              for (Standard_Integer i = 0; i < aNbWLines; i++)
-              {
-                if ((aWLFindStatus[i] == WLFStatus_Absent) || (aWLine[i]->NbPnts() == 0))
-                  continue;
-
-                Standard_Real aU1c = 0.0, aV1c = 0.0;
-                if (isReversed)
-                  aWLine[i]->Curve()->Value(aWLine[i]->NbPnts()).ParametersOnS2(aU1c, aV1c);
-                else
-                  aWLine[i]->Curve()->Value(aWLine[i]->NbPnts()).ParametersOnS1(aU1c, aV1c);
-
-                anUmaxAdded = Max(anUmaxAdded, aU1c);
-                isChanged = Standard_True;
-              }
-
-              if (!isChanged)
-              { //If anUmaxAdded were not changed in previous cycle then
-                //we would break existing WLines.
-                break;
-              }
-            }
-
-            for (Standard_Integer i = 0; i < aNbWLines; i++)
-            {
-              if (isAddingWLEnabled[i])
-              {
-                continue;
-              }
-
-              ComputationMethods::CylCylComputeParameters(anUmaxAdded, i, anEquationCoeffs,
-                aU2[i], aV1[i], aV2[i]);
-
-              AddPointIntoWL(aQuad1, aQuad2, anEquationCoeffs, isReversed,
-                             Standard_True, gp_Pnt2d(anUmaxAdded, aV1[i]),
-                             gp_Pnt2d(aU2[i], aV2[i]), aUSurf1f, aUSurf1l,
-                             aUSurf2f, aUSurf2l, aVSurf1f, aVSurf1l,
-                             aVSurf2f, aVSurf2l, aPeriod, aWLine[i]->Curve(),
-                             i, aTol3D, aTol2D, Standard_False);
-            }
-          }
-
-          break;
-        }
-
-        //Step computing
-
-        {
-          //Step of aU1-parameter is computed adaptively. The algorithm 
-          //aims to provide given aDeltaV1 and aDeltaV2 values (if it is 
-          //possible because the intersection line can go along V-isoline)
-          //in every iteration. It allows avoiding "flying" intersection
-          //points too far each from other (see issue #24915).
-
-          const Standard_Real aDeltaV1 = aRangeS1.Delta() / IntToReal(aNbPoints),
-                              aDeltaV2 = aRangeS2.Delta() / IntToReal(aNbPoints);
-
-          math_Matrix aMatr(1, 3, 1, 5);
-
-          Standard_Real aMinUexp = RealLast();
-
-          for (Standard_Integer i = 0; i < aNbWLines; i++)
-          {
-            if (aTol2D < (anUexpect[i] - anU1))
-            {
-              continue;
-            }
-
-            if (aWLFindStatus[i] == WLFStatus_Absent)
-            {
-              anUexpect[i] += aStepMax;
-              aMinUexp = Min(aMinUexp, anUexpect[i]);
-              continue;
-            }
-            //
-            if (isGoodIntersection)
-            {
-              //Use constant step
-              anUexpect[i] += aStepMax;
-              aMinUexp = Min(aMinUexp, anUexpect[i]);
-
-              continue;
-            }
-            //
-
-            Standard_Real aStepTmp = aStepMax;
-
-            const Standard_Real aSinU1 = sin(anU1),
-                                aCosU1 = cos(anU1),
-                                aSinU2 = sin(aU2[i]),
-                                aCosU2 = cos(aU2[i]);
-
-            aMatr.SetCol(1, anEquationCoeffs.mVecC1);
-            aMatr.SetCol(2, anEquationCoeffs.mVecC2);
-            aMatr.SetCol(3, anEquationCoeffs.mVecA1*aSinU1 - anEquationCoeffs.mVecB1*aCosU1);
-            aMatr.SetCol(4, anEquationCoeffs.mVecA2*aSinU2 - anEquationCoeffs.mVecB2*aCosU2);
-            aMatr.SetCol(5, anEquationCoeffs.mVecA1*aCosU1 + anEquationCoeffs.mVecB1*aSinU1 +
-                            anEquationCoeffs.mVecA2*aCosU2 + anEquationCoeffs.mVecB2*aSinU2 +
-                            anEquationCoeffs.mVecD);
-
-            //The main idea is in solving of linearized system (2)
-            //(see description to ComputationMethods class) in order to find new U1-value
-            //to provide new value V1 or V2, which differs from current one by aDeltaV1 or
-            //aDeltaV2 respectively. 
-
-            //While linearizing, following Taylor formulas are used:
-            //    cos(x0+dx) = cos(x0) - sin(x0)*dx
-            //    sin(x0+dx) = sin(x0) + cos(x0)*dx
-
-            //Consequently cos(U1), cos(U2), sin(U1) and sin(U2) in the system (2)
-            //must be substituted by corresponding values.
-
-            //ATTENTION!!!
-            //The solution is approximate. More over, all requirements to the
-            //linearization must be satisfied in order to obtain quality result.
-
-            if (!StepComputing(aMatr, aV1[i], aV2[i], aDeltaV1, aDeltaV2, aStepTmp))
-            {
-              //To avoid cycling-up
-              anUexpect[i] += aStepMax;
-              aMinUexp = Min(aMinUexp, anUexpect[i]);
-
-              continue;
-            }
-
-            if (aStepTmp < aStepMin)
-              aStepTmp = aStepMin;
-
-            if (aStepTmp > aStepMax)
-              aStepTmp = aStepMax;
-
-            anUexpect[i] = anU1 + aStepTmp;
-            aMinUexp = Min(aMinUexp, anUexpect[i]);
-          }
-
-          anU1 = aMinUexp;
-        }
-
-        if (Precision::PConfusion() >= (anUl - anU1))
-          anU1 = anUl;
-
-        anUf = anU1;
-
-        for (Standard_Integer i = 0; i < aNbWLines; i++)
-        {
-          if (aWLine[i]->NbPnts() != 1)
-            isAddedIntoWL[i] = Standard_False;
-
-          if (anU1 == anUl)
-          {//strictly equal. Tolerance is considered above.
-            anUexpect[i] = anUl;
-          }
-        }
-      }
-
-      for (Standard_Integer i = 0; i < aNbWLines; i++)
-      {
-        if ((aWLine[i]->NbPnts() == 1) && (!isAddedIntoWL[i]))
-        {
-          isTheEmpty = Standard_False;
-          Standard_Real u1, v1, u2, v2;
-          aWLine[i]->Point(1).Parameters(u1, v1, u2, v2);
-          IntPatch_Point aP;
-          aP.SetParameter(u1);
-          aP.SetParameters(u1, v1, u2, v2);
-          aP.SetTolerance(aTol3D);
-          aP.SetValue(aWLine[i]->Point(1).Value());
-
-          //Check whether the added point exists.
-          //It is enough to check the last point.
-          if (theSPnt.IsEmpty() ||
-              !theSPnt.Last().PntOn2S().IsSame(aP.PntOn2S(), Precision::Confusion()))
-          {
-            theSPnt.Append(aP);
-          }
-        }
-        else if (aWLine[i]->NbPnts() > 1)
-        {
-          Standard_Boolean isGood = Standard_True;
-
-          if (aWLine[i]->NbPnts() == 2)
-          {
-            const IntSurf_PntOn2S& aPf = aWLine[i]->Point(1);
-            const IntSurf_PntOn2S& aPl = aWLine[i]->Point(2);
-
-            if (aPf.IsSame(aPl, Precision::Confusion()))
-              isGood = Standard_False;
-          }
-          else if (aWLine[i]->NbPnts() > 2)
-          {
-            // Sometimes points of the WLine are distributed
-            // linearly and uniformly. However, such position
-            // of the points does not always describe the real intersection
-            // curve. I.e. real tangents at the ends of the intersection
-            // curve can significantly deviate from this "line" direction.
-            // Here we are processing this case by inserting additional points
-            // to the beginning/end of the WLine to make it more precise.
-            // See description to the issue #30082.
-
-            const Standard_Real aSqTol3D = aTol3D*aTol3D;
-            for (Standard_Integer j = 0; j < 2; j++)
-            {
-              // If j == 0 ==> add point at begin of WLine.
-              // If j == 1 ==> add point at end of WLine.
-
-              for (;;)
-              {
-                if (aWLine[i]->NbPnts() >= aNbMaxPoints)
-                {
-                  break;
-                }
-
-                // Take 1st and 2nd point to compute the "line" direction.
-                // For our convenience, we make 2nd point be the ends of the WLine
-                // because it will be used for computation of the normals 
-                // to the surfaces.
-                const Standard_Integer anIdx1 = j ? aWLine[i]->NbPnts() - 1 : 2;
-                const Standard_Integer anIdx2 = j ? aWLine[i]->NbPnts() : 1;
-
-                const gp_Pnt &aP1 = aWLine[i]->Point(anIdx1).Value();
-                const gp_Pnt &aP2 = aWLine[i]->Point(anIdx2).Value();
-
-                const gp_Vec aDir(aP1, aP2);
-
-                if (aDir.SquareMagnitude() < aSqTol3D)
-                {
-                  break;
-                }
-
-                // Compute tangent in first/last point of the WLine.
-                // We do not take into account the flag "isReversed"
-                // because strict direction of the tangent is not
-                // important here (we are interested in the tangent
-                // line itself and nothing to fear if its direction
-                // is reversed).
-                const gp_Vec aN1 = aQuad1.Normale(aP2);
-                const gp_Vec aN2 = aQuad2.Normale(aP2);
-                const gp_Vec aTg(aN1.Crossed(aN2));
-
-                if (aTg.SquareMagnitude() < Precision::SquareConfusion())
-                {
-                  // Tangent zone
-                  break;
-                }
-
-                // Check of the bending
-                Standard_Real anAngle = aDir.Angle(aTg);
-
-                if (anAngle > M_PI_2)
-                  anAngle -= M_PI;
-
-                if (Abs(anAngle) > 0.25) // ~ 14deg.
-                {
-                  const Standard_Integer aNbPntsPrev = aWLine[i]->NbPnts();
-                  SeekAdditionalPoints(aQuad1, aQuad2, aWLine[i]->Curve(),
-                                       anEquationCoeffs, i, 3, anIdx1, anIdx2,
-                                       aTol2D, aPeriod, isReversed);
-
-                  if (aWLine[i]->NbPnts() == aNbPntsPrev)
-                  {
-                    // No points have been added. ==> Exit from a loop.
-                    break;
-                  }
-                }
-                else
-                {
-                  // Good result has been achieved. ==> Exit from a loop.
-                  break;
-                }
-              } // for (;;)
-            }
-          }
-
-          if (isGood)
-          {
-            isTheEmpty = Standard_False;
-            isAddedIntoWL[i] = Standard_True;
-            SeekAdditionalPoints(aQuad1, aQuad2, aWLine[i]->Curve(),
-                                 anEquationCoeffs, i, aNbPoints, 1,
-                                 aWLine[i]->NbPnts(), aTol2D, aPeriod,
-                                 isReversed);
-
-            aWLine[i]->ComputeVertexParameters(aTol3D);
-            theSlin.Append(aWLine[i]);
-          }
-        }
-        else
-        {
-          isAddedIntoWL[i] = Standard_False;
-        }
-
-#ifdef INTPATCH_IMPIMPINTERSECTION_DEBUG
-        aWLine[i]->Dump(0);
-#endif
-      }
-    }
-  }
-
-
-  //Delete the points in theSPnt, which
-  //lie at least in one of the line in theSlin.
-  for (Standard_Integer aNbPnt = 1; aNbPnt <= theSPnt.Length(); aNbPnt++)
-  {
-    for (Standard_Integer aNbLin = 1; aNbLin <= theSlin.Length(); aNbLin++)
-    {
-      Handle(IntPatch_WLine) aWLine1(Handle(IntPatch_WLine)::
-        DownCast(theSlin.Value(aNbLin)));
-
-      const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1);
-      const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aWLine1->NbPnts());
-
-      const IntSurf_PntOn2S aPntCur = theSPnt.Value(aNbPnt).PntOn2S();
-      if (aPntCur.IsSame(aPntFWL1, aTol3D) ||
-        aPntCur.IsSame(aPntLWL1, aTol3D))
-      {
-        theSPnt.Remove(aNbPnt);
-        aNbPnt--;
-        break;
-      }
-    }
-  }
-
-  //Try to add new points in the neighborhood of existing point
-  for (Standard_Integer aNbPnt = 1; aNbPnt <= theSPnt.Length(); aNbPnt++)
-  {
-    // Standard algorithm (implemented above) could not find any
-    // continuous curve in neighborhood of aPnt2S (e.g. because
-    // this curve is too small; see tests\bugs\modalg_5\bug25292_35 and _36).
-    // Here, we will try to find several new points nearer to aPnt2S.
-
-    // The algorithm below tries to find two points in every
-    // intervals [u1 - aStepMax, u1] and [u1, u1 + aStepMax]
-    // and every new point will be in maximal distance from
-    // u1. If these two points exist they will be joined
-    // by the intersection curve.
-
-    const IntPatch_Point& aPnt2S = theSPnt.Value(aNbPnt);
-
-    Standard_Real u1, v1, u2, v2;
-    aPnt2S.Parameters(u1, v1, u2, v2);
-
-    Handle(IntSurf_LineOn2S) aL2S = new IntSurf_LineOn2S();
-    Handle(IntPatch_WLine) aWLine = new IntPatch_WLine(aL2S, Standard_False);
-    aWLine->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLImpImp);
-
-    //Define the index of WLine, which lies the point aPnt2S in.
-    Standard_Integer anIndex = 0;
-
-    Standard_Real anUf = 0.0, anUl = 0.0, aCurU2 = 0.0;
-    if (isReversed)
-    {
-      anUf = Max(u2 - aStepMax, aUSurf1f);
-      anUl = Min(u2 + aStepMax, aUSurf1l);
-      aCurU2 = u1;
-    }
-    else
-    {
-      anUf = Max(u1 - aStepMax, aUSurf1f);
-      anUl = Min(u1 + aStepMax, aUSurf1l);
-      aCurU2 = u2;
-    }
-
-    const Standard_Real anUinf = anUf, anUsup = anUl, anUmid = 0.5*(anUf + anUl);
-
-    {
-      //Find the value of anIndex variable.
-      Standard_Real aDelta = RealLast();
-      for (Standard_Integer i = 0; i < aNbWLines; i++)
-      {
-        Standard_Real anU2t = 0.0;
-        if (!ComputationMethods::CylCylComputeParameters(anUmid, i, anEquationCoeffs, anU2t))
-          continue;
-
-        Standard_Real aDU2 = fmod(Abs(anU2t - aCurU2), aPeriod);
-        aDU2 = Min(aDU2, Abs(aDU2 - aPeriod));
-        if (aDU2 < aDelta)
-        {
-          aDelta = aDU2;
-          anIndex = i;
-        }
-      }
-    }
-
-    // Bisection method is used in order to find every new point.
-    // I.e. if we need to find intersection point in the interval [anUinf, anUmid]
-    // we check the point anUC = 0.5*(anUinf+anUmid). If it is an intersection point
-    // we try to find another point in the interval [anUinf, anUC] (because we find the point in
-    // maximal distance from anUmid). If it is not then we try to find another point in the
-    // interval [anUC, anUmid]. Next iterations will be made analogically.
-    // When we find intersection point in the interval [anUmid, anUsup] we try to find
-    // another point in the interval [anUC, anUsup] if anUC is intersection point and
-    // in the interval [anUmid, anUC], otherwise.
-
-    Standard_Real anAddedPar[2] = {isReversed ? u2 : u1, isReversed ? u2 : u1};
-
-    for (Standard_Integer aParID = 0; aParID < 2; aParID++)
-    {
-      if (aParID == 0)
-      {
-        anUf = anUinf;
-        anUl = anUmid;
-      }
-      else // if(aParID == 1)
-      {
-        anUf = anUmid;
-        anUl = anUsup;
-      }
-
-      Standard_Real &aPar1 = (aParID == 0) ? anUf : anUl,
-                    &aPar2 = (aParID == 0) ? anUl : anUf;
-
-      while (Abs(aPar2 - aPar1) > aStepMin)
-      {
-        Standard_Real anUC = 0.5*(anUf + anUl);
-        Standard_Real aU2 = 0.0, aV1 = 0.0, aV2 = 0.0;
-        Standard_Boolean isDone = ComputationMethods::
-                CylCylComputeParameters(anUC, anIndex, anEquationCoeffs, aU2, aV1, aV2);
-
-        if (isDone)
-        {
-          if (Abs(aV1 - aVSurf1f) <= aTol2D)
-            aV1 = aVSurf1f;
-
-          if (Abs(aV1 - aVSurf1l) <= aTol2D)
-            aV1 = aVSurf1l;
-
-          if (Abs(aV2 - aVSurf2f) <= aTol2D)
-            aV2 = aVSurf2f;
-
-          if (Abs(aV2 - aVSurf2l) <= aTol2D)
-            aV2 = aVSurf2l;
-
-          isDone = AddPointIntoWL(aQuad1, aQuad2, anEquationCoeffs, isReversed,
-                                  Standard_True, gp_Pnt2d(anUC, aV1), gp_Pnt2d(aU2, aV2),
-                                  aUSurf1f, aUSurf1l, aUSurf2f, aUSurf2l,
-                                  aVSurf1f, aVSurf1l, aVSurf2f, aVSurf2l,
-                                  aPeriod, aWLine->Curve(), anIndex, aTol3D,
-                                  aTol2D, Standard_False, Standard_True);
-        }
-
-        if (isDone)
-        {
-          anAddedPar[0] = Min(anAddedPar[0], anUC);
-          anAddedPar[1] = Max(anAddedPar[1], anUC);
-          aPar2 = anUC;
-        }
-        else
-        {
-          aPar1 = anUC;
-        }
-      }
-    }
-
-    //Fill aWLine by additional points
-    if (anAddedPar[1] - anAddedPar[0] > aStepMin)
-    {
-      for (Standard_Integer aParID = 0; aParID < 2; aParID++)
-      {
-        Standard_Real aU2 = 0.0, aV1 = 0.0, aV2 = 0.0;
-        ComputationMethods::CylCylComputeParameters(anAddedPar[aParID], anIndex,
-                                                  anEquationCoeffs, aU2, aV1, aV2);
-
-        AddPointIntoWL(aQuad1, aQuad2, anEquationCoeffs, isReversed, Standard_True,
-                        gp_Pnt2d(anAddedPar[aParID], aV1), gp_Pnt2d(aU2, aV2),
-                        aUSurf1f, aUSurf1l, aUSurf2f, aUSurf2l,
-                        aVSurf1f, aVSurf1l, aVSurf2f, aVSurf2l, aPeriod, aWLine->Curve(),
-                        anIndex, aTol3D, aTol2D, Standard_False, Standard_False);
-      }
-
-      SeekAdditionalPoints(aQuad1, aQuad2, aWLine->Curve(),
-                            anEquationCoeffs, anIndex, aNbMinPoints,
-                            1, aWLine->NbPnts(), aTol2D, aPeriod,
-                            isReversed);
-
-      aWLine->ComputeVertexParameters(aTol3D);
-      theSlin.Append(aWLine);
-
-      theSPnt.Remove(aNbPnt);
-      aNbPnt--;
-    }
-  }
-
-  return IntPatch_ImpImpIntersection::IntStatus_OK;
-}
-
-//=======================================================================
-//function : IntCyCy
-//purpose  : 
-//=======================================================================
-IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
-                                               const IntSurf_Quadric& theQuad2,
-                                               const Standard_Real theTol3D,
-                                               const Standard_Real theTol2D,
-                                               const Bnd_Box2d& theUVSurf1,
-                                               const Bnd_Box2d& theUVSurf2,
-                                               Standard_Boolean& isTheEmpty,
-                                               Standard_Boolean& isTheSameSurface,
-                                               Standard_Boolean& isTheMultiplePoint,
-                                               IntPatch_SequenceOfLine& theSlin,
-                                               IntPatch_SequenceOfPoint& theSPnt)
-{
-  isTheEmpty = Standard_True;
-  isTheSameSurface = Standard_False;
-  isTheMultiplePoint = Standard_False;
-  theSlin.Clear();
-  theSPnt.Clear();
-
-  const gp_Cylinder aCyl1 = theQuad1.Cylinder(),
-                    aCyl2 = theQuad2.Cylinder();
-
-  IntAna_QuadQuadGeo anInter(aCyl1,aCyl2,theTol3D);
-
-  if (!anInter.IsDone())
-  {
-    return IntPatch_ImpImpIntersection::IntStatus_Fail;
-  }
-
-  if(anInter.TypeInter() != IntAna_NoGeometricSolution)
-  {
-    if (CyCyAnalyticalIntersect(theQuad1, theQuad2, anInter,
-                                theTol3D, isTheEmpty,
-                                isTheSameSurface, isTheMultiplePoint,
-                                theSlin, theSPnt))
-    {
-      return IntPatch_ImpImpIntersection::IntStatus_OK;
-    }
-  }
-  
-  //Here, intersection line is not an analytical curve(line, circle, ellipsis etc.)
-
-  Standard_Real aUSBou[2][2], aVSBou[2][2]; //const
-
-  theUVSurf1.Get(aUSBou[0][0], aVSBou[0][0], aUSBou[0][1], aVSBou[0][1]);
-  theUVSurf2.Get(aUSBou[1][0], aVSBou[1][0], aUSBou[1][1], aVSBou[1][1]);
-
-  const Standard_Real aPeriod = 2.0*M_PI;
-  const Standard_Integer aNbWLines = 2;
-
-  const ComputationMethods::stCoeffsValue anEquationCoeffs1(aCyl1, aCyl2);
-  const ComputationMethods::stCoeffsValue anEquationCoeffs2(aCyl2, aCyl1);
-
-  //Boundaries. 
-  //Intersection result can include two non-connected regions
-  //(see WorkWithBoundaries::BoundariesComputing(...) method).
-  const Standard_Integer aNbOfBoundaries = 2;
-  Bnd_Range anURange[2][aNbOfBoundaries];   //const
-
-  if (!WorkWithBoundaries::BoundariesComputing(anEquationCoeffs1, aPeriod, anURange[0]))
-    return IntPatch_ImpImpIntersection::IntStatus_OK;
-
-  if (!WorkWithBoundaries::BoundariesComputing(anEquationCoeffs2, aPeriod, anURange[1]))
-    return IntPatch_ImpImpIntersection::IntStatus_OK;
-
-  //anURange[*] can be in different periodic regions in
-  //compare with First-Last surface. E.g. the surface
-  //is full cylinder [0, 2*PI] but anURange is [5, 7].
-  //Trivial common range computation returns [5, 2*PI] and
-  //its summary length is 2*PI-5 == 1.28... only. That is wrong.
-  //This problem can be solved by the following
-  //algorithm:
-  // 1. split anURange[*] by the surface boundary;
-  // 2. shift every new range in order to inscribe it
-  //      in [Ufirst, Ulast] of cylinder;
-  // 3. consider only common ranges between [Ufirst, Ulast]
-  //    and new ranges.
-  //
-  // In above example, we obtain following:
-  // 1. two ranges: [5, 2*PI] and [2*PI, 7];
-  // 2. after shifting: [5, 2*PI] and [0, 7-2*PI];
-  // 3. Common ranges: ([5, 2*PI] and [0, 2*PI]) == [5, 2*PI],
-  //                   ([0, 7-2*PI] and [0, 2*PI]) == [0, 7-2*PI];
-  // 4. Their summary length is (2*PI-5)+(7-2*PI-0)==7-5==2 ==> GOOD.
-
-  Standard_Real aSumRange[2] = { 0.0, 0.0 };
-  Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
-  for (Standard_Integer aCID = 0; aCID < 2; aCID++)
-  {
-    anAlloc->Reset(false);
-    NCollection_List<Bnd_Range> aListOfRng(anAlloc);
-    
-    aListOfRng.Append(anURange[aCID][0]);
-    aListOfRng.Append(anURange[aCID][1]);
-
-    const Standard_Real aSplitArr[3] = {aUSBou[aCID][0], aUSBou[aCID][1], 0.0};
-
-    NCollection_List<Bnd_Range>::Iterator anITrRng;
-    for (Standard_Integer aSInd = 0; aSInd < 3; aSInd++)
-    {
-      NCollection_List<Bnd_Range> aLstTemp(aListOfRng);
-      aListOfRng.Clear();
-      for (anITrRng.Init(aLstTemp); anITrRng.More(); anITrRng.Next())
-      {
-        Bnd_Range& aRng = anITrRng.ChangeValue();
-        aRng.Split(aSplitArr[aSInd], aListOfRng, aPeriod);
-      }
-    }
-
-    anITrRng.Init(aListOfRng);
-    for (; anITrRng.More(); anITrRng.Next())
-    {
-      Bnd_Range& aCurrRange = anITrRng.ChangeValue();
-
-      Bnd_Range aBoundR;
-      aBoundR.Add(aUSBou[aCID][0]);
-      aBoundR.Add(aUSBou[aCID][1]);
-
-      if (!InscribeInterval(aUSBou[aCID][0], aUSBou[aCID][1],
-                                          aCurrRange, theTol2D, aPeriod))
-      {
-        //If aCurrRange does not have common block with
-        //[Ufirst, Ulast] of cylinder then we will try
-        //to inscribe [Ufirst, Ulast] in the boundaries of aCurrRange.
-        Standard_Real aF = 1.0, aL = 0.0;
-        if (!aCurrRange.GetBounds(aF, aL))
-          continue;
-
-        if ((aL < aUSBou[aCID][0]))
-        {
-          aCurrRange.Shift(aPeriod);
-        }
-        else if (aF > aUSBou[aCID][1])
-        {
-          aCurrRange.Shift(-aPeriod);
-        }
-      }
-
-      aBoundR.Common(aCurrRange);
-
-      const Standard_Real aDelta = aBoundR.Delta();
-
-      if (aDelta > 0.0)
-      {
-        aSumRange[aCID] += aDelta;
-      }
-    }
-  }
-
-  //The bigger range the bigger number of points in Walking-line (WLine)
-  //we will be able to add and consequently we will obtain more
-  //precise intersection line.
-  //Every point of WLine is determined as function from U1-parameter,
-  //where U1 is U-parameter on 1st quadric.
-  //Therefore, we should use quadric with bigger range as 1st parameter
-  //in IntCyCy() function.
-  //On the other hand, there is no point in reversing in case of
-  //analytical intersection (when result is line, ellipse, point...).
-  //This result is independent of the arguments order.
-  const Standard_Boolean isToReverse = (aSumRange[1] > aSumRange[0]);
-
-  if (isToReverse)
-  {
-    const WorkWithBoundaries aBoundWork(theQuad2, theQuad1, anEquationCoeffs2,
-                                        theUVSurf2, theUVSurf1, aNbWLines,
-                                        aPeriod, theTol3D, theTol2D, Standard_True);
-
-    return CyCyNoGeometric(aCyl2, aCyl1, aBoundWork, anURange[1], aNbOfBoundaries,
-                              isTheEmpty, theSlin, theSPnt);
-  }
-  else
-  {
-    const WorkWithBoundaries aBoundWork(theQuad1, theQuad2, anEquationCoeffs1,
-                                        theUVSurf1, theUVSurf2, aNbWLines,
-                                        aPeriod, theTol3D, theTol2D, Standard_False);
-
-    return CyCyNoGeometric(aCyl1, aCyl2, aBoundWork, anURange[0], aNbOfBoundaries,
-                              isTheEmpty, theSlin, theSPnt);
-  }
-}
-
-//=======================================================================
-//function : IntCySp
-//purpose  : 
-//=======================================================================
-Standard_Boolean IntCySp(const IntSurf_Quadric& Quad1,
-                        const IntSurf_Quadric& Quad2,
-                        const Standard_Real Tol,
-                        const Standard_Boolean Reversed,
-                        Standard_Boolean& Empty,
-                        Standard_Boolean& Multpoint,
-                        IntPatch_SequenceOfLine& slin,
-                        IntPatch_SequenceOfPoint& spnt)
-
-{
-  Standard_Integer i;
-
-  IntSurf_TypeTrans trans1,trans2;
-  IntAna_ResultType typint;
-  IntPatch_Point ptsol;
-  gp_Circ cirsol;
-
-  gp_Cylinder Cy;
-  gp_Sphere Sp;
-
-  if (!Reversed) {
-    Cy = Quad1.Cylinder();
-    Sp = Quad2.Sphere();
-  }
-  else {
-    Cy = Quad2.Cylinder();
-    Sp = Quad1.Sphere();
-  }
-  IntAna_QuadQuadGeo inter(Cy,Sp,Tol);
-
-  if (!inter.IsDone()) {return Standard_False;}
-
-  typint = inter.TypeInter();
-  Standard_Integer NbSol = inter.NbSolutions();
-  Empty = Standard_False;
-
-  switch (typint) {
-
-  case IntAna_Empty :
-    {
-      Empty = Standard_True;
-    }
-    break;
-
-  case IntAna_Point :
-    {
-      gp_Pnt psol(inter.Point(1));
-      Standard_Real U1,V1,U2,V2;
-      Quad1.Parameters(psol,U1,V1);
-      Quad2.Parameters(psol,U2,V2);
-      ptsol.SetValue(psol,Tol,Standard_True);
-      ptsol.SetParameters(U1,V1,U2,V2);
-      spnt.Append(ptsol);
-    }
-    break;
-
-  case IntAna_Circle:
-    {
-      cirsol = inter.Circle(1);
-      gp_Vec Tgt;
-      gp_Pnt ptref;
-      ElCLib::D1(0.,cirsol,ptref,Tgt);
-
-      if (NbSol == 1) {
-       gp_Vec TestCurvature(ptref,Sp.Location());
-       gp_Vec Normsp,Normcyl;
-       if (!Reversed) {
-         Normcyl = Quad1.Normale(ptref);
-         Normsp  = Quad2.Normale(ptref);
-       }
-       else {
-         Normcyl = Quad2.Normale(ptref);
-         Normsp  = Quad1.Normale(ptref);
-       }
-       
-       IntSurf_Situation situcyl;
-       IntSurf_Situation situsp;
-       
-       if (Normcyl.Dot(TestCurvature) > 0.) {
-         situsp = IntSurf_Outside;
-         if (Normsp.Dot(Normcyl) > 0.) {
-           situcyl = IntSurf_Inside;
-         }
-         else {
-           situcyl = IntSurf_Outside;
-         }
-       }
-       else {
-         situsp = IntSurf_Inside;
-         if (Normsp.Dot(Normcyl) > 0.) {
-           situcyl = IntSurf_Outside;
-         }
-         else {
-           situcyl = IntSurf_Inside;
-         }
-       }
-       Handle(IntPatch_GLine) glig;
-       if (!Reversed) {
-         glig = new IntPatch_GLine(cirsol, Standard_True, situcyl, situsp);
-       }
-       else {
-         glig = new IntPatch_GLine(cirsol, Standard_True, situsp, situcyl);
-       }
-       slin.Append(glig);
-      }
-      else {
-       if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) > 0.0) {
-         trans1 = IntSurf_Out;
-         trans2 = IntSurf_In;
-       }
-       else {
-         trans1 = IntSurf_In;
-         trans2 = IntSurf_Out;
-       }
-       Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
-       slin.Append(glig);
-
-       cirsol = inter.Circle(2);
-       ElCLib::D1(0.,cirsol,ptref,Tgt);
-       Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
-       if(qwe> 0.0000001) {
-         trans1 = IntSurf_Out;
-         trans2 = IntSurf_In;
-       }
-       else if(qwe<-0.0000001) {
-         trans1 = IntSurf_In;
-         trans2 = IntSurf_Out;
-       }
-       else { 
-         trans1=trans2=IntSurf_Undecided; 
-       }
-       glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
-       slin.Append(glig);
-      }
-    }
-    break;
-    
-  case IntAna_NoGeometricSolution:
-    {
-      gp_Pnt psol;
-      Standard_Real U1,V1,U2,V2;
-      IntAna_IntQuadQuad anaint(Cy,Sp,Tol);
-      if (!anaint.IsDone()) {
-       return Standard_False;
-      }
-
-      if (anaint.NbPnt()==0 && anaint.NbCurve()==0) {
-       Empty = Standard_True;
-      }
-      else {
-
-       NbSol = anaint.NbPnt();
-       for (i = 1; i <= NbSol; i++) {
-         psol = anaint.Point(i);
-         Quad1.Parameters(psol,U1,V1);
-         Quad2.Parameters(psol,U2,V2);
-         ptsol.SetValue(psol,Tol,Standard_True);
-         ptsol.SetParameters(U1,V1,U2,V2);
-         spnt.Append(ptsol);
-       }
-       
-       gp_Pnt ptvalid,ptf,ptl;
-       gp_Vec tgvalid;
-       Standard_Real first,last,para;
-       IntAna_Curve curvsol;
-       Standard_Boolean tgfound;
-       Standard_Integer kount;
-       
-       NbSol = anaint.NbCurve();
-       for (i = 1; i <= NbSol; i++) {
-         curvsol = anaint.Curve(i);
-         curvsol.Domain(first,last);
-         ptf = curvsol.Value(first);
-         ptl = curvsol.Value(last);
-
-         para = last;
-         kount = 1;
-         tgfound = Standard_False;
-         
-         while (!tgfound) {
-           para = (1.123*first + para)/2.123;
-           tgfound = curvsol.D1u(para,ptvalid,tgvalid);
-           if (!tgfound) {
-             kount ++;
-             tgfound = kount > 5;
-           }
-         }
-         Handle(IntPatch_ALine) alig;
-         if (kount <= 5) {
-           Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid),
-                                                Quad1.Normale(ptvalid));
-           if(qwe> 0.00000001) {
-             trans1 = IntSurf_Out;
-             trans2 = IntSurf_In;
-           }
-           else if(qwe<-0.00000001) {
-             trans1 = IntSurf_In;
-             trans2 = IntSurf_Out;
-           }
-           else { 
-             trans1=trans2=IntSurf_Undecided; 
-           }
-           alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2);
-         }
-         else {
-           alig = new IntPatch_ALine(curvsol,Standard_False);
-         }
-         Standard_Boolean TempFalse1a = Standard_False;
-         Standard_Boolean TempFalse2a = Standard_False;
-
-         //-- ptf et ptl : points debut et fin de alig 
-         
-         ProcessBounds(alig,slin,Quad1,Quad2,TempFalse1a,ptf,first,
-                       TempFalse2a,ptl,last,Multpoint,Tol);
-         slin.Append(alig);
-       } //-- boucle sur les lignes 
-      } //-- solution avec au moins une lihne 
-    }
-    break;
-
-  default:
-    {
-      return Standard_False;
-    }
-  }
-  return Standard_True;
-}
-//=======================================================================
-//function : IntCyCo
-//purpose  : 
-//=======================================================================
-Standard_Boolean IntCyCo(const IntSurf_Quadric& Quad1,
-                        const IntSurf_Quadric& Quad2,
-                        const Standard_Real Tol,
-                        const Standard_Boolean Reversed,
-                        Standard_Boolean& Empty,
-                        Standard_Boolean& Multpoint,
-                        IntPatch_SequenceOfLine& slin,
-                        IntPatch_SequenceOfPoint& spnt)
-
-{
-  IntPatch_Point ptsol;
-
-  Standard_Integer i;
-
-  IntSurf_TypeTrans trans1,trans2;
-  IntAna_ResultType typint;
-  gp_Circ cirsol;
-
-  gp_Cylinder Cy;
-  gp_Cone     Co;
-
-  if (!Reversed) {
-    Cy = Quad1.Cylinder();
-    Co = Quad2.Cone();
-  }
-  else {
-    Cy = Quad2.Cylinder();
-    Co = Quad1.Cone();
-  }
-  IntAna_QuadQuadGeo inter(Cy,Co,Tol);
-
-  if (!inter.IsDone()) {return Standard_False;}
-
-  typint = inter.TypeInter();
-  Standard_Integer NbSol = inter.NbSolutions();
-  Empty = Standard_False;
-
-  switch (typint) {
-
-  case IntAna_Empty : {
-    Empty = Standard_True;
-  }
-    break;
-
-  case IntAna_Point :{
-    gp_Pnt psol(inter.Point(1));
-    Standard_Real U1,V1,U2,V2;
-    Quad1.Parameters(psol,U1,V1);
-    Quad1.Parameters(psol,U2,V2);
-    ptsol.SetValue(psol,Tol,Standard_True);
-    ptsol.SetParameters(U1,V1,U2,V2);
-    spnt.Append(ptsol);
-  }
-    break;
-    
-  case IntAna_Circle:  {
-    gp_Vec Tgt;
-    gp_Pnt ptref;
-    Standard_Integer j;
-    Standard_Real qwe;
-    //
-    for(j=1; j<=2; ++j) { 
-      cirsol = inter.Circle(j);
-      ElCLib::D1(0.,cirsol,ptref,Tgt);
-      qwe = Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
-      if(qwe> 0.00000001) {
-       trans1 = IntSurf_Out;
-       trans2 = IntSurf_In;
-      }
-      else if(qwe<-0.00000001) {
-       trans1 = IntSurf_In;
-       trans2 = IntSurf_Out;
-      }
-      else { 
-       trans1=trans2=IntSurf_Undecided; 
-      }
-      Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
-      slin.Append(glig);
-    }
-  }
-    break;
-    
-  case IntAna_NoGeometricSolution:    {
-    gp_Pnt psol;
-    Standard_Real U1,V1,U2,V2;
-    IntAna_IntQuadQuad anaint(Cy,Co,Tol);
-    if (!anaint.IsDone()) {
-      return Standard_False;
-    }
-    
-    if (anaint.NbPnt() == 0 && anaint.NbCurve() == 0) {
-      Empty = Standard_True;
-    }
-    else {
-      NbSol = anaint.NbPnt();
-      for (i = 1; i <= NbSol; i++) {
-       psol = anaint.Point(i);
-       Quad1.Parameters(psol,U1,V1);
-       Quad2.Parameters(psol,U2,V2);
-       ptsol.SetValue(psol,Tol,Standard_True);
-       ptsol.SetParameters(U1,V1,U2,V2);
-       spnt.Append(ptsol);
-      }
-      
-      gp_Pnt ptvalid, ptf, ptl;
-      gp_Vec tgvalid;
-      //
-      Standard_Real first,last,para;
-      Standard_Boolean tgfound,firstp,lastp,kept;
-      Standard_Integer kount;
-      //
-      //
-      //IntAna_Curve curvsol;
-      IntAna_Curve aC;
-      IntAna_ListOfCurve aLC;
-      IntAna_ListIteratorOfListOfCurve aIt;
-      
-      //
-      NbSol = anaint.NbCurve();
-      for (i = 1; i <= NbSol; ++i) {
-       kept = Standard_False;
-       //curvsol = anaint.Curve(i);
-       aC=anaint.Curve(i);
-       aLC.Clear();
-       ExploreCurve(Co, aC, 10.*Tol, aLC);
-       //
-       aIt.Initialize(aLC);
-       for (; aIt.More(); aIt.Next()) {
-         IntAna_Curve& curvsol=aIt.ChangeValue();
-         //
-         curvsol.Domain(first, last);
-         firstp = !curvsol.IsFirstOpen();
-         lastp  = !curvsol.IsLastOpen();
-         if (firstp) {
-           ptf = curvsol.Value(first);
-         }
-         if (lastp) {
-           ptl = curvsol.Value(last);
-         }
-         para = last;
-         kount = 1;
-         tgfound = Standard_False;
-         
-         while (!tgfound) {
-           para = (1.123*first + para)/2.123;
-           tgfound = curvsol.D1u(para,ptvalid,tgvalid);
-           if (!tgfound) {
-             kount ++;
-             tgfound = kount > 5;
-           }
-         }
-         Handle(IntPatch_ALine) alig;
-         if (kount <= 5) {
-           Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid),
-                                                Quad1.Normale(ptvalid));
-           if(qwe> 0.00000001) {
-             trans1 = IntSurf_Out;
-             trans2 = IntSurf_In;
-           }
-           else if(qwe<-0.00000001) {
-             trans1 = IntSurf_In;
-             trans2 = IntSurf_Out;
-           }
-           else { 
-             trans1=trans2=IntSurf_Undecided; 
-           }
-           alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2);
-           kept = Standard_True;
-         }
-         else {
-           ptvalid = curvsol.Value(para);
-           alig = new IntPatch_ALine(curvsol,Standard_False);
-           kept = Standard_True;
-           //-- std::cout << "Transition indeterminee" << std::endl;
-         }
-         if (kept) {
-           Standard_Boolean Nfirstp = !firstp;
-           Standard_Boolean Nlastp  = !lastp;
-           ProcessBounds(alig,slin,Quad1,Quad2,Nfirstp,ptf,first,
-                         Nlastp,ptl,last,Multpoint,Tol);
-           slin.Append(alig);
-         }
-       } // for (; aIt.More(); aIt.Next())
-      } // for (i = 1; i <= NbSol; ++i) 
-    }
-  }
-    break;
-    
-  default:
-    return Standard_False;
-    
-  } // switch (typint)
-  
-  return Standard_True;
-}
-//=======================================================================
-//function : ExploreCurve
-//purpose  : Splits aC on several curves in the cone apex points.
-//=======================================================================
-Standard_Boolean ExploreCurve(const gp_Cone& theCo,
-                              IntAna_Curve& theCrv,
-                              const Standard_Real theTol,
-                              IntAna_ListOfCurve& theLC)
-{
-  const Standard_Real aSqTol = theTol*theTol;
-  const gp_Pnt aPapx(theCo.Apex());
-
-  Standard_Real aT1, aT2;
-  theCrv.Domain(aT1, aT2);
-
-  theLC.Clear();
-  //
-  TColStd_ListOfReal aLParams;
-  theCrv.FindParameter(aPapx, aLParams);
-  if (aLParams.IsEmpty())
-  {
-    theLC.Append(theCrv);
-    return Standard_False;
-  }
-
-  for (TColStd_ListIteratorOfListOfReal anItr(aLParams); anItr.More(); anItr.Next())
-  {
-    Standard_Real aPrm = anItr.Value();
-
-    if ((aPrm - aT1) < Precision::PConfusion())
-      continue;
-
-    Standard_Boolean isLast = Standard_False;
-    if ((aT2 - aPrm) < Precision::PConfusion())
-    {
-      aPrm = aT2;
-      isLast = Standard_True;
-    }
-
-    const gp_Pnt aP = theCrv.Value(aPrm);
-    const Standard_Real aSqD = aP.SquareDistance(aPapx);
-    if (aSqD < aSqTol)
-    {
-      IntAna_Curve aC1 = theCrv;
-      aC1.SetDomain(aT1, aPrm);
-      aT1 = aPrm;
-      theLC.Append(aC1);
-    }
-
-    if (isLast)
-      break;
-  }
-
-  if (theLC.IsEmpty())
-  {
-    theLC.Append(theCrv);
-    return Standard_False;
-  }
-
-  if ((aT2 - aT1) > Precision::PConfusion())
-  {
-    IntAna_Curve aC1 = theCrv;
-    aC1.SetDomain(aT1, aT2);
-    theLC.Append(aC1);
-  }
-
-  return Standard_True;
-}
diff --git a/src/IntPatch/IntPatch_ImpImpIntersection_5.gxx b/src/IntPatch/IntPatch_ImpImpIntersection_5.gxx
deleted file mode 100644 (file)
index bdbe126..0000000
+++ /dev/null
@@ -1,832 +0,0 @@
-// Created on: 1992-05-07
-// Created by: Jacques GOUSSARD
-// Copyright (c) 1992-1999 Matra Datavision
-// Copyright (c) 1999-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 <gce_MakeLin.hxx>
-
-//=======================================================================
-//function : IntCoCo
-//purpose  : 
-//=======================================================================
-Standard_Boolean IntCoCo(const IntSurf_Quadric& Quad1,
-                        const IntSurf_Quadric& Quad2,
-                        const Standard_Real Tol,
-                        Standard_Boolean& Empty,
-                        Standard_Boolean& Same,
-                        Standard_Boolean& Multpoint,
-                        IntPatch_SequenceOfLine& slin,
-                        IntPatch_SequenceOfPoint& spnt)
-
-{
-  Standard_Integer i, NbSol;
-  Standard_Real U1,V1,U2,V2;
-  IntSurf_TypeTrans trans1,trans2;
-  IntAna_ResultType typint;
-  //
-  gp_Cone Co1(Quad1.Cone());
-  gp_Cone Co2(Quad2.Cone());
-  //
-  IntAna_QuadQuadGeo inter(Co1,Co2,Tol);
-  if (!inter.IsDone()) {
-    return Standard_False;
-  }
-  //
-  typint = inter.TypeInter();
-  NbSol = inter.NbSolutions();
-  Empty = Standard_False;
-  Same  = Standard_False;
-
-  switch (typint) {
-
-  case IntAna_Empty :
-    {
-      Empty = Standard_True;
-    }
-    break;
-
-  case IntAna_Same:
-    {
-       Same  = Standard_True;
-    }
-    break;
-
-    //modified by NIZNHY-PKV Wed Nov 30 12:56:06 2005f
-  case IntAna_Line :{
-    Standard_Real para, aDot;
-    gp_Pnt aPApex1, aPApex2, ptbid;
-    gp_Lin linsol;
-    gp_Vec NormC1,NormC2;
-    IntPatch_Point aPtsol;
-    Handle(IntPatch_GLine) glig;
-    //
-    aPApex1=Co1.Apex();
-    aPApex2=Co2.Apex();
-    //
-    if (NbSol==1) {
-      IntSurf_Situation situC1, situC2;
-      //
-      linsol = inter.Line(1);
-      para =ElCLib::Parameter(linsol, aPApex1);
-      ptbid=ElCLib::Value(para+5., linsol);
-      Quad1.Parameters(aPApex1, U1, V1);
-      Quad2.Parameters(aPApex1, U2, V2);
-      //
-      aPtsol.SetValue(aPApex1, Tol, Standard_False);
-      aPtsol.SetParameters(U1, V1, U2, V2);
-      aPtsol.SetParameter(para);
-      //
-      NormC1=Quad1.Normale(ptbid);
-      NormC2=Quad2.Normale(ptbid);
-      aDot=NormC1.Dot(NormC2);
-      if (aDot<0.) {
-       situC1=IntSurf_Outside;
-       situC2=IntSurf_Outside;
-      }
-      else {
-       Standard_Real aR1, aR2;
-       gp_Lin aLAx1(aPApex1, Co1.Axis().Direction());
-       gp_Lin aLAx2(aPApex2, Co2.Axis().Direction());
-       //
-       aR1=aLAx1.Distance(ptbid);
-       aR2=aLAx2.Distance(ptbid);
-       //
-       situC1=IntSurf_Inside;
-       situC2=IntSurf_Outside;
-       if (aR1>aR2) {                                  // Intersection line parametrizes from Apex1 to Apex2,
-         situC1=IntSurf_Outside;               // So the distance between ptbid and aLAx1 is greater than the
-         situC2=IntSurf_Inside;                // distance between ptbid and aLAx2 and in that case Cone2 
-                                                                       // is inside Cone 1
-       }
-      }
-      // 1
-      glig=new IntPatch_GLine(linsol, Standard_True, situC1, situC2);
-      glig->AddVertex(aPtsol);
-      glig->SetFirstPoint(1);
-      slin.Append(glig);
-      // 2
-      linsol.SetDirection(linsol.Direction().Reversed());
-      para =ElCLib::Parameter(linsol, aPApex1);
-      aPtsol.SetParameter(para);
-      
-      glig = new IntPatch_GLine(linsol, Standard_True, situC2, situC1);
-      glig->AddVertex(aPtsol);
-      glig->SetFirstPoint(1);
-      slin.Append(glig);
-    } // if (NbSol==1) {
-    //////////////////////
-    else if (NbSol==2) {
-      //
-      for (i=1; i<=2; ++i) {
-       linsol = inter.Line(i);
-       para =ElCLib::Parameter(linsol, aPApex1);
-       ptbid=ElCLib::Value(para+5., linsol);
-       Quad1.Parameters(aPApex1, U1, V1);
-       Quad2.Parameters(aPApex1, U2, V2);
-       //
-       trans1 = IntSurf_In;
-       trans2 = IntSurf_Out;
-       if (linsol.Direction().
-           DotCross(Quad2.Normale(ptbid),Quad1.Normale(ptbid)) >0.) {
-         trans1 = IntSurf_Out;
-         trans2 = IntSurf_In;
-       }
-       //
-       Multpoint = Standard_True;
-       // 1,3
-       aPtsol.SetValue(aPApex1, Tol, Standard_False);
-       aPtsol.SetParameters(U1,V1,U2,V2);
-       aPtsol.SetParameter(para);
-       aPtsol.SetMultiple(Standard_True);
-       
-       glig = new IntPatch_GLine(linsol, Standard_False, trans1, trans2);
-       glig->AddVertex(aPtsol);
-       glig->SetFirstPoint(1);
-       slin.Append(glig);
-       // 2,4
-       linsol.SetDirection(linsol.Direction().Reversed());
-       para = ElCLib::Parameter(linsol, aPApex1);
-       aPtsol.SetParameter(para);
-       glig = new IntPatch_GLine(linsol, Standard_False, trans1, trans2);
-       glig->AddVertex(aPtsol);
-       glig->SetFirstPoint(1);
-       slin.Append(glig);
-       //
-      } //for (i=1; i<=2; ++i) 
-    } //else if (NbSol==2)
-  }
-    break;
-    //modified by NIZNHY-PKV Wed Nov 30 12:56:10 2005t
-  
-  case IntAna_Point : {
-    gp_Pnt ptcontact;
-    gp_Pnt apex1(Co1.Apex());
-    gp_Pnt apex2(Co2.Apex());
-    Standard_Real param1,param2;
-    Standard_Real paramapex1   = ElCLib::LineParameter(Co1.Axis(),apex1);
-    Standard_Real paramapex2   = ElCLib::LineParameter(Co2.Axis(),apex2);
-    for (i=1; i <= NbSol; i++) {
-      ptcontact = inter.Point(i);
-      param1 = ElCLib::LineParameter(Co1.Axis(),ptcontact);
-      param2 = ElCLib::LineParameter(Co2.Axis(),ptcontact);
-      
-      Quad1.Parameters(ptcontact,U1,V1);
-      Quad2.Parameters(ptcontact,U2,V2);
-      
-      if (apex1.Distance(ptcontact) <= Tol &&
-         apex2.Distance(ptcontact) <= Tol) {
-       IntPatch_Point ptsol;
-       ptsol.SetValue(ptcontact,Tol,Standard_False);
-       ptsol.SetParameters(U1,V1,U2,V2);
-       spnt.Append(ptsol);
-      }
-      else if (param1 >= paramapex1 && param2 >= paramapex2) {
-       IntPatch_Point ptsol;
-       ptsol.SetValue(ptcontact,Tol,Standard_True);
-       ptsol.SetParameters(U1,V1,U2,V2);
-       spnt.Append(ptsol);
-      }
-    }
-  }
-    break;
-
-  case IntAna_Circle:
-    {
-      IntPatch_Point aPtsol;
-      gp_Vec Tgt;
-      gp_Pnt ptref;
-      for (i = 1; i <= NbSol; i++) {
-       gp_Circ cirsol = inter.Circle(i);
-       ElCLib::D1(0.,cirsol,ptref,Tgt);
-       Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
-       if(qwe> 0.00000001) {
-         trans1 = IntSurf_Out;
-         trans2 = IntSurf_In;
-       }
-       else if(qwe<-0.00000001){
-         trans1 = IntSurf_In;
-         trans2 = IntSurf_Out;
-       }
-       else { 
-         trans1=trans2=IntSurf_Undecided; 
-       }
-       Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
-       if(inter.HasCommonGen()) {
-         const gp_Pnt& aPChar = inter.PChar();
-         Quad1.Parameters(aPChar, U1, V1);
-         Quad2.Parameters(aPChar, U2, V2);
-         aPtsol.SetValue(aPChar, Tol, Standard_False);
-         aPtsol.SetParameters(U1, V1, U2, V2);
-         aPtsol.SetParameter(0.);
-         glig->AddVertex(aPtsol);
-       }
-       slin.Append(glig);
-      }
-    }
-    break;
-
-
-  case IntAna_Ellipse:
-    {
-      IntPatch_Point aPtsol;
-      gp_Elips elipsol = inter.Ellipse(1);
-      
-      gp_Vec Tgt;
-      gp_Pnt ptref;
-      ElCLib::D1(0.,elipsol,ptref,Tgt);
-      
-      Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
-      if(qwe> 0.00000001) {
-       trans1 = IntSurf_Out;
-       trans2 = IntSurf_In;
-      }
-      else if(qwe<-0.00000001) {
-       trans1 = IntSurf_In;
-       trans2 = IntSurf_Out;
-      }
-      else { 
-       trans1=trans2=IntSurf_Undecided;
-      }
-      Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2);
-      if(inter.HasCommonGen()) {
-       const gp_Pnt& aPChar = inter.PChar();
-       Quad1.Parameters(aPChar, U1, V1);
-       Quad2.Parameters(aPChar, U2, V2);
-       aPtsol.SetValue(aPChar, Tol, Standard_False);
-       aPtsol.SetParameters(U1, V1, U2, V2);
-       aPtsol.SetParameter(0.);
-       glig->AddVertex(aPtsol);
-      }
-      slin.Append(glig);
-      
-    }
-    break;
-
-
-  case IntAna_Hyperbola:
-    {
-      IntPatch_Point aPtsol;
-      gp_Vec Tgt;
-      gp_Pnt ptref;
-      for(i=1; i<=2; i++) { 
-       gp_Hypr hyprsol = inter.Hyperbola(i);
-       ElCLib::D1(0.,hyprsol,ptref,Tgt);
-       Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
-       if(qwe> 0.00000001) {
-         trans1 = IntSurf_Out;
-         trans2 = IntSurf_In;
-       }
-       else if(qwe<-0.00000001){
-         trans1 = IntSurf_In;
-         trans2 = IntSurf_Out;
-       }
-       else { 
-         trans1=trans2=IntSurf_Undecided; 
-       }
-       Handle(IntPatch_GLine) glig = new IntPatch_GLine(hyprsol,Standard_False,trans1,trans2);
-       if(inter.HasCommonGen()) {
-         const gp_Pnt& aPChar = inter.PChar();
-         Quad1.Parameters(aPChar, U1, V1);
-         Quad2.Parameters(aPChar, U2, V2);
-         aPtsol.SetValue(aPChar, Tol, Standard_False);
-         aPtsol.SetParameters(U1, V1, U2, V2);
-         aPtsol.SetParameter(0.);
-         glig->AddVertex(aPtsol);
-       }
-       slin.Append(glig);
-      }
-    }
-    break;
-    
-  case IntAna_Parabola:
-    {
-      IntPatch_Point aPtsol;
-      gp_Parab parabsol = inter.Parabola(1);
-      
-      gp_Vec Tgtorig(parabsol.YAxis().Direction());
-      Standard_Real ptran = Tgtorig.DotCross(Quad2.Normale(parabsol.Location()),
-                                              Quad1.Normale(parabsol.Location()));
-      if (ptran >0.00000001) {
-       trans1 = IntSurf_Out;
-       trans2 = IntSurf_In;
-      }
-      else if (ptran <-0.00000001) {
-       trans1 = IntSurf_In;
-       trans2 = IntSurf_Out;
-      }
-      else { 
-       trans1=trans2=IntSurf_Undecided; 
-      }
-
-      Handle(IntPatch_GLine) glig = new IntPatch_GLine(parabsol,Standard_False,trans1,trans2);
-      if(inter.HasCommonGen()) {
-       const gp_Pnt& aPChar = inter.PChar();
-       Quad1.Parameters(aPChar, U1, V1);
-       Quad2.Parameters(aPChar, U2, V2);
-       aPtsol.SetValue(aPChar, Tol, Standard_False);
-       aPtsol.SetParameters(U1, V1, U2, V2);
-       aPtsol.SetParameter(0.);
-       glig->AddVertex(aPtsol);
-      }
-      slin.Append(glig);
-    }
-    break;
-    
-    
-  case IntAna_NoGeometricSolution:
-    {
-      gp_Pnt psol;
-      IntAna_IntQuadQuad anaint(Co1,Co2,Tol);
-      if (!anaint.IsDone()) {
-       return Standard_False;
-      }
-
-      if (anaint.NbPnt() == 0 && anaint.NbCurve() == 0) {
-       Empty = Standard_True;
-      }
-      else {
-       NbSol = anaint.NbPnt();
-       for (i = 1; i <= NbSol; i++) {
-         psol = anaint.Point(i);
-         Quad1.Parameters(psol,U1,V1);
-         Quad2.Parameters(psol,U2,V2);
-         IntPatch_Point ptsol;
-         ptsol.SetValue(psol,Tol,Standard_True);
-         ptsol.SetParameters(U1,V1,U2,V2);
-         spnt.Append(ptsol);
-       }
-
-       gp_Pnt ptvalid, ptf, ptl;
-       gp_Vec tgvalid;
-
-       Standard_Real first,last,para;
-       Standard_Boolean tgfound,firstp,lastp,kept;
-       Standard_Integer kount;
-       
-       NbSol = anaint.NbCurve();
-       for (i = 1; i <= NbSol; i++) {
-         Handle(IntPatch_ALine) alig;
-         kept = Standard_False;
-         IntAna_Curve curvsol = anaint.Curve(i);
-         curvsol.Domain(first,last);
-         firstp = !curvsol.IsFirstOpen();
-         lastp  = !curvsol.IsLastOpen();
-         if (firstp) {
-           ptf = curvsol.Value(first);
-         }
-         if (lastp) {
-           ptl = curvsol.Value(last);
-         }
-         para = last;
-         kount = 1;
-         tgfound = Standard_False;
-         
-         while (!tgfound) {
-           para = (1.123*first + para)/2.123;
-           tgfound = curvsol.D1u(para,ptvalid,tgvalid);
-           if(tgvalid.SquareMagnitude() < 1e-14) { 
-             //-- on se trouve ds un cas ou les normales n'auront pas de sens
-             tgfound = Standard_False; 
-           } 
-             
-           if (!tgfound) {
-             kount ++;
-             tgfound = kount > 5;
-           }
-         }
-         if (kount <= 5) {
-           Standard_Real qwe= tgvalid.DotCross(Quad2.Normale(ptvalid),
-                                               Quad1.Normale(ptvalid));
-           if(qwe > 0.000000001) {
-             trans1 = IntSurf_Out;
-             trans2 = IntSurf_In;
-           }
-           else if(qwe < -0.000000001) {
-             trans1 = IntSurf_In;
-             trans2 = IntSurf_Out;
-           }
-           else { 
-             trans1=trans2=IntSurf_Undecided;
-           }
-           alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2);
-           kept = Standard_True;
-         }
-         else {
-           ptvalid = curvsol.Value(para);
-           alig = new IntPatch_ALine(curvsol,Standard_False);
-           kept = Standard_True;
-           //-- cout << "Transition indeterminee" << endl;
-         }
-         if (kept) {
-           Standard_Boolean Nfirstp = !firstp;
-           Standard_Boolean Nlastp  = !lastp;
-           ProcessBounds(alig,slin,Quad1,Quad2,Nfirstp,ptf,first,
-                         Nlastp,ptl,last,Multpoint,Tol);
-           slin.Append(alig);
-         }
-       }
-      }
-    }
-    break;
-    
-  default:
-    {
-      return Standard_False;
-    }
-  }
-
-  //When two cones have common generatrix passing through apexes
-  //it is necessary to add it is solution
-  if(inter.HasCommonGen()) {
-    Standard_Real para;
-    IntPatch_Point aPtsol;
-    gp_Pnt aPApex1, aPApex2;
-    aPApex1=Co1.Apex();
-    aPApex2=Co2.Apex();
-    //common generatrix of cones
-    gce_MakeLin aMkLin(aPApex1, aPApex2);
-    const gp_Lin& linsol = aMkLin.Value();
-    Handle(IntPatch_GLine) glig = 
-      new IntPatch_GLine(linsol,Standard_True,IntSurf_Undecided,IntSurf_Undecided);
-    
-    const gp_Pnt& aPChar = inter.PChar();
-    Quad1.Parameters(aPChar, U1, V1);
-    Quad2.Parameters(aPChar, U2, V2);
-    aPtsol.SetValue(aPChar, Tol, Standard_False);
-    aPtsol.SetParameters(U1, V1, U2, V2);
-    para = ElCLib::Parameter(linsol, aPChar);
-    aPtsol.SetParameter(para);
-    glig->AddVertex(aPtsol);
-
-    slin.Append(glig);
-
-  }    
-
-  return Standard_True;
-}
-//=======================================================================
-//function : IntCoSp
-//purpose  : 
-//=======================================================================
-Standard_Boolean IntCoSp(const IntSurf_Quadric& Quad1,
-                        const IntSurf_Quadric& Quad2,
-                        const Standard_Real Tol,
-                        const Standard_Boolean Reversed,
-                        Standard_Boolean& Empty,
-                        Standard_Boolean& Multpoint,
-                        IntPatch_SequenceOfLine& slin,
-                        IntPatch_SequenceOfPoint& spnt)
-
-{
-
-  Standard_Integer i;
-
-  IntSurf_TypeTrans trans1,trans2;
-  IntAna_ResultType typint;
-
-  gp_Sphere Sp;
-  gp_Cone   Co;
-  Standard_Real U1,V1,U2,V2;
-
-  if (!Reversed) {
-    Co = Quad1.Cone();
-    Sp = Quad2.Sphere();
-  }
-  else {
-    Co = Quad2.Cone();
-    Sp = Quad1.Sphere();
-  }
-  IntAna_QuadQuadGeo inter(Sp,Co,Tol);
-
-  if (!inter.IsDone()) {return Standard_False;}
-
-  typint = inter.TypeInter();
-  Standard_Integer NbSol = inter.NbSolutions();
-  Empty = Standard_False;
-
-  switch (typint) {
-
-  case IntAna_Empty :
-    {
-      Empty = Standard_True;
-    }
-    break;
-
-  case IntAna_Point :
-    {
-      gp_Pnt ptcontact;
-      gp_Pnt apex(Co.Apex());
-      Standard_Real param;
-      Standard_Real paramapex   = ElCLib::LineParameter(Co.Axis(),apex);
-      for (i=1; i <= NbSol; i++) {
-       ptcontact = inter.Point(i);
-       param = ElCLib::LineParameter(Co.Axis(),ptcontact);
-       Quad1.Parameters(ptcontact,U1,V1);
-       Quad2.Parameters(ptcontact,U2,V2);
-
-       if (apex.Distance(ptcontact) <= Tol) {
-         IntPatch_Point ptsol;
-         ptsol.SetValue(ptcontact,Tol,Standard_False);
-         ptsol.SetParameters(U1,V1,U2,V2);
-         spnt.Append(ptsol);
-       }
-       else if (param >= paramapex) {
-         IntPatch_Point ptsol;
-         ptsol.SetValue(ptcontact,Tol,Standard_True);
-         ptsol.SetParameters(U1,V1,U2,V2);
-         spnt.Append(ptsol);
-       }
-      }
-    }
-    break;
-
-  case IntAna_Circle:
-    {
-      gp_Vec Tgt;
-      gp_Pnt ptref;
-
-      for (i=1; i<=NbSol; i++) {
-       gp_Circ cirsol = inter.Circle(i);
-       //-- param = ElCLib::LineParameter(Co.Axis(),
-       //--                          cirsol.Location());
-       //-- if (param >= paramapex) {
-       
-       ElCLib::D1(0.,cirsol,ptref,Tgt);
-       Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref),
-                                        Quad1.Normale(ptref));
-       if(qwe> 0.00000001) {
-         trans1 = IntSurf_Out;
-         trans2 = IntSurf_In;
-       }
-       else if(qwe< -0.00000001) {
-         trans1 = IntSurf_In;
-         trans2 = IntSurf_Out;
-       }
-       else { 
-         trans1=trans2=IntSurf_Undecided; 
-       }
-       Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
-       slin.Append(glig);
-       //-- }
-      }
-    }
-    break;
-
-  case IntAna_PointAndCircle:
-    {
-      gp_Vec Tgt;
-      gp_Pnt ptref;
-      gp_Pnt apex(Co.Apex());
-      Standard_Real param;
-      Standard_Real paramapex   = ElCLib::LineParameter(Co.Axis(),apex);
-
-      // le point est necessairement l apex
-      Quad1.Parameters(apex,U1,V1);
-      Quad2.Parameters(apex,U2,V2);
-      IntPatch_Point ptsol;
-      ptsol.SetValue(apex,Tol,Standard_False);
-      ptsol.SetParameters(U1,V1,U2,V2);
-      spnt.Append(ptsol);
-
-      gp_Circ cirsol = inter.Circle(1);
-      param = ElCLib::LineParameter(Co.Axis(),
-                                    cirsol.Location());
-      ElCLib::D1(0., cirsol, ptref, Tgt);
-      Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref),
-                                       Quad1.Normale(ptref));
-
-      if (param >= paramapex)
-      {
-        if (qwe > Precision::PConfusion())
-        {
-          trans1 = IntSurf_Out;
-          trans2 = IntSurf_In;
-        }
-        else if (qwe < -Precision::PConfusion())
-        {
-          trans1 = IntSurf_In;
-          trans2 = IntSurf_Out;
-        }
-        else
-        {
-          trans1 = trans2 = IntSurf_Undecided;
-        }
-      }
-      else
-      {
-        if (qwe < -Precision::PConfusion())
-        {
-          trans1 = IntSurf_Out;
-          trans2 = IntSurf_In;
-        }
-        else if (qwe > Precision::PConfusion())
-        {
-          trans1 = IntSurf_In;
-          trans2 = IntSurf_Out;
-        }
-        else
-        {
-          trans1 = trans2 = IntSurf_Undecided;
-        }
-      }
-      Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol, Standard_False, trans1, trans2);
-      slin.Append(glig);
-    }
-    break;
-
-  case IntAna_NoGeometricSolution:
-    {
-      gp_Pnt psol;
-      IntAna_IntQuadQuad anaint(Co,Sp,Tol);
-      if (!anaint.IsDone()) {
-       return Standard_False;
-      }
-      
-      if (anaint.NbPnt()==0 && anaint.NbCurve()==0) {
-       Empty = Standard_True;
-      }
-      else {
-       NbSol = anaint.NbPnt();
-       for (i = 1; i <= NbSol; i++) {
-         psol = anaint.Point(i);
-         Quad1.Parameters(psol,U1,V1);
-         Quad2.Parameters(psol,U2,V2);
-         IntPatch_Point ptsol;
-         ptsol.SetValue(psol,Tol,Standard_True);
-         ptsol.SetParameters(U1,V1,U2,V2);
-         spnt.Append(ptsol);
-       }
-
-       gp_Pnt ptvalid, ptf, ptl;
-       gp_Vec tgvalid;
-       Standard_Real first,last,para;
-       Standard_Boolean tgfound,firstp,lastp,kept;
-       Standard_Integer kount;
-       
-       NbSol = anaint.NbCurve();
-       for (i = 1; i <= NbSol; i++) {
-         Handle(IntPatch_ALine) alig;
-         kept = Standard_False;
-         IntAna_Curve curvsol = anaint.Curve(i);
-         curvsol.Domain(first,last);
-         firstp = !curvsol.IsFirstOpen();
-         lastp  = !curvsol.IsLastOpen();
-         if (firstp) {
-           ptf = curvsol.Value(first);
-         }
-         if (lastp) {
-           ptl = curvsol.Value(last);
-         }
-         para = last;
-         kount = 1;
-         tgfound = Standard_False;
-         
-         while (!tgfound) {
-           para = (1.123*first + para)/2.123;
-           tgfound = curvsol.D1u(para,ptvalid,tgvalid);
-           if (!tgfound) {
-             kount ++;
-             tgfound = kount > 5;
-           }
-         }
-         if (kount <= 5) {
-           para = ElCLib::LineParameter(Co.Axis(),ptvalid);
-           Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid),
-                                                Quad1.Normale(ptvalid));
-           if(qwe> 0.000000001) {
-             trans1 = IntSurf_Out;
-             trans2 = IntSurf_In;
-           }
-           else if(qwe<-0.000000001) {
-             trans1 = IntSurf_In;
-             trans2 = IntSurf_Out;
-           }
-           else { 
-             trans1=trans2=IntSurf_Undecided; 
-           }
-           alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2);
-           kept = Standard_True;
-         }
-         else {
-           ptvalid = curvsol.Value(para);
-           para = ElCLib::LineParameter(Co.Axis(),ptvalid);
-           alig = new IntPatch_ALine(curvsol,Standard_False);
-           kept = Standard_True;
-           //-- cout << "Transition indeterminee" << endl;
-         }
-         if (kept) {
-           Standard_Boolean Nfirstp = !firstp;
-           Standard_Boolean Nlastp  = !lastp;
-           ProcessBounds(alig,slin,Quad1,Quad2,Nfirstp,ptf,first,
-                         Nlastp,ptl,last,Multpoint,Tol);
-           slin.Append(alig);
-         }
-       }
-      }
-    }
-    break;
-
-  default:
-    {
-      return Standard_False;
-    }
-  }
-
-  return Standard_True;
-}
-//=======================================================================
-//function : IntSpSp
-//purpose  : 
-//=======================================================================
-Standard_Boolean IntSpSp(const IntSurf_Quadric& Quad1,
-                        const IntSurf_Quadric& Quad2,
-                        const Standard_Real Tol,
-                        Standard_Boolean& Empty,
-                        Standard_Boolean& Same,
-                        IntPatch_SequenceOfLine& slin,
-                        IntPatch_SequenceOfPoint& spnt)
-
-// Traitement du cas Sphere/Sphere
-
-{
-  IntSurf_TypeTrans trans1,trans2;
-  IntAna_ResultType typint;
-  gp_Sphere sph1(Quad1.Sphere());
-  gp_Sphere sph2(Quad2.Sphere());
-
-  IntAna_QuadQuadGeo inter(sph1,sph2,Tol);
-  if (!inter.IsDone()) {return Standard_False;}
-
-  typint = inter.TypeInter();
-  Empty  = Standard_False;
-  Same   = Standard_False;
-
-  switch (typint) {
-
-  case IntAna_Empty :
-    {
-      Empty = Standard_True;
-    }
-    break;
-
-  case IntAna_Same:
-    {
-      Same  = Standard_True;
-    }
-    break;
-
-  case IntAna_Point:
-    {
-      gp_Pnt psol(inter.Point(1));
-      Standard_Real U1,V1,U2,V2;
-      Quad1.Parameters(psol,U1,V1);
-      Quad2.Parameters(psol,U2,V2);
-      IntPatch_Point ptsol;
-      ptsol.SetValue(psol,Tol,Standard_True);
-      ptsol.SetParameters(U1,V1,U2,V2);
-      spnt.Append(ptsol);
-    }
-    break;
-    
-  case IntAna_Circle:
-    {
-      gp_Circ cirsol = inter.Circle(1);
-      gp_Pnt ptref;
-      gp_Vec Tgt;
-      ElCLib::D1(0.,cirsol,ptref,Tgt);
-
-      Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
-      if(qwe>0.00000001) {
-       trans1 = IntSurf_Out;
-       trans2 = IntSurf_In;
-      }
-      else  if(qwe<-0.00000001) {
-       trans1 = IntSurf_In;
-       trans2 = IntSurf_Out;
-      }
-      else { 
-       trans1=trans2=IntSurf_Undecided; 
-      }
-      Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
-      slin.Append(glig);
-    }
-    break;
-    
-  default:
-    {
-      return Standard_False;  // on ne doit pas passer ici
-    }
-  }
-  return Standard_True;
-}
diff --git a/src/IntPatch/IntPatch_ImpImpIntersection_6.gxx b/src/IntPatch/IntPatch_ImpImpIntersection_6.gxx
deleted file mode 100644 (file)
index 0112683..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-// Created on: 1992-05-07
-// Created by: Jacques GOUSSARD
-// Copyright (c) 1992-1999 Matra Datavision
-// Copyright (c) 1999-2012 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.
-
-
-static 
-  Standard_Boolean TreatResultTorus(const IntSurf_Quadric& theQuad1,
-                                    const IntSurf_Quadric& theQuad2,
-                                    const IntAna_QuadQuadGeo& anInt,
-                                    Standard_Boolean& bEmpty,
-                                    IntPatch_SequenceOfLine& theSeqLin);
-
-//=======================================================================
-//function : IntCyTo
-//purpose  : 
-//=======================================================================
-Standard_Boolean IntCyTo(const IntSurf_Quadric& theQuad1,
-                         const IntSurf_Quadric& theQuad2,
-                         const Standard_Real theTolTang,
-                         const Standard_Boolean bReversed,
-                         Standard_Boolean& bEmpty,
-                         IntPatch_SequenceOfLine& theSeqLin)
-{
-  const gp_Cylinder aCyl = bReversed ? theQuad2.Cylinder() : theQuad1.Cylinder();
-  const gp_Torus aTorus = bReversed ? theQuad1.Torus() : theQuad2.Torus();
-  //
-  IntAna_QuadQuadGeo anInt(aCyl, aTorus, theTolTang);
-  Standard_Boolean bRet = 
-    TreatResultTorus(theQuad1, theQuad2, anInt, bEmpty, theSeqLin);
-  //
-  return bRet;
-}
-
-//=======================================================================
-//function : IntCoTo
-//purpose  : 
-//=======================================================================
-Standard_Boolean IntCoTo(const IntSurf_Quadric& theQuad1,
-                         const IntSurf_Quadric& theQuad2,
-                         const Standard_Real theTolTang,
-                         const Standard_Boolean bReversed,
-                         Standard_Boolean& bEmpty,
-                         IntPatch_SequenceOfLine& theSeqLin)
-{
-  const gp_Cone aCone = bReversed ? theQuad2.Cone() : theQuad1.Cone();
-  const gp_Torus aTorus = bReversed ? theQuad1.Torus() : theQuad2.Torus();
-  //
-  IntAna_QuadQuadGeo anInt(aCone, aTorus, theTolTang);
-  Standard_Boolean bRet = 
-    TreatResultTorus(theQuad1, theQuad2, anInt, bEmpty, theSeqLin);
-  //
-  return bRet;
-}
-
-//=======================================================================
-//function : IntSpTo
-//purpose  : 
-//=======================================================================
-Standard_Boolean IntSpTo(const IntSurf_Quadric& theQuad1,
-                         const IntSurf_Quadric& theQuad2,
-                         const Standard_Real theTolTang,
-                         const Standard_Boolean bReversed,
-                         Standard_Boolean& bEmpty,
-                         IntPatch_SequenceOfLine& theSeqLin)
-{
-  const gp_Sphere aSphere = bReversed ? theQuad2.Sphere() : theQuad1.Sphere();
-  const gp_Torus aTorus = bReversed ? theQuad1.Torus() : theQuad2.Torus();
-  //
-  IntAna_QuadQuadGeo anInt(aSphere, aTorus, theTolTang);
-  Standard_Boolean bRet = 
-    TreatResultTorus(theQuad1, theQuad2, anInt, bEmpty, theSeqLin);
-  //
-  return bRet;
-}
-
-//=======================================================================
-//function : IntToTo
-//purpose  : 
-//=======================================================================
-Standard_Boolean IntToTo(const IntSurf_Quadric& theQuad1,
-                         const IntSurf_Quadric& theQuad2,
-                         const Standard_Real theTolTang,
-                         Standard_Boolean& bSameSurf,
-                         Standard_Boolean& bEmpty,
-                         IntPatch_SequenceOfLine& theSeqLin)
-{
-  const gp_Torus aTorus1 = theQuad1.Torus();
-  const gp_Torus aTorus2 = theQuad2.Torus();
-  //
-  IntAna_QuadQuadGeo anInt(aTorus1, aTorus2, theTolTang);
-  Standard_Boolean bRet = anInt.IsDone();
-  if (bRet) {
-    if (anInt.TypeInter() == IntAna_Same) {
-      bEmpty = Standard_False;
-      bSameSurf = Standard_True;
-    } else {
-      bRet = TreatResultTorus(theQuad1, theQuad2, anInt, bEmpty, theSeqLin);
-    }
-  }
-  //
-  return bRet;
-}
-
-//=======================================================================
-//function : TreatResultTorus
-//purpose  : 
-//=======================================================================
-static Standard_Boolean TreatResultTorus(const IntSurf_Quadric& theQuad1,
-                                         const IntSurf_Quadric& theQuad2,
-                                         const IntAna_QuadQuadGeo& anInt,
-                                         Standard_Boolean& bEmpty,
-                                         IntPatch_SequenceOfLine& theSeqLin)
-{
-  Standard_Boolean bRet = anInt.IsDone();
-  //
-  if (!bRet) {
-    return bRet;
-  }
-  //
-  IntAna_ResultType typint = anInt.TypeInter();
-  Standard_Integer NbSol = anInt.NbSolutions();
-  bEmpty = Standard_False;
-  //
-  switch (typint) {
-  case IntAna_Empty :
-    bEmpty = Standard_True;
-    break;
-  //
-  case IntAna_Circle : {
-    Standard_Integer i;
-    IntSurf_TypeTrans trans1, trans2;
-    gp_Vec Tgt;
-    gp_Pnt ptref;
-    //
-    for (i = 1; i <= NbSol; ++i) {
-      gp_Circ aC = anInt.Circle(i);
-      if (theQuad1.TypeQuadric() == theQuad2.TypeQuadric()) {
-        AdjustToSeam(theQuad1.Torus(), aC);
-      }
-      ElCLib::D1(0., aC, ptref, Tgt);
-      Standard_Real qwe = Tgt.DotCross(theQuad2.Normale(ptref),
-                                       theQuad1.Normale(ptref));
-      if(qwe> 0.00000001) {
-        trans1 = IntSurf_Out;
-        trans2 = IntSurf_In;
-      }
-      else if(qwe< -0.00000001) {
-        trans1 = IntSurf_In;
-        trans2 = IntSurf_Out;
-      }
-      else { 
-        trans1=trans2=IntSurf_Undecided; 
-      }
-      //
-      Handle(IntPatch_GLine) glig = 
-        new IntPatch_GLine(aC, Standard_False, trans1, trans2);
-      theSeqLin.Append(glig);
-    }
-  }
-    break;
-  //
-  case IntAna_NoGeometricSolution:
-  default:
-    bRet = Standard_False;
-    break;
-  }
-  //
-  return bRet;
-}
index fa573846ee436c53fa73adf38267c7433bf8471a..c6c16c39d807ae4ea22d2db19d3b7fbd4e9d90c0 100755 (executable)
@@ -1,11 +1,5 @@
 IntWalk_IWalking.gxx
 IntWalk_IWalking.lxx
-IntWalk_IWalking_1.gxx
-IntWalk_IWalking_2.gxx
-IntWalk_IWalking_3.gxx
-IntWalk_IWalking_4.gxx
-IntWalk_IWalking_5.gxx
-IntWalk_IWalking_6.gxx
 IntWalk_IWLine.gxx
 IntWalk_IWLine.lxx
 IntWalk_PWalking.cxx
index b2189bc7b8734b7f674fe4fe091a0b5d23f2b2d1..93253ca42bb4a72b93f8d7a23639b7d7690e6cb4 100644 (file)
@@ -1,5 +1,5 @@
 // Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
+// Copyright (c) 1999-2024 OPEN CASCADE SAS
 //
 // This file is part of Open CASCADE Technology software library.
 //
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <Bnd_Range.hxx>
 #include <IntWalk_StatusDeflection.hxx>
+#include <NCollection_IncAllocator.hxx>
+#include <NCollection_LocalArray.hxx>
+#include <Precision.hxx>
 #include <Standard_ConstructionError.hxx>
+#include <TColStd_MapOfInteger.hxx>
+#include <TColgp_Array1OfPnt.hxx>
 #include <math_FunctionSetRoot.hxx>
 
-#include <TColgp_Array1OfPnt.hxx>
+//-- IntWalk_IWalking_1.gxx
+
+#ifdef CHRONO
+  #include <OSD_Chronometer.hxx>
+OSD_Chronometer Chronrsnld;
+#endif
+
+//==================================================================================
+// function : IsTangentExtCheck
+// purpose  : Additional check if the point (theU, theV) in parametric surface
+//            is a tangent point.
+//            If that is TRUE then we can go along any (!) direction in order to
+//            obtain next intersection point. At present, this case is difficult
+//            for processing. Therefore, we will return an empty intersection line
+//            in this case.
+//==================================================================================
+static Standard_Boolean IsTangentExtCheck(TheIWFunction&      theFunc,
+                                          const Standard_Real theU,
+                                          const Standard_Real theV,
+                                          const Standard_Real theStepU,
+                                          const Standard_Real theStepV,
+                                          const Standard_Real theUinf,
+                                          const Standard_Real theUsup,
+                                          const Standard_Real theVinf,
+                                          const Standard_Real theVsup)
+{
+  const Standard_Real    aTol            = theFunc.Tolerance();
+  const Standard_Integer aNbItems        = 4;
+  const Standard_Real    aParU[aNbItems] = {Min(theU + theStepU, theUsup), Max(theU - theStepU, theUinf), theU, theU};
+  const Standard_Real    aParV[aNbItems] = {theV, theV, Min(theV + theStepV, theVsup), Max(theV - theStepV, theVinf)};
+
+  math_Vector aX(1, 2), aVal(1, 1);
+
+  for (Standard_Integer i = 0; i < aNbItems; i++)
+  {
+    aX.Value(1) = aParU[i];
+    aX.Value(2) = aParV[i];
+
+    if (!theFunc.Value(aX, aVal))
+      continue;
+
+    if (Abs(theFunc.Root()) > aTol)
+      return Standard_False;
+  }
+
+  return Standard_True;
+}
+
+IntWalk_IWalking::IntWalk_IWalking(const Standard_Real    Epsilon,
+                                   const Standard_Real    Deflection,
+                                   const Standard_Real    Increment,
+                                   const Standard_Boolean theToFillHoles)
+: done(Standard_False),
+  fleche(Deflection),
+  pas(Increment),
+  tolerance(1, 2),
+  epsilon(Epsilon * Epsilon),
+  reversed(Standard_False),
+  wd1(IntWalk_VectorOfWalkingData::allocator_type(new NCollection_IncAllocator)),
+  wd2(wd1.get_allocator()),
+  nbMultiplicities(wd1.get_allocator()),
+  Um(0.0),
+  UM(0.0),
+  Vm(0.0),
+  VM(0.0),
+  ToFillHoles(theToFillHoles)
+{}
+
+//=======================================================================
+//function : Reset
+//purpose  : Clears NCollection_Vector-based containers and adds
+//           dummy data to maintain start index of 1 and consistent with
+//           previous TCollection_Sequence-based implementation and other
+//           used TCollection-based containers
+//=======================================================================
+
+void IntWalk_IWalking::Clear()
+{
+  wd1.clear();
+  wd2.clear();
+  IntWalk_WalkingData aDummy;
+  aDummy.etat   = -10;
+  aDummy.ustart = aDummy.vstart = 0.;
+  wd1.push_back(aDummy);
+  wd2.push_back(aDummy);
+  nbMultiplicities.clear();
+  nbMultiplicities.push_back(-1);
+
+  done = Standard_False;
+  seqAjout.Clear();
+  lines.Clear();
+}
+
+// ***************************************************************************
+//  etat1=12 not tangent, not passes
+//  etat1=11 tangent, not passes
+//  etat1=2  not tangent, passes
+//  etat1=1  tangent, passes
+//  after a point is processed its state becomes negative.
+// ***************************************************************************
+//  etat2=13  interior start point on closed line
+//  etat2=12  interior start point on open line
+//            (line initially closed -> la line s is open)
+//  after a point is processed (or if it is passed over during
+//  routing) its state becomes negative.
+// ****************************************************************************
+
+//
+// Perform with interior points
+//
+void IntWalk_IWalking::Perform(const ThePOPIterator&  Pnts1,
+                               const ThePOLIterator&  Pnts2,
+                               TheIWFunction&         Func,
+                               const ThePSurface&     Caro,
+                               const Standard_Boolean Reversed)
+
+{
+  Standard_Integer I;
+  Standard_Boolean Rajout  = Standard_False;
+  Standard_Integer nbPnts1 = Pnts1.Length();
+  Standard_Integer nbPnts2 = Pnts2.Length();
+  Standard_Real    U, V;
+
+  Clear();
+  reversed = Reversed;
+
+  Um       = ThePSurfaceTool::FirstUParameter(Caro);
+  Vm       = ThePSurfaceTool::FirstVParameter(Caro);
+  UM       = ThePSurfaceTool::LastUParameter(Caro);
+  VM       = ThePSurfaceTool::LastVParameter(Caro);
+
+  if (UM < Um)
+  {
+    Standard_Real utemp = UM;
+    UM                  = Um;
+    Um                  = utemp;
+  }
+  if (VM < Vm)
+  {
+    Standard_Real vtemp = VM;
+    VM                  = Vm;
+    Vm                  = vtemp;
+  }
+
+  const Standard_Real aStepU = pas * (UM - Um), aStepV = pas * (VM - Vm);
+
+  // Loading of etat1 and etat2  as well as  ustart and vstart.
+
+  TColStd_SequenceOfReal Umult;
+  TColStd_SequenceOfReal Vmult;
+
+  Standard_Integer decal = 0;
+  wd1.reserve(nbPnts1 + decal);
+  nbMultiplicities.reserve(nbPnts1 + decal);
+  for (I = 1; I <= nbPnts1 + decal; I++)
+  {
+    const ThePointOfPath& PathPnt = Pnts1.Value(I - decal);
+    IntWalk_WalkingData   aWD1;
+    aWD1.etat = 1;
+    if (!ThePointOfPathTool::IsPassingPnt(PathPnt))
+      aWD1.etat = 11;
+    if (!ThePointOfPathTool::IsTangent(PathPnt))
+      ++aWD1.etat;
+
+    if (aWD1.etat == 2)
+    {
+      aWD1.etat = 11;
+    }
+
+    ThePointOfPathTool::Value2d(PathPnt, aWD1.ustart, aWD1.vstart);
+    mySRangeU.Add(aWD1.ustart);
+    mySRangeV.Add(aWD1.vstart);
+
+    wd1.push_back(aWD1);
+    Standard_Integer aNbMult = ThePointOfPathTool::Multiplicity(PathPnt);
+    nbMultiplicities.push_back(aNbMult);
+
+    for (Standard_Integer J = 1; J <= aNbMult; J++)
+    {
+      ThePointOfPathTool::Parameters(PathPnt, J, U, V);
+      Umult.Append(U);
+      Vmult.Append(V);
+    }
+  }
+
+  wd2.reserve(nbPnts2);
+  for (I = 1; I <= nbPnts2; I++)
+  {
+    IntWalk_WalkingData aWD2;
+    aWD2.etat                         = 1;
+    const IntSurf_InteriorPoint& anIP = Pnts2.Value(I);
+    ThePointOfLoopTool::Value2d(anIP, aWD2.ustart, aWD2.vstart);
+    mySRangeU.Add(aWD2.ustart);
+    mySRangeV.Add(aWD2.vstart);
+
+    if (!IsTangentExtCheck(Func, aWD2.ustart, aWD2.vstart, aStepU, aStepV, Um, UM, Vm, VM))
+      aWD2.etat = 13;
+
+    wd2.push_back(aWD2);
+  }
+
+  tolerance(1) = ThePSurfaceTool::UResolution(Caro, Precision::Confusion());
+  tolerance(2) = ThePSurfaceTool::VResolution(Caro, Precision::Confusion());
+
+  Func.Set(Caro);
+
+  if (mySRangeU.Delta() > Max(tolerance(1), Precision::PConfusion()))
+  {
+    mySRangeU.Enlarge(mySRangeU.Delta());
+    mySRangeU.Common(Bnd_Range(Um, UM));
+  }
+  else
+  {
+    mySRangeU = Bnd_Range(Um, UM);
+  }
+
+  if (mySRangeV.Delta() > Max(tolerance(2), Precision::PConfusion()))
+  {
+    mySRangeV.Enlarge(mySRangeV.Delta());
+    mySRangeV.Common(Bnd_Range(Vm, VM));
+  }
+  else
+  {
+    mySRangeV = Bnd_Range(Vm, VM);
+  }
+
+  // calculation of all open lines
+  if (nbPnts1 != 0)
+    ComputeOpenLine(Umult, Vmult, Pnts1, Func, Rajout);
+
+  // calculation of all closed lines
+  if (nbPnts2 != 0)
+    ComputeCloseLine(Umult, Vmult, Pnts1, Pnts2, Func, Rajout);
+
+  if (ToFillHoles)
+  {
+    Standard_Integer MaxNbIter = 10, nb_iter = 0;
+    while (seqAlone.Length() > 1 && nb_iter < MaxNbIter)
+    {
+      nb_iter++;
+      IntSurf_SequenceOfInteriorPoint PntsInHoles;
+      TColStd_SequenceOfInteger       CopySeqAlone = seqAlone;
+      FillPntsInHoles(Func, CopySeqAlone, PntsInHoles);
+      wd2.clear();
+      IntWalk_WalkingData aDummy;
+      aDummy.etat   = -10;
+      aDummy.ustart = aDummy.vstart = 0.;
+      wd2.push_back(aDummy);
+      Standard_Integer nbHoles = PntsInHoles.Length();
+      wd2.reserve(nbHoles);
+      for (I = 1; I <= nbHoles; I++)
+      {
+        IntWalk_WalkingData aWD2;
+        aWD2.etat                         = 13;
+        const IntSurf_InteriorPoint& anIP = PntsInHoles.Value(I);
+        ThePointOfLoopTool::Value2d(anIP, aWD2.ustart, aWD2.vstart);
+        wd2.push_back(aWD2);
+      }
+      ComputeCloseLine(Umult, Vmult, Pnts1, PntsInHoles, Func, Rajout);
+    }
+  }
+
+  for (I = 1; I <= nbPnts1; I++)
+  {
+    if (wd1[I].etat > 0)
+      seqSingle.Append(Pnts1(I));
+  }
+  done = Standard_True;
+}
+
+//
+// Perform without interior point
+//
+
+void IntWalk_IWalking::Perform(const ThePOPIterator&  Pnts1,
+                               TheIWFunction&         Func,
+                               const ThePSurface&     Caro,
+                               const Standard_Boolean Reversed)
+
+{
+  Standard_Integer I;
+  Standard_Boolean Rajout  = Standard_False;
+  Standard_Integer nbPnts1 = Pnts1.Length();
+  Standard_Real    U, V;
+
+  reversed = Reversed;
+
+  // Loading of etat1 as well as ustart1 and vstart1.
+
+  TColStd_SequenceOfReal Umult;
+  TColStd_SequenceOfReal Vmult;
+
+  wd1.reserve(nbPnts1);
+  for (I = 1; I <= nbPnts1; I++)
+  {
+    const ThePointOfPath& PathPnt = Pnts1.Value(I);
+    IntWalk_WalkingData   aWD1;
+    aWD1.etat = 1;
+    if (!ThePointOfPathTool::IsPassingPnt(PathPnt))
+      aWD1.etat = 11;
+    if (!ThePointOfPathTool::IsTangent(PathPnt))
+      ++aWD1.etat;
+    ThePointOfPathTool::Value2d(PathPnt, aWD1.ustart, aWD1.vstart);
+    wd1.push_back(aWD1);
+    Standard_Integer aNbMult = ThePointOfPathTool::Multiplicity(PathPnt);
+    nbMultiplicities.push_back(aNbMult);
+
+    for (Standard_Integer J = 1; J <= aNbMult; J++)
+    {
+      ThePointOfPathTool::Parameters(PathPnt, J, U, V);
+      Umult.Append(U);
+      Vmult.Append(V);
+    }
+  }
+
+  tolerance(1) = ThePSurfaceTool::UResolution(Caro, Precision::Confusion());
+  tolerance(2) = ThePSurfaceTool::VResolution(Caro, Precision::Confusion());
+
+  Um           = ThePSurfaceTool::FirstUParameter(Caro);
+  Vm           = ThePSurfaceTool::FirstVParameter(Caro);
+  UM           = ThePSurfaceTool::LastUParameter(Caro);
+  VM           = ThePSurfaceTool::LastVParameter(Caro);
+
+  if (UM < Um)
+  {
+    Standard_Real utemp = UM;
+    UM                  = Um;
+    Um                  = utemp;
+  }
+  if (VM < Vm)
+  {
+    Standard_Real vtemp = VM;
+    VM                  = Vm;
+    Vm                  = vtemp;
+  }
+
+  Func.Set(Caro);
+
+  // calcul de toutes les lignes ouvertes
+  if (nbPnts1 != 0)
+    ComputeOpenLine(Umult, Vmult, Pnts1, Func, Rajout);
+
+  for (I = 1; I <= nbPnts1; I++)
+  {
+    if (wd1[I].etat > 0)
+      seqSingle.Append(Pnts1(I));
+  }
+  done = Standard_True;
+}
+
+//-- IntWalk_IWalking_2.gxx
+
+#ifndef OCCT_DEBUG
+  #define No_Standard_RangeError
+  #define No_Standard_OutOfRange
+#endif
+
+static void CutVectorByTolerances(gp_Vec2d& theVector, const math_Vector& theTolerance)
+{
+  if (Abs(theVector.X()) < theTolerance(1))
+    theVector.SetX(0.);
+  if (Abs(theVector.Y()) < theTolerance(2))
+    theVector.SetY(0.);
+}
+
+// _______________________________________________
+//
+// Location of point (u, v) in the natural domain of a surface AND update
+// of couple (u, v) for the calculation of the next point.
+//
+Standard_Boolean IntWalk_IWalking::Cadrage(math_Vector&   BornInf,
+                                           math_Vector&   BornSup,
+                                           math_Vector&   UVap,
+                                           Standard_Real& Step,
+                                           //   Standard_Real& StepV,
+                                           const Standard_Integer StepSign) const
+
+// there are always :
+// BorInf(1) <= UVap(1) <= BornSup(1) et BorInf(2) <= UVap(2) <= BornSup(2)
+// 1) check if the process point is out of the natural domain of the surface.
+// 2) if yes the approximated point is located on border taking the best direction
+// the step and a limit blocating one of the parameters during the recent call of
+// FunctionSetRoot are modified;
+// 3) couple (u, v) is recomputed by approximation for the calculation of the next point.
+// 4) return Standard_True if location, Standard_False if no location.
+{
+  Standard_Real Duvx = previousd2d.X();
+  Standard_Real Duvy = previousd2d.Y();
+
+  if (!reversed)
+  {
+    previousPoint.ParametersOnS2(UVap(1), UVap(2));
+  }
+  else
+  {
+    previousPoint.ParametersOnS1(UVap(1), UVap(2));
+  }
+
+  Standard_Real U1      = UVap(1) + Step * Duvx * StepSign;
+  Standard_Real V1      = UVap(2) + Step * Duvy * StepSign;
+
+  Standard_Boolean infu = (U1 <= BornInf(1) + Precision::PConfusion());
+  Standard_Boolean supu = (U1 >= BornSup(1) - Precision::PConfusion());
+  Standard_Boolean infv = (V1 <= BornInf(2) + Precision::PConfusion());
+  Standard_Boolean supv = (V1 >= BornSup(2) - Precision::PConfusion());
+
+  Standard_Real theStepU, theStepV;
+
+  if (!infu && !supu && !infv && !supv)
+  {
+    UVap(1) = U1;
+    UVap(2) = V1;
+    return Standard_False;
+  }
+
+  if ((infu || supu) && (infv || supv))
+  {
+    if (infu)
+    { // jag 940616
+      if (Duvx)
+      {
+        theStepU = Abs((BornInf(1) - UVap(1)) / Duvx); // iso U =BornInf(1)
+      }
+      else
+      {
+        theStepU = Step;
+      }
+    }
+    else
+    {
+      if (Duvx)
+      {
+        theStepU = Abs((BornSup(1) - UVap(1)) / Duvx); // iso U =BornSup(1)
+      }
+      else
+      {
+        theStepU = Step;
+      }
+    }
+    if (infv)
+    { // jag 940616
+      if (Duvy)
+      {
+        theStepV = Abs((BornInf(2) - UVap(2)) / Duvy); // iso V =BornInf(2)
+      }
+      else
+      {
+        theStepV = Step;
+      }
+    }
+    else
+    {
+      if (Duvy)
+      {
+        theStepV = Abs((BornSup(2) - UVap(2)) / Duvy); // iso V =BornSup(2)
+      }
+      else
+      {
+        theStepV = Step;
+      }
+    }
+
+    if (theStepU <= theStepV)
+    {
+      Step = theStepU;
+      if (infu)
+      {
+        UVap(1)    = BornInf(1);
+        BornSup(1) = BornInf(1);
+      }
+      else
+      {
+        UVap(1)    = BornSup(1);
+        BornInf(1) = BornSup(1);
+      }
+      UVap(2) += Step * Duvy * StepSign;
+    }
+    else
+    {
+      Step = theStepV;
+      if (infv)
+      {
+        UVap(2)    = BornInf(2);
+        BornSup(2) = BornInf(2);
+      }
+      else
+      {
+        UVap(2)    = BornSup(2);
+        BornInf(2) = BornSup(2);
+      }
+      UVap(1) += Step * Duvx * StepSign;
+    }
+    return Standard_True;
+  }
+
+  else if (infu)
+  { // jag 940616
+    if (Duvx)
+    {
+      Standard_Real aStep = Abs((BornInf(1) - UVap(1)) / Duvx); // iso U =BornInf(1)
+      if (aStep < Step)
+        Step = aStep;
+    }
+    BornSup(1) = BornInf(1); // limit the parameter
+    UVap(1)    = BornInf(1);
+    UVap(2) += Step * Duvy * StepSign;
+    return Standard_True;
+  }
+  else if (supu)
+  { // jag 940616
+    if (Duvx)
+    {
+      Standard_Real aStep = Abs((BornSup(1) - UVap(1)) / Duvx); // iso U =BornSup(1)
+      if (aStep < Step)
+        Step = aStep;
+    }
+    BornInf(1) = BornSup(1); // limit the parameter
+    UVap(1)    = BornSup(1);
+    UVap(2) += Step * Duvy * StepSign;
+    return Standard_True;
+  }
+  else if (infv)
+  { // jag 940616
+    if (Duvy)
+    {
+      Standard_Real aStep = Abs((BornInf(2) - UVap(2)) / Duvy); // iso V =BornInf(2)
+      if (aStep < Step)
+        Step = aStep;
+    }
+    BornSup(2) = BornInf(2);
+    UVap(1) += Step * Duvx * StepSign;
+    UVap(2) = BornInf(2);
+    return Standard_True;
+  }
+  else if (supv)
+  { // jag 940616
+    if (Duvy)
+    {
+      Standard_Real aStep = Abs((BornSup(2) - UVap(2)) / Duvy); // iso V =BornSup(2)
+      if (aStep < Step)
+        Step = aStep;
+    }
+    BornInf(2) = BornSup(2);
+    UVap(1) += Step * Duvx * StepSign;
+    UVap(2) = BornSup(2);
+    return Standard_True;
+  }
+  return Standard_True;
+}
+
+Standard_Boolean IntWalk_IWalking::TestArretPassage(const TColStd_SequenceOfReal& Umult,
+                                                    const TColStd_SequenceOfReal& Vmult,
+                                                    TheIWFunction&                sp,
+                                                    math_Vector&                  UV,
+                                                    Standard_Integer&             Irang)
+
+// Umult et Vmult : table of stop (or crossing) points on border,
+//         here only the crossing points are taken into account.
+// UV     : the current point.
+// Irang  : at exit : give index of the stop point in uvstart1 or 0.
+//          consider that there is no risk of crossing only if there is one crossing point.
+
+// test of stop for an OPEN intersection line
+// 1) crossing test on all interior points
+// 2) stop test on all start points
+// if a stop is detected, the index of the stop point (Irang) is returned
+// in the iterator of start points and the associated parameters in UV space.
+{
+  Standard_Real    Up, Vp, Du, Dv, Dup, Dvp, Utest, Vtest;
+  Standard_Integer j, N, ind;
+  Standard_Real    tolu   = tolerance(1);
+  Standard_Real    tolv   = tolerance(2);
+  Standard_Real    tolu2  = 10. * tolerance(1);
+  Standard_Real    tolv2  = 10. * tolerance(2);
+
+  Standard_Boolean Arrive = Standard_False;
+
+  // crossing test  on point that can start a loop; mark
+  // as processed if passes through an open line
+
+  if (!reversed)
+  {
+    previousPoint.ParametersOnS2(Up, Vp);
+  }
+  else
+  {
+    previousPoint.ParametersOnS1(Up, Vp);
+  }
+
+  for (size_t i = 1; i < wd2.size(); i++)
+  {
+    if (wd2[i].etat > 0)
+    {
+      // debug jag 05.04.94
+
+      //      if ((Up-wd2[i].ustart)*(UV(1)-wd2[i].ustart) +
+      //         (Vp-wd2[i].vstart)*(UV(2)-wd2[i].vstart) <= 0)
+      Utest = wd2[i].ustart;
+      Vtest = wd2[i].vstart;
+
+      Du    = UV(1) - Utest;
+      Dv    = UV(2) - Vtest;
+      Dup   = Up - Utest;
+      Dvp   = Vp - Vtest;
+
+      //-- lbr le 30 oct 97
+
+      //IFV for OCC20285
+
+      if ((Abs(Du) < tolu2 && Abs(Dv) < tolv2) || (Abs(Dup) < tolu2 && Abs(Dvp) < tolv2))
+      {
+        wd2[i].etat = -wd2[i].etat;
+      }
+      else
+      {
+        Standard_Real DDu = (UV(1) - Up);
+        Standard_Real DDv = (UV(2) - Vp);
+        Standard_Real DDD = DDu * DDu + DDv * DDv;
+        Standard_Real DD1 = Du * Du + Dv * Dv;
+        if (DD1 <= DDD)
+        {
+          Standard_Real DD2 = Dup * Dup + Dvp * Dvp;
+          if (DD2 <= DDD && ((Du * Dup) + (Dv * Dvp * tolu / tolv) <= 0.))
+          {
+            wd2[i].etat = -wd2[i].etat;
+          }
+        }
+      }
+    }
+  }
+
+  // stop test on point given at input and not yet processed
+
+  //  Modified by Sergey KHROMOV - Tue Nov 20 10:55:01 2001 Begin
+  // Check of all path points in the following order:
+  //   * First check all not treated points;
+  //   * After that check of already treated ones.
+  Standard_Integer l;
+
+  //// Modified by jgv, 28.07.2010 for OCC21914 ////
+  // There are several path points between (Up,Vp) and UV
+  // So several path points satisfy the condition
+  // Dup*UV1mUtest + Dvp*UV2mVtest) < 0
+  // We choose from them the path point with
+  // minimum distance to (Up,Vp)
+  TColStd_SequenceOfInteger i_candidates;
+  TColStd_SequenceOfReal    SqDist_candidates;
+
+  for (l = 1; l <= 2 && !Arrive; l++)
+  {
+    Standard_Boolean isToCheck;
+
+    for (size_t i = 1; i < wd1.size(); i++)
+    {
+      if (l == 1)
+        isToCheck = (wd1[i].etat > 0);
+      else
+        isToCheck = (wd1[i].etat < 0);
+
+      if (isToCheck)
+      {
+        //  Modified by Sergey KHROMOV - Tue Nov 20 11:03:16 2001 End
+
+        // debug jag voir avec isg
+
+        Utest = wd1[i].ustart;
+        Vtest = wd1[i].vstart;
+        Dup   = Up - Utest;
+        Dvp   = Vp - Vtest;
+        if (Abs(Dup) >= tolu || Abs(Dvp) >= tolv)
+        {
+          Standard_Real UV1mUtest = UV(1) - Utest;
+          Standard_Real UV2mVtest = UV(2) - Vtest;
+          if (((Dup * UV1mUtest + Dvp * UV2mVtest) < 0) || (Abs(UV1mUtest) < tolu && Abs(UV2mVtest) < tolv))
+          {
+            i_candidates.Append((Standard_Integer)i);
+            SqDist_candidates.Append(Dup * Dup + Dvp * Dvp);
+            /*
+           Irang=i;
+           Arrive = Standard_True;
+           UV(1) = Utest;
+           UV(2) = Vtest;
+           */
+          }
+          else if (nbMultiplicities[i] > 0 && i_candidates.IsEmpty())
+          {
+            N = 0;
+            for (size_t k = 1; k < i; k++)
+            {
+              N += nbMultiplicities[k];
+            }
+            for (j = N + 1; j <= N + nbMultiplicities[i]; j++)
+            {
+              if (((Up - Umult(j)) * (UV(1) - Umult(j)) + (Vp - Vmult(j)) * (UV(2) - Vmult(j)) < 0)
+                  || (Abs(UV(1) - Umult(j)) < tolu && Abs(UV(2) - Vmult(j)) < tolv))
+              {
+                Irang  = (Standard_Integer)i;
+                Arrive = Standard_True;
+                UV(1)  = Utest;
+                UV(2)  = Vtest;
+                break;
+              }
+            }
+          }
+          if (Arrive)
+          {
+            Standard_Real abidF[1], abidD[1][2];
+            math_Vector   bidF(abidF, 1, 1);
+            math_Matrix   bidD(abidD, 1, 1, 1, 2);
+            sp.Values(UV, bidF, bidD);
+            break;
+          }
+        }
+      }
+    } //end of for (i = 1; i < wd1.size(); i++)
+    if (!i_candidates.IsEmpty())
+    {
+      Standard_Real MinSqDist = RealLast();
+      for (ind = 1; ind <= i_candidates.Length(); ind++)
+        if (SqDist_candidates(ind) < MinSqDist)
+        {
+          MinSqDist = SqDist_candidates(ind);
+          Irang     = i_candidates(ind);
+        }
+      Arrive = Standard_True;
+      UV(1)  = wd1[Irang].ustart;
+      UV(2)  = wd1[Irang].vstart;
+    }
+  } //end of for (l = 1; l <= 2 && !Arrive; l++)
+  return Arrive;
+}
+
+Standard_Boolean IntWalk_IWalking::TestArretPassage(const TColStd_SequenceOfReal& Umult,
+                                                    const TColStd_SequenceOfReal& Vmult,
+                                                    const math_Vector&            UV,
+                                                    const Standard_Integer        Index,
+                                                    Standard_Integer&             Irang)
+{
+  // Umult, Vmult : table of stop (or crossing) points on border, here
+  //          only crossing points are taken into account.
+  // UV     : the current point.
+  // Index  : index of the start point in uvstart2 of the current line
+  //          (this is an interior point).
+  // Irang  : at output : gives the index of the point passing in uvstart1 or 0.
+  //          consider that there is risk to cross only one crossing point.
+
+  // test of stop for a CLOSED intersection line.
+  // 1) test of crossing on all interior points.
+  // 2) test of crossing on all crossing points.
+
+  Standard_Real    Up, Vp, Scal;
+  Standard_Boolean Arrive = Standard_False;
+  Standard_Integer N, k, i;
+  Standard_Real    Utest, Vtest;
+  Standard_Real    tolu = tolerance(1);
+  Standard_Real    tolv = tolerance(2);
+
+  // tests of stop and of crossing on all interior points.
+
+  if (!reversed)
+  {
+    previousPoint.ParametersOnS2(Up, Vp);
+  }
+  else
+  {
+    previousPoint.ParametersOnS1(Up, Vp);
+  }
+
+  Standard_Real UV1                          = UV(1);
+  Standard_Real UV2                          = UV(2);
+
+  //Normalizing factor. If it is less than 1.0 then the range will be expanded.
+  //This is no good for computation. Therefore, it is limited.
+  //Do not limit this factor in case of highly anisotropic parametrization
+  //(parametric space is considerably larger in one direction than another).
+  const Standard_Boolean isHighlyAnisotropic = Max(tolu, tolv) > 1000. * Min(tolu, tolv);
+  const Standard_Real    deltau              = mySRangeU.IsVoid() ? UM - Um
+                                                                  : (isHighlyAnisotropic ? mySRangeU.Delta() : Max(mySRangeU.Delta(), 1.0));
+  const Standard_Real    deltav              = mySRangeV.IsVoid() ? VM - Vm
+                                                                  : (isHighlyAnisotropic ? mySRangeV.Delta() : Max(mySRangeV.Delta(), 1.0));
+
+  Up /= deltau;
+  UV1 /= deltau;
+  Vp /= deltav;
+  UV2 /= deltav;
+
+  tolu /= deltau;
+  tolv /= deltav;
+
+  Standard_Real tolu2            = tolu + tolu;
+  Standard_Real tolv2            = tolv + tolv;
+
+  Standard_Real dPreviousCurrent = (Up - UV1) * (Up - UV1) + (Vp - UV2) * (Vp - UV2);
+  for (k = 1; k < (int)wd2.size(); k++)
+  {
+    if (wd2[k].etat > 0)
+    {
+      Utest = wd2[k].ustart;
+      Vtest = wd2[k].vstart;
+
+      Utest /= deltau;
+      Vtest /= deltav;
+
+      Standard_Real UV1mUtest = UV1 - Utest;
+      Standard_Real UV2mVtest = UV2 - Vtest;
+      if ((UV1mUtest < tolu2 && UV1mUtest > -tolu2) && (UV2mVtest < tolv2 && UV2mVtest > -tolv2))
+      {
+        if (Index != k)
+        {
+          //-- cout<<"* etat2 : ("<<k<<")"<<endl;
+          wd2[k].etat = -wd2[k].etat; //-- mark the point as a crossing point
+        }
+        else
+        { //-- Index == k
+          //-- cout<<"* Arrive"<<endl;
+          Arrive = Standard_True;
+        }
+      }
+      else
+      {
+        Standard_Real UpmUtest       = (Up - Utest);
+        Standard_Real VpmVtest       = (Vp - Vtest);
+        Standard_Real dPreviousStart = (UpmUtest) * (UpmUtest) + (VpmVtest) * (VpmVtest);
+        Standard_Real dCurrentStart  = UV1mUtest * UV1mUtest + UV2mVtest * UV2mVtest;
+
+        Scal                         = (UpmUtest) * (UV1mUtest) + (VpmVtest) * (UV2mVtest);
+        if ((Abs(UpmUtest) < tolu && Abs(VpmVtest) < tolv))
+        {
+          if (Index != k)
+          {
+            //-- cout<<"** etat2 : ("<<k<<")"<<endl;
+            wd2[k].etat = -wd2[k].etat;
+          }
+        }
+        else if (Scal < 0 && (dPreviousStart + dCurrentStart < dPreviousCurrent))
+        {
+          if (Index == k)
+          { // on a boucle.
+            Arrive = Standard_True;
+            //-- cout<<"** Arrive  : k="<<k<<endl;
+          }
+          else
+          {
+            //-- cout<<"*** etat2 : ("<<k<<")"<<endl;
+            wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point
+          }
+        }
+        else if (k != Index)
+        {
+          if (dPreviousStart < dPreviousCurrent * 0.25)
+          {
+            wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point
+            //-- cout<<"**** etat2 : ("<<k<<")"<<endl;
+          }
+          else
+          {
+            if (dCurrentStart < dPreviousCurrent * 0.25)
+            {
+              //-- cout<<"***** etat2 : ("<<k<<")"<<endl;
+              wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point
+            }
+            else
+            {
+              Standard_Real UMidUtest    = 0.5 * (UV1 + Up) - Utest;
+              Standard_Real VMidVtest    = 0.5 * (UV2 + Vp) - Vtest;
+              Standard_Real dMiddleStart = UMidUtest * UMidUtest + VMidVtest * VMidVtest;
+
+              if (dMiddleStart < dPreviousCurrent * 0.5)
+              {
+                //-- cout<<"*********** etat2 : ("<<k<<")"<<endl;
+                wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  // crossing test on crossing points.
+
+  Irang = 0;
+  for (i = 1; i < (int)wd1.size(); i++)
+  {
+    if (wd1[i].etat > 0 && wd1[i].etat < 11)
+    { //test of crossing points
+      Utest = wd1[i].ustart;
+      Vtest = wd1[i].vstart;
+      Utest /= deltau;
+      Vtest /= deltav;
+
+      if (((Up - Utest) * (UV1 - Utest) + (Vp - Vtest) * (UV2 - Vtest) < 0)
+          || (Abs(UV1 - Utest) < tolu && Abs(UV2 - Vtest) < tolv))
+        Irang = i;
+      else if (nbMultiplicities[i] > 0)
+      {
+        N = 0;
+        for (k = 1; k < i; k++)
+          N = N + nbMultiplicities[k];
+        for (Standard_Integer j = N + 1; j <= N + nbMultiplicities[i]; j++)
+        {
+          Standard_Real Umultj = Umult(j) / deltau;
+          Standard_Real Vmultj = Vmult(j) / deltav;
+          if (((Up - Umultj) * (UV1 - Umultj) + (Vp - Vmultj) * (UV2 - Vmultj) < 0)
+              || (Abs(UV1 - Umultj) < tolu && Abs(UV2 - Vmultj) < tolv))
+          {
+            Irang = i;
+            break;
+          }
+        }
+      }
+    }
+  }
+  return Arrive;
+}
+
+Standard_Boolean IntWalk_IWalking::TestArretAjout(TheIWFunction&    sp,
+                                                  math_Vector&      UV,
+                                                  Standard_Integer& Irang,
+                                                  IntSurf_PntOn2S&  Psol)
+
+// test of stop on added points
+// these are the points on the natural biorder that were not given at input
+// return : Psol,  the added point.
+//          Irang, index in the iterator of added points.
+//          UV,    parameter of the added point.
+//
+{
+  Standard_Boolean Arrive = Standard_False;
+  Standard_Real    U1, V1;
+  Standard_Real    Up, Vp;
+
+  if (!reversed)
+  {
+    previousPoint.ParametersOnS2(Up, Vp);
+  }
+  else
+  {
+    previousPoint.ParametersOnS1(Up, Vp);
+  }
+
+  Standard_Integer nbAjout = seqAjout.Length();
+  for (Standard_Integer i = 1; i <= nbAjout; i++)
+  {
+    Irang = seqAjout.Value(i);
+
+    // add test Abs(Irang) <= lines.Length() for the case when
+    // a closed line is opened by adding a  1 point on this same
+    // line. Anyway there is a huge problem as 2 points will be
+    // added on this line...
+
+    if (Abs(Irang) <= lines.Length())
+    {
+      const Handle(IntWalk_TheIWLine)& Line = lines.Value(Abs(Irang));
+      if (Irang > 0)
+        Psol = Line->Value(Line->NbPoints());
+      else
+        Psol = Line->Value(1);
+      if (!reversed)
+      {
+        Psol.ParametersOnS2(U1, V1);
+      }
+      else
+      {
+        Psol.ParametersOnS1(U1, V1);
+      }
+      if (((Up - U1) * (UV(1) - U1) + (Vp - V1) * (UV(2) - V1)) < 0
+          || (Abs(UV(1) - U1) < tolerance(1) && Abs(UV(2) - V1) < tolerance(2)))
+      {
+        //jag 940615   Irang= -Abs(Irang);
+        Arrive = Standard_True;
+        UV(1)  = U1;
+        UV(2)  = V1;
+        Standard_Real abidF[1], abidD[1][2];
+        math_Vector   bidF(abidF, 1, 1);
+        math_Matrix   bidD(abidD, 1, 1, 1, 2);
+        sp.Values(UV, bidF, bidD);
+        break;
+      }
+    }
+  }
+  return Arrive;
+}
+
+void IntWalk_IWalking::FillPntsInHoles(TheIWFunction&                   sp,
+                                       TColStd_SequenceOfInteger&       CopySeqAlone,
+                                       IntSurf_SequenceOfInteriorPoint& PntsInHoles)
+{
+  math_Vector BornInf(1, 2), BornSup(1, 2);
+  BornInf(1) = Um;
+  BornSup(1) = UM;
+  BornInf(2) = Vm;
+  BornSup(2) = VM;
+  PointLineLine.Clear();
+  TColStd_SequenceOfInteger SeqToRemove;
+  TColStd_MapOfInteger      BadSolutions;
+
+  for (Standard_Integer i = 1; i < CopySeqAlone.Length(); i++)
+  {
+    Standard_Integer Irang1 = CopySeqAlone(i);
+    if (Irang1 == 0)
+      continue;
+    Standard_Boolean                 ToRemove = Standard_False;
+    IntSurf_PntOn2S                  PointAlone1, PointAlone2;
+    const Handle(IntWalk_TheIWLine)& Line1 = lines.Value(Abs(Irang1));
+    if (Irang1 > 0)
+      PointAlone1 = Line1->Value(Line1->NbPoints());
+    else
+      PointAlone1 = Line1->Value(1);
+    gp_Pnt2d         P2d1      = PointAlone1.ValueOnSurface(reversed), P2d2;
+    Standard_Real    MinSqDist = RealLast();
+    Standard_Integer MinRang = 0, MinIndex = 0;
+    for (Standard_Integer j = i + 1; j <= CopySeqAlone.Length(); j++)
+    {
+      Standard_Integer Irang2 = CopySeqAlone(j);
+      if (Irang2 == 0 || BadSolutions.Contains(Irang2))
+        continue;
+      const Handle(IntWalk_TheIWLine)& Line2 = lines.Value(Abs(Irang2));
+      if (Irang2 > 0)
+        PointAlone2 = Line2->Value(Line2->NbPoints());
+      else
+        PointAlone2 = Line2->Value(1);
+      P2d2                  = PointAlone2.ValueOnSurface(reversed);
+      Standard_Real aSqDist = P2d1.SquareDistance(P2d2);
+      if (aSqDist < MinSqDist)
+      {
+        MinSqDist = aSqDist;
+        MinRang   = Irang2;
+        MinIndex  = j;
+      }
+    }
+    //processing points from Irang1 and MinRang
+    if (MinRang == 0)
+    {
+      SeqToRemove.Append(Irang1);
+      BadSolutions.Clear();
+      continue;
+    }
+    //Ends of same line
+    if (Abs(Irang1) == Abs(MinRang) && lines.Value(Abs(Irang1))->NbPoints() == 2)
+    {
+      SeqToRemove.Append(Irang1);
+      SeqToRemove.Append(MinRang);
+      CopySeqAlone(i)        = 0;
+      CopySeqAlone(MinIndex) = 0;
+      BadSolutions.Clear();
+      continue;
+    }
+    ///////////////////
+    const Handle(IntWalk_TheIWLine)& Line2 = lines.Value(Abs(MinRang));
+    if (MinRang > 0)
+      PointAlone2 = Line2->Value(Line2->NbPoints());
+    else
+      PointAlone2 = Line2->Value(1);
+    gp_Pnt Pnt1               = PointAlone1.Value();
+    gp_Pnt Pnt2               = PointAlone2.Value();
+    P2d2                      = PointAlone2.ValueOnSurface(reversed);
+    Standard_Real MinSqDist3d = Pnt1.SquareDistance(Pnt2);
+    if (MinSqDist3d <= epsilon
+        || (Abs(P2d1.X() - P2d2.X()) <= tolerance(1) && Abs(P2d1.Y() - P2d2.Y()) <= tolerance(2))) //close points
+      ToRemove = Standard_True;
+    else //real curve
+    {
+      math_Vector UVap(1, 2), UV(1, 2);
+      UVap(1) = (P2d1.X() + P2d2.X()) / 2;
+      UVap(2) = (P2d1.Y() + P2d2.Y()) / 2;
+      math_FunctionSetRoot Rsnld(sp, tolerance);
+      Rsnld.Perform(sp, UVap, BornInf, BornSup);
+      if (Rsnld.IsDone() && Abs(sp.Root()) <= sp.Tolerance() && !sp.IsTangent())
+      {
+        Rsnld.Root(UV);
+        gp_Pnt2d         Pmid(UV(1), UV(2));
+        gp_Vec2d         P1P2(P2d1, P2d2);
+        gp_Vec2d         P1Pmid(P2d1, Pmid);
+        gp_Vec2d         P2Pmid(P2d2, Pmid);
+        Standard_Real    ScalProd1   = P1P2 * P1Pmid;
+        Standard_Real    ScalProd2   = P1P2 * P2Pmid;
+        Standard_Boolean IsPmidValid = (ScalProd1 > 0. && ScalProd2 < 0); //Pmid is in the middle
+        if (IsPmidValid)
+        {
+          for (Standard_Integer iline = 1; iline <= lines.Length(); iline++)
+            if (IsPointOnLine(Pmid, iline))
+            {
+              IsPmidValid = Standard_False;
+              break;
+            }
+        }
+        if (IsPmidValid)
+        {
+          IntSurf_InteriorPoint aPoint(sp.Point(), UV(1), UV(2), sp.Direction3d(), sp.Direction2d());
+          PntsInHoles.Append(aPoint);
+          TColStd_ListOfInteger LineLine;
+          LineLine.Append(Irang1);
+          LineLine.Append(MinRang);
+          PointLineLine.Bind(PntsInHoles.Length(), LineLine);
+        }
+        else
+        {
+          BadSolutions.Add(MinRang);
+          i--;
+          continue;
+        }
+      }
+      else
+      {
+        BadSolutions.Add(MinRang);
+        i--;
+        continue;
+      }
+    }
+    CopySeqAlone(i)        = 0;
+    CopySeqAlone(MinIndex) = 0;
+    if (ToRemove)
+    {
+      SeqToRemove.Append(Irang1);
+      SeqToRemove.Append(MinRang);
+    }
+    BadSolutions.Clear();
+  }
+
+  for (Standard_Integer i = 1; i <= SeqToRemove.Length(); i++)
+    for (Standard_Integer j = 1; j <= seqAlone.Length(); j++)
+      if (seqAlone(j) == SeqToRemove(i))
+      {
+        seqAlone.Remove(j);
+        break;
+      }
+}
+
+void IntWalk_IWalking::TestArretCadre(const TColStd_SequenceOfReal&    Umult,
+                                      const TColStd_SequenceOfReal&    Vmult,
+                                      const Handle(IntWalk_TheIWLine)& Line,
+                                      TheIWFunction&                   sp,
+                                      math_Vector&                     UV,
+                                      Standard_Integer&                Irang)
+
+// test of stop when located on border.
+// tried all tests of stop and arrived.
+// test of stop on all given departure points already marked and on the entire current line.
+// This line can be shortened if the stop point is found.
+// Abs(Irang) = index in the iterator of departure points or 0
+//  if Irang <0 , it is necessary to add this point on the line (no Line->Cut)
+// UV = parameter of the departure point
+{
+  Standard_Real    Scal, Up, Vp, Uc, Vc;
+  Standard_Integer N;
+  Standard_Boolean Found = Standard_False;
+
+  Irang                  = 0;
+  for (Standard_Integer i = 1; i < (int)wd1.size(); i++)
+  {
+    if (wd1[i].etat < 0)
+    {
+      N = 0; // range in UVMult.
+      if (nbMultiplicities[i] > 0)
+      {
+        for (Standard_Integer k = 1; k < i; k++)
+          N += nbMultiplicities[k];
+      }
+      if (!reversed)
+      {
+        Line->Value(1).ParametersOnS2(Up, Vp);
+      }
+      else
+      {
+        Line->Value(1).ParametersOnS1(Up, Vp);
+      }
+      Standard_Integer nbp = Line->NbPoints();
+      for (Standard_Integer j = 2; j <= nbp; j++)
+      {
+        if (!reversed)
+        {
+          Line->Value(j).ParametersOnS2(Uc, Vc);
+        }
+        else
+        {
+          Line->Value(j).ParametersOnS1(Uc, Vc);
+        }
+
+        gp_Vec2d aVec1(Up - wd1[i].ustart, Vp - wd1[i].vstart), aVec2(Uc - wd1[i].ustart, Vc - wd1[i].vstart);
+        CutVectorByTolerances(aVec1, tolerance);
+        CutVectorByTolerances(aVec2, tolerance);
+
+        Scal = aVec1 * aVec2;
+
+        // if a stop point is found: stop the line on this point.
+        if (Scal < 0)
+        {
+          Line->Cut(j);
+          nbp   = Line->NbPoints();
+          Irang = i;
+          UV(1) = wd1[Irang].ustart;
+          UV(2) = wd1[Irang].vstart;
+          Found = Standard_True;
+        }
+        else if (Abs(Uc - wd1[i].ustart) < tolerance(1) && Abs(Vc - wd1[i].vstart) < tolerance(2))
+        {
+          Line->Cut(j);
+          nbp   = Line->NbPoints();
+          Irang = i;
+          UV(1) = wd1[Irang].ustart;
+          UV(2) = wd1[Irang].vstart;
+          Found = Standard_True;
+        }
+        else if (nbMultiplicities[i] > 0)
+        {
+          for (Standard_Integer k = N + 1; k <= N + nbMultiplicities[i]; k++)
+          {
+            aVec1.SetCoord(Up - Umult(k), Vp - Vmult(k)), aVec2.SetCoord(Uc - Umult(k), Vc - Vmult(k));
+            CutVectorByTolerances(aVec1, tolerance);
+            CutVectorByTolerances(aVec2, tolerance);
+
+            Scal = aVec1 * aVec2;
+
+            if (Scal < 0)
+            {
+              Line->Cut(j);
+              nbp   = Line->NbPoints();
+              Irang = i;
+              UV(1) = wd1[Irang].ustart;
+              UV(2) = wd1[Irang].vstart;
+              Found = Standard_True;
+              break;
+            }
+            else if (Abs(Uc - Umult(k)) < tolerance(1) && Abs(Vc - Vmult(k)) < tolerance(2))
+            {
+              Line->Cut(j);
+              nbp   = Line->NbPoints();
+              Irang = i;
+              UV(1) = wd1[Irang].ustart;
+              UV(2) = wd1[Irang].vstart;
+              Found = Standard_True;
+              break;
+            }
+          }
+        }
+        if (Found)
+        {
+          Standard_Real abidF[1], abidD[1][2];
+          math_Vector   bidF(abidF, 1, 1);
+          math_Matrix   bidD(abidD, 1, 1, 1, 2);
+          sp.Values(UV, bidF, bidD);
+          Standard_Integer NBP = Line->NbPoints();
+          Standard_Integer Indextg;
+          Line->TangentVector(Indextg);
+          if (Indextg > NBP)
+          {
+            if (j > 3 && j <= NBP + 1)
+            {
+              gp_Vec        Dir3d  = sp.Direction3d();
+              gp_Vec        Dir3d1 = gp_Vec(Line->Value(j - 2).Value(), Line->Value(j - 1).Value());
+              Standard_Real dot    = Dir3d.Dot(Dir3d1);
+              if (dot < 0.0)
+              { // Normally this Function should not be used often !!!
+                Dir3d.Reverse();
+                //-- cout<<" IntWalk_IWalking_2.gxx REVERSE "<<endl;
+              }
+              Line->SetTangentVector(previousd3d, j - 1);
+            }
+#ifdef OCCT_DEBUG
+            else
+            {
+              std::cout << " IntWalk_IWalking_2.gxx : bizarrerie 30 10 97 " << std::endl;
+            }
+#endif
+          }
+
+          return;
+        }
+        Up = Uc;
+        Vp = Vc;
+      }
+
+      // now the last point of the line and the last calculated point are compated.
+      // there will be no need to "Cut"
+
+      gp_Vec2d aVec1(Up - wd1[i].ustart, Vp - wd1[i].vstart), aVec2(UV(1) - wd1[i].ustart, UV(2) - wd1[i].vstart);
+      CutVectorByTolerances(aVec1, tolerance);
+      CutVectorByTolerances(aVec2, tolerance);
+
+      Scal = aVec1 * aVec2;
+
+      if (Scal < 0)
+      {
+        Irang = i;
+        UV(1) = wd1[Irang].ustart;
+        UV(2) = wd1[Irang].vstart;
+        Found = Standard_True;
+      }
+      else if (Abs(UV(1) - wd1[i].ustart) < tolerance(1) && Abs(UV(2) - wd1[i].vstart) < tolerance(2))
+      {
+        Irang = i;
+        UV(1) = wd1[Irang].ustart;
+        UV(2) = wd1[Irang].vstart;
+        Found = Standard_True;
+      }
+      else if (nbMultiplicities[i] > 0)
+      {
+        for (Standard_Integer j = N + 1; j <= N + nbMultiplicities[i]; j++)
+        {
+          aVec1.SetCoord(Up - Umult(j), Vp - Vmult(j));
+          aVec2.SetCoord(UV(1) - Umult(j), UV(2) - Vmult(j));
+          CutVectorByTolerances(aVec1, tolerance);
+          CutVectorByTolerances(aVec2, tolerance);
+
+          Scal = aVec1 * aVec2;
+
+          if (Scal < 0)
+          {
+            Irang = i;
+            UV(1) = wd1[Irang].ustart;
+            UV(2) = wd1[Irang].vstart;
+            Found = Standard_True;
+            break;
+          }
+          else if (Abs(UV(1) - Umult(j)) < tolerance(1) && Abs(UV(2) - Vmult(j)) < tolerance(2))
+          {
+            Irang = i;
+            UV(1) = wd1[Irang].ustart;
+            UV(2) = wd1[Irang].vstart;
+            Found = Standard_True;
+            break;
+          }
+        }
+      }
+      if (Found)
+      {
+        Irang = -Irang; // jag 941017
+        Standard_Real abidF[1], abidD[1][2];
+        math_Vector   bidF(abidF, 1, 1);
+        math_Matrix   bidD(abidD, 1, 1, 1, 2);
+        sp.Values(UV, bidF, bidD);
+        return;
+      }
+    }
+  }
+}
+
+//-- IntWalk_IWalking_3.gxx
+
+// modified by NIZHNY-MKK  Thu Nov  2 15:07:26 2000.BEGIN
+static Standard_Boolean TestPassedSolutionWithNegativeState(const IntWalk_VectorOfWalkingData& wd,
+                                                            const TColStd_SequenceOfReal&      Umult,
+                                                            const TColStd_SequenceOfReal&      Vmult,
+                                                            const Standard_Real&               prevUp,
+                                                            const Standard_Real&               prevVp,
+                                                            const IntWalk_VectorOfInteger&     nbMultiplicities,
+                                                            const math_Vector&                 tolerance,
+                                                            TheIWFunction&                     sp,
+                                                            math_Vector&                       UV,
+                                                            Standard_Integer&                  Irang);
+// modified by NIZHNY-MKK  Thu Nov  2 15:07:39 2000.END
+
+void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
+                                       const TColStd_SequenceOfReal& Vmult,
+                                       const ThePOPIterator&         Pnts1,
+                                       TheIWFunction&                Func,
+                                       Standard_Boolean&             Rajout)
+
+// Processing of open line.
+//
+// 1) for any starting point, which is not passing and not tangent and not yet processed,
+//    calculation of the step of advancement = step depending on the arrow and the maximum step.
+//
+// 2) calculate a point of approach (this point is on the tangent to the section
+// of distance = no point in the interior)
+//
+// 3) conditions  {
+//            (all calculated points do not exceed a point in the
+//             list of starting points)
+//                              or
+//            (all points do not form an open line going
+//            from one border of the domain to the other or from a point tangent
+//            to border or from 2 tangent points : single cases)
+//
+//     1) framing of approached point on borders if necessary (there is
+//        calculation of step)
+//     2) calculation of the point
+//     3) if the point is not found the step is divided
+//     4) stop tests
+//     5) calculation of the step depending on the arrow and the max step,
+//        (TestDeflection)
+//        stop  possible.
+//    end of conditions.
+
+{
+  Standard_Integer          I = 0, N = 0, SaveN = 0;
+  Standard_Real             aBornInf[2] = {}, aBornSup[2] = {}, aUVap[2] = {};
+  math_Vector               BornInf(aBornInf, 1, 2), BornSup(aBornSup, 1, 2), UVap(aUVap, 1, 2);
+  Standard_Real             PasC = 0.0, PasCu = 0.0, PasCv = 0.0;
+  Standard_Boolean          Arrive     = false; // shows if the line ends
+  Standard_Boolean          Cadre      = false; // shows if one is on border of the domain
+  Standard_Boolean          ArretAjout = false; //shows if one is on added point
+  IntSurf_PntOn2S           Psol;
+  Handle(IntWalk_TheIWLine) CurrentLine; // line under construction
+  Standard_Boolean          Tgtend = false;
+
+  IntWalk_StatusDeflection aStatus = IntWalk_OK, StatusPrecedent = IntWalk_OK;
+
+  Standard_Integer NbDivision = 0;
+  // number of divisions of step for each section
+
+  Standard_Integer StepSign   = 0;
+
+  ThePointOfPath PathPnt;
+
+  BornInf(1) = Um;
+  BornSup(1) = UM;
+  BornInf(2) = Vm;
+  BornSup(2) = VM;
+
+  math_FunctionSetRoot Rsnld(Func, tolerance);
+  Standard_Integer     nbPath = Pnts1.Length();
+
+  // modified by NIZHNY-MKK  Fri Oct 27 12:32:34 2000.BEGIN
+  NCollection_LocalArray<Standard_Integer> movementdirectioninfoarr(nbPath + 1);
+  Standard_Integer*                        movementdirectioninfo = movementdirectioninfoarr;
+  for (I = 0; I <= nbPath; I++)
+  {
+    movementdirectioninfo[I] = 0;
+  }
+  // modified by NIZHNY-MKK  Fri Oct 27 12:32:38 2000.END
+
+  TheIWFunction aFuncForDuplicate = Func;
+
+  for (I = 1; I <= nbPath; I++)
+  {
+    //start point of the progression
+    //     if (wd1[I].etat > 11) {
+    // modified by NIZHNY-MKK  Fri Oct 27 12:33:37 2000.BEGIN
+    if ((wd1[I].etat > 11) || ((wd1[I].etat < -11) && (movementdirectioninfo[I] != 0)))
+    {
+      // modified by NIZHNY-MKK  Fri Oct 27 12:33:43 2000.END
+      PathPnt = Pnts1.Value(I);
+      UVap(1) = wd1[I].ustart;
+      UVap(2) = wd1[I].vstart;
+      MakeWalkingPoint(11, UVap(1), UVap(2), Func, previousPoint);
+
+      if (IsPointOnLine(previousPoint, BornInf, BornSup, Rsnld, aFuncForDuplicate))
+      {
+        wd1[I].etat = -Abs(wd1[I].etat); //mark point as processed
+        continue;
+      }
+
+      CurrentLine = new IntWalk_TheIWLine(new NCollection_IncAllocator());
+      CurrentLine->SetTangencyAtBegining(Standard_False);
+      Tgtend = Standard_False;
+      CurrentLine->AddStatusFirst(Standard_False, Standard_True, I, PathPnt);
+      previousd3d = Func.Direction3d();
+      previousd2d = Func.Direction2d();
+      CurrentLine->AddPoint(previousPoint);
+      // modified by NIZHNY-MKK  Fri Oct 27 12:34:32 2000.BEGIN
+      if (movementdirectioninfo[I] != 0)
+      {
+        if (movementdirectioninfo[I] < 0)
+        {
+          StepSign = -1;
+          CurrentLine->SetTangentVector(previousd3d.Reversed(), 1);
+        }
+        else
+        {
+          StepSign = 1;
+          CurrentLine->SetTangentVector(previousd3d, 1);
+        }
+      }
+      else
+      {
+        Standard_Real tyutuyt = ThePointOfPathTool::Direction3d(PathPnt) * previousd3d;
+        if (tyutuyt < 0)
+        {
+          StepSign = -1;
+          CurrentLine->SetTangentVector(previousd3d.Reversed(), 1);
+        }
+        else
+        {
+          StepSign = 1;
+          CurrentLine->SetTangentVector(previousd3d, 1);
+        }
+      }
+      // modified by NIZHNY-MKK  Fri Oct 27 12:34:37 2000.END
+
+      //  Modified by Sergey KHROMOV - Tue Nov 20 10:41:45 2001 Begin
+      wd1[I].etat              = -Abs(wd1[I].etat);
+      movementdirectioninfo[I] = (movementdirectioninfo[I] == 0) ? StepSign : 0;
+      //  Modified by Sergey KHROMOV - Tue Nov 20 10:41:56 2001 End
+      // first step of advancement
+      Standard_Real d2dx       = Abs(previousd2d.X());
+      Standard_Real d2dy       = Abs(previousd2d.Y());
+      if (d2dx < tolerance(1))
+      {
+        PasC = pas * (VM - Vm) / d2dy;
+      }
+      else if (d2dy < tolerance(2))
+      {
+        PasC = pas * (UM - Um) / d2dx;
+      }
+      else
+      {
+        PasC = pas * Min((UM - Um) / d2dx, (VM - Vm) / d2dy);
+      }
+
+      Arrive                                      = Standard_False;
+      ArretAjout                                  = Standard_False;
+      NbDivision                                  = 0;
+      StatusPrecedent                             = IntWalk_OK;
+      // modified by NIZHNY-MKK  Fri Oct 27 12:39:37 2000
+      Standard_Integer IndexOfPathPointDoNotCheck = 0;
+      Standard_Integer aNbIter                    = 10;
+      while (!Arrive)
+      { //    as one of stop tests is not checked
+        Cadre = Cadrage(BornInf, BornSup, UVap, PasC, StepSign);
+        //  Border?
+
+#ifdef CHRONO
+        Chronrsnld.Start();
+#endif
+
+        Rsnld.Perform(Func, UVap, BornInf, BornSup);
+
+#ifdef CHRONO
+        Chronrsnld.Stop();
+#endif
+
+        if (Cadre)
+        {
+          BornInf(1) = Um;
+          BornSup(1) = UM;
+          BornInf(2) = Vm;
+          BornSup(2) = VM;
+        }
+        if (Rsnld.IsDone())
+        {
+          if (Abs(Func.Root()) > Func.Tolerance())
+          {
+            PasC  = PasC / 2.0;
+            PasCu = Abs(PasC * previousd2d.X());
+            PasCv = Abs(PasC * previousd2d.Y());
+            if (PasCu <= tolerance(1) && PasCv <= tolerance(2))
+            {
+              if (CurrentLine->NbPoints() == 1)
+                break;
+              Arrive = Standard_True;
+              CurrentLine->AddStatusLast(Standard_False);
+              Tgtend = Standard_True; // check
+              Rajout = Standard_True;
+              seqAlone.Append(lines.Length() + 1);
+              seqAjout.Append(lines.Length() + 1);
+            }
+          }
+          else
+          { // test stop
+            Rsnld.Root(UVap);
+            Arrive = TestArretPassage(Umult, Vmult, Func, UVap, N);
+            if (Arrive)
+            {
+              Cadre = Standard_False;
+              //in case if there is a frame and arrive at the same time
+            }
+            else
+            {
+              if (Rajout)
+              {
+                ArretAjout = TestArretAjout(Func, UVap, N, Psol);
+                SaveN      = N;
+                if (ArretAjout)
+                {
+                  // jag 940615
+                  Tgtend = lines.Value(N)->IsTangentAtEnd();
+                  N      = -N;
+                }
+              }
+              // modified by NIZHNY-MKK  Thu Nov  2 15:09:08 2000.BEGIN
+              if (!(Rajout && ArretAjout))
+              {
+                Standard_Real prevUp, prevVp;
+                if (!reversed)
+                {
+                  previousPoint.ParametersOnS2(prevUp, prevVp);
+                }
+                else
+                {
+                  previousPoint.ParametersOnS1(prevUp, prevVp);
+                }
+                Arrive = TestPassedSolutionWithNegativeState(wd1,
+                                                             Umult,
+                                                             Vmult,
+                                                             prevUp,
+                                                             prevVp,
+                                                             nbMultiplicities,
+                                                             tolerance,
+                                                             Func,
+                                                             UVap,
+                                                             N);
+                if (Arrive)
+                {
+                  Cadre = Standard_False;
+                }
+              }
+              // modified by NIZHNY-MKK  Thu Nov  2 15:09:13 2000.END
+              if (!ArretAjout && Cadre)
+              {
+                if (CurrentLine->NbPoints() == 1)
+                  break; // cancel the line
+                TestArretCadre(Umult, Vmult, CurrentLine, Func, UVap, N);
+                //             if (N == 0) {
+                if (N <= 0)
+                { // jag 941017
+                  MakeWalkingPoint(2, UVap(1), UVap(2), Func, Psol);
+                  Tgtend = Func.IsTangent();
+                  N      = -N;
+                }
+              }
+            }
+            aStatus         = TestDeflection(Func, Arrive, UVap, StatusPrecedent, NbDivision, PasC, StepSign);
+            StatusPrecedent = aStatus;
+            if (aStatus == IntWalk_PasTropGrand)
+            {
+              Arrive     = Standard_False;
+              ArretAjout = Standard_False;
+              Tgtend     = Standard_False; // jag 940615
+              if (!reversed)
+              {
+                previousPoint.ParametersOnS2(UVap(1), UVap(2));
+              }
+              else
+              {
+                previousPoint.ParametersOnS1(UVap(1), UVap(2));
+              }
+            }
+            else if (ArretAjout || Cadre)
+            {
+              Arrive = Standard_True;
+              CurrentLine->AddStatusLast(Standard_False);
+              //if (aStatus != IntWalk_ArretSurPointPrecedent)
+              CurrentLine->AddPoint(Psol);
+              //Remove <SaveN> from <seqAlone>
+              for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++)
+                if (seqAlone(iseq) == SaveN)
+                {
+                  seqAlone.Remove(iseq);
+                  break;
+                }
+
+              if (Cadre && N == 0)
+              {
+                Rajout = Standard_True;
+                seqAjout.Append(lines.Length() + 1);
+              }
+            }
+            else if (aStatus == IntWalk_ArretSurPointPrecedent)
+            {
+              if (CurrentLine->NbPoints() == 1)
+              { //cancel the line
+                Arrive = Standard_False;
+                break;
+              }
+              Arrive = Standard_True;
+              Rajout = Standard_True;
+              //AddAlonePoint();
+              seqAlone.Append(lines.Length() + 1);
+              seqAjout.Append(lines.Length() + 1);
+              CurrentLine->AddStatusLast(Standard_False);
+              Tgtend = Standard_True; // check
+            }
+            else if (Arrive)
+            {
+              if (CurrentLine->NbPoints() == 1 && // cancel the line
+                  (N == I || aStatus == IntWalk_PointConfondu))
+              {
+                // if N == I the main uv is probably lost
+                // or the point is a point of accumulation
+                // if point is confused the start data is bad
+                Arrive = Standard_False;
+                break;
+              }
+              // necessarily N > 0 jag 940617
+              // point of stop given at input
+              PathPnt                 = Pnts1.Value(N);
+
+              Standard_Integer etat1N = wd1[N].etat;
+              // modified by NIZHNY-MKK  Thu Nov  2 15:09:51 2000.BEGIN
+              //             if (etat1N < 11) { // passing point that is a stop
+              if (Abs(etat1N) < 11)
+              { // passing point that is a stop
+                // modified by NIZHNY-MKK  Thu Nov  2 15:12:11 2000.END
+                if (aStatus == IntWalk_ArretSurPoint)
+                {
+                  CurrentLine->AddStatusLast(Standard_False);
+                  Tgtend = Standard_True; // need check
+                }
+                else
+                {
+                  Arrive = Standard_False;
+                }
+                CurrentLine->AddIndexPassing(N);
+              }
+              else
+              { // point of stop given at input
+                if (etat1N == 11)
+                {
+                  Tgtend = Standard_True;
+                }
+                CurrentLine->AddStatusLast(Standard_True, N, PathPnt);
+              }
+              AddPointInCurrentLine(N, PathPnt, CurrentLine);
+              if ((etat1N != 1 && etat1N != 11))
+              {
+                // modified by NIZHNY-MKK  Fri Oct 27 12:43:05 2000.BEGIN
+                //             wd1[N].etat= - wd1[N].etat;
+                wd1[N].etat              = -Abs(etat1N);
+                movementdirectioninfo[N] = (movementdirectioninfo[N] == 0) ? StepSign : 0;
+                if (Arrive && movementdirectioninfo[N] != 0)
+                {
+                  IndexOfPathPointDoNotCheck = N;
+                }
+
+                if (Arrive)
+                {
+                  Rajout = Standard_True;
+                  seqAjout.Append(lines.Length() + 1);
+                }
+                // modified by NIZHNY-MKK  Fri Oct 27 12:45:33 2000.END
+              }
+            }
+            else if (aStatus == IntWalk_ArretSurPoint)
+            {
+              Arrive = Standard_True;
+              CurrentLine->AddStatusLast(Standard_False);
+              Tgtend = Standard_True;
+              MakeWalkingPoint(1, UVap(1), UVap(2), Func, Psol);
+              CurrentLine->AddPoint(Psol);
+              Rajout = Standard_True;
+              seqAlone.Append(lines.Length() + 1);
+              seqAjout.Append(lines.Length() + 1);
+            }
+            else if (aStatus == IntWalk_OK)
+            {
+              MakeWalkingPoint(2, UVap(1), UVap(2), Func, previousPoint);
+              previousd3d = Func.Direction3d();
+              previousd2d = Func.Direction2d();
+              CurrentLine->AddPoint(previousPoint);
+            }
+            else if (aStatus == IntWalk_PointConfondu)
+            {
+              aNbIter--;
+            }
+          }
+        }
+        else
+        { // no numerical solution
+          PasC  = PasC / 2.;
+          PasCu = Abs(PasC * previousd2d.X());
+          PasCv = Abs(PasC * previousd2d.Y());
+          if (PasCu <= tolerance(1) && PasCv <= tolerance(2))
+          {
+            if (CurrentLine->NbPoints() == 1)
+              break;
+            Arrive = Standard_True;
+            CurrentLine->AddStatusLast(Standard_False);
+            Tgtend = Standard_True; // need check
+            Rajout = Standard_True;
+            seqAlone.Append(lines.Length() + 1);
+            seqAjout.Append(lines.Length() + 1);
+          }
+        }
+
+        if (aNbIter < 0)
+          break;
+      } // end of started line
+
+      if (Arrive)
+      {
+        CurrentLine->SetTangencyAtEnd(Tgtend);
+        lines.Append(CurrentLine);
+        // modified by NIZHNY-MKK  Fri Oct 27 12:59:29 2000.BEGIN
+        movementdirectioninfo[I] = 0;
+        if (wd1[I].etat > 0)
+          // modified by NIZHNY-MKK  Fri Oct 27 12:59:42 2000.END
+          wd1[I].etat = -wd1[I].etat;
+
+        //-- lbr le 5 juin 97 (Pb ds Contap)
+        for (Standard_Integer av = 1; av <= nbPath; av++)
+        {
+          // modified by NIZHNY-MKK  Fri Oct 27 13:00:22 2000.BEGIN
+          //     if (wd1[av].etat > 11) {
+          if ((wd1[av].etat > 11)
+              || ((av != I) && (av != IndexOfPathPointDoNotCheck) && (wd1[av].etat < -11) && (movementdirectioninfo[av] != 0)))
+          {
+            // modified by NIZHNY-MKK  Fri Oct 27 13:00:26 2000.END
+            Standard_Real          Uav = wd1[av].ustart;
+            Standard_Real          Vav = wd1[av].vstart;
+            Standard_Real          Uavp, Vavp;
+            const IntSurf_PntOn2S& avP = CurrentLine->Value(CurrentLine->NbPoints());
+            if (!reversed)
+            {
+              avP.ParametersOnS2(Uavp, Vavp);
+            }
+            else
+            {
+              avP.ParametersOnS1(Uavp, Vavp);
+            }
+            Uav -= Uavp;
+            Vav -= Vavp;
+            Uav *= 0.001;
+            Vav *= 0.001;
+            if (Abs(Uav) < tolerance(1) && Abs(Vav) < tolerance(2))
+            {
+              // modified by NIZHNY-MKK  Fri Oct 27 13:01:38 2000.BEGIN
+              //             wd1[av].etat=-wd1[av].etat;
+              if (wd1[av].etat < 0)
+              {
+                movementdirectioninfo[av] = 0;
+              }
+              else
+              {
+                wd1[av].etat              = -wd1[av].etat;
+                movementdirectioninfo[av] = StepSign;
+              }
+              // modified by NIZHNY-MKK  Fri Oct 27 13:01:42 2000.END
+              CurrentLine->AddStatusLast(Standard_True, av, Pnts1.Value(av));
+              //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl;
+            }
+
+            const IntSurf_PntOn2S& avPP = CurrentLine->Value(1);
+            if (!reversed)
+            {
+              avPP.ParametersOnS2(Uavp, Vavp);
+            }
+            else
+            {
+              avPP.ParametersOnS1(Uavp, Vavp);
+            }
+            Uav = wd1[av].ustart;
+            Vav = wd1[av].vstart;
+            Uav -= Uavp;
+            Vav -= Vavp;
+            Uav *= 0.001;
+            Vav *= 0.001;
+            if (Abs(Uav) < tolerance(1) && Abs(Vav) < tolerance(2))
+            {
+              // modified by NIZHNY-MKK  Fri Oct 27 13:02:49 2000.BEGIN
+              //             wd1[av].etat=-wd1[av].etat;
+              if (wd1[av].etat < 0)
+              {
+                movementdirectioninfo[av] = 0;
+              }
+              else
+              {
+                wd1[av].etat              = -wd1[av].etat;
+                movementdirectioninfo[av] = -StepSign;
+              }
+              // modified by NIZHNY-MKK  Fri Oct 27 13:02:52 2000.END
+              //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl;
+              CurrentLine->AddStatusFirst(Standard_False, Standard_True, av, Pnts1.Value(av));
+            }
+          }
+        }
+      }
+    } //end of point processing
+  } //end of all points
+}
+
+// modified by NIZHNY-MKK  Thu Nov  2 15:07:53 2000.BEGIN
+static Standard_Boolean TestPassedSolutionWithNegativeState(const IntWalk_VectorOfWalkingData& wd,
+                                                            const TColStd_SequenceOfReal&      Umult,
+                                                            const TColStd_SequenceOfReal&      Vmult,
+                                                            const Standard_Real&               prevUp,
+                                                            const Standard_Real&               prevVp,
+                                                            const IntWalk_VectorOfInteger&     nbMultiplicities,
+                                                            const math_Vector&                 tolerance,
+                                                            TheIWFunction&                     sp,
+                                                            math_Vector&                       UV,
+                                                            Standard_Integer&                  Irang)
+{
+  Standard_Boolean Arrive = Standard_False;
+  Standard_Real    Dup, Dvp, Utest, Vtest;
+  Standard_Real    tolu = tolerance(1);
+  Standard_Real    tolv = tolerance(2);
+  Standard_Integer i, j, k, N;
+  for (i = 1; i < (int)wd.size(); i++)
+  {
+    if (wd[i].etat < -11)
+    {
+      // debug jag see with isg
+
+      Utest = wd[i].ustart;
+      Vtest = wd[i].vstart;
+      Dup   = prevUp - Utest;
+      Dvp   = prevVp - Vtest;
+      if (Abs(Dup) >= tolu || Abs(Dvp) >= tolv)
+      {
+        Standard_Real UV1mUtest = UV(1) - Utest;
+        Standard_Real UV2mVtest = UV(2) - Vtest;
+        if (((Dup * UV1mUtest + Dvp * UV2mVtest) < 0) || (Abs(UV1mUtest) < tolu && Abs(UV2mVtest) < tolv))
+        {
+          Irang  = i;
+          Arrive = Standard_True;
+          UV(1)  = Utest;
+          UV(2)  = Vtest;
+        }
+        else if (nbMultiplicities[i] > 0)
+        {
+          N = 0;
+          for (k = 1; k < i; k++)
+          {
+            N += nbMultiplicities[k];
+          }
+          for (j = N + 1; j <= N + nbMultiplicities[i]; j++)
+          {
+            if (((prevUp - Umult(j)) * (UV(1) - Umult(j)) + (prevVp - Vmult(j)) * (UV(2) - Vmult(j)) < 0)
+                || (Abs(UV(1) - Umult(j)) < tolu && Abs(UV(2) - Vmult(j)) < tolv))
+            {
+              Irang  = i;
+              Arrive = Standard_True;
+              UV(1)  = Utest;
+              UV(2)  = Vtest;
+              break;
+            }
+          }
+        }
+        if (Arrive)
+        {
+          Standard_Real abidF[1], abidD[1][2];
+          math_Vector   bidF(abidF, 1, 1);
+          math_Matrix   bidD(abidD, 1, 1, 1, 2);
+          sp.Values(UV, bidF, bidD);
+          break;
+        }
+      }
+    }
+  }
+  return Arrive;
+}
+// modified by NIZHNY-MKK  Thu Nov  2 15:07:58 2000.END
+
+//-- IntWalk_IWalking_4.gxx
+
+void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
+                                        const TColStd_SequenceOfReal& Vmult,
+                                        const ThePOPIterator&         Pnts1,
+                                        const ThePOLIterator&         Pnts2,
+                                        TheIWFunction&                Func,
+                                        Standard_Boolean&             Rajout)
+// *********** Processing of closed line **********************
+//
+// for any interior non-processed point
+//       calculate the step of advancement=step depending on the arrow and max step
+//       calculate a point of approach (this point is on the tangent to the section
+// of distance = no interior point)
+//  conditions
+//            (all calculated points do not form a closed loop)
+//                              or
+//            (all points do not form an open line going from
+//            one border of the domain to the other or from a point tangent
+//            to the border or from 2 tangent points : single cases)
+//
+//     frame the point of approach on borders if necessary
+//     calculate the point
+//     if point not found divide the step
+//     test of stop
+//     calculate step depending on the arrow and the max step (stop possible)
+//
+// ********************************************************************
+{
+  Standard_Integer          I = 0, N = 0, SaveN = 0;
+  Standard_Real             aBornInf[2] = {}, aBornSup[2] = {}, aUVap[2] = {};
+  math_Vector               BornInf(aBornInf, 1, 2), BornSup(aBornSup, 1, 2);
+  math_Vector               Uvap(aUVap, 1, 2);  // parameters of current approach
+  Standard_Real             PasC       = 0.0;   // step of advancement on the tangent
+  Standard_Real             PasCu      = 0.0;   // step of advancement current by U
+  Standard_Real             PasCv      = 0.0;   // step of advancement current by V
+  Standard_Real             PasSav     = 0.0;   // save first step of advancement
+  Standard_Boolean          Arrive     = false; // show if line ends
+  Standard_Boolean          Cadre      = false; // show if on border of the  domains
+  Standard_Boolean          ArretAjout = false; // show if on the added point
+  IntSurf_PntOn2S           Psol;
+  Handle(IntWalk_TheIWLine) CurrentLine; //line under construction
+  ThePointOfPath            PathPnt;
+  ThePointOfLoop            LoopPnt;
+
+  Standard_Boolean Tgtbeg = false, Tgtend = false;
+
+  Standard_Integer StepSign           = 0;
+
+  IntWalk_StatusDeflection aStatus    = IntWalk_OK, StatusPrecedent;
+  Standard_Integer         NbDivision = 0; // number of divisions of step
+  // during calculation of  1 section
+
+  Standard_Integer Ipass              = 0;
+  //index in the iterator of points on edge of point of passage
+
+  BornInf(1)                          = Um;
+  BornSup(1)                          = UM;
+  BornInf(2)                          = Vm;
+  BornSup(2)                          = VM;
+
+  math_FunctionSetRoot Rsnld(Func, tolerance);
+  Standard_Integer     nbLoop = Pnts2.Length();
+
+  // Check borders for degeneracy:
+  math_Matrix            D(1, 1, 1, 2);
+  const Standard_Integer aNbSamplePnt                = 10;
+  Standard_Boolean       isLeftDegeneratedBorder[2]  = {Standard_True, Standard_True};
+  Standard_Boolean       isRightDegeneratedBorder[2] = {Standard_True, Standard_True};
+  math_Vector            aStep(1, 2);
+  aStep = (BornSup - BornInf) / (aNbSamplePnt - 1);
+  for (Standard_Integer aBorderIdx = 1; aBorderIdx <= 2; aBorderIdx++)
+  {
+    Standard_Integer aChangeIdx = aBorderIdx == 2 ? 1 : 2;
+    math_Vector      UV(1, 2);
+
+    // Left border.
+    UV(aBorderIdx) = BornInf(aBorderIdx);
+    for (Standard_Integer aParamIdx = 0; aParamIdx < aNbSamplePnt; aParamIdx++)
+    {
+      Standard_Real aParam = BornInf(aChangeIdx) + aParamIdx * aStep(aChangeIdx);
+      UV(aChangeIdx)       = aParam;
+      Func.Derivatives(UV, D);
+      if (Abs(D(1, aChangeIdx)) > Precision::Confusion())
+      {
+        isLeftDegeneratedBorder[aBorderIdx - 1] = Standard_False;
+        break;
+      }
+    }
+
+    // Right border.
+    UV(aBorderIdx) = BornSup(aBorderIdx);
+    for (Standard_Integer aParamIdx = 0; aParamIdx < aNbSamplePnt; aParamIdx++)
+    {
+      Standard_Real aParam = BornInf(aChangeIdx) + aParamIdx * aStep(aChangeIdx);
+      UV(aChangeIdx)       = aParam;
+      Func.Derivatives(UV, D);
+      if (Abs(D(1, aChangeIdx)) > Precision::Confusion())
+      {
+        isRightDegeneratedBorder[aBorderIdx - 1] = Standard_False;
+        break;
+      }
+    }
+  }
+
+  TheIWFunction aFuncForDuplicate = Func;
+
+  for (I = 1; I <= nbLoop; I++)
+  {
+    if (wd2[I].etat > 12)
+    { // start point of closed line
+      LoopPnt = Pnts2.Value(I);
+      previousPoint.SetValue(ThePointOfLoopTool::Value3d(LoopPnt), reversed, wd2[I].ustart, wd2[I].vstart);
+
+      if (IsPointOnLine(previousPoint, BornInf, BornSup, Rsnld, aFuncForDuplicate))
+      {
+        wd2[I].etat = -wd2[I].etat; //mark point as processed
+        continue;
+      }
+
+      previousd3d = ThePointOfLoopTool::Direction3d(LoopPnt);
+      previousd2d = ThePointOfLoopTool::Direction2d(LoopPnt);
+
+      CurrentLine = new IntWalk_TheIWLine(new NCollection_IncAllocator());
+      CurrentLine->AddPoint(previousPoint);
+      CurrentLine->SetTangentVector(previousd3d, 1);
+      Tgtbeg             = Standard_False;
+      Tgtend             = Standard_False;
+      Uvap(1)            = wd2[I].ustart;
+      Uvap(2)            = wd2[I].vstart;
+
+      StepSign           = 1;
+
+      // first step of advancement
+
+      Standard_Real d2dx = Abs(previousd2d.X());
+      Standard_Real d2dy = Abs(previousd2d.Y());
+      if (d2dx < tolerance(1))
+      {
+        PasC = pas * (VM - Vm) / d2dy;
+      }
+      else if (d2dy < tolerance(2))
+      {
+        PasC = pas * (UM - Um) / d2dx;
+      }
+      else
+      {
+        PasC = pas * Min((UM - Um) / d2dx, (VM - Vm) / d2dy);
+      }
+
+      PasSav                   = PasC;
+
+      Arrive                   = Standard_False;
+      ArretAjout               = Standard_False;
+      NbDivision               = 0;
+      StatusPrecedent          = IntWalk_OK;
+      Standard_Integer aNbIter = 10;
+      while (!Arrive)
+      {                                                          // as no test of stop is passed
+        Cadre = Cadrage(BornInf, BornSup, Uvap, PasC, StepSign); // border?
+#ifdef CHRONO
+        Chronrsnld.Start();
+#endif
+
+        Rsnld.Perform(Func, Uvap, BornInf, BornSup);
+
+#ifdef CHRONO
+        Chronrsnld.Stop();
+#endif
+        Standard_Boolean isOnDegeneratedBorder = Standard_False;
+
+        if (Cadre)
+        { // update of limits.
+          BornInf(1) = Um;
+          BornSup(1) = UM;
+          BornInf(2) = Vm;
+          BornSup(2) = VM;
+        }
+        if (Rsnld.IsDone())
+        {
+          if (Abs(Func.Root()) > Func.Tolerance())
+          { // no solution for the tolerance
+            PasC  = PasC / 2.;
+            PasCu = Abs(PasC * previousd2d.X());
+            PasCv = Abs(PasC * previousd2d.Y());
+
+            if (PasCu <= tolerance(1) && PasCv <= tolerance(2))
+            {
+              if (CurrentLine->NbPoints() == 1)
+              {
+                RemoveTwoEndPoints(I);
+                break; //cancel the line
+              }
+              if (wd2[I].etat > 12)
+              {                   //the line should become open
+                wd2[I].etat = 12; //declare it open
+                ArretAjout  = Standard_False;
+                OpenLine(0, Psol, Pnts1, Func, CurrentLine);
+                StepSign        = -1;
+                StatusPrecedent = IntWalk_OK;
+                Arrive          = Standard_False;
+                PasC            = PasSav;
+                Rajout          = Standard_True;
+                seqAlone.Append(-lines.Length() - 1);
+                seqAjout.Append(-lines.Length() - 1);
+              }
+              else
+              { // line s is open
+                Arrive = Standard_True;
+                CurrentLine->AddStatusLast(Standard_False);
+                Rajout = Standard_True;
+                seqAlone.Append(lines.Length() + 1);
+                seqAjout.Append(lines.Length() + 1);
+                Tgtend = Standard_True;
+              }
+              /*              
+              Arrive = Standard_True;
+              CurrentLine->AddStatusFirstLast(Standard_False,
+                Standard_False,Standard_False);
+              Rajout = Standard_True;
+              seqAlone.Append(lines.Length()+1);
+              seqAjout.Append(lines.Length()+1);
+              Tgtend = Standard_True;
+              */
+            }
+          }
+          else
+          { // there is a solution
+            Rsnld.Root(Uvap);
+
+            // Avoid uninitialized memory access.
+            if (CurrentLine->NbPoints() > 2)
+            {
+              for (Standard_Integer aCoordIdx = 1; aCoordIdx <= 2; aCoordIdx++)
+              {
+                // Check degenerated cases and fix if possible.
+                if ((isLeftDegeneratedBorder[aCoordIdx - 1]
+                     && Abs(Uvap(aCoordIdx) - BornInf(aCoordIdx)) < Precision::PConfusion())
+                    || (isRightDegeneratedBorder[aCoordIdx - 1]
+                        && Abs(Uvap(aCoordIdx) - BornSup(aCoordIdx)) < Precision::PConfusion()))
+                {
+                  Standard_Real uvprev[2], uv[2];
+                  if (!reversed)
+                  {
+                    CurrentLine->Value(CurrentLine->NbPoints() - 1).ParametersOnS2(uvprev[0], uvprev[1]);
+                    CurrentLine->Value(CurrentLine->NbPoints()).ParametersOnS2(uv[0], uv[1]);
+                  }
+                  else
+                  {
+                    CurrentLine->Value(CurrentLine->NbPoints() - 1).ParametersOnS1(uvprev[0], uvprev[1]);
+                    CurrentLine->Value(CurrentLine->NbPoints()).ParametersOnS1(uv[0], uv[1]);
+                  }
+
+                  Standard_Real aScaleCoeff = 0.0;
+
+                  // Avoid finite cycle which lead to stop computing iline.
+                  if (aStatus != IntWalk_PasTropGrand)
+                  {
+                    // Make linear extrapolation.
+                    if (Abs(uv[aCoordIdx - 1] - uvprev[aCoordIdx - 1]) > gp::Resolution())
+                      aScaleCoeff = Abs((Uvap(aCoordIdx) - uv[aCoordIdx - 1]) / (uv[aCoordIdx - 1] - uvprev[aCoordIdx - 1]));
+                    Standard_Integer aFixIdx = aCoordIdx == 1 ? 2 : 1; // Fixing index;
+                    Uvap(aFixIdx)            = uv[aFixIdx - 1] + (uv[aFixIdx - 1] - uvprev[aFixIdx - 1]) * aScaleCoeff;
+                    isOnDegeneratedBorder    = Standard_True;
+                  }
+                }
+              }
+            }
+
+            Arrive = TestArretPassage(Umult, Vmult, Uvap, I, Ipass);
+            if (Arrive)
+            { //reset proper parameter to test the arrow.
+              Psol = CurrentLine->Value(1);
+              if (!reversed)
+              {
+                Psol.ParametersOnS2(Uvap(1), Uvap(2));
+              }
+              else
+              {
+                Psol.ParametersOnS1(Uvap(1), Uvap(2));
+              }
+              Cadre = Standard_False;
+              //in case if there is a frame and arrival at the same time
+            }
+            else
+            { // modif jag 940615
+              if (Rajout)
+              { // test on added points
+                ArretAjout = TestArretAjout(Func, Uvap, N, Psol);
+                SaveN      = N;
+                if (ArretAjout)
+                {
+                  if (N > 0)
+                  {
+                    Tgtend = lines.Value(N)->IsTangentAtEnd();
+                    N      = -N;
+                  }
+                  else
+                  {
+                    Tgtend = lines.Value(-N)->IsTangentAtBegining();
+                  }
+                  Arrive = (wd2[I].etat == 12);
+                }
+              }
+
+              if (!ArretAjout && Cadre)
+              { // test on already marked points
+                if (CurrentLine->NbPoints() == 1)
+                {
+                  RemoveTwoEndPoints(I);
+                  break; // cancel the line
+                }
+                TestArretCadre(Umult, Vmult, CurrentLine, Func, Uvap, N);
+                SaveN = N;
+                //             if (N==0) {
+                if (N <= 0)
+                { // jag 941017
+                  MakeWalkingPoint(2, Uvap(1), Uvap(2), Func, Psol);
+                  Tgtend = Func.IsTangent(); // jag 940616
+                  if (isOnDegeneratedBorder)
+                    Tgtend = Standard_True;
+                  N = -N;
+                }
+                Arrive = (wd2[I].etat == 12); // the line is open
+              }
+            }
+            aStatus = TestDeflection(Func, Arrive, Uvap, StatusPrecedent, NbDivision, PasC, StepSign);
+
+            if (isOnDegeneratedBorder && Tgtend)
+              aStatus = IntWalk_ArretSurPoint;
+
+            StatusPrecedent = aStatus;
+            if (aStatus == IntWalk_PasTropGrand)
+            { // division of the step
+              Arrive     = Standard_False;
+              ArretAjout = Standard_False;
+              Tgtend     = Standard_False; // jag 940616
+              if (!reversed)
+              {
+                previousPoint.ParametersOnS2(Uvap(1), Uvap(2));
+              }
+              else
+              {
+                previousPoint.ParametersOnS1(Uvap(1), Uvap(2));
+              }
+            }
+            else if (ArretAjout || Cadre)
+            {
+              if (Arrive)
+              { // line s is open
+                CurrentLine->AddStatusLast(Standard_False);
+                //if (aStatus != IntWalk_ArretSurPointPrecedent)
+                CurrentLine->AddPoint(Psol);
+
+                //Remove <SaveN> from <seqAlone> and, if it is first found point,
+                //from <seqAjout> too
+                if (IsValidEndPoint(I, SaveN))
+                {
+                  for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++)
+                    if (seqAlone(iseq) == SaveN)
+                    {
+                      seqAlone.Remove(iseq);
+                      break;
+                    }
+                  if (CurrentLine->NbPoints() <= 3)
+                    for (Standard_Integer iseq = 1; iseq <= seqAjout.Length(); iseq++)
+                      if (seqAjout(iseq) == SaveN)
+                      {
+                        seqAjout.Remove(iseq);
+                        break;
+                      }
+                }
+                else
+                {
+                  if (seqAlone.Last() == -lines.Length() - 1)
+                  {
+                    seqAlone.Remove(seqAlone.Length());
+                    seqAjout.Remove(seqAjout.Length());
+                  }
+                  RemoveTwoEndPoints(I);
+                  Arrive = Standard_False;
+                  break; //cancel the line
+                }
+
+                if (Cadre && N == 0)
+                {
+                  Rajout = Standard_True;
+                  //seqAlone.Append(lines.Length()+1);
+                  seqAjout.Append(lines.Length() + 1);
+                }
+              }
+              else
+              {                       // open
+                wd2[I].etat     = 12; // declare it open
+                Tgtbeg          = Tgtend;
+                Tgtend          = Standard_False;
+                ArretAjout      = Standard_False;
+                StepSign        = -1;
+                StatusPrecedent = IntWalk_OK;
+                PasC            = PasSav;
+                //Check if <Psol> has been really updated
+                if (Arrive || Rajout || (!ArretAjout && Cadre && SaveN <= 0))
+                {
+                  if (aStatus == IntWalk_ArretSurPointPrecedent)
+                  {
+                    CurrentLine->AddPoint(Psol);
+                    OpenLine(0, Psol, Pnts1, Func, CurrentLine);
+                  }
+                  else
+                  {
+                    OpenLine(-lines.Length() - 1, Psol, Pnts1, Func, CurrentLine);
+                  }
+                }
+                //Remove <SaveN> from <seqAlone> and, if it is first found point,
+                //from <seqAjout> too
+                if (IsValidEndPoint(I, SaveN))
+                {
+                  for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++)
+                    if (seqAlone(iseq) == SaveN)
+                    {
+                      seqAlone.Remove(iseq);
+                      break;
+                    }
+                  if (CurrentLine->NbPoints() <= 2)
+                    for (Standard_Integer iseq = 1; iseq <= seqAjout.Length(); iseq++)
+                      if (seqAjout(iseq) == SaveN)
+                      {
+                        seqAjout.Remove(iseq);
+                        break;
+                      }
+                }
+                else
+                {
+                  RemoveTwoEndPoints(I);
+                  break; //cancel the line
+                }
+
+                if (Cadre && N == 0)
+                {
+                  Rajout = Standard_True;
+                  seqAjout.Append(-lines.Length() - 1);
+                }
+              }
+            }
+            else if (aStatus == IntWalk_ArretSurPointPrecedent)
+            {
+              if (CurrentLine->NbPoints() == 1)
+              { //cancel the line
+                Arrive = Standard_False;
+                RemoveTwoEndPoints(I);
+                break;
+              }
+              if (wd2[I].etat > 12)
+              {                   //the line should become open
+                wd2[I].etat = 12; //declare it open
+                ArretAjout  = Standard_False;
+                OpenLine(0, Psol, Pnts1, Func, CurrentLine);
+                StepSign        = -1;
+                StatusPrecedent = IntWalk_OK;
+                Arrive          = Standard_False;
+                PasC            = PasSav;
+                Rajout          = Standard_True;
+                seqAlone.Append(-lines.Length() - 1);
+                seqAjout.Append(-lines.Length() - 1);
+              }
+              else
+              { // line s is open
+                Arrive = Standard_True;
+                CurrentLine->AddStatusLast(Standard_False);
+                Rajout = Standard_True;
+                seqAlone.Append(lines.Length() + 1);
+                seqAjout.Append(lines.Length() + 1);
+              }
+            }
+            else if (Arrive)
+            {
+              if (wd2[I].etat > 12)
+              { //line closed good case
+                CurrentLine->AddStatusFirstLast(Standard_True, Standard_False, Standard_False);
+                CurrentLine->AddPoint(CurrentLine->Value(1));
+              }
+              else if ((N > 0) && (Pnts1.Length() >= N))
+              {
+                //point of stop given at input
+                PathPnt = Pnts1.Value(N);
+                CurrentLine->AddStatusLast(Standard_True, N, PathPnt);
+                AddPointInCurrentLine(N, PathPnt, CurrentLine);
+              }
+            }
+            else if (aStatus == IntWalk_ArretSurPoint)
+            {
+              if (wd2[I].etat > 12)
+              {                   //line should become open
+                wd2[I].etat = 12; //declare it open
+                Tgtbeg      = Standard_True;
+                Tgtend      = Standard_False;
+                N           = -lines.Length() - 1;
+                Psol.SetValue(Func.Point(), reversed, Uvap(1), Uvap(2));
+                OpenLine(N, Psol, Pnts1, Func, CurrentLine);
+                StepSign = -1;
+                Rajout   = Standard_True;
+                seqAlone.Append(N);
+                seqAjout.Append(N);
+                StatusPrecedent = IntWalk_OK;
+                Arrive          = Standard_False;
+                PasC            = PasSav;
+              }
+              else
+              {
+                Arrive = Standard_True;
+                if (Ipass != 0)
+                { //point of passage, point of stop
+                  PathPnt = Pnts1.Value(Ipass);
+                  CurrentLine->AddStatusLast(Standard_True, Ipass, PathPnt);
+                  AddPointInCurrentLine(Ipass, PathPnt, CurrentLine);
+                }
+                else
+                {
+                  CurrentLine->AddStatusLast(Standard_False);
+                  IntSurf_PntOn2S newP;
+                  newP.SetValue(Func.Point(), reversed, Uvap(1), Uvap(2));
+                  CurrentLine->AddPoint(newP);
+                  Rajout = Standard_True;
+                  seqAlone.Append(lines.Length() + 1);
+                  seqAjout.Append(lines.Length() + 1);
+                }
+              }
+            }
+            else if (aStatus == IntWalk_OK)
+            {
+              if (Ipass != 0)
+                CurrentLine->AddIndexPassing(Ipass);
+              previousPoint.SetValue(Func.Point(), reversed, Uvap(1), Uvap(2));
+              previousd3d = Func.Direction3d();
+              previousd2d = Func.Direction2d();
+              CurrentLine->AddPoint(previousPoint);
+            }
+            else if (aStatus == IntWalk_PointConfondu)
+            {
+              aNbIter--;
+            }
+          }
+        }
+        else
+        { //no numerical solution NotDone
+          PasC  = PasC / 2.;
+          PasCu = Abs(PasC * previousd2d.X());
+          PasCv = Abs(PasC * previousd2d.Y());
+
+          if (PasCu <= tolerance(1) && PasCv <= tolerance(2))
+          {
+            if (CurrentLine->NbPoints() == 1)
+            {
+              RemoveTwoEndPoints(I);
+              break; // cancel the line
+            }
+            if (wd2[I].etat > 12)
+            {                   //the line should become open
+              wd2[I].etat = 12; //declare it open
+              ArretAjout  = Standard_False;
+              OpenLine(0, Psol, Pnts1, Func, CurrentLine);
+              StepSign        = -1;
+              StatusPrecedent = IntWalk_OK;
+              Arrive          = Standard_False;
+              PasC            = PasSav;
+              Rajout          = Standard_True;
+              seqAlone.Append(-lines.Length() - 1);
+              seqAjout.Append(-lines.Length() - 1);
+            }
+            else
+            { // line s is open
+              Arrive = Standard_True;
+              CurrentLine->AddStatusLast(Standard_False);
+              Tgtend = Standard_True;
+              Rajout = Standard_True;
+              seqAlone.Append(lines.Length() + 1);
+              seqAjout.Append(lines.Length() + 1);
+            }
+            /*
+            Arrive = Standard_True;
+            CurrentLine->AddStatusFirstLast(Standard_False,Standard_False,
+              Standard_False);
+            Tgtend = Standard_True;
+            Rajout = Standard_True;
+            seqAlone.Append(lines.Length()+1);
+            seqAjout.Append(lines.Length()+1);
+            */
+          }
+        }
+
+        if (aNbIter < 0)
+          break;
+      } // end of started line
+      if (Arrive)
+      {
+        CurrentLine->SetTangencyAtBegining(Tgtbeg);
+        CurrentLine->SetTangencyAtEnd(Tgtend);
+
+        lines.Append(CurrentLine);
+        wd2[I].etat = -wd2[I].etat; //mark point as processed
+      }
+    } //end of processing of start point
+  } //end of all start points
+}
+
+//-- IntWalk_IWalking_5.gxx
+
+namespace
+{
+  static const Standard_Real CosRef3D       = 0.98; // rule by tests in U4
+                                                    // correspond to  11.478 d
+  static const Standard_Real    CosRef2D    = 0.88; // correspond to 25 d
+  static const Standard_Integer MaxDivision = 60;   // max number of step division
+                                                    // because the angle is too great in 2d (U4)
+}
+
+IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection(TheIWFunction&                 sp,
+                                                          const Standard_Boolean         Finished,
+                                                          const math_Vector&             UV,
+                                                          const IntWalk_StatusDeflection StatusPrecedent,
+                                                          Standard_Integer&              NbDivision,
+                                                          Standard_Real&                 Step,
+                                                          const Standard_Integer         StepSign)
+{
+  // Check the step of advancement, AND recalculate this step :
+  //
+  // 1) test point confused
+  //     if yes other tests are not done
+  // 2) test angle 3d too great
+  //     if yes divide the step and leave
+  //     angle3d = angle ((previous point, calculated point),
+  //                       previous tangent)
+  // 3) check step of advancement in 2d
+  // 4) test point confused
+  // 5) test angle 2d too great
+  // 6) test point of tangency
+  //     if yes leave
+  // 7) calculate the tangent by u,v of the section
+  // 8) test angle 3d too great
+  //     angle3d = angle ((previous point, calculated point),
+  //                       new tangent)
+  // 9) test angle 2d too great
+  //10) test change of side (pass the tangent point not knowing it)
+  //11) calculate the step of advancement depending on the vector
+  //12) adjust the step depending on the previous steps
+
+  IntWalk_StatusDeflection aStatus = IntWalk_OK;
+
+  //---------------------------------------------------------------------------------
+  //-- lbr le 4 Avril 95 : it is possible that the status returns points confused
+  //-- if epsilon is great enough (1e-11). In this case one loops
+  //-- without ever changing the values sent to Rsnld.
+  //---------------------------------------------------------------------------------
+  Standard_Real Paramu = 0.0, Paramv = 0.0;
+
+  if (!reversed)
+  {
+    previousPoint.ParametersOnS2(Paramu, Paramv);
+  }
+  else
+  {
+    previousPoint.ParametersOnS1(Paramu, Paramv);
+  }
+
+  const Standard_Real Du  = UV(1) - Paramu;
+  const Standard_Real Dv  = UV(2) - Paramv;
+  const Standard_Real Duv = Du * Du + Dv * Dv;
+
+  gp_Vec Corde(previousPoint.Value(), sp.Point());
+
+  const Standard_Real Norme = Corde.SquareMagnitude();
+
+  if ((Norme <= 4.0 * Precision::SquareConfusion())
+      && ((Duv <= Precision::SquarePConfusion()) || (StatusPrecedent != IntWalk_OK)))
+  { // the square is already taken in the constructor
+    aStatus = IntWalk_PointConfondu;
+    if (StatusPrecedent == IntWalk_PasTropGrand)
+    {
+      return IntWalk_ArretSurPointPrecedent;
+    }
+  }
+  else
+  {
+    Standard_Real Cosi  = Corde * previousd3d;
+    Standard_Real Cosi2 = 0.0;
+
+    if (Cosi * StepSign >= 0.)
+    { // angle 3d <= pi/2 !!!!
+      const Standard_Real aDiv = previousd3d.SquareMagnitude() * Norme;
+      if (aDiv == 0)
+        return aStatus;
+      Cosi2 = Cosi * Cosi / aDiv;
+    }
+    if (Cosi2 < CosRef3D)
+    { //angle 3d too great
+      Step                = Step / 2.0;
+      Standard_Real StepU = Abs(Step * previousd2d.X()), StepV = Abs(Step * previousd2d.Y());
+      if (StepU < tolerance(1) && StepV < tolerance(2))
+        aStatus = IntWalk_ArretSurPointPrecedent;
+      else
+        aStatus = IntWalk_PasTropGrand;
+      return aStatus;
+    }
+  }
+
+  const Standard_Real aMinTolU = 0.1 * Abs(Step * previousd2d.X()), aMinTolV = 0.1 * Abs(Step * previousd2d.Y());
+  const Standard_Real aTolU = (aMinTolU > 0.0) ? Min(tolerance(1), aMinTolU) : tolerance(1),
+                      aTolV = (aMinTolV > 0.0) ? Min(tolerance(2), aMinTolV) : tolerance(2);
+
+  //If aMinTolU==0.0 then (Abs(Du) < aMinTolU) is equivalent of (Abs(Du) < 0.0).
+  //It is impossible. Therefore, this case should be processed separately.
+  //Analogically for aMinTolV.
+
+  if ((Abs(Du) < aTolU) && (Abs(Dv) < aTolV))
+  {
+    //Thin shapes (for which Ulast-Ufirst or/and Vlast-Vfirst is quite small)
+    //exists (see bug #25820). In this case, step is quite small too.
+    //Nevertheless, it not always means that we mark time. Therefore, Du and Dv
+    //must consider step (aMinTolU and aMinTolV parameters).
+
+    return IntWalk_ArretSurPointPrecedent; //confused point 2d
+  }
+
+  Standard_Real Cosi = StepSign * (Du * previousd2d.X() + Dv * previousd2d.Y());
+
+  if (Cosi < 0 && aStatus == IntWalk_PointConfondu)
+    return IntWalk_ArretSurPointPrecedent; // leave as step back
+                                           // with confused point
+
+  if (sp.IsTangent())
+    return IntWalk_ArretSurPoint;
+
+  //if during routing one has subdivided more than  MaxDivision for each
+  //previous step, bug on the square; do nothing (experience U4)
+
+  if ((NbDivision < MaxDivision) && (aStatus != IntWalk_PointConfondu) && (StatusPrecedent != IntWalk_PointConfondu))
+  {
+    Standard_Real Cosi2 = Cosi * Cosi / Duv;
+    if (Cosi2 < CosRef2D || Cosi < 0)
+    {
+      Step                = Step / 2.0;
+      Standard_Real StepU = Abs(Step * previousd2d.X()), StepV = Abs(Step * previousd2d.Y());
+
+      if (StepU < tolerance(1) && StepV < tolerance(2))
+        aStatus = IntWalk_ArretSurPointPrecedent;
+      else
+        aStatus = IntWalk_PasTropGrand;
+      NbDivision = NbDivision + 1;
+      return aStatus;
+    }
+
+    Cosi  = Corde * sp.Direction3d();
+    Cosi2 = Cosi * Cosi / sp.Direction3d().SquareMagnitude() / Norme;
+    if (Cosi2 < CosRef3D)
+    { //angle 3d too great
+      Step                = Step / 2.;
+      Standard_Real StepU = Abs(Step * previousd2d.X()), StepV = Abs(Step * previousd2d.Y());
+      if (StepU < tolerance(1) && StepV < tolerance(2))
+        aStatus = IntWalk_ArretSurPoint;
+      else
+        aStatus = IntWalk_PasTropGrand;
+      return aStatus;
+    }
+    Cosi  = Du * sp.Direction2d().X() + Dv * sp.Direction2d().Y();
+    Cosi2 = Cosi * Cosi / Duv;
+    if (Cosi2 < CosRef2D || sp.Direction2d() * previousd2d < 0)
+    {
+      //angle 2d too great or change the side
+      Step                = Step / 2.;
+      Standard_Real StepU = Abs(Step * previousd2d.X()), StepV = Abs(Step * previousd2d.Y());
+      if (StepU < tolerance(1) && StepV < tolerance(2))
+        aStatus = IntWalk_ArretSurPointPrecedent;
+      else
+        aStatus = IntWalk_PasTropGrand;
+      return aStatus;
+    }
+  }
+
+  if (!Finished)
+  {
+    if (aStatus == IntWalk_PointConfondu)
+    {
+      Standard_Real StepU = Min(Abs(1.5 * Du), pas * (UM - Um)), StepV = Min(Abs(1.5 * Dv), pas * (VM - Vm));
+
+      Standard_Real d2dx = Abs(previousd2d.X());
+      Standard_Real d2dy = Abs(previousd2d.Y());
+
+      if (d2dx < tolerance(1))
+      {
+        Step = StepV / d2dy;
+      }
+      else if (d2dy < tolerance(2))
+      {
+        Step = StepU / d2dx;
+      }
+      else
+      {
+        Step = Min(StepU / d2dx, StepV / d2dy);
+      }
+    }
+    else
+    {
+      //   estimate the current vector.
+      //   if vector/2<=current vector<= vector it is considered that the criterion
+      //   is observed.
+      //   otherwise adjust the step depending on the previous step
+
+      /*
+        Standard_Real Dist = Sqrt(Norme)/3.;
+        TColgp_Array1OfPnt Poles(1,4);
+        gp_Pnt POnCurv,Milieu;
+        Poles(1) = previousPoint.Value();
+        Poles(4) = sp.Point();
+        Poles(2) = Poles(1).XYZ() + 
+      StepSign * Dist* previousd3d.Normalized().XYZ();
+        Poles(3) = Poles(4).XYZ() - 
+      StepSign * Dist*sp.Direction3d().Normalized().XYZ();
+        BzCLib::PntPole(0.5,Poles,POnCurv);
+        Milieu = (Poles(1).XYZ() + Poles(4).XYZ())*0.5;
+      //      FlecheCourante = Milieu.Distance(POnCurv);
+        Standard_Real FlecheCourante = Milieu.SquareDistance(POnCurv);
+      */
+
+      // Direct calculation :
+      // POnCurv=(((p1+p2)/2.+(p2+p3)/2.)/2. + ((p2+p3)/2.+(p3+P4)/2.)/2.)/2.
+      // either POnCurv = p1/8. + 3.p2/8. + 3.p3/8. + p4/8.
+      // Or p2 = p1 + lambda*d1 et p3 = p4 - lambda*d4
+      // So POnCurv = (p1 + p4)/2. + 3.*(lambda d1 - lambda d4)/8.
+      // Calculate the deviation with (p1+p4)/2. . So it is just necessary to calculate
+      // the norm (square) of 3.*lambda (d1 - d4)/8.
+      // either the norm of :
+      //    3.*(Sqrt(Norme)/3.)*StepSign*(d1-d4)/8.
+      // which produces, taking the square :
+      //         Norme * (d1-d4).SquareMagnitude()/64.
+
+      Standard_Real FlecheCourante = (previousd3d.Normalized().XYZ() - sp.Direction3d().Normalized().XYZ()).SquareModulus()
+                                   * Norme / 64.;
+
+      //      if (FlecheCourante <= 0.5*fleche) {
+      if (FlecheCourante <= 0.25 * fleche * fleche)
+      {
+        Standard_Real d2dx  = Abs(sp.Direction2d().X());
+        Standard_Real d2dy  = Abs(sp.Direction2d().Y());
+
+        Standard_Real StepU = Min(Abs(1.5 * Du), pas * (UM - Um)), StepV = Min(Abs(1.5 * Dv), pas * (VM - Vm));
+
+        if (d2dx < tolerance(1))
+        {
+          Step = StepV / d2dy;
+        }
+        else if (d2dy < tolerance(2))
+        {
+          Step = StepU / d2dx;
+        }
+        else
+        {
+          Step = Min(StepU / d2dx, StepV / d2dy);
+        }
+      }
+      else
+      {
+        //if (FlecheCourante > fleche) {  // step too great
+        if (FlecheCourante > fleche * fleche)
+        { // step too great
+          Step                = Step / 2.;
+          Standard_Real StepU = Abs(Step * previousd2d.X()), StepV = Abs(Step * previousd2d.Y());
+
+          if (StepU < tolerance(1) && StepV < tolerance(2))
+            aStatus = IntWalk_ArretSurPointPrecedent;
+          else
+            aStatus = IntWalk_PasTropGrand;
+        }
+        else
+        {
+          Standard_Real d2dx  = Abs(sp.Direction2d().X());
+          Standard_Real d2dy  = Abs(sp.Direction2d().Y());
+
+          Standard_Real StepU = Min(Abs(1.5 * Du), pas * (UM - Um)), StepV = Min(Abs(1.5 * Dv), pas * (VM - Vm));
+
+          if (d2dx < tolerance(1))
+          {
+            Step = Min(Step, StepV / d2dy);
+          }
+          else if (d2dy < tolerance(2))
+          {
+            Step = Min(Step, StepU / d2dx);
+          }
+          else
+          {
+            Step = Min(Step, Min(StepU / d2dx, StepV / d2dy));
+          }
+        }
+      }
+    }
+  }
+  return aStatus;
+}
+
+//-- IntWalk_IWalking_6.gxx
+
+#ifndef OCCT_DEBUG
+  #define No_Standard_RangeError
+  #define No_Standard_OutOfRange
+#endif
+
+void IntWalk_IWalking::AddPointInCurrentLine(const Standard_Integer           N,
+                                             const ThePointOfPath&            PathPnt,
+                                             const Handle(IntWalk_TheIWLine)& CurrentLine) const
+{
+  IntSurf_PntOn2S Psol;
+  Psol.SetValue(ThePointOfPathTool::Value3d(PathPnt), reversed, wd1[N].ustart, wd1[N].vstart);
+  CurrentLine->AddPoint(Psol);
+}
+
+void IntWalk_IWalking::MakeWalkingPoint(const Standard_Integer Case,
+                                        const Standard_Real    U,
+                                        const Standard_Real    V,
+                                        TheIWFunction&         sp,
+                                        IntSurf_PntOn2S&       Psol)
+
+{
+  // Case == 1      : make a WalkinkPoint.
+  // Case == 2      : make a WalkinkPoint.
+  //                  The computation of the tangency on is done
+  // Case == 10 + i : make a WalkinkPoint according to i.
+  //                  but F is updated according to U and V
+  // Case == other  : the exception Standard_Failure is raised.
+
+  if ((Case == 1) || (Case == 2))
+  {
+    Psol.SetValue(sp.Point(), reversed, U, V);
+  }
+  else if (Case == 11 || Case == 12)
+  {
+    Standard_Real aUV[2] = {}, aFF[1] = {}, aDD[1][2] = {};
+    math_Vector   UV(aUV, 1, 2);
+    math_Vector   FF(aFF, 1, 1);
+    math_Matrix   DD(aDD, 1, 1, 1, 2);
+    UV(1) = U;
+    UV(2) = V;
+    sp.Values(UV, FF, DD);
+    MakeWalkingPoint(Case - 10, U, V, sp, Psol);
+  }
+  else
+  {
+    throw Standard_ConstructionError();
+  }
+}
+
+void IntWalk_IWalking::OpenLine(const Standard_Integer           N,
+                                const IntSurf_PntOn2S&           Psol,
+                                const ThePOPIterator&            Pnts1,
+                                TheIWFunction&                   sp,
+                                const Handle(IntWalk_TheIWLine)& Line)
+// **************** open the line and restart in the other direction********
+
+{
+  ThePointOfPath PathPnt;
+
+  Standard_Real aUV[2], aFF[1], aDD[1][2];
+  math_Vector   UV(aUV, 1, 2);
+  math_Vector   FF(aFF, 1, 1);
+  math_Matrix   DD(aDD, 1, 1, 1, 2);
+
+  previousPoint = Line->Value(1);
+  if (!reversed)
+  {
+    previousPoint.ParametersOnS2(UV(1), UV(2));
+  }
+  else
+  {
+    previousPoint.ParametersOnS1(UV(1), UV(2));
+  }
+  sp.Values(UV, FF, DD);
+  previousd3d = sp.Direction3d();
+  previousd2d = sp.Direction2d();
+
+  if (N > 0)
+  { //departure point given at input
+    PathPnt = Pnts1.Value(N);
+    //mark the line as open with a given stop point
+    Line->AddStatusFirst(Standard_False, Standard_True, N, PathPnt);
+
+    AddPointInCurrentLine(N, PathPnt, Line);
+  }
+  else
+  {
+    if (N < 0)
+      Line->AddPoint(Psol);
+    Line->AddStatusFirst(Standard_False, Standard_False);
+    //mark the line as open without given stop point
+  }
+  Line->Reverse(); //inverser la ligne
+  Line->SetTangentVector(previousd3d.Reversed(), Line->NbPoints());
+}
+
+Standard_Boolean IntWalk_IWalking::IsValidEndPoint(const Standard_Integer IndOfPoint, const Standard_Integer IndOfLine)
+{
+  if (PointLineLine.IsEmpty())
+    return Standard_True;
+
+  TColStd_ListIteratorOfListOfInteger itl(PointLineLine(IndOfPoint));
+  for (; itl.More(); itl.Next())
+    if (itl.Value() == IndOfLine)
+    {
+      PointLineLine(IndOfPoint).Remove(itl);
+      return Standard_True;
+    }
+  return Standard_False;
+}
+
+void IntWalk_IWalking::RemoveTwoEndPoints(const Standard_Integer IndOfPoint)
+{
+  if (PointLineLine.IsBound(IndOfPoint))
+  {
+    Standard_Integer Line1 = PointLineLine(IndOfPoint).First();
+    Standard_Integer Line2 = PointLineLine(IndOfPoint).Last();
+    for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++)
+    {
+      if (seqAlone(iseq) == Line1 || seqAlone(iseq) == Line2)
+        seqAlone.Remove(iseq--);
+    }
+  }
+}
+
+Standard_Boolean IntWalk_IWalking::IsPointOnLine(const gp_Pnt2d& theP2d, const Standard_Integer Irang)
+{
+  const Handle(IntWalk_TheIWLine)& aLine = lines.Value(Abs(Irang));
+  for (Standard_Integer i = 1; i <= aLine->NbPoints(); i++)
+  {
+    gp_Pnt2d P2d1 = aLine->Value(i).ValueOnSurface(reversed);
+    if (Abs(P2d1.X() - theP2d.X()) <= tolerance(1) && Abs(P2d1.Y() - theP2d.Y()) <= tolerance(2))
+      return Standard_True;
+    if (i < aLine->NbPoints())
+    {
+      gp_Pnt2d P2d2 = aLine->Value(i + 1).ValueOnSurface(reversed);
+      gp_Vec2d PP1(theP2d, P2d1);
+      gp_Vec2d PP2(theP2d, P2d2);
+      if (PP1 * PP2 < 0)
+        return Standard_True;
+    }
+  }
+  return Standard_False;
+}
+
+//==================================================================================
+//function : IsPointOnLine
+//purpose  : Projects thePOn2S on the nearest segment of the already computed line.
+//           The retrieved projection point (aPa) is refined using theSolver.
+//            After the refinement, we will obtain a point aPb.
+//            If thePOn2S is quite far from aPb then thePOn2S is not
+//            in the line.
+//           Every already computed line is checked.
+//==================================================================================
+Standard_Boolean IntWalk_IWalking::IsPointOnLine(const IntSurf_PntOn2S& thePOn2S,
+                                                 const math_Vector&     theInfBounds,
+                                                 const math_Vector&     theSupBounds,
+                                                 math_FunctionSetRoot&  theSolver,
+                                                 TheIWFunction&         theFunc)
+{
+  const Standard_Real eps  = Epsilon(1.);
+  const gp_Pnt&       aP3d = thePOn2S.Value();
+
+  for (Standard_Integer aLIdx = 1; aLIdx <= lines.Length(); aLIdx++)
+  {
+    const Handle(IntSurf_LineOn2S)& aL = lines(aLIdx)->Line();
+
+    if (aL->IsOutBox(aP3d))
+      continue;
+
+    //Look for the nearest segment
+    Standard_Real aUMin = 0.0, aVMin = 0.0;
+    Standard_Real aMinSqDist = RealLast();
+    for (Standard_Integer aPtIdx = 1; aPtIdx < aL->NbPoints(); aPtIdx++)
+    {
+      const gp_Pnt& aP1 = aL->Value(aPtIdx).Value();
+      const gp_Pnt& aP2 = aL->Value(aPtIdx + 1).Value();
+
+      const gp_XYZ aP1P(aP3d.XYZ() - aP1.XYZ());
+      const gp_XYZ aP1P2(aP2.XYZ() - aP1.XYZ());
+
+      const Standard_Real aSq12 = aP1P2.SquareModulus();
+
+      if (aSq12 < gp::Resolution())
+        continue;
+
+      const Standard_Real aDP = aP1P.Dot(aP1P2);
+
+      Standard_Real aSqD      = RealLast();
+      if (aDP < 0.0)
+      {
+        continue;
+      }
+      else if (aDP > aSq12)
+      {
+        continue;
+      }
+      else
+      {
+        aSqD = aP1P.CrossSquareMagnitude(aP1P2) / aSq12;
+      }
+
+      if (aSqD < aMinSqDist)
+      {
+        aMinSqDist              = aSqD;
+
+        const Standard_Real aL1 = aDP / aSq12;
+        const Standard_Real aL2 = 1.0 - aL1;
+
+        if (aL1 < eps || aL2 < eps)
+        {
+          return Standard_True;
+        }
+
+        Standard_Real aU1, aV1, aU2, aV2;
+        aL->Value(aPtIdx).ParametersOnSurface(reversed, aU1, aV1);
+        aL->Value(aPtIdx + 1).ParametersOnSurface(reversed, aU2, aV2);
+
+        aUMin = aL1 * aU2 + aL2 * aU1;
+        aVMin = aL1 * aV2 + aL2 * aV1;
+      }
+    }
+
+    if (aMinSqDist > Precision::Infinite())
+      continue;
+
+    math_Vector aVecPrms(1, 2);
+    aVecPrms(1) = aUMin;
+    aVecPrms(2) = aVMin;
+    theSolver.Perform(theFunc, aVecPrms, theInfBounds, theSupBounds);
+    if (!theSolver.IsDone())
+      continue;
+
+    theSolver.Root(aVecPrms);
+
+    const gp_Pnt        aPa(theFunc.PSurface()->Value(aUMin, aVMin)), aPb(theFunc.PSurface()->Value(aVecPrms(1), aVecPrms(2)));
+    const Standard_Real aSqD1 = aPb.SquareDistance(aP3d);
+    const Standard_Real aSqD2 = aPa.SquareDistance(aPb);
+
+    if (aSqD1 < 4.0 * aSqD2)
+    {
+      return Standard_True;
+    }
+  }
 
-#include "../IntWalk/IntWalk_IWalking_1.gxx"
-#include "../IntWalk/IntWalk_IWalking_2.gxx"
-#include "../IntWalk/IntWalk_IWalking_3.gxx"
-#include "../IntWalk/IntWalk_IWalking_4.gxx"
-#include "../IntWalk/IntWalk_IWalking_5.gxx"
-#include "../IntWalk/IntWalk_IWalking_6.gxx"
+  return Standard_False;
+}
diff --git a/src/IntWalk/IntWalk_IWalking_1.gxx b/src/IntWalk/IntWalk_IWalking_1.gxx
deleted file mode 100644 (file)
index 272da63..0000000
+++ /dev/null
@@ -1,362 +0,0 @@
-// Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-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.
-
-#ifdef CHRONO
-#include <OSD_Chronometer.hxx>
-OSD_Chronometer Chronrsnld;
-
-#endif
-
-#include <NCollection_IncAllocator.hxx>
-#include <Precision.hxx>
-
-//==================================================================================
-// function : IsTangentExtCheck
-// purpose  : Additional check if the point (theU, theV) in parametric surface
-//            is a tangent point.
-//            If that is TRUE then we can go along any (!) direction in order to
-//            obtain next intersection point. At present, this case is difficult
-//            for processing. Therefore, we will return an empty intersection line
-//            in this case.
-//==================================================================================
-static Standard_Boolean IsTangentExtCheck(TheIWFunction& theFunc,
-                                          const Standard_Real theU,
-                                          const Standard_Real theV,
-                                          const Standard_Real theStepU,
-                                          const Standard_Real theStepV,
-                                          const Standard_Real theUinf,
-                                          const Standard_Real theUsup,
-                                          const Standard_Real theVinf,
-                                          const Standard_Real theVsup)
-{
-  const Standard_Real aTol = theFunc.Tolerance();
-  const Standard_Integer aNbItems = 4;
-  const Standard_Real aParU[aNbItems] = { Min(theU + theStepU, theUsup),
-                                          Max(theU - theStepU, theUinf),
-                                          theU, theU};
-  const Standard_Real aParV[aNbItems] = { theV, theV,
-                                          Min(theV + theStepV, theVsup),
-                                          Max(theV - theStepV, theVinf)};
-
-  math_Vector aX(1, 2), aVal(1, 1);
-
-  for(Standard_Integer i = 0; i < aNbItems; i++)
-  {
-    aX.Value(1) = aParU[i];
-    aX.Value(2) = aParV[i];
-
-    if(!theFunc.Value(aX, aVal))
-      continue;
-
-    if(Abs(theFunc.Root()) > aTol)
-      return Standard_False;
-  }
-
-  return Standard_True;
-}
-
-
-
-IntWalk_IWalking::IntWalk_IWalking (const Standard_Real Epsilon,
-                                    const Standard_Real Deflection,
-                                    const Standard_Real Increment,
-                                    const Standard_Boolean theToFillHoles) :
-      done(Standard_False),
-      fleche(Deflection),
-      pas(Increment),
-      tolerance(1,2),
-      epsilon(Epsilon*Epsilon),
-      reversed(Standard_False),
-      wd1 (IntWalk_VectorOfWalkingData::allocator_type (new NCollection_IncAllocator)),
-      wd2 (wd1.get_allocator()),
-      nbMultiplicities (wd1.get_allocator()),
-      Um(0.0),
-      UM(0.0),
-      Vm(0.0),
-      VM(0.0),
-      ToFillHoles(theToFillHoles)
-{
-}
-
-    
-//=======================================================================
-//function : Reset
-//purpose  : Clears NCollection_Vector-based containers and adds
-//           dummy data to maintain start index of 1 and consistent with
-//           previous TCollection_Sequence-based implementation and other
-//           used TCollection-based containers
-//=======================================================================
-
-void IntWalk_IWalking::Clear()
-{
-  wd1.clear();
-  wd2.clear();
-  IntWalk_WalkingData aDummy;
-  aDummy.etat = -10;
-  aDummy.ustart = aDummy.vstart = 0.;
-  wd1.push_back (aDummy);
-  wd2.push_back (aDummy);
-  nbMultiplicities.clear();
-  nbMultiplicities.push_back (-1);
-  
-  done = Standard_False;
-  seqAjout.Clear();
-  lines.Clear();
-}
-
-// ***************************************************************************
-     //  etat1=12 not tangent, not passes
-     //  etat1=11 tangent, not passes
-     //  etat1=2  not tangent, passes
-     //  etat1=1  tangent, passes
-     //  after a point is processed its state becomes negative.
-// ***************************************************************************
-     //  etat2=13  interior start point on closed line
-     //  etat2=12  interior start point on open line 
-     //            (line initially closed -> la line s is open)       
-     //  after a point is processed (or if it is passed over during
-     //  routing) its state becomes negative.
-// ****************************************************************************
-
-//
-// Perform with interior points
-//
-void IntWalk_IWalking::Perform(const ThePOPIterator& Pnts1,
-                              const ThePOLIterator& Pnts2,
-                              TheIWFunction& Func,
-                              const ThePSurface& Caro,
-                              const Standard_Boolean Reversed)
-
-{
-  Standard_Integer I;
-  Standard_Boolean Rajout = Standard_False;
-  Standard_Integer nbPnts1 = Pnts1.Length();
-  Standard_Integer nbPnts2 = Pnts2.Length();
-  Standard_Real U,V;
-
-  Clear();
-  reversed = Reversed;
-
-  Um = ThePSurfaceTool::FirstUParameter(Caro);
-  Vm = ThePSurfaceTool::FirstVParameter(Caro);
-  UM = ThePSurfaceTool::LastUParameter(Caro);
-  VM = ThePSurfaceTool::LastVParameter(Caro);
-
-  if (UM < Um) {
-    Standard_Real utemp = UM;
-    UM = Um;
-    Um = utemp;
-  }
-  if (VM < Vm) {
-    Standard_Real vtemp = VM;
-    VM = Vm;
-    Vm = vtemp;
-  }
-
-  const Standard_Real aStepU = pas*(UM-Um), aStepV = pas*(VM-Vm);
-
-  // Loading of etat1 and etat2  as well as  ustart and vstart.
-
-  TColStd_SequenceOfReal Umult;
-  TColStd_SequenceOfReal Vmult;
-
-  Standard_Integer decal=0;
-  wd1.reserve (nbPnts1+decal);
-  nbMultiplicities.reserve (nbPnts1+decal);
-  for (I=1;I <= nbPnts1+decal; I++) {
-    const ThePointOfPath& PathPnt = Pnts1.Value(I-decal);
-    IntWalk_WalkingData aWD1;
-    aWD1.etat = 1;
-    if (!ThePointOfPathTool::IsPassingPnt(PathPnt)) 
-      aWD1.etat = 11;
-    if (!ThePointOfPathTool::IsTangent(PathPnt))   
-      ++aWD1.etat;
-
-    if(aWD1.etat==2) {   
-      aWD1.etat=11;
-    }      
-
-    ThePointOfPathTool::Value2d(PathPnt, aWD1.ustart, aWD1.vstart);
-    mySRangeU.Add(aWD1.ustart);
-    mySRangeV.Add(aWD1.vstart);
-
-    wd1.push_back (aWD1);
-    Standard_Integer aNbMult = ThePointOfPathTool::Multiplicity(PathPnt);
-    nbMultiplicities.push_back(aNbMult);
-
-    for (Standard_Integer J = 1; J <= aNbMult; J++) {
-      ThePointOfPathTool::Parameters(PathPnt, J, U, V);
-      Umult.Append(U);
-      Vmult.Append(V);
-    }
-  }
-
-  wd2.reserve (nbPnts2);
-  for (I = 1; I <= nbPnts2; I++) {
-    IntWalk_WalkingData aWD2;
-    aWD2.etat = 1;
-    const IntSurf_InteriorPoint& anIP = Pnts2.Value(I);
-    ThePointOfLoopTool::Value2d(anIP, aWD2.ustart, aWD2.vstart);
-    mySRangeU.Add(aWD2.ustart);
-    mySRangeV.Add(aWD2.vstart);
-
-    if (!IsTangentExtCheck(Func, aWD2.ustart, aWD2.vstart, aStepU, aStepV, Um, UM, Vm, VM))
-      aWD2.etat = 13;
-    
-    wd2.push_back (aWD2);
-  }
-
-  tolerance(1) = ThePSurfaceTool::UResolution(Caro,Precision::Confusion());
-  tolerance(2) = ThePSurfaceTool::VResolution(Caro,Precision::Confusion());
-
-  Func.Set(Caro);
-
-  if (mySRangeU.Delta() > Max(tolerance(1), Precision::PConfusion()))
-  {
-    mySRangeU.Enlarge(mySRangeU.Delta());
-    mySRangeU.Common(Bnd_Range(Um, UM));
-  }
-  else
-  {
-    mySRangeU = Bnd_Range(Um, UM);
-  }
-
-  if (mySRangeV.Delta() > Max(tolerance(2), Precision::PConfusion()))
-  {
-    mySRangeV.Enlarge(mySRangeV.Delta());
-    mySRangeV.Common(Bnd_Range(Vm, VM));
-  }
-  else
-  {
-    mySRangeV = Bnd_Range(Vm, VM);
-  }
-
-  // calculation of all open lines   
-  if (nbPnts1 != 0)
-    ComputeOpenLine(Umult,Vmult,Pnts1,Func,Rajout); 
-
-  // calculation of all closed lines 
-  if (nbPnts2 != 0)
-    ComputeCloseLine(Umult,Vmult,Pnts1,Pnts2,Func,Rajout);
-
-  if (ToFillHoles)
-  {
-    Standard_Integer MaxNbIter = 10, nb_iter = 0;
-    while (seqAlone.Length() > 1 && nb_iter < MaxNbIter)
-    {
-      nb_iter++;
-      IntSurf_SequenceOfInteriorPoint PntsInHoles;
-      TColStd_SequenceOfInteger CopySeqAlone = seqAlone;
-      FillPntsInHoles(Func, CopySeqAlone, PntsInHoles);
-      wd2.clear();
-      IntWalk_WalkingData aDummy;
-      aDummy.etat = -10;
-      aDummy.ustart = aDummy.vstart = 0.;
-      wd2.push_back (aDummy);
-      Standard_Integer nbHoles = PntsInHoles.Length();
-      wd2.reserve(nbHoles);
-      for (I = 1; I <= nbHoles; I++)
-      {
-        IntWalk_WalkingData aWD2;
-        aWD2.etat = 13;
-        const IntSurf_InteriorPoint& anIP = PntsInHoles.Value(I);
-        ThePointOfLoopTool::Value2d(anIP, aWD2.ustart, aWD2.vstart);
-        wd2.push_back (aWD2);
-      }
-      ComputeCloseLine(Umult,Vmult,Pnts1,PntsInHoles,Func,Rajout);
-    }
-  }
-  
-  for (I = 1; I <= nbPnts1; I++) { 
-    if (wd1[I].etat >0) seqSingle.Append(Pnts1(I));
-  }
-  done = Standard_True;
-}
-
-
-
-//
-// Perform without interior point
-//
-
-void IntWalk_IWalking::Perform(const ThePOPIterator& Pnts1,
-                              TheIWFunction& Func,
-                              const ThePSurface& Caro,
-                              const Standard_Boolean Reversed)
-
-{
-  Standard_Integer I;
-  Standard_Boolean Rajout = Standard_False;
-  Standard_Integer nbPnts1 = Pnts1.Length();
-  Standard_Real U,V;
-
-  reversed = Reversed;
-
-
-  // Loading of etat1 as well as ustart1 and vstart1.
-
-  TColStd_SequenceOfReal Umult;
-  TColStd_SequenceOfReal Vmult;
-
-  wd1.reserve (nbPnts1);
-  for (I=1;I <= nbPnts1; I++) {
-    const ThePointOfPath& PathPnt = Pnts1.Value(I);
-    IntWalk_WalkingData aWD1;
-    aWD1.etat = 1;
-    if (!ThePointOfPathTool::IsPassingPnt(PathPnt)) aWD1.etat = 11; 
-    if (!ThePointOfPathTool::IsTangent(PathPnt))   ++aWD1.etat;
-    ThePointOfPathTool::Value2d(PathPnt, aWD1.ustart, aWD1.vstart);
-    wd1.push_back (aWD1);
-    Standard_Integer aNbMult = ThePointOfPathTool::Multiplicity(PathPnt);
-    nbMultiplicities.push_back(aNbMult);
-
-    for (Standard_Integer J = 1; J <= aNbMult; J++) {
-      ThePointOfPathTool::Parameters(PathPnt, J, U, V);
-      Umult.Append(U);
-      Vmult.Append(V);
-    }
-  }
-
-  tolerance(1) = ThePSurfaceTool::UResolution(Caro,Precision::Confusion());
-  tolerance(2) = ThePSurfaceTool::VResolution(Caro,Precision::Confusion());
-
-  Um = ThePSurfaceTool::FirstUParameter(Caro);
-  Vm = ThePSurfaceTool::FirstVParameter(Caro);
-  UM = ThePSurfaceTool::LastUParameter(Caro);
-  VM = ThePSurfaceTool::LastVParameter(Caro);
-
-  if (UM < Um) {
-    Standard_Real utemp = UM;
-    UM = Um;
-    Um = utemp;
-  }
-  if (VM < Vm) {
-    Standard_Real vtemp = VM;
-    VM = Vm;
-    Vm = vtemp;
-  }
-
-  Func.Set(Caro);
-
-  // calcul de toutes les lignes ouvertes   
-  if (nbPnts1 != 0) ComputeOpenLine(Umult,Vmult,Pnts1,Func,Rajout); 
-
-  for (I = 1; I <= nbPnts1; I++) { 
-    if (wd1[I].etat >0) seqSingle.Append(Pnts1(I));
-  }
-  done = Standard_True;
-}
-
-
-
diff --git a/src/IntWalk/IntWalk_IWalking_2.gxx b/src/IntWalk/IntWalk_IWalking_2.gxx
deleted file mode 100644 (file)
index 4e9933a..0000000
+++ /dev/null
@@ -1,935 +0,0 @@
-// Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-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.
-
-//-- IntWalk_IWalking_2.gxx
-
-#include <Bnd_Range.hxx>
-#include <TColStd_MapOfInteger.hxx>
-
-#ifndef OCCT_DEBUG
-#define No_Standard_RangeError
-#define No_Standard_OutOfRange
-#endif
-
-static void CutVectorByTolerances (gp_Vec2d&          theVector,
-                                   const math_Vector& theTolerance)
-{
-  if (Abs(theVector.X()) < theTolerance(1))
-    theVector.SetX (0.);
-  if (Abs(theVector.Y()) < theTolerance(2))
-    theVector.SetY (0.);
-}
-
-// _______________________________________________
-//
-// Location of point (u, v) in the natural domain of a surface AND update  
-// of couple (u, v) for the calculation of the next point.
-//
-Standard_Boolean IntWalk_IWalking::Cadrage 
-  (math_Vector& BornInf,
-   math_Vector& BornSup,
-   math_Vector& UVap,
-   Standard_Real& Step,
-//   Standard_Real& StepV,
-   const Standard_Integer StepSign) const 
-
-// there are always :
-// BorInf(1) <= UVap(1) <= BornSup(1) et BorInf(2) <= UVap(2) <= BornSup(2)
-// 1) check if the process point is out of the natural domain of the surface.
-// 2) if yes the approximated point is located on border taking the best direction
-// the step and a limit blocating one of the parameters during the recent call of 
-// FunctionSetRoot are modified;
-// 3) couple (u, v) is recomputed by approximation for the calculation of the next point.
-// 4) return Standard_True if location, Standard_False if no location.
-{
-  Standard_Real Duvx = previousd2d.X();
-  Standard_Real Duvy = previousd2d.Y();
-
-  if (!reversed) {
-    previousPoint.ParametersOnS2(UVap(1),UVap(2));
-  }
-  else {
-    previousPoint.ParametersOnS1(UVap(1),UVap(2));
-  }
-
-  Standard_Real U1 = UVap(1) + Step * Duvx * StepSign;
-  Standard_Real V1 = UVap(2) + Step * Duvy * StepSign;
-
-
-  Standard_Boolean infu = (U1 <= BornInf(1)+Precision::PConfusion());
-  Standard_Boolean supu = (U1 >= BornSup(1)-Precision::PConfusion());
-  Standard_Boolean infv = (V1 <= BornInf(2)+Precision::PConfusion());
-  Standard_Boolean supv = (V1 >= BornSup(2)-Precision::PConfusion());
-
-  Standard_Real theStepU,theStepV;
-
-  if (!infu && !supu && !infv && !supv) {
-    UVap(1) = U1;
-    UVap(2) = V1;
-    return Standard_False;
-  }
-
-  if ((infu || supu) && (infv || supv)) {
-    if (infu) { // jag 940616
-      if(Duvx) { 
-       theStepU = Abs((BornInf(1) - UVap(1)) / Duvx);  // iso U =BornInf(1)
-      }
-      else { 
-       theStepU = Step; 
-      }
-    }
-    else {
-      if(Duvx) { 
-       theStepU = Abs((BornSup(1) - UVap(1)) / Duvx);  // iso U =BornSup(1)
-      }
-      else { 
-       theStepU = Step;
-      }
-    }
-    if (infv) { // jag 940616
-      if(Duvy) { 
-       theStepV = Abs((BornInf(2) - UVap(2)) / Duvy);  // iso V =BornInf(2)
-      }
-      else { 
-       theStepV = Step;
-      }
-    }
-    else {
-      if(Duvy) { 
-       theStepV = Abs((BornSup(2) - UVap(2)) / Duvy);  // iso V =BornSup(2)
-      }
-      else { 
-       theStepV = Step; 
-      }
-    }
-
-
-    if (theStepU <= theStepV) {
-      Step = theStepU;
-      if (infu) {
-       UVap(1) = BornInf(1);
-       BornSup(1) = BornInf(1);
-      }
-      else {
-       UVap(1) = BornSup(1);
-       BornInf(1) = BornSup(1);
-      }
-      UVap(2) += Step*Duvy*StepSign;
-    }
-    else {
-      Step = theStepV;
-      if (infv) {
-       UVap(2) = BornInf(2);
-       BornSup(2) = BornInf(2); 
-      }
-      else {
-       UVap(2) = BornSup(2);
-       BornInf(2) = BornSup(2); 
-      }
-      UVap(1) += Step*Duvx*StepSign;
-    }
-    return Standard_True;
-  }
-
-  else if (infu) { // jag 940616
-    if(Duvx) { 
-      Standard_Real aStep = Abs((BornInf(1) - UVap(1)) / Duvx);  // iso U =BornInf(1)
-      if(aStep<Step) Step=aStep;
-    }
-    BornSup(1) = BornInf(1);                     // limit the parameter
-    UVap(1) = BornInf(1);
-    UVap(2) += Step*Duvy*StepSign;
-    return Standard_True;
-  }
-  else if (supu) { // jag 940616
-    if(Duvx) { 
-      Standard_Real aStep = Abs((BornSup(1) - UVap(1)) / Duvx);  // iso U =BornSup(1)
-      if(aStep<Step) Step=aStep;
-    }
-    BornInf(1) = BornSup(1);                    // limit the parameter
-    UVap(1) = BornSup(1);
-    UVap(2) += Step*Duvy*StepSign;
-    return Standard_True;
-  }
-  else if (infv) { // jag 940616
-    if(Duvy) { 
-      Standard_Real aStep = Abs((BornInf(2) - UVap(2)) / Duvy);  // iso V =BornInf(2) 
-      if(aStep<Step) Step=aStep;
-    }
-    BornSup(2) = BornInf(2);
-    UVap(1) += Step*Duvx*StepSign;
-    UVap(2) = BornInf(2);
-    return Standard_True;
-  }
-  else if (supv) { // jag 940616
-    if(Duvy) { 
-      Standard_Real aStep = Abs((BornSup(2) - UVap(2)) / Duvy);  // iso V =BornSup(2)
-      if(aStep<Step) Step=aStep;
-    }
-    BornInf(2) = BornSup(2);
-    UVap(1) += Step*Duvx*StepSign;
-    UVap(2) = BornSup(2);
-    return Standard_True;
-  }
-  return Standard_True;
-}
-
-
-Standard_Boolean IntWalk_IWalking::TestArretPassage
-  (const TColStd_SequenceOfReal& Umult,
-   const TColStd_SequenceOfReal& Vmult,
-   TheIWFunction& sp,
-   math_Vector& UV,
-   Standard_Integer& Irang)
-
-// Umult et Vmult : table of stop (or crossing) points on border, 
-//         here only the crossing points are taken into account.
-// UV     : the current point.
-// Irang  : at exit : give index of the stop point in uvstart1 or 0.
-//          consider that there is no risk of crossing only if there is one crossing point.
-
-
-// test of stop for an OPEN intersection line
-// 1) crossing test on all interior points
-// 2) stop test on all start points
-// if a stop is detected, the index of the stop point (Irang) is returned  
-// in the iterator of start points and the associated parameters in UV space.
-{
-  Standard_Real Up, Vp, Du, Dv, Dup, Dvp, Utest,Vtest; 
-  Standard_Integer j, N, ind;
-  Standard_Real tolu = tolerance(1);
-  Standard_Real tolv = tolerance(2);
-  Standard_Real tolu2 = 10.*tolerance(1);
-  Standard_Real tolv2 = 10.*tolerance(2);
-  
-  Standard_Boolean Arrive = Standard_False;
-  
-  // crossing test  on point that can start a loop; mark 
-  // as processed if passes through an open line 
-  
-  if (!reversed) {
-    previousPoint.ParametersOnS2(Up,Vp);
-  }
-  else {
-    previousPoint.ParametersOnS1(Up,Vp);
-  }
-
-  for (size_t i = 1; i < wd2.size(); i++) { 
-    if (wd2[i].etat > 0) { 
-      // debug jag 05.04.94
-
-//      if ((Up-wd2[i].ustart)*(UV(1)-wd2[i].ustart) +
-//       (Vp-wd2[i].vstart)*(UV(2)-wd2[i].vstart) <= 0)
-      Utest = wd2[i].ustart;
-      Vtest = wd2[i].vstart;
-
-      Du  = UV(1)-Utest;
-      Dv  = UV(2)-Vtest;
-      Dup = Up - Utest;
-      Dvp = Vp - Vtest;
-      
-//-- lbr le 30 oct 97 
-
-      //IFV for OCC20285
-
-      if ((Abs(Du) < tolu2 && Abs(Dv) < tolv2) ||
-         (Abs(Dup) < tolu2 && Abs(Dvp) < tolv2)) { 
-           
-       wd2[i].etat = -wd2[i].etat;
-      }
-      else {
-       Standard_Real DDu = (UV(1)-Up);
-       Standard_Real DDv = (UV(2)-Vp);
-       Standard_Real DDD = DDu*DDu+DDv*DDv;
-       Standard_Real DD1 = Du*Du+Dv*Dv;
-       if(DD1<=DDD) { 
-         Standard_Real DD2 = Dup*Dup+Dvp*Dvp;
-         if(DD2<=DDD && ((Du*Dup) + (Dv*Dvp*tolu/tolv) <= 0.)) {       
-           wd2[i].etat = -wd2[i].etat;
-         }
-       }
-      }
-    }
-  }
-
-  // stop test on point given at input and not yet processed
-
-//  Modified by Sergey KHROMOV - Tue Nov 20 10:55:01 2001 Begin
-// Check of all path points in the following order:
-//   * First check all not treated points;
-//   * After that check of already treated ones.
-  Standard_Integer l;
-
-  //// Modified by jgv, 28.07.2010 for OCC21914 ////
-  // There are several path points between (Up,Vp) and UV
-  // So several path points satisfy the condition
-  // Dup*UV1mUtest + Dvp*UV2mVtest) < 0
-  // We choose from them the path point with
-  // minimum distance to (Up,Vp)
-  TColStd_SequenceOfInteger i_candidates;
-  TColStd_SequenceOfReal    SqDist_candidates;
-
-  for (l = 1; l <= 2 && !Arrive; l++) {
-    Standard_Boolean isToCheck;
-
-    for (size_t i = 1; i < wd1.size(); i++) {
-      if (l == 1)
-       isToCheck = (wd1[i].etat > 0);
-      else
-       isToCheck = (wd1[i].etat < 0);
-       
-      if (isToCheck) {
-//  Modified by Sergey KHROMOV - Tue Nov 20 11:03:16 2001 End
-
-       // debug jag voir avec isg
-
-       Utest = wd1[i].ustart;
-       Vtest = wd1[i].vstart;
-       Dup = Up - Utest;
-       Dvp = Vp - Vtest;
-       if (Abs(Dup) >= tolu || Abs(Dvp) >= tolv) {
-         Standard_Real UV1mUtest = UV(1)-Utest;
-         Standard_Real UV2mVtest = UV(2)-Vtest;
-         if(( (Dup*UV1mUtest + Dvp*UV2mVtest) < 0) ||
-            (   Abs(UV1mUtest) < tolu 
-             && Abs(UV2mVtest) < tolv)) {
-           i_candidates.Append((Standard_Integer)i);
-           SqDist_candidates.Append(Dup*Dup + Dvp*Dvp);
-           /*
-           Irang=i;
-           Arrive = Standard_True;
-           UV(1) = Utest;
-           UV(2) = Vtest;
-           */
-         }
-         else if (nbMultiplicities[i] > 0 && i_candidates.IsEmpty()) {
-           N=0;
-           for (size_t k = 1; k < i; k++) { 
-             N+=nbMultiplicities[k];
-           }
-           for (j = N + 1; j <= N + nbMultiplicities[i]; j++) {
-             if (((Up-Umult(j))*(UV(1)-Umult(j)) +
-                  (Vp-Vmult(j))*(UV(2)-Vmult(j)) < 0) ||
-                 (Abs(UV(1)-Umult(j)) < tolu &&
-                  Abs(UV(2)-Vmult(j)) < tolv)) {
-               Irang=(Standard_Integer)i;
-               Arrive = Standard_True;
-               UV(1) = Utest;
-               UV(2) = Vtest;
-               break;
-             }
-           }
-         }
-         if (Arrive) {
-           Standard_Real abidF[1], abidD[1][2];
-           math_Vector bidF(abidF,1,1);
-           math_Matrix bidD(abidD,1,1,1,2);
-        sp.Values(UV,bidF,bidD);
-           break;
-         }
-       }
-      }
-    } //end of for (i = 1; i < wd1.size(); i++)
-    if (!i_candidates.IsEmpty())
-      {
-       Standard_Real MinSqDist = RealLast();
-       for (ind = 1; ind <= i_candidates.Length(); ind++)
-         if (SqDist_candidates(ind) < MinSqDist)
-           {
-             MinSqDist = SqDist_candidates(ind);
-             Irang = i_candidates(ind);
-           }
-       Arrive = Standard_True;
-       UV(1) = wd1[Irang].ustart;
-       UV(2) = wd1[Irang].vstart;
-      }
-  } //end of for (l = 1; l <= 2 && !Arrive; l++)
-  return  Arrive;
-}
-
-Standard_Boolean IntWalk_IWalking::TestArretPassage
-  (const TColStd_SequenceOfReal& Umult,
-   const TColStd_SequenceOfReal& Vmult,
-   const math_Vector& UV, 
-   const Standard_Integer Index, 
-   Standard_Integer& Irang)
-{
-// Umult, Vmult : table of stop (or crossing) points on border, here
-//          only crossing points are taken into account.
-// UV     : the current point.
-// Index  : index of the start point in uvstart2 of the current line
-//          (this is an interior point).
-// Irang  : at output : gives the index of the point passing in uvstart1 or 0.
-//          consider that there is risk to cross only one crossing point.
-
-// test of stop for a CLOSED intersection line.
-// 1) test of crossing on all interior points.
-// 2) test of crossing on all crossing points.
-
-  Standard_Real Up, Vp, Scal;
-  Standard_Boolean Arrive = Standard_False;
-  Standard_Integer N, k, i;
-  Standard_Real Utest,Vtest;
-  Standard_Real tolu = tolerance(1);
-  Standard_Real tolv = tolerance(2);
-
-  
-  // tests of stop and of crossing on all interior points.
-
-  if (!reversed) {
-    previousPoint.ParametersOnS2(Up,Vp);
-  }
-  else {
-    previousPoint.ParametersOnS1(Up,Vp);
-  }
-
-  Standard_Real UV1=UV(1);
-  Standard_Real UV2=UV(2);
-
-
-  //Normalizing factor. If it is less than 1.0 then the range will be expanded. 
-  //This is no good for computation. Therefore, it is limited.
-  //Do not limit this factor in case of highly anisotropic parametrization
-  //(parametric space is considerably larger in one direction than another).
-  const Standard_Boolean isHighlyAnisotropic = Max(tolu, tolv) > 1000. * Min(tolu, tolv);
-  const Standard_Real deltau = mySRangeU.IsVoid() ? UM - Um
-                                                  : (isHighlyAnisotropic ? mySRangeU.Delta()
-                                                                         : Max(mySRangeU.Delta(), 1.0));
-  const Standard_Real deltav = mySRangeV.IsVoid() ? VM - Vm
-                                                  : (isHighlyAnisotropic ? mySRangeV.Delta()
-                                                                         : Max(mySRangeV.Delta(), 1.0));
-
-  Up/=deltau; UV1/=deltau; 
-  Vp/=deltav; UV2/=deltav;
-
-  tolu/=deltau;
-  tolv/=deltav;
-
-  Standard_Real tolu2=tolu+tolu;
-  Standard_Real tolv2=tolv+tolv;
-
-  
-  Standard_Real dPreviousCurrent = (Up-UV1)*(Up-UV1)+(Vp-UV2)*(Vp-UV2);
-  for (k = 1; k < (int)wd2.size(); k++) { 
-    if (wd2[k].etat > 0) {
-      Utest = wd2[k].ustart;
-      Vtest = wd2[k].vstart;
-      
-      Utest/=deltau;
-      Vtest/=deltav;
-      
-      Standard_Real UV1mUtest=UV1-Utest;
-      Standard_Real UV2mVtest=UV2-Vtest;
-      if(   (UV1mUtest<tolu2 && UV1mUtest>-tolu2)
-        && (UV2mVtest<tolv2 && UV2mVtest>-tolv2)) { 
-       if(Index!=k) { 
-         //-- cout<<"* etat2 : ("<<k<<")"<<endl;
-         wd2[k].etat=-wd2[k].etat; //-- mark the point as a crossing point 
-       }
-       else {  //-- Index == k
-         //-- cout<<"* Arrive"<<endl;
-         Arrive=Standard_True;
-       }
-      }
-      else { 
-       Standard_Real UpmUtest = (Up-Utest);
-       Standard_Real VpmVtest = (Vp-Vtest);
-       Standard_Real dPreviousStart = (UpmUtest)*(UpmUtest)+(VpmVtest)*(VpmVtest);
-       Standard_Real dCurrentStart  = UV1mUtest * UV1mUtest + UV2mVtest * UV2mVtest;
-
-       Scal=(UpmUtest)*(UV1mUtest)+(VpmVtest)*(UV2mVtest);
-       if( (Abs(UpmUtest)<tolu && Abs(VpmVtest)<tolv)) { 
-         if(Index != k ) { 
-           //-- cout<<"** etat2 : ("<<k<<")"<<endl;
-           wd2[k].etat = -wd2[k].etat;
-         }
-       }
-       else if(Scal<0 && (dPreviousStart+dCurrentStart < dPreviousCurrent)) { 
-         if (Index == k ) { // on a boucle.
-           Arrive = Standard_True;
-           //-- cout<<"** Arrive  : k="<<k<<endl;
-         }
-         else {
-           //-- cout<<"*** etat2 : ("<<k<<")"<<endl;
-           wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point 
-         }
-       }
-       else if(k!=Index) {
-         if(dPreviousStart < dPreviousCurrent*0.25) { 
-           wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point 
-           //-- cout<<"**** etat2 : ("<<k<<")"<<endl;
-         }
-         else { 
-           if(dCurrentStart < dPreviousCurrent*0.25) {
-             //-- cout<<"***** etat2 : ("<<k<<")"<<endl;
-             wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point 
-           }
-           else { 
-             Standard_Real UMidUtest = 0.5*(UV1+Up)-Utest;
-             Standard_Real VMidVtest = 0.5*(UV2+Vp)-Vtest;         
-             Standard_Real dMiddleStart =  UMidUtest* UMidUtest+VMidVtest*VMidVtest;
-
-             if(dMiddleStart < dPreviousCurrent*0.5) { 
-               //-- cout<<"*********** etat2 : ("<<k<<")"<<endl;
-               wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point 
-             }
-           }
-         }
-       }
-      }
-    }
-  }
-
-  // crossing test on crossing points.
-  
-  Irang =0;
-  for (i = 1; i < (int)wd1.size(); i++) {
-    if (wd1[i].etat > 0 && wd1[i].etat < 11) { //test of crossing points 
-      Utest = wd1[i].ustart;
-      Vtest = wd1[i].vstart;
-      Utest/=deltau;
-      Vtest/=deltav;
-      
-      if (((Up-Utest) * (UV1-Utest) + (Vp-Vtest) * (UV2-Vtest) < 0) ||
-         (Abs(UV1-Utest) < tolu &&  Abs(UV2-Vtest) < tolv)) 
-       Irang = i;
-      else if (nbMultiplicities[i] > 0) {
-       N=0;
-       for (k = 1; k < i; k++) N = N + nbMultiplicities[k];
-       for (Standard_Integer j = N + 1; j <= N + nbMultiplicities[i]; j++) {
-         Standard_Real Umultj = Umult(j)/deltau;
-         Standard_Real Vmultj = Vmult(j)/deltav;         
-          if (((Up-Umultj)*(UV1-Umultj) +
-              (Vp-Vmultj)*(UV2-Vmultj) < 0) ||
-             (Abs(UV1-Umultj) < tolu &&
-              Abs(UV2-Vmultj) < tolv)) {
-           Irang=i;
-           break;
-          }
-       }
-      }
-    }    
-  }
-  return Arrive;
-}
-
-
-Standard_Boolean IntWalk_IWalking::TestArretAjout
-  (TheIWFunction& sp,
-   math_Vector& UV, 
-   Standard_Integer& Irang,
-   IntSurf_PntOn2S& Psol) 
-
-// test of stop on added points 
-// these are the points on the natural biorder that were not given at input
-// return : Psol,  the added point.
-//          Irang, index in the iterator of added points.
-//          UV,    parameter of the added point.
-//
-{
-  Standard_Boolean Arrive = Standard_False;
-  Standard_Real U1,V1;
-  Standard_Real Up,Vp; 
-
-  if (!reversed) {
-    previousPoint.ParametersOnS2(Up,Vp);
-  }
-  else {
-    previousPoint.ParametersOnS1(Up,Vp);
-  }
-
-  Standard_Integer nbAjout = seqAjout.Length();
-  for (Standard_Integer i = 1; i <= nbAjout; i++) {
-    Irang = seqAjout.Value(i);
-
-// add test Abs(Irang) <= lines.Length() for the case when 
-// a closed line is opened by adding a  1 point on this same
-// line. Anyway there is a huge problem as 2 points will be 
-// added on this line...
-
-    if (Abs(Irang) <= lines.Length()) {
-
-      const Handle(IntWalk_TheIWLine)& Line = lines.Value(Abs(Irang));
-      if (Irang>0) 
-       Psol = Line->Value(Line->NbPoints()); 
-      else 
-       Psol = Line->Value(1);
-      if (!reversed) {
-       Psol.ParametersOnS2(U1, V1);
-      }
-      else {
-       Psol.ParametersOnS1(U1, V1);
-      }
-      if (((Up-U1) * (UV(1)-U1) + 
-          (Vp-V1) * (UV(2)-V1)) < 0 ||
-         (Abs(UV(1)-U1) < tolerance(1) &&  
-          Abs(UV(2)-V1) < tolerance(2))) {
-//jag 940615   Irang= -Abs(Irang); 
-       Arrive = Standard_True; 
-       UV(1) = U1;
-       UV(2) = V1;
-       Standard_Real abidF[1], abidD[1][2];
-       math_Vector bidF(abidF,1,1);
-       math_Matrix bidD(abidD,1,1,1,2);
-    sp.Values(UV,bidF,bidD);
-       break;
-      }
-    }
-  }
-  return Arrive;
-}
-
-void IntWalk_IWalking::FillPntsInHoles(TheIWFunction& sp,
-                                       TColStd_SequenceOfInteger& CopySeqAlone,
-                                       IntSurf_SequenceOfInteriorPoint& PntsInHoles)
-{
-  math_Vector BornInf(1,2), BornSup(1,2);
-  BornInf(1) = Um;
-  BornSup(1) = UM;
-  BornInf(2) = Vm;
-  BornSup(2) = VM;
-  PointLineLine.Clear();
-  TColStd_SequenceOfInteger SeqToRemove;
-  TColStd_MapOfInteger BadSolutions;
-  
-  for (Standard_Integer i = 1; i < CopySeqAlone.Length(); i++)
-  {
-    Standard_Integer Irang1 = CopySeqAlone(i);
-    if (Irang1 == 0)
-      continue;
-    Standard_Boolean ToRemove = Standard_False;
-    IntSurf_PntOn2S PointAlone1, PointAlone2;
-    const Handle(IntWalk_TheIWLine)& Line1 = lines.Value(Abs(Irang1));
-    if (Irang1 > 0) 
-      PointAlone1 = Line1->Value(Line1->NbPoints()); 
-    else 
-      PointAlone1 = Line1->Value(1);
-    gp_Pnt2d P2d1 = PointAlone1.ValueOnSurface(reversed), P2d2;
-    Standard_Real MinSqDist = RealLast();
-    Standard_Integer MinRang = 0, MinIndex = 0;
-    for (Standard_Integer j = i+1; j <= CopySeqAlone.Length(); j++)
-    {
-      Standard_Integer Irang2 = CopySeqAlone(j);
-      if (Irang2 == 0 ||
-          BadSolutions.Contains(Irang2))
-        continue;
-      const Handle(IntWalk_TheIWLine)& Line2 = lines.Value(Abs(Irang2));
-      if (Irang2 > 0)
-        PointAlone2 = Line2->Value(Line2->NbPoints());
-      else
-        PointAlone2 = Line2->Value(1);
-      P2d2 = PointAlone2.ValueOnSurface(reversed);
-      Standard_Real aSqDist = P2d1.SquareDistance(P2d2);
-      if (aSqDist < MinSqDist)
-      {
-        MinSqDist = aSqDist;
-        MinRang = Irang2;
-        MinIndex = j;
-      }
-    }
-    //processing points from Irang1 and MinRang
-    if (MinRang == 0)
-    {
-      SeqToRemove.Append(Irang1);
-      BadSolutions.Clear();
-      continue;
-    }
-    //Ends of same line
-    if (Abs(Irang1) == Abs(MinRang) &&
-        lines.Value(Abs(Irang1))->NbPoints() == 2)
-    {
-      SeqToRemove.Append(Irang1);
-      SeqToRemove.Append(MinRang);
-      CopySeqAlone(i) = 0;
-      CopySeqAlone(MinIndex) = 0;
-      BadSolutions.Clear();
-      continue;
-    }
-    ///////////////////
-    const Handle(IntWalk_TheIWLine)& Line2 = lines.Value(Abs(MinRang));
-    if (MinRang > 0)
-      PointAlone2 = Line2->Value(Line2->NbPoints());
-    else
-      PointAlone2 = Line2->Value(1);
-    gp_Pnt Pnt1 = PointAlone1.Value();
-    gp_Pnt Pnt2 = PointAlone2.Value();
-    P2d2 = PointAlone2.ValueOnSurface(reversed);
-    Standard_Real MinSqDist3d = Pnt1.SquareDistance(Pnt2);
-    if (MinSqDist3d <= epsilon ||
-        (Abs(P2d1.X() - P2d2.X()) <= tolerance(1) &&
-         Abs(P2d1.Y() - P2d2.Y()) <= tolerance(2))) //close points
-      ToRemove = Standard_True;
-    else //real curve
-    {
-      math_Vector UVap(1,2), UV(1,2);
-      UVap(1) = (P2d1.X() + P2d2.X())/2;
-      UVap(2) = (P2d1.Y() + P2d2.Y())/2;
-      math_FunctionSetRoot Rsnld(sp, tolerance);
-      Rsnld.Perform(sp, UVap, BornInf, BornSup);
-      if (Rsnld.IsDone() &&
-          Abs(sp.Root()) <= sp.Tolerance() &&
-          !sp.IsTangent())
-      {
-        Rsnld.Root(UV);
-        gp_Pnt2d Pmid(UV(1),UV(2));
-        gp_Vec2d P1P2(P2d1, P2d2);
-        gp_Vec2d P1Pmid(P2d1, Pmid);
-        gp_Vec2d P2Pmid(P2d2, Pmid);
-        Standard_Real ScalProd1 = P1P2 * P1Pmid;
-        Standard_Real ScalProd2 = P1P2 * P2Pmid;
-        Standard_Boolean IsPmidValid = (ScalProd1 > 0. && ScalProd2 < 0); //Pmid is in the middle
-        if (IsPmidValid)
-        {
-          for (Standard_Integer iline = 1; iline <= lines.Length(); iline++)
-            if (IsPointOnLine(Pmid,iline))
-            {
-              IsPmidValid = Standard_False;
-              break;
-            }
-        }
-        if (IsPmidValid)
-        {
-          IntSurf_InteriorPoint aPoint(sp.Point(), UV(1), UV(2),
-                                       sp.Direction3d(),
-                                       sp.Direction2d());
-          PntsInHoles.Append(aPoint);
-          TColStd_ListOfInteger LineLine;
-          LineLine.Append(Irang1);
-          LineLine.Append(MinRang);
-          PointLineLine.Bind(PntsInHoles.Length(), LineLine);
-        }
-        else
-        {
-          BadSolutions.Add(MinRang);
-          i--;
-          continue;
-        }
-      }
-      else
-      {
-        BadSolutions.Add(MinRang);
-        i--;
-        continue;
-      }
-    }
-    CopySeqAlone(i) = 0;
-    CopySeqAlone(MinIndex) = 0;
-    if (ToRemove)
-    {
-      SeqToRemove.Append(Irang1);
-      SeqToRemove.Append(MinRang);
-    }
-    BadSolutions.Clear();
-  }
-
-  for (Standard_Integer i = 1; i <= SeqToRemove.Length(); i++)
-    for (Standard_Integer j = 1; j <= seqAlone.Length(); j++)
-      if (seqAlone(j) == SeqToRemove(i))
-      {
-        seqAlone.Remove(j);
-        break;
-      }
-}
-
-void IntWalk_IWalking::TestArretCadre
-  (const TColStd_SequenceOfReal& Umult,
-   const TColStd_SequenceOfReal& Vmult,
-   const Handle(IntWalk_TheIWLine)& Line,
-   TheIWFunction& sp,
-   math_Vector& UV,
-   Standard_Integer& Irang)
-
-// test of stop when located on border.
-// tried all tests of stop and arrived.
-// test of stop on all given departure points already marked and on the entire current line.
-// This line can be shortened if the stop point is found.
-// Abs(Irang) = index in the iterator of departure points or 0
-//  if Irang <0 , it is necessary to add this point on the line (no Line->Cut)
-// UV = parameter of the departure point
-{
-  Standard_Real Scal, Up, Vp, Uc, Vc;
-  Standard_Integer N;
-  Standard_Boolean Found = Standard_False;
-
-
-  Irang =0;
-  for (Standard_Integer i = 1; i < (int)wd1.size(); i++) {
-    if (wd1[i].etat < 0) {
-      N=0; // range in UVMult.
-      if (nbMultiplicities[i] > 0) {
-       for (Standard_Integer k = 1; k < i; k++) 
-         N+=nbMultiplicities[k];
-      }
-      if (!reversed) {
-       Line->Value(1).ParametersOnS2(Up,Vp);
-      }
-      else {
-       Line->Value(1).ParametersOnS1(Up,Vp);
-      }
-      Standard_Integer nbp= Line->NbPoints();
-      for (Standard_Integer j = 2; j <= nbp; j++) {
-       if (!reversed) {
-         Line->Value(j).ParametersOnS2(Uc,Vc);
-       }
-       else {
-         Line->Value(j).ParametersOnS1(Uc,Vc);
-       }
-
-        gp_Vec2d aVec1 (Up-wd1[i].ustart, Vp-wd1[i].vstart),
-          aVec2 (Uc-wd1[i].ustart, Vc-wd1[i].vstart);
-        CutVectorByTolerances (aVec1, tolerance);
-        CutVectorByTolerances (aVec2, tolerance);
-
-        Scal = aVec1 * aVec2;
-        
-        // if a stop point is found: stop the line on this point.
-       if (Scal < 0) { 
-          Line->Cut(j);  nbp= Line->NbPoints();
-          Irang = i;
-         UV(1) = wd1[Irang].ustart;
-         UV(2) = wd1[Irang].vstart;
-          Found = Standard_True;
-       }
-       else if (Abs(Uc-wd1[i].ustart) < tolerance(1) &&
-                Abs(Vc-wd1[i].vstart) < tolerance(2) ) {
-          Line->Cut(j);  nbp= Line->NbPoints();
-          Irang=i; 
-         UV(1) = wd1[Irang].ustart;
-         UV(2) = wd1[Irang].vstart;
-          Found = Standard_True;
-       }
-       else if (nbMultiplicities[i] > 0) {
-          for (Standard_Integer k = N+1; k <= N + nbMultiplicities[i]; k++) {
-
-            aVec1.SetCoord (Up-Umult(k), Vp-Vmult(k)),
-            aVec2.SetCoord (Uc-Umult(k), Vc-Vmult(k));
-            CutVectorByTolerances (aVec1, tolerance);
-            CutVectorByTolerances (aVec2, tolerance);
-
-            Scal = aVec1 * aVec2;
-            
-           if (Scal < 0) { 
-             Line->Cut(j);  nbp= Line->NbPoints();
-             Irang=i;
-             UV(1) = wd1[Irang].ustart;
-             UV(2) = wd1[Irang].vstart;
-             Found = Standard_True;
-             break;
-           }
-           else if (Abs(Uc-Umult(k)) < tolerance(1) &&
-                    Abs(Vc-Vmult(k)) < tolerance(2)) {
-             Line->Cut(j);  nbp= Line->NbPoints();
-             Irang=i; 
-             UV(1) = wd1[Irang].ustart;
-             UV(2) = wd1[Irang].vstart;
-             Found = Standard_True;
-             break;
-           }
-          }
-       }
-       if (Found) {
-         Standard_Real abidF[1], abidD[1][2];
-         math_Vector bidF(abidF,1,1);
-         math_Matrix bidD(abidD,1,1,1,2);
-      sp.Values(UV,bidF,bidD);
-         Standard_Integer NBP =  Line->NbPoints();
-         Standard_Integer Indextg;       
-         Line->TangentVector(Indextg);
-         if(Indextg > NBP) { 
-           if(j>3 && j<=NBP+1) { 
-             gp_Vec Dir3d = sp.Direction3d();
-             gp_Vec Dir3d1 = gp_Vec(Line->Value(j-2).Value(),Line->Value(j-1).Value());
-             Standard_Real dot = Dir3d.Dot(Dir3d1);
-             if(dot<0.0) { // Normally this Function should not be used often !!! 
-               Dir3d.Reverse();
-               //-- cout<<" IntWalk_IWalking_2.gxx REVERSE "<<endl;
-             }
-             Line->SetTangentVector(previousd3d,j-1);
-           }
-#ifdef OCCT_DEBUG
-           else { 
-             std::cout<<" IntWalk_IWalking_2.gxx : bizarrerie 30 10 97 "<<std::endl;
-           }
-#endif
-         }
-
-         return;
-       }
-       Up = Uc;
-       Vp = Vc;
-      }
-
-      // now the last point of the line and the last calculated point are compated.
-      // there will be no need to "Cut"
-
-      gp_Vec2d aVec1 (Up-wd1[i].ustart, Vp-wd1[i].vstart),
-        aVec2 (UV(1)-wd1[i].ustart, UV(2)-wd1[i].vstart);
-      CutVectorByTolerances (aVec1, tolerance);
-      CutVectorByTolerances (aVec2, tolerance);
-      
-      Scal = aVec1 * aVec2;
-      
-      if (Scal < 0) { 
-        Irang = i;
-       UV(1) = wd1[Irang].ustart;
-       UV(2) = wd1[Irang].vstart;
-       Found = Standard_True;
-      }
-      else if (Abs(UV(1)-wd1[i].ustart) < tolerance(1) &&
-              Abs(UV(2)-wd1[i].vstart) < tolerance(2)) {
-        Irang=i; 
-       UV(1) = wd1[Irang].ustart;
-       UV(2) = wd1[Irang].vstart;
-       Found = Standard_True;
-      }
-      else if (nbMultiplicities[i] > 0) {
-        for (Standard_Integer j = N+1; j <= N+nbMultiplicities[i]; j++) {
-
-          aVec1.SetCoord (Up-Umult(j), Vp-Vmult(j));
-          aVec2.SetCoord (UV(1)-Umult(j), UV(2)-Vmult(j));
-          CutVectorByTolerances (aVec1, tolerance);
-          CutVectorByTolerances (aVec2, tolerance);
-          
-          Scal = aVec1 * aVec2;
-          
-         if (Scal < 0) { 
-           Irang=i;
-           UV(1) = wd1[Irang].ustart;
-           UV(2) = wd1[Irang].vstart;
-           Found = Standard_True;
-           break;
-         }
-         else if (Abs(UV(1)-Umult(j)) < tolerance(1) &&
-                  Abs(UV(2)-Vmult(j)) < tolerance(2)) {
-           Irang=i; 
-           UV(1) = wd1[Irang].ustart;
-           UV(2) = wd1[Irang].vstart;
-           Found = Standard_True;
-           break;
-         }
-        }
-      }
-      if (Found) {
-       Irang = -Irang; // jag 941017
-       Standard_Real abidF[1], abidD[1][2];
-       math_Vector bidF(abidF,1,1);
-       math_Matrix bidD(abidD,1,1,1,2);
-    sp.Values(UV,bidF,bidD);
-       return;
-      }
-    }
-  } 
-}
-
-
diff --git a/src/IntWalk/IntWalk_IWalking_3.gxx b/src/IntWalk/IntWalk_IWalking_3.gxx
deleted file mode 100644 (file)
index a2c4823..0000000
+++ /dev/null
@@ -1,531 +0,0 @@
-// Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-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 <NCollection_IncAllocator.hxx>
-#include <NCollection_LocalArray.hxx>
-
-
-// modified by NIZHNY-MKK  Thu Nov  2 15:07:26 2000.BEGIN
-static Standard_Boolean TestPassedSolutionWithNegativeState(const IntWalk_VectorOfWalkingData& wd,
-                                                           const TColStd_SequenceOfReal& Umult,
-                                                           const TColStd_SequenceOfReal& Vmult,
-                                                           const Standard_Real& prevUp, 
-                                                           const Standard_Real& prevVp,
-                                                           const IntWalk_VectorOfInteger& nbMultiplicities,
-                                                           const math_Vector& tolerance,
-                                                           TheIWFunction& sp,
-                                                           math_Vector& UV,
-                                                           Standard_Integer& Irang);
-// modified by NIZHNY-MKK  Thu Nov  2 15:07:39 2000.END
-
-
-void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
-                                      const TColStd_SequenceOfReal& Vmult,
-                                      const ThePOPIterator& Pnts1,
-                                      TheIWFunction& Func,
-                                      Standard_Boolean& Rajout) 
-
-// Processing of open line.
-//
-// 1) for any starting point, which is not passing and not tangent and not yet processed,
-//    calculation of the step of advancement = step depending on the arrow and the maximum step.
-//
-// 2) calculate a point of approach (this point is on the tangent to the section
-// of distance = no point in the interior)
-//  
-// 3) conditions  {
-//            (all calculated points do not exceed a point in the
-//             list of starting points)
-//                              or                    
-//            (all points do not form an open line going 
-//            from one border of the domain to the other or from a point tangent 
-//            to border or from 2 tangent points : single cases)
-//  
-//     1) framing of approached point on borders if necessary (there is
-//        calculation of step)
-//     2) calculation of the point
-//     3) if the point is not found the step is divided
-//     4) stop tests
-//     5) calculation of the step depending on the arrow and the max step,
-//        (TestDeflection)
-//        stop  possible.
-//    end of conditions.
-
-{
-  Standard_Integer I = 0, N = 0, SaveN = 0;
-  Standard_Real aBornInf[2] = {}, aBornSup[2] = {}, aUVap[2] = {};
-  math_Vector BornInf(aBornInf,1,2), BornSup(aBornSup,1,2), UVap(aUVap,1,2);
-  Standard_Real PasC = 0.0, PasCu = 0.0, PasCv = 0.0;
-  Standard_Boolean Arrive = false; // shows if the line ends
-  Standard_Boolean Cadre = false;  // shows if one is on border of the domain
-  Standard_Boolean ArretAjout = false;  //shows if one is on added point
-  IntSurf_PntOn2S Psol;
-  Handle(IntWalk_TheIWLine)  CurrentLine;    // line under construction
-  Standard_Boolean Tgtend = false;
-
-  IntWalk_StatusDeflection aStatus = IntWalk_OK, StatusPrecedent = IntWalk_OK;
-  
-  Standard_Integer NbDivision = 0;
-  // number of divisions of step for each section
-
-  Standard_Integer StepSign = 0;
-  
-  ThePointOfPath PathPnt;
-
-  BornInf(1) = Um;
-  BornSup(1) = UM;
-  BornInf(2) = Vm;
-  BornSup(2) = VM;
-
-  math_FunctionSetRoot Rsnld(Func, tolerance);
-  Standard_Integer nbPath = Pnts1.Length();
-
-  // modified by NIZHNY-MKK  Fri Oct 27 12:32:34 2000.BEGIN
-  NCollection_LocalArray<Standard_Integer> movementdirectioninfoarr (nbPath + 1);
-  Standard_Integer* movementdirectioninfo = movementdirectioninfoarr;
-  for (I = 0; I <= nbPath; I++) {
-    movementdirectioninfo[I] = 0;
-  }
-  // modified by NIZHNY-MKK  Fri Oct 27 12:32:38 2000.END
-
-  TheIWFunction aFuncForDuplicate = Func;
-
-  for (I = 1; I <= nbPath; I++) {
-    //start point of the progression
-    //     if (wd1[I].etat > 11) {                
-    // modified by NIZHNY-MKK  Fri Oct 27 12:33:37 2000.BEGIN
-    if ((wd1[I].etat > 11) || ((wd1[I].etat < -11) && (movementdirectioninfo[I]!=0))) {
-    // modified by NIZHNY-MKK  Fri Oct 27 12:33:43 2000.END
-      PathPnt = Pnts1.Value(I);
-      UVap(1) = wd1[I].ustart;
-      UVap(2) = wd1[I].vstart;
-      MakeWalkingPoint(11, UVap(1), UVap(2), Func, previousPoint);
-
-      if (IsPointOnLine(previousPoint, BornInf, BornSup, Rsnld, aFuncForDuplicate))
-      {
-        wd1[I].etat = -Abs(wd1[I].etat); //mark point as processed
-        continue;
-      }
-
-      CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator());
-      CurrentLine->SetTangencyAtBegining(Standard_False);
-      Tgtend = Standard_False;
-      CurrentLine->AddStatusFirst(Standard_False, Standard_True, I, PathPnt);
-      previousd3d = Func.Direction3d();
-      previousd2d = Func.Direction2d();
-      CurrentLine->AddPoint(previousPoint);
-      // modified by NIZHNY-MKK  Fri Oct 27 12:34:32 2000.BEGIN
-      if(movementdirectioninfo[I] !=0) {
-        if(movementdirectioninfo[I] < 0) {
-          StepSign = -1;
-          CurrentLine->SetTangentVector(previousd3d.Reversed(),1);
-        } else {
-          StepSign = 1; 
-          CurrentLine->SetTangentVector(previousd3d,1);
-        }
-      } else {
-        Standard_Real tyutuyt=ThePointOfPathTool::Direction3d(PathPnt) * previousd3d;
-        if( tyutuyt < 0) {
-          StepSign = -1;
-          CurrentLine->SetTangentVector(previousd3d.Reversed(),1);
-        }
-        else {
-          StepSign = 1; 
-          CurrentLine->SetTangentVector(previousd3d,1);
-        }
-      }
-      // modified by NIZHNY-MKK  Fri Oct 27 12:34:37 2000.END
-
-      //  Modified by Sergey KHROMOV - Tue Nov 20 10:41:45 2001 Begin
-      wd1[I].etat = -Abs(wd1[I].etat);
-      movementdirectioninfo[I] = (movementdirectioninfo[I]==0) ? StepSign : 0;
-//  Modified by Sergey KHROMOV - Tue Nov 20 10:41:56 2001 End
-      // first step of advancement
-      Standard_Real d2dx = Abs(previousd2d.X()); 
-      Standard_Real d2dy = Abs(previousd2d.Y()); 
-      if (d2dx < tolerance(1)) {
-        PasC = pas * (VM-Vm)/d2dy;
-      }
-      else if (d2dy < tolerance(2)) {
-        PasC = pas * (UM-Um)/d2dx;
-      }
-      else {
-        PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy);
-      }
-
-      Arrive = Standard_False;
-      ArretAjout = Standard_False;
-      NbDivision = 0;
-      StatusPrecedent = IntWalk_OK;
-      // modified by NIZHNY-MKK  Fri Oct 27 12:39:37 2000
-      Standard_Integer IndexOfPathPointDoNotCheck=0;
-      Standard_Integer aNbIter = 10;
-      while (!Arrive) { //    as one of stop tests is not checked
-        Cadre = Cadrage(BornInf,BornSup,UVap,PasC,StepSign);
-        //  Border?
-
-#ifdef CHRONO
-        Chronrsnld.Start();
-#endif
-
-        Rsnld.Perform(Func,UVap,BornInf,BornSup);
-
-#ifdef CHRONO
-        Chronrsnld.Stop();
-#endif
-
-        if (Cadre) {
-          BornInf(1) = Um; BornSup(1) = UM; BornInf(2) = Vm; BornSup(2) = VM;
-        }
-        if (Rsnld.IsDone()) {
-          if (Abs(Func.Root()) > Func.Tolerance()) {
-            PasC = PasC / 2.0;
-            PasCu = Abs(PasC*previousd2d.X());
-            PasCv = Abs(PasC*previousd2d.Y());
-            if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
-              if (CurrentLine->NbPoints() == 1) break;
-              Arrive = Standard_True;
-              CurrentLine->AddStatusLast(Standard_False);
-              Tgtend = Standard_True; // check
-              Rajout = Standard_True;
-              seqAlone.Append(lines.Length() + 1);
-              seqAjout.Append(lines.Length() + 1);
-            }  
-          }
-          else { // test stop
-            Rsnld.Root(UVap);
-            Arrive = TestArretPassage(Umult, Vmult, Func, UVap, N);
-            if (Arrive) {
-              Cadre = Standard_False;
-              //in case if there is a frame and arrive at the same time
-            }
-            else {
-              if (Rajout) {
-                ArretAjout =TestArretAjout(Func, UVap, N, Psol);
-                SaveN = N;
-                if (ArretAjout) {
-                  // jag 940615
-                  Tgtend = lines.Value(N)->IsTangentAtEnd();
-                  N = -N;
-                }
-              }
-              // modified by NIZHNY-MKK  Thu Nov  2 15:09:08 2000.BEGIN
-              if(!(Rajout && ArretAjout)) {
-                Standard_Real prevUp, prevVp;
-                if (!reversed) {
-                  previousPoint.ParametersOnS2(prevUp, prevVp);
-                }
-                else {
-                  previousPoint.ParametersOnS1(prevUp, prevVp);
-                }
-                Arrive = TestPassedSolutionWithNegativeState(wd1, Umult, Vmult, prevUp, prevVp,
-                  nbMultiplicities, tolerance, Func, UVap, N);         
-                if(Arrive) {
-                  Cadre = Standard_False;
-                }
-              }
-              // modified by NIZHNY-MKK  Thu Nov  2 15:09:13 2000.END
-              if (!ArretAjout && Cadre) {
-                if (CurrentLine->NbPoints() == 1) break; // cancel the line
-                TestArretCadre(Umult, Vmult, CurrentLine, Func, UVap, N);
-                //             if (N == 0) {
-                if (N <= 0) { // jag 941017
-                  MakeWalkingPoint(2, UVap(1), UVap(2), Func, Psol);
-                  Tgtend = Func.IsTangent();
-                  N = -N;
-                }
-              }
-            }
-            aStatus = TestDeflection(Func, Arrive, UVap, StatusPrecedent,
-              NbDivision,PasC,StepSign);
-            StatusPrecedent = aStatus;
-            if (aStatus == IntWalk_PasTropGrand) {
-              Arrive = Standard_False;
-              ArretAjout = Standard_False;
-              Tgtend = Standard_False; // jag 940615
-              if (!reversed) {
-                previousPoint.ParametersOnS2(UVap(1), UVap(2));
-              }
-              else {
-                previousPoint.ParametersOnS1(UVap(1), UVap(2));
-              }
-            }
-            else if (ArretAjout || Cadre) {
-              Arrive = Standard_True;
-              CurrentLine->AddStatusLast(Standard_False);
-              //if (aStatus != IntWalk_ArretSurPointPrecedent)
-              CurrentLine->AddPoint(Psol);                      
-              //Remove <SaveN> from <seqAlone>
-              for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++)
-                if (seqAlone(iseq) == SaveN)
-                {
-                  seqAlone.Remove(iseq);
-                  break;
-                }
-
-              if (Cadre && N==0) {
-                Rajout = Standard_True;
-                seqAjout.Append(lines.Length()+1);
-              }
-            }
-            else if (aStatus == IntWalk_ArretSurPointPrecedent) {
-              if (CurrentLine->NbPoints() == 1) { //cancel the line
-                Arrive = Standard_False;
-                break;
-              }
-              Arrive = Standard_True;
-              Rajout = Standard_True;
-              //AddAlonePoint();
-              seqAlone.Append(lines.Length() + 1);
-              seqAjout.Append(lines.Length() + 1);
-              CurrentLine->AddStatusLast(Standard_False);
-              Tgtend = Standard_True; // check
-            }
-            else if (Arrive)  {
-              if (CurrentLine->NbPoints() == 1 &&    // cancel the line
-                (N == I || aStatus == IntWalk_PointConfondu) ) {
-                  // if N == I the main uv is probably lost
-                  // or the point is a point of accumulation
-                  // if point is confused the start data is bad
-                  Arrive =  Standard_False;
-                  break;
-              }
-              // necessarily N > 0 jag 940617
-              // point of stop given at input 
-              PathPnt = Pnts1.Value(N);
-
-              Standard_Integer etat1N=wd1[N].etat;
-              // modified by NIZHNY-MKK  Thu Nov  2 15:09:51 2000.BEGIN
-              //             if (etat1N < 11) { // passing point that is a stop  
-              if (Abs(etat1N) < 11) { // passing point that is a stop    
-                // modified by NIZHNY-MKK  Thu Nov  2 15:12:11 2000.END
-                if (aStatus == IntWalk_ArretSurPoint) {
-                  CurrentLine->AddStatusLast(Standard_False);
-                  Tgtend = Standard_True; // need check
-                }
-                else { 
-                  Arrive = Standard_False;
-                }
-                CurrentLine->AddIndexPassing(N);
-              }
-              else { // point of stop given at input
-                if (etat1N == 11) {
-                  Tgtend = Standard_True;
-                }
-                CurrentLine->AddStatusLast(Standard_True, N, PathPnt);
-              }
-              AddPointInCurrentLine(N,PathPnt,CurrentLine);
-              if ((etat1N != 1 && etat1N != 11)) {
-                // modified by NIZHNY-MKK  Fri Oct 27 12:43:05 2000.BEGIN
-                //             wd1[N].etat= - wd1[N].etat;
-                wd1[N].etat = - Abs(etat1N);           
-                movementdirectioninfo[N] = (movementdirectioninfo[N]==0) ? StepSign : 0;
-                if(Arrive && movementdirectioninfo[N]!=0) {
-                  IndexOfPathPointDoNotCheck = N;
-                }
-
-                if(Arrive) {
-                  Rajout = Standard_True;
-                  seqAjout.Append(lines.Length() + 1);
-                }
-                // modified by NIZHNY-MKK  Fri Oct 27 12:45:33 2000.END
-              }
-            }
-            else if (aStatus == IntWalk_ArretSurPoint) {
-              Arrive = Standard_True;                   
-              CurrentLine->AddStatusLast(Standard_False);
-              Tgtend = Standard_True;
-              MakeWalkingPoint(1, UVap(1), UVap(2), Func, Psol);
-              CurrentLine->AddPoint(Psol);
-              Rajout = Standard_True;
-              seqAlone.Append(lines.Length() + 1);
-              seqAjout.Append(lines.Length() + 1);
-            }
-            else if (aStatus == IntWalk_OK) {
-              MakeWalkingPoint(2, UVap(1), UVap(2), Func, previousPoint);
-              previousd3d = Func.Direction3d();
-              previousd2d = Func.Direction2d();
-              CurrentLine->AddPoint(previousPoint);
-            }     
-            else if (aStatus == IntWalk_PointConfondu)
-            {
-              aNbIter --;
-            }
-          }
-        }
-        else { // no numerical solution
-          PasC = PasC / 2.;
-          PasCu = Abs(PasC*previousd2d.X());
-          PasCv = Abs(PasC*previousd2d.Y());
-          if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
-            if (CurrentLine->NbPoints()==1) break;
-            Arrive = Standard_True;
-            CurrentLine->AddStatusLast(Standard_False);
-            Tgtend = Standard_True; // need check
-            Rajout = Standard_True;
-            seqAlone.Append(lines.Length() + 1);
-            seqAjout.Append(lines.Length() + 1);
-          }  
-        }
-
-        if(aNbIter < 0)
-          break;
-      } // end of started line
-      
-      if (Arrive) {
-        CurrentLine->SetTangencyAtEnd(Tgtend);
-        lines.Append(CurrentLine);
-        // modified by NIZHNY-MKK  Fri Oct 27 12:59:29 2000.BEGIN
-        movementdirectioninfo[I]=0;
-        if(wd1[I].etat > 0)
-          // modified by NIZHNY-MKK  Fri Oct 27 12:59:42 2000.END
-          wd1[I].etat=-wd1[I].etat;
-
-        //-- lbr le 5 juin 97 (Pb ds Contap)
-        for(Standard_Integer av=1; av<=nbPath; av++) { 
-          // modified by NIZHNY-MKK  Fri Oct 27 13:00:22 2000.BEGIN
-          //     if (wd1[av].etat > 11) {
-          if ((wd1[av].etat > 11) || 
-            ((av!=I) && 
-            (av!=IndexOfPathPointDoNotCheck) && 
-            (wd1[av].etat < -11)  && 
-            (movementdirectioninfo[av]!=0)))
-          {
-            // modified by NIZHNY-MKK  Fri Oct 27 13:00:26 2000.END
-            Standard_Real Uav=wd1[av].ustart;
-            Standard_Real Vav=wd1[av].vstart;
-            Standard_Real Uavp,Vavp;
-            const IntSurf_PntOn2S &avP=CurrentLine->Value(CurrentLine->NbPoints());
-            if (!reversed) {
-              avP.ParametersOnS2(Uavp,Vavp);
-            }
-            else {
-              avP.ParametersOnS1(Uavp,Vavp);
-            }
-            Uav-=Uavp;
-            Vav-=Vavp;
-            Uav*=0.001; Vav*=0.001;
-            if(Abs(Uav)<tolerance(1) && Abs(Vav)<tolerance(2)) { 
-              // modified by NIZHNY-MKK  Fri Oct 27 13:01:38 2000.BEGIN
-              //             wd1[av].etat=-wd1[av].etat;
-              if(wd1[av].etat < 0) {
-                movementdirectioninfo[av] = 0;
-              } else {
-                wd1[av].etat=-wd1[av].etat;
-                movementdirectioninfo[av] = StepSign;
-              }
-              // modified by NIZHNY-MKK  Fri Oct 27 13:01:42 2000.END
-              CurrentLine->AddStatusLast(Standard_True, av, Pnts1.Value(av));
-              //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl;
-            }
-
-            const IntSurf_PntOn2S &avPP=CurrentLine->Value(1);
-            if (!reversed) {
-              avPP.ParametersOnS2(Uavp,Vavp);
-            }
-            else {
-              avPP.ParametersOnS1(Uavp,Vavp);
-            }
-            Uav=wd1[av].ustart;
-            Vav=wd1[av].vstart;
-            Uav-=Uavp;
-            Vav-=Vavp;
-            Uav*=0.001; Vav*=0.001;
-            if(Abs(Uav)<tolerance(1) && Abs(Vav)<tolerance(2)) { 
-              // modified by NIZHNY-MKK  Fri Oct 27 13:02:49 2000.BEGIN
-              //             wd1[av].etat=-wd1[av].etat;
-              if(wd1[av].etat < 0) {
-                movementdirectioninfo[av] = 0;
-              } else {
-                wd1[av].etat=-wd1[av].etat;
-                movementdirectioninfo[av] = -StepSign;
-              }
-              // modified by NIZHNY-MKK  Fri Oct 27 13:02:52 2000.END
-              //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl;
-              CurrentLine->AddStatusFirst(Standard_False, Standard_True, av, Pnts1.Value(av));
-            }
-          }
-        }
-      }
-    } //end of point processing
-  } //end of all points
-}
-
-// modified by NIZHNY-MKK  Thu Nov  2 15:07:53 2000.BEGIN
-static Standard_Boolean TestPassedSolutionWithNegativeState(const IntWalk_VectorOfWalkingData& wd,
-                                                           const TColStd_SequenceOfReal& Umult,
-                                                           const TColStd_SequenceOfReal& Vmult,
-                                                           const Standard_Real& prevUp,
-                                                           const Standard_Real& prevVp,
-                                                           const IntWalk_VectorOfInteger& nbMultiplicities,
-                                                           const math_Vector& tolerance,
-                                                           TheIWFunction& sp,
-                                                           math_Vector& UV,
-                                                           Standard_Integer& Irang) {
-  Standard_Boolean Arrive = Standard_False;
-  Standard_Real Dup, Dvp, Utest,Vtest;
-  Standard_Real tolu = tolerance(1);
-  Standard_Real tolv = tolerance(2);
-  Standard_Integer i, j, k, N;
-  for (i = 1; i < (int)wd.size(); i++) {
-    if (wd[i].etat < -11) {
-
- // debug jag see with isg
-
-      Utest = wd[i].ustart;
-      Vtest = wd[i].vstart;
-      Dup = prevUp - Utest;
-      Dvp = prevVp - Vtest;
-      if (Abs(Dup) >= tolu || Abs(Dvp) >= tolv) {
-       Standard_Real UV1mUtest = UV(1)-Utest;
-       Standard_Real UV2mVtest = UV(2)-Vtest;
-       if(( (Dup*UV1mUtest + Dvp*UV2mVtest) < 0) ||
-          (   Abs(UV1mUtest) < tolu 
-           && Abs(UV2mVtest) < tolv)) {
-         Irang=i;
-         Arrive = Standard_True;
-         UV(1) = Utest;
-         UV(2) = Vtest;
-       }
-       else if (nbMultiplicities[i] > 0) {
-         N=0;
-         for (k = 1; k < i; k++) { 
-           N+=nbMultiplicities[k];
-         }
-         for (j = N + 1; j <= N + nbMultiplicities[i]; j++) {
-           if (((prevUp-Umult(j))*(UV(1)-Umult(j)) +
-                (prevVp-Vmult(j))*(UV(2)-Vmult(j)) < 0) ||
-               (Abs(UV(1)-Umult(j)) < tolu &&
-                Abs(UV(2)-Vmult(j)) < tolv)) {
-             Irang=i;
-             Arrive = Standard_True;
-             UV(1) = Utest;
-             UV(2) = Vtest;
-             break;
-           }
-         }
-       }
-       if (Arrive) {
-         Standard_Real abidF[1], abidD[1][2];
-         math_Vector bidF(abidF,1,1);
-         math_Matrix bidD(abidD,1,1,1,2); 
-      sp.Values(UV,bidF,bidD);
-         break;
-       }
-      }
-    }    
-  }
-  return Arrive;
-}
-// modified by NIZHNY-MKK  Thu Nov  2 15:07:58 2000.END
diff --git a/src/IntWalk/IntWalk_IWalking_4.gxx b/src/IntWalk/IntWalk_IWalking_4.gxx
deleted file mode 100644 (file)
index 8965974..0000000
+++ /dev/null
@@ -1,572 +0,0 @@
-// Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-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 <NCollection_IncAllocator.hxx>
-
-void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
-                                       const TColStd_SequenceOfReal& Vmult,
-                                       const ThePOPIterator& Pnts1,
-                                       const ThePOLIterator& Pnts2,
-                                       TheIWFunction& Func,
-                                        Standard_Boolean& Rajout )
-// *********** Processing of closed line **********************
-//
-// for any interior non-processed point 
-//       calculate the step of advancement=step depending on the arrow and max step
-//       calculate a point of approach (this point is on the tangent to the section
-// of distance = no interior point)
-//  conditions 
-//            (all calculated points do not form a closed loop)  
-//                              or                    
-//            (all points do not form an open line going from 
-//            one border of the domain to the other or from a point tangent
-//            to the border or from 2 tangent points : single cases)
-//  
-//     frame the point of approach on borders if necessary
-//     calculate the point
-//     if point not found divide the step
-//     test of stop    
-//     calculate step depending on the arrow and the max step (stop possible)
-//
-// ******************************************************************** 
-{
-  Standard_Integer I = 0, N = 0,SaveN = 0;
-  Standard_Real aBornInf[2] = {}, aBornSup[2] = {}, aUVap[2] = {};
-  math_Vector BornInf(aBornInf,1,2), BornSup(aBornSup,1,2);
-  math_Vector Uvap(aUVap,1,2);// parameters of current approach
-  Standard_Real PasC = 0.0;  // step of advancement on the tangent
-  Standard_Real PasCu = 0.0; // step of advancement current by U
-  Standard_Real PasCv = 0.0; // step of advancement current by V
-  Standard_Real PasSav = 0.0; // save first step of advancement
-  Standard_Boolean Arrive = false;// show if line ends
-  Standard_Boolean Cadre = false; // show if on border of the  domains
-  Standard_Boolean ArretAjout = false; // show if on the added point
-  IntSurf_PntOn2S Psol;
-  Handle(IntWalk_TheIWLine)  CurrentLine; //line under construction
-  ThePointOfPath PathPnt;
-  ThePointOfLoop LoopPnt;
-
-  Standard_Boolean Tgtbeg = false, Tgtend = false;
-
-  Standard_Integer StepSign = 0;
-  
-  IntWalk_StatusDeflection aStatus = IntWalk_OK, StatusPrecedent;
-  Standard_Integer NbDivision = 0;   // number of divisions of step
-  // during calculation of  1 section
-
-  Standard_Integer Ipass = 0;
-  //index in the iterator of points on edge of point of passage  
-
-
-  BornInf(1) = Um;
-  BornSup(1) = UM;
-  BornInf(2) = Vm;
-  BornSup(2) = VM;
-  
-  math_FunctionSetRoot Rsnld(Func,tolerance);
-  Standard_Integer nbLoop = Pnts2.Length();
-
-  // Check borders for degeneracy:
-  math_Matrix D(1,1,1,2);
-  const Standard_Integer aNbSamplePnt = 10;
-  Standard_Boolean isLeftDegeneratedBorder[2] = {Standard_True, Standard_True};
-  Standard_Boolean isRightDegeneratedBorder[2] = {Standard_True, Standard_True};
-  math_Vector aStep(1,2);
-  aStep = (BornSup - BornInf) / (aNbSamplePnt - 1);
-  for(Standard_Integer aBorderIdx = 1; aBorderIdx <= 2; aBorderIdx++)
-  {
-    Standard_Integer aChangeIdx = aBorderIdx == 2? 1 : 2;
-    math_Vector UV(1,2);
-
-    // Left border.
-    UV(aBorderIdx) = BornInf(aBorderIdx);
-    for(Standard_Integer aParamIdx = 0; aParamIdx < aNbSamplePnt; aParamIdx++)
-    {
-      Standard_Real aParam = BornInf(aChangeIdx) + aParamIdx * aStep(aChangeIdx);
-      UV(aChangeIdx) = aParam;
-      Func.Derivatives(UV, D);
-      if ( Abs(D(1, aChangeIdx) ) > Precision::Confusion())
-      {
-        isLeftDegeneratedBorder[aBorderIdx - 1] = Standard_False;
-        break;
-      }
-    }
-
-    // Right border.
-    UV(aBorderIdx) = BornSup(aBorderIdx);
-    for(Standard_Integer aParamIdx = 0; aParamIdx < aNbSamplePnt; aParamIdx++)
-    {
-      Standard_Real aParam = BornInf(aChangeIdx) + aParamIdx * aStep(aChangeIdx);
-      UV(aChangeIdx) = aParam;
-      Func.Derivatives(UV, D);
-      if ( Abs(D(1, aChangeIdx) ) > Precision::Confusion())
-      {
-        isRightDegeneratedBorder[aBorderIdx - 1] = Standard_False;
-        break;
-      }
-    }
-  }
-
-  TheIWFunction aFuncForDuplicate = Func;
-
-  for (I = 1;I<=nbLoop;I++) {
-    if (wd2[I].etat > 12)
-    { // start point of closed line
-      LoopPnt = Pnts2.Value(I);
-      previousPoint.SetValue(ThePointOfLoopTool::Value3d(LoopPnt), reversed,
-                             wd2[I].ustart, wd2[I].vstart);
-
-      if (IsPointOnLine(previousPoint, BornInf, BornSup, Rsnld, aFuncForDuplicate))
-      {
-        wd2[I].etat = -wd2[I].etat; //mark point as processed
-        continue;
-      }
-
-      previousd3d = ThePointOfLoopTool::Direction3d(LoopPnt);
-      previousd2d = ThePointOfLoopTool::Direction2d(LoopPnt);
-
-      CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator());
-      CurrentLine->AddPoint(previousPoint);
-      CurrentLine->SetTangentVector(previousd3d,1);
-      Tgtbeg = Standard_False;
-      Tgtend = Standard_False;
-      Uvap(1) = wd2[I].ustart;
-      Uvap(2) = wd2[I].vstart;
-
-      StepSign = 1;
-
-      // first step of advancement
-
-      Standard_Real d2dx = Abs(previousd2d.X()); 
-      Standard_Real d2dy = Abs(previousd2d.Y()); 
-      if (d2dx < tolerance(1)) {
-        PasC = pas * (VM-Vm)/d2dy;
-      }
-      else if (d2dy < tolerance(2)) {
-        PasC = pas * (UM-Um)/d2dx;
-      }
-      else {
-        PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy);
-      }
-
-      PasSav = PasC;
-
-      Arrive = Standard_False;
-      ArretAjout = Standard_False;
-      NbDivision = 0;
-      StatusPrecedent = IntWalk_OK;
-      Standard_Integer aNbIter = 10;
-      while (!Arrive) {  // as no test of stop is passed
-        Cadre=Cadrage(BornInf,BornSup,Uvap,PasC, StepSign);  // border?
-#ifdef CHRONO
-        Chronrsnld.Start();
-#endif
-
-        Rsnld.Perform(Func,Uvap,BornInf,BornSup);
-
-#ifdef CHRONO
-        Chronrsnld.Stop();
-#endif
-        Standard_Boolean isOnDegeneratedBorder = Standard_False;
-        
-        if (Cadre) { // update of limits.
-          BornInf(1) = Um;BornSup(1) = UM;BornInf(2) = Vm;BornSup(2) = VM;
-        }
-        if (Rsnld.IsDone()) {
-          if (Abs(Func.Root()) > Func.Tolerance()) { // no solution for the tolerance
-            PasC = PasC/2.;
-            PasCu = Abs(PasC*previousd2d.X());
-            PasCv = Abs(PasC*previousd2d.Y());
-
-            if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
-              if (CurrentLine->NbPoints()==1)
-              {
-                RemoveTwoEndPoints(I);
-                break; //cancel the line
-              }
-              if (wd2[I].etat >12) { //the line should become open
-                wd2[I].etat = 12; //declare it open
-                ArretAjout = Standard_False;
-                OpenLine(0,Psol,Pnts1,Func,CurrentLine);
-                StepSign = -1;
-                StatusPrecedent = IntWalk_OK;
-                Arrive = Standard_False;
-                PasC = PasSav;
-                Rajout = Standard_True;
-                seqAlone.Append(-lines.Length()-1);
-                seqAjout.Append(-lines.Length()-1);
-              }
-              else { // line s is open                 
-                Arrive =Standard_True;
-                CurrentLine->AddStatusLast(Standard_False);
-                Rajout = Standard_True;
-                seqAlone.Append(lines.Length()+1);
-                seqAjout.Append(lines.Length()+1);
-                Tgtend = Standard_True;
-              } 
-              /*              
-              Arrive = Standard_True;
-              CurrentLine->AddStatusFirstLast(Standard_False,
-                Standard_False,Standard_False);
-              Rajout = Standard_True;
-              seqAlone.Append(lines.Length()+1);
-              seqAjout.Append(lines.Length()+1);
-              Tgtend = Standard_True;
-              */
-            }
-          }
-          else { // there is a solution
-            Rsnld.Root(Uvap);
-
-            // Avoid uninitialized memory access.
-            if (CurrentLine->NbPoints() > 2)
-            {
-              for(Standard_Integer aCoordIdx = 1; aCoordIdx <= 2; aCoordIdx++)
-              {
-                // Check degenerated cases and fix if possible.
-                if ( ( isLeftDegeneratedBorder[aCoordIdx - 1]
-                && Abs (Uvap(aCoordIdx) - BornInf(aCoordIdx)) < Precision::PConfusion())||
-                  (isRightDegeneratedBorder[aCoordIdx - 1]
-                && Abs (Uvap(aCoordIdx) - BornSup(aCoordIdx)) < Precision::PConfusion()) )
-                {
-                  Standard_Real uvprev[2], uv[2];
-                  if (!reversed)
-                  {
-                    CurrentLine->Value(CurrentLine->NbPoints() - 1).ParametersOnS2(uvprev[0], uvprev[1]);
-                    CurrentLine->Value(CurrentLine->NbPoints()).ParametersOnS2(uv[0], uv[1]);
-                  }
-                  else
-                  {
-                    CurrentLine->Value(CurrentLine->NbPoints() - 1).ParametersOnS1(uvprev[0], uvprev[1]);
-                    CurrentLine->Value(CurrentLine->NbPoints()).ParametersOnS1(uv[0], uv[1]);
-                  }
-
-                  Standard_Real aScaleCoeff = 0.0;
-
-                  // Avoid finite cycle which lead to stop computing iline.
-                  if (aStatus != IntWalk_PasTropGrand)
-                  {
-                    // Make linear extrapolation.
-                    if ( Abs(uv[aCoordIdx - 1] - uvprev[aCoordIdx - 1]) > gp::Resolution())
-                      aScaleCoeff = Abs ((Uvap(aCoordIdx) - uv[aCoordIdx - 1])
-                                      /  (uv[aCoordIdx - 1] - uvprev[aCoordIdx - 1]) );
-                    Standard_Integer aFixIdx =  aCoordIdx == 1? 2 : 1; // Fixing index;
-                    Uvap(aFixIdx) = uv[aFixIdx - 1] + (uv[aFixIdx - 1] - uvprev[aFixIdx - 1]) * aScaleCoeff;
-                    isOnDegeneratedBorder = Standard_True;
-                  }
-                }
-              }
-            }
-
-            Arrive = TestArretPassage(Umult,Vmult,Uvap,I,Ipass);
-            if (Arrive) {//reset proper parameter to test the arrow.
-              Psol = CurrentLine->Value(1);
-              if (!reversed) {
-                Psol.ParametersOnS2(Uvap(1),Uvap(2));
-              }
-              else {
-                Psol.ParametersOnS1(Uvap(1),Uvap(2));
-              }
-              Cadre=Standard_False; 
-              //in case if there is a frame and arrival at the same time
-            }
-            else { // modif jag 940615
-              if (Rajout) {    // test on added points
-                ArretAjout =TestArretAjout(Func,Uvap,N,Psol);
-                SaveN = N;
-                if (ArretAjout) {
-                  if (N >0) {
-                    Tgtend = lines.Value(N)->IsTangentAtEnd();
-                    N = -N;
-                  }
-                  else {
-                    Tgtend = lines.Value(-N)->IsTangentAtBegining();
-                  }
-                  Arrive = (wd2[I].etat == 12);
-                }
-              }
-
-              if (!ArretAjout&& Cadre) {  // test on already marked points
-                if (CurrentLine->NbPoints() == 1)
-                {
-                  RemoveTwoEndPoints(I);
-                  break; // cancel the line
-                }
-                TestArretCadre(Umult,Vmult,CurrentLine,Func,Uvap,N);
-                SaveN = N;
-                //             if (N==0) {
-                if (N <= 0) { // jag 941017
-                  MakeWalkingPoint(2,Uvap(1),Uvap(2),Func,Psol);
-                  Tgtend = Func.IsTangent(); // jag 940616
-                  if (isOnDegeneratedBorder)
-                    Tgtend = Standard_True;
-                  N = -N;
-                }
-                Arrive = (wd2[I].etat == 12); // the line is open
-              }
-            }
-            aStatus = TestDeflection(Func, Arrive,Uvap,StatusPrecedent,
-                                                NbDivision,PasC,StepSign);
-
-            if (isOnDegeneratedBorder && Tgtend)
-              aStatus = IntWalk_ArretSurPoint;
-            
-            StatusPrecedent = aStatus;
-            if (aStatus == IntWalk_PasTropGrand) {// division of the step
-              Arrive = Standard_False;
-              ArretAjout = Standard_False;
-              Tgtend = Standard_False; // jag 940616
-              if (!reversed) {
-                previousPoint.ParametersOnS2(Uvap(1),Uvap(2));
-              }
-              else {
-                previousPoint.ParametersOnS1(Uvap(1),Uvap(2));
-              }
-            }
-            else if (ArretAjout || Cadre) {
-
-              if (Arrive) { // line s is open
-                CurrentLine->AddStatusLast(Standard_False);
-                //if (aStatus != IntWalk_ArretSurPointPrecedent)
-                CurrentLine->AddPoint(Psol);
-
-                //Remove <SaveN> from <seqAlone> and, if it is first found point,
-                //from <seqAjout> too
-                if (IsValidEndPoint(I, SaveN))
-                {
-                  for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++)
-                    if (seqAlone(iseq) == SaveN)
-                    {
-                      seqAlone.Remove(iseq);
-                      break;
-                    }
-                  if (CurrentLine->NbPoints() <= 3)
-                    for (Standard_Integer iseq = 1; iseq <= seqAjout.Length(); iseq++)
-                      if (seqAjout(iseq) == SaveN)
-                      {
-                        seqAjout.Remove(iseq);
-                        break;
-                      }
-                }
-                else
-                {
-                  if (seqAlone.Last() == -lines.Length()-1)
-                  {
-                    seqAlone.Remove(seqAlone.Length());
-                    seqAjout.Remove(seqAjout.Length());
-                  }
-                  RemoveTwoEndPoints(I);
-                  Arrive = Standard_False;
-                  break; //cancel the line
-                }
-
-                if (Cadre && N==0) {
-                  Rajout = Standard_True;
-                  //seqAlone.Append(lines.Length()+1);
-                  seqAjout.Append(lines.Length()+1);
-                }
-
-              }
-              else { // open
-                wd2[I].etat = 12; // declare it open
-                Tgtbeg = Tgtend;
-                Tgtend = Standard_False;
-                ArretAjout = Standard_False;
-                StepSign = -1;
-                StatusPrecedent = IntWalk_OK;
-                PasC = PasSav;
-                //Check if <Psol> has been really updated
-                if (Arrive || Rajout || (!ArretAjout && Cadre && SaveN <= 0))
-                {
-                  if (aStatus == IntWalk_ArretSurPointPrecedent) {
-                    CurrentLine->AddPoint(Psol);
-                    OpenLine(0,Psol,Pnts1,Func,CurrentLine);
-                  }
-                  else {
-                    OpenLine(-lines.Length()-1,Psol,Pnts1,Func,CurrentLine);
-                  }
-                }
-                //Remove <SaveN> from <seqAlone> and, if it is first found point,
-                //from <seqAjout> too
-                if (IsValidEndPoint(I, SaveN))
-                {
-                  for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++)
-                    if (seqAlone(iseq) == SaveN)
-                    {
-                      seqAlone.Remove(iseq);
-                      break;
-                    }
-                  if (CurrentLine->NbPoints() <= 2)
-                    for (Standard_Integer iseq = 1; iseq <= seqAjout.Length(); iseq++)
-                      if (seqAjout(iseq) == SaveN)
-                      {
-                        seqAjout.Remove(iseq);
-                        break;
-                      }
-                }
-                else
-                {
-                  RemoveTwoEndPoints(I);
-                  break; //cancel the line
-                }
-                
-                if (Cadre && N==0) {
-                  Rajout = Standard_True;
-                  seqAjout.Append(-lines.Length()-1);
-                }
-              }
-            }
-            else if (aStatus == IntWalk_ArretSurPointPrecedent) {
-              if (CurrentLine->NbPoints() == 1) { //cancel the line
-                Arrive = Standard_False;
-                RemoveTwoEndPoints(I);
-                break;
-              }
-              if (wd2[I].etat >12) { //the line should become open
-                wd2[I].etat = 12; //declare it open
-                ArretAjout = Standard_False;
-                OpenLine(0,Psol,Pnts1,Func,CurrentLine);
-                StepSign = -1;
-                StatusPrecedent = IntWalk_OK;
-                Arrive = Standard_False;
-                PasC = PasSav;
-                Rajout = Standard_True;
-                seqAlone.Append(-lines.Length()-1);
-                seqAjout.Append(-lines.Length()-1);
-              }
-              else { // line s is open                 
-                Arrive =Standard_True;
-                CurrentLine->AddStatusLast(Standard_False);
-                Rajout = Standard_True;
-                seqAlone.Append(lines.Length()+1);
-                seqAjout.Append(lines.Length()+1);
-              } 
-            }
-            else if (Arrive)  {
-              if (wd2[I].etat > 12) {  //line closed good case
-                CurrentLine->AddStatusFirstLast(Standard_True,
-                  Standard_False,Standard_False);
-                CurrentLine->AddPoint(CurrentLine->Value(1));
-              }
-              else if ((N >0) && (Pnts1.Length() >= N))
-              {
-                //point of stop given at input 
-                PathPnt = Pnts1.Value(N);
-                CurrentLine->AddStatusLast(Standard_True,N,PathPnt);
-                AddPointInCurrentLine(N,PathPnt,CurrentLine);
-              }
-            }
-            else if (aStatus == IntWalk_ArretSurPoint) {
-              if (wd2[I].etat >12) { //line should become open
-                wd2[I].etat = 12; //declare it open
-                Tgtbeg = Standard_True;
-                Tgtend = Standard_False;
-                N= -lines.Length()-1;
-                Psol.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
-                OpenLine(N,Psol,Pnts1,Func,CurrentLine);
-                StepSign = -1;
-                Rajout = Standard_True;
-                seqAlone.Append(N);
-                seqAjout.Append(N);
-                StatusPrecedent = IntWalk_OK;
-                Arrive = Standard_False;
-                PasC = PasSav; 
-              }
-              else { 
-                Arrive = Standard_True;                   
-                if (Ipass!=0) { //point of passage, point of stop
-                  PathPnt = Pnts1.Value(Ipass);
-                  CurrentLine->AddStatusLast(Standard_True,Ipass,PathPnt);
-                  AddPointInCurrentLine(Ipass,PathPnt,CurrentLine);
-                }
-                else {
-                  CurrentLine->AddStatusLast(Standard_False);
-                  IntSurf_PntOn2S newP;
-                  newP.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
-                  CurrentLine->AddPoint(newP);
-                  Rajout = Standard_True;
-                  seqAlone.Append(lines.Length()+1);
-                  seqAjout.Append(lines.Length()+1);
-                }
-              }
-            }
-            else if (aStatus == IntWalk_OK) {
-              if (Ipass!=0) CurrentLine->AddIndexPassing(Ipass);
-              previousPoint.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
-              previousd3d = Func.Direction3d();
-              previousd2d = Func.Direction2d();
-              CurrentLine->AddPoint(previousPoint);
-            }
-            else if (aStatus == IntWalk_PointConfondu)
-            {
-              aNbIter --;
-            }
-          }
-        }
-        else { //no numerical solution NotDone
-          PasC = PasC/2.;
-          PasCu = Abs(PasC*previousd2d.X());
-          PasCv = Abs(PasC*previousd2d.Y());
-
-          if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
-            if (CurrentLine->NbPoints() == 1)
-            {
-              RemoveTwoEndPoints(I);
-              break; // cancel the line
-            }
-            if (wd2[I].etat >12) { //the line should become open
-              wd2[I].etat = 12; //declare it open
-              ArretAjout = Standard_False;
-              OpenLine(0,Psol,Pnts1,Func,CurrentLine);
-              StepSign = -1;
-              StatusPrecedent = IntWalk_OK;
-              Arrive = Standard_False;
-              PasC = PasSav;
-              Rajout = Standard_True;
-              seqAlone.Append(-lines.Length()-1);
-              seqAjout.Append(-lines.Length()-1);
-            }
-            else { // line s is open                 
-              Arrive =Standard_True;
-              CurrentLine->AddStatusLast(Standard_False);
-              Tgtend = Standard_True;
-              Rajout = Standard_True;
-              seqAlone.Append(lines.Length()+1);
-              seqAjout.Append(lines.Length()+1);
-            } 
-            /*
-            Arrive = Standard_True;
-            CurrentLine->AddStatusFirstLast(Standard_False,Standard_False,
-              Standard_False);
-            Tgtend = Standard_True;
-            Rajout = Standard_True;
-            seqAlone.Append(lines.Length()+1);
-            seqAjout.Append(lines.Length()+1);
-            */
-          }  
-        }
-
-        if(aNbIter < 0)
-          break;
-      }// end of started line 
-      if (Arrive) {
-        CurrentLine->SetTangencyAtBegining(Tgtbeg);
-        CurrentLine->SetTangencyAtEnd(Tgtend);
-
-        lines.Append(CurrentLine);
-        wd2[I].etat=-wd2[I].etat; //mark point as processed
-      }
-    } //end of processing of start point
-  } //end of all start points
-}
diff --git a/src/IntWalk/IntWalk_IWalking_5.gxx b/src/IntWalk/IntWalk_IWalking_5.gxx
deleted file mode 100644 (file)
index 2d5cf5e..0000000
+++ /dev/null
@@ -1,310 +0,0 @@
-// Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-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.
-
-namespace {
-  static const Standard_Real CosRef3D = 0.98;// rule by tests in U4 
-                                             // correspond to  11.478 d
-  static const Standard_Real CosRef2D = 0.88; // correspond to 25 d
-  static const Standard_Integer MaxDivision = 60;  // max number of step division 
-                                                   // because the angle is too great in 2d (U4)
-}
-
-IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection
-  (TheIWFunction& sp,
-   const Standard_Boolean Finished,
-   const math_Vector& UV,
-   const IntWalk_StatusDeflection StatusPrecedent,
-   Standard_Integer& NbDivision,
-   Standard_Real& Step,
-   const Standard_Integer StepSign)
-{
-  // Check the step of advancement, AND recalculate this step :
-  //
-  // 1) test point confused
-  //     if yes other tests are not done
-  // 2) test angle 3d too great
-  //     if yes divide the step and leave
-  //     angle3d = angle ((previous point, calculated point),
-  //                       previous tangent)
-  // 3) check step of advancement in 2d
-  // 4) test point confused
-  // 5) test angle 2d too great
-  // 6) test point of tangency 
-  //     if yes leave
-  // 7) calculate the tangent by u,v of the section 
-  // 8) test angle 3d too great  
-  //     angle3d = angle ((previous point, calculated point),  
-  //                       new tangent)
-  // 9) test angle 2d too great
-  //10) test change of side (pass the tangent point not knowing it)
-  //11) calculate the step of advancement depending on the vector
-  //12) adjust the step depending on the previous steps 
-  
-  IntWalk_StatusDeflection aStatus = IntWalk_OK;
-
-  //---------------------------------------------------------------------------------
-  //-- lbr le 4 Avril 95 : it is possible that the status returns points confused
-  //-- if epsilon is great enough (1e-11). In this case one loops 
-  //-- without ever changing the values sent to Rsnld. 
-  //---------------------------------------------------------------------------------
-  Standard_Real Paramu = 0.0, Paramv = 0.0;
-
-  if (!reversed) {
-    previousPoint.ParametersOnS2(Paramu, Paramv);
-  }
-  else
-  {
-    previousPoint.ParametersOnS1(Paramu, Paramv);
-  }
-
-  const Standard_Real Du = UV(1) - Paramu;
-  const Standard_Real Dv = UV(2) - Paramv;
-  const Standard_Real Duv = Du * Du + Dv * Dv;
-
-  gp_Vec Corde(previousPoint.Value(), sp.Point());
-
-  const Standard_Real Norme = Corde.SquareMagnitude();
-
-  if ((Norme <= 4.0*Precision::SquareConfusion()) && 
-      ((Duv <= Precision::SquarePConfusion()) || (StatusPrecedent != IntWalk_OK)))
-  { // the square is already taken in the constructor
-    aStatus = IntWalk_PointConfondu;
-    if (StatusPrecedent == IntWalk_PasTropGrand)
-    {
-      return IntWalk_ArretSurPointPrecedent;
-    }
-  }
-  else
-  {
-    Standard_Real Cosi = Corde * previousd3d;
-    Standard_Real Cosi2 = 0.0;
-
-    if (Cosi*StepSign >= 0.) {// angle 3d <= pi/2 !!!!
-      const Standard_Real aDiv = previousd3d.SquareMagnitude()*Norme;
-      if(aDiv == 0)
-        return aStatus;
-      Cosi2 = Cosi * Cosi / aDiv;
-    }
-    if (Cosi2 < CosRef3D) { //angle 3d too great
-      Step = Step /2.0;
-      Standard_Real StepU = Abs(Step*previousd2d.X()),
-                    StepV = Abs(Step*previousd2d.Y());
-      if (StepU < tolerance(1) && StepV < tolerance(2)) 
-        aStatus = IntWalk_ArretSurPointPrecedent;
-      else 
-        aStatus = IntWalk_PasTropGrand;
-      return aStatus;
-    }
-  }
-
-  const Standard_Real aMinTolU = 0.1*Abs(Step*previousd2d.X()),
-                      aMinTolV = 0.1*Abs(Step*previousd2d.Y());
-  const Standard_Real aTolU = (aMinTolU > 0.0) ? Min(tolerance(1), aMinTolU) : tolerance(1),
-                      aTolV = (aMinTolV > 0.0) ? Min(tolerance(2), aMinTolV) : tolerance(2);
-
-  //If aMinTolU==0.0 then (Abs(Du) < aMinTolU) is equivalent of (Abs(Du) < 0.0).
-  //It is impossible. Therefore, this case should be processed separately.
-  //Analogically for aMinTolV.
-
-  if ((Abs(Du) < aTolU) && (Abs(Dv) < aTolV))
-  {
-    //Thin shapes (for which Ulast-Ufirst or/and Vlast-Vfirst is quite small)
-    //exists (see bug #25820). In this case, step is quite small too.
-    //Nevertheless, it not always means that we mark time. Therefore, Du and Dv
-    //must consider step (aMinTolU and aMinTolV parameters).
-
-    return IntWalk_ArretSurPointPrecedent; //confused point 2d
-  }
-
-  Standard_Real Cosi = StepSign * (Du * previousd2d.X() + Dv * previousd2d.Y());
-
-  if (Cosi < 0 && aStatus == IntWalk_PointConfondu)
-    return IntWalk_ArretSurPointPrecedent; // leave as step back  
-                                           // with confused point
-
-  if (sp.IsTangent()) 
-    return IntWalk_ArretSurPoint;       
-
-//if during routing one has subdivided more than  MaxDivision for each
-//previous step, bug on the square; do nothing (experience U4)
-
-  if ((NbDivision < MaxDivision) && (aStatus != IntWalk_PointConfondu) &&
-    (StatusPrecedent!= IntWalk_PointConfondu))
-  {
-    Standard_Real Cosi2 = Cosi * Cosi / Duv;
-    if (Cosi2 < CosRef2D || Cosi < 0  ) {
-      Step = Step / 2.0;
-      Standard_Real StepU = Abs(Step*previousd2d.X()),
-                    StepV = Abs(Step*previousd2d.Y());
-
-      if (StepU < tolerance(1) && StepV < tolerance(2))
-        aStatus = IntWalk_ArretSurPointPrecedent;
-      else 
-        aStatus = IntWalk_PasTropGrand;
-      NbDivision = NbDivision + 1;
-      return aStatus;
-    }
-
-    Cosi = Corde * sp.Direction3d(); 
-    Cosi2 = Cosi * Cosi / sp.Direction3d().SquareMagnitude() / Norme;
-    if (Cosi2 < CosRef3D ){ //angle 3d too great
-      Step = Step / 2.;
-      Standard_Real StepU = Abs(Step*previousd2d.X()),
-                    StepV = Abs(Step*previousd2d.Y());
-      if (StepU < tolerance(1) && StepV < tolerance(2))
-        aStatus = IntWalk_ArretSurPoint;
-      else 
-        aStatus = IntWalk_PasTropGrand;
-      return aStatus;
-    }
-    Cosi = Du * sp.Direction2d().X() + 
-      Dv * sp.Direction2d().Y();
-    Cosi2 = Cosi * Cosi / Duv;
-    if (Cosi2 < CosRef2D || 
-      sp.Direction2d() * previousd2d < 0) {
-        //angle 2d too great or change the side       
-        Step  = Step / 2.;
-        Standard_Real StepU = Abs(Step*previousd2d.X()),
-                      StepV = Abs(Step*previousd2d.Y());
-        if (StepU < tolerance(1) && StepV < tolerance(2))
-          aStatus = IntWalk_ArretSurPointPrecedent;
-        else 
-          aStatus = IntWalk_PasTropGrand;
-        return aStatus;
-    }
-  }
-
-  if (!Finished) {
-    if (aStatus == IntWalk_PointConfondu)
-    {
-      Standard_Real StepU = Min(Abs(1.5 * Du),pas*(UM-Um)),
-                    StepV = Min(Abs(1.5 * Dv),pas*(VM-Vm));
-
-      Standard_Real d2dx = Abs(previousd2d.X()); 
-      Standard_Real d2dy = Abs(previousd2d.Y()); 
-
-      if (d2dx < tolerance(1))
-      {
-        Step = StepV/d2dy;
-      }
-      else if (d2dy < tolerance(2))
-      {
-        Step = StepU/d2dx;
-      }
-      else
-      {
-        Step = Min(StepU/d2dx,StepV/d2dy);
-      }
-    }
-    else
-    {
-      //   estimate the current vector.
-      //   if vector/2<=current vector<= vector it is considered that the criterion
-      //   is observed.
-      //   otherwise adjust the step depending on the previous step 
-
-      /*
-        Standard_Real Dist = Sqrt(Norme)/3.;
-        TColgp_Array1OfPnt Poles(1,4);
-        gp_Pnt POnCurv,Milieu;
-        Poles(1) = previousPoint.Value();
-        Poles(4) = sp.Point();
-        Poles(2) = Poles(1).XYZ() + 
-      StepSign * Dist* previousd3d.Normalized().XYZ();
-        Poles(3) = Poles(4).XYZ() - 
-      StepSign * Dist*sp.Direction3d().Normalized().XYZ();
-        BzCLib::PntPole(0.5,Poles,POnCurv);
-        Milieu = (Poles(1).XYZ() + Poles(4).XYZ())*0.5;
-      //      FlecheCourante = Milieu.Distance(POnCurv);
-        Standard_Real FlecheCourante = Milieu.SquareDistance(POnCurv);
-      */
-
-        // Direct calculation : 
-        // POnCurv=(((p1+p2)/2.+(p2+p3)/2.)/2. + ((p2+p3)/2.+(p3+P4)/2.)/2.)/2.
-        // either POnCurv = p1/8. + 3.p2/8. + 3.p3/8. + p4/8.
-        // Or p2 = p1 + lambda*d1 et p3 = p4 - lambda*d4
-        // So POnCurv = (p1 + p4)/2. + 3.*(lambda d1 - lambda d4)/8.
-        // Calculate the deviation with (p1+p4)/2. . So it is just necessary to calculate
-        // the norm (square) of 3.*lambda (d1 - d4)/8.
-        // either the norm of :
-        //    3.*(Sqrt(Norme)/3.)*StepSign*(d1-d4)/8.
-        // which produces, taking the square :
-        //         Norme * (d1-d4).SquareMagnitude()/64.
-
-      Standard_Real FlecheCourante = 
-       (previousd3d.Normalized().XYZ()-sp.Direction3d().Normalized().XYZ()).SquareModulus()*Norme/64.;
-
-  
-//      if (FlecheCourante <= 0.5*fleche) {
-      if (FlecheCourante <= 0.25*fleche*fleche)
-      {
-        Standard_Real d2dx = Abs(sp.Direction2d().X()); 
-        Standard_Real d2dy = Abs(sp.Direction2d().Y()); 
-        
-        Standard_Real StepU = Min(Abs(1.5*Du),pas*(UM-Um)),
-                      StepV = Min(Abs(1.5*Dv),pas*(VM-Vm));
-
-        if (d2dx < tolerance(1))
-        {
-          Step = StepV/d2dy;
-        }
-        else if (d2dy < tolerance(2))
-        {
-          Step = StepU/d2dx;
-        }
-        else
-        {
-          Step = Min(StepU/d2dx,StepV/d2dy);
-        }      
-      }
-      else
-      {
-        //if (FlecheCourante > fleche) {  // step too great
-        if (FlecheCourante > fleche*fleche)
-        {  // step too great
-          Step = Step /2.;
-          Standard_Real StepU = Abs(Step*previousd2d.X()),
-                        StepV = Abs(Step*previousd2d.Y());
-          
-          if (StepU < tolerance(1) && StepV < tolerance(2)) 
-            aStatus = IntWalk_ArretSurPointPrecedent;
-          else 
-            aStatus = IntWalk_PasTropGrand;
-        }
-        else
-        {
-          Standard_Real d2dx = Abs(sp.Direction2d().X()); 
-          Standard_Real d2dy = Abs(sp.Direction2d().Y()); 
-          
-          Standard_Real StepU = Min(Abs(1.5*Du),pas*(UM-Um)),
-                        StepV = Min(Abs(1.5*Dv),pas*(VM-Vm));
-
-          if (d2dx < tolerance(1))
-          {
-            Step = Min(Step,StepV/d2dy);
-          }
-          else if (d2dy < tolerance(2))
-          {
-            Step = Min(Step,StepU/d2dx);
-          }
-          else
-          {
-            Step = Min(Step,Min(StepU/d2dx,StepV/d2dy));
-          }
-        }
-      }
-    }
-  }
-  return aStatus;
-}
diff --git a/src/IntWalk/IntWalk_IWalking_6.gxx b/src/IntWalk/IntWalk_IWalking_6.gxx
deleted file mode 100644 (file)
index 4fa8f92..0000000
+++ /dev/null
@@ -1,272 +0,0 @@
-// Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-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.
-
-#ifndef OCCT_DEBUG
-#define No_Standard_RangeError
-#define No_Standard_OutOfRange
-#endif
-
-
-void IntWalk_IWalking::AddPointInCurrentLine
-         (const Standard_Integer N,
-         const ThePointOfPath& PathPnt,
-         const Handle(IntWalk_TheIWLine)& CurrentLine) const {
-
-
-  IntSurf_PntOn2S Psol;
-  Psol.SetValue(ThePointOfPathTool::Value3d(PathPnt),
-               reversed,wd1[N].ustart,wd1[N].vstart);
-  CurrentLine->AddPoint(Psol);
-}
-
-
-void IntWalk_IWalking::MakeWalkingPoint
-         (const Standard_Integer Case, 
-         const Standard_Real U, 
-         const Standard_Real V,
-         TheIWFunction& sp,
-         IntSurf_PntOn2S& Psol )
-
-{
-
-// Case == 1      : make a WalkinkPoint.
-// Case == 2      : make a WalkinkPoint.
-//                  The computation of the tangency on is done  
-// Case == 10 + i : make a WalkinkPoint according to i.
-//                  but F is updated according to U and V
-// Case == other  : the exception Standard_Failure is raised.
-
-  if ((Case == 1) || (Case == 2))
-  {
-    Psol.SetValue(sp.Point(), reversed, U, V);
-  }
-  else if (Case == 11 || Case == 12)
-  {
-    Standard_Real aUV[2] = {}, aFF[1] = {}, aDD[1][2] = {};
-    math_Vector UV(aUV, 1, 2);
-    math_Vector FF(aFF, 1, 1);
-    math_Matrix DD(aDD, 1, 1, 1, 2);
-    UV(1) = U;
-    UV(2) = V;
-    sp.Values(UV, FF, DD);
-    MakeWalkingPoint(Case - 10, U, V, sp, Psol);
-  }
-  else
-  {
-    throw Standard_ConstructionError();
-  }
-}
-
-
-
-void IntWalk_IWalking::OpenLine(const Standard_Integer N,
-                                const IntSurf_PntOn2S& Psol,
-                               const ThePOPIterator& Pnts1,
-                               TheIWFunction& sp,
-                                const Handle(IntWalk_TheIWLine)& Line )
-// **************** open the line and restart in the other direction********
-
-{
-  ThePointOfPath PathPnt;
-
-  Standard_Real aUV[2], aFF[1], aDD[1][2];
-  math_Vector UV(aUV,1, 2);
-  math_Vector FF(aFF,1, 1);
-  math_Matrix DD(aDD,1, 1, 1, 2); 
-
-  previousPoint = Line->Value(1);  
-  if (!reversed) {
-    previousPoint.ParametersOnS2(UV(1),UV(2));
-  }
-  else {
-    previousPoint.ParametersOnS1(UV(1),UV(2));
-  }
-  sp.Values(UV, FF, DD);
-  previousd3d = sp.Direction3d();
-  previousd2d = sp.Direction2d();
-
-  if (N>0) { //departure point given at input
-    PathPnt = Pnts1.Value(N);
-    //mark the line as open with a given stop point
-    Line->AddStatusFirst(Standard_False,Standard_True,N,PathPnt); 
-
-
-    AddPointInCurrentLine(N,PathPnt,Line);
-
-  }
-  else  {
-    if (N <0) Line->AddPoint(Psol);                      
-    Line->AddStatusFirst(Standard_False,Standard_False);
-       //mark the line as open without given stop point 
-  }
-  Line->Reverse();  //inverser la ligne        
-  Line->SetTangentVector(previousd3d.Reversed(),Line->NbPoints());
-}
-
-Standard_Boolean IntWalk_IWalking::IsValidEndPoint(const Standard_Integer IndOfPoint,
-                                                   const Standard_Integer IndOfLine)
-{
-  if (PointLineLine.IsEmpty())
-    return Standard_True;
-  
-  TColStd_ListIteratorOfListOfInteger itl(PointLineLine(IndOfPoint));
-  for (; itl.More(); itl.Next())
-    if (itl.Value() == IndOfLine)
-    {
-      PointLineLine(IndOfPoint).Remove(itl);
-      return Standard_True;
-    }
-  return Standard_False;
-}
-
-void IntWalk_IWalking::RemoveTwoEndPoints(const Standard_Integer IndOfPoint)
-{
-  if (PointLineLine.IsBound(IndOfPoint))
-  {
-    Standard_Integer Line1 = PointLineLine(IndOfPoint).First();
-    Standard_Integer Line2 = PointLineLine(IndOfPoint).Last();
-    for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++)
-    {
-      if (seqAlone(iseq) == Line1 ||
-          seqAlone(iseq) == Line2)
-        seqAlone.Remove(iseq--);
-    }
-  }
-}
-
-Standard_Boolean IntWalk_IWalking::IsPointOnLine(const gp_Pnt2d& theP2d,
-                                                 const Standard_Integer Irang)
-{
-  const Handle(IntWalk_TheIWLine)& aLine = lines.Value(Abs(Irang));
-  for (Standard_Integer i = 1; i <= aLine->NbPoints(); i++)
-  {
-    gp_Pnt2d P2d1 = aLine->Value(i).ValueOnSurface(reversed);
-    if (Abs(P2d1.X() - theP2d.X()) <= tolerance(1) &&
-        Abs(P2d1.Y() - theP2d.Y()) <= tolerance(2))
-      return Standard_True;
-    if (i < aLine->NbPoints())
-    {
-      gp_Pnt2d P2d2 = aLine->Value(i+1).ValueOnSurface(reversed);
-      gp_Vec2d PP1(theP2d, P2d1);
-      gp_Vec2d PP2(theP2d, P2d2);
-      if (PP1 * PP2 < 0)
-        return Standard_True;
-    }
-  }
-  return Standard_False;
-}
-
-//==================================================================================
-//function : IsPointOnLine
-//purpose  : Projects thePOn2S on the nearest segment of the already computed line.
-//           The retrieved projection point (aPa) is refined using theSolver.
-//            After the refinement, we will obtain a point aPb.
-//            If thePOn2S is quite far from aPb then thePOn2S is not
-//            in the line.
-//           Every already computed line is checked.
-//==================================================================================
-Standard_Boolean IntWalk_IWalking::IsPointOnLine(const IntSurf_PntOn2S& thePOn2S,
-                                                 const math_Vector& theInfBounds,
-                                                 const math_Vector& theSupBounds,
-                                                 math_FunctionSetRoot& theSolver,
-                                                 TheIWFunction& theFunc)
-{
-  const Standard_Real eps = Epsilon(1.);
-  const gp_Pnt &aP3d = thePOn2S.Value();
-
-  for (Standard_Integer aLIdx = 1; aLIdx <= lines.Length(); aLIdx++)
-  {
-    const Handle(IntSurf_LineOn2S) &aL = lines(aLIdx)->Line();
-
-    if (aL->IsOutBox(aP3d))
-      continue;
-
-    //Look for the nearest segment
-    Standard_Real aUMin = 0.0, aVMin = 0.0;
-    Standard_Real aMinSqDist = RealLast();
-    for (Standard_Integer aPtIdx = 1; aPtIdx < aL->NbPoints(); aPtIdx++)
-    {
-      const gp_Pnt &aP1 = aL->Value(aPtIdx).Value();
-      const gp_Pnt &aP2 = aL->Value(aPtIdx + 1).Value();
-
-      const gp_XYZ aP1P(aP3d.XYZ() - aP1.XYZ());
-      const gp_XYZ aP1P2(aP2.XYZ() - aP1.XYZ());
-
-      const Standard_Real aSq12 = aP1P2.SquareModulus();
-
-      if (aSq12 < gp::Resolution())
-        continue;
-
-      const Standard_Real aDP = aP1P.Dot(aP1P2);
-
-      Standard_Real aSqD = RealLast();
-      if (aDP < 0.0)
-      {
-        continue;
-      }
-      else if (aDP > aSq12)
-      {
-        continue;
-      }
-      else
-      {
-        aSqD = aP1P.CrossSquareMagnitude(aP1P2) / aSq12;
-      }
-
-      if (aSqD < aMinSqDist)
-      {
-        aMinSqDist = aSqD;
-
-        const Standard_Real aL1 = aDP / aSq12;
-        const Standard_Real aL2 = 1.0 - aL1;
-
-        if (aL1 < eps || aL2 < eps)
-        {
-          return Standard_True;
-        }
-
-        Standard_Real aU1, aV1, aU2, aV2;
-        aL->Value(aPtIdx).ParametersOnSurface(reversed, aU1, aV1);
-        aL->Value(aPtIdx + 1).ParametersOnSurface(reversed, aU2, aV2);
-
-        aUMin = aL1*aU2 + aL2*aU1;
-        aVMin = aL1*aV2 + aL2*aV1;
-      }
-    }
-
-    if (aMinSqDist > Precision::Infinite())
-      continue;
-
-    math_Vector aVecPrms(1, 2);
-    aVecPrms(1) = aUMin;
-    aVecPrms(2) = aVMin;
-    theSolver.Perform(theFunc, aVecPrms, theInfBounds, theSupBounds);
-    if (!theSolver.IsDone())
-      continue;
-
-    theSolver.Root(aVecPrms);
-
-    const gp_Pnt aPa(theFunc.PSurface()->Value(aUMin, aVMin)),
-                 aPb(theFunc.PSurface()->Value(aVecPrms(1), aVecPrms(2)));
-    const Standard_Real aSqD1 = aPb.SquareDistance(aP3d);
-    const Standard_Real aSqD2 = aPa.SquareDistance(aPb);
-    if (aSqD1 < 4.0*aSqD2)
-    {
-      return Standard_True;
-    }
-  }
-
-  return Standard_False;
-}