0030100: Modeling Algorithms - ShapeUpgrade_UnifySameDomain is unable to unify faces...
[occt.git] / src / IntPatch / IntPatch_Intersection.cxx
index 4756b16..f749781 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <IntPatch_Intersection.ixx>
+#include <stdio.h>
+#include <IntPatch_Intersection.hxx>
 
+#include <Adaptor3d_HSurface.hxx>
+#include <Adaptor3d_TopolTool.hxx>
+#include <IntPatch_ALine.hxx>
 #include <IntPatch_ALineToWLine.hxx>
 #include <IntPatch_GLine.hxx>
-#include <IntPatch_ALine.hxx>
-#include <IntPatch_WLine.hxx>
-#include <IntPatch_RLine.hxx>
-#include <IntPatch_PrmPrmIntersection.hxx>
-#include <IntPatch_ImpPrmIntersection.hxx>
 #include <IntPatch_ImpImpIntersection.hxx>
-#include <IntSurf_Quadric.hxx>
-
-#include <stdio.h>
+#include <IntPatch_ImpPrmIntersection.hxx>
+#include <IntPatch_PrmPrmIntersection.hxx>
+#include <IntPatch_WLine.hxx>
+#include <IntPatch_WLineTool.hxx>
 
-#define DEBUG 0 
-static const Standard_Integer aNbPointsInALine = 200;
+#include <ProjLib_ProjectOnPlane.hxx>
+#include <Geom_Plane.hxx>
+#include <GeomAdaptor_HSurface.hxx>
+#include <GeomAdaptor_HCurve.hxx>
+#include <ProjLib_ProjectedCurve.hxx>
+#include <Geom2dInt_GInter.hxx>
+#include <Geom2dAdaptor_Curve.hxx>
+#include <ProjLib.hxx>
 
 //======================================================================
 // function: SequenceOfLine
@@ -132,23 +138,47 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
 
   switch (S1->GetType())
   { 
-    case GeomAbs_Plane:
-    case GeomAbs_Cylinder:
-    case GeomAbs_Sphere:
-    case GeomAbs_Cone:
-    case GeomAbs_Torus: break;
-    default:
+  case GeomAbs_Plane:
+  case GeomAbs_Cylinder:
+  case GeomAbs_Sphere:
+  case GeomAbs_Cone:
+  case GeomAbs_Torus:
+    break;
+  case GeomAbs_SurfaceOfExtrusion:
     {
-         IntPatch_PrmPrmIntersection interpp;
-         interpp.Perform(S1,D1,TolArc,TolTang,myFleche,myUVMaxStep);
-         if (interpp.IsDone())
-         {
-           done = Standard_True;
-           tgte = Standard_False;
-           empt = interpp.IsEmpty();
-           const Standard_Integer nblm = interpp.NbLines();
-           for (Standard_Integer i=1; i<=nblm; i++) slin.Append(interpp.Line(i));
-         }
+      gp_Dir aDirection = S1->Direction();
+      gp_Ax3 anAxis(gp::Origin(), aDirection);
+      Handle(Adaptor3d_HCurve) aBasisCurve = S1->BasisCurve();
+      ProjLib_ProjectOnPlane Projector(anAxis);
+      Projector.Load(aBasisCurve, Precision::Confusion());
+      Handle(GeomAdaptor_HCurve) aProjCurve = Projector.GetResult();
+      Handle(Geom_Plane) aPlane = new Geom_Plane(anAxis);
+      Handle(GeomAdaptor_HSurface) aGAHsurf = new GeomAdaptor_HSurface(aPlane);
+      ProjLib_ProjectedCurve aProjectedCurve(aGAHsurf, aProjCurve);
+      Handle(Geom2d_Curve) aPCurve;
+      ProjLib::MakePCurveOfType(aProjectedCurve, aPCurve);
+      Geom2dAdaptor_Curve AC(aPCurve,
+                             aProjectedCurve.FirstParameter(),
+                             aProjectedCurve.LastParameter());
+      Geom2dInt_GInter Intersector(AC,
+                                   Precision::Confusion(),
+                                   Precision::Confusion());
+      if (Intersector.IsDone() && Intersector.IsEmpty())
+        break;
+    }
+    Standard_FALLTHROUGH
+  default:
+    {
+      IntPatch_PrmPrmIntersection interpp;
+      interpp.Perform(S1,D1,TolTang,TolArc,myFleche,myUVMaxStep);
+      if (interpp.IsDone())
+      {
+        done = Standard_True;
+        tgte = Standard_False;
+        empt = interpp.IsEmpty();
+        const Standard_Integer nblm = interpp.NbLines();
+        for (Standard_Integer i=1; i<=nblm; i++) slin.Append(interpp.Line(i));
+      }
     }
     break;
   }
@@ -174,7 +204,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
 #include <GeomAdaptor_HCurve.hxx>
 #include <GeomAdaptor_Curve.hxx>
 #include <GeomAdaptor_Surface.hxx>
-#include <Handle_GeomAdaptor_HSurface.hxx>
+#include <GeomAdaptor_HSurface.hxx>
 #include <Geom_Plane.hxx>
 #include <ProjLib_ProjectOnPlane.hxx>
 #include <GeomProjLib.hxx>
