0030100: Modeling Algorithms - ShapeUpgrade_UnifySameDomain is unable to unify faces...
[occt.git] / src / IntPatch / IntPatch_Intersection.cxx
index c9a02f4..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>
-
-#define DEBUG 0 
-static const Standard_Integer aNbPointsInALine = 200;
-
-//=======================================================================
-//function : IsSeamOrBound
-//purpose  : Returns TRUE if point thePt1 lies in seam-edge
-//            (if it exists) or surface boundaries;
-//=======================================================================
-static Standard_Boolean IsSeamOrBound(const IntSurf_PntOn2S& thePt1,
-                                      const Standard_Real theU1Period,
-                                      const Standard_Real theU2Period,
-                                      const Standard_Real theV1Period,
-                                      const Standard_Real theV2Period,
-                                      const Standard_Real theUfSurf1,
-                                      const Standard_Real theUlSurf1,
-                                      const Standard_Real theVfSurf1,
-                                      const Standard_Real theVlSurf1,
-                                      const Standard_Real theUfSurf2,
-                                      const Standard_Real theUlSurf2,
-                                      const Standard_Real theVfSurf2,
-                                      const Standard_Real theVlSurf2)
-{
-  Standard_Real aU11 = 0.0, aU12 = 0.0, aV11 = 0.0, aV12 = 0.0;
-  thePt1.Parameters(aU11, aV11, aU12, aV12);
-
-  Standard_Boolean aCond = Standard_False;
-  aCond = aCond || (!IsEqual(theU1Period, 0.0) &&
-                    IsEqual(fmod(aU11, theU1Period), 0.0));
-
-  aCond = aCond || (!IsEqual(theU2Period, 0.0) &&
-                    IsEqual(fmod(aU12, theU2Period), 0.0));
-
-  aCond = aCond || (!IsEqual(theV1Period, 0.0) &&
-                    IsEqual(fmod(aV11, theV1Period), 0.0));
-
-  aCond = aCond || (!IsEqual(theV2Period, 0.0) &&
-                    IsEqual(fmod(aV12, theV2Period), 0.0));
-
-  return  aCond ||
-          IsEqual(aU11, theUfSurf1) || IsEqual(aU11, theUlSurf1) ||
-          IsEqual(aU12, theUfSurf2) || IsEqual(aU12, theUlSurf2) ||
-          IsEqual(aV11, theVfSurf1) || IsEqual(aV11, theVlSurf1) ||
-          IsEqual(aV12, theVfSurf2) || IsEqual(aV12, theVlSurf2);
-}
-
-//=======================================================================
-//function : JoinWLines
-//purpose  : joins all WLines from theSlin to one if it is possible and
-//            records the result into theSlin again.
-//            Lines will be kept to be splitted if:
-//              a) they are separated (has no common points);
-//              b) resulted line (after joining) go through
-//                 seam-edges or surface boundaries.
-//
-//          In addition, if points in theSPnt lies at least in one of 
-//          the line in theSlin, this point will be deleted.
-//=======================================================================
-static void JoinWLines(IntPatch_SequenceOfLine& theSlin,
-                IntPatch_SequenceOfPoint& theSPnt,
-                const Standard_Real theTol3D,
-                const Standard_Real theU1Period,
-                const Standard_Real theU2Period,
-                const Standard_Real theV1Period,
-                const Standard_Real theV2Period,
-                const Standard_Real theUfSurf1,
-                const Standard_Real theUlSurf1,
-                const Standard_Real theVfSurf1,
-                const Standard_Real theVlSurf1,
-                const Standard_Real theUfSurf2,
-                const Standard_Real theUlSurf2,
-                const Standard_Real theVfSurf2,
-                const Standard_Real theVlSurf2)
-{
-  if(theSlin.Length() == 0)
-    return;
-
-  for(Standard_Integer aNumOfLine1 = 1; aNumOfLine1 <= theSlin.Length(); aNumOfLine1++)
-  {
-    const Handle(IntPatch_WLine)& aWLine1 = Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNumOfLine1));
-
-    if(aWLine1.IsNull())
-    {//We must have failed to join not-point-lines
-      return;
-    }
-
-    const Standard_Integer aNbPntsWL1 = aWLine1->NbPnts();
-    const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1);
-    const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aNbPntsWL1);
-
-    for(Standard_Integer aNPt = 1; aNPt <= theSPnt.Length(); aNPt++)
-    {
-      const IntSurf_PntOn2S aPntCur = theSPnt.Value(aNPt).PntOn2S();
-
-      if( aPntCur.IsSame(aPntFWL1, Precision::Confusion()) ||
-        aPntCur.IsSame(aPntLWL1, Precision::Confusion()))
-      {
-        theSPnt.Remove(aNPt);
-        aNPt--;
-      }
-    }
-
-    Standard_Boolean hasBeenRemoved = Standard_False;
-    for(Standard_Integer aNumOfLine2 = aNumOfLine1 + 1; aNumOfLine2 <= theSlin.Length(); aNumOfLine2++)
-    {
-      const Handle(IntPatch_WLine)& aWLine2 = Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNumOfLine2));
-
-      const Standard_Integer aNbPntsWL1 = aWLine1->NbPnts();
-      const Standard_Integer aNbPntsWL2 = aWLine2->NbPnts();
-
-      const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1);
-      const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aNbPntsWL1);
-
-      const IntSurf_PntOn2S& aPntFWL2 = aWLine2->Point(1);
-      const IntSurf_PntOn2S& aPntLWL2 = aWLine2->Point(aNbPntsWL2);
-
-      if(aPntFWL1.IsSame(aPntFWL2, Precision::Confusion()))
-      {
-        if(!IsSeamOrBound(aPntFWL1, theU1Period, theU2Period,
-                          theV1Period, theV2Period, theUfSurf1, theUlSurf1,
-                          theVfSurf1, theVlSurf1, theUfSurf2, theUlSurf2,
-                          theVfSurf2, theVlSurf2))
-        {
-          aWLine1->ClearVertexes();
-          for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
-          {
-            const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
-            aWLine1->Curve()->InsertBefore(1, aPt);
-          }
-
-          aWLine1->ComputeVertexParameters(theTol3D);
-
-          theSlin.Remove(aNumOfLine2);
-          aNumOfLine2--;
-          hasBeenRemoved = Standard_True;
-
-          continue;
-        }
-      }
-
-      if(aPntFWL1.IsSame(aPntLWL2, Precision::Confusion()))
-      {
-        if(!IsSeamOrBound(aPntFWL1, theU1Period, theU2Period,
-                          theV1Period, theV2Period, theUfSurf1, theUlSurf1,
-                          theVfSurf1, theVlSurf1, theUfSurf2, theUlSurf2,
-                          theVfSurf2, theVlSurf2))
-        {
-          aWLine1->ClearVertexes();
-          for(Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--)
-          {
-            const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
-            aWLine1->Curve()->InsertBefore(1, aPt);
-          }
-
-          aWLine1->ComputeVertexParameters(theTol3D);
-
-          theSlin.Remove(aNumOfLine2);
-          aNumOfLine2--;
-          hasBeenRemoved = Standard_True;
-
-          continue;
-        }
-      }
-
-      if(aPntLWL1.IsSame(aPntFWL2, Precision::Confusion()))
-      {
-        if(!IsSeamOrBound(aPntLWL1, theU1Period, theU2Period,
-                          theV1Period, theV2Period, theUfSurf1, theUlSurf1,
-                          theVfSurf1, theVlSurf1, theUfSurf2, theUlSurf2,
-                          theVfSurf2, theVlSurf2))
-        {
-          aWLine1->ClearVertexes();
-          for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
-          {
-            const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
-            aWLine1->Curve()->Add(aPt);
-          }
-
-          aWLine1->ComputeVertexParameters(theTol3D);
-
-          theSlin.Remove(aNumOfLine2);
-          aNumOfLine2--;
-          hasBeenRemoved = Standard_True;
-
-          continue;
-        }
-      }
-
-      if(aPntLWL1.IsSame(aPntLWL2, Precision::Confusion()))
-      {
-        if(!IsSeamOrBound(aPntLWL1, theU1Period, theU2Period,
-                          theV1Period, theV2Period, theUfSurf1, theUlSurf1,
-                          theVfSurf1, theVlSurf1, theUfSurf2, theUlSurf2,
-                          theVfSurf2, theVlSurf2))
-        {
-          aWLine1->ClearVertexes();
-          for(Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--)
-          {
-            const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
-            aWLine1->Curve()->Add(aPt);
-          }
-
-          aWLine1->ComputeVertexParameters(theTol3D);
-
-          theSlin.Remove(aNumOfLine2);
-          aNumOfLine2--;
-          hasBeenRemoved = Standard_True;
-
-          continue;
-        }
-      }
-    }
+#include <IntPatch_ImpPrmIntersection.hxx>
+#include <IntPatch_PrmPrmIntersection.hxx>
+#include <IntPatch_WLine.hxx>
+#include <IntPatch_WLineTool.hxx>
 
