From 36d197d8b6f3be2ae2df2464cf4932b7e4297f3f Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Wed, 3 Jun 2020 18:46:44 +0100 Subject: [PATCH] Increase pad clearance test epsilon to polygonization max error. Fixes https://gitlab.com/kicad/code/kicad/issues/4604 --- pcbnew/drc/drc.cpp | 38 ++++++++++----------- pcbnew/drc/drc_clearance_test_functions.cpp | 9 +++-- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/pcbnew/drc/drc.cpp b/pcbnew/drc/drc.cpp index 55bea08393..9cbd5444f6 100644 --- a/pcbnew/drc/drc.cpp +++ b/pcbnew/drc/drc.cpp @@ -676,8 +676,7 @@ void DRC::testUnconnected() void DRC::testZones( BOARD_COMMIT& aCommit ) { - BOARD* board = m_editFrame->GetBoard(); - BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings(); + BOARD_DESIGN_SETTINGS& bds = m_pcb->GetDesignSettings(); // Test copper areas for valid netcodes // if a netcode is < 0 the netname was not found when reading a netlist @@ -689,7 +688,7 @@ void DRC::testZones( BOARD_COMMIT& aCommit ) // if it differs from the net name from net code, there is a DRC issue std::vector smoothed_polys; - smoothed_polys.resize( board->GetAreaCount() ); + smoothed_polys.resize( m_pcb->GetAreaCount() ); for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ ) { @@ -713,26 +712,26 @@ void DRC::testZones( BOARD_COMMIT& aCommit ) } } - ZONE_CONTAINER* zoneRef = board->GetArea( ii ); + ZONE_CONTAINER* zoneRef = m_pcb->GetArea( ii ); std::set colinearCorners; - zoneRef->GetColinearCorners( board, colinearCorners ); + zoneRef->GetColinearCorners( m_pcb, colinearCorners ); zoneRef->BuildSmoothedPoly( smoothed_polys[ii], &colinearCorners ); } // iterate through all areas - for( int ia = 0; ia < board->GetAreaCount(); ia++ ) + for( int ia = 0; ia < m_pcb->GetAreaCount(); ia++ ) { - ZONE_CONTAINER* zoneRef = board->GetArea( ia ); + ZONE_CONTAINER* zoneRef = m_pcb->GetArea( ia ); if( !zoneRef->IsOnCopperLayer() ) continue; // If we are testing a single zone, then iterate through all other zones // Otherwise, we have already tested the zone combination - for( int ia2 = ia + 1; ia2 < board->GetAreaCount(); ia2++ ) + for( int ia2 = ia + 1; ia2 < m_pcb->GetAreaCount(); ia2++ ) { - ZONE_CONTAINER* zoneToTest = board->GetArea( ia2 ); + ZONE_CONTAINER* zoneToTest = m_pcb->GetArea( ia2 ); if( zoneRef == zoneToTest ) continue; @@ -1144,15 +1143,12 @@ void DRC::testOutline( BOARD_COMMIT& aCommit ) void DRC::testDisabledLayers( BOARD_COMMIT& aCommit ) { - BOARD* board = m_editFrame->GetBoard(); - wxCHECK( board, /*void*/ ); - - LSET disabledLayers = board->GetEnabledLayers().flip(); + LSET disabledLayers = m_pcb->GetEnabledLayers().flip(); // Perform the test only for copper layers disabledLayers &= LSET::AllCuMask(); - for( TRACK* track : board->Tracks() ) + for( TRACK* track : m_pcb->Tracks() ) { if( disabledLayers.test( track->GetLayer() ) ) { @@ -1169,7 +1165,7 @@ void DRC::testDisabledLayers( BOARD_COMMIT& aCommit ) } } - for( MODULE* module : board->Modules() ) + for( MODULE* module : m_pcb->Modules() ) { module->RunOnChildren( [&]( BOARD_ITEM* child ) @@ -1190,7 +1186,7 @@ void DRC::testDisabledLayers( BOARD_COMMIT& aCommit ) } ); } - for( ZONE_CONTAINER* zone : board->Zones() ) + for( ZONE_CONTAINER* zone : m_pcb->Zones() ) { if( disabledLayers.test( zone->GetLayer() ) ) { @@ -1213,9 +1209,10 @@ bool DRC::doPadToPadsDrc( BOARD_COMMIT& aCommit, D_PAD* aRefPad, D_PAD** aStart, int x_limit ) { const static LSET all_cu = LSET::AllCuMask(); - constexpr int TOLERANCE = 1; // 1nm tolerance for rotated pad rounding errors. - LSET layerMask = aRefPad->GetLayerSet() & all_cu; + // Allow an epsilon at least as great as our allowed polygonisation error. + int epsilon = m_pcb->GetDesignSettings().m_MaxError; + LSET layerMask = aRefPad->GetLayerSet() & all_cu; // For hole testing we use a dummy pad which is given the shape of the hole. Note that // this pad must have a parent because some functions expect a non-null parent to find @@ -1349,10 +1346,11 @@ bool DRC::doPadToPadsDrc( BOARD_COMMIT& aCommit, D_PAD* aRefPad, D_PAD** aStart, continue; } - int minClearance = aRefPad->GetClearance( pad, &m_clearanceSource ) - TOLERANCE; + int minClearance = aRefPad->GetClearance( pad, &m_clearanceSource ); + int clearanceAllowed = minClearance - epsilon; int actual; - if( !checkClearancePadToPad( aRefPad, pad, minClearance, &actual ) ) + if( !checkClearancePadToPad( aRefPad, pad, clearanceAllowed, &actual ) ) { DRC_ITEM* drcItem = new DRC_ITEM( DRCE_PAD_NEAR_PAD ); diff --git a/pcbnew/drc/drc_clearance_test_functions.cpp b/pcbnew/drc/drc_clearance_test_functions.cpp index 14b90ee881..30ddcec9ef 100644 --- a/pcbnew/drc/drc_clearance_test_functions.cpp +++ b/pcbnew/drc/drc_clearance_test_functions.cpp @@ -149,7 +149,6 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS int refSegWidth = aRefSeg->GetWidth(); - /******************************************/ /* Phase 0 : via DRC tests : */ /******************************************/ @@ -356,6 +355,9 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS /* Phase 1 : test DRC track to pads : */ /******************************************/ + // Allow an epsilon at least as great as our allowed polygonisation error. + int epsilon = m_pcb->GetDesignSettings().m_MaxError; + // Compute the min distance to pads for( MODULE* mod : m_pcb->Modules() ) { @@ -417,7 +419,7 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS SEG slotSeg( slotStart, slotEnd ); int widths = ( slotWidth + refSegWidth ) / 2; - int center2centerAllowed = minClearance + widths; + int center2centerAllowed = minClearance + widths + epsilon; // Avoid square-roots if possible (for performance) SEG::ecoord center2center_squared = refSeg.SquaredDistance( slotSeg ); @@ -444,9 +446,10 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS } int minClearance = aRefSeg->GetClearance( pad, &m_clearanceSource ); + int clearanceAllowed = minClearance - epsilon; int actual; - if( !checkClearanceSegmToPad( refSeg, refSegWidth, pad, minClearance, &actual ) ) + if( !checkClearanceSegmToPad( refSeg, refSegWidth, pad, clearanceAllowed, &actual ) ) { actual = std::max( 0, actual ); SEG padSeg( pad->GetPosition(), pad->GetPosition() );