@@ -200,12 +230,12 @@ static void FUN_GetMinMaxXYZPnt( const Handle(Adaptor3d_HSurface)& S,
   for(Standard_Real U = S->FirstUParameter(); U <= S->LastUParameter(); U += DU)
   {
     for(Standard_Real V = S->FirstVParameter(); V <= S->LastVParameter(); V += DV)
-       {
-         S->D0(U,V,PUV);
+    {
+      S->D0(U,V,PUV);
       const Standard_Real cXYZ = PUV.XYZ().Modulus();
-         if(cXYZ > tMaxXYZ) { tMaxXYZ = cXYZ; ptMax = PUV; }
-         if(cXYZ < tMinXYZ) { tMinXYZ = cXYZ; ptMin = PUV; }
-       }
+      if(cXYZ > tMaxXYZ) { tMaxXYZ = cXYZ; ptMax = PUV; }
+      if(cXYZ < tMinXYZ) { tMinXYZ = cXYZ; ptMin = PUV; }
+    }
   }
   pMin = ptMin;
   pMax = ptMax;
@@ -226,19 +256,19 @@ static void FUN_TrimInfSurf(const gp_Pnt& Pmin,
   {
     Standard_Real Umax = -1.e+100, Umin = 1.e+100, Vmax = -1.e+100, Vmin = 1.e+100, cU, cV;
     if(ext1.IsDone())
-       {
+    {
       for(Standard_Integer i = 1; i <= ext1.NbExt(); i++)
       {
-           const Extrema_POnSurf & pons = ext1.Point(i);
-           pons.Parameter(cU,cV);
-           if(cU > Umax) Umax = cU;
-           if(cU < Umin) Umin = cU;
-           if(cV > Vmax) Vmax = cV;
-           if(cV < Vmin) Vmin = cV;
+        const Extrema_POnSurf & pons = ext1.Point(i);
+        pons.Parameter(cU,cV);
+        if(cU > Umax) Umax = cU;
+        if(cU < Umin) Umin = cU;
+        if(cV > Vmax) Vmax = cV;
+        if(cV < Vmin) Vmin = cV;
       }
-       }
+    }
     if(ext2.IsDone())
-       {
+    {
       for(Standard_Integer i = 1; i <= ext2.NbExt(); i++)
       {
         const Extrema_POnSurf & pons = ext2.Point(i);
@@ -248,7 +278,7 @@ static void FUN_TrimInfSurf(const gp_Pnt& Pmin,
         if(cV > Vmax) Vmax = cV;
         if(cV < Vmin) Vmin = cV;
       }
-       }
+    }
     TP = Max(Abs(Umin),Max(Abs(Umax),Max(Abs(Vmin),Abs(Vmax))));
   }
   if(TP == 0.) { TrimS = InfSurf; return; }
@@ -265,18 +295,18 @@ static void FUN_TrimInfSurf(const gp_Pnt& Pmin,
     if(Vinf && !Vsup){ TrimS = InfSurf->VTrim(-tp, InfSurf->LastVParameter(), 1.0e-7); IsTrimed = 1; }
     if(!Vinf && Vsup){ TrimS = InfSurf->VTrim(InfSurf->FirstVParameter(), tp, 1.0e-7); IsTrimed = 1; }
     if(IsTrimed)
-       {
-         TmpSS = TrimS;
-         if(Uinf && Usup)  TrimS = TmpSS->UTrim(-tp, tp, 1.0e-7);
-         if(Uinf && !Usup) TrimS = TmpSS->UTrim(-tp, InfSurf->LastUParameter(), 1.0e-7);
-         if(!Uinf && Usup) TrimS = TmpSS->UTrim(InfSurf->FirstUParameter(), tp, 1.0e-7);
-       }
+    {
+      TmpSS = TrimS;
+      if(Uinf && Usup)  TrimS = TmpSS->UTrim(-tp, tp, 1.0e-7);
+      if(Uinf && !Usup) TrimS = TmpSS->UTrim(-tp, InfSurf->LastUParameter(), 1.0e-7);
+      if(!Uinf && Usup) TrimS = TmpSS->UTrim(InfSurf->FirstUParameter(), tp, 1.0e-7);
+    }
     else
-       {
-         if(Uinf && Usup)  TrimS = InfSurf->UTrim(-tp, tp, 1.0e-7);
-         if(Uinf && !Usup) TrimS = InfSurf->UTrim(-tp, InfSurf->LastUParameter(), 1.0e-7);
-         if(!Uinf && Usup) TrimS = InfSurf->UTrim(InfSurf->FirstUParameter(), tp, 1.0e-7);
-       }
+    {
+      if(Uinf && Usup)  TrimS = InfSurf->UTrim(-tp, tp, 1.0e-7);
+      if(Uinf && !Usup) TrimS = InfSurf->UTrim(-tp, InfSurf->LastUParameter(), 1.0e-7);
+      if(!Uinf && Usup) TrimS = InfSurf->UTrim(InfSurf->FirstUParameter(), tp, 1.0e-7);
+    }
   }
 }
 //================================================================================
@@ -296,57 +326,57 @@ static void FUN_GetUiso(const Handle(Geom_Surface)& GS,
     Handle(Geom_Curve) gc = GS->UIso(U);
     if(IsVP && (FirstV == 0.0 && LastV == (2.*M_PI))) I = gc;
     else
-       {
-         Handle(Geom_TrimmedCurve) gtc = new Geom_TrimmedCurve(gc,FirstV,LastV);
-         //szv:I = Handle(Geom_Curve)::DownCast(gtc);
-         I = gtc;
-       }
+    {
+      Handle(Geom_TrimmedCurve) gtc = new Geom_TrimmedCurve(gc,FirstV,LastV);
+      //szv:I = Handle(Geom_Curve)::DownCast(gtc);
+      I = gtc;
+    }
   }
   else//OffsetSurface
   {
-    const Handle(Geom_OffsetSurface) gos = *(Handle_Geom_OffsetSurface*)&GS;
+    const Handle(Geom_OffsetSurface) gos = Handle(Geom_OffsetSurface)::DownCast (GS);
     const Handle(Geom_Surface) bs = gos->BasisSurface();
     Handle(Geom_Curve) gcbs = bs->UIso(U);
     GeomAdaptor_Curve gac(gcbs);
     const GeomAbs_CurveType GACT = gac.GetType();
     if(IsVP || IsVC || GACT == GeomAbs_BSplineCurve || GACT == GeomAbs_BezierCurve || Abs(LastV - FirstV) < 1.e+5)
-       {
-         Handle(Geom_Curve) gc = gos->UIso(U);
-         if(IsVP && (FirstV == 0.0 && LastV == (2*M_PI))) I = gc;
-         else
+    {
+      Handle(Geom_Curve) gc = gos->UIso(U);
+      if(IsVP && (FirstV == 0.0 && LastV == (2*M_PI))) I = gc;
+      else
       {
-           Handle(Geom_TrimmedCurve) gtc = new Geom_TrimmedCurve(gc,FirstV,LastV);
-           //szv:I = Handle(Geom_Curve)::DownCast(gtc);
-           I = gtc;
-         }
-       }
+        Handle(Geom_TrimmedCurve) gtc = new Geom_TrimmedCurve(gc,FirstV,LastV);
+        //szv:I = Handle(Geom_Curve)::DownCast(gtc);
+        I = gtc;
+      }
+    }
     else//Offset Line, Parab, Hyperb
-       {
-         Standard_Real VmTr, VMTr;
-         if(GACT != GeomAbs_Hyperbola)
+    {
+      Standard_Real VmTr, VMTr;
+      if(GACT != GeomAbs_Hyperbola)
       {
-           if(FirstV >= 0. && LastV >= 0.){ VmTr = FirstV; VMTr = ((LastV - FirstV) > 1.e+4) ? (FirstV + 1.e+4) : LastV; }
-           else if(FirstV < 0. && LastV < 0.){ VMTr = LastV; VmTr = ((FirstV - LastV) < -1.e+4) ? (LastV - 1.e+4) : FirstV; }
-           else { VmTr = (FirstV < -1.e+4) ? -1.e+4 : FirstV; VMTr = (LastV > 1.e+4) ? 1.e+4 : LastV; }
-         }
-         else//Hyperbola
-         {
-           if(FirstV >= 0. && LastV >= 0.)
-               {
-                 if(FirstV > 4.) return;
-                 VmTr = FirstV; VMTr = (LastV > 4.) ? 4. : LastV;
-               }
-           else if(FirstV < 0. && LastV < 0.)
-               {
-                 if(LastV < -4.) return;
-                 VMTr = LastV; VmTr = (FirstV < -4.) ? -4. : FirstV;
-               }
-           else { VmTr = (FirstV < -4.) ? -4. : FirstV; VMTr = (LastV > 4.) ? 4. : LastV; }
-         }
-         //Make trimmed surface
-         Handle(Geom_RectangularTrimmedSurface) rts = new Geom_RectangularTrimmedSurface(gos,VmTr,VMTr,Standard_True);
-         I = rts->UIso(U);
-       }
+        if(FirstV >= 0. && LastV >= 0.){ VmTr = FirstV; VMTr = ((LastV - FirstV) > 1.e+4) ? (FirstV + 1.e+4) : LastV; }
+        else if(FirstV < 0. && LastV < 0.){ VMTr = LastV; VmTr = ((FirstV - LastV) < -1.e+4) ? (LastV - 1.e+4) : FirstV; }
+        else { VmTr = (FirstV < -1.e+4) ? -1.e+4 : FirstV; VMTr = (LastV > 1.e+4) ? 1.e+4 : LastV; }
+      }
+      else//Hyperbola
+      {
+        if(FirstV >= 0. && LastV >= 0.)
+        {
+          if(FirstV > 4.) return;
+          VmTr = FirstV; VMTr = (LastV > 4.) ? 4. : LastV;
+        }
+        else if(FirstV < 0. && LastV < 0.)
+        {
+          if(LastV < -4.) return;
+          VMTr = LastV; VmTr = (FirstV < -4.) ? -4. : FirstV;
+        }
+        else { VmTr = (FirstV < -4.) ? -4. : FirstV; VMTr = (LastV > 4.) ? 4. : LastV; }
+      }
+      //Make trimmed surface
+      Handle(Geom_RectangularTrimmedSurface) rts = new Geom_RectangularTrimmedSurface(gos,VmTr,VMTr,Standard_True);
+      I = rts->UIso(U);
+    }
   }
 }
 //================================================================================
