Break out separate holes-co-located violation.

Fixes https://gitlab.com/kicad/code/kicad/issues/8456
This commit is contained in:
Jeff Young 2021-05-20 10:35:31 +01:00
parent 4d227d2d2b
commit 4c3d78dec0
7 changed files with 64 additions and 39 deletions

View File

@ -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

View File

@ -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;

View File

@ -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> DRC_ITEM::Create( int aErrorCode )
case DRCE_DANGLING_VIA: return std::make_shared<DRC_ITEM>( viaDangling );
case DRCE_DANGLING_TRACK: return std::make_shared<DRC_ITEM>( trackDangling );
case DRCE_DRILLED_HOLES_TOO_CLOSE: return std::make_shared<DRC_ITEM>( holeNearHole );
case DRCE_DRILLED_HOLES_COLOCATED: return std::make_shared<DRC_ITEM>( holesCoLocated );
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_DRILL_OUT_OF_RANGE: return std::make_shared<DRC_ITEM>( drillTooSmall );
case DRCE_ANNULAR_WIDTH: return std::make_shared<DRC_ITEM>( annularWidth );
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_MICROVIA_DRILL_OUT_OF_RANGE: return std::make_shared<DRC_ITEM>( microviaDrillTooSmall );

View File

@ -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;

View File

@ -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<SHAPE_CIRCLE> 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<SHAPE_CIRCLE> 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() );
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();
if( minClearance >= 0 && actual < minClearance )
// Holes at same location generate a separate violation
if( ( aHole->GetCenter() - otherHole->GetCenter() ).SquaredEuclideanNorm() < epsilon_sq )
{
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_DRILLED_HOLES_TOO_CLOSE );
if( reportCoLocation )
{
std::shared_ptr<DRC_ITEM> 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() );
m_msg.Printf( _( "(%s min %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), minClearance ),
MessageTextFromValue( userUnits(), actual ) );
auto constraint = m_drcEngine->EvalRules( HOLE_TO_HOLE_CONSTRAINT, aItem, aOther,
UNDEFINED_LAYER /* holes pierce all layers */ );
int minClearance = constraint.GetValue().Min() - epsilon;
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetItems( aItem, aOther );
drce->SetViolatingRule( constraint.GetParentRule() );
if( minClearance >= 0 && actual < minClearance )
{
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_DRILLED_HOLES_TOO_CLOSE );
reportViolation( drce, (wxPoint) aHole->GetCenter() );
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() );
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_CONSTRAINT_T> DRC_TEST_PROVIDER_HOLE_CLEARANCE::GetConstraintTypes() const
std::set<DRC_CONSTRAINT_T> DRC_TEST_PROVIDER_HOLE_TO_HOLE::GetConstraintTypes() const
{
return { HOLE_TO_HOLE_CONSTRAINT };
}
@ -322,5 +338,5 @@ std::set<DRC_CONSTRAINT_T> DRC_TEST_PROVIDER_HOLE_CLEARANCE::GetConstraintTypes(
namespace detail
{
static DRC_REGISTER_TEST_PROVIDER<DRC_TEST_PROVIDER_HOLE_CLEARANCE> dummy;
static DRC_REGISTER_TEST_PROVIDER<DRC_TEST_PROVIDER_HOLE_TO_HOLE> dummy;
}

View File

@ -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

View File

@ -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