Implement max hole size DRC checks.

Fixes https://gitlab.com/kicad/code/kicad/issues/6893
This commit is contained in:
Jeff Young 2021-01-03 22:57:51 +00:00
parent 710e621c6a
commit 7378c2c3b3
3 changed files with 82 additions and 36 deletions

View File

@ -101,9 +101,9 @@ DRC_ITEM DRC_ITEM::annularWidth( DRCE_ANNULAR_WIDTH,
_( "Annular width" ),
wxT( "annular_width" ) );
DRC_ITEM DRC_ITEM::drillTooSmall( DRCE_TOO_SMALL_DRILL,
_( "Drill too small" ),
wxT( "drill_too_small" ) );
DRC_ITEM DRC_ITEM::drillTooSmall( DRCE_DRILL_OUT_OF_RANGE,
_( "Drill out of range" ),
wxT( "drill_out_of_range" ) );
DRC_ITEM DRC_ITEM::viaDiameter( DRCE_VIA_DIAMETER,
_( "Via diameter" ),
@ -113,9 +113,9 @@ DRC_ITEM DRC_ITEM::padstack( DRCE_PADSTACK,
_( "Padstack is not valid" ),
wxT( "padstack" ) );
DRC_ITEM DRC_ITEM::microviaDrillTooSmall( DRCE_TOO_SMALL_MICROVIA_DRILL,
_( "Micro via drill too small" ),
wxT( "microvia_drill_too_small" ) );
DRC_ITEM DRC_ITEM::microviaDrillTooSmall( DRCE_MICROVIA_DRILL_OUT_OF_RANGE,
_( "Micro via drill out of range" ),
wxT( "microvia_drill_out_of_range" ) );
DRC_ITEM DRC_ITEM::courtyardsOverlap( DRCE_OVERLAPPING_FOOTPRINTS,
_( "Courtyards overlap" ),
@ -260,10 +260,10 @@ std::shared_ptr<DRC_ITEM> DRC_ITEM::Create( int aErrorCode )
case DRCE_HOLE_CLEARANCE: return std::make_shared<DRC_ITEM>( holeClearance );
case DRCE_TRACK_WIDTH: return std::make_shared<DRC_ITEM>( trackWidth );
case DRCE_ANNULAR_WIDTH: return std::make_shared<DRC_ITEM>( annularWidth );
case DRCE_TOO_SMALL_DRILL: return std::make_shared<DRC_ITEM>( drillTooSmall );
case DRCE_DRILL_OUT_OF_RANGE: return std::make_shared<DRC_ITEM>( drillTooSmall );
case DRCE_VIA_DIAMETER: return std::make_shared<DRC_ITEM>( viaDiameter );
case DRCE_PADSTACK: return std::make_shared<DRC_ITEM>( padstack );
case DRCE_TOO_SMALL_MICROVIA_DRILL: return std::make_shared<DRC_ITEM>( microviaDrillTooSmall );
case DRCE_MICROVIA_DRILL_OUT_OF_RANGE: return std::make_shared<DRC_ITEM>( microviaDrillTooSmall );
case DRCE_OVERLAPPING_FOOTPRINTS: return std::make_shared<DRC_ITEM>( courtyardsOverlap );
case DRCE_MISSING_COURTYARD: return std::make_shared<DRC_ITEM>( missingCourtyard );
case DRCE_MALFORMED_COURTYARD: return std::make_shared<DRC_ITEM>( malformedCourtyard );

View File

@ -47,10 +47,10 @@ enum PCB_DRC_CODE {
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
DRCE_TOO_SMALL_DRILL, // Too small via or pad drill
DRCE_DRILL_OUT_OF_RANGE, // Too small via or pad drill
DRCE_VIA_DIAMETER, // Via diameter checks (min/max)
DRCE_PADSTACK, // something is wrong with a pad or via stackup
DRCE_TOO_SMALL_MICROVIA_DRILL, // Too small micro via drill
DRCE_MICROVIA_DRILL_OUT_OF_RANGE, // Too small micro via drill
DRCE_OVERLAPPING_FOOTPRINTS, // footprint courtyards overlap
DRCE_MISSING_COURTYARD, // footprint has no courtyard defined
DRCE_MALFORMED_COURTYARD, // footprint has a courtyard but malformed

View File

@ -23,7 +23,6 @@
#include <pad.h>
#include <track.h>
#include <drc/drc_engine.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc_test_provider_clearance_base.h>
@ -32,10 +31,8 @@
/*
Drilled hole size test. scans vias/through-hole pads and checks for min drill sizes
Errors generated:
- DRCE_TOO_SMALL_DRILL
- DRCE_TOO_SMALL_MICROVIA_DRILL
TODO: max drill size check
- DRCE_DRILL_OUT_OF_RANGE
- DRCE_MICROVIA_DRILL_OUT_OF_RANGE
*/
class DRC_TEST_PROVIDER_HOLE_SIZE : public DRC_TEST_PROVIDER
@ -83,12 +80,12 @@ bool DRC_TEST_PROVIDER_HOLE_SIZE::Run()
for( FOOTPRINT* footprint : m_board->Footprints() )
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_TOO_SMALL_DRILL ) )
if( m_drcEngine->IsErrorLimitExceeded( DRCE_DRILL_OUT_OF_RANGE ) )
break;
for( PAD* pad : footprint->Pads() )
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_TOO_SMALL_DRILL ) )
if( m_drcEngine->IsErrorLimitExceeded( DRCE_DRILL_OUT_OF_RANGE ) )
break;
checkPad( pad );
@ -109,8 +106,8 @@ bool DRC_TEST_PROVIDER_HOLE_SIZE::Run()
for( VIA* via : vias )
{
bool exceedMicro = m_drcEngine->IsErrorLimitExceeded( DRCE_TOO_SMALL_MICROVIA_DRILL );
bool exceedStd = m_drcEngine->IsErrorLimitExceeded( DRCE_TOO_SMALL_DRILL );
bool exceedMicro = m_drcEngine->IsErrorLimitExceeded( DRCE_MICROVIA_DRILL_OUT_OF_RANGE );
bool exceedStd = m_drcEngine->IsErrorLimitExceeded( DRCE_DRILL_OUT_OF_RANGE );
if( exceedMicro && exceedStd )
break;
@ -126,24 +123,49 @@ bool DRC_TEST_PROVIDER_HOLE_SIZE::Run()
void DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( PAD* aPad )
{
int holeSize = std::min( aPad->GetDrillSize().x, aPad->GetDrillSize().y );
int holeMinor = std::min( aPad->GetDrillSize().x, aPad->GetDrillSize().y );
int holeMajor = std::max( aPad->GetDrillSize().x, aPad->GetDrillSize().y );
if( holeSize == 0 )
if( holeMinor == 0 )
return;
auto constraint = m_drcEngine->EvalRulesForItems( HOLE_SIZE_CONSTRAINT, aPad );
int minHole = constraint.GetValue().Min();
bool fail_min = false;
bool fail_max = false;
int constraintValue;
accountCheck( constraint );
if( holeSize < minHole )
if( constraint.Value().HasMin() && holeMinor < constraint.Value().Min() )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_TOO_SMALL_DRILL );
fail_min = true;
constraintValue = constraint.Value().Min();
}
m_msg.Printf( _( "(%s %s; actual %s)" ),
if( constraint.Value().HasMax() && holeMajor > constraint.Value().Max() )
{
fail_max = true;
constraintValue = constraint.Value().Max();
}
if( fail_min || fail_max )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_DRILL_OUT_OF_RANGE );
if( fail_min )
{
m_msg.Printf( _( "(%s min width %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), minHole ),
MessageTextFromValue( userUnits(), holeSize ) );
MessageTextFromValue( userUnits(), constraintValue ),
MessageTextFromValue( userUnits(), holeMinor ) );
}
else
{
m_msg.Printf( _( "(%s max width %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), constraintValue ),
MessageTextFromValue( userUnits(), holeMajor ) );
}
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
drcItem->SetItems( aPad );
@ -163,29 +185,53 @@ void DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via, bool aExceedMicro, bool aE
if( aExceedMicro )
return;
errorCode = DRCE_TOO_SMALL_MICROVIA_DRILL;
errorCode = DRCE_MICROVIA_DRILL_OUT_OF_RANGE;
}
else
{
if( aExceedStd )
return;
errorCode = DRCE_TOO_SMALL_DRILL;
errorCode = DRCE_DRILL_OUT_OF_RANGE;
}
auto constraint = m_drcEngine->EvalRulesForItems( HOLE_SIZE_CONSTRAINT, via );
int minHole = constraint.GetValue().Min();
bool fail_min = false;
bool fail_max = false;
int constraintValue;
accountCheck( constraint );
if( via->GetDrillValue() < minHole )
if( constraint.Value().HasMin() && via->GetDrillValue() < constraint.Value().Min() )
{
fail_min = true;
constraintValue = constraint.Value().Min();
}
if( constraint.Value().HasMax() && via->GetDrillValue() > constraint.Value().Max() )
{
fail_max = true;
constraintValue = constraint.Value().Max();
}
if( fail_min || fail_max )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( errorCode );
m_msg.Printf( _( "(%s %s; actual %s)" ),
if( fail_min )
{
m_msg.Printf( _( "(%s min width %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), minHole ),
MessageTextFromValue( userUnits(), constraintValue ),
MessageTextFromValue( userUnits(), via->GetDrillValue() ) );
}
else
{
m_msg.Printf( _( "(%s max width %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), constraintValue ),
MessageTextFromValue( userUnits(), via->GetDrillValue() ) );
}
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
drcItem->SetItems( via );