@@ -366,57 +396,57 @@ static void FUN_GetViso(const Handle(Geom_Surface)& GS,
     Handle(Geom_Curve) gc = GS->VIso(V);
     if(IsUP && (FirstU == 0.0 && LastU == (2*M_PI))) I = gc;
     else
-       {
-         Handle(Geom_TrimmedCurve) gtc = new Geom_TrimmedCurve(gc,FirstU,LastU);
-         //szv:I = Handle(Geom_Curve)::DownCast(gtc);
-         I = gtc;
-       }
+    {
+      Handle(Geom_TrimmedCurve) gtc = new Geom_TrimmedCurve(gc,FirstU,LastU);
+      //szv:I = Handle(Geom_Curve)::DownCast(gtc);
+      I = gtc;
+    }
   }
   else//OffsetSurface
   {
-    const Handle(Geom_OffsetSurface) gos = *(Handle_Geom_OffsetSurface*)&GS;
+    const Handle(Geom_OffsetSurface) gos = Handle(Geom_OffsetSurface)::DownCast (GS);
     const Handle(Geom_Surface) bs = gos->BasisSurface();
     Handle(Geom_Curve) gcbs = bs->VIso(V);
     GeomAdaptor_Curve gac(gcbs);
     const GeomAbs_CurveType GACT = gac.GetType();
     if(IsUP || IsUC || GACT == GeomAbs_BSplineCurve || GACT == GeomAbs_BezierCurve || Abs(LastU - FirstU) < 1.e+5)
-       {
-         Handle(Geom_Curve) gc = gos->VIso(V);
-         if(IsUP && (FirstU == 0.0 && LastU == (2*M_PI))) I = gc;
-         else
-         {
-           Handle(Geom_TrimmedCurve) gtc = new Geom_TrimmedCurve(gc,FirstU,LastU);
-           //szv:I = Handle(Geom_Curve)::DownCast(gtc);
-           I = gtc;
-         }
-       }
+    {
+      Handle(Geom_Curve) gc = gos->VIso(V);
+      if(IsUP && (FirstU == 0.0 && LastU == (2*M_PI))) I = gc;
+      else
+      {
+        Handle(Geom_TrimmedCurve) gtc = new Geom_TrimmedCurve(gc,FirstU,LastU);
+        //szv:I = Handle(Geom_Curve)::DownCast(gtc);
+        I = gtc;
+      }
+    }
     else//Offset Line, Parab, Hyperb
-       {
-         Standard_Real UmTr, UMTr;
-         if(GACT != GeomAbs_Hyperbola)
-         {
-           if(FirstU >= 0. && LastU >= 0.){ UmTr = FirstU; UMTr = ((LastU - FirstU) > 1.e+4) ? (FirstU + 1.e+4) : LastU; }
-           else if(FirstU < 0. && LastU < 0.){ UMTr = LastU; UmTr = ((FirstU - LastU) < -1.e+4) ? (LastU - 1.e+4) : FirstU; }
-           else { UmTr = (FirstU < -1.e+4) ? -1.e+4 : FirstU; UMTr = (LastU > 1.e+4) ? 1.e+4 : LastU; }
-         }
-         else//Hyperbola
-         {
-           if(FirstU >= 0. && LastU >= 0.)
-               {
-                 if(FirstU > 4.) return;
-                 UmTr = FirstU; UMTr = (LastU > 4.) ? 4. : LastU;
-               }
-           else if(FirstU < 0. && LastU < 0.)
-               {
-                 if(LastU < -4.) return;
-                 UMTr = LastU; UmTr = (FirstU < -4.) ? -4. : FirstU;
-               }
-           else { UmTr = (FirstU < -4.) ? -4. : FirstU; UMTr = (LastU > 4.) ? 4. : LastU; }
-           }
-         //Make trimmed surface
-         Handle(Geom_RectangularTrimmedSurface) rts = new Geom_RectangularTrimmedSurface(gos,UmTr,UMTr,Standard_True);
-         I = rts->VIso(V);
-       }
+    {
+      Standard_Real UmTr, UMTr;
+      if(GACT != GeomAbs_Hyperbola)
+      {
+        if(FirstU >= 0. && LastU >= 0.){ UmTr = FirstU; UMTr = ((LastU - FirstU) > 1.e+4) ? (FirstU + 1.e+4) : LastU; }
+        else if(FirstU < 0. && LastU < 0.){ UMTr = LastU; UmTr = ((FirstU - LastU) < -1.e+4) ? (LastU - 1.e+4) : FirstU; }
+        else { UmTr = (FirstU < -1.e+4) ? -1.e+4 : FirstU; UMTr = (LastU > 1.e+4) ? 1.e+4 : LastU; }
+      }
+      else//Hyperbola
+      {
+        if(FirstU >= 0. && LastU >= 0.)
+        {
+          if(FirstU > 4.) return;
+          UmTr = FirstU; UMTr = (LastU > 4.) ? 4. : LastU;
+        }
+        else if(FirstU < 0. && LastU < 0.)
+        {
+          if(LastU < -4.) return;
+          UMTr = LastU; UmTr = (FirstU < -4.) ? -4. : FirstU;
+        }
+        else { UmTr = (FirstU < -4.) ? -4. : FirstU; UMTr = (LastU > 4.) ? 4. : LastU; }
+      }
+      //Make trimmed surface
+      Handle(Geom_RectangularTrimmedSurface) rts = new Geom_RectangularTrimmedSurface(gos,UmTr,UMTr,Standard_True);
+      I = rts->VIso(V);
+    }
   }
 }
 //================================================================================