-    if(hasBeenRemoved)
-      aNumOfLine1--;
-  }
-}
+#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
@@ -346,15 +138,39 @@ 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:
+    {
+      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,TolArc,TolTang,myFleche,myUVMaxStep);
+      interpp.Perform(S1,D1,TolTang,TolArc,myFleche,myUVMaxStep);
       if (interpp.IsDone())
       {
         done = Standard_True;
@@ -518,7 +334,7 @@ static void FUN_GetUiso(const Handle(Geom_Surface)& GS,
   }
   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);
@@ -588,7 +404,7 @@ static void FUN_GetViso(const Handle(Geom_Surface)& GS,
   }
   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);
@@ -663,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]);
     }
@@ -673,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]);
     }
@@ -684,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]);
     }
@@ -694,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]);
     }
@@ -759,10 +575,8 @@ 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 )
   {
@@ -864,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);
   }
@@ -926,7 +740,8 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
                                     const Standard_Real TolArc,
                                     const Standard_Real TolTang,
                                     const Standard_Boolean isGeomInt,
-                                    const Standard_Boolean theIsReqToKeepRLine)
+                                    const Standard_Boolean theIsReqToKeepRLine,
+                                    const Standard_Boolean theIsReqToPostWLProc)
 {
   myTolArc = TolArc;
   myTolTang = TolTang;
@@ -1118,28 +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)
     {
-      if(theD1->DomainIsInfinite() || theD2->DomainIsInfinite())
-      {
-        GeomGeomPerfom( theS1, theD1, theS2, theD2, TolArc, 
-                        TolTang, ListOfPnts, RestrictLine,
-                        typs1, typs2, theIsReqToKeepRLine);
-      }
-      else
-      {
-        GeomGeomPerfomTrimSurf( theS1, theD1, theS2, theD2,
-                                TolArc, TolTang, ListOfPnts, RestrictLine,
-                                typs1, typs2, theIsReqToKeepRLine);
-      }
+      GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang,
+                     ListOfPnts, typs1, typs2, theIsReqToKeepRLine);
     }
     else
     {
       ParamParamPerfom(theS1, theD1, theS2, theD2, 
-              TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
+              TolArc, TolTang, ListOfPnts, typs1, typs2);
     }
   }
 
