0026621: Boolean Cut does not work on two solids
[occt.git] / src / IntPatch / IntPatch_PrmPrmIntersection.cxx
index 4c3a6da..c68e8d5 100644 (file)
 // modified by Edward AGAPOV (eap) Tue Jan 22 12:29:55 2002
 // modified by Oleg FEDYAED  (ofv) Fri Nov 29 16:08:02 2002
 
-#include <IntPatch_PrmPrmIntersection.ixx>
-
-#include <IntPatch_TheInterfPolyhedron.hxx>
-#include <IntPatch_ThePWalkingInter.hxx>
-#include <IntPatch_WLine.hxx>
-#include <IntPatch_RstInt.hxx>
-
-#include <IntPatch_Line.hxx>
-
-#include <Handle_IntSurf_LineOn2S.hxx>
-#include <IntSurf_PntOn2S.hxx>
-#include <IntSurf_LineOn2S.hxx>
-#include <TColStd_Array1OfReal.hxx>
+#include <Adaptor3d_HSurface.hxx>
+#include <Adaptor3d_TopolTool.hxx>
+#include <gp_Dir.hxx>
+#include <gp_Pnt.hxx>
 #include <Intf_PIType.hxx>
 #include <Intf_SectionLine.hxx>
-#include <Intf_TangentZone.hxx>
 #include <Intf_SectionPoint.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Dir.hxx>
+#include <Intf_TangentZone.hxx>
+#include <IntPatch_InterferencePolyhedron.hxx>
+#include <IntPatch_Line.hxx>
+#include <IntPatch_Polyhedron.hxx>
+#include <IntPatch_PrmPrmIntersection.hxx>
+#include <IntPatch_PrmPrmIntersection_T3Bits.hxx>
+#include <IntPatch_RstInt.hxx>
+#include <IntPatch_WLine.hxx>
 #include <IntPolyh_Intersection.hxx>
-
-#include <TColStd_SequenceOfInteger.hxx>
+#include <IntSurf_LineOn2S.hxx>
 #include <IntSurf_ListIteratorOfListOfPntOn2S.hxx>
+#include <IntSurf_PntOn2S.hxx>
+#include <IntWalk_PWalking.hxx>
+#include <Standard_OutOfRange.hxx>
+#include <StdFail_NotDone.hxx>
+#include <TColStd_Array1OfReal.hxx>
 #include <TColStd_HArray1OfReal.hxx>
