0025715: Intersection between cylinders produces excess vertices
authornbv <nbv@opencascade.com>
Thu, 29 Jan 2015 11:00:11 +0000 (14:00 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 29 Jan 2015 11:01:10 +0000 (14:01 +0300)
1. Curve boundaries were more precised.
2. Some test cases were changed in accordance of their new behavior.
3. Code fragment for WLines joining was moved to higher level (for more universal using in the future).

Code was changed in accordance with the last remark.

Added test cases bugs/modalg_5/bug25715_1 bug25715_2 bug25715_3

src/IntPatch/IntPatch_ImpImpIntersection_4.gxx
src/IntPatch/IntPatch_Intersection.cxx
src/IntTools/IntTools_FaceFace.cxx
tests/bugs/modalg_5/bug24825_common
tests/bugs/modalg_5/bug24825_cut
tests/bugs/modalg_5/bug24825_fuse
tests/bugs/modalg_5/bug24981
tests/bugs/modalg_5/bug25715_1 [new file with mode: 0644]
tests/bugs/modalg_5/bug25715_2 [new file with mode: 0644]
tests/bugs/modalg_5/bug25715_3 [new file with mode: 0644]

index 6812cd7..d5cdd42 100644 (file)
@@ -1860,6 +1860,13 @@ Standard_Boolean IntCyCyTrim( const IntSurf_Quadric& theQuad1,
 
   //Getting Walking-line
 
+  enum WLFStatus
+  {
+    WLFStatus_Absent = 0,
+    WLFStatus_Exist  = 1,
+    WLFStatus_Broken = 2
+  };
+
   for(Standard_Integer aCurInterval = 0; aCurInterval < aNbOfBoundaries; aCurInterval++)
   {
     if(Precision::IsInfinite(aU1f[aCurInterval]) && Precision::IsInfinite(aU1l[aCurInterval]))
@@ -1878,7 +1885,7 @@ Standard_Boolean IntCyCyTrim( const IntSurf_Quadric& theQuad1,
     while(anUf < anUl)
     {
       Standard_Real aU2[aNbWLines], aV1[aNbWLines], aV2[aNbWLines];
-      Standard_Integer aWLFindStatus[aNbWLines];
+      WLFStatus aWLFindStatus[aNbWLines];
       Standard_Real aV1Prev[aNbWLines], aV2Prev[aNbWLines];
       Standard_Real anArccosFactor[aNbWLines] = {1.0, -1.0};
       Standard_Boolean isAddingWLEnabled[aNbWLines];
@@ -1889,7 +1896,7 @@ Standard_Boolean IntCyCyTrim( const IntSurf_Quadric& theQuad1,
       {
         aL2S[i] = new IntSurf_LineOn2S();
         aWLine[i] = new IntPatch_WLine(aL2S[i], Standard_False);
-        aWLFindStatus[i] = 0;
+        aWLFindStatus[i] = WLFStatus_Absent;
         isAddingWLEnabled[i] = Standard_True;
         aU2[i] = aV1[i] = aV2[i] = 0.0;
         aV1Prev[i] = aV2Prev[i] = 0.0;
@@ -1929,7 +1936,7 @@ Standard_Boolean IntCyCyTrim( const IntSurf_Quadric& theQuad1,
             anU1 = anU1crit[i];
 
             for(Standard_Integer i = 0; i < aNbWLines; i++)
-              aWLFindStatus[i] = 2;
+              aWLFindStatus[i] = WLFStatus_Broken;
 
             break;
           }
@@ -2005,6 +2012,18 @@ Standard_Boolean IntCyCyTrim( const IntSurf_Quadric& theQuad1,
             }
           }
 
+          if(aWLFindStatus[i] == WLFStatus_Broken)
+          {
+            if(Abs(aU2[i]) <= theTol2D)
+              aU2[i] = 0.0;
+            else if(Abs(aU2[i] - aPeriod) <= theTol2D)
+              aU2[i] = aPeriod;
+            else if(Abs(aU2[i] - aUSurf2f) <= theTol2D)
+              aU2[i] = aUSurf2f;
+            else if(Abs(aU2[i] - aUSurf2l) <= theTol2D)
+              aU2[i] = aUSurf2l;
+          }
+
           aV1[i] =  anEquationCoeffs.mK21 * sin(aU2[i]) + 
                     anEquationCoeffs.mK11 * sin(anU1) +
                     anEquationCoeffs.mL21 * cos(aU2[i]) +
@@ -2033,7 +2052,7 @@ Standard_Boolean IntCyCyTrim( const IntSurf_Quadric& theQuad1,
             aV1Prev[i] = aV1[i];
             aV2Prev[i] = aV2[i];
 
-            if(aWLFindStatus[i] == 2)
+            if(aWLFindStatus[i] == WLFStatus_Broken)
               isBroken = Standard_True;
 
             continue;
@@ -2044,7 +2063,7 @@ Standard_Boolean IntCyCyTrim( const IntSurf_Quadric& theQuad1,
               ((aVSurf2f - aV2[i]) <= theTol2D) && ((aV2[i] - aVSurf2l) <= theTol2D))
           {
             Standard_Boolean isForce = Standard_False;
-            if(!aWLFindStatus[i])
+            if(aWLFindStatus[i] == WLFStatus_Absent)
             {
               Standard_Boolean isFound1 = Standard_False, isFound2 = Standard_False;
 
@@ -2061,27 +2080,27 @@ Standard_Boolean IntCyCyTrim( const IntSurf_Quadric& theQuad1,
               
               if(isFound1 || isFound2)
               {
-                aWLFindStatus[i] = 1;
+                aWLFindStatus[i] = WLFStatus_Exist;
               }
             }
 
-            if(( aWLFindStatus[i] != 2) || (aWLine[i]->NbPnts() >= 1))
+            if(( aWLFindStatus[i] != WLFStatus_Broken) || (aWLine[i]->NbPnts() >= 1))
             {
               if(AddPointIntoWL(theQuad1, theQuad2, isTheReverse, 
                                 gp_Pnt2d(anU1, aV1[i]), gp_Pnt2d(aU2[i], aV2[i]),
                                 aUSurf1f, aUSurf1l, aPeriod,
                                 aWLine[i]->Curve(), theTol3D, theTol2D, isForce))
               {
-                if(!aWLFindStatus[i])
+                if(aWLFindStatus[i] == WLFStatus_Absent)
                 {
-                  aWLFindStatus[i] = 1;
+                  aWLFindStatus[i] = WLFStatus_Exist;
                 }
               }
             }
           }
           else
           {
-            if(aWLFindStatus[i] == 1)
+            if(aWLFindStatus[i] == WLFStatus_Exist)
             {
               Standard_Boolean isFound1 = Standard_False, isFound2 = Standard_False;
 
@@ -2092,14 +2111,14 @@ Standard_Boolean IntCyCyTrim( const IntSurf_Quadric& theQuad1,
                                 anArccosFactor[i], Standard_False, isFound1, isFound2);
 
               if(isFound1 || isFound2)
-                aWLFindStatus[i] = 2; //start a new line
+                aWLFindStatus[i] = WLFStatus_Broken; //start a new line
             }
           }
 
           aV1Prev[i] = aV1[i];
           aV2Prev[i] = aV2[i];
 
-          if(aWLFindStatus[i] == 2)
+          if(aWLFindStatus[i] == WLFStatus_Broken)
             isBroken = Standard_True;
         }//for(Standard_Integer i = 0; i < aNbWLines; i++)
 
@@ -2228,201 +2247,6 @@ Standard_Boolean IntCyCyTrim( const IntSurf_Quadric& theQuad1,
     }
   }
 
-  if(theSlin.Length() > 0)
-  {
-    for(Standard_Integer aNumOfLine = 2; aNumOfLine <= theSlin.Length(); aNumOfLine++)
-    {
-      const Handle(IntPatch_WLine)& aWLine = Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNumOfLine));
-
-      const IntSurf_PntOn2S& aPntFWL = aWLine->Point(1);
-
-      Standard_Real aU1 = 0.0, aU2 = 0.0, aV1 = 0.0, aV2 = 0.0;
-      aPntFWL.Parameters(aU1, aV1, aU2, aV2);
-
-      if( IsEqual(aU1, 0.0) || IsEqual(aU1, aPeriod))
-      {
-        theSlin.Exchange(1, aNumOfLine);
-        break;
-      }
-    }
-
-    for(Standard_Integer aNumOfLine1 = 1; aNumOfLine1 <= theSlin.Length(); aNumOfLine1++)
-    {
-      const Handle(IntPatch_WLine)& aWLine1 = Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNumOfLine1));
-
-      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()))
-        {
-          Standard_Real aU11 = 0.0, aU12 = 0.0, aV11 = 0.0, aV12 = 0.0;
-          Standard_Real aU21 = 0.0, aU22 = 0.0, aV21 = 0.0, aV22 = 0.0;
-
-          aPntFWL1.Parameters(aU11, aV11, aU12, aV12);
-          aPntFWL2.Parameters(aU21, aV21, aU22, aV22);
-
-          if( !(IsEqual(fmod(aU11, aPeriod), 0.0) ||
-                IsEqual(fmod(aU12, aPeriod), 0.0) ||
-                IsEqual(fmod(aU21, aPeriod), 0.0) ||
-                IsEqual(fmod(aU22, aPeriod), 0.0) ||
-                IsEqual(aU11, aUSurf1f) || IsEqual(aU11, aUSurf1l) ||
-                IsEqual(aU21, aUSurf1f) || IsEqual(aU21, aUSurf1l) ||
-                IsEqual(aU12, aUSurf2f) || IsEqual(aU12, aUSurf2l) ||
-                IsEqual(aU22, aUSurf2f) || IsEqual(aU22, aUSurf2l)))
-          {
-            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()))
-        {
-          Standard_Real aU11 = 0.0, aU12 = 0.0, aV11 = 0.0, aV12 = 0.0;
-          Standard_Real aU21 = 0.0, aU22 = 0.0, aV21 = 0.0, aV22 = 0.0;
-
-          aPntFWL1.Parameters(aU11, aV11, aU12, aV12);
-          aPntLWL2.Parameters(aU21, aV21, aU22, aV22);
-
-          if( !(IsEqual(fmod(aU11, aPeriod), 0.0) ||
-                IsEqual(fmod(aU12, aPeriod), 0.0) ||
-                IsEqual(fmod(aU21, aPeriod), 0.0) ||
-                IsEqual(fmod(aU22, aPeriod), 0.0) ||
-                IsEqual(aU11, aUSurf1f) || IsEqual(aU11, aUSurf1l) ||
-                IsEqual(aU21, aUSurf1f) || IsEqual(aU21, aUSurf1l) ||
-                IsEqual(aU12, aUSurf2f) || IsEqual(aU12, aUSurf2l) ||
-                IsEqual(aU22, aUSurf2f) || IsEqual(aU22, aUSurf2l)))
-          {
-            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()))
-        {
-          Standard_Real aU11 = 0.0, aU12 = 0.0, aV11 = 0.0, aV12 = 0.0;
-          Standard_Real aU21 = 0.0, aU22 = 0.0, aV21 = 0.0, aV22 = 0.0;
-
-          aPntLWL1.Parameters(aU11, aV11, aU12, aV12);
-          aPntFWL2.Parameters(aU21, aV21, aU22, aV22);
-
-          if( !(IsEqual(fmod(aU11, aPeriod), 0.0) ||
-                IsEqual(fmod(aU12, aPeriod), 0.0) ||
-                IsEqual(fmod(aU21, aPeriod), 0.0) ||
-                IsEqual(fmod(aU22, aPeriod), 0.0) ||
-                IsEqual(aU11, aUSurf1f) || IsEqual(aU11, aUSurf1l) ||
-                IsEqual(aU21, aUSurf1f) || IsEqual(aU21, aUSurf1l) ||
-                IsEqual(aU12, aUSurf2f) || IsEqual(aU12, aUSurf2l) ||
-                IsEqual(aU22, aUSurf2f) || IsEqual(aU22, aUSurf2l)))
-          {
-            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()))
-        {
-          Standard_Real aU11 = 0.0, aU12 = 0.0, aV11 = 0.0, aV12 = 0.0;
-          Standard_Real aU21 = 0.0, aU22 = 0.0, aV21 = 0.0, aV22 = 0.0;
-
-          aPntLWL1.Parameters(aU11, aV11, aU12, aV12);
-          aPntLWL2.Parameters(aU21, aV21, aU22, aV22);
-
-          if( !(IsEqual(fmod(aU11, aPeriod), 0.0) ||
-                IsEqual(fmod(aU12, aPeriod), 0.0) ||
-                IsEqual(fmod(aU21, aPeriod), 0.0) ||
-                IsEqual(fmod(aU22, aPeriod), 0.0) ||
-                IsEqual(aU11, aUSurf1f) || IsEqual(aU11, aUSurf1l) ||
-                IsEqual(aU21, aUSurf1f) || IsEqual(aU21, aUSurf1l) ||
-                IsEqual(aU12, aUSurf2f) || IsEqual(aU12, aUSurf2l) ||
-                IsEqual(aU22, aUSurf2f) || IsEqual(aU22, aUSurf2l)))
-          {
-            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;
-          }
-        }
-      }
-
-      if(hasBeenRemoved)
-        aNumOfLine1--;
-    }
-  }//if(theSlin.Length() > 0)
-
-
   return Standard_True;
 }
 