@@ -1152,12 +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);
+                        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);
   }
 }
 
@@ -1172,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;
@@ -1245,7 +1072,9 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
       bToCheck = aTor1.MajorRadius() > aTor1.MinorRadius();
       if (typs1 == typs2) {
         const gp_Torus aTor2 = aGeomSurf->Torus();
-        bToCheck = aTor2.MajorRadius() > aTor2.MinorRadius();
+        bToCheck = (bToCheck && (aTor2.MajorRadius() > aTor2.MinorRadius())) ||
+                   (Abs(aTor1.MajorRadius() - aTor2.MajorRadius()) < TolTang &&
+                    Abs(aTor1.MinorRadius() - aTor2.MinorRadius()) < TolTang);
       }
       //
       if (aCTType == GeomAbs_Torus) {
@@ -1354,7 +1183,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
   if(!isGeomInt)
   {
     ParamParamPerfom(theS1, theD1, theS2, theD2, 
-                TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
+                TolArc, TolTang, ListOfPnts, typs1, typs2);
   }
   else if(ts1 != ts2)
   {
@@ -1363,20 +1192,35 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
   else if (ts1 == 0)
   {
     ParamParamPerfom(theS1, theD1, theS2, theD2,
-                TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
+                TolArc, TolTang, ListOfPnts, typs1, typs2);
   }
   else if(ts1 == 1)
   {
-    if(theD1->DomainIsInfinite() || theD2->DomainIsInfinite())
-    {
-      GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc, 
-                      TolTang, ListOfPnts, RestrictLine, typs1, typs2);
-    }
-    else
-    {
-      GeomGeomPerfomTrimSurf(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);
   }
 }
 
@@ -1391,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)
 {
@@ -1401,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()))
   {
@@ -1417,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
     {
@@ -1427,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
@@ -1450,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;
@@ -1466,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
 
@@ -1501,101 +1344,123 @@ 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, theIsReqToKeepRLine);
-  const Standard_Boolean anIS = interii.IsDone();
-  if (anIS)
+
+  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);
+  }
 }
 
 //=======================================================================