+#include <TColStd_SequenceOfInteger.hxx>
 
 static void SectionPointToParameters(const Intf_SectionPoint& Sp,
                                      const IntPatch_Polyhedron& Surf1,
@@ -69,6 +70,228 @@ static void AddWLine(IntPatch_SequenceOfLine      &theLines,
                      const Handle(IntPatch_WLine) &theWLine,
                      const Standard_Real           Deflection);
 
+static void SeveralWlinesProcessing(const Handle(Adaptor3d_HSurface)& theSurf1,
+                                    const Handle(Adaptor3d_HSurface)& theSurf2,
+                                    const IntPatch_SequenceOfLine& theSLin,
+                                    const Standard_Real* const thePeriodsArr,
+                                    const IntSurf_TypeTrans theTrans1,
+                                    const IntSurf_TypeTrans theTrans2,
+                                    const Standard_Real theTol,
+                                    Handle(IntPatch_WLine)& theWLline)
+{
+  if(theSLin.Length() == 0)
+    return;
+
+  Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
+
+  const Standard_Real aTol2D = 1.e-4;
+  Standard_Integer cnbV = theWLline->NbVertex();
+  Standard_Integer ciV;
+  for( ciV = 1; ciV <= cnbV; ciV++ )
+  {
+    Standard_Real pntDMin = 1.e+100;
+    Standard_Integer VDMin = 0;
+    Standard_Integer WLDMin = 0;
+    gp_Pnt cPV = theWLline->Vertex(ciV).Value();
+    theWLline->Vertex(ciV).Parameters(aU1, aV1, aU2, aV2);
+    const gp_Pnt2d aPCS1(aU1, aV1), aPCS2(aU2, aV2);
+    Standard_Integer iL;
+    for( iL = 1; iL <= theSLin.Length(); iL++)
+    {
+      const Handle(IntPatch_Line)& aSLine = theSLin.Value(iL);
+      IntPatch_IType aType = aSLine->ArcType();
+      if( aType != IntPatch_Walking)
+        continue;
+      const Handle(IntPatch_WLine) aWLine = Handle(IntPatch_WLine)::DownCast(aSLine);
+      Standard_Integer tnbV = aWLine->NbVertex();
+      Standard_Integer tiV;
+      for( tiV = 1; tiV <= tnbV; tiV++ )
+      {
+        gp_Pnt tPV = aWLine->Vertex(tiV).Value();
+
+        aWLine->Vertex(tiV).Parameters(aU1, aV1, aU2, aV2);
+        const gp_Pnt2d aPTS1(aU1, aV1), aPTS2(aU2, aV2);
+
+        Standard_Real tDistance = cPV.Distance(tPV);
+        Standard_Real uRs1 = theSurf1->Surface().UResolution(tDistance);
+        Standard_Real vRs1 = theSurf1->Surface().VResolution(tDistance);
+        Standard_Real uRs2 = theSurf2->Surface().UResolution(tDistance);
+        Standard_Real vRs2 = theSurf2->Surface().VResolution(tDistance);
+        Standard_Real RmaxS1 = Max(uRs1,vRs1);
+        Standard_Real RmaxS2 = Max(uRs2,vRs2);
+        if((aPCS1.SquareDistance(aPTS1) < RmaxS1*RmaxS1) && (aPCS2.SquareDistance(aPTS2) < RmaxS2*RmaxS2))
+        {
+          if(RmaxS1 < aTol2D && RmaxS2 < aTol2D)
+          {
+            if( pntDMin > tDistance && tDistance > 1.e-9)
+            {
+              pntDMin = tDistance;
+              VDMin = tiV;
+              WLDMin = iL;
+            }
+          }
+        }
+      }
+    }
+
+    if( VDMin != 0 )
+    {
+      const Handle(IntPatch_Line)& aSLine = theSLin.Value(WLDMin);
+      const Handle(IntPatch_WLine) aWLine = Handle(IntPatch_WLine)::DownCast(aSLine);
+      Standard_Integer tiVpar = (Standard_Integer)aWLine->Vertex(VDMin).ParameterOnLine();
+      Standard_Integer ciVpar = (Standard_Integer)theWLline->Vertex(ciV).ParameterOnLine();
+      Standard_Real u11 = 0., u12 = 0., v11 = 0., v12 = 0.;
+      Standard_Real u21 = 0., u22 = 0., v21 = 0., v22 = 0.;
+      theWLline->Point(ciVpar).Parameters(u11,v11,u12,v12);
+      aWLine->Point(tiVpar).Parameters(u21,v21,u22,v22);
+
+      Handle(IntSurf_LineOn2S) newL2s = new IntSurf_LineOn2S();
+      IntSurf_PntOn2S replacePnt = aWLine->Point(tiVpar);
+      Standard_Integer cNbP = theWLline->NbPnts();
+
+      TColStd_SequenceOfInteger VPold;
+      Standard_Integer iPo;
+      for( iPo = 1; iPo <= cnbV; iPo++ )
+      {
+        Standard_Real Po = theWLline->Vertex(iPo).ParameterOnLine();
+        Standard_Integer IPo = (Standard_Integer) Po;
+        VPold.Append(IPo);
+      }
+
+      Standard_Boolean removeNext = Standard_False;
+      Standard_Boolean removePrev = Standard_False;
+      if( ciV == 1)
+      {
+        Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
+        if(dPar > 10)
+        {
+          removeNext = Standard_True;
+          for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
+            VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
+        }
+      }
+      else if( ciV == cnbV)
+      {
+        Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
+        if(dPar > 10)
+        {
+          removePrev = Standard_True;
+          VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
+        }
+      }
+      else
+      {
+        Standard_Integer dParMi = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
+        Standard_Integer dParMa = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
+        if(dParMi > 10)
+        {
+          removePrev = Standard_True;
+          VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
+        }
+
+        if(dParMa > 10)
+        {
+          removeNext = Standard_True;
+          for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
+          {
+            if(dParMi > 10)
+              VPold.SetValue(iPo, VPold.Value(iPo) - 2 );
+            else
+              VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
+          }
+        }
+        else
+        {
+          if(dParMi > 10)
+            for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
+              VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
+        } 
+      }
+
+      Standard_Integer pI = ciVpar;
+
+      Standard_Integer iP;
+      for( iP = 1; iP <= cNbP; iP++)
+      {
+        if( pI == iP )
+        {
+          IntSurf_PntOn2S newPnt = MakeNewPoint(replacePnt, theWLline->Point(iP), thePeriodsArr);
+          newL2s->Add(newPnt);
+        }
+        else if(removeNext && iP == (pI + 1))
+          continue;
+        else if(removePrev && iP == (pI - 1))
+          continue;
+        else
+          newL2s->Add(theWLline->Point(iP));
+      }
+
+      IntPatch_Point newVtx;
+      gp_Pnt Pnt3dV = aWLine->Vertex(VDMin).Value();
+      newVtx.SetValue(Pnt3dV,theTol,Standard_False);
+      newVtx.SetParameters(u21,v21,u22,v22);
+      newVtx.SetParameter(VPold.Value(ciV));
+
+      Handle(IntPatch_WLine) NWLine = new IntPatch_WLine(newL2s,Standard_False,theTrans1,theTrans2);
+
+      Standard_Integer iV;
+      for( iV = 1; iV <= cnbV; iV++ )
+      {
+        if( iV == ciV )
+          NWLine->AddVertex(newVtx);
+        else
+        {
+          IntPatch_Point theVtx = theWLline->Vertex(iV);
+          theVtx.SetParameter(VPold.Value(iV));
+          NWLine->AddVertex(theVtx);
+        }
+      }
+
+      theWLline = NWLine;
+    }//if( VDMin != 0 )
+  }//for( ciV = 1; ciV <= cnbV; ciV++ )
+}
+
+//=======================================================================
+//function : DublicateOfLinesProcessing
+//purpose  : Decides, if rejecting current line is necessary
+//=======================================================================
+static void DublicateOfLinesProcessing( const IntWalk_PWalking& thePW,
+                                        const Standard_Integer theWLID,
+                                        IntPatch_SequenceOfLine& theLines,
+                                        Standard_Boolean& theIsRejectReq)
+{
+  const Handle(IntPatch_WLine)& anExistWL =
+                      *((Handle(IntPatch_WLine)*)&theLines.Value(theWLID));
+  const Standard_Integer aNbPrevPoints = anExistWL->NbPnts();
+  const Standard_Integer aNbCurrPoints = thePW.NbPoints();
+
+  if(aNbPrevPoints < aNbCurrPoints)
+  {//Remove preview line
+    theLines.Remove(theWLID);
+    theIsRejectReq = Standard_False;
+  }
+  else if(aNbPrevPoints == aNbCurrPoints)
+  {
+    Standard_Real aLPrev = 0.0, aLCurr = 0.0;
+    for(Standard_Integer aNbPP = 1; aNbPP < aNbPrevPoints; aNbPP++)
+    {
+      const gp_Pnt  aP1prev(anExistWL->Point(aNbPP).Value()),
+        aP2prev(anExistWL->Point(aNbPP+1).Value());
+      const gp_Pnt  aP1curr(thePW.Value(aNbPP).Value()),
+        aP2curr(thePW.Value(aNbPP+1).Value());
+
+      aLPrev += aP1prev.Distance(aP2prev);
+      aLCurr += aP1curr.Distance(aP2curr);
+    }
+
+    if(aLPrev < aLCurr)
+    {//Remove preview line
+      theLines.Remove(theWLID);
+      theIsRejectReq = Standard_False;
+    }
+  }
+}
 
 //==================================================================================
 // function : 
@@ -144,7 +367,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
                                            const Standard_Real   Deflection,
                                            const Standard_Real   Increment)
 { 
-  IntPatch_TheInterfPolyhedron Interference(Poly1,Poly2);
+  IntPatch_InterferencePolyhedron Interference(Poly1,Poly2);
   empt = Standard_True;
   done = Standard_True;
   SLin.Clear();  
@@ -159,7 +382,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
 
   TColStd_Array1OfReal StartParams(1,4);
 
-  IntPatch_ThePWalkingInter PW( Surf1, Surf2, TolTangency, Epsilon, Deflection, Increment );
+  IntWalk_PWalking PW( Surf1, Surf2, TolTangency, Epsilon, Deflection, Increment );
 
   Standard_Real    SeuildPointLigne = 15.0 * Increment * Increment; //-- 10 est insuffisant
   Standard_Real    incidence;
@@ -314,7 +537,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
                   Point3dDebut = PW.Value(1).Value();
                   const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints());
                   Point3dFin   = PointFin.Value();
