← Back to team overview

kicad-developers team mailing list archive

[PATCH] pcbnew: fix false DRC violations for oval pads

 

(This is also at https://bugs.launchpad.net/kicad/+bug/1455345)

Minimal example screenshot: http://u.forre.st/u/fiyaqxjg/drc.png
Minimal example board file: http://u.forre.st/u/kjzegyao/drc.kicad_pcb

Two pads (one a circle and one an oval) cause a false DRC violation in
certain arrangements.

I am reasonably certain that this is due to the rectangle part of the
segment-oval test in DRC::checkClearanceSegmToPad. This function is
called by DRC::checkClearancePadToPad with the circle pad having been
transformed to a zero-length segment and the oval pad remaining as is.
Then, DRC::checkClearanceSegmToPad looks at the oval pad as two
circles and a rectangle, testing the segment against each, grown
according to the segment's width and the clearance. The rectangle is
grown at each end of its short axis by half the width of the segment
(the radius of the circular pad in this case) plus the clearance
(which makes sense) and grown at each end of its long axis by half the
width of the segment (!!!).

Growing the rectangular part of the pad along its long axis by
anything is wrong because the dilation of a rectangle is a rounded
rectangle, but by growing it along both axes, we form a shape that is
bigger than what it should be (it has corners that shouldn't be
there). We don't need to grow it along its long axis at all, because
intersections near the ends of the pad are taken care of by the circle
tests.

A patch that fixes this issue, as I see it, is here:


diff --git a/pcbnew/drc_clearance_test_
functions.cpp
b/pcbnew/drc_clearance_test_
functions.cpp
index 87acf72..af5f78d 100644
--- a/pcbnew/drc_clearance_test_
functions.cpp
+++ b/pcbnew/drc_clearance_test_functions.cpp
@@ -897,9 +897,9 @@ bool DRC::checkClearanceSegmToPad( const D_PAD*
aPad, int aSegmentWidth, int aMi

         // Test the rectangle area between the two circles
         m_xcliplo = m_padToTestPos.x - seuil - padHalfsize.x;
-        m_ycliplo = m_padToTestPos.y - segmHalfWidth - deltay;
+        m_ycliplo = m_padToTestPos.y - deltay;
         m_xcliphi = m_padToTestPos.x + seuil + padHalfsize.x;
-        m_ycliphi = m_padToTestPos.y + segmHalfWidth + deltay;
+        m_ycliphi = m_padToTestPos.y + deltay;

         if( !checkLine( startPoint, endPoint ) )
         {


Note that the reason that this hasn't been noticed until now even
though DRC::checkClearanceSegmToPad is used to check traces against
pads is that the effect of this bug is vanishingly small unless the
segment (here being the circular pad) is much larger than the pad
(here being the oval pad). Indeed, I can trigger the same bug with a
big enough segment and the same oval pad:
http://u.forre.st/u/yftulnmj/drc2.png
http://u.forre.st/u/bnfxrhwc/drc2.kicad_pcb


Follow ups