From c24985e8cf2a6a3276fceae079d5d66599b658ef Mon Sep 17 00:00:00 2001
From: jean-pierre charras <jp.charras@wanadoo.fr>
Date: Mon, 10 Jan 2022 11:31:29 +0100
Subject: [PATCH] drc_test_provider_sliver_checker.cpp: skip very small
 vertices when testing. Very small vertices (length <= 2 or 3 iu) are frequent
 in filled areas, and create false positive detections because one cannot
 calculate a meaningful orientation of these vertices.

---
 .../drc/drc_test_provider_sliver_checker.cpp  | 28 +++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/pcbnew/drc/drc_test_provider_sliver_checker.cpp b/pcbnew/drc/drc_test_provider_sliver_checker.cpp
index 976c9e57ca..94e7129783 100644
--- a/pcbnew/drc/drc_test_provider_sliver_checker.cpp
+++ b/pcbnew/drc/drc_test_provider_sliver_checker.cpp
@@ -132,6 +132,13 @@ bool DRC_TEST_PROVIDER_SLIVER_CHECKER::Run()
         // Sharpen corners
         poly.Deflate( widthTolerance / 2, ARC_LOW_DEF, SHAPE_POLY_SET::CHAMFER_ACUTE_CORNERS );
 
+        // Frequently, in filled areas, some points of the polygons are very near (dist is only
+        // a few internal units, like 2 or 3 units.
+        // We skip very small vertices: one cannot really compute a valid orientation of
+        // such a vertex
+        // So skip points near than min_len (in internal units).
+        const int min_len = 3;
+
         for( int jj = 0; jj < poly.OutlineCount(); ++jj )
         {
             const std::vector<VECTOR2I>& pts = poly.Outline( jj ).CPoints();
@@ -141,10 +148,27 @@ bool DRC_TEST_PROVIDER_SLIVER_CHECKER::Run()
             {
                 VECTOR2I pt = pts[ kk ];
                 VECTOR2I ptBefore = pts[ ( ptCount + kk - 1 ) % ptCount ];
-                VECTOR2I ptAfter  = pts[ ( kk + 1 ) % ptCount ];
-
                 VECTOR2I vBefore = ( ptBefore - pt );
+
+                if( std::abs( vBefore.x ) < min_len
+                        && std::abs( vBefore.y ) < min_len
+                        && ptCount > 5)
+                {
+                    ptBefore = pts[ ( ptCount + kk - 2 ) % ptCount ];
+                    vBefore = ( ptBefore - pt );
+                }
+
+                VECTOR2I ptAfter  = pts[ ( kk + 1 ) % ptCount ];
                 VECTOR2I vAfter = ( ptAfter - pt );
+
+                if( std::abs( vAfter.x ) < min_len
+                        && std::abs( vAfter.y ) < min_len
+                        && ptCount > 5 )
+                {
+                    ptAfter  = pts[ ( kk + 2 ) % ptCount ];
+                    vAfter = ( ptAfter - pt );
+                }
+
                 VECTOR2I vIncluded = vBefore.Resize( testLength ) - vAfter.Resize( testLength );
 
                 if( vIncluded.SquaredEuclideanNorm() < SEG::Square( widthTolerance ) )