From 4c3d78dec08f3a79d134fe532e23a00960a92f91 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Thu, 20 May 2021 10:35:31 +0100 Subject: [PATCH] Break out separate holes-co-located violation. Fixes https://gitlab.com/kicad/code/kicad/issues/8456 --- pcbnew/CMakeLists.txt | 2 +- pcbnew/board_design_settings.cpp | 2 + pcbnew/drc/drc_item.cpp | 9 +- pcbnew/drc/drc_item.h | 2 + ...cpp => drc_test_provider_hole_to_hole.cpp} | 82 +++++++++++-------- qa/drc_proto/CMakeLists.txt | 2 +- qa/pns/CMakeLists.txt | 2 +- 7 files changed, 63 insertions(+), 38 deletions(-) rename pcbnew/drc/{drc_test_provider_hole_clearance.cpp => drc_test_provider_hole_to_hole.cpp} (75%) diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 4181254964..84ae6a0e35 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -241,7 +241,7 @@ set( PCBNEW_DRC_SRCS drc/drc_test_provider_copper_clearance.cpp drc/drc_test_provider_courtyard_clearance.cpp drc/drc_test_provider_edge_clearance.cpp - drc/drc_test_provider_hole_clearance.cpp + drc/drc_test_provider_hole_to_hole.cpp drc/drc_test_provider_hole_size.cpp drc/drc_test_provider_lvs.cpp drc/drc_test_provider_misc.cpp diff --git a/pcbnew/board_design_settings.cpp b/pcbnew/board_design_settings.cpp index 38bc88ee0d..2876851f35 100644 --- a/pcbnew/board_design_settings.cpp +++ b/pcbnew/board_design_settings.cpp @@ -149,6 +149,8 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std: for( int errorCode = DRCE_FIRST; errorCode <= DRCE_LAST; ++errorCode ) m_DRCSeverities[ errorCode ] = RPT_SEVERITY_ERROR; + m_DRCSeverities[ DRCE_DRILLED_HOLES_COLOCATED ] = RPT_SEVERITY_WARNING; + m_DRCSeverities[ DRCE_MISSING_COURTYARD ] = RPT_SEVERITY_IGNORE; m_DRCSeverities[ DRCE_PTH_IN_COURTYARD ] = RPT_SEVERITY_IGNORE; m_DRCSeverities[ DRCE_NPTH_IN_COURTYARD ] = RPT_SEVERITY_IGNORE; diff --git a/pcbnew/drc/drc_item.cpp b/pcbnew/drc/drc_item.cpp index 5611107764..64c14f74ab 100644 --- a/pcbnew/drc/drc_item.cpp +++ b/pcbnew/drc/drc_item.cpp @@ -93,6 +93,10 @@ DRC_ITEM DRC_ITEM::holeNearHole( DRCE_DRILLED_HOLES_TOO_CLOSE, _( "Drilled holes too close together" ), wxT( "hole_near_hole" ) ); +DRC_ITEM DRC_ITEM::holesCoLocated( DRCE_DRILLED_HOLES_COLOCATED, + _( "Drilled holes co-located" ), + wxT( "holes_co_located" ) ); + DRC_ITEM DRC_ITEM::trackWidth( DRCE_TRACK_WIDTH, _( "Track width" ), wxT( "track_width" ) ); @@ -257,10 +261,11 @@ std::shared_ptr DRC_ITEM::Create( int aErrorCode ) case DRCE_DANGLING_VIA: return std::make_shared( viaDangling ); case DRCE_DANGLING_TRACK: return std::make_shared( trackDangling ); case DRCE_DRILLED_HOLES_TOO_CLOSE: return std::make_shared( holeNearHole ); + case DRCE_DRILLED_HOLES_COLOCATED: return std::make_shared( holesCoLocated ); case DRCE_HOLE_CLEARANCE: return std::make_shared( holeClearance ); case DRCE_TRACK_WIDTH: return std::make_shared( trackWidth ); - case DRCE_ANNULAR_WIDTH: return std::make_shared( annularWidth ); - case DRCE_DRILL_OUT_OF_RANGE: return std::make_shared( drillTooSmall ); + case DRCE_ANNULAR_WIDTH: return std::make_shared( annularWidth ); + case DRCE_DRILL_OUT_OF_RANGE: return std::make_shared( drillTooSmall ); case DRCE_VIA_DIAMETER: return std::make_shared( viaDiameter ); case DRCE_PADSTACK: return std::make_shared( padstack ); case DRCE_MICROVIA_DRILL_OUT_OF_RANGE: return std::make_shared( microviaDrillTooSmall ); diff --git a/pcbnew/drc/drc_item.h b/pcbnew/drc/drc_item.h index 2ba068b6d9..df29410574 100644 --- a/pcbnew/drc/drc_item.h +++ b/pcbnew/drc/drc_item.h @@ -44,6 +44,7 @@ enum PCB_DRC_CODE { DRCE_DANGLING_VIA, // via which isn't connected to anything DRCE_DANGLING_TRACK, // track with at least one end not connected to anything DRCE_DRILLED_HOLES_TOO_CLOSE, // overlapping drilled holes break drill bits + DRCE_DRILLED_HOLES_COLOCATED, // two holes at the same location DRCE_HOLE_CLEARANCE, // DRCE_TRACK_WIDTH, // Track width is too small or too large DRCE_ANNULAR_WIDTH, // Via size and drill leave annulus too small or too large @@ -136,6 +137,7 @@ private: static DRC_ITEM viaDangling; static DRC_ITEM trackDangling; static DRC_ITEM holeNearHole; + static DRC_ITEM holesCoLocated; static DRC_ITEM holeClearance; static DRC_ITEM trackWidth; static DRC_ITEM annularWidth; diff --git a/pcbnew/drc/drc_test_provider_hole_clearance.cpp b/pcbnew/drc/drc_test_provider_hole_to_hole.cpp similarity index 75% rename from pcbnew/drc/drc_test_provider_hole_clearance.cpp rename to pcbnew/drc/drc_test_provider_hole_to_hole.cpp index 3d88c97d48..84f0c6665c 100644 --- a/pcbnew/drc/drc_test_provider_hole_clearance.cpp +++ b/pcbnew/drc/drc_test_provider_hole_to_hole.cpp @@ -35,20 +35,21 @@ Holes clearance test. Checks pad and via holes for their mechanical clearances. Generated errors: - DRCE_DRILLED_HOLES_TOO_CLOSE + - DRCE_DRILLED_HOLES_COLOCATED TODO: vias-in-smd-pads check */ -class DRC_TEST_PROVIDER_HOLE_CLEARANCE : public DRC_TEST_PROVIDER_CLEARANCE_BASE +class DRC_TEST_PROVIDER_HOLE_TO_HOLE : public DRC_TEST_PROVIDER_CLEARANCE_BASE { public: - DRC_TEST_PROVIDER_HOLE_CLEARANCE () : + DRC_TEST_PROVIDER_HOLE_TO_HOLE () : DRC_TEST_PROVIDER_CLEARANCE_BASE(), m_board( nullptr ) { } - virtual ~DRC_TEST_PROVIDER_HOLE_CLEARANCE() + virtual ~DRC_TEST_PROVIDER_HOLE_TO_HOLE() { } @@ -56,7 +57,7 @@ public: virtual const wxString GetName() const override { - return "hole_clearance"; + return "hole_to_hole_clearance"; }; virtual const wxString GetDescription() const override @@ -93,11 +94,12 @@ static std::shared_ptr getDrilledHoleShape( BOARD_ITEM* aItem ) } -bool DRC_TEST_PROVIDER_HOLE_CLEARANCE::Run() +bool DRC_TEST_PROVIDER_HOLE_TO_HOLE::Run() { - if( m_drcEngine->IsErrorLimitExceeded( DRCE_DRILLED_HOLES_TOO_CLOSE ) ) + if( m_drcEngine->IsErrorLimitExceeded( DRCE_DRILLED_HOLES_TOO_CLOSE ) + && m_drcEngine->IsErrorLimitExceeded( DRCE_DRILLED_HOLES_COLOCATED ) ) { - reportAux( "Hole-to-hole violations ignored. Tests not run." ); + reportAux( "Hole to hole violations ignored. Tests not run." ); return true; // continue with other tests } @@ -269,52 +271,66 @@ bool DRC_TEST_PROVIDER_HOLE_CLEARANCE::Run() } -bool DRC_TEST_PROVIDER_HOLE_CLEARANCE::testHoleAgainstHole( BOARD_ITEM* aItem, SHAPE_CIRCLE* aHole, - BOARD_ITEM* aOther ) +bool DRC_TEST_PROVIDER_HOLE_TO_HOLE::testHoleAgainstHole( BOARD_ITEM* aItem, SHAPE_CIRCLE* aHole, + BOARD_ITEM* aOther ) { - if( m_drcEngine->IsErrorLimitExceeded( DRCE_DRILLED_HOLES_TOO_CLOSE ) ) + bool reportCoLocation = !m_drcEngine->IsErrorLimitExceeded( DRCE_DRILLED_HOLES_COLOCATED ); + bool reportHole2Hole = !m_drcEngine->IsErrorLimitExceeded( DRCE_DRILLED_HOLES_TOO_CLOSE ); + + if( !reportCoLocation && !reportHole2Hole ) return false; std::shared_ptr otherHole = getDrilledHoleShape( aOther ); + int epsilon = m_board->GetDesignSettings().GetDRCEpsilon(); + SEG::ecoord epsilon_sq = SEG::Square( epsilon ); - // Holes with identical locations are allowable - if( aHole->GetCenter() == otherHole->GetCenter() ) - return true; - - int actual = ( aHole->GetCenter() - otherHole->GetCenter() ).EuclideanNorm(); - actual = std::max( 0, actual - aHole->GetRadius() - otherHole->GetRadius() ); + // Holes at same location generate a separate violation + if( ( aHole->GetCenter() - otherHole->GetCenter() ).SquaredEuclideanNorm() < epsilon_sq ) + { + if( reportCoLocation ) + { + std::shared_ptr drce = DRC_ITEM::Create( DRCE_DRILLED_HOLES_COLOCATED ); + drce->SetItems( aItem, aOther ); + reportViolation( drce, (wxPoint) aHole->GetCenter() ); + } + } + else if( reportHole2Hole ) + { + int actual = ( aHole->GetCenter() - otherHole->GetCenter() ).EuclideanNorm(); + actual = std::max( 0, actual - aHole->GetRadius() - otherHole->GetRadius() ); - auto constraint = m_drcEngine->EvalRules( HOLE_TO_HOLE_CONSTRAINT, aItem, aOther, - UNDEFINED_LAYER /* holes pierce all layers */ ); - int minClearance = constraint.GetValue().Min() - m_board->GetDesignSettings().GetDRCEpsilon(); + auto constraint = m_drcEngine->EvalRules( HOLE_TO_HOLE_CONSTRAINT, aItem, aOther, + UNDEFINED_LAYER /* holes pierce all layers */ ); + int minClearance = constraint.GetValue().Min() - epsilon; - if( minClearance >= 0 && actual < minClearance ) - { - std::shared_ptr drce = DRC_ITEM::Create( DRCE_DRILLED_HOLES_TOO_CLOSE ); + if( minClearance >= 0 && actual < minClearance ) + { + std::shared_ptr drce = DRC_ITEM::Create( DRCE_DRILLED_HOLES_TOO_CLOSE ); - m_msg.Printf( _( "(%s min %s; actual %s)" ), - constraint.GetName(), - MessageTextFromValue( userUnits(), minClearance ), - MessageTextFromValue( userUnits(), actual ) ); + m_msg.Printf( _( "(%s min %s; actual %s)" ), + constraint.GetName(), + MessageTextFromValue( userUnits(), minClearance ), + MessageTextFromValue( userUnits(), actual ) ); - drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg ); - drce->SetItems( aItem, aOther ); - drce->SetViolatingRule( constraint.GetParentRule() ); + drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg ); + drce->SetItems( aItem, aOther ); + drce->SetViolatingRule( constraint.GetParentRule() ); - reportViolation( drce, (wxPoint) aHole->GetCenter() ); + reportViolation( drce, (wxPoint) aHole->GetCenter() ); + } } return true; } -int DRC_TEST_PROVIDER_HOLE_CLEARANCE::GetNumPhases() const +int DRC_TEST_PROVIDER_HOLE_TO_HOLE::GetNumPhases() const { return 1; } -std::set DRC_TEST_PROVIDER_HOLE_CLEARANCE::GetConstraintTypes() const +std::set DRC_TEST_PROVIDER_HOLE_TO_HOLE::GetConstraintTypes() const { return { HOLE_TO_HOLE_CONSTRAINT }; } @@ -322,5 +338,5 @@ std::set DRC_TEST_PROVIDER_HOLE_CLEARANCE::GetConstraintTypes( namespace detail { - static DRC_REGISTER_TEST_PROVIDER dummy; + static DRC_REGISTER_TEST_PROVIDER dummy; } diff --git a/qa/drc_proto/CMakeLists.txt b/qa/drc_proto/CMakeLists.txt index 56035c4776..926f0f9406 100644 --- a/qa/drc_proto/CMakeLists.txt +++ b/qa/drc_proto/CMakeLists.txt @@ -35,7 +35,7 @@ add_executable( drc_proto ../../pcbnew/drc/drc_rule_parser.cpp ../../pcbnew/drc/drc_test_provider.cpp ../../pcbnew/drc/drc_test_provider_copper_clearance.cpp - ../../pcbnew/drc/drc_test_provider_hole_clearance.cpp + ../../pcbnew/drc/drc_test_provider_hole_to_hole.cpp ../../pcbnew/drc/drc_test_provider_edge_clearance.cpp ../../pcbnew/drc/drc_test_provider_hole_size.cpp ../../pcbnew/drc/drc_test_provider_disallow.cpp diff --git a/qa/pns/CMakeLists.txt b/qa/pns/CMakeLists.txt index 76477ddb07..8825692c03 100644 --- a/qa/pns/CMakeLists.txt +++ b/qa/pns/CMakeLists.txt @@ -40,7 +40,7 @@ add_executable( test_pns ../../pcbnew/drc/drc_rule_parser.cpp ../../pcbnew/drc/drc_test_provider.cpp ../../pcbnew/drc/drc_test_provider_copper_clearance.cpp - ../../pcbnew/drc/drc_test_provider_hole_clearance.cpp + ../../pcbnew/drc/drc_test_provider_hole_to_hole.cpp ../../pcbnew/drc/drc_test_provider_edge_clearance.cpp ../../pcbnew/drc/drc_test_provider_hole_size.cpp ../../pcbnew/drc/drc_test_provider_disallow.cpp