@@ -1634,8 +1499,8 @@ void IntPatch_Intersection::
         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;
@@ -1682,80 +1547,6 @@ void IntPatch_Intersection::
   }
 }
 
-//=======================================================================
-//function : GeomGeomPerfomTrimSurf
-//purpose  : This function returns ready walking-line (which is not need
-//            in convertation) as an intersection line between two
-//            trimmed surfaces.
-//=======================================================================
-void IntPatch_Intersection::
-  GeomGeomPerfomTrimSurf( const Handle(Adaptor3d_HSurface)& theS1,
-                          const Handle(Adaptor3d_TopolTool)& theD1,
-                          const Handle(Adaptor3d_HSurface)& theS2,
-                          const Handle(Adaptor3d_TopolTool)& theD2,
-                          const Standard_Real theTolArc,
-                          const Standard_Real theTolTang,
-                          IntSurf_ListOfPntOn2S& theListOfPnts,
-                          const Standard_Boolean RestrictLine,
-                          const GeomAbs_SurfaceType theTyps1,
-                          const GeomAbs_SurfaceType theTyps2,
-                          const Standard_Boolean theIsReqToKeepRLine)
-{
-  IntSurf_Quadric Quad1,Quad2;
-
-  if((theTyps1 == GeomAbs_Cylinder) && (theTyps2 == GeomAbs_Cylinder))
-  {
-    IntPatch_ImpImpIntersection anInt;
-    anInt.Perform(theS1, theD1, theS2, theD2, myTolArc,
-                  myTolTang, Standard_True, theIsReqToKeepRLine);
-
-    done = anInt.IsDone();
-
-    if(done)
-    {
-      empt = anInt.IsEmpty();
-      if (!empt)
-      {
-        tgte = anInt.TangentFaces();
-        if (tgte)
-          oppo = anInt.OppositeFaces();
-
-        const Standard_Integer aNbLin = anInt.NbLines();
-        const Standard_Integer aNbPts = anInt.NbPnts();
-
-        for(Standard_Integer aLID = 1; aLID <= aNbLin; aLID++)
-        {
-          const Handle(IntPatch_Line)& aLine = anInt.Line(aLID);
-          slin.Append(aLine);
-        }
-
-        for(Standard_Integer aPID = 1; aPID <= aNbPts; aPID++)
-        {
-          const IntPatch_Point& aPoint = anInt.Point(aPID);
-          spnt.Append(aPoint);
-        }
-
-        JoinWLines( slin, spnt, theTolTang,
-                    theS1->IsUPeriodic()? theS1->UPeriod() : 0.0,
-                    theS2->IsUPeriodic()? theS2->UPeriod() : 0.0,
-                    theS1->IsVPeriodic()? theS1->VPeriod() : 0.0,
-                    theS2->IsVPeriodic()? theS2->VPeriod() : 0.0,
-                    theS1->FirstUParameter(), theS1->LastUParameter(),
-                    theS1->FirstVParameter(), theS1->LastVParameter(),
-                    theS2->FirstUParameter(), theS2->LastUParameter(),
-                    theS2->FirstVParameter(), theS2->LastVParameter());
-      }
-    }
-  }
-  else
-  {
-    GeomGeomPerfom(theS1, theD1, theS2, theD2,
-            theTolArc, theTolTang, theListOfPnts,
-            RestrictLine, theTyps1, theTyps2, theIsReqToKeepRLine);
-  }
-}
-
-
 void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
                                     const Handle(Adaptor3d_TopolTool)& D1,
                                     const Handle(Adaptor3d_HSurface)&  S2,