index 3698add..dee76ad 100644 (file)
 #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 failure 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;
+        }
+      }
+    }
+
+    if(hasBeenRemoved)
+      aNumOfLine1--;
+  }
+}
+
 //======================================================================
 // function: SequenceOfLine
 //======================================================================
@@ -1513,6 +1727,16 @@ void IntPatch_Intersection::
           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());
       }
     }
   }
index a062695..0bcbc42 100644 (file)
@@ -3770,7 +3770,7 @@ Standard_Boolean DecompositionOfWLine(const Handle(IntPatch_WLine)& theWLine,
               bCheckAngle1 = Standard_True;
               aNewVec = gp_Vec2d(gp_Pnt2d(nU1, nV1), gp_Pnt2d(anewU, anewV));
 
-              if(aNewVec.SquareMagnitude() < (gp::Resolution() * gp::Resolution())) {
+              if(aNewVec.SquareMagnitude() < gp::Resolution()) {
                 aNewP.SetValue((surfit == 0), anewU, anewV);
                 bCheckAngle1 = Standard_False;
               }
@@ -3779,7 +3779,7 @@ Standard_Boolean DecompositionOfWLine(const Handle(IntPatch_WLine)& theWLine,
               bCheckAngle2 = Standard_True;
               aNewVec = gp_Vec2d(gp_Pnt2d(nU1, nV1), gp_Pnt2d(U, V));
 
-              if(aNewVec.SquareMagnitude() < (gp::Resolution() * gp::Resolution())) {
+              if(aNewVec.SquareMagnitude() < gp::Resolution()) {
                 bCheckAngle2 = Standard_False;
               }
             }
@@ -3799,7 +3799,7 @@ Standard_Boolean DecompositionOfWLine(const Handle(IntPatch_WLine)& theWLine,
                   aPrevNeighbourPoint.ParametersOnS2(nU2, nV2);
                 gp_Vec2d aVecOld(gp_Pnt2d(nU2, nV2), gp_Pnt2d(nU1, nV1));
 
-                if(aVecOld.SquareMagnitude() <= (gp::Resolution() * gp::Resolution())) {
+                if(aVecOld.SquareMagnitude() <= gp::Resolution()) {
                   continue;
                 }
                 else {
@@ -3916,7 +3916,7 @@ Standard_Boolean DecompositionOfWLine(const Handle(IntPatch_WLine)& theWLine,
               ap2.SetX(nU2);
               ap2.SetY(nV2);
 
-              if(ap1.SquareDistance(ap2) > (gp::Resolution() * gp::Resolution())) {
+              if(ap1.SquareDistance(ap2) > gp::Resolution()) {
                 break;
               }
             }  
index d66bc41..25737d3 100644 (file)
@@ -45,14 +45,14 @@ bbop result 0
 
 set square 10008.9
 
-set nb_v_good 140
-set nb_e_good 186
+set nb_v_good 86
+set nb_e_good 132
 set nb_w_good 126
 set nb_f_good 126
 set nb_sh_good 40
 set nb_sol_good 40
 set nb_compsol_good 0
 set nb_compound_good 1
-set nb_shape_good 659
+set nb_shape_good 551
 
 set 2dviewer 1
index a36b052..4b40448 100644 (file)
@@ -45,14 +45,14 @@ bbop result 2
 
 set square 103838
 
-set nb_v_good 160
-set nb_e_good 218
+set nb_v_good 106
+set nb_e_good 164
 set nb_w_good 142
 set nb_f_good 80
 set nb_sh_good 3
 set nb_sol_good 3
 set nb_compsol_good 0
 set nb_compound_good 1
-set nb_shape_good 607
+set nb_shape_good 499
 
 set 2dviewer 1
index f9ce0fd..a3f9aad 100644 (file)
@@ -46,14 +46,14 @@ bbop result 1
 
 set square 157211
 
-set nb_v_good 160
-set nb_e_good 218
+set nb_v_good 106
+set nb_e_good 164
 set nb_w_good 142
 set nb_f_good 80
 set nb_sh_good 1
 set nb_sol_good 1
 set nb_compsol_good 0
 set nb_compound_good 1
-set nb_shape_good 603
+set nb_shape_good 495
 
 set 2dviewer 1
index 42daa4e..3bfa8f1 100644 (file)
@@ -20,14 +20,14 @@ baddtools b_1 b_2 b_3 b_4 b_5 b_6 b_7 b_8 b_9 b_10 b_11 b_12 b_13 b_14 b_15 b_16
 bfillds
 bbuild result
 
-set nb_v_good 170
-set nb_e_good 268
+set nb_v_good 122
+set nb_e_good 220
 set nb_w_good 243
 set nb_f_good 195
 set nb_sh_good 75
 set nb_sol_good 75
 set nb_compsol_good 0
 set nb_compound_good  1
-set nb_shape_good 1027
+set nb_shape_good 931
 
 set 2dviewer 1
diff --git a/tests/bugs/modalg_5/bug25715_1 b/tests/bugs/modalg_5/bug25715_1
new file mode 100644 (file)
index 0000000..3c98421
--- /dev/null
@@ -0,0 +1,28 @@
+puts "=========="
+puts "OCC25715"
+puts "=========="
+puts ""
+#############################################################
+# Intersection between cylinders produces excess vertices
+#############################################################
+# don't change nbshapes values according to 25715
+
+pcylinder s1 0.069 0.6
+pcylinder s2 0.024, 0.4
+trotate s1 0 0 0 0 0 1 90
+trotate s2 0 0 0 0 1 0 90
+trotate s2 0 0 0 1 0 0 -45
+ttranslate s2 -0.2 0 0.48
+bcut result s1 s2
+
+set nb_v_good 4
+set nb_e_good 6
+set nb_w_good 6
+set nb_f_good 4
+set nb_sh_good 1
+set nb_sol_good 1
+set nb_compsol_good 0
+set nb_compound_good 1
+set nb_shape_good 23
+
+set 2dviewer 1
diff --git a/tests/bugs/modalg_5/bug25715_2 b/tests/bugs/modalg_5/bug25715_2
new file mode 100644 (file)
index 0000000..898464f
--- /dev/null
@@ -0,0 +1,24 @@
+puts "=========="
+puts "OCC25715"
+puts "=========="
+puts ""
+#############################################################
+# Intersection between cylinders produces excess vertices
+#############################################################
+# don't change nbshapes values according to 25715
+
+restore [locate_data_file bug25715_b14p9s1.brep] s1
+restore [locate_data_file bug25715_b14p9s2.brep] s2
+bfuse result s1 s2
+
+set nb_v_good 4
+set nb_e_good 6
+set nb_w_good 6
+set nb_f_good 5
+set nb_sh_good 1
+set nb_sol_good 1
+set nb_compsol_good 0
+set nb_compound_good 1
+set nb_shape_good 24
+
+set 2dviewer 1
diff --git a/tests/bugs/modalg_5/bug25715_3 b/tests/bugs/modalg_5/bug25715_3
new file mode 100644 (file)
index 0000000..47aab08
--- /dev/null
@@ -0,0 +1,25 @@
+puts "TODO OCC24418 ALL: Error : Result shape is WRONG because it must contains"
+puts "=========="
+puts "OCC25715"
+puts "=========="
+puts ""
+#############################################################
+# Intersection between cylinders produces excess vertices
+#############################################################
+# don't change nbshapes values according to 25715
+
+restore [locate_data_file bug25715_p02c3s1.brep] s1
+restore [locate_data_file bug25715_p02c3s3.brep] s3
+bfuse result s1 s3
+
+set nb_v_good 8
+set nb_e_good 14
+set nb_w_good 6
+set nb_f_good 5
+set nb_sh_good 1
+set nb_sol_good 1
+set nb_compsol_good 0
+set nb_compound_good 1
+set nb_shape_good 36
+
+set 2dviewer 1