]> OCCT Git - occt-copy.git/commitdiff
0029323: Intersection algorithm produces the curve with oscillation
authornbv <nbv@opencascade.com>
Mon, 13 Nov 2017 10:55:48 +0000 (13:55 +0300)
committeremv <emv@opencascade.com>
Fri, 29 Jun 2018 10:55:05 +0000 (13:55 +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 78148f677abe551ae8400e24ec52d3f951aa44b0..968c2461f25e2cff1bf7a993c7b9d794d2a02be3 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 975468398297129cdfa4ec7f6864ceff9b27dca7..7f7adce1d463df72937c4c9ab46009bbecc2e6e6 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 34487c42a0f0de61ce461f85e0eaf95eb072f97a..91c6fe3485f75397ffdf6e24f3cf9a4d780e2513 100644 (file)
@@ -1,5 +1,3 @@
-puts "TODO OCC28989 ALL: Error: result is self-interfered"
-
 puts "======="
 puts "OCC28892"
 puts "======="
index 881f6e703135df7edefe0e6a1db231581c951a3f..22fcf3d1945280c9669b98b14a631efec7738464 100644 (file)
@@ -1,5 +1,3 @@
-puts "TODO OCC28989 ALL: Error: result is self-interfered"
-
 puts "======="
 puts "OCC28892"
 puts "======="
index 62d0bf282a3a8c64ff02f04b0449ebe2160ede3b..b8f120fd6695ac4b6cbb017f43114d557e02d1cc 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