@@ -1812,7 +1603,7 @@ 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;
@@ -1823,31 +1614,39 @@ 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 <Adaptor2d_HCurve2d.hxx>
-#include <Geom_Curve.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) *,
+
+#ifdef DUMPOFIntPatch_Intersection
+
+void IntPatch_Intersection__MAJ_R(Handle(Adaptor2d_HCurve2d) *R1,
                                   Handle(Adaptor2d_HCurve2d) *,
+                                  int *NR1,
                                   int *,
-                                  int *,
+                                  Standard_Integer nbR1,
                                   Standard_Integer ,
-                                  Standard_Integer ,
-                                  const IntPatch_Point& )
+                                  const IntPatch_Point& VTX)
 { 
-  /*
+  
   if(VTX.IsOnDomS1()) { 
     
     //-- long unsigned ptr= *((long unsigned *)(((Handle(Standard_Transient) *)(&(VTX.ArcOnS1())))));
@@ -1861,18 +1660,17 @@ void IntPatch_Intersection__MAJ_R(Handle(Adaptor2d_HCurve2d) *,
     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 
   //--
@@ -1884,14 +1682,14 @@ void IntPatch_Intersection::Dump(const Standard_Integer ,
     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++) { 
@@ -1900,8 +1698,7 @@ 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++;
     }
@@ -1937,8 +1734,7 @@ 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);
+        Handle(IntPatch_ALine) alin (Handle(IntPatch_ALine)::DownCast (LineK));
         nbvtx=alin->NbVertex();
         nbva+=nbvtx;        nba++;
         for(v=1;v<=nbvtx;v++) { 
@@ -1946,8 +1742,7 @@ void IntPatch_Intersection::Dump(const Standard_Integer ,
         }
       }
       else if (LineK->ArcType() == IntPatch_Restriction) {
-        Handle(IntPatch_RLine)& rlin =
-          *((Handle(IntPatch_RLine) *)&LineK);
+        Handle(IntPatch_RLine) rlin (Handle(IntPatch_RLine)::DownCast (LineK));
         nbvtx=rlin->NbVertex();
         nbvr+=nbvtx;        nbr++;
         for(v=1;v<=nbvtx;v++) { 
@@ -1955,8 +1750,7 @@ void IntPatch_Intersection::Dump(const Standard_Integer ,
         }
       }
       else if (LineK->ArcType() == IntPatch_Walking) {
-        Handle(IntPatch_WLine)& wlin =
-          *((Handle(IntPatch_WLine) *)&LineK);
+        Handle(IntPatch_WLine) wlin (Handle(IntPatch_WLine)::DownCast (LineK));
         nbvtx=wlin->NbVertex();
         nbvw+=nbvtx;        nbw++;
         for(v=1;v<=nbvtx;v++) { 
@@ -1964,8 +1758,7 @@ void IntPatch_Intersection::Dump(const Standard_Integer ,
         }
       }
       else { 
-        Handle(IntPatch_GLine)& glin =
-          *((Handle(IntPatch_GLine) *)&LineK);
+        Handle(IntPatch_GLine) glin (Handle(IntPatch_GLine)::DownCast (LineK));
         nbvtx=glin->NbVertex();
         nbvg+=nbvtx;        nbg++;
         for(v=1;v<=nbvtx;v++) { 
@@ -1979,7 +1772,7 @@ void IntPatch_Intersection::Dump(const Standard_Integer ,
   printf("\nDUMP_LC :vtx          :%2d     r:%2d    :%2d     :%2d",
          nbvw,nbvr,nbva,nbvg);
 
+  printf("\n");
 
-
-   printf("\n");
+#endif 
 }