Break out separate holes-co-located violation.
Fixes https://gitlab.com/kicad/code/kicad/issues/8456
This commit is contained in:
parent
4d227d2d2b
commit
4c3d78dec0
|
@ -241,7 +241,7 @@ set( PCBNEW_DRC_SRCS
|
||||||
drc/drc_test_provider_copper_clearance.cpp
|
drc/drc_test_provider_copper_clearance.cpp
|
||||||
drc/drc_test_provider_courtyard_clearance.cpp
|
drc/drc_test_provider_courtyard_clearance.cpp
|
||||||
drc/drc_test_provider_edge_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_hole_size.cpp
|
||||||
drc/drc_test_provider_lvs.cpp
|
drc/drc_test_provider_lvs.cpp
|
||||||
drc/drc_test_provider_misc.cpp
|
drc/drc_test_provider_misc.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 )
|
for( int errorCode = DRCE_FIRST; errorCode <= DRCE_LAST; ++errorCode )
|
||||||
m_DRCSeverities[ errorCode ] = RPT_SEVERITY_ERROR;
|
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_MISSING_COURTYARD ] = RPT_SEVERITY_IGNORE;
|
||||||
m_DRCSeverities[ DRCE_PTH_IN_COURTYARD ] = RPT_SEVERITY_IGNORE;
|
m_DRCSeverities[ DRCE_PTH_IN_COURTYARD ] = RPT_SEVERITY_IGNORE;
|
||||||
m_DRCSeverities[ DRCE_NPTH_IN_COURTYARD ] = RPT_SEVERITY_IGNORE;
|
m_DRCSeverities[ DRCE_NPTH_IN_COURTYARD ] = RPT_SEVERITY_IGNORE;
|
||||||
|
|
|
@ -93,6 +93,10 @@ DRC_ITEM DRC_ITEM::holeNearHole( DRCE_DRILLED_HOLES_TOO_CLOSE,
|
||||||
_( "Drilled holes too close together" ),
|
_( "Drilled holes too close together" ),
|
||||||
wxT( "hole_near_hole" ) );
|
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,
|
DRC_ITEM DRC_ITEM::trackWidth( DRCE_TRACK_WIDTH,
|
||||||
_( "Track width" ),
|
_( "Track width" ),
|
||||||
wxT( "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_VIA: return std::make_shared<DRC_ITEM>( viaDangling );
|
||||||
case DRCE_DANGLING_TRACK: return std::make_shared<DRC_ITEM>( trackDangling );
|
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_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_HOLE_CLEARANCE: return std::make_shared<DRC_ITEM>( holeClearance );
|
||||||
case DRCE_TRACK_WIDTH: return std::make_shared<DRC_ITEM>( trackWidth );
|
case DRCE_TRACK_WIDTH: return std::make_shared<DRC_ITEM>( trackWidth );
|
||||||
case DRCE_ANNULAR_WIDTH: return std::make_shared<DRC_ITEM>( annularWidth );
|
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_DRILL_OUT_OF_RANGE: return std::make_shared<DRC_ITEM>( drillTooSmall );
|
||||||
case DRCE_VIA_DIAMETER: return std::make_shared<DRC_ITEM>( viaDiameter );
|
case DRCE_VIA_DIAMETER: return std::make_shared<DRC_ITEM>( viaDiameter );
|
||||||
case DRCE_PADSTACK: return std::make_shared<DRC_ITEM>( padstack );
|
case DRCE_PADSTACK: return std::make_shared<DRC_ITEM>( padstack );
|
||||||
case DRCE_MICROVIA_DRILL_OUT_OF_RANGE: return std::make_shared<DRC_ITEM>( microviaDrillTooSmall );
|
case DRCE_MICROVIA_DRILL_OUT_OF_RANGE: return std::make_shared<DRC_ITEM>( microviaDrillTooSmall );
|
||||||
|
|
|
@ -44,6 +44,7 @@ enum PCB_DRC_CODE {
|
||||||
DRCE_DANGLING_VIA, // via which isn't connected to anything
|
DRCE_DANGLING_VIA, // via which isn't connected to anything
|
||||||
DRCE_DANGLING_TRACK, // track with at least one end not 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_TOO_CLOSE, // overlapping drilled holes break drill bits
|
||||||
|
DRCE_DRILLED_HOLES_COLOCATED, // two holes at the same location
|
||||||
DRCE_HOLE_CLEARANCE, //
|
DRCE_HOLE_CLEARANCE, //
|
||||||
DRCE_TRACK_WIDTH, // Track width is too small or too large
|
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_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 viaDangling;
|
||||||
static DRC_ITEM trackDangling;
|
static DRC_ITEM trackDangling;
|
||||||
static DRC_ITEM holeNearHole;
|
static DRC_ITEM holeNearHole;
|
||||||
|
static DRC_ITEM holesCoLocated;
|
||||||
static DRC_ITEM holeClearance;
|
static DRC_ITEM holeClearance;
|
||||||
static DRC_ITEM trackWidth;
|
static DRC_ITEM trackWidth;
|
||||||
static DRC_ITEM annularWidth;
|
static DRC_ITEM annularWidth;
|
||||||
|
|
|
@ -35,20 +35,21 @@
|
||||||
Holes clearance test. Checks pad and via holes for their mechanical clearances.
|
Holes clearance test. Checks pad and via holes for their mechanical clearances.
|
||||||
Generated errors:
|
Generated errors:
|
||||||
- DRCE_DRILLED_HOLES_TOO_CLOSE
|
- DRCE_DRILLED_HOLES_TOO_CLOSE
|
||||||
|
- DRCE_DRILLED_HOLES_COLOCATED
|
||||||
|
|
||||||
TODO: vias-in-smd-pads check
|
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:
|
public:
|
||||||
DRC_TEST_PROVIDER_HOLE_CLEARANCE () :
|
DRC_TEST_PROVIDER_HOLE_TO_HOLE () :
|
||||||
DRC_TEST_PROVIDER_CLEARANCE_BASE(),
|
DRC_TEST_PROVIDER_CLEARANCE_BASE(),
|
||||||
m_board( nullptr )
|
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
|
virtual const wxString GetName() const override
|
||||||
{
|
{
|
||||||
return "hole_clearance";
|
return "hole_to_hole_clearance";
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual const wxString GetDescription() const override
|
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
|
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,
|
bool DRC_TEST_PROVIDER_HOLE_TO_HOLE::testHoleAgainstHole( BOARD_ITEM* aItem, SHAPE_CIRCLE* aHole,
|
||||||
BOARD_ITEM* aOther )
|
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;
|
return false;
|
||||||
|
|
||||||
std::shared_ptr<SHAPE_CIRCLE> otherHole = getDrilledHoleShape( aOther );
|
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
|
// Holes at same location generate a separate violation
|
||||||
if( aHole->GetCenter() == otherHole->GetCenter() )
|
if( ( aHole->GetCenter() - otherHole->GetCenter() ).SquaredEuclideanNorm() < epsilon_sq )
|
||||||
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 )
|
|
||||||
{
|
{
|
||||||
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)" ),
|
auto constraint = m_drcEngine->EvalRules( HOLE_TO_HOLE_CONSTRAINT, aItem, aOther,
|
||||||
constraint.GetName(),
|
UNDEFINED_LAYER /* holes pierce all layers */ );
|
||||||
MessageTextFromValue( userUnits(), minClearance ),
|
int minClearance = constraint.GetValue().Min() - epsilon;
|
||||||
MessageTextFromValue( userUnits(), actual ) );
|
|
||||||
|
|
||||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
if( minClearance >= 0 && actual < minClearance )
|
||||||
drce->SetItems( aItem, aOther );
|
{
|
||||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int DRC_TEST_PROVIDER_HOLE_CLEARANCE::GetNumPhases() const
|
int DRC_TEST_PROVIDER_HOLE_TO_HOLE::GetNumPhases() const
|
||||||
{
|
{
|
||||||
return 1;
|
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 };
|
return { HOLE_TO_HOLE_CONSTRAINT };
|
||||||
}
|
}
|
||||||
|
@ -322,5 +338,5 @@ std::set<DRC_CONSTRAINT_T> DRC_TEST_PROVIDER_HOLE_CLEARANCE::GetConstraintTypes(
|
||||||
|
|
||||||
namespace detail
|
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;
|
||||||
}
|
}
|
|
@ -35,7 +35,7 @@ add_executable( drc_proto
|
||||||
../../pcbnew/drc/drc_rule_parser.cpp
|
../../pcbnew/drc/drc_rule_parser.cpp
|
||||||
../../pcbnew/drc/drc_test_provider.cpp
|
../../pcbnew/drc/drc_test_provider.cpp
|
||||||
../../pcbnew/drc/drc_test_provider_copper_clearance.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_edge_clearance.cpp
|
||||||
../../pcbnew/drc/drc_test_provider_hole_size.cpp
|
../../pcbnew/drc/drc_test_provider_hole_size.cpp
|
||||||
../../pcbnew/drc/drc_test_provider_disallow.cpp
|
../../pcbnew/drc/drc_test_provider_disallow.cpp
|
||||||
|
|
|
@ -40,7 +40,7 @@ add_executable( test_pns
|
||||||
../../pcbnew/drc/drc_rule_parser.cpp
|
../../pcbnew/drc/drc_rule_parser.cpp
|
||||||
../../pcbnew/drc/drc_test_provider.cpp
|
../../pcbnew/drc/drc_test_provider.cpp
|
||||||
../../pcbnew/drc/drc_test_provider_copper_clearance.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_edge_clearance.cpp
|
||||||
../../pcbnew/drc/drc_test_provider_hole_size.cpp
|
../../pcbnew/drc/drc_test_provider_hole_size.cpp
|
||||||
../../pcbnew/drc/drc_test_provider_disallow.cpp
|
../../pcbnew/drc/drc_test_provider_disallow.cpp
|
||||||
|
|
Loading…
Reference in New Issue