-                  for( ver = 1 ; (!RejetLigne) && (ver<= NbLigCalculee) ; ver++) { 
+                  for( ver = 1 ; ver<= NbLigCalculee ; ver++) { 
                     const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver));
 
                     // Check end point if it is on existing line.
@@ -326,12 +549,19 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
 
                     const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
                     const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts());
-                    if( Point3dDebut.Distance(verPointDebut.Value()) <= TolTangency ) { 
-                      if(Point3dFin.Distance(verPointFin.Value()) <= TolTangency)
-                        RejetLigne = Standard_True; 
+                    if( (Point3dDebut.Distance(verPointDebut.Value()) <= TolTangency) &&
+                        (Point3dFin.Distance(verPointFin.Value()) <= TolTangency))
+                    { 
+                      RejetLigne = Standard_True; 
+                      break;
                     }
                   }
 
+                  if(RejetLigne)
+                  {
+                    DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne);
+                  }
+
                   if(!RejetLigne) { 
                     // Calculation transition
                     IntSurf_TypeTrans trans1,trans2;
@@ -452,7 +682,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
               Point3dDebut = PW.Value(1).Value();
               const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints());
               Point3dFin   = PointFin.Value();
-              for(ver=1 ; (!RejetLigne) && (ver<= NbLigCalculee) ; ver++) { 
+              for(ver=1 ; ver<= NbLigCalculee ; ver++) { 
                 const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver));
 
                 // Check end point if it is on existing line.
@@ -464,14 +694,19 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
 
                 const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
                 const IntSurf_PntOn2S& verPointFin   = verwline->Point(verwline->NbPnts());
-                if(Point3dDebut.Distance(verPointDebut.Value()) < TolTangency)
+                if( (Point3dDebut.Distance(verPointDebut.Value()) < TolTangency) ||
+                    (Point3dFin.Distance(verPointFin.Value()) < TolTangency))
+                {
                   RejetLigne = Standard_True; 
-                else { 
-                  if(Point3dFin.Distance(verPointFin.Value()) < TolTangency)
-                    RejetLigne = Standard_True; 
+                  break;
                 }
               }
 
+              if(RejetLigne)
+              {
+                DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne);
+              }
+
               if(!RejetLigne) { 
                 IntSurf_TypeTrans trans1,trans2;
                 Standard_Real locu,locv;
@@ -539,7 +774,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
                                            const Standard_Real   Deflection,
                                            const Standard_Real   Increment)
 { 
-  IntPatch_TheInterfPolyhedron Interference(Poly1);
+  IntPatch_InterferencePolyhedron Interference(Poly1);
   empt = Standard_True;
   done = Standard_True;
   SLin.Clear();  
@@ -554,7 +789,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
   Standard_Real pu1,pu2,pv1,pv2;
 
   TColStd_Array1OfReal StartParams(1,4);
-  IntPatch_ThePWalkingInter PW(Surf1,Surf1,TolTangency,Epsilon,Deflection,Increment);
+  IntWalk_PWalking PW(Surf1,Surf1,TolTangency,Epsilon,Deflection,Increment);
 
   Standard_Real    SeuildPointLigne = 15.0 * Increment * Increment; //-- 10 est insuffisant
   Standard_Real    incidence;
@@ -677,18 +912,23 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
                   RejetLigne = Standard_False;
                   Point3dDebut = PW.Value(1).Value();
                   Point3dFin   = PW.Value(PW.NbPoints()).Value();
-                  for(ver=1 ; (!RejetLigne) && (ver<= NbLigCalculee) ; ver++) { 
+                  for(ver=1 ; ver<= NbLigCalculee ; ver++) { 
                     const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver));
                     const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
                     const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts());