@@ -449,7 +479,7 @@ static void FUN_PL_Intersection(const Handle(Adaptor3d_HSurface)& S1,
   else if(!S1->IsVPeriodic() && !S1->IsVClosed()) {
     if(T1 != GeomAbs_OffsetSurface) C1 = gs1->UIso(MS1[0]);
     else {
-      const Handle(Geom_OffsetSurface) gos = *(Handle_Geom_OffsetSurface*)&gs1;
+      const Handle(Geom_OffsetSurface) gos = Handle(Geom_OffsetSurface)::DownCast (gs1);
       const Handle(Geom_Surface) bs = gos->BasisSurface();
       C1 = bs->UIso(MS1[0]);
     }
@@ -459,7 +489,7 @@ static void FUN_PL_Intersection(const Handle(Adaptor3d_HSurface)& S1,
   if(!S1->IsUPeriodic() && !S1->IsUClosed()) {
     if(T1 != GeomAbs_OffsetSurface) C1 = gs1->VIso(MS1[1]);
     else {
-      const Handle(Geom_OffsetSurface) gos = *(Handle_Geom_OffsetSurface*)&gs1;
+      const Handle(Geom_OffsetSurface) gos = Handle(Geom_OffsetSurface)::DownCast (gs1);
       const Handle(Geom_Surface) bs = gos->BasisSurface();
       C1 = bs->VIso(MS1[1]);
     }
@@ -470,7 +500,7 @@ static void FUN_PL_Intersection(const Handle(Adaptor3d_HSurface)& S1,
   else if(!S2->IsVPeriodic() && !S2->IsVClosed()) {
     if(T2 != GeomAbs_OffsetSurface) C2 = gs2->UIso(MS2[0]);
     else {
-      const Handle(Geom_OffsetSurface) gos = *(Handle_Geom_OffsetSurface*)&gs2;
+      const Handle(Geom_OffsetSurface) gos = Handle(Geom_OffsetSurface)::DownCast (gs2);
       const Handle(Geom_Surface) bs = gos->BasisSurface();
       C2 = bs->UIso(MS2[0]);
     }
@@ -480,7 +510,7 @@ static void FUN_PL_Intersection(const Handle(Adaptor3d_HSurface)& S1,
   if(!S2->IsUPeriodic() && !S2->IsUClosed()) {
     if(T2 != GeomAbs_OffsetSurface) C2 = gs2->VIso(MS2[1]);
     else {
-      const Handle(Geom_OffsetSurface) gos = *(Handle_Geom_OffsetSurface*)&gs2;
+      const Handle(Geom_OffsetSurface) gos = Handle(Geom_OffsetSurface)::DownCast (gs2);
       const Handle(Geom_Surface) bs = gos->BasisSurface();
       C2 = bs->VIso(MS2[1]);
     }
@@ -545,19 +575,17 @@ static void FUN_PL_Intersection(const Handle(Adaptor3d_HSurface)& S1,
   Handle(Geom_Curve) C2Prj =
     GeomProjLib::ProjectOnPlane(C2,GPln,gp_Dir(DV),Standard_True);
   if(C1Prj.IsNull() || C2Prj.IsNull()) return;
-  Handle(Geom2d_Curve) C1Prj2d =
-    GeomProjLib::Curve2d(C1Prj,*(Handle_Geom_Surface *)&GPln);
-  Handle(Geom2d_Curve) C2Prj2d =
-    GeomProjLib::Curve2d(C2Prj,*(Handle_Geom_Surface *)&GPln);
+  Handle(Geom2d_Curve) C1Prj2d = GeomProjLib::Curve2d (C1Prj,GPln);
+  Handle(Geom2d_Curve) C2Prj2d = GeomProjLib::Curve2d (C2Prj,GPln);
   Geom2dAPI_InterCurveCurve ICC(C1Prj2d,C2Prj2d,1.0e-7);
   if(ICC.NbPoints() > 0 )
   {
     for(Standard_Integer ip = 1; ip <= ICC.NbPoints(); ip++)
-       {
-         gp_Pnt2d P = ICC.Point(ip);
-         gp_Pnt P3d = ElCLib::To3d(gp_Ax2(puvS1,gp_Dir(DV)),P);
-         SP.Append(P3d);
-       }
+    {
+      gp_Pnt2d P = ICC.Point(ip);
+      gp_Pnt P3d = ElCLib::To3d(gp_Ax2(puvS1,gp_Dir(DV)),P);
+      SP.Append(P3d);
+    }
   }
 }
 //================================================================================
@@ -578,58 +606,58 @@ static void FUN_NewFirstLast(const GeomAbs_CurveType& ga_ct,
     case GeomAbs_Parabola:
     {
       if(Abs(Lst - Fst) > TrVal)
-         {
-           if(Fst >= 0. && Lst >= 0.)
+      {
+        if(Fst >= 0. && Lst >= 0.)
         {
-             NewFst = Fst;
-             NewLst = ((Fst + TrVal) < Lst) ? (Fst + TrVal) : Lst;
-           }
-           if(Fst < 0. && Lst < 0.)
-           {
-             NewLst = Lst;
-             NewFst = ((Lst - TrVal) > Fst) ? (Lst - TrVal) : Fst;
-           }
-           else
-           {
-             NewFst = (Fst < -TrVal) ? -TrVal : Fst;
-             NewLst = (Lst > TrVal) ? TrVal : Lst;
-           }
-           NeedTr = Standard_True;
-         }
-         break;
+          NewFst = Fst;
+          NewLst = ((Fst + TrVal) < Lst) ? (Fst + TrVal) : Lst;
+        }
+        if(Fst < 0. && Lst < 0.)
+        {
+          NewLst = Lst;
+          NewFst = ((Lst - TrVal) > Fst) ? (Lst - TrVal) : Fst;
+        }
+        else
+        {
+          NewFst = (Fst < -TrVal) ? -TrVal : Fst;
+          NewLst = (Lst > TrVal) ? TrVal : Lst;
+        }
+        NeedTr = Standard_True;
+      }
+      break;
     }
-       case GeomAbs_Hyperbola:
+    case GeomAbs_Hyperbola:
     {
       if(Abs(Lst - Fst) > 10.)
-         
-           if(Fst >= 0. && Lst >= 0.)
-           {
-             if(Fst > 4.) return;
-             NewFst = Fst;
-             NewLst = (Lst > 4.) ? 4. : Lst;
-           }
-           if(Fst < 0. && Lst < 0.)
-           {
-             if(Lst < -4.) return;
-             NewLst = Lst;
-             NewFst = (Fst < -4.) ? -4. : Fst;
-           }
-           else
-           {
-             NewFst = (Fst < -4.) ? -4. : Fst;
-             NewLst = (Lst > 4.) ? 4. : Lst;
-           }
-           NeedTr = Standard_True;
-         }
+      { 
+        if(Fst >= 0. && Lst >= 0.)
+        {
+          if(Fst > 4.) return;
+          NewFst = Fst;
+          NewLst = (Lst > 4.) ? 4. : Lst;
+        }
+        if(Fst < 0. && Lst < 0.)
+        {
+          if(Lst < -4.) return;
+          NewLst = Lst;
+          NewFst = (Fst < -4.) ? -4. : Fst;
+        }
+        else
+        {
+          NewFst = (Fst < -4.) ? -4. : Fst;
+          NewLst = (Lst > 4.) ? 4. : Lst;
+        }
+        NeedTr = Standard_True;
+      }
       break;
     }
-  default:
+    default:
     break;
   }
 }
 //================================================================================
 //function: FUN_TrimBothSurf
-//================================================================================              
+//================================================================================
 static void FUN_TrimBothSurf(const Handle(Adaptor3d_HSurface)& S1,
                              const GeomAbs_SurfaceType&        T1,
                              const Handle(Adaptor3d_HSurface)& S2,
@@ -650,14 +678,14 @@ static void FUN_TrimBothSurf(const Handle(Adaptor3d_HSurface)& S1,
   if(T1 != GeomAbs_OffsetSurface){ visoS1 = gs1->VIso(VM1); uisoS1 = gs1->UIso(UM1); }
   else
   {
-    const Handle(Geom_OffsetSurface) gos = *(Handle_Geom_OffsetSurface*)&gs1;
+    const Handle(Geom_OffsetSurface) gos = Handle(Geom_OffsetSurface)::DownCast (gs1);
     const Handle(Geom_Surface) bs = gos->BasisSurface();
     visoS1 = bs->VIso(VM1); uisoS1 = bs->UIso(UM1);
   }
   if(T2 != GeomAbs_OffsetSurface){ visoS2 = gs2->VIso(VM2); uisoS2 = gs2->UIso(UM2); }
   else
   {
-    const Handle(Geom_OffsetSurface) gos = *(Handle_Geom_OffsetSurface*)&gs2;
+    const Handle(Geom_OffsetSurface) gos = Handle(Geom_OffsetSurface)::DownCast (gs2);
     const Handle(Geom_Surface) bs = gos->BasisSurface();
     visoS2 = bs->VIso(VM2); uisoS2 = bs->UIso(UM2);
   }
@@ -684,19 +712,19 @@ static void FUN_TrimBothSurf(const Handle(Adaptor3d_HSurface)& S1,
   if(TrmU1)
   {
     if(TrmV1)
-       {
-         Handle(Adaptor3d_HSurface) TS = NS1;
-         NS1 = TS->UTrim(U1S1, U2S1, 1.0e-7);
-       }
+    {
+      Handle(Adaptor3d_HSurface) TS = NS1;
+      NS1 = TS->UTrim(U1S1, U2S1, 1.0e-7);
+    }
     else NS1 = S1->UTrim(U1S1, U2S1, 1.0e-7);
   }
   if(TrmU2)
   {
     if(TrmV2)
-       {
-         Handle(Adaptor3d_HSurface) TS = NS2;
-         NS2 = TS->UTrim(U1S2, U2S2, 1.0e-7);
-       }
+    {
+      Handle(Adaptor3d_HSurface) TS = NS2;
+      NS2 = TS->UTrim(U1S2, U2S2, 1.0e-7);
+    }
     else NS2 = S2->UTrim(U1S2, U2S2, 1.0e-7);
   }
 }
@@ -711,7 +739,9 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
                                     const Handle(Adaptor3d_TopolTool)& theD2,
                                     const Standard_Real TolArc,
                                     const Standard_Real TolTang,
-                                    const Standard_Boolean isGeomInt)
+                                    const Standard_Boolean isGeomInt,
+                                    const Standard_Boolean theIsReqToKeepRLine,
+                                    const Standard_Boolean theIsReqToPostWLProc)
 {
   myTolArc = TolArc;
   myTolTang = TolTang;
@@ -732,7 +762,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
   
   //treatment of the cases with cone or torus
   Standard_Boolean TreatAsBiParametric = Standard_False;
-  Standard_Integer bImp = 0;
+  Standard_Integer bGeomGeom = 0;
   //
   if (typs1 == GeomAbs_Cone  || typs2 == GeomAbs_Cone ||
       typs1 == GeomAbs_Torus || typs2 == GeomAbs_Torus) {
@@ -748,36 +778,47 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
     aCTType = aCTSurf->GetType();
     bToCheck = Standard_False;
     //
-    if (aCTType == GeomAbs_Cone) {
-      Standard_Real a1 = Abs(aCTSurf->Cone().SemiAngle());
+    if (typs1 == GeomAbs_Cone  || typs2 == GeomAbs_Cone) {
+      const gp_Cone aCon1 = (aCTType == GeomAbs_Cone) ? 
+        aCTSurf->Cone() : aGeomSurf->Cone();
+      Standard_Real a1 = Abs(aCon1.SemiAngle());
       bToCheck = (a1 < 0.02) || (a1 > 1.55);
+      //
       if (typs1 == typs2) {
-        Standard_Real a2 = Abs(aGeomSurf->Cone().SemiAngle());
+        const gp_Cone aCon2 = aGeomSurf->Cone();
+        Standard_Real a2 = Abs(aCon2.SemiAngle());
         bToCheck = bToCheck || (a2 < 0.02) || (a2 > 1.55);
         //
         if (a1 > 1.55 && a2 > 1.55) {//quasi-planes: if same domain, treat as canonic
-          const gp_Cone aCon1 = aCTSurf->Cone();
-          const gp_Cone aCon2 = aGeomSurf->Cone();
           const gp_Ax1 A1 = aCon1.Axis(), A2 = aCon2.Axis();
           if (A1.IsParallel(A2,Precision::Angular())) {
             const gp_Pnt Apex1 = aCon1.Apex(), Apex2 = aCon2.Apex();
             const gp_Pln Plan1( Apex1, A1.Direction() );
             if (Plan1.Distance( Apex2 ) <= Precision::Confusion()) {
               bToCheck = Standard_False;
-              bImp = 1;
             }
           }
         }
       }
       //
-      aCTAx = aCTSurf->Cone().Axis();
+      TreatAsBiParametric = bToCheck;
+      if (aCTType == GeomAbs_Cone) {
+        aCTAx = aCon1.Axis();
+      }
     }
-    else {
-      bToCheck = aCTSurf->Torus().MajorRadius() > aCTSurf->Torus().MinorRadius();
-      if (bToCheck && (typs1 == typs2)) {
-        bToCheck = aGeomSurf->Torus().MajorRadius() > aGeomSurf->Torus().MinorRadius();
+    //
+    if (typs1 == GeomAbs_Torus || typs2 == GeomAbs_Torus) {
+      const gp_Torus aTor1 = (aCTType == GeomAbs_Torus) ? 
+        aCTSurf->Torus() : aGeomSurf->Torus();
+      bToCheck = aTor1.MajorRadius() > aTor1.MinorRadius();
+      if (typs1 == typs2) {
+        const gp_Torus aTor2 = aGeomSurf->Torus();
+        bToCheck = aTor2.MajorRadius() > aTor2.MinorRadius();
+      }
+      //
+      if (aCTType == GeomAbs_Torus) {
+        aCTAx = aTor1.Axis();
       }
-      aCTAx = aCTSurf->Torus().Axis();
     }
     //
     if (bToCheck) {
@@ -787,11 +828,11 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
       case GeomAbs_Plane: {
         aGeomAx = aGeomSurf->Plane().Axis();
         if (aCTType == GeomAbs_Cone) {
-          bImp = 1;
+          bGeomGeom = 1;
           if (Abs(aCTSurf->Cone().SemiAngle()) < 0.02) {
             Standard_Real ps = Abs(aCTAx.Direction().Dot(aGeomAx.Direction()));
             if(ps < 0.015) {
-              bImp = 0;
+              bGeomGeom = 0;
             }
           }
         }
@@ -799,7 +840,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
           if (aCTAx.IsParallel(aGeomAx, Precision::Angular()) ||
               (aCTAx.IsNormal(aGeomAx, Precision::Angular()) && 
                (aGeomSurf->Plane().Distance(aCTAx.Location()) < Precision::Confusion()))) {
-            bImp = 1;
+            bGeomGeom = 1;
           }
         }
         bToCheck = Standard_False;
@@ -807,7 +848,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
       }
       case GeomAbs_Sphere: {
         if (aL1.Distance(aGeomSurf->Sphere().Location()) < Precision::Confusion()) {
-          bImp = 1;
+          bGeomGeom = 1;
         }
         bToCheck = Standard_False;
         break;
@@ -829,12 +870,12 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
       if (bToCheck) {
         if (aCTAx.IsParallel(aGeomAx, Precision::Angular()) &&
             (aL1.Distance(aGeomAx.Location()) <= Precision::Confusion())) {
-          bImp = 1;
+          bGeomGeom = 1;
         }
       }
       //
-      if (aCTType == GeomAbs_Cone) {
-        TreatAsBiParametric = (bImp == 0);
+      if (bGeomGeom == 1) {
+        TreatAsBiParametric = Standard_False;
       }
     }
   }
@@ -868,7 +909,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
     case GeomAbs_Cylinder:
     case GeomAbs_Sphere:
     case GeomAbs_Cone: ts1 = 1; break;
-    case GeomAbs_Torus: ts1 = bImp; break;
+    case GeomAbs_Torus: ts1 = bGeomGeom; break;
     default: break;
   }
 
@@ -879,7 +920,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
     case GeomAbs_Cylinder:
     case GeomAbs_Sphere:
     case GeomAbs_Cone: ts2 = 1; break;
-    case GeomAbs_Torus: ts2 = bImp; break;
+    case GeomAbs_Torus: ts2 = bGeomGeom; break;
     default: break;
   }
   //
@@ -892,16 +933,17 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
   // Geom - Geom
   if(ts1 == ts2 && ts1 == 1)
   {
-    const Standard_Boolean RestrictLine = Standard_True;
     IntSurf_ListOfPntOn2S ListOfPnts;
     ListOfPnts.Clear();
     if(isGeomInt)
     {
-      GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
+      GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang,
+                     ListOfPnts, typs1, typs2, theIsReqToKeepRLine);
     }
     else
     {
-      ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
+      ParamParamPerfom(theS1, theD1, theS2, theD2, 
+              TolArc, TolTang, ListOfPnts, typs1, typs2);
     }
   }
 
@@ -914,11 +956,34 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
   // Param - Param 
   if(ts1 == ts2 && ts1 == 0)
   {
-    const Standard_Boolean RestrictLine = Standard_True;
     IntSurf_ListOfPntOn2S ListOfPnts;
     ListOfPnts.Clear();
 
-    ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
+    ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc,
+                        TolTang, ListOfPnts, typs1, typs2);
+  }
+
+  if(!theIsReqToPostWLProc)
+    return;
+
+  for(Standard_Integer i = slin.Lower(); i <= slin.Upper(); i++)
+  {
+    Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(slin.Value(i));
+
+    if(aWL.IsNull())
+      continue;
+
+    if (!aWL->IsPurgingAllowed())
+      continue;
+
+    Handle(IntPatch_WLine) aRW =
+      IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2);
+
+    if(aRW.IsNull())
+      continue;
+
+    slin.InsertAfter(i, aRW);
+    slin.Remove(i);
   }
 }
 
@@ -933,8 +998,9 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
                                     const Standard_Real TolArc,
                                     const Standard_Real TolTang,
                                     IntSurf_ListOfPntOn2S& ListOfPnts,
-                                    const Standard_Boolean RestrictLine,
-                                    const Standard_Boolean isGeomInt)
+                                    const Standard_Boolean isGeomInt,
+                                    const Standard_Boolean theIsReqToKeepRLine,
+                                    const Standard_Boolean theIsReqToPostWLProc)
 {
   myTolArc = TolArc;
   myTolTang = TolTang;
@@ -955,7 +1021,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
   //
   //treatment of the cases with cone or torus
   Standard_Boolean TreatAsBiParametric = Standard_False;
-  Standard_Integer bImp = 0;
+  Standard_Integer bGeomGeom = 0;
   //
   if (typs1 == GeomAbs_Cone  || typs2 == GeomAbs_Cone ||
       typs1 == GeomAbs_Torus || typs2 == GeomAbs_Torus) {
@@ -971,36 +1037,49 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
     aCTType = aCTSurf->GetType();
     bToCheck = Standard_False;
     //
-    if (aCTType == GeomAbs_Cone) {
-      Standard_Real a1 = Abs(aCTSurf->Cone().SemiAngle());
+    if (typs1 == GeomAbs_Cone  || typs2 == GeomAbs_Cone) {
+      const gp_Cone aCon1 = (aCTType == GeomAbs_Cone) ? 
+        aCTSurf->Cone() : aGeomSurf->Cone();
+      Standard_Real a1 = Abs(aCon1.SemiAngle());
       bToCheck = (a1 < 0.02) || (a1 > 1.55);
+      //
       if (typs1 == typs2) {
-        Standard_Real a2 = Abs(aGeomSurf->Cone().SemiAngle());
+        const gp_Cone aCon2 = aGeomSurf->Cone();
+        Standard_Real a2 = Abs(aCon2.SemiAngle());
         bToCheck = bToCheck || (a2 < 0.02) || (a2 > 1.55);
         //
         if (a1 > 1.55 && a2 > 1.55) {//quasi-planes: if same domain, treat as canonic
-          const gp_Cone aCon1 = aCTSurf->Cone();
-          const gp_Cone aCon2 = aGeomSurf->Cone();
           const gp_Ax1 A1 = aCon1.Axis(), A2 = aCon2.Axis();
           if (A1.IsParallel(A2,Precision::Angular())) {
             const gp_Pnt Apex1 = aCon1.Apex(), Apex2 = aCon2.Apex();
             const gp_Pln Plan1( Apex1, A1.Direction() );
             if (Plan1.Distance( Apex2 ) <= Precision::Confusion()) {
               bToCheck = Standard_False;
-              bImp = 1;
             }
           }
         }
       }
       //
-      aCTAx = aCTSurf->Cone().Axis();
+      TreatAsBiParametric = bToCheck;
+      if (aCTType == GeomAbs_Cone) {
+        aCTAx = aCon1.Axis();
+      }
     }
-    else {
-      bToCheck = aCTSurf->Torus().MajorRadius() > aCTSurf->Torus().MinorRadius();
-      if (bToCheck && (typs1 == typs2)) {
-        bToCheck = aGeomSurf->Torus().MajorRadius() > aGeomSurf->Torus().MinorRadius();
+    //
+    if (typs1 == GeomAbs_Torus || typs2 == GeomAbs_Torus) {
+      const gp_Torus aTor1 = (aCTType == GeomAbs_Torus) ? 
+        aCTSurf->Torus() : aGeomSurf->Torus();
+      bToCheck = aTor1.MajorRadius() > aTor1.MinorRadius();
+      if (typs1 == typs2) {
+        const gp_Torus aTor2 = aGeomSurf->Torus();
+        bToCheck = (bToCheck && (aTor2.MajorRadius() > aTor2.MinorRadius())) ||
+                   (Abs(aTor1.MajorRadius() - aTor2.MajorRadius()) < TolTang &&
+                    Abs(aTor1.MinorRadius() - aTor2.MinorRadius()) < TolTang);
+      }
+      //
+      if (aCTType == GeomAbs_Torus) {
+        aCTAx = aTor1.Axis();
       }
-      aCTAx = aCTSurf->Torus().Axis();
     }
     //
     if (bToCheck) {
@@ -1010,11 +1089,11 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
       case GeomAbs_Plane: {
         aGeomAx = aGeomSurf->Plane().Axis();
         if (aCTType == GeomAbs_Cone) {
-          bImp = 1;
+          bGeomGeom = 1;
           if (Abs(aCTSurf->Cone().SemiAngle()) < 0.02) {
             Standard_Real ps = Abs(aCTAx.Direction().Dot(aGeomAx.Direction()));
             if(ps < 0.015) {
-              bImp = 0;
+              bGeomGeom = 0;
             }
           }
         }
@@ -1022,7 +1101,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
           if (aCTAx.IsParallel(aGeomAx, Precision::Angular()) ||
               (aCTAx.IsNormal(aGeomAx, Precision::Angular()) && 
                (aGeomSurf->Plane().Distance(aCTAx.Location()) < Precision::Confusion()))) {
-            bImp = 1;
+            bGeomGeom = 1;
           }
         }
         bToCheck = Standard_False;
@@ -1030,7 +1109,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
       }
       case GeomAbs_Sphere: {
         if (aL1.Distance(aGeomSurf->Sphere().Location()) < Precision::Confusion()) {
-          bImp = 1;
+          bGeomGeom = 1;
         }
         bToCheck = Standard_False;
         break;
@@ -1052,12 +1131,12 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
       if (bToCheck) {
         if (aCTAx.IsParallel(aGeomAx, Precision::Angular()) &&
             (aL1.Distance(aGeomAx.Location()) <= Precision::Confusion())) {
-          bImp = 1;
+          bGeomGeom = 1;
         }
       }
       //
-      if (aCTType == GeomAbs_Cone) {
-        TreatAsBiParametric = (bImp == 0);
+      if (bGeomGeom == 1) {
+        TreatAsBiParametric = Standard_False;
       }
     }
   }
@@ -1082,7 +1161,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
     case GeomAbs_Cylinder:
     case GeomAbs_Sphere:
     case GeomAbs_Cone: ts1 = 1; break;
-    case GeomAbs_Torus: ts1 = bImp; break;
+    case GeomAbs_Torus: ts1 = bGeomGeom; break;
     default: break;
   }
 
@@ -1093,7 +1172,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
     case GeomAbs_Cylinder:
     case GeomAbs_Sphere:
     case GeomAbs_Cone: ts2 = 1; break;
-    case GeomAbs_Torus: ts2 = bImp; break;
+    case GeomAbs_Torus: ts2 = bGeomGeom; break;
     default: break;
   }
   //
@@ -1103,7 +1182,8 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
 
   if(!isGeomInt)
   {
-    ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
+    ParamParamPerfom(theS1, theD1, theS2, theD2, 
+                TolArc, TolTang, ListOfPnts, typs1, typs2);
   }
   else if(ts1 != ts2)
   {
@@ -1111,11 +1191,36 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
   }
   else if (ts1 == 0)
   {
-    ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
+    ParamParamPerfom(theS1, theD1, theS2, theD2,
+                TolArc, TolTang, ListOfPnts, typs1, typs2);
   }
   else if(ts1 == 1)
   {
-    GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
+    GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang,
+                   ListOfPnts, typs1, typs2, theIsReqToKeepRLine);
+  }
+
+  if(!theIsReqToPostWLProc)
+    return;
+
+  for(Standard_Integer i = slin.Lower(); i <= slin.Upper(); i++)
+  {
+    Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(slin.Value(i));
+
+    if(aWL.IsNull())
+      continue;
+
+    if(!aWL->IsPurgingAllowed())
+      continue;
+
+    Handle(IntPatch_WLine) aRW = 
+      IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2);
+
+    if(aRW.IsNull())
+      continue;
+
+    slin.InsertAfter(i, aRW);
+    slin.Remove(i);
   }
 }
 
@@ -1130,7 +1235,6 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)&
                                              const Standard_Real TolArc,
                                              const Standard_Real TolTang,
                                              IntSurf_ListOfPntOn2S& ListOfPnts,
-                                             const Standard_Boolean RestrictLine,
                                              const GeomAbs_SurfaceType typs1,
                                              const GeomAbs_SurfaceType typs2)
 {
@@ -1140,10 +1244,10 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)&
     Standard_Boolean ClearFlag = Standard_True;
     if(!ListOfPnts.IsEmpty())
     {
-      interpp.Perform(theS1,theD1,theS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep, ListOfPnts, RestrictLine);
+      interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep, ListOfPnts);
       ClearFlag = Standard_False;
     }
