0029323: Intersection algorithm produces the curve with oscillation
authornbv <nbv@opencascade.com>
Mon, 13 Nov 2017 10:55:48 +0000 (13:55 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 8 Dec 2017 13:39:03 +0000 (16:39 +0300)
Sometimes the algorithm of purging of extra points in the walking line makes enormous difference in distance between two neighbor segments of the line. This badly impacts the quality of approximation result. This patch balances the difference in distances by forbidding deletion of some points.

1. tests/bugs/modalg_6/bug27615

The reason of the correction is explained in the message ~0072580 (see issue #28557).

2. tests/bugs/modalg_7/bug28892*
   tests/bugs/modalg_7/bug28984

The reason of the correction is explained in the message ~0072583 (see issue #28984).

src/IntPatch/IntPatch_WLineTool.cxx
tests/bugs/modalg_6/bug27615
tests/bugs/modalg_7/bug28557 [new file with mode: 0644]
tests/bugs/modalg_7/bug28892_2
tests/bugs/modalg_7/bug28892_3
tests/bugs/modalg_7/bug28984
tests/bugs/modalg_7/bug29323 [new file with mode: 0644]

index 78148f6..968c246 100644 (file)
@@ -91,20 +91,80 @@ static void FillPointsHash(const Handle(IntPatch_WLine)         &theWLine,
 //            Static subfunction in ComputePurgedWLine and DeleteOuter.
 //=========================================================================
 static Handle(IntPatch_WLine) MakeNewWLine(const Handle(IntPatch_WLine)         &theWLine,
-                                           const NCollection_Array1<Standard_Integer> &thePointsHash)
+                                           NCollection_Array1<Standard_Integer> &thePointsHash,
+                                           const Standard_Boolean theIsOuter)
 {
   Standard_Integer i;
 
   Handle(IntSurf_LineOn2S) aPurgedLineOn2S = new IntSurf_LineOn2S();
   Handle(IntPatch_WLine) aLocalWLine = new IntPatch_WLine(aPurgedLineOn2S, Standard_False);
-  Standard_Integer anOldLineIdx = 1, aVertexIdx = 1;
+  Standard_Integer anOldLineIdx = 1, aVertexIdx = 1, anIndexPrev = -1, anIdxOld = -1;
+  gp_Pnt aPPrev, aPOld;
   for(i = 1; i <= thePointsHash.Upper(); i++)
   {
     if (thePointsHash(i) == 0)
     {
-      // Store this point.
-      aPurgedLineOn2S->Add(theWLine->Point(i));
-      anOldLineIdx++;
+      // Point has to be added
+
+      const gp_Pnt aP = theWLine->Point(i).Value();
+      const Standard_Real aSqDistPrev = aPPrev.SquareDistance(aPOld);
+      const Standard_Real aSqDist = aPPrev.SquareDistance(aP);
+
+      const Standard_Real aRatio = (aSqDistPrev < gp::Resolution()) ? 0.0 : 9.0*aSqDist / aSqDistPrev;
+
+      if(theIsOuter ||
+         (aRatio < gp::Resolution()) ||
+         ((1.0 < aRatio) && (aRatio < 81.0)) ||
+         (i - anIndexPrev <= 1) ||
+         (i - anIdxOld <= 1))
+      {
+        // difference in distances is satisfactory
+        // (1/9 < aSqDist/aSqDistPrev < 9)
+
+        // Store this point.
+        aPurgedLineOn2S->Add(theWLine->Point(i));
+        anOldLineIdx++;
+        aPOld = aPPrev;
+        aPPrev = aP;
+        anIdxOld = anIndexPrev;
+        anIndexPrev = i;
+      }
+      else if(aSqDist >= aSqDistPrev*9.0)
+      {
+        // current segment is much more longer
+        // (aSqDist/aSqDistPrev >= 9)
+
+        i = (i + anIndexPrev)/2;
+        thePointsHash(i) = 0;
+        i--;
+      }
+      else
+      {
+        //previous segment is much more longer
+        //(aSqDist/aSqDistPrev <= 1/9)
+
+        if(anIndexPrev - anIdxOld > 1)
+        {
+          //Delete aPPrev from WL
+          aPurgedLineOn2S->RemovePoint(aPurgedLineOn2S->NbPoints());
+          anOldLineIdx--;
+
+          // Insert point between aPOld and aPPrev 
+          i = (anIdxOld + anIndexPrev) / 2;
+          thePointsHash(i) = 0;
+
+          aPPrev = aPOld;
+          anIndexPrev = anIdxOld;
+        }
+        else
+        {
+          aPOld = aPPrev;
+          anIdxOld = anIndexPrev;
+        }
+
+        //Next iterations will start from this inserted point.
+        i--;
+      }
     }
     else if (thePointsHash(i) == -1)
     {
@@ -113,7 +173,11 @@ static Handle(IntPatch_WLine) MakeNewWLine(const Handle(IntPatch_WLine)
       aVertex.SetParameter(anOldLineIdx++);
       aLocalWLine->AddVertex(aVertex);
       aPurgedLineOn2S->Add(theWLine->Point(i));
+      aPPrev = aPOld = theWLine->Point(i).Value();
+      anIndexPrev = anIdxOld = i;
     }
+
+    //Other points will be rejected by purger.
   }
 
   return aLocalWLine;
@@ -241,7 +305,7 @@ static Handle(IntPatch_WLine)
   }
 
   // Build new line and modify geometry of necessary vertexes.
-  Handle(IntPatch_WLine) aLocalWLine = MakeNewWLine(theWLine, aDelOuterPointsHash);
+  Handle(IntPatch_WLine) aLocalWLine = MakeNewWLine(theWLine, aDelOuterPointsHash, Standard_True);
 
   if (aChangedFirst)
   {
@@ -483,7 +547,7 @@ static Handle(IntPatch_WLine)
     }
   }
 
-  return MakeNewWLine(theWLine, aNewPointsHash);
+  return MakeNewWLine(theWLine, aNewPointsHash, Standard_False);
 }
 
 //=======================================================================
index 9754683..7f7adce 100644 (file)
@@ -22,9 +22,13 @@ whatis result
 explode result
 whatis result_1
 
+if { [regexp "This shape seems to be OK" [bopcheck result] ] != 1 } {
+    puts "Error : The result of General Fuse operation is self-interfered shape"
+}
+
 checkshape result_1
 
-checkprops result_1 -v 15041.2 -s 8245.4
+checkprops result_1 -v 15287.7 -s 8383.16
 
 checkview -display result_1 -2d -path ${imagedir}/${test_image}.png
 
diff --git a/tests/bugs/modalg_7/bug28557 b/tests/bugs/modalg_7/bug28557
new file mode 100644 (file)
index 0000000..b878a85
--- /dev/null
@@ -0,0 +1,33 @@
+puts "========"
+puts "OCC28557"
+puts "========"
+puts ""
+#################################################
+# Test case bugs modalg_6 bug27615 works differently on VC10 and VC12
+#################################################
+
+set MaxTolReached 5.0e-6
+set GoodNbCurv 1
+
+brestore [locate_data_file bug27615.brep] b
+explode b f
+copy b_1 f1; copy b_19 f2;
+don f1 f2
+set log [bopcurves f1 f2 -2d -p 2.2023968513463648  29.150590232723459 2. 0.085664915040461045 -p 2.2023968513457164 31.082210390953925 2.9507808705284453 0.085823752287563393]
+
+smallview
+donly c_1
+fit
+disp f1 f2
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_1.png
+
+regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv
+
+if {$Toler > $MaxTolReached} {
+  puts "Error: Big tolerance is returned by intersector"
+}
+
+if {$NbCurv != $GoodNbCurv} {
+  puts "Error: Please check NbCurves for intersector"
+}
index 34487c4..91c6fe3 100644 (file)
@@ -1,5 +1,3 @@
-puts "TODO OCC28989 ALL: Error: result is self-interfered"
-
 puts "======="
 puts "OCC28892"
 puts "======="
index 881f6e7..22fcf3d 100644 (file)
@@ -1,5 +1,3 @@
-puts "TODO OCC28989 ALL: Error: result is self-interfered"
-
 puts "======="
 puts "OCC28892"
 puts "======="
index 62d0bf2..b8f120f 100644 (file)
@@ -1,5 +1,3 @@
-puts "TODO OCC28984 ALL: Error: Too big intersection tolerance"
-
 puts "======="
 puts "0028984"
 puts "======="
@@ -20,6 +18,6 @@ if {$nb_curves != 2} {
   puts "Error: Invalid number of curves"
 }
 
-if {$tol_reached > 0.1} {
+if {$tol_reached > 0.01} {
   puts "Error: Too big intersection tolerance"
 }
\ No newline at end of file
diff --git a/tests/bugs/modalg_7/bug29323 b/tests/bugs/modalg_7/bug29323
new file mode 100644 (file)
index 0000000..ca94e94
--- /dev/null
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC29323"
+puts "========"
+puts ""
+#################################################
+# Intersection algorithm produces the curve with oscillation
+#################################################
+
+set MaxTolReached 0.15
+set GoodNbCurv 1
+set ExpLength 96.268040111795571
+
+restore [locate_data_file bug29323_hb.brep] h
+plane p 0 0 4 0 0 1
+mkface f p -200 200 -200 200
+explode h f
+
+set log [bopcurves h_4 f -2d]
+
+smallview
+donly c_1
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_1.png
+checklength c_1 -l $ExpLength
+
+regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv
+
+if {$Toler > $MaxTolReached} {
+  puts "Error: Big tolerance is returned by intersector"
+}
+
+if {$NbCurv != $GoodNbCurv} {
+  puts "Error: Please check NbCurves for intersector"
+}
\ No newline at end of file