-                    if(Point3dDebut.Distance(verPointDebut.Value()) < TolTangency)
+                    if( (Point3dDebut.Distance(verPointDebut.Value()) < TolTangency) ||
+                        (Point3dFin.Distance(verPointFin.Value()) < TolTangency)) 
+                    {
                       RejetLigne = Standard_True; 
-                    else { 
-                      if(Point3dFin.Distance(verPointFin.Value()) < TolTangency)
-                        RejetLigne = Standard_True; 
+                      break;
                     }
                   }
 
+                  if(RejetLigne)
+                  {
+                    DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne);
+                  }
+
                   if(!RejetLigne) { 
                     IntSurf_TypeTrans trans1,trans2;
                     Standard_Real locu,locv;
@@ -738,7 +978,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
                       imax++;
 
                     if(imin<imax) { 
-                      Handle_IntSurf_LineOn2S PWLine = new IntSurf_LineOn2S();
+                      Handle(IntSurf_LineOn2S) PWLine = new IntSurf_LineOn2S();
                       for(i=imin;i<=imax;i++) 
                         PWLine->Add(PW.Line()->Value(i));
 
@@ -845,18 +1085,23 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
                 RejetLigne = Standard_False;
                 Point3dDebut = PW.Value(1).Value();
                 Point3dFin   = PW.Value(PW.NbPoints()).Value();
-                for( ver = 1 ; (!RejetLigne) && (ver<= NbLigCalculee) ; ver++) { 
+                for( ver = 1 ; ver<= NbLigCalculee ; ver++) { 
                   const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver));
                   const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
                   const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts());
-                  if(Point3dDebut.Distance(verPointDebut.Value()) < TolTangency)
+                  if( (Point3dDebut.Distance(verPointDebut.Value()) < TolTangency) ||
+                      (Point3dFin.Distance(verPointFin.Value()) < TolTangency))
+                  {
                     RejetLigne = Standard_True; 
-                  else { 
-                    if(Point3dFin.Distance(verPointFin.Value()) < TolTangency)
-                      RejetLigne = Standard_True; 
+                    break;
                   }
                 }
 
+                if(RejetLigne)
+                {
+                  DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne);
+                }
+
                 if(!RejetLigne)        { 
                   IntSurf_TypeTrans trans1,trans2;
                   Standard_Real locu,locv;
@@ -906,7 +1151,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
                     imax++;
 
                   if(imin<imax) { 
-                    Handle_IntSurf_LineOn2S PWLine = new IntSurf_LineOn2S();
+                    Handle(IntSurf_LineOn2S) PWLine = new IntSurf_LineOn2S();
                     for(i=imin;i<=imax;i++)
                       PWLine->Add(PW.Line()->Value(i));
 
@@ -960,7 +1205,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
 // function : NewLine
 // purpose  : 
 //==================================================================================
-Handle_IntPatch_Line IntPatch_PrmPrmIntersection::NewLine (const Handle(Adaptor3d_HSurface)&    Surf1,
+Handle(IntPatch_Line) IntPatch_PrmPrmIntersection::NewLine (const Handle(Adaptor3d_HSurface)&    Surf1,
                                                            const Handle(Adaptor3d_HSurface)&    Surf2,
                                                            const Standard_Integer NumLine,
                                                            const Standard_Integer Low,
@@ -996,7 +1241,7 @@ Handle_IntPatch_Line IntPatch_PrmPrmIntersection::NewLine (const Handle(Adaptor3
   V2(Low) = v2;
   AC(Low) =0.0;
 
-  IntPatch_ThePWalkingInter PW(Surf1,Surf2,0.000001,0.000001,0.001,0.001);
+  IntWalk_PWalking PW(Surf1,Surf2,0.000001,0.000001,0.001,0.001);
 
   Standard_Integer i;
   for(i=Low+1; i<=High; i++)
@@ -1317,8 +1562,102 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
   Periods[3] = (Surf2->IsVPeriodic())? Surf2->VPeriod() : 0.;
 
   IntSurf_ListIteratorOfListOfPntOn2S IterLOP1(LOfPnts);
+  if (Surf1->IsUClosed() || Surf1->IsVClosed() ||
+      Surf2->IsUClosed() || Surf2->IsVClosed())
+  {
+    Standard_Real TolPar = Precision::PConfusion();
+    IntSurf_ListOfPntOn2S AdditionalPnts;
+    Standard_Real NewU1, NewV1, NewU2, NewV2;
+    for(; IterLOP1.More(); IterLOP1.Next())
+    {
+      IntSurf_PntOn2S Pnt = IterLOP1.Value();
+      Pnt.Parameters(U1, V1, U2, V2);
+      IntSurf_PntOn2S NewPnt;
+      if (Surf1->IsUClosed())
+      {
+        if (Abs(U1 - Surf1->FirstUParameter()) <= TolPar)
+        {
+          NewU1 = Surf1->LastUParameter();
+          NewPnt.SetValue( NewU1, V1, U2, V2 );
+          AdditionalPnts.Append(NewPnt);
+        }
+        else if (Abs(U1 - Surf1->LastUParameter()) <= TolPar)
+        {
+          NewU1 = Surf1->FirstUParameter();
+          NewPnt.SetValue( NewU1, V1, U2, V2 );
+          AdditionalPnts.Append(NewPnt);
+        }
+      }
+      if (Surf1->IsVClosed())
+      {
+        if (Abs(V1 - Surf1->FirstVParameter()) <= TolPar)
+        {
+          NewV1 = Surf1->LastVParameter();
+          NewPnt.SetValue( U1, NewV1, U2, V2 );
+          AdditionalPnts.Append(NewPnt);
+        }
+        else if (Abs(V1 - Surf1->LastVParameter()) <= TolPar)
+        {
+          NewV1 = Surf1->FirstVParameter();
+          NewPnt.SetValue( U1, NewV1, U2, V2 );
+          AdditionalPnts.Append(NewPnt);
+        }
+      }
+      if (Surf2->IsUClosed())
+      {
+        if (Abs(U2 - Surf2->FirstUParameter()) <= TolPar)
+        {
+          NewU2 = Surf2->LastUParameter();
+          NewPnt.SetValue( U1, V1, NewU2, V2);
+          AdditionalPnts.Append(NewPnt);
+        }
+        else if (Abs(U2 - Surf2->LastUParameter()) <= TolPar)
+        {
+          NewU2 = Surf2->FirstUParameter();
+          NewPnt.SetValue( U1, V1, NewU2, V2);
+          AdditionalPnts.Append(NewPnt);
+        }
+      }
+      if (Surf2->IsVClosed())
+      {
+        if (Abs(V2 - Surf2->FirstVParameter()) <= TolPar)
+        {
+          NewV2 = Surf2->LastVParameter();
+          NewPnt.SetValue( U1, V1, U2, NewV2 );
+          AdditionalPnts.Append(NewPnt);
+        }
+        else if (Abs(V2 - Surf2->LastVParameter()) <= TolPar)
+        {
+          NewV2 = Surf2->FirstVParameter();
+          NewPnt.SetValue( U1, V1, U2, NewV2 );
+          AdditionalPnts.Append(NewPnt);
+        }
+      }
+    }
+    //Cut repeated points
+    for (IterLOP1.Initialize(LOfPnts); IterLOP1.More(); IterLOP1.Next())
+    {
+      IntSurf_PntOn2S aPnt = IterLOP1.Value();
+      aPnt.Parameters(U1, V1, U2, V2);
+      IntSurf_ListIteratorOfListOfPntOn2S iter2(AdditionalPnts);
+      while (iter2.More())
+      {
+        IntSurf_PntOn2S aNewPnt = iter2.Value();
+        aNewPnt.Parameters(NewU1, NewV1, NewU2, NewV2);
+        if (Abs(U1 - NewU1) <= TolPar &&
+            Abs(V1 - NewV1) <= TolPar &&
+            Abs(U2 - NewU2) <= TolPar &&
+            Abs(V2 - NewV2) <= TolPar)
+          AdditionalPnts.Remove(iter2);
+        else
+          iter2.Next();
+      }
+    }
+
+    LOfPnts.Append(AdditionalPnts);
+  }
 
-  for(; IterLOP1.More(); IterLOP1.Next()){
+  for(IterLOP1.Initialize(LOfPnts); IterLOP1.More(); IterLOP1.Next()){
     IntSurf_PntOn2S Pnt = IterLOP1.Value();
     Pnt.Parameters(U1, V1, U2, V2);
     if(U1>UmaxLig1) UmaxLig1=U1;
@@ -1341,7 +1680,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
   gp_Pnt Point3dDebut,Point3dFin;
 
   TColStd_Array1OfReal StartParams(1,4);
-  IntPatch_ThePWalkingInter PW(Surf1,Surf2,TolTangency,Epsilon,Deflection,Increment);  
+  IntWalk_PWalking PW(Surf1,Surf2,TolTangency,Epsilon,Deflection,Increment);  
 
   IntSurf_ListIteratorOfListOfPntOn2S IterLOP2(LOfPnts);
   for(; IterLOP2.More(); IterLOP2.Next() ){
@@ -1380,7 +1719,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
             Point3dDebut = PW.Value(1).Value();
             const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints());
             Point3dFin   = PointFin.Value();
-            for( ver = 1 ; (!RejetLigne) && (ver<= NbLigCalculee) ; ver++) { 
+            for( ver = 1 ; ver<= NbLigCalculee ; ver++) { 
               const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver));
 
               // Check end point if it is on existing line.
@@ -1392,12 +1731,19 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
 
               const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
               const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts());
-              if(Point3dDebut.Distance(verPointDebut.Value()) <= TolTangency) { 
-                if(Point3dFin.Distance(verPointFin.Value()) <= TolTangency)
-                  RejetLigne = Standard_True; 
+              if( (Point3dDebut.Distance(verPointDebut.Value()) <= TolTangency) &&
+                  (Point3dFin.Distance(verPointFin.Value()) <= TolTangency)) 
+              {
+                RejetLigne = Standard_True; 
+                break;
               }
             }
 
+            if(RejetLigne)
+            {
+              DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne);
+            }
+
             if(!RejetLigne) {
               IntSurf_TypeTrans trans1,trans2;
               Standard_Real locu,locv;
@@ -1444,144 +1790,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
                 wline->AddVertex(vtx);
               }              
 
-              Standard_Integer slinlen = SLin.Length();
-              if( slinlen > 0 ) {
-                Standard_Integer cnbV = wline->NbVertex();
-                Standard_Integer ciV;
-                for( ciV = 1; ciV <= cnbV; ciV++ ) {
-                  Standard_Real pntDMin = 1.e+100;
-                  Standard_Integer VDMin = 0;
-                  Standard_Integer WLDMin = 0;
-                  gp_Pnt cPV = wline->Vertex(ciV).Value();
-                  Standard_Integer iL;
-                  for( iL = 1; iL <= slinlen; iL++) {
-                    const Handle(IntPatch_Line)& aSLine = SLin.Value(iL);
-                    IntPatch_IType aType = aSLine->ArcType();
-                    if( aType != IntPatch_Walking)
-                      continue;
-                    const Handle(IntPatch_WLine)&  aWLine = (*((Handle(IntPatch_WLine)*)&aSLine));
-                    Standard_Integer tnbV = aWLine->NbVertex();
-                    Standard_Integer tiV;
-                    for( tiV = 1; tiV <= tnbV; tiV++ ) {
-                      gp_Pnt tPV = aWLine->Vertex(tiV).Value();
-                      Standard_Real tDistance = cPV.Distance(tPV);
-                      Standard_Real uRs1 = Surf1->Surface().UResolution(tDistance);
-                      Standard_Real vRs1 = Surf1->Surface().VResolution(tDistance);
-                      Standard_Real uRs2 = Surf2->Surface().UResolution(tDistance);
-                      Standard_Real vRs2 = Surf2->Surface().VResolution(tDistance);
-                      Standard_Real RmaxS1 = Max(uRs1,vRs1);
-                      Standard_Real RmaxS2 = Max(uRs2,vRs2);
-                      if(RmaxS1 < 1.e-4 && RmaxS2 < 1.e-4) {
-                        if( pntDMin > tDistance && tDistance > 1.e-9) {
-                          pntDMin = tDistance;
-                          VDMin = tiV;
-                          WLDMin = iL;
-                        }
-                      }
-                    }
-                  }
-
-                  if( VDMin != 0 ) {
-                    const Handle(IntPatch_Line)& aSLine = SLin.Value(WLDMin);
-                    const Handle(IntPatch_WLine)&  aWLine = (*((Handle(IntPatch_WLine)*)&aSLine));
-                    Standard_Integer tiVpar = (Standard_Integer)aWLine->Vertex(VDMin).ParameterOnLine();
-                    Standard_Integer ciVpar = (Standard_Integer)wline->Vertex(ciV).ParameterOnLine();
-                    Standard_Real u11 = 0., u12 = 0., v11 = 0., v12 = 0.;
-                    Standard_Real u21 = 0., u22 = 0., v21 = 0., v22 = 0.;
-                    wline->Point(ciVpar).Parameters(u11,v11,u12,v12);
-                    aWLine->Point(tiVpar).Parameters(u21,v21,u22,v22);
-
-                    Handle(IntSurf_LineOn2S) newL2s = new IntSurf_LineOn2S();
-                    IntSurf_PntOn2S replacePnt = aWLine->Point(tiVpar);
-                    Standard_Integer cNbP = wline->NbPnts();
-
-                    TColStd_SequenceOfInteger VPold;
-                    Standard_Integer iPo;
-                    for( iPo = 1; iPo <= cnbV; iPo++ ) {
-                      Standard_Real Po = wline->Vertex(iPo).ParameterOnLine();
-                      Standard_Integer IPo = (Standard_Integer) Po;
-                      VPold.Append(IPo);
-                    }
-
-                    Standard_Boolean removeNext = Standard_False;
-                    Standard_Boolean removePrev = Standard_False;
-                    if( ciV == 1) {
-                      Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
-                      if(dPar > 10) {
-                        removeNext = Standard_True;
-                        for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
-                          VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
-                      }
-                    }
-                    else if( ciV == cnbV) {
-                      Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
-                      if(dPar > 10) {
-                        removePrev = Standard_True;
-                        VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
-                      }
-                    }
-                    else {
-                      Standard_Integer dParMi = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
-                      Standard_Integer dParMa = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
-                      if(dParMi > 10) {
-                        removePrev = Standard_True;
-                        VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
-                      }
-                      if(dParMa > 10) {
-                        removeNext = Standard_True;
-                        for( iPo = (ciV+1); iPo <= cnbV; iPo++ ) {
-                          if(dParMi > 10)
-                            VPold.SetValue(iPo, VPold.Value(iPo) - 2 );
-                          else
-                            VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
-                        }
-                      }
-                      else {
-                        if(dParMi > 10)
-                          for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
-                            VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
-                      } 
-                    }
-                    Standard_Integer pI = (Standard_Integer) ciVpar;
-
-                    Standard_Integer iP;
-                    for( iP = 1; iP <= cNbP; iP++) {
-                      if( pI == iP )
-                      {
-                        IntSurf_PntOn2S newPnt = MakeNewPoint(replacePnt, wline->Point(iP), Periods);
-                        newL2s->Add(newPnt);
-                      }
-                      else if(removeNext && iP == (pI + 1))
-                        continue;
-                      else if(removePrev && iP == (pI - 1))
-                        continue;
-                      else
-                        newL2s->Add(wline->Point(iP));
-                    }
-
-                    IntPatch_Point newVtx;
-                    gp_Pnt Pnt3dV = aWLine->Vertex(VDMin).Value();
-                    newVtx.SetValue(Pnt3dV,TolTang,Standard_False);
-                    newVtx.SetParameters(u21,v21,u22,v22);
-                    newVtx.SetParameter(VPold.Value(ciV));
-
-                    Handle(IntPatch_WLine) NWLine = new IntPatch_WLine(newL2s,Standard_False,trans1,trans2);
-
-                    Standard_Integer iV;
-                    for( iV = 1; iV <= cnbV; iV++ ) {
-                      if( iV == ciV )
-                        NWLine->AddVertex(newVtx);
-                      else {
-                        IntPatch_Point theVtx = wline->Vertex(iV);
-                        theVtx.SetParameter(VPold.Value(iV));
-                        NWLine->AddVertex(theVtx);
-                      }
-                    }
-
-                    wline = NWLine;
-                  }
-                }
-              }// SLin.Length > 0
+              SeveralWlinesProcessing(Surf1, Surf2, SLin, Periods, trans1, trans2, TolTang, wline);
 
               AddWLine(SLin, wline, Deflection);
               empt = Standard_False;
@@ -1634,13 +1843,13 @@ void IntPatch_PrmPrmIntersection::Perform(const Handle(Adaptor3d_HSurface)&    S
 
   //    Standard_Real nIncrement=Increment;
   //    if(MaxOscill>10) { 
-  //  #ifdef DEB 
+  //  #ifdef OCCT_DEBUG
   //      cout<<"\n IntPatch_PrmPrmIntersection.gxx : Increment:"<<Increment<<" -> "<<Increment/(0.5*MaxOscill)<<endl;
   //  #endif
   //      nIncrement/=0.5*MaxOscill;
   //    }
 
-  IntPatch_ThePWalkingInter PW(Surf1,Surf2,
+  IntWalk_PWalking PW(Surf1,Surf2,
     TolTangency,
     Epsilon,
     Deflection,
@@ -1965,7 +2174,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
     gp_Pnt Point3dDebut,Point3dFin;
 
     TColStd_Array1OfReal StartParams(1,4);
-    IntPatch_ThePWalkingInter PW(Surf1,Surf2,TolTangency,Epsilon,Deflection,Increment);
+    IntWalk_PWalking PW(Surf1,Surf2,TolTangency,Epsilon,Deflection,Increment);
 
     if(nbLigSec>=1)
     {
@@ -2198,6 +2407,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
                             //modified by NIZNHY-PKV Tue May 10 11:08:13 2011t
 
                             RejectLine = Standard_True;
+                            ver--;
                             break;
                           }
                         }//for(m=1; m<iPWNbPoints; ++m){
@@ -2205,6 +2415,11 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
                     }// for( ver = 1 ; (!RejetLigne) && (ver<= NbLigCalculee) ; ver++) { 
                     //
 
+                    if(RejectLine)
+                    {
+                      DublicateOfLinesProcessing(PW, ver, SLin, RejectLine);
+                    }
+
                     if(!RejectLine)
                     {
                       IntSurf_TypeTrans trans1,trans2;
@@ -2255,166 +2470,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
 
                       lignetrouvee = Standard_True;
 
-                      Standard_Integer slinlen = SLin.Length();
-                      if( slinlen > 0 )
-                      {
-                        Standard_Integer cnbV = wline->NbVertex();
-                        Standard_Integer ciV;
-                        for( ciV = 1; ciV <= cnbV; ciV++ )
-                        {
-                          Standard_Real pntDMin = 1.e+100;
-                          Standard_Integer VDMin = 0;
-                          Standard_Integer WLDMin = 0;
-                          gp_Pnt cPV = wline->Vertex(ciV).Value();
-                          Standard_Integer iL;
-                          for( iL = 1; iL <= slinlen; iL++)
-                          {
-                            const Handle(IntPatch_Line)& aSLine = SLin.Value(iL);
-                            IntPatch_IType aType = aSLine->ArcType();
-                            if( aType != IntPatch_Walking)
-                              continue;
-                            const Handle(IntPatch_WLine)&  aWLine = (*((Handle(IntPatch_WLine)*)&aSLine));
-                            Standard_Integer tnbV = aWLine->NbVertex();
-                            Standard_Integer tiV;
-                            for( tiV = 1; tiV <= tnbV; tiV++ )
-                            {
-                              gp_Pnt tPV = aWLine->Vertex(tiV).Value();
-                              Standard_Real tDistance = cPV.Distance(tPV);
-                              Standard_Real uRs1 = Surf1->Surface().UResolution(tDistance);
-                              Standard_Real vRs1 = Surf1->Surface().VResolution(tDistance);
-                              Standard_Real uRs2 = Surf2->Surface().UResolution(tDistance);
-                              Standard_Real vRs2 = Surf2->Surface().VResolution(tDistance);
-                              Standard_Real RmaxS1 = Max(uRs1,vRs1);
-                              Standard_Real RmaxS2 = Max(uRs2,vRs2);
-                              if(RmaxS1 < 1.e-4 && RmaxS2 < 1.e-4)
-                              {
-                                if( pntDMin > tDistance && tDistance > 1.e-9)
-                                {
-                                  pntDMin = tDistance;
-                                  VDMin = tiV;
-                                  WLDMin = iL;
-                                }
-                              }
-                            }
-                          }
-
-                          if( VDMin != 0 )
-                          {
-                            const Handle(IntPatch_Line)& aSLine = SLin.Value(WLDMin);
-                            const Handle(IntPatch_WLine)&  aWLine = (*((Handle(IntPatch_WLine)*)&aSLine));
-                            Standard_Integer tiVpar = (Standard_Integer)aWLine->Vertex(VDMin).ParameterOnLine();
-                            Standard_Integer ciVpar = (Standard_Integer)wline->Vertex(ciV).ParameterOnLine();
-                            Standard_Real u11 = 0., u12 = 0., v11 = 0., v12 = 0.;
-                            Standard_Real u21 = 0., u22 = 0., v21 = 0., v22 = 0.;
-                            wline->Point(ciVpar).Parameters(u11,v11,u12,v12);
-                            aWLine->Point(tiVpar).Parameters(u21,v21,u22,v22);
-
-                            Handle(IntSurf_LineOn2S) newL2s = new IntSurf_LineOn2S();
-                            IntSurf_PntOn2S replacePnt = aWLine->Point(tiVpar);
-                            Standard_Integer cNbP = wline->NbPnts();
-
-                            TColStd_SequenceOfInteger VPold;
-                            Standard_Integer iPo;
-                            for( iPo = 1; iPo <= cnbV; iPo++ )
-                            {
-                              Standard_Real Po = wline->Vertex(iPo).ParameterOnLine();
-                              Standard_Integer IPo = (Standard_Integer) Po;
-                              VPold.Append(IPo);
-                            }
-
-                            Standard_Boolean removeNext = Standard_False;
-                            Standard_Boolean removePrev = Standard_False;
-                            if( ciV == 1)
-                            {
-                              Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
-                              if(dPar > 10)
-                              {
-                                removeNext = Standard_True;
-                                for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
-                                  VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
-                              }
-                            }
-                            else if( ciV == cnbV)
-                            {
-                              Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
-                              if(dPar > 10)
-                              {
-                                removePrev = Standard_True;
-                                VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
-                              }
-                            }
-                            else
-                            {
-                              Standard_Integer dParMi = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
-                              Standard_Integer dParMa = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
-                              if(dParMi > 10)
-                              {
-                                removePrev = Standard_True;
-                                VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
-                              }
-
-                              if(dParMa > 10)
-                              {
-                                removeNext = Standard_True;
-                                for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
-                                {
-                                  if(dParMi > 10)
-                                    VPold.SetValue(iPo, VPold.Value(iPo) - 2 );
-                                  else
-                                    VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
-                                }
-                              }
-                              else
-                              {
-                                if(dParMi > 10)
-                                  for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
-                                    VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
-                              } 
-                            }
-
-                            Standard_Integer pI = ciVpar;
-
-                            Standard_Integer iP;
-                            for( iP = 1; iP <= cNbP; iP++)
-                            {
-                              if( pI == iP )
-                              {
-                                IntSurf_PntOn2S newPnt = MakeNewPoint(replacePnt, wline->Point(iP), Periods);
-                                newL2s->Add(newPnt);
-                              }
-                              else if(removeNext && iP == (pI + 1))
-                                continue;
-                              else if(removePrev && iP == (pI - 1))
-                                continue;
-                              else
-                                newL2s->Add(wline->Point(iP));
-                            }
-
-                            IntPatch_Point newVtx;
-                            gp_Pnt Pnt3dV = aWLine->Vertex(VDMin).Value();
-                            newVtx.SetValue(Pnt3dV,TolTang,Standard_False);
-                            newVtx.SetParameters(u21,v21,u22,v22);
-                            newVtx.SetParameter(VPold.Value(ciV));
-
-                            Handle(IntPatch_WLine) NWLine = new IntPatch_WLine(newL2s,Standard_False,trans1,trans2);
-
-                            Standard_Integer iV;
-                            for( iV = 1; iV <= cnbV; iV++ )
-                            {
-                              if( iV == ciV )
-                                NWLine->AddVertex(newVtx);
-                              else
-                              {
-                                IntPatch_Point theVtx = wline->Vertex(iV);
-                                theVtx.SetParameter(VPold.Value(iV));
-                                NWLine->AddVertex(theVtx);
-                              }
-                            }
-
-                            wline = NWLine;
-                          }//if( VDMin != 0 )
-                        }//for( ciV = 1; ciV <= cnbV; ciV++ )
-                      }// SLin.Length > 0
+                      SeveralWlinesProcessing(Surf1, Surf2, SLin, Periods, trans1, trans2, TolTang, wline);
 
                       AddWLine(SLin, wline, Deflection);
                       empt = Standard_False;
@@ -2664,7 +2720,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
   //if(MaxOscill>10)
   //nIncrement/=0.5*MaxOscill;
 
-  IntPatch_ThePWalkingInter PW(Surf1,Surf2,TolTangency,Epsilon,Deflection,nIncrement);
+  IntWalk_PWalking PW(Surf1,Surf2,TolTangency,Epsilon,Deflection,nIncrement);
   Standard_Real    SeuildPointLigne = 15.0 * Increment * Increment; //-- 10 est insuffisant
   Standard_Real    dminiPointLigne;
   Standard_Boolean HasStartPoint,RejetLigne;
@@ -2735,7 +2791,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
             const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints());
             Point3dFin   = PointFin.Value();
 
-            for(ver=1 ; (!RejetLigne) && (ver<= NbLigCalculee) ; ver++)
+            for(ver=1 ; ver<= NbLigCalculee ; ver++)
             {
               const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver));
               //-- Handle(IntPatch_WLine) verwline=Handle(IntPatch_WLine)::DownCast(SLin.Value(ver));
@@ -2750,19 +2806,19 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
 
               const IntSurf_PntOn2S& verPointDebut = verwline->Point(1);
               const IntSurf_PntOn2S& verPointFin   = verwline->Point(verwline->NbPnts());
-              if(Point3dDebut.Distance(verPointDebut.Value()) < TolTangency)
+              if( (Point3dDebut.Distance(verPointDebut.Value()) < TolTangency) ||
+                  (Point3dFin.Distance(verPointFin.Value()) < TolTangency))
               {
                 RejetLigne = Standard_True; 
-              }
-              else
-              {
-                if(Point3dFin.Distance(verPointFin.Value()) < TolTangency)
-                {
-                  RejetLigne = Standard_True; 
-                }
+                break;
               }
             }
 
+            if(RejetLigne)
+            {
+              DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne);
+            }
+
             if(!RejetLigne)
             {
               IntSurf_TypeTrans trans1,trans2;
@@ -2905,7 +2961,14 @@ public:
     const Standard_Integer j) { 
       return myP2[Index(i,j)];
   };
-protected:
+
+private:
+
+  IntPatch_InfoPD (const IntPatch_InfoPD&);
+  IntPatch_InfoPD& operator=(const IntPatch_InfoPD&);
+
+private:
+
   Standard_Integer myNBI;
   char *myP1DS2;
   char *myP2DS1;