-    interpp.Perform(theS1,theD1,theS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep,ClearFlag);   //double call!!!!!!!
+    interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep,ClearFlag);
   }
   else if((theD1->DomainIsInfinite()) ^ (theD2->DomainIsInfinite()))
   {
@@ -1156,7 +1260,7 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)&
       const Standard_Real AP = Max(MU, MV);
       Handle(Adaptor3d_HSurface) SS;
       FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, theS1, AP, SS);
-      interpp.Perform(SS,theD1,theS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep);
+      interpp.Perform(SS,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep);
     }
     else
     {
@@ -1166,7 +1270,7 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)&
       const Standard_Real AP = Max(MU, MV);
       Handle(Adaptor3d_HSurface) SS;
       FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, theS2, AP, SS);
-      interpp.Perform(theS1, theD1, SS, theD2,TolArc,TolTang,myFleche,myUVMaxStep);
+      interpp.Perform(theS1, theD1, SS, theD2,TolTang, TolArc,myFleche,myUVMaxStep);
     }
   }//(theD1->DomainIsInfinite()) ^ (theD2->DomainIsInfinite())
   else
@@ -1189,8 +1293,8 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)&
         for(Standard_Integer ip = 1; ip <= sop.Length(); ip++)
         {
           gp_Lin lin(sop.Value(ip),gp_Dir(v));
-          Handle(IntPatch_GLine) gl = new IntPatch_GLine(lin,Standard_False);
-          slin.Append(*(Handle_IntPatch_Line *)&gl);
+          Handle(IntPatch_Line) gl = new IntPatch_GLine(lin,Standard_False);
+          slin.Append(gl);
         }
 
         done = Standard_True;
@@ -1205,7 +1309,7 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)&
       Handle(Adaptor3d_HSurface) nS1 = theS1;
       Handle(Adaptor3d_HSurface) nS2 = theS2;
       FUN_TrimBothSurf(theS1,typs1,theS2,typs2,1.e+8,nS1,nS2);
-      interpp.Perform(nS1,theD1,nS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep);
+      interpp.Perform(nS1,theD1,nS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep);
     }// 'NON - COLLINEAR LINES'
   }// both domains are infinite
 
@@ -1240,111 +1344,137 @@ void IntPatch_Intersection::GeomGeomPerfom(const Handle(Adaptor3d_HSurface)& the
                                            const Standard_Real TolArc,
                                            const Standard_Real TolTang,
                                            IntSurf_ListOfPntOn2S& ListOfPnts,
-                                           const Standard_Boolean RestrictLine,
-                                           const GeomAbs_SurfaceType typs1,
-                                           const GeomAbs_SurfaceType typs2)
+                                           const GeomAbs_SurfaceType theTyps1,
+                                           const GeomAbs_SurfaceType theTyps2,
+                                           const Standard_Boolean theIsReqToKeepRLine)
 {
-  IntPatch_ImpImpIntersection interii(theS1,theD1,theS2,theD2,myTolArc,myTolTang);
-  const Standard_Boolean anIS = interii.IsDone();
-  if (anIS)
+  IntPatch_ImpImpIntersection interii(theS1,theD1,theS2,theD2,
+                                      myTolArc,myTolTang, theIsReqToKeepRLine);
+
+  if (!interii.IsDone())
   {
-    done = anIS;
-    empt = interii.IsEmpty();
-    if (!empt)
-    {
-      tgte = interii.TangentFaces();
-      if (tgte)
-        oppo = interii.OppositeFaces();
+    done = Standard_False;
+    ParamParamPerfom(theS1, theD1, theS2, theD2, 
+                TolArc, TolTang, ListOfPnts, theTyps1, theTyps2);
+    return;
+  }
 
-      for (Standard_Integer i = 1; i <= interii.NbLines(); i++)
-      {
-        const Handle_IntPatch_Line& line = interii.Line(i);
-        if (line->ArcType() == IntPatch_Analytic)
-        {
-          const GeomAbs_SurfaceType typs1 = theS1->GetType();
-          const GeomAbs_SurfaceType typs2 = theS2->GetType();
-          IntSurf_Quadric Quad1,Quad2;
-          
-          switch(typs1)
-          {
-          case GeomAbs_Plane:
-            Quad1.SetValue(theS1->Plane());
-            break;
-
-          case GeomAbs_Cylinder:
-            Quad1.SetValue(theS1->Cylinder());
-            break;
-
-          case GeomAbs_Sphere:
-            Quad1.SetValue(theS1->Sphere());
-            break;
-
-          case GeomAbs_Cone:
-            Quad1.SetValue(theS1->Cone());
-            break;
-
-          case GeomAbs_Torus:
-            Quad1.SetValue(theS1->Torus());
-            break;
-
-          default:
-            break;
-          }
+  done = (interii.GetStatus() == IntPatch_ImpImpIntersection::IntStatus_OK);
+  empt = interii.IsEmpty();
 
-          switch(typs2)
-          {
-          case GeomAbs_Plane:
-            Quad2.SetValue(theS2->Plane());
-            break;
-          case GeomAbs_Cylinder:
-            Quad2.SetValue(theS2->Cylinder());
-            break;
-
-          case GeomAbs_Sphere:
-            Quad2.SetValue(theS2->Sphere());
-            break;
-
-          case GeomAbs_Cone:
-            Quad2.SetValue(theS2->Cone());
-            break;
-
-          case GeomAbs_Torus:
-            Quad2.SetValue(theS2->Torus());
-            break;
-
-          default:
-            break;
-          }
+  if(empt)
+  {
+    return;
+  }
 
-          IntPatch_ALineToWLine AToW(Quad1,Quad2,0.01,0.05,aNbPointsInALine);
-          Handle(IntPatch_Line) wlin=AToW.MakeWLine((*((Handle_IntPatch_ALine *)(&line))));
-          slin.Append(wlin);
-        }
-        else
-          slin.Append(interii.Line(i));
-      }
+  const Standard_Integer aNbPointsInALine = 200;
+
+  tgte = interii.TangentFaces();
+  if (tgte)
+    oppo = interii.OppositeFaces();
 
-      for (Standard_Integer i = 1; i <= interii.NbPnts(); i++)
+  Standard_Boolean isWLExist = Standard_False;
+  IntPatch_ALineToWLine AToW(theS1, theS2, aNbPointsInALine);
+
+  for (Standard_Integer i = 1; i <= interii.NbLines(); i++)
+  {
+    const Handle(IntPatch_Line)& line = interii.Line(i);
+    if (line->ArcType() == IntPatch_Analytic)
+    {
+      isWLExist = Standard_True;
+      AToW.MakeWLine(Handle(IntPatch_ALine)::DownCast(line), slin);
+    }
+    else
+    {
+      if (line->ArcType() == IntPatch_Walking)
       {
-        spnt.Append(interii.Point(i));
+        Handle(IntPatch_WLine)::DownCast(line)->EnablePurging(Standard_False);
       }
+
+      if((line->ArcType() != IntPatch_Restriction) || theIsReqToKeepRLine)
+        slin.Append(line);
     }
   }
-  else
-    ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
+
+  for (Standard_Integer i = 1; i <= interii.NbPnts(); i++)
+  {
+    spnt.Append(interii.Point(i));
+  }
+
+  if((theTyps1 == GeomAbs_Cylinder) && (theTyps2 == GeomAbs_Cylinder))
+  {
+    IntPatch_WLineTool::JoinWLines(slin, spnt, theS1, theS2, TolTang);
+  }
+
+  if(isWLExist)
+  {
+    Bnd_Box2d aBx1, aBx2;
+    const Standard_Real aU1F = theS1->FirstUParameter(),
+                        aU1L = theS1->LastUParameter(),
+                        aV1F = theS1->FirstVParameter(),
+                        aV1L = theS1->LastVParameter(),
+                        aU2F = theS2->FirstUParameter(),
+                        aU2L = theS2->LastUParameter(),
+                        aV2F = theS2->FirstVParameter(),
+                        aV2L = theS2->LastVParameter();
+    aBx1.Add(gp_Pnt2d(aU1F, aV1F));
+    aBx1.Add(gp_Pnt2d(aU1L, aV1F));
+    aBx1.Add(gp_Pnt2d(aU1L, aV1L));
+    aBx1.Add(gp_Pnt2d(aU1F, aV1L));
+    aBx2.Add(gp_Pnt2d(aU2F, aV2F));
+    aBx2.Add(gp_Pnt2d(aU2L, aV2F));
+    aBx2.Add(gp_Pnt2d(aU2L, aV2L));
+    aBx2.Add(gp_Pnt2d(aU2F, aV2L));
+
+    aBx1.Enlarge(Precision::PConfusion());
+    aBx2.Enlarge(Precision::PConfusion());
+
+    const Standard_Real
+            anArrOfPeriod[4] = {theS1->IsUPeriodic()? theS1->UPeriod() : 0.0,
+                                theS1->IsVPeriodic()? theS1->VPeriod() : 0.0,
+                                theS2->IsUPeriodic()? theS2->UPeriod() : 0.0,
+                                theS2->IsVPeriodic()? theS2->VPeriod() : 0.0};
+
+    NCollection_List<gp_Pnt> aListOfCriticalPoints;
+
+    if (theS1->GetType() == GeomAbs_Cone)
+    {
+      aListOfCriticalPoints.Append(theS1->Cone().Apex());
+    }
+    else if (theS1->GetType() == GeomAbs_Sphere)
+    {
+      aListOfCriticalPoints.Append(theS1->Value(0.0, M_PI_2));
+      aListOfCriticalPoints.Append(theS1->Value(0.0, -M_PI_2));
+    }
+
+    if (theS2->GetType() == GeomAbs_Cone)
+    {
+      aListOfCriticalPoints.Append(theS2->Cone().Apex());
+    }
+    else if (theS2->GetType() == GeomAbs_Sphere)
+    {
+      aListOfCriticalPoints.Append(theS2->Value(0.0, M_PI_2));
+      aListOfCriticalPoints.Append(theS2->Value(0.0, -M_PI_2));
+    }
+
+    IntPatch_WLineTool::ExtendTwoWLines(slin, theS1, theS2, TolTang,
+                                        anArrOfPeriod, aBx1, aBx2,
+                                        aListOfCriticalPoints);
+  }
 }
 
 //=======================================================================
-////function : GeomParamPerfom
+//function : GeomParamPerfom
 //purpose  : 
 //=======================================================================
-void IntPatch_Intersection::GeomParamPerfom(const Handle(Adaptor3d_HSurface)&  theS1,
-                                            const Handle(Adaptor3d_TopolTool)& theD1,
-                                            const Handle(Adaptor3d_HSurface)&  theS2,
-                                            const Handle(Adaptor3d_TopolTool)& theD2,
-                                            const Standard_Boolean isNotAnalitical,
-                                            const GeomAbs_SurfaceType typs1,
-                                            const GeomAbs_SurfaceType typs2)
+void IntPatch_Intersection::
+  GeomParamPerfom(const Handle(Adaptor3d_HSurface)&  theS1,
+                  const Handle(Adaptor3d_TopolTool)& theD1,
+                  const Handle(Adaptor3d_HSurface)&  theS2,
+                  const Handle(Adaptor3d_TopolTool)& theD2,
+                  const Standard_Boolean isNotAnalitical,
+                  const GeomAbs_SurfaceType typs1,
+                  const GeomAbs_SurfaceType typs2)
 {
   IntPatch_ImpPrmIntersection interip;
   if (myIsStartPnt)
@@ -1369,8 +1499,8 @@ void IntPatch_Intersection::GeomParamPerfom(const Handle(Adaptor3d_HSurface)&  t
         for(Standard_Integer ip = 1; ip <= sop.Length(); ip++)
         {
           gp_Lin lin(sop.Value(ip),gp_Dir(v));
-          Handle(IntPatch_GLine) gl = new IntPatch_GLine(lin,Standard_False);
-          slin.Append(*(Handle_IntPatch_Line *)&gl);
+          Handle(IntPatch_Line) gl = new IntPatch_GLine(lin,Standard_False);
+          slin.Append(gl);
         }
 
         done = Standard_True;
@@ -1398,13 +1528,14 @@ void IntPatch_Intersection::GeomParamPerfom(const Handle(Adaptor3d_HSurface)&  t
 
     if (!empt)
     {
-      for(Standard_Integer i = 1; i <= interip.NbLines(); i++)
+      const Standard_Integer aNbLines = interip.NbLines();
+      for(Standard_Integer i = 1; i <= aNbLines; i++)
       {
         if(interip.Line(i)->ArcType() != IntPatch_Walking)
           slin.Append(interip.Line(i));
       }
 
-      for(Standard_Integer i = 1; i <= interip.NbLines(); i++)
+      for(Standard_Integer i = 1; i <= aNbLines; i++)
       {
         if(interip.Line(i)->ArcType() == IntPatch_Walking)
           slin.Append(interip.Line(i));
@@ -1416,7 +1547,6 @@ void IntPatch_Intersection::GeomParamPerfom(const Handle(Adaptor3d_HSurface)&  t
   }
 }
 
-
 void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
                                     const Handle(Adaptor3d_TopolTool)& D1,
                                     const Handle(Adaptor3d_HSurface)&  S2,
@@ -1473,9 +1603,9 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
   else
   {
     IntPatch_PrmPrmIntersection interpp;
-    interpp.Perform(S1,D1,S2,D2,U1,V1,U2,V2,TolArc,TolTang,myFleche,myUVMaxStep);
+    interpp.Perform(S1,D1,S2,D2,U1,V1,U2,V2,TolTang,TolArc,myFleche,myUVMaxStep);
     if (interpp.IsDone())
-       {
+    {
       done = Standard_True;
       tgte = Standard_False;
       empt = interpp.IsEmpty();
@@ -1484,74 +1614,82 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
       for (; i<=nblm; i++) slin.Append(interpp.Line(i));
     }
   }
+
+  for(Standard_Integer i = slin.Lower(); i <= slin.Upper(); i++)
+  {
+    Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(slin.Value(i));
+
+    if(aWL.IsNull())
+      continue;
+
+    if (!aWL->IsPurgingAllowed())
+      continue;
+
+    Handle(IntPatch_WLine) aRW =
+      IntPatch_WLineTool::ComputePurgedWLine(aWL, S1, S2, D1, D2);
+
+    if(aRW.IsNull())
+      continue;
+
+    slin.InsertAfter(i, aRW);
+    slin.Remove(i);
+  }
 }
-//======================================================================
-#include <IntPatch_IType.hxx>
-#include <IntPatch_LineConstructor.hxx>
-#include <Handle_Adaptor2d_HCurve2d.hxx>
-#define MAXR 200
-
-
-//void IntPatch_Intersection__MAJ_R(Handle_Adaptor2d_HCurve2d *R1,
-//                                  Handle_Adaptor2d_HCurve2d *R2,
-//                                  int *NR1,
-//                                  int *NR2,
-//                                  Standard_Integer nbR1,
-//                                  Standard_Integer nbR2,
-//                                  const IntPatch_Point& VTX)
-void IntPatch_Intersection__MAJ_R(Handle_Adaptor2d_HCurve2d *,
-                                    Handle_Adaptor2d_HCurve2d *,
-                                    int *,
-                                    int *,
-                                    Standard_Integer ,
-                                    Standard_Integer ,
-                                    const IntPatch_Point& )
+
+#ifdef DUMPOFIntPatch_Intersection
+
+void IntPatch_Intersection__MAJ_R(Handle(Adaptor2d_HCurve2d) *R1,
+                                  Handle(Adaptor2d_HCurve2d) *,
+                                  int *NR1,
+                                  int *,
+                                  Standard_Integer nbR1,
+                                  Standard_Integer ,
+                                  const IntPatch_Point& VTX)
 { 
-  /*
+  
   if(VTX.IsOnDomS1()) { 
     
-    //-- long unsigned ptr= *((long unsigned *)(((Handle_Standard_Transient *)(&(VTX.ArcOnS1())))));
+    //-- long unsigned ptr= *((long unsigned *)(((Handle(Standard_Transient) *)(&(VTX.ArcOnS1())))));
     for(Standard_Integer i=0; i<nbR1;i++) { 
       if(VTX.ArcOnS1()==R1[i]) { 
-       NR1[i]++;
-       printf("\n ******************************");
-       return;
+        NR1[i]++;
+        printf("\n ******************************");
+        return;
       }
     }
     printf("\n R Pas trouvee  (IntPatch)\n");
     
   }
-  */
 }
+#endif
 
-
-//void IntPatch_Intersection::Dump(const Standard_Integer Mode,
-void IntPatch_Intersection::Dump(const Standard_Integer ,
-                                   const Handle(Adaptor3d_HSurface)&  S1,
-                                   const Handle(Adaptor3d_TopolTool)& D1,
-                                   const Handle(Adaptor3d_HSurface)&  S2,
-                                   const Handle(Adaptor3d_TopolTool)& D2) const 
+void IntPatch_Intersection::Dump(const Standard_Integer /*Mode*/,
+                                 const Handle(Adaptor3d_HSurface)&  /*S1*/,
+                                 const Handle(Adaptor3d_TopolTool)& /*D1*/,
+                                 const Handle(Adaptor3d_HSurface)&  /*S2*/,
+                                 const Handle(Adaptor3d_TopolTool)& /*D2*/) const 
 { 
-  
+#ifdef DUMPOFIntPatch_Intersection
+  const int MAXR = 200;
   //-- ----------------------------------------------------------------------
   //--  construction de la liste des restrictions & vertex 
   //--
   int NR1[MAXR],NR2[MAXR];
-  Handle_Adaptor2d_HCurve2d R1[MAXR],R2[MAXR];
+  Handle(Adaptor2d_HCurve2d) R1[MAXR],R2[MAXR];
   Standard_Integer nbR1=0,nbR2=0;
   for(D1->Init();D1->More() && nbR1<MAXR; D1->Next()) { 
     R1[nbR1]=D1->Value(); 
     NR1[nbR1]=0;
     nbR1++;
   }
-  for(D2->Init();D2->More() && nbR2<MAXR; D2->Next()) { 
+  for(D2->Init();D2->More() && nbR2<MAXR; D2->Next()) {
     R2[nbR2]=D2->Value();
     NR2[nbR2]=0;
     nbR2++;
   }
   
   printf("\nDUMP_INT:  ----empt:%2ud  tgte:%2ud  oppo:%2ud ---------------------------------",empt,tgte,empt);
-  Standard_Integer i,j,nbr1,nbr2,nbgl,nbgc,nbge,nbgp,nbgh,nbl,nbr,nbg,nbw,nba;
+  Standard_Integer i,nbr1,nbr2,nbgl,nbgc,nbge,nbgp,nbgh,nbl,nbr,nbg,nbw,nba;
   nbl=nbr=nbg=nbw=nba=nbgl=nbge=nbr1=nbr2=nbgc=nbgp=nbgh=0;
   nbl=NbLines();
   for(i=1;i<=nbl;i++) { 
@@ -1560,24 +1698,24 @@ void IntPatch_Intersection::Dump(const Standard_Integer ,
     if(IType == IntPatch_Walking) nbw++;
     else     if(IType == IntPatch_Restriction) { 
       nbr++;
-      Handle(IntPatch_RLine)& rlin =
-       *((Handle(IntPatch_RLine) *)&line);
+      Handle(IntPatch_RLine) rlin (Handle(IntPatch_RLine)::DownCast (line));
       if(rlin->IsArcOnS1()) nbr1++;
       if(rlin->IsArcOnS2()) nbr2++;
     }
     else     if(IType == IntPatch_Analytic) nba++;
-    else     { nbg++; 
-              if(IType == IntPatch_Lin) nbgl++;
-              else if(IType == IntPatch_Circle) nbgc++;
-              else if(IType == IntPatch_Parabola) nbgp++;
-              else if(IType == IntPatch_Hyperbola) nbgh++;
-              else if(IType == IntPatch_Ellipse) nbge++;
-            }
+    else     { 
+      nbg++; 
+      if(IType == IntPatch_Lin) nbgl++;
+      else if(IType == IntPatch_Circle) nbgc++;
+      else if(IType == IntPatch_Parabola) nbgp++;
+      else if(IType == IntPatch_Hyperbola) nbgh++;
+      else if(IType == IntPatch_Ellipse) nbge++;
+    }
   }
   
   
   printf("\nDUMP_INT:Lines:%2d Wlin:%2d Restr:%2d(On1:%2d On2:%2d) Ana:%2d Geom:%2d(L:%2d C:%2d E:%2d H:%2d P:%2d)",
-        nbl,nbw,nbr,nbr1,nbr2,nba,nbg,nbgl,nbgc,nbge,nbgh,nbgp);
+         nbl,nbw,nbr,nbr1,nbr2,nba,nbg,nbgl,nbgc,nbge,nbgh,nbgp);
   
   IntPatch_LineConstructor LineConstructor(2);
   
@@ -1596,49 +1734,45 @@ void IntPatch_Intersection::Dump(const Standard_Integer ,
       nbllc++;
       const Handle(IntPatch_Line)& LineK = LineConstructor.Line(k);
       if (LineK->ArcType() == IntPatch_Analytic) { 
-       Handle(IntPatch_ALine)& alin =
-         *((Handle(IntPatch_ALine) *)&LineK);
-       nbvtx=alin->NbVertex();
-       nbva+=nbvtx;    nba++;
-       for(v=1;v<=nbvtx;v++) { 
-         IntPatch_Intersection__MAJ_R(R1,R2,NR1,NR2,nbR1,nbR2,alin->Vertex(v));
-       }
+        Handle(IntPatch_ALine) alin (Handle(IntPatch_ALine)::DownCast (LineK));
+        nbvtx=alin->NbVertex();
+        nbva+=nbvtx;        nba++;
+        for(v=1;v<=nbvtx;v++) { 
+          IntPatch_Intersection__MAJ_R(R1,R2,NR1,NR2,nbR1,nbR2,alin->Vertex(v));
+        }
       }
       else if (LineK->ArcType() == IntPatch_Restriction) {
-       Handle(IntPatch_RLine)& rlin =
-         *((Handle(IntPatch_RLine) *)&LineK);
-       nbvtx=rlin->NbVertex();
-       nbvr+=nbvtx;    nbr++;
-       for(v=1;v<=nbvtx;v++) { 
-         IntPatch_Intersection__MAJ_R(R1,R2,NR1,NR2,nbR1,nbR2,rlin->Vertex(v));
-       }
+        Handle(IntPatch_RLine) rlin (Handle(IntPatch_RLine)::DownCast (LineK));
+        nbvtx=rlin->NbVertex();
+        nbvr+=nbvtx;        nbr++;
+        for(v=1;v<=nbvtx;v++) { 
+          IntPatch_Intersection__MAJ_R(R1,R2,NR1,NR2,nbR1,nbR2,rlin->Vertex(v));
+        }
       }
       else if (LineK->ArcType() == IntPatch_Walking) {
-       Handle(IntPatch_WLine)& wlin =
-         *((Handle(IntPatch_WLine) *)&LineK);
-       nbvtx=wlin->NbVertex();
-       nbvw+=nbvtx;    nbw++;
-       for(v=1;v<=nbvtx;v++) { 
-         IntPatch_Intersection__MAJ_R(R1,R2,NR1,NR2,nbR1,nbR2,wlin->Vertex(v));
-       }
+        Handle(IntPatch_WLine) wlin (Handle(IntPatch_WLine)::DownCast (LineK));
+        nbvtx=wlin->NbVertex();
+        nbvw+=nbvtx;        nbw++;
+        for(v=1;v<=nbvtx;v++) { 
+          IntPatch_Intersection__MAJ_R(R1,R2,NR1,NR2,nbR1,nbR2,wlin->Vertex(v));
+        }
       }
       else { 
-       Handle(IntPatch_GLine)& glin =
-         *((Handle(IntPatch_GLine) *)&LineK);
-       nbvtx=glin->NbVertex();
-       nbvg+=nbvtx;    nbg++;
-       for(v=1;v<=nbvtx;v++) { 
-         IntPatch_Intersection__MAJ_R(R1,R2,NR1,NR2,nbR1,nbR2,glin->Vertex(v));
-       }
+        Handle(IntPatch_GLine) glin (Handle(IntPatch_GLine)::DownCast (LineK));
+        nbvtx=glin->NbVertex();
+        nbvg+=nbvtx;        nbg++;
+        for(v=1;v<=nbvtx;v++) { 
+          IntPatch_Intersection__MAJ_R(R1,R2,NR1,NR2,nbR1,nbR2,glin->Vertex(v));
+        }
       }
     }
   }
   printf("\nDUMP_LC :Lines:%2d WLin:%2d Restr:%2d Ana:%2d Geom:%2d",
-        nbllc,nbw,nbr,nba,nbg);
+         nbllc,nbw,nbr,nba,nbg);
   printf("\nDUMP_LC :vtx          :%2d     r:%2d    :%2d     :%2d",
-        nbvw,nbvr,nbva,nbvg);
-
+         nbvw,nbvr,nbva,nbvg);
 
+  printf("\n");
 
-   printf("\n");
+#endif 
 }