Start pulling new DRC engine into Kicad.

This commit is contained in:
Jeff Young 2020-09-11 16:04:11 +01:00
parent 6b4a6f4d3e
commit cc86630f11
63 changed files with 743 additions and 5738 deletions

View File

@ -236,6 +236,8 @@ set( PCBNEW_DRC_SRCS
drc/drc_textvar_tester.cpp
drc/drc.cpp
drc/drc_clearance_test_functions.cpp
drc/drc_engine.cpp
drc/drc_test_provider.cpp
drc/drc_rule_parser.cpp
drc/footprint_tester.cpp
)

View File

@ -156,8 +156,8 @@ bool BOARD_CONNECTED_ITEM::GetRuleClearance( BOARD_ITEM* aItem, PCB_LAYER_ID aLa
int* aClearance, wxString* aSource,
REPORTER* aReporter ) const
{
const DRC_CONSTRAINT* constraint = GetConstraint( this, aItem, DRC_RULE_ID_CLEARANCE, aLayer,
aSource, aReporter );
const DRC_CONSTRAINT* constraint = GetConstraint( this, aItem, DRC_CONSTRAINT_TYPE_CLEARANCE,
aLayer, aSource, aReporter );
if( constraint )
{

View File

@ -836,7 +836,7 @@ int BOARD_DESIGN_SETTINGS::GetBiggestClearanceValue()
{
for( const DRC_CONSTRAINT& constraint : rule->m_Constraints )
{
if( constraint.m_Type == DRC_RULE_ID_CLEARANCE )
if( constraint.m_Type == DRC_CONSTRAINT_TYPE_CLEARANCE )
clearance = std::max( clearance, constraint.m_Value.Min() );
}
}

View File

@ -139,8 +139,9 @@ void TRACK::GetWidthConstraints( int* aMin, int* aMax, wxString* aSource ) const
// Not currently implemented
// LEVEL 2: Rules
const DRC_CONSTRAINT* constraint = GetConstraint( this, nullptr, DRC_RULE_ID_TRACK, m_Layer,
aSource );
const DRC_CONSTRAINT* constraint = GetConstraint( this, nullptr,
DRC_CONSTRAINT_TYPE_TRACK_WIDTH,
m_Layer, aSource );
if( constraint )
{
@ -177,8 +178,9 @@ int VIA::GetMinAnnulus( PCB_LAYER_ID aLayer, wxString* aSource ) const
return 0;
}
const DRC_CONSTRAINT* constraint = GetConstraint( this, nullptr, DRC_RULE_ID_ANNULUS, aLayer,
aSource );
const DRC_CONSTRAINT* constraint = GetConstraint( this, nullptr,
DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH,
aLayer, aSource );
if( constraint )
{

View File

@ -372,58 +372,58 @@ int ZONE_CONTAINER::GetKeepouts( PCB_LAYER_ID aLayer, std::map<int, wxString>* a
source = _( "zone properties" );
if( m_doNotAllowTracks )
setFlag( DISALLOW_TRACKS );
setFlag( DRC_DISALLOW_TRACKS );
if( m_doNotAllowVias )
setFlag( DISALLOW_VIAS );
setFlag( DRC_DISALLOW_VIAS );
if( m_doNotAllowPads )
setFlag( DISALLOW_PADS );
setFlag( DRC_DISALLOW_PADS );
if( m_doNotAllowFootprints )
setFlag( DISALLOW_FOOTPRINTS );
setFlag( DRC_DISALLOW_FOOTPRINTS );
if( m_doNotAllowCopperPour )
setFlag( DISALLOW_ZONES );
setFlag( DRC_DISALLOW_ZONES );
}
const DRC_CONSTRAINT* constraint = GetConstraint( this, nullptr, DRC_RULE_ID_DISALLOW, aLayer,
&source );
const DRC_CONSTRAINT* constraint = GetConstraint( this, nullptr, DRC_CONSTRAINT_TYPE_DISALLOW,
aLayer, &source );
if( constraint )
{
if( aSources )
source = wxString::Format( _( "'%s' rule" ), source );
if( ( constraint->m_DisallowFlags & DISALLOW_VIAS ) > 0 )
setFlag( DISALLOW_VIAS );
if( ( constraint->m_DisallowFlags & DRC_DISALLOW_VIAS ) > 0 )
setFlag( DRC_DISALLOW_VIAS );
if( ( constraint->m_DisallowFlags & DISALLOW_MICRO_VIAS ) > 0 )
setFlag( DISALLOW_MICRO_VIAS );
if( ( constraint->m_DisallowFlags & DRC_DISALLOW_MICRO_VIAS ) > 0 )
setFlag( DRC_DISALLOW_MICRO_VIAS );
if( ( constraint->m_DisallowFlags & DISALLOW_BB_VIAS ) > 0 )
setFlag( DISALLOW_BB_VIAS );
if( ( constraint->m_DisallowFlags & DRC_DISALLOW_BB_VIAS ) > 0 )
setFlag( DRC_DISALLOW_BB_VIAS );
if( ( constraint->m_DisallowFlags & DISALLOW_TRACKS ) > 0 )
setFlag( DISALLOW_TRACKS );
if( ( constraint->m_DisallowFlags & DRC_DISALLOW_TRACKS ) > 0 )
setFlag( DRC_DISALLOW_TRACKS );
if( ( constraint->m_DisallowFlags & DISALLOW_PADS ) > 0 )
setFlag( DISALLOW_PADS );
if( ( constraint->m_DisallowFlags & DRC_DISALLOW_PADS ) > 0 )
setFlag( DRC_DISALLOW_PADS );
if( ( constraint->m_DisallowFlags & DISALLOW_ZONES ) > 0 )
setFlag( DISALLOW_ZONES );
if( ( constraint->m_DisallowFlags & DRC_DISALLOW_ZONES ) > 0 )
setFlag( DRC_DISALLOW_ZONES );
if( ( constraint->m_DisallowFlags & DISALLOW_TEXTS ) > 0 )
setFlag( DISALLOW_TEXTS );
if( ( constraint->m_DisallowFlags & DRC_DISALLOW_TEXTS ) > 0 )
setFlag( DRC_DISALLOW_TEXTS );
if( ( constraint->m_DisallowFlags & DISALLOW_GRAPHICS ) > 0 )
setFlag( DISALLOW_GRAPHICS );
if( ( constraint->m_DisallowFlags & DRC_DISALLOW_GRAPHICS ) > 0 )
setFlag( DRC_DISALLOW_GRAPHICS );
if( ( constraint->m_DisallowFlags & DISALLOW_HOLES ) > 0 )
setFlag( DISALLOW_HOLES );
if( ( constraint->m_DisallowFlags & DRC_DISALLOW_HOLES ) > 0 )
setFlag( DRC_DISALLOW_HOLES );
if( ( constraint->m_DisallowFlags & DISALLOW_FOOTPRINTS ) > 0 )
setFlag( DISALLOW_FOOTPRINTS );
if( ( constraint->m_DisallowFlags & DRC_DISALLOW_FOOTPRINTS ) > 0 )
setFlag( DRC_DISALLOW_FOOTPRINTS );
}
return keepouts;

View File

@ -29,7 +29,7 @@
#include <tools/pcb_actions.h>
#include <tracks_cleaner.h>
#include <drc/drc_item.h>
#include <drc/drc_provider.h>
#include <drc/drc_results_provider.h>
#include <tools/zone_filler_tool.h>
DIALOG_CLEANUP_TRACKS_AND_VIAS::DIALOG_CLEANUP_TRACKS_AND_VIAS( PCB_EDIT_FRAME* aParentFrame ) :

View File

@ -39,38 +39,41 @@
/// DRC error codes:
enum PCB_DRC_CODE {
DRCE_FIRST = 1,
DRCE_UNCONNECTED_ITEMS = DRCE_FIRST, ///< items are unconnected
DRCE_SHORTING_ITEMS, ///< items short two nets but are not a net tie
DRCE_ALLOWED_ITEMS, ///< a disallowed item has been used
DRCE_CLEARANCE, ///< items are too close together
DRCE_TRACKS_CROSSING, ///< tracks are crossing
DRCE_COPPER_EDGE_CLEARANCE, ///< a copper item is too close to the board edge
DRCE_ZONES_INTERSECT, ///< copper area outlines intersect
DRCE_ZONE_HAS_EMPTY_NET, ///< copper area has a net but no pads in nets, which is suspicious
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_TRACK_WIDTH, ///< Track width is too small or too large
DRCE_TOO_SMALL_VIA, ///< Too small via size
DRCE_VIA_ANNULUS, ///< Via size and drill leave annulus too small or too large
DRCE_TOO_SMALL_DRILL, ///< Too small via or pad drill
DRCE_VIA_HOLE_BIGGER, ///< via's hole is bigger than its diameter
DRCE_PADSTACK, ///< something is wrong with a pad or via stackup
DRCE_TOO_SMALL_MICROVIA, ///< Too small micro via size
DRCE_TOO_SMALL_MICROVIA_DRILL, ///< Too small micro via drill
DRCE_KEEPOUT, ///< A disallowed object is inside a keepout
DRCE_OVERLAPPING_FOOTPRINTS, ///< footprint courtyards overlap
DRCE_MISSING_COURTYARD, ///< footprint has no courtyard defined
DRCE_MALFORMED_COURTYARD, ///< footprint has a courtyard but malformed
///< (not convertible to a closed polygon with holes)
DRCE_UNCONNECTED_ITEMS = DRCE_FIRST, // items are unconnected
DRCE_SHORTING_ITEMS, // items short two nets but are not a net-tie
DRCE_ALLOWED_ITEMS, // a disallowed item has been used
DRCE_CLEARANCE, // items are too close together
DRCE_TRACKS_CROSSING, // tracks are crossing
DRCE_COPPER_EDGE_CLEARANCE, // a copper item is too close to the board edge
DRCE_ZONES_INTERSECT, // copper area outlines intersect
DRCE_ZONE_HAS_EMPTY_NET, // copper area has a net but no pads in nets, which is suspicious
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_HOLE_CLEARANCE, //
DRCE_TRACK_WIDTH, // Track width is too small or too large
DRCE_TOO_SMALL_VIA, // Too small via size
DRCE_ANNULUS, // Via size and drill leave annulus too small or too large
DRCE_TOO_SMALL_DRILL, // Too small via or pad drill
DRCE_VIA_HOLE_BIGGER, // via's hole is bigger than its diameter
DRCE_VIA_DIAMETER, // Via diameter checks (min/max)
DRCE_PADSTACK, // something is wrong with a pad or via stackup
DRCE_TOO_SMALL_MICROVIA, // Too small micro via size
DRCE_TOO_SMALL_MICROVIA_DRILL, // Too small micro via drill
DRCE_KEEPOUT, // A disallowed object is inside a keepout
DRCE_OVERLAPPING_FOOTPRINTS, // footprint courtyards overlap
DRCE_MISSING_COURTYARD, // footprint has no courtyard defined
DRCE_MALFORMED_COURTYARD, // footprint has a courtyard but malformed
// (not convertible to a closed polygon with holes)
DRCE_PTH_IN_COURTYARD,
DRCE_NPTH_IN_COURTYARD,
DRCE_DISABLED_LAYER_ITEM, ///< item on a disabled layer
DRCE_INVALID_OUTLINE, ///< invalid board outline
DRCE_MISSING_FOOTPRINT, ///< footprint not found for netlist item
DRCE_DUPLICATE_FOOTPRINT, ///< more than one footprints found for netlist item
DRCE_EXTRA_FOOTPRINT, ///< netlist item not found for footprint
DRCE_NET_CONFLICT, ///< pad net doesn't match netlist
DRCE_DISABLED_LAYER_ITEM, // item on a disabled layer
DRCE_INVALID_OUTLINE, // invalid board outline
DRCE_MISSING_FOOTPRINT, // footprint not found for netlist item
DRCE_DUPLICATE_FOOTPRINT, // more than one footprints found for netlist item
DRCE_EXTRA_FOOTPRINT, // netlist item not found for footprint
DRCE_NET_CONFLICT, // pad net doesn't match netlist
DRCE_UNRESOLVED_VARIABLE,

View File

@ -43,7 +43,7 @@ void DRC::doSingleViaDRC( BOARD_COMMIT& aCommit, VIA* aRefVia )
{
if( aRefVia->GetWidth() < bds.m_MicroViasMinSize )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_VIA_ANNULUS );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ANNULUS );
m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; actual %s)" ),
MessageTextFromValue( userUnits(), bds.m_MicroViasMinSize, true ),
@ -60,7 +60,7 @@ void DRC::doSingleViaDRC( BOARD_COMMIT& aCommit, VIA* aRefVia )
{
if( aRefVia->GetWidth() < bds.m_ViasMinSize )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_VIA_ANNULUS );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ANNULUS );
m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; actual %s)" ),
MessageTextFromValue( userUnits(), bds.m_ViasMinSize, true ),
@ -231,7 +231,7 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS
{
if( viaAnnulus < minAnnulus )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_VIA_ANNULUS );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ANNULUS );
m_msg.Printf( _( "Via annulus too small (%s %s; actual %s)" ),
m_clearanceSource,
@ -255,7 +255,7 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS
if( viaAnnulus < minAnnulus )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_VIA_ANNULUS );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ANNULUS );
m_msg.Printf( _( "Via annulus too small (%s %s; actual %s)" ),
m_clearanceSource,
@ -303,8 +303,8 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS
{
const SHAPE_SEGMENT* slot = pad->GetEffectiveHoleShape();
const DRC_CONSTRAINT* constraint = GetConstraint( aRefSeg, pad,
DRC_RULE_ID_CLEARANCE, aLayer,
&m_clearanceSource );
DRC_CONSTRAINT_TYPE_CLEARANCE,
aLayer, &m_clearanceSource );
int minClearance;
int actual;

View File

@ -35,7 +35,7 @@
#include <drc/drc_item.h>
DRC_COURTYARD_TESTER::DRC_COURTYARD_TESTER( MARKER_HANDLER aMarkerHandler ) :
DRC_TEST_PROVIDER( std::move( aMarkerHandler ) )
LEGACY_DRC_TEST_PROVIDER( std::move( aMarkerHandler ) )
{
}

View File

@ -25,12 +25,12 @@
#ifndef DRC_COURTYARD_OVERLAP__H
#define DRC_COURTYARD_OVERLAP__H
#include <drc/drc_provider.h>
#include <drc/drc_results_provider.h>
class BOARD;
class DRC_COURTYARD_TESTER : public DRC_TEST_PROVIDER
class DRC_COURTYARD_TESTER : public LEGACY_DRC_TEST_PROVIDER
{
public:
DRC_COURTYARD_TESTER( MARKER_HANDLER aMarkerHandler );

View File

@ -31,7 +31,7 @@
DRC_DRILLED_HOLE_TESTER::DRC_DRILLED_HOLE_TESTER( MARKER_HANDLER aMarkerHandler ) :
DRC_TEST_PROVIDER( std::move( aMarkerHandler ) ),
LEGACY_DRC_TEST_PROVIDER( std::move( aMarkerHandler ) ),
m_units( EDA_UNITS::MILLIMETRES ),
m_board( nullptr ),
m_largestRadius( 0 )
@ -94,7 +94,7 @@ bool DRC_DRILLED_HOLE_TESTER::checkPad( D_PAD* aPad )
if( !bds.Ignore( DRCE_TOO_SMALL_DRILL ) )
{
int minHole;
const DRC_CONSTRAINT* constraint = GetConstraint( aPad, nullptr, DRC_RULE_ID_HOLE_SIZE,
const DRC_CONSTRAINT* constraint = GetConstraint( aPad, nullptr, DRC_CONSTRAINT_TYPE_HOLE_SIZE,
layer, &m_source );
if( constraint )
@ -145,7 +145,7 @@ bool DRC_DRILLED_HOLE_TESTER::checkVia( VIA* via )
if( !bds.Ignore( DRCE_TOO_SMALL_DRILL ) )
{
int minHole;
const DRC_CONSTRAINT* constraint = GetConstraint( via, nullptr, DRC_RULE_ID_HOLE_SIZE,
const DRC_CONSTRAINT* constraint = GetConstraint( via, nullptr, DRC_CONSTRAINT_TYPE_HOLE_SIZE,
layer, &m_source );
if( constraint )
@ -197,7 +197,7 @@ bool DRC_DRILLED_HOLE_TESTER::checkMicroVia( VIA* via )
if( !bds.Ignore( DRCE_TOO_SMALL_MICROVIA_DRILL ) )
{
int minHole;
const DRC_CONSTRAINT* constraint = GetConstraint( via, nullptr, DRC_RULE_ID_HOLE_SIZE,
const DRC_CONSTRAINT* constraint = GetConstraint( via, nullptr, DRC_CONSTRAINT_TYPE_HOLE_SIZE,
layer, &m_source );
if( constraint )

View File

@ -25,14 +25,14 @@
#ifndef DRC_DRILLED_HOLE_TESTER__H
#define DRC_DRILLED_HOLE_TESTER__H
#include <drc/drc_provider.h>
#include <drc/drc_results_provider.h>
class BOARD;
class BOARD_ITEM;
class DRC_DRILLED_HOLE_TESTER : public DRC_TEST_PROVIDER
class DRC_DRILLED_HOLE_TESTER : public LEGACY_DRC_TEST_PROVIDER
{
public:
DRC_DRILLED_HOLE_TESTER( MARKER_HANDLER aMarkerHandler );

View File

@ -30,16 +30,17 @@
#include <reporter.h>
#include <widgets/progress_reporter.h>
#include <drc_proto/drc_engine.h>
#include <drc_proto/drc_rule_parser.h>
#include <drc_proto/drc_rule.h>
#include <drc_proto/drc_item.h>
#include <drc_proto/drc_test_provider.h>
#include <drc/drc_engine.h>
#include <drc/drc_rule_parser.h>
#include <drc/drc_rule.h>
#include <drc/drc_item.h>
#include <drc/drc_test_provider.h>
void drcPrintDebugMessage( int level, wxString msg, const char *function, int line )
{
wxString valueStr;
if( wxGetEnv( "DRC_DEBUG", &valueStr ) )
{
int setLevel = wxAtoi( valueStr );
@ -51,29 +52,28 @@ void drcPrintDebugMessage( int level, wxString msg, const char *function, int li
}
test::DRC_ENGINE::DRC_ENGINE( BOARD* aBoard, BOARD_DESIGN_SETTINGS *aSettings ) :
m_board( aBoard ),
DRC_ENGINE::DRC_ENGINE( BOARD* aBoard, BOARD_DESIGN_SETTINGS *aSettings ) :
m_designSettings ( aSettings ),
m_board( aBoard ),
m_worksheet( nullptr ),
m_schematicNetlist( nullptr ),
m_reporter( nullptr ),
m_progressReporter( nullptr )
{
}
test::DRC_ENGINE::~DRC_ENGINE()
DRC_ENGINE::~DRC_ENGINE()
{
}
test::DRC_REPORT::~DRC_REPORT()
DRC_REPORT::~DRC_REPORT()
{
}
/*void test::DRC_ENGINE::AddMarker( MARKER_PCB* aMarker )
/*void DRC_ENGINE::AddMarker( MARKER_PCB* aMarker )
{
if( m_designSettings->Ignore( aMarker->GetRCItem()->GetErrorCode() ) )
{
@ -85,49 +85,11 @@ test::DRC_REPORT::~DRC_REPORT()
}*/
bool test::DRC_ENGINE::LoadRules( wxFileName aPath )
{
if( aPath.FileExists() )
{
m_ruleConditions.clear();
m_rules.clear();
FILE* fp = wxFopen( aPath.GetFullPath(), wxT( "rt" ) );
if( fp )
{
try
{
DRC_RULES_PARSER parser( m_board, fp, aPath.GetFullPath() );
parser.Parse( m_rules, m_reporter );
}
catch( PARSE_ERROR& pe )
{
// Don't leave possibly malformed stuff around for us to trip over
m_ruleConditions.clear();
m_rules.clear();
//wxSafeYield( m_editFrame );
//m_editFrame->ShowBoardSetupDialog( _( "Rules" ), pe.What(), ID_RULES_EDITOR,
// pe.lineNumber, pe.byteIndex );
throw;
return false;
}
}
}
return true;
}
test::DRC_RULE* test::DRC_ENGINE::createInferredRule( const wxString& name, std::set<BOARD_ITEM*> items, int priority )
DRC_RULE* DRC_ENGINE::createInferredRule( const wxString& name, std::set<BOARD_ITEM*> items, int priority )
{
DRC_RULE *rule = new DRC_RULE;
rule->SetName( name );
rule->m_Name = name;
if (! items.empty() )
rule->FillSpecificItemSet( items );
@ -212,7 +174,7 @@ int BOARD_CONNECTED_ITEM::GetClearance( PCB_LAYER_ID aLayer, BOARD_ITEM* aItem,
#endif
void test::DRC_ENGINE::inferLegacyRules()
void DRC_ENGINE::inferLegacyRules()
{
int priorityRangeMin = INT_MIN + 10000;
int priorityRangeMax = INT_MAX - 10000;
@ -221,38 +183,38 @@ void test::DRC_ENGINE::inferLegacyRules()
// 1) global defaults
test::DRC_RULE* rule = createInferredRule( "inferred-defaults", {}, priorityRangeMin );
DRC_RULE* rule = createInferredRule( "inferred-defaults", {}, priorityRangeMin );
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
DRC_CONSTRAINT clearanceConstraint( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE );
DRC_CONSTRAINT clearanceConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE );
clearanceConstraint.Value().SetMin( bds.m_MinClearance );
rule->AddConstraint( clearanceConstraint );
DRC_CONSTRAINT widthConstraint( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_TRACK_WIDTH );
DRC_CONSTRAINT widthConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_TRACK_WIDTH );
widthConstraint.Value().SetMin( bds.m_TrackMinWidth );
rule->AddConstraint( widthConstraint );
DRC_CONSTRAINT drillConstraint( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE );
DRC_CONSTRAINT drillConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE );
drillConstraint.Value().SetMin( bds.m_MinThroughDrill );
rule->AddConstraint( drillConstraint );
DRC_CONSTRAINT annulusConstraint( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH );
DRC_CONSTRAINT annulusConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH );
annulusConstraint.Value().SetMin( bds.m_ViasMinAnnulus );
rule->AddConstraint( annulusConstraint );
DRC_CONSTRAINT diameterConstraint( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_VIA_DIAMETER );
DRC_CONSTRAINT diameterConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_VIA_DIAMETER );
diameterConstraint.Value().SetMin( bds.m_ViasMinSize );
rule->AddConstraint( diameterConstraint );
DRC_CONSTRAINT edgeClearanceConstraint( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE );
DRC_CONSTRAINT edgeClearanceConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE );
edgeClearanceConstraint.Value().SetMin( bds.m_CopperEdgeClearance );
rule->AddConstraint( edgeClearanceConstraint );
DRC_CONSTRAINT holeClearanceConstraint( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE );
DRC_CONSTRAINT holeClearanceConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE );
holeClearanceConstraint.Value().SetMin( bds.m_HoleToHoleMin );
rule->AddConstraint( holeClearanceConstraint );
DRC_CONSTRAINT courtyardClearanceConstraint( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE );
DRC_CONSTRAINT courtyardClearanceConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE );
holeClearanceConstraint.Value().SetMin( 0 );
rule->AddConstraint( courtyardClearanceConstraint );
@ -261,24 +223,24 @@ void test::DRC_ENGINE::inferLegacyRules()
priorityRangeMin++;
auto isMicroViaCondition = new DRC_RULE_CONDITION ( "A.type == 'Via' && A.isMicroVia()" );
test::DRC_RULE* uViaRule = createInferredRule( "inferred-microvia-defaults", {}, priorityRangeMin );
DRC_RULE* uViaRule = createInferredRule( "inferred-microvia-defaults", {}, priorityRangeMin );
uViaRule->SetCondition( isMicroViaCondition );
uViaRule->m_Condition = isMicroViaCondition;
DRC_CONSTRAINT uViaDrillConstraint( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE );
DRC_CONSTRAINT uViaDrillConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE );
uViaDrillConstraint.Value().SetMin( bds.m_MicroViasMinDrill );
uViaRule->AddConstraint( uViaDrillConstraint );
DRC_CONSTRAINT uViaDiameterConstraint( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_VIA_DIAMETER );
DRC_CONSTRAINT uViaDiameterConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_VIA_DIAMETER );
uViaDiameterConstraint.Value().SetMin( bds.m_MicroViasMinSize );
uViaRule->AddConstraint( uViaDiameterConstraint );
auto isBlindBuriedViaCondition = new DRC_RULE_CONDITION ( "A.type == 'Via' && A.isBlindBuriedVia()" );
test::DRC_RULE* blindBuriedViaRule = createInferredRule( "inferred-blind-buried-via-defaults", {}, priorityRangeMin );
DRC_RULE* blindBuriedViaRule = createInferredRule( "inferred-blind-buried-via-defaults", {}, priorityRangeMin );
DRC_CONSTRAINT disallowConstraint( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_DISALLOW );
DRC_CONSTRAINT disallowConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_DISALLOW );
blindBuriedViaRule->SetCondition ( isBlindBuriedViaCondition );
blindBuriedViaRule->m_Condition = isBlindBuriedViaCondition;
if( !bds.m_MicroViasAllowed )
{
@ -310,14 +272,14 @@ void test::DRC_ENGINE::inferLegacyRules()
netclasses.push_back( bds.GetNetClasses().GetDefault() );
for( auto netclass : bds.GetNetClasses() )
for( const auto& netclass : bds.GetNetClasses() )
netclasses.push_back( netclass.second );
ReportAux( wxString::Format( "Importing %d legacy net classes", (int) netclasses.size() ) );
int i = 0;
for( auto &nc : netclasses )
for( const NETCLASSPTR& nc : netclasses )
{
wxString className = nc->GetName();
@ -325,10 +287,10 @@ void test::DRC_ENGINE::inferLegacyRules()
auto inNetclassCondition = new DRC_RULE_CONDITION ( expr );
test::DRC_RULE* netclassRule = createInferredRule( wxString::Format( "inferred-netclass-clearance-%s", className ),
DRC_RULE* netclassRule = createInferredRule( wxString::Format( "inferred-netclass-clearance-%s", className ),
{}, priorityRangeMin + i );
netclassRule->SetCondition( inNetclassCondition );
netclassRule->m_Condition = inNetclassCondition;
DRC_CONSTRAINT ncClearanceConstraint ( DRC_CONSTRAINT_TYPE_CLEARANCE );
ncClearanceConstraint.Value().SetMin( nc->GetClearance() );
@ -337,7 +299,7 @@ void test::DRC_ENGINE::inferLegacyRules()
netclassRule = createInferredRule( wxString::Format( "inferred-netclass-width-%s", className ),
{}, priorityRangeMin + i );
netclassRule->SetCondition( inNetclassCondition );
netclassRule->m_Condition = inNetclassCondition;
DRC_CONSTRAINT ncWidthConstraint ( DRC_CONSTRAINT_TYPE_TRACK_WIDTH );
ncWidthConstraint.Value().SetMin( nc->GetTrackWidth() );
@ -347,25 +309,22 @@ void test::DRC_ENGINE::inferLegacyRules()
i++;
}
//clearanceConstraint.SetMin( )
//rule->AddConstraint( )
}
static wxString formatConstraint( const test::DRC_CONSTRAINT& constraint )
static wxString formatConstraint( const DRC_CONSTRAINT& constraint )
{
struct Formatter
{
test::DRC_CONSTRAINT_TYPE_T type;
DRC_CONSTRAINT_TYPE_T type;
wxString name;
std::function<wxString(const test::DRC_CONSTRAINT&)> formatter;
std::function<wxString(const DRC_CONSTRAINT&)> formatter;
};
auto formatMinMax = []( const test::DRC_CONSTRAINT& c ) -> wxString {
auto formatMinMax = []( const DRC_CONSTRAINT& c ) -> wxString {
wxString str;
const auto value = c.GetValue();
@ -380,23 +339,23 @@ static wxString formatConstraint( const test::DRC_CONSTRAINT& constraint )
};
std::vector<Formatter> formats = {
{ test::DRC_CONSTRAINT_TYPE_UNKNOWN, "unknown", nullptr },
{ test::DRC_CONSTRAINT_TYPE_CLEARANCE, "clearance", formatMinMax },
{ test::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE, "hole_clearance", formatMinMax },
{ test::DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE, "edge_clearance", formatMinMax },
{ test::DRC_CONSTRAINT_TYPE_HOLE_SIZE, "hole_size", formatMinMax },
{ test::DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE, "courtyard_clearance", formatMinMax },
{ test::DRC_CONSTRAINT_TYPE_SILK_TO_PAD, "silk_to_pad", formatMinMax },
{ test::DRC_CONSTRAINT_TYPE_SILK_TO_SILK, "silk_to_silk", formatMinMax },
{ test::DRC_CONSTRAINT_TYPE_TRACK_WIDTH, "track_width", formatMinMax },
{ test::DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH, "annulus_width", formatMinMax },
{ test::DRC_CONSTRAINT_TYPE_DISALLOW, "disallow", nullptr }, // fixme
{ test::DRC_CONSTRAINT_TYPE_VIA_DIAMETER, "via_diameter", formatMinMax }
{ DRC_CONSTRAINT_TYPE_UNKNOWN, "unknown", nullptr },
{ DRC_CONSTRAINT_TYPE_CLEARANCE, "clearance", formatMinMax },
{ DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE, "hole_clearance", formatMinMax },
{ DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE, "edge_clearance", formatMinMax },
{ DRC_CONSTRAINT_TYPE_HOLE_SIZE, "hole_size", formatMinMax },
{ DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE, "courtyard_clearance", formatMinMax },
{ DRC_CONSTRAINT_TYPE_SILK_TO_PAD, "silk_to_pad", formatMinMax },
{ DRC_CONSTRAINT_TYPE_SILK_TO_SILK, "silk_to_silk", formatMinMax },
{ DRC_CONSTRAINT_TYPE_TRACK_WIDTH, "track_width", formatMinMax },
{ DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH, "annulus_width", formatMinMax },
{ DRC_CONSTRAINT_TYPE_DISALLOW, "disallow", nullptr }, // fixme
{ DRC_CONSTRAINT_TYPE_VIA_DIAMETER, "via_diameter", formatMinMax }
};
for( auto& fmt : formats)
{
if( fmt.type == constraint.GetType() )
if( fmt.type == constraint.m_Type )
{
wxString rv = fmt.name + " ";
if( fmt.formatter )
@ -409,11 +368,13 @@ static wxString formatConstraint( const test::DRC_CONSTRAINT& constraint )
}
bool test::DRC_ENGINE::CompileRules()
bool DRC_ENGINE::CompileRules()
{
ReportAux( wxString::Format( "Compiling Rules (%d rules, %d conditions): ", (int)m_rules.size(), (int)m_ruleConditions.size() ) );
ReportAux( wxString::Format( "Compiling Rules (%d rules, %d conditions): ",
(int) m_rules.size(),
(int) m_ruleConditions.size() ) );
for( auto provider : m_testProviders )
for( DRC_TEST_PROVIDER* provider : m_testProviders )
{
ReportAux( wxString::Format( "- Provider: '%s': ", provider->GetName() ) );
drc_dbg(7, "do prov %s", provider->GetName() );
@ -428,52 +389,52 @@ bool test::DRC_ENGINE::CompileRules()
for( auto rule : m_rules )
{
test::DRC_RULE_CONDITION* condition = nullptr;
DRC_RULE_CONDITION* condition = nullptr;
bool compileOk = false;
std::vector<test::DRC_CONSTRAINT> matchingConstraints;
drc_dbg(7, "Scan provider %s, rule %s", provider->GetName(), rule->GetName() );
std::vector<DRC_CONSTRAINT> matchingConstraints;
drc_dbg(7, "Scan provider %s, rule %s", provider->GetName(), rule->m_Name );
if( ! rule->IsEnabled() )
continue;
if( rule->IsConditional() )
if( !rule->m_Condition->GetExpression().IsEmpty() )
{
condition = rule->Condition();
condition = rule->m_Condition;
compileOk = condition->Compile( nullptr, 0, 0 ); // fixme
}
for( auto& constraint : rule->Constraints() )
for( const DRC_CONSTRAINT& constraint : rule->m_Constraints )
{
drc_dbg(7, "scan constraint id %d\n", constraint.GetType() );
if( constraint.GetType() != id )
drc_dbg(7, "scan constraint id %d\n", constraint.m_Type );
if( constraint.m_Type != id )
continue;
CONSTRAINT_WITH_CONDITIONS* rcons = new CONSTRAINT_WITH_CONDITIONS;
auto rcons = new CONSTRAINT_WITH_CONDITIONS;
if( condition )
rcons->conditions.push_back( condition );
if( condition )
{
rcons->conditions.push_back( condition );
}
matchingConstraints.push_back( constraint );
rcons->constraint = constraint;
rcons->parentRule = rule;
m_constraintMap[ id ]->sortedConstraints.push_back( rcons );
matchingConstraints.push_back( constraint );
rcons->constraint = constraint;
rcons->parentRule = rule;
m_constraintMap[ id ]->sortedConstraints.push_back( rcons );
}
if( !matchingConstraints.empty() )
{
ReportAux( wxString::Format( " |- Rule: '%s' ", rule->GetName() ) );
if( condition )
ReportAux( wxString::Format( " |- condition: '%s' compile: %s", condition->GetExpression(), compileOk ? "OK" : "ERROR") );
ReportAux( wxString::Format( " |- Rule: '%s' ",
rule->m_Name ) );
for (const auto& constraint : matchingConstraints )
if( condition )
{
ReportAux( wxString::Format( " |- constraint: %s", formatConstraint( constraint ) ) );
ReportAux( wxString::Format( " |- condition: '%s' compile: %s",
condition->GetExpression(),
compileOk ? "OK" : "ERROR" ) );
}
for (const DRC_CONSTRAINT& constraint : matchingConstraints )
{
ReportAux( wxString::Format( " |- constraint: %s",
formatConstraint( constraint ) ) );
}
}
@ -486,9 +447,9 @@ bool test::DRC_ENGINE::CompileRules()
}
void test::DRC_ENGINE::RunTests( )
void DRC_ENGINE::RunTests( )
{
m_drcReport.reset( new test::DRC_REPORT );
m_drcReport.reset( new DRC_REPORT );
m_testProviders = DRC_TEST_PROVIDER_REGISTRY::Instance().GetTestProviders();
for( auto provider : m_testProviders )
@ -497,7 +458,6 @@ void test::DRC_ENGINE::RunTests( )
provider->SetDRCEngine( this );
}
inferLegacyRules();
CompileRules();
@ -512,7 +472,8 @@ void test::DRC_ENGINE::RunTests( )
{
if( !HasCorrectRulesForId( ruleID ) )
{
ReportAux( wxString::Format( "DRC provider '%s' has no rules provided. Skipping run.", provider->GetName() ) );
ReportAux( wxString::Format( "DRC provider '%s' has no rules provided. Skipping run.",
provider->GetName() ) );
skipProvider = true;
break;
}
@ -529,31 +490,34 @@ void test::DRC_ENGINE::RunTests( )
}
const test::DRC_CONSTRAINT& test::DRC_ENGINE::EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T aConstraintId, BOARD_ITEM* a, BOARD_ITEM* b, PCB_LAYER_ID aLayer )
const DRC_CONSTRAINT& DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintId,
BOARD_ITEM* a, BOARD_ITEM* b,
PCB_LAYER_ID aLayer )
{
test::DRC_RULE* rv;
DRC_RULE* rv;
auto ruleset = m_constraintMap[ aConstraintId ];
for( auto rcond : ruleset->sortedConstraints )
for( const auto& rcond : ruleset->sortedConstraints )
{
if( rcond->conditions.size() == 0 ) // uconditional
{
drc_dbg( 8, " -> rule '%s' matches (unconditional)\n",
rcond->constraint.GetParentRule()->GetName()
);
rcond->constraint.GetParentRule()->m_Name );
return rcond->constraint;
}
for( auto condition : rcond->conditions )
for( const auto& condition : rcond->conditions )
{
drc_dbg( 8, " -> check condition '%s'\n",
condition->GetExpression() );
condition->GetExpression() );
bool result = condition->EvaluateFor( a, b, aLayer );
bool result = condition->EvaluateFor( a, b, aLayer ); // FIXME: need the actual layer
if( result )
{
drc_dbg( 8, " -> rule '%s' matches, triggered by condition '%s'\n",
rcond->constraint.GetParentRule()->GetName(),
condition->GetExpression() );
rcond->constraint.GetParentRule()->m_Name,
condition->GetExpression() );
return rcond->constraint;
}
@ -562,43 +526,43 @@ const test::DRC_CONSTRAINT& test::DRC_ENGINE::EvalRulesForItems( test::DRC_CONST
// fixme: return optional<drc_constraint>, let the particular test decide what to do if no matching constraint
// is found
static test::DRC_CONSTRAINT nullConstraint;
static DRC_CONSTRAINT nullConstraint;
nullConstraint.m_DisallowFlags = 0;
nullConstraint.m_LayerCondition.reset();
return nullConstraint;
}
void test::DRC_ENGINE::Report( std::shared_ptr<DRC_ITEM> aItem, ::MARKER_PCB *aMarker )
void DRC_ENGINE::Report( std::shared_ptr<DRC_ITEM> aItem, MARKER_PCB *aMarker )
{
m_drcReport->AddItem( aItem, aMarker );
if( m_reporter )
{
wxString msg = wxString::Format( "Test '%s': %s (code %d)",
aItem->GetViolatingTest()->GetName(),
aItem->GetErrorMessage(),
aItem->GetErrorCode() );
aItem->GetViolatingTest()->GetName(),
aItem->GetErrorMessage(),
aItem->GetErrorCode() );
auto rule = aItem->GetViolatingRule();
if( rule )
msg += wxString::Format( ", violating rule: '%s'", rule->GetName() );
msg += wxString::Format( ", violating rule: '%s'", rule->m_Name );
m_reporter->Report ( msg, RPT_SEVERITY_ERROR /* fixme */ );
m_reporter->Report( msg );
wxString violatingItemsStr = "Violating items: ";
if( aMarker )
{
m_reporter->Report( wxString::Format( " |- violating position (%d, %d)", aMarker->GetPos().x, aMarker->GetPos().y ),
RPT_SEVERITY_ERROR /* fixme */ );
m_reporter->Report( wxString::Format( " |- violating position (%d, %d)",
aMarker->GetPos().x,
aMarker->GetPos().y ) );
}
}
}
void test::DRC_ENGINE::ReportAux ( const wxString& aStr )
void DRC_ENGINE::ReportAux ( const wxString& aStr )
{
if( !m_reporter )
return;
@ -607,7 +571,7 @@ void test::DRC_ENGINE::ReportAux ( const wxString& aStr )
}
void test::DRC_ENGINE::ReportProgress( double aProgress )
void DRC_ENGINE::ReportProgress( double aProgress )
{
if( !m_progressReporter )
return;
@ -616,7 +580,7 @@ void test::DRC_ENGINE::ReportProgress( double aProgress )
}
void test::DRC_ENGINE::ReportStage ( const wxString& aStageName, int index, int total )
void DRC_ENGINE::ReportStage ( const wxString& aStageName, int index, int total )
{
if( !m_progressReporter )
return;
@ -628,7 +592,7 @@ void test::DRC_ENGINE::ReportStage ( const wxString& aStageName, int index, int
#if 0
test::DRC_CONSTRAINT test::DRC_ENGINE::GetWorstGlobalConstraint( test::DRC_CONSTRAINT_TYPE_T ruleID )
DRC_CONSTRAINT DRC_ENGINE::GetWorstGlobalConstraint( DRC_CONSTRAINT_TYPE_T ruleID )
{
DRC_CONSTRAINT rv;
@ -648,27 +612,30 @@ test::DRC_CONSTRAINT test::DRC_ENGINE::GetWorstGlobalConstraint( test::DRC_CONST
#endif
std::vector<test::DRC_CONSTRAINT> test::DRC_ENGINE::QueryConstraintsById( test::DRC_CONSTRAINT_TYPE_T constraintID )
std::vector<DRC_CONSTRAINT> DRC_ENGINE::QueryConstraintsById( DRC_CONSTRAINT_TYPE_T constraintID )
{
std::vector<test::DRC_CONSTRAINT> rv;
std::vector<DRC_CONSTRAINT> rv;
for ( auto c : m_constraintMap[constraintID]->sortedConstraints )
rv.push_back(c->constraint);
return rv;
}
bool test::DRC_ENGINE::HasCorrectRulesForId( test::DRC_CONSTRAINT_TYPE_T constraintID )
bool DRC_ENGINE::HasCorrectRulesForId( DRC_CONSTRAINT_TYPE_T constraintID )
{
//drc_dbg(10,"hascorrect id %d size %d\n", ruleID, m_ruleMap[ruleID]->sortedRules.size( ) );
return m_constraintMap[constraintID]->sortedConstraints.size() != 0;
}
bool test::DRC_ENGINE::QueryWorstConstraint( test::DRC_CONSTRAINT_TYPE_T aConstraintId, test::DRC_CONSTRAINT& aConstraint, test::DRC_CONSTRAINT_QUERY_T aQueryType )
bool DRC_ENGINE::QueryWorstConstraint( DRC_CONSTRAINT_TYPE_T aConstraintId,
DRC_CONSTRAINT& aConstraint,
DRC_CONSTRAINT_QUERY_T aQueryType )
{
if( aQueryType == DRCCQ_LARGEST_MINIMUM )
{
int worst = 0;
for( const auto constraint : QueryConstraintsById( aConstraintId ) )
{
if( constraint.GetValue().HasMin() )

View File

@ -34,8 +34,8 @@
#include <tools/pcb_tool_base.h>
#include <vector>
#include <drc/drc_rule.h>
#include <drc_proto/drc_rule.h>
class BOARD_DESIGN_SETTINGS;
class PCB_EDIT_FRAME;
@ -67,13 +67,10 @@ void drcPrintDebugMessage( int level, wxString msg, const char *function, int li
//#define drc_dbg(level, fmt, ...) \
// wxLogTrace("DUPA", fmt, __VA_ARGS__);
namespace test
{
class DRC_RULE_CONDITION;
class DRC_ITEM;
class DRC_RULE;
class DRC_TEST_PROVIDER;
class LEGACY_DRC_TEST_PROVIDER;
class DRC_CONSTRAINT;
enum DRC_CONSTRAINT_QUERY_T
@ -82,47 +79,6 @@ enum DRC_CONSTRAINT_QUERY_T
// fixme: more to come I guess...
};
/// DRC error codes:
enum PCB_DRC_CODE
{
DRCE_FIRST = 1,
DRCE_UNCONNECTED_ITEMS = DRCE_FIRST, ///< items are unconnected
DRCE_SHORTING_ITEMS, ///< items shorting two nets but not a net-tie
DRCE_ALLOWED_ITEMS, ///< a disallowed item has been used
DRCE_CLEARANCE, ///< items are too close together
DRCE_TRACKS_CROSSING, ///< tracks are crossing
DRCE_COPPER_EDGE_CLEARANCE, ///< a copper item is too close to the board edge
DRCE_ZONES_INTERSECT, ///< copper area outlines intersect
DRCE_ZONE_HAS_EMPTY_NET, ///< copper area has a net but no pads in nets, which is suspicious
DRCE_DANGLING_VIA, ///< via which isn't connected to anything
DRCE_DANGLING_TRACK, ///< track with at least one end not connected to anything
DRCE_HOLE_CLEARANCE, ///< overlapping drilled holes break drill bits
DRCE_TRACK_WIDTH, ///< Track width is too small or too large
DRCE_TOO_SMALL_VIA, ///< Too small via size
DRCE_ANNULUS, ///< Via size and drill leave annulus too small or too large
DRCE_TOO_SMALL_DRILL, ///< Too small via or pad drill
DRCE_VIA_HOLE_BIGGER, ///< via's hole is bigger than its diameter
DRCE_PADSTACK, ///< something is wrong with a pad or via stackup
DRCE_TOO_SMALL_MICROVIA, ///< Too small micro via size
DRCE_TOO_SMALL_MICROVIA_DRILL, ///< Too small micro via drill
DRCE_KEEPOUT, ///< A disallowed object is inside a keepout
DRCE_OVERLAPPING_FOOTPRINTS, ///< footprint courtyards overlap
DRCE_MISSING_COURTYARD, ///< footprint has no courtyard defined
DRCE_MALFORMED_COURTYARD, ///< footprint has a courtyard but malformed
///< (not convertible to a closed polygon with holes)
DRCE_PTH_IN_COURTYARD,
DRCE_NPTH_IN_COURTYARD,
DRCE_DISABLED_LAYER_ITEM, ///< item on a disabled layer
DRCE_INVALID_OUTLINE, ///< invalid board outline
DRCE_MISSING_FOOTPRINT, ///< footprint not found for netlist item
DRCE_DUPLICATE_FOOTPRINT, ///< more than one footprints found for netlist item
DRCE_EXTRA_FOOTPRINT, ///< netlist item not found for footprint
DRCE_UNRESOLVED_VARIABLE,
DRCE_VIA_DIAMETER, ///< Via diameter checks (min/max)
DRCE_LAST = DRCE_UNRESOLVED_VARIABLE
};
class DRC_REPORT
{
@ -197,7 +153,6 @@ public:
m_reporter = aReporter;
}
bool LoadRules( wxFileName aPath );
void RunTests();
void SetErrorLimit( int aLimit );
@ -212,14 +167,13 @@ public:
return m_board;
}
const DRC_CONSTRAINT& EvalRulesForItems( DRC_CONSTRAINT_TYPE_T ruleID, BOARD_ITEM* a,
BOARD_ITEM* b = nullptr,
PCB_LAYER_ID aLayer = UNDEFINED_LAYER );
std::vector<DRC_CONSTRAINT> QueryConstraintsById( DRC_CONSTRAINT_TYPE_T ruleID );
const DRC_CONSTRAINT& EvalRulesForItems(
DRC_CONSTRAINT_TYPE_T ruleID, BOARD_ITEM* a, BOARD_ITEM* b = nullptr, PCB_LAYER_ID aLayer = UNDEFINED_LAYER );
std::vector<DRC_CONSTRAINT> QueryConstraintsById( test::DRC_CONSTRAINT_TYPE_T ruleID );
bool HasCorrectRulesForId( test::DRC_CONSTRAINT_TYPE_T ruleID );
bool HasCorrectRulesForId( DRC_CONSTRAINT_TYPE_T ruleID );
EDA_UNITS UserUnits() const
{
@ -235,12 +189,11 @@ public:
std::shared_ptr<DRC_REPORT> GetReport() const { return m_drcReport; }
bool QueryWorstConstraint( DRC_CONSTRAINT_TYPE_T aRuleId, test::DRC_CONSTRAINT& aConstraint, DRC_CONSTRAINT_QUERY_T aQueryType );
bool QueryWorstConstraint( DRC_CONSTRAINT_TYPE_T aRuleId, DRC_CONSTRAINT& aConstraint,
DRC_CONSTRAINT_QUERY_T aQueryType );
private:
void addRule( test::DRC_RULE* rule )
void addRule( DRC_RULE* rule )
{
m_rules.push_back(rule);
}
@ -249,42 +202,40 @@ private:
struct CONSTRAINT_WITH_CONDITIONS
{
std::vector<test::DRC_RULE_CONDITION*> conditions;
test::DRC_RULE* parentRule;
test::DRC_CONSTRAINT constraint;
std::vector<DRC_RULE_CONDITION*> conditions;
DRC_RULE* parentRule;
DRC_CONSTRAINT constraint;
};
struct CONSTRAINT_SET
{
std::vector<CONSTRAINT_WITH_CONDITIONS*> sortedConstraints;
DRC_TEST_PROVIDER* provider;
DRC_TEST_PROVIDER* provider;
};
typedef std::unordered_map<test::DRC_CONSTRAINT_TYPE_T, CONSTRAINT_SET*> CONSTRAINT_MAP;
typedef std::unordered_map<DRC_CONSTRAINT_TYPE_T, CONSTRAINT_SET*> CONSTRAINT_MAP;
void inferLegacyRules();
void loadTestProviders();
test::DRC_RULE* createInferredRule( const wxString& name, std::set<BOARD_ITEM*> items, int priority );
DRC_RULE* createInferredRule( const wxString& name, std::set<BOARD_ITEM*> items, int priority );
BOARD_DESIGN_SETTINGS* m_designSettings;
BOARD* m_board;
KIGFX::WS_PROXY_VIEW_ITEM* m_worksheet;
NETLIST* m_schematicNetlist;
protected:
BOARD_DESIGN_SETTINGS* m_designSettings;
BOARD* m_board;
KIGFX::WS_PROXY_VIEW_ITEM* m_worksheet;
NETLIST* m_schematicNetlist;
std::shared_ptr<DRC_REPORT> m_drcReport;
std::shared_ptr<DRC_REPORT> m_drcReport;
std::vector<DRC_RULE_CONDITION*> m_ruleConditions;
std::vector<DRC_RULE*> m_rules;
std::vector<DRC_TEST_PROVIDER*> m_testProviders;
std::unordered_map<EDA_ITEM*, CONSTRAINT_SET*> m_implicitRules;
CONSTRAINT_MAP m_constraintMap;
REPORTER* m_reporter;
PROGRESS_REPORTER* m_progressReporter;
CONSTRAINT_MAP m_constraintMap;
REPORTER* m_reporter;
PROGRESS_REPORTER* m_progressReporter;
// condition -> rule -> provider
};
}; // namespace test
#endif // DRC_H

View File

@ -79,6 +79,10 @@ DRC_ITEM DRC_ITEM::trackDangling( DRCE_DANGLING_TRACK,
_( "Track has unconnected end" ),
wxT( "track_dangling" ) );
DRC_ITEM DRC_ITEM::holeClearance( DRCE_HOLE_CLEARANCE,
_( "Hole clearance" ),
wxT( "hole_clearance" ) );
DRC_ITEM DRC_ITEM::holeNearHole( DRCE_DRILLED_HOLES_TOO_CLOSE,
_( "Drilled holes too close together" ),
wxT( "hole_near_hole" ) );
@ -91,9 +95,9 @@ DRC_ITEM DRC_ITEM::viaTooSmall( DRCE_TOO_SMALL_VIA,
_( "Via size too small" ),
wxT( "via_too_small" ) );
DRC_ITEM DRC_ITEM::viaAnnulus( DRCE_VIA_ANNULUS,
_( "Via annulus" ),
wxT( "via_annulus" ) );
DRC_ITEM DRC_ITEM::annulus( DRCE_ANNULUS,
_( "Annulus" ),
wxT( "annulus" ) );
DRC_ITEM DRC_ITEM::drillTooSmall( DRCE_TOO_SMALL_DRILL,
_( "Drill too small" ),
@ -180,9 +184,10 @@ std::vector<std::reference_wrapper<RC_ITEM>> DRC_ITEM::allItemTypes( {
DRC_ITEM::viaDangling,
DRC_ITEM::trackDangling,
DRC_ITEM::holeNearHole,
DRC_ITEM::holeClearance,
DRC_ITEM::trackWidth,
DRC_ITEM::viaTooSmall,
DRC_ITEM::viaAnnulus,
DRC_ITEM::annulus,
DRC_ITEM::drillTooSmall,
DRC_ITEM::viaHoleLargerThanPad,
DRC_ITEM::padstack,
@ -199,6 +204,7 @@ std::vector<std::reference_wrapper<RC_ITEM>> DRC_ITEM::allItemTypes( {
DRC_ITEM::duplicateFootprints,
DRC_ITEM::missingFootprint,
DRC_ITEM::extraFootprint,
DRC_ITEM::netConflict,
DRC_ITEM::unresolvedVariable
} );
@ -218,9 +224,10 @@ 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_HOLE_CLEARANCE: return std::make_shared<DRC_ITEM>( holeClearance );
case DRCE_TRACK_WIDTH: return std::make_shared<DRC_ITEM>( trackWidth );
case DRCE_TOO_SMALL_VIA: return std::make_shared<DRC_ITEM>( viaTooSmall );
case DRCE_VIA_ANNULUS: return std::make_shared<DRC_ITEM>( viaAnnulus );
case DRCE_ANNULUS: return std::make_shared<DRC_ITEM>( annulus );
case DRCE_TOO_SMALL_DRILL: return std::make_shared<DRC_ITEM>( drillTooSmall );
case DRCE_VIA_HOLE_BIGGER: return std::make_shared<DRC_ITEM>( viaHoleLargerThanPad );
case DRCE_PADSTACK: return std::make_shared<DRC_ITEM>( padstack );

View File

@ -28,6 +28,8 @@
#include <rc_item.h>
class PCB_BASE_FRAME;
class DRC_RULE;
class DRC_TEST_PROVIDER;
class DRC_ITEM : public RC_ITEM
{
@ -55,7 +57,14 @@ public:
* Translates this object into a fragment of HTML suitable for the wxHtmlListBox class.
* @return wxString - the html text.
*/
wxString ShowHtml( PCB_BASE_FRAME* aFrame ) const;
wxString ShowHtml( PCB_BASE_FRAME* aFrame ) const; // JEY TODO
wxString FormatHtml( ) const { return ""; } // fixme
void SetViolatingRule ( DRC_RULE *aRule ) { m_violatingRule = aRule; }
DRC_RULE* GetViolatingRule() const { return m_violatingRule; }
void SetViolatingTest( DRC_TEST_PROVIDER *aProvider ) { m_violatingTest = aProvider; }
DRC_TEST_PROVIDER* GetViolatingTest() const { return m_violatingTest; }
private:
DRC_ITEM( int aErrorCode = 0, const wxString& aTitle = "", const wxString& aSettingsKey = "" )
@ -78,10 +87,11 @@ private:
static DRC_ITEM zoneHasEmptyNet;
static DRC_ITEM viaDangling;
static DRC_ITEM trackDangling;
static DRC_ITEM holeNearHole;
static DRC_ITEM holeNearHole; // JEY TODO
static DRC_ITEM holeClearance; // JEY TODO
static DRC_ITEM trackWidth;
static DRC_ITEM viaTooSmall;
static DRC_ITEM viaAnnulus;
static DRC_ITEM annulus;
static DRC_ITEM drillTooSmall;
static DRC_ITEM viaHoleLargerThanPad;
static DRC_ITEM padstack;
@ -100,7 +110,10 @@ private:
static DRC_ITEM extraFootprint;
static DRC_ITEM netConflict;
static DRC_ITEM unresolvedVariable;
private:
DRC_RULE* m_violatingRule = nullptr;
DRC_TEST_PROVIDER* m_violatingTest = nullptr;
};
#endif // DRC_ITEM_H

View File

@ -29,7 +29,7 @@
#include <drc/drc_item.h>
DRC_KEEPOUT_TESTER::DRC_KEEPOUT_TESTER( MARKER_HANDLER aMarkerHandler ) :
DRC_TEST_PROVIDER( std::move( aMarkerHandler ) ),
LEGACY_DRC_TEST_PROVIDER( std::move( aMarkerHandler ) ),
m_units( EDA_UNITS::MILLIMETRES ),
m_board( nullptr ),
m_zone( nullptr ),
@ -71,9 +71,9 @@ bool DRC_KEEPOUT_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard )
bool DRC_KEEPOUT_TESTER::checkTracksAndVias()
{
constexpr int VIA_MASK = DISALLOW_VIAS | DISALLOW_MICRO_VIAS | DISALLOW_BB_VIAS;
constexpr int CHECK_VIAS_MASK = VIA_MASK | DISALLOW_HOLES;
constexpr int CHECK_TRACKS_AND_VIAS_MASK = CHECK_VIAS_MASK | DISALLOW_TRACKS;
constexpr int VIA_MASK = DRC_DISALLOW_VIAS | DRC_DISALLOW_MICRO_VIAS | DRC_DISALLOW_BB_VIAS;
constexpr int CHECK_VIAS_MASK = VIA_MASK | DRC_DISALLOW_HOLES;
constexpr int CHECK_TRACKS_AND_VIAS_MASK = CHECK_VIAS_MASK | DRC_DISALLOW_TRACKS;
if(( m_keepoutFlags & CHECK_TRACKS_AND_VIAS_MASK ) == 0 )
return true;
@ -85,7 +85,7 @@ bool DRC_KEEPOUT_TESTER::checkTracksAndVias()
if( !m_zoneBBox.Intersects( segm->GetBoundingBox() ) )
continue;
if( segm->Type() == PCB_TRACE_T && ( m_keepoutFlags & DISALLOW_TRACKS ) != 0 )
if( segm->Type() == PCB_TRACE_T && ( m_keepoutFlags & DRC_DISALLOW_TRACKS ) != 0 )
{
// Ignore if the keepout zone is not on the same layer
PCB_LAYER_ID layer = segm->GetLayer();
@ -100,7 +100,7 @@ bool DRC_KEEPOUT_TESTER::checkTracksAndVias()
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_KEEPOUT );
m_msg.Printf( drcItem->GetErrorText() + _( " (%s)" ),
m_sources.at( DISALLOW_TRACKS ) );
m_sources.at( DRC_DISALLOW_TRACKS ) );
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( segm, m_zone );
@ -116,23 +116,23 @@ bool DRC_KEEPOUT_TESTER::checkTracksAndVias()
int test = 0;
int clearance = via->GetWidth() / 2;
if( ( m_keepoutFlags & DISALLOW_VIAS ) > 0 )
if( ( m_keepoutFlags & DRC_DISALLOW_VIAS ) > 0 )
{
test = DISALLOW_VIAS;
test = DRC_DISALLOW_VIAS;
}
else if( via->GetViaType() == VIATYPE::MICROVIA
&& ( m_keepoutFlags & DISALLOW_MICRO_VIAS ) > 0 )
&& ( m_keepoutFlags & DRC_DISALLOW_MICRO_VIAS ) > 0 )
{
test = DISALLOW_MICRO_VIAS;
test = DRC_DISALLOW_MICRO_VIAS;
}
else if( via->GetViaType() == VIATYPE::BLIND_BURIED
&& ( m_keepoutFlags & DISALLOW_BB_VIAS ) > 0 )
&& ( m_keepoutFlags & DRC_DISALLOW_BB_VIAS ) > 0 )
{
test = DISALLOW_BB_VIAS;
test = DRC_DISALLOW_BB_VIAS;
}
else if( ( m_keepoutFlags & DISALLOW_HOLES ) > 0 )
else if( ( m_keepoutFlags & DRC_DISALLOW_HOLES ) > 0 )
{
test = DISALLOW_HOLES;
test = DRC_DISALLOW_HOLES;
clearance = via->GetDrillValue() / 2;
}
else
@ -157,8 +157,8 @@ bool DRC_KEEPOUT_TESTER::checkTracksAndVias()
bool DRC_KEEPOUT_TESTER::checkFootprints()
{
constexpr int CHECK_PADS_MASK = DISALLOW_PADS | DISALLOW_HOLES;
constexpr int CHECK_FOOTPRINTS_MASK = CHECK_PADS_MASK | DISALLOW_FOOTPRINTS;
constexpr int CHECK_PADS_MASK = DRC_DISALLOW_PADS | DRC_DISALLOW_HOLES;
constexpr int CHECK_FOOTPRINTS_MASK = CHECK_PADS_MASK | DRC_DISALLOW_FOOTPRINTS;
if(( m_keepoutFlags & CHECK_FOOTPRINTS_MASK ) == 0 )
return true;
@ -173,7 +173,7 @@ bool DRC_KEEPOUT_TESTER::checkFootprints()
if( !m_zoneBBox.Intersects( fp->GetBoundingBox() ) )
continue;
if( ( m_keepoutFlags & DISALLOW_FOOTPRINTS ) > 0
if( ( m_keepoutFlags & DRC_DISALLOW_FOOTPRINTS ) > 0
&& ( fp->IsFlipped() ? m_zone->CommonLayerExists( LSET::BackMask() )
: m_zone->CommonLayerExists( LSET::FrontMask() ) ) )
{
@ -195,7 +195,7 @@ bool DRC_KEEPOUT_TESTER::checkFootprints()
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_KEEPOUT );
m_msg.Printf( drcItem->GetErrorText() + _( " (%s)" ),
m_sources.at( DISALLOW_FOOTPRINTS ) );
m_sources.at( DRC_DISALLOW_FOOTPRINTS ) );
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( fp, m_zone );
@ -231,7 +231,7 @@ bool DRC_KEEPOUT_TESTER::checkPads( MODULE* aModule )
if( !m_zoneBBox.Intersects( padBBox ) )
continue;
if( ( m_keepoutFlags & DISALLOW_PADS ) > 0 )
if( ( m_keepoutFlags & DRC_DISALLOW_PADS ) > 0 )
{
SHAPE_POLY_SET outline = *pad->GetEffectivePolygon();
@ -245,7 +245,7 @@ bool DRC_KEEPOUT_TESTER::checkPads( MODULE* aModule )
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_KEEPOUT );
m_msg.Printf( drcItem->GetErrorText() + _( " (%s)" ),
m_sources.at( DISALLOW_PADS ) );
m_sources.at( DRC_DISALLOW_PADS ) );
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( pad, m_zone );
@ -254,7 +254,7 @@ bool DRC_KEEPOUT_TESTER::checkPads( MODULE* aModule )
success = false;
}
}
else if( ( m_keepoutFlags & DISALLOW_HOLES ) > 0 )
else if( ( m_keepoutFlags & DRC_DISALLOW_HOLES ) > 0 )
{
const SHAPE_SEGMENT* slot = pad->GetEffectiveHoleShape();
@ -263,7 +263,7 @@ bool DRC_KEEPOUT_TESTER::checkPads( MODULE* aModule )
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_KEEPOUT );
m_msg.Printf( drcItem->GetErrorText() + _( " (%s)" ),
m_sources.at( DISALLOW_HOLES ) );
m_sources.at( DRC_DISALLOW_HOLES ) );
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( pad, m_zone );
@ -280,7 +280,7 @@ bool DRC_KEEPOUT_TESTER::checkPads( MODULE* aModule )
bool DRC_KEEPOUT_TESTER::checkDrawings()
{
constexpr int CHECK_DRAWINGS_MASK = DISALLOW_TEXTS | DISALLOW_GRAPHICS;
constexpr int CHECK_DRAWINGS_MASK = DRC_DISALLOW_TEXTS | DRC_DISALLOW_GRAPHICS;
constexpr KICAD_T graphicTypes[] = { PCB_LINE_T, PCB_DIMENSION_T, PCB_TARGET_T, EOT };
if(( m_keepoutFlags & CHECK_DRAWINGS_MASK ) == 0 )
@ -295,10 +295,10 @@ bool DRC_KEEPOUT_TESTER::checkDrawings()
int sourceId = 0;
if( drawing->IsType( graphicTypes ) && ( m_keepoutFlags & DISALLOW_GRAPHICS ) > 0 )
sourceId = DISALLOW_GRAPHICS;
else if( drawing->Type() == PCB_TEXT_T && ( m_keepoutFlags & DISALLOW_TEXTS ) > 0 )
sourceId = DISALLOW_TEXTS;
if( drawing->IsType( graphicTypes ) && ( m_keepoutFlags & DRC_DISALLOW_GRAPHICS ) > 0 )
sourceId = DRC_DISALLOW_GRAPHICS;
else if( drawing->Type() == PCB_TEXT_T && ( m_keepoutFlags & DRC_DISALLOW_TEXTS ) > 0 )
sourceId = DRC_DISALLOW_TEXTS;
else
continue;

View File

@ -25,13 +25,13 @@
#ifndef DRC_KEEPOUT_TESTER__H
#define DRC_KEEPOUT_TESTER__H
#include <drc/drc_provider.h>
#include <drc/drc_results_provider.h>
class BOARD;
class DRC_KEEPOUT_TESTER : public DRC_TEST_PROVIDER
class DRC_KEEPOUT_TESTER : public LEGACY_DRC_TEST_PROVIDER
{
public:
DRC_KEEPOUT_TESTER( MARKER_HANDLER aMarkerHandler );

View File

@ -35,11 +35,14 @@
/**
* DRC_TEST_PROVIDER
* LEGACY_DRC_TEST_PROVIDER
* is a base class that represents a DRC "provider" which runs some DRC functions over a
* #BOARD and spits out #PCB_MARKERs as needed.
*
* JEY TODO: to remove
*
*/
class DRC_TEST_PROVIDER
class LEGACY_DRC_TEST_PROVIDER
{
public:
/**
@ -55,10 +58,10 @@ public:
*/
virtual bool RunDRC( EDA_UNITS aUnits, BOARD& aBoard ) = 0;
virtual ~DRC_TEST_PROVIDER() {}
virtual ~LEGACY_DRC_TEST_PROVIDER() {}
protected:
DRC_TEST_PROVIDER( MARKER_HANDLER aMarkerHandler ) :
LEGACY_DRC_TEST_PROVIDER( MARKER_HANDLER aMarkerHandler ) :
m_marker_handler( std::move( aMarkerHandler ) )
{
}

View File

@ -27,6 +27,7 @@
#include <class_board_item.h>
#include <reporter.h>
#include <drc/drc_rule.h>
#include <drc/drc_engine.h>
#include <pcb_expr_evaluator.h>
@ -34,7 +35,7 @@ const DRC_CONSTRAINT* GetConstraint( const BOARD_ITEM* aItem, const BOARD_ITEM*
int aConstraint, PCB_LAYER_ID aLayer, wxString* aRuleName,
REPORTER* aReporter )
{
BOARD* board = aItem->GetBoard();
BOARD* board = aItem->GetBoard();
if( !board )
return nullptr;
@ -80,10 +81,10 @@ const DRC_CONSTRAINT* GetConstraint( const BOARD_ITEM* aItem, const BOARD_ITEM*
if( aReporter )
{
aReporter->Report( wxString::Format( _( "Checking rule condition \"%s\"." ),
rule->m_Condition.m_Expression ) );
rule->m_Condition->GetExpression() ) );
}
if( rule->m_Condition.EvaluateFor( aItem, bItem, aLayer ) )
if( rule->m_Condition->EvaluateFor( aItem, bItem, aLayer ) )
{
if( aReporter )
aReporter->Report( "Rule applied." );
@ -94,7 +95,7 @@ const DRC_CONSTRAINT* GetConstraint( const BOARD_ITEM* aItem, const BOARD_ITEM*
return constraint;
}
if( bItem && rule->m_Condition.EvaluateFor( bItem, aItem, aLayer ) )
if( bItem && rule->m_Condition->EvaluateFor( bItem, aItem, aLayer ) )
{
if( aReporter )
aReporter->Report( "Rule applied." );
@ -118,32 +119,43 @@ const DRC_CONSTRAINT* GetConstraint( const BOARD_ITEM* aItem, const BOARD_ITEM*
DRC_RULE::DRC_RULE() :
m_LayerCondition( LSET::AllLayersMask() )
m_Unary( false ),
m_LayerCondition( LSET::AllLayersMask() ),
m_Priority( 0 ),
m_Severity( SEVERITY::RPT_SEVERITY_ERROR )
{
}
DRC_RULE::~DRC_RULE()
{
delete m_Condition;
}
DRC_RULE_CONDITION::DRC_RULE_CONDITION()
void DRC_RULE::AddConstraint( DRC_CONSTRAINT& aConstraint )
{
aConstraint.SetParentRule( this );
m_Constraints.push_back( aConstraint );
}
DRC_RULE_CONDITION::DRC_RULE_CONDITION( const wxString& aExpression ) :
m_expression( aExpression ),
m_ucode ( nullptr )
{
m_ucode = nullptr;
}
DRC_RULE_CONDITION::~DRC_RULE_CONDITION()
{
delete m_ucode;
}
bool DRC_RULE_CONDITION::EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB,
PCB_LAYER_ID aLayer, REPORTER* aReporter )
{
if( m_Expression.IsEmpty() )
if( GetExpression().IsEmpty() )
{
if( aReporter )
aReporter->Report( _( "Unconditional constraint." ) );
@ -152,7 +164,7 @@ bool DRC_RULE_CONDITION::EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM
}
if( aReporter )
aReporter->Report( _( "Evaluating expression \"" + m_Expression + "\"." ) );
aReporter->Report( _( "Evaluating expression \"" + GetExpression() + "\"." ) );
if( !m_ucode )
{
@ -195,12 +207,11 @@ bool DRC_RULE_CONDITION::Compile( REPORTER* aReporter, int aSourceLine, int aSou
PCB_EXPR_COMPILER compiler;
compiler.SetErrorCallback( errorHandler );
if (!m_ucode)
m_ucode = new PCB_EXPR_UCODE;
m_ucode = std::make_unique<PCB_EXPR_UCODE>();
PCB_EXPR_CONTEXT preflightContext( F_Cu );
bool ok = compiler.Compile( m_Expression.ToUTF8().data(), m_ucode, &preflightContext );
bool ok = compiler.Compile( GetExpression().ToUTF8().data(), m_ucode.get(), &preflightContext );
return ok;
}

View File

@ -21,39 +21,49 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef DRC_RULE_H
#define DRC_RULE_H
#ifndef DRC_RULE_PROTO_H
#define DRC_RULE_PROTO_H
#include <core/typeinfo.h>
#include <layers_id_colors_and_visibility.h>
#include <netclass.h>
#include <libeval_compiler/libeval_compiler.h>
class BOARD_ITEM;
class PCB_EXPR_UCODE;
#define DISALLOW_VIAS (1 << 0)
#define DISALLOW_MICRO_VIAS (1 << 1)
#define DISALLOW_BB_VIAS (1 << 2)
#define DISALLOW_TRACKS (1 << 3)
#define DISALLOW_PADS (1 << 4)
#define DISALLOW_ZONES (1 << 5)
#define DISALLOW_TEXTS (1 << 6)
#define DISALLOW_GRAPHICS (1 << 7)
#define DISALLOW_HOLES (1 << 8)
#define DISALLOW_FOOTPRINTS (1 << 9)
class DRC_RULE;
class DRC_RULE_CONDITION;
enum DRC_CONSTRAINT_TYPE_T
{
DRC_RULE_ID_UNKNOWN = -1,
DRC_RULE_ID_CLEARANCE = 0,
DRC_RULE_ID_HOLE_SIZE,
DRC_RULE_ID_ANNULUS,
DRC_RULE_ID_TRACK,
DRC_RULE_ID_DISALLOW
DRC_CONSTRAINT_TYPE_UNKNOWN = -1,
DRC_CONSTRAINT_TYPE_CLEARANCE = 0,
DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE,
DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE,
DRC_CONSTRAINT_TYPE_HOLE_SIZE,
DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE,
DRC_CONSTRAINT_TYPE_SILK_TO_PAD,
DRC_CONSTRAINT_TYPE_SILK_TO_SILK,
DRC_CONSTRAINT_TYPE_TRACK_WIDTH,
DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH,
DRC_CONSTRAINT_TYPE_DISALLOW,
DRC_CONSTRAINT_TYPE_VIA_DIAMETER
};
enum DRC_DISALLOW_T
{
DRC_DISALLOW_VIAS = (1 << 0),
DRC_DISALLOW_MICRO_VIAS = (1 << 1),
DRC_DISALLOW_BB_VIAS = (1 << 2),
DRC_DISALLOW_TRACKS = (1 << 3),
DRC_DISALLOW_PADS = (1 << 4),
DRC_DISALLOW_ZONES = (1 << 5),
DRC_DISALLOW_TEXTS = (1 << 6),
DRC_DISALLOW_GRAPHICS = (1 << 7),
DRC_DISALLOW_HOLES = (1 << 8),
DRC_DISALLOW_FOOTPRINTS = (1 << 9)
};
@ -85,37 +95,47 @@ private:
class DRC_CONSTRAINT
{
public:
DRC_CONSTRAINT() :
m_Type( DRC_RULE_ID_UNKNOWN ),
m_DisallowFlags( 0 )
{}
public:
DRC_CONSTRAINT( DRC_CONSTRAINT_TYPE_T aType = DRC_CONSTRAINT_TYPE_UNKNOWN ) :
m_Type( aType ),
m_DisallowFlags( 0 ),
m_parentRule( nullptr ) // fixme
{
}
const MINOPTMAX<int>& GetValue() const { return m_Value; }
MINOPTMAX<int>& Value() { return m_Value; }
void SetParentRule( DRC_RULE *aParentRule ) { m_parentRule = aParentRule; }
DRC_RULE* GetParentRule() const { return m_parentRule; }
public:
DRC_CONSTRAINT_TYPE_T m_Type;
MINOPTMAX<int> m_Value;
int m_DisallowFlags;
private:
DRC_RULE* m_parentRule;
};
class DRC_RULE_CONDITION
{
public:
DRC_RULE_CONDITION();
DRC_RULE_CONDITION( const wxString& aExpression = "" );
~DRC_RULE_CONDITION();
bool EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB, PCB_LAYER_ID aLayer,
REPORTER* aReporter = nullptr );
bool Compile( REPORTER* aReporter, int aSourceLine, int aSourceOffset );
public:
wxString m_Expression;
bool Compile( REPORTER* aReporter, int aSourceLine = 0, int aSourceOffset = 0 );
void SetExpression( const wxString& aExpression ) { m_expression = aExpression; }
wxString GetExpression() const { return m_expression; }
private:
PCB_EXPR_UCODE* m_ucode;
wxString m_expression;
std::unique_ptr<PCB_EXPR_UCODE> m_ucode;
};
@ -125,13 +145,40 @@ public:
DRC_RULE();
virtual ~DRC_RULE();
virtual bool IsImplicit() const
{
return false;
};
virtual bool AppliesTo( const BOARD_ITEM* a, const BOARD_ITEM* b = nullptr ) const
{
return true;
};
virtual bool HasSpecificItemSet() const
{
return false;
};
virtual void FillSpecificItemSet( std::set<BOARD_ITEM*> specificItems )
{
};
void SetPriority( int aPriority ) { m_Priority = aPriority; }
int GetPriority() const { return m_Priority; }
void AddConstraint( DRC_CONSTRAINT& aConstraint );
public:
bool m_Unary;
wxString m_Name;
wxString m_LayerSource;
LSET m_LayerCondition;
wxString m_TestProviderName;
DRC_RULE_CONDITION m_Condition;
DRC_RULE_CONDITION* m_Condition;
std::vector<DRC_CONSTRAINT> m_Constraints;
int m_Priority; // 0 indicates automatic priority generation fixme: use enum
SEVERITY m_Severity;
};
@ -141,4 +188,4 @@ const DRC_CONSTRAINT* GetConstraint( const BOARD_ITEM* aItem, const BOARD_ITEM*
REPORTER* aReporter = nullptr );
#endif // DRC_RULE_H
#endif // DRC_RULE_H

View File

@ -92,7 +92,7 @@ void DRC_RULES_PARSER::Parse( std::vector<DRC_RULE*>& aRules, REPORTER* aReporte
m_reporter = aReporter;
for( T token = NextTok(); token != T_EOF; token = NextTok() )
for( T token = NextTok(); token != T_EOF; token = NextTok() )
{
if( token != T_LEFT )
reportError( _( "Missing '('." ) );
@ -172,7 +172,7 @@ DRC_RULE* DRC_RULES_PARSER::parseDRC_RULE()
rule->m_Name = FromUTF8();
for( token = NextTok(); token != T_RIGHT && token != T_EOF; token = NextTok() )
for( token = NextTok(); token != T_RIGHT && token != T_EOF; token = NextTok() )
{
if( token != T_LEFT )
reportError( _( "Missing '('." ) );
@ -196,8 +196,8 @@ DRC_RULE* DRC_RULES_PARSER::parseDRC_RULE()
if( IsSymbol( token ) )
{
rule->m_Condition.m_Expression = FromUTF8();
rule->m_Condition.Compile( m_reporter, CurLineNumber(), CurOffset() );
rule->m_Condition->SetExpression( FromUTF8() );
rule->m_Condition->Compile( m_reporter, CurLineNumber(), CurOffset() );
}
else
{
@ -241,11 +241,10 @@ DRC_RULE* DRC_RULES_PARSER::parseDRC_RULE()
void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
{
aRule->m_Constraints.emplace_back( DRC_CONSTRAINT() );
DRC_CONSTRAINT constraint;
DRC_CONSTRAINT& constraint = aRule->m_Constraints.back();
int value;
wxString msg;
int value;
wxString msg;
T token = NextTok();
@ -259,11 +258,16 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
switch( token )
{
case T_clearance: constraint.m_Type = DRC_RULE_ID_CLEARANCE; break;
case T_track_width: constraint.m_Type = DRC_RULE_ID_TRACK; break;
case T_annulus_width: constraint.m_Type = DRC_RULE_ID_ANNULUS; break;
case T_hole: constraint.m_Type = DRC_RULE_ID_HOLE_SIZE; break;
case T_disallow: constraint.m_Type = DRC_RULE_ID_DISALLOW; break;
case T_clearance: constraint.m_Type = DRC_CONSTRAINT_TYPE_CLEARANCE; break;
case T_hole_clearance: constraint.m_Type = DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE; break;
case T_edge_clearance: constraint.m_Type = DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE; break;
case T_hole: constraint.m_Type = DRC_CONSTRAINT_TYPE_HOLE_SIZE; break;
case T_courtyard_clearance: constraint.m_Type = DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE; break;
case T_silk_to_pad: constraint.m_Type = DRC_CONSTRAINT_TYPE_SILK_TO_PAD; break;
case T_silk_to_silk: constraint.m_Type = DRC_CONSTRAINT_TYPE_SILK_TO_SILK; break;
case T_track_width: constraint.m_Type = DRC_CONSTRAINT_TYPE_TRACK_WIDTH; break;
case T_annulus_width: constraint.m_Type = DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH; break;
case T_disallow: constraint.m_Type = DRC_CONSTRAINT_TYPE_DISALLOW; break;
default:
msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ),
FromUTF8(),
@ -272,7 +276,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
reportError( msg );
}
if( constraint.m_Type == DRC_RULE_ID_DISALLOW )
if( constraint.m_Type == DRC_CONSTRAINT_TYPE_DISALLOW )
{
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
@ -281,16 +285,16 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
switch( token )
{
case T_track: constraint.m_DisallowFlags |= DISALLOW_TRACKS; break;
case T_via: constraint.m_DisallowFlags |= DISALLOW_VIAS; break;
case T_micro_via: constraint.m_DisallowFlags |= DISALLOW_MICRO_VIAS; break;
case T_buried_via: constraint.m_DisallowFlags |= DISALLOW_BB_VIAS; break;
case T_pad: constraint.m_DisallowFlags |= DISALLOW_PADS; break;
case T_zone: constraint.m_DisallowFlags |= DISALLOW_ZONES; break;
case T_text: constraint.m_DisallowFlags |= DISALLOW_TEXTS; break;
case T_graphic: constraint.m_DisallowFlags |= DISALLOW_GRAPHICS; break;
case T_hole: constraint.m_DisallowFlags |= DISALLOW_HOLES; break;
case T_footprint: constraint.m_DisallowFlags |= DISALLOW_FOOTPRINTS; break;
case T_track: constraint.m_DisallowFlags |= DRC_DISALLOW_TRACKS; break;
case T_via: constraint.m_DisallowFlags |= DRC_DISALLOW_VIAS; break;
case T_micro_via: constraint.m_DisallowFlags |= DRC_DISALLOW_MICRO_VIAS; break;
case T_buried_via: constraint.m_DisallowFlags |= DRC_DISALLOW_BB_VIAS; break;
case T_pad: constraint.m_DisallowFlags |= DRC_DISALLOW_PADS; break;
case T_zone: constraint.m_DisallowFlags |= DRC_DISALLOW_ZONES; break;
case T_text: constraint.m_DisallowFlags |= DRC_DISALLOW_TEXTS; break;
case T_graphic: constraint.m_DisallowFlags |= DRC_DISALLOW_GRAPHICS; break;
case T_hole: constraint.m_DisallowFlags |= DRC_DISALLOW_HOLES; break;
case T_footprint: constraint.m_DisallowFlags |= DRC_DISALLOW_FOOTPRINTS; break;
case T_EOF:
reportError( _( "Missing ')'." ) );
@ -313,7 +317,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
return;
}
for( token = NextTok(); token != T_RIGHT && token != T_EOF; token = NextTok() )
for( token = NextTok(); token != T_RIGHT && token != T_EOF; token = NextTok() )
{
if( token != T_LEFT )
reportError( _( "Missing '('." ) );
@ -396,6 +400,8 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
if( (int) CurTok() != DSN_RIGHT )
reportError( _( "Missing ')'." ) );
aRule->AddConstraint( constraint );
}
@ -416,7 +422,7 @@ void DRC_RULES_PARSER::parseValueWithUnits( const wxString& aExpr, int& aResult
PCB_EXPR_EVALUATOR evaluator;
evaluator.SetErrorCallback( errorHandler );
evaluator.Evaluate( aExpr );
aResult = evaluator.Result();
}

View File

@ -34,7 +34,7 @@
class BOARD_ITEM;
#define DRC_RULE_FILE_VERSION 20200515
#define DRC_RULE_FILE_VERSION 20200610
class DRC_RULES_PARSER : public DRC_RULES_LEXER

View File

@ -1,60 +1,60 @@
#include <drc/drc_engine.h>
#include <drc/drc_item.h>
#include <drc_proto/drc_test_provider.h>
#include <pcbnew/drc/drc_test_provider.h>
test::DRC_TEST_PROVIDER::DRC_TEST_PROVIDER() :
DRC_TEST_PROVIDER::DRC_TEST_PROVIDER() :
m_drcEngine( nullptr ),
m_enable( false )
{
}
void test::DRC_TEST_PROVIDER::Enable( bool enable )
void DRC_TEST_PROVIDER::Enable( bool enable )
{
m_enable = enable;
}
bool test::DRC_TEST_PROVIDER::IsEnabled() const
bool DRC_TEST_PROVIDER::IsEnabled() const
{
return m_enable;
}
const wxString test::DRC_TEST_PROVIDER::GetName() const { return "<no name test>"; }
const wxString test::DRC_TEST_PROVIDER::GetDescription() const { return ""; }
const wxString DRC_TEST_PROVIDER::GetName() const { return "<no name test>"; }
const wxString DRC_TEST_PROVIDER::GetDescription() const { return ""; }
void test::DRC_TEST_PROVIDER::Report( std::shared_ptr<DRC_ITEM> item )
void DRC_TEST_PROVIDER::Report( std::shared_ptr<DRC_ITEM> item )
{
item->SetViolatingTest( this );
m_drcEngine->Report( item, nullptr );
}
void test::DRC_TEST_PROVIDER::ReportWithMarker( std::shared_ptr<DRC_ITEM> item, VECTOR2I aMarkerPos )
void DRC_TEST_PROVIDER::ReportWithMarker( std::shared_ptr<DRC_ITEM> item, VECTOR2I aMarkerPos )
{
item->SetViolatingTest( this );
MARKER_PCB* marker = new MARKER_PCB( item, wxPoint( aMarkerPos.x, aMarkerPos.y) );
m_drcEngine->Report( item, marker );
}
void test::DRC_TEST_PROVIDER::ReportWithMarker( std::shared_ptr<DRC_ITEM> item, wxPoint aMarkerPos )
void DRC_TEST_PROVIDER::ReportWithMarker( std::shared_ptr<DRC_ITEM> item, wxPoint aMarkerPos )
{
item->SetViolatingTest( this );
MARKER_PCB* marker = new MARKER_PCB( item, wxPoint( aMarkerPos.x, aMarkerPos.y) );
m_drcEngine->Report( item, marker ); // fixme: create marker
}
void test::DRC_TEST_PROVIDER::ReportProgress( double aProgress )
void DRC_TEST_PROVIDER::ReportProgress( double aProgress )
{
m_drcEngine->ReportProgress( aProgress );
}
void test::DRC_TEST_PROVIDER::ReportStage ( const wxString& aStageName, int index, int total )
void DRC_TEST_PROVIDER::ReportStage ( const wxString& aStageName, int index, int total )
{
m_drcEngine->ReportStage( aStageName, index, total );
ReportAux( aStageName );
}
void test::DRC_TEST_PROVIDER::ReportAux( const wxString fmt, ... )
void DRC_TEST_PROVIDER::ReportAux( const wxString& fmt, ... )
{
va_list vargs;
va_start( vargs, fmt );
@ -64,45 +64,50 @@ void test::DRC_TEST_PROVIDER::ReportAux( const wxString fmt, ... )
m_drcEngine->ReportAux( str );
}
bool test::DRC_TEST_PROVIDER::isErrorLimitExceeded( int error_code )
bool DRC_TEST_PROVIDER::isErrorLimitExceeded( int error_code )
{
// fixme: implement error limit (or timeout)
return false;
}
EDA_UNITS test::DRC_TEST_PROVIDER::userUnits() const
EDA_UNITS DRC_TEST_PROVIDER::userUnits() const
{
return m_drcEngine->UserUnits();
}
void test::DRC_TEST_PROVIDER::accountCheck( const test::DRC_RULE* ruleToTest )
void DRC_TEST_PROVIDER::accountCheck( const DRC_RULE* ruleToTest )
{
auto it = m_stats.find( ruleToTest );
if( it == m_stats.end() )
m_stats[ ruleToTest ] = 1;
else
it->second++;
}
void test::DRC_TEST_PROVIDER::accountCheck( const test::DRC_CONSTRAINT& constraintToTest )
void DRC_TEST_PROVIDER::accountCheck( const DRC_CONSTRAINT& constraintToTest )
{
accountCheck( constraintToTest.GetParentRule() );
}
void test::DRC_TEST_PROVIDER::reportRuleStatistics()
void DRC_TEST_PROVIDER::reportRuleStatistics()
{
if( !m_isRuleDriven )
return;
m_drcEngine->ReportAux("Rule hit statistics: ");
for( auto stat : m_stats )
for( const std::pair<const DRC_RULE*, int>& stat : m_stats )
{
m_drcEngine->ReportAux( wxString::Format( " - rule '%s': %d hits ", stat.first->GetName().c_str(), stat.second ) );
m_drcEngine->ReportAux( wxString::Format( " - rule '%s': %d hits ",
stat.first->m_Name,
stat.second ) );
}
}
int test::DRC_TEST_PROVIDER::forEachGeometryItem( const std::vector<KICAD_T> aTypes, const LSET aLayers, std::function<bool(BOARD_ITEM*)> aFunc )
int DRC_TEST_PROVIDER::forEachGeometryItem( const std::vector<KICAD_T> aTypes, const LSET aLayers,
std::function<bool( BOARD_ITEM*)> aFunc )
{
BOARD *brd = m_drcEngine->GetBoard();
std::bitset<MAX_STRUCT_TYPE_ID> typeMask;
@ -126,7 +131,7 @@ int test::DRC_TEST_PROVIDER::forEachGeometryItem( const std::vector<KICAD_T> aTy
/* case PCB_TRACE_T:
case PCB_VIA_T:
case PCB_ARC_T:*/
for ( auto item : brd->Tracks() )
for( TRACK* item : brd->Tracks() )
{
if( (item->GetLayerSet() & aLayers).any() )
{
@ -153,7 +158,7 @@ int test::DRC_TEST_PROVIDER::forEachGeometryItem( const std::vector<KICAD_T> aTy
case PCB_TEXT_T:
case PCB_TARGET_T:
*/
for( auto item : brd->Drawings() )
for( BOARD_ITEM* item : brd->Drawings() )
{
if( (item->GetLayerSet() & aLayers).any() )
{
@ -188,7 +193,7 @@ int test::DRC_TEST_PROVIDER::forEachGeometryItem( const std::vector<KICAD_T> aTy
}
}
for( auto item : brd->Zones() )
for( ZONE_CONTAINER* item : brd->Zones() )
{
if( (item->GetLayerSet() & aLayers).any() )
{
@ -202,7 +207,7 @@ int test::DRC_TEST_PROVIDER::forEachGeometryItem( const std::vector<KICAD_T> aTy
}
}
for( auto mod : brd->Modules() )
for( MODULE* mod : brd->Modules() )
{
if( typeMask[ PCB_MODULE_TEXT_T ] )
{
@ -223,7 +228,7 @@ int test::DRC_TEST_PROVIDER::forEachGeometryItem( const std::vector<KICAD_T> aTy
}
}
for( auto pad : mod->Pads() )
for( D_PAD* pad : mod->Pads() )
{
if( (pad->GetLayerSet() & aLayers).any() )
{
@ -237,7 +242,7 @@ int test::DRC_TEST_PROVIDER::forEachGeometryItem( const std::vector<KICAD_T> aTy
}
}
for( auto dwg : mod->GraphicalItems() )
for( BOARD_ITEM* dwg : mod->GraphicalItems() )
{
if( (dwg->GetLayerSet() & aLayers).any() )
{
@ -258,7 +263,7 @@ int test::DRC_TEST_PROVIDER::forEachGeometryItem( const std::vector<KICAD_T> aTy
}
}
for( auto zone : mod->Zones() )
for( ZONE_CONTAINER* zone : mod->Zones() )
{
if( (zone->GetLayerSet() & aLayers).any() )
{

View File

@ -22,8 +22,8 @@
*/
#ifndef DRC_PROVIDER__H
#define DRC_PROVIDER__H
#ifndef DRC_TEST_PROVIDER__H
#define DRC_TEST_PROVIDER__H
#include <class_board.h>
#include <class_marker_pcb.h>
@ -31,38 +31,37 @@
#include <functional>
#include <set>
namespace test {
class DRC_ENGINE;
class DRC_TEST_PROVIDER;
class DRC_TEST_PROVIDER_REGISTRY
{
public:
DRC_TEST_PROVIDER_REGISTRY() {};
~DRC_TEST_PROVIDER_REGISTRY() {};
public:
DRC_TEST_PROVIDER_REGISTRY() {};
~DRC_TEST_PROVIDER_REGISTRY() {};
static DRC_TEST_PROVIDER_REGISTRY& Instance()
{
static DRC_TEST_PROVIDER_REGISTRY self;
return self;
}
static DRC_TEST_PROVIDER_REGISTRY& Instance()
{
static DRC_TEST_PROVIDER_REGISTRY self;
return self;
}
void RegisterTestProvider(DRC_TEST_PROVIDER* provider) { m_providers.push_back(provider); }
std::vector<DRC_TEST_PROVIDER*> GetTestProviders() const { return m_providers; }
private:
std::vector<DRC_TEST_PROVIDER*> m_providers;
void RegisterTestProvider( DRC_TEST_PROVIDER* provider ) { m_providers.push_back( provider ); }
std::vector<DRC_TEST_PROVIDER*> GetTestProviders() const { return m_providers; }
private:
std::vector<DRC_TEST_PROVIDER*> m_providers;
};
template<class T> class DRC_REGISTER_TEST_PROVIDER
{
public:
DRC_REGISTER_TEST_PROVIDER()
{
T* provider = new T;
DRC_TEST_PROVIDER_REGISTRY::Instance().RegisterTestProvider( provider );
}
public:
DRC_REGISTER_TEST_PROVIDER()
{
T* provider = new T;
DRC_TEST_PROVIDER_REGISTRY::Instance().RegisterTestProvider( provider );
}
};
/**
@ -96,7 +95,7 @@ public:
virtual const wxString GetName() const;
virtual const wxString GetDescription() const;
virtual void ReportAux( const wxString fmt, ... );
virtual void ReportAux( const wxString& fmt, ... );
virtual void Report( std::shared_ptr<DRC_ITEM> item );
virtual void ReportWithMarker( std::shared_ptr<DRC_ITEM> item, wxPoint aMarkerPos );
virtual void ReportWithMarker( std::shared_ptr<DRC_ITEM> item, VECTOR2I aMarkerPos );
@ -112,7 +111,6 @@ public:
}
protected:
int forEachGeometryItem( const std::vector<KICAD_T> aTypes, const LSET aLayers,
std::function<bool(BOARD_ITEM*)> aFunc );
@ -128,7 +126,4 @@ protected:
bool m_isRuleDriven = true;
};
};
#endif // DRC_PROVIDER__H
#endif // DRC_TEST_PROVIDER__H

View File

@ -31,7 +31,7 @@
DRC_TEXTVAR_TESTER::DRC_TEXTVAR_TESTER( MARKER_HANDLER aMarkerHandler,
KIGFX::WS_PROXY_VIEW_ITEM* aWorksheet ) :
DRC_TEST_PROVIDER( std::move( aMarkerHandler ) ),
LEGACY_DRC_TEST_PROVIDER( std::move( aMarkerHandler ) ),
m_units( EDA_UNITS::MILLIMETRES ),
m_board( nullptr ),
m_worksheet( aWorksheet )

View File

@ -25,13 +25,13 @@
#ifndef DRC_TEXTVAR_TESTER__H
#define DRC_TEXTVAR_TESTER__H
#include <drc/drc_provider.h>
#include <drc/drc_results_provider.h>
class BOARD;
class DRC_TEXTVAR_TESTER : public DRC_TEST_PROVIDER
class DRC_TEXTVAR_TESTER : public LEGACY_DRC_TEST_PROVIDER
{
public:
DRC_TEXTVAR_TESTER( MARKER_HANDLER aMarkerHandler, KIGFX::WS_PROXY_VIEW_ITEM* aWorksheet );

View File

@ -36,9 +36,9 @@ endif()
add_executable( drc_proto
drc_rules_proto_keywords.cpp
drc_proto_test.cpp
drc_rule.cpp
drc_rule_parser.cpp
drc_test_provider.cpp
../../pcbnew/drc/drc_rule.cpp
../../pcbnew/drc/drc_rule_parser.cpp
../../pcbnew/drc/drc_test_provider.cpp
drc_test_provider_clearance_base.cpp
drc_test_provider_copper_clearance.cpp
drc_test_provider_hole_clearance.cpp
@ -52,8 +52,8 @@ add_executable( drc_proto
drc_test_provider_via_diameter.cpp
drc_test_provider_lvs.cpp
drc_test_provider_misc.cpp
drc_engine.cpp
drc_item.cpp
../../pcbnew/drc/drc_engine.cpp
../../pcbnew/drc/drc_item.cpp
../qa_utils/mocks.cpp
../pcbnew_utils/board_file_utils.cpp
../qa_utils/stdstream_line_reader.cpp

File diff suppressed because it is too large Load Diff

View File

@ -1,373 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2007-2016 Dick Hollenbeck, dick@softplc.com
* Copyright (C) 2017-2019 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef DRC_H
#define DRC_H
#include <board_commit.h>
#include <class_board.h>
#include <class_track.h>
#include <class_marker_pcb.h>
#include <geometry/seg.h>
#include <geometry/shape_poly_set.h>
#include <memory>
#include <vector>
#include <tools/pcb_tool_base.h>
/// DRC error codes:
enum PCB_DRC_CODE {
DRCE_FIRST = 1,
DRCE_UNCONNECTED_ITEMS = DRCE_FIRST, ///< items are unconnected
DRCE_TRACK_NEAR_HOLE, ///< thru hole is too close to track
DRCE_TRACK_NEAR_PAD, ///< pad too close to track
DRCE_TRACK_NEAR_VIA, ///< track too close to via
DRCE_TRACK_NEAR_ZONE, ///< track & zone collide or are too close together
DRCE_TRACK_NEAR_COPPER, ///< track & copper graphic collide or are too close
DRCE_VIA_NEAR_VIA, ///< via too close to via
DRCE_VIA_NEAR_TRACK, ///< via too close to track
DRCE_VIA_NEAR_COPPER, ///< via and copper graphic collide or are too close
DRCE_TRACK_ENDS, ///< track ends are too close
DRCE_TRACK_SEGMENTS_TOO_CLOSE, ///< 2 parallel track segments too close: segm ends between segref ends
DRCE_TRACKS_CROSSING, ///< tracks are crossing
DRCE_TRACK_NEAR_EDGE, ///< track too close to board edge
DRCE_VIA_NEAR_EDGE, ///< via too close to board edge
DRCE_PAD_NEAR_EDGE, ///< pad too close to board edge
DRCE_PAD_NEAR_PAD, ///< pad too close to pad
DRCE_PAD_NEAR_COPPER, ///< pad and copper graphic collide or are too close
DRCE_ZONES_INTERSECT, ///< copper area outlines intersect
DRCE_ZONES_TOO_CLOSE, ///< copper area outlines are too close
DRCE_ZONE_HAS_EMPTY_NET, ///< copper area has a net but no pads in nets, which is suspicious
DRCE_DANGLING_VIA, ///< via which isn't connected to anything
DRCE_DANGLING_TRACK, ///< track with at least one end not connected to anything
DRCE_HOLE_NEAR_PAD, ///< hole too close to pad
DRCE_HOLE_NEAR_TRACK, ///< hole too close to track
DRCE_DRILLED_HOLES_TOO_CLOSE, ///< overlapping drilled holes break drill bits
DRCE_TOO_SMALL_TRACK_WIDTH, ///< Too small track width
DRCE_TOO_LARGE_TRACK_WIDTH, ///< Too small track width
DRCE_TOO_SMALL_VIA, ///< Too small via size
DRCE_TOO_SMALL_VIA_ANNULUS, ///< Via size and drill leave annulus too small
DRCE_TOO_SMALL_VIA_DRILL, ///< Too small via drill
DRCE_TOO_SMALL_PAD_DRILL, ///< Too small via drill
DRCE_VIA_HOLE_BIGGER, ///< via's hole is bigger than its diameter
DRCE_MICROVIA_NOT_ALLOWED, ///< micro vias are not allowed
DRCE_MICROVIA_TOO_MANY_LAYERS, ///< micro via's layer pair incorrect (layers must be adjacent)
DRCE_TOO_SMALL_MICROVIA, ///< Too small micro via size
DRCE_TOO_SMALL_MICROVIA_DRILL, ///< Too small micro via drill
DRCE_BURIED_VIA_NOT_ALLOWED, ///< buried vias are not allowed
DRCE_NETCLASS_TRACKWIDTH, ///< netclass has TrackWidth < board.m_designSettings->m_TrackMinWidth
DRCE_NETCLASS_CLEARANCE, ///< netclass has Clearance < board.m_designSettings->m_TrackClearance
DRCE_NETCLASS_VIAANNULUS, ///< netclass ViaSize & ViaDrill leave annulus < board.m_designSettings->m_ViasMinAnnulus
DRCE_NETCLASS_VIASIZE, ///< netclass has ViaSize < board.m_designSettings->m_ViasMinSize
DRCE_NETCLASS_VIADRILLSIZE, ///< netclass has ViaDrillSize < board.m_designSettings->m_MinThroughDrill
DRCE_NETCLASS_uVIASIZE, ///< netclass has ViaSize < board.m_designSettings->m_MicroViasMinSize
DRCE_NETCLASS_uVIADRILLSIZE, ///< netclass has ViaSize < board.m_designSettings->m_MicroViasMinDrill
DRCE_VIA_INSIDE_KEEPOUT,
DRCE_MICROVIA_INSIDE_KEEPOUT,
DRCE_BBVIA_INSIDE_KEEPOUT,
DRCE_TRACK_INSIDE_KEEPOUT,
DRCE_PAD_INSIDE_KEEPOUT,
DRCE_FOOTPRINT_INSIDE_KEEPOUT,
DRCE_HOLE_INSIDE_KEEPOUT,
DRCE_TEXT_INSIDE_KEEPOUT,
DRCE_GRAPHICS_INSIDE_KEEPOUT,
DRCE_OVERLAPPING_FOOTPRINTS, ///< footprint courtyards overlap
DRCE_MISSING_COURTYARD, ///< footprint has no courtyard defined
DRCE_MALFORMED_COURTYARD, ///< footprint has a courtyard but malformed
///< (not convertible to a closed polygon with holes)
DRCE_PTH_IN_COURTYARD,
DRCE_NPTH_IN_COURTYARD,
DRCE_DISABLED_LAYER_ITEM, ///< item on a disabled layer
DRCE_INVALID_OUTLINE, ///< invalid board outline
DRCE_MISSING_FOOTPRINT, ///< footprint not found for netlist item
DRCE_DUPLICATE_FOOTPRINT, ///< more than one footprints found for netlist item
DRCE_EXTRA_FOOTPRINT, ///< netlist item not found for footprint
DRCE_UNRESOLVED_VARIABLE,
DRCE_LAST = DRCE_UNRESOLVED_VARIABLE,
// These are actually Cleanup Tracks and Vias actions, not DRCE errors
CLEANUP_SHORT,
CLEANUP_REDUNDANT_VIA,
CLEANUP_DUPLICATE_TRACK,
CLEANUP_MERGE_TRACKS,
CLEANUP_DANGLING_TRACK,
CLEANUP_DANGLING_VIA,
CLEANUP_ZERO_LENGTH_TRACK,
CLEANUP_TRACK_IN_PAD
};
class PCB_EDIT_FRAME;
class DIALOG_DRC;
class BOARD_ITEM;
class BOARD;
class D_PAD;
class ZONE_CONTAINER;
class TRACK;
class MARKER_PCB;
class DRC_ITEM;
class NETCLASS;
class EDA_TEXT;
class DRAWSEGMENT;
class NETLIST;
class wxWindow;
class wxString;
class wxTextCtrl;
class DRC_ENGINE
{
}
/**
* Design Rule Checker object that performs all the DRC tests. The output of
* the checking goes to the BOARD file in the form of two MARKER lists. Those
* two lists are displayable in the drc dialog box. And they can optionally
* be sent to a text file on disk.
* This class is given access to the windows and the BOARD
* that it needs via its constructor or public access functions.
*/
class DRC : public PCB_TOOL_BASE
{
friend class DIALOG_DRC;
public:
DRC();
~DRC();
/// @copydoc TOOL_INTERACTIVE::Reset()
void Reset( RESET_REASON aReason ) override;
private:
bool m_doUnconnectedTest; // enable unconnected tests
bool m_testTracksAgainstZones; // enable zone to items clearance tests
bool m_doKeepoutTest; // enable keepout areas to items clearance tests
bool m_refillZones; // refill zones if requested (by user).
bool m_reportAllTrackErrors; // Report all tracks errors (or only 4 first errors)
bool m_testFootprints; // Test footprints against schematic
PCB_EDIT_FRAME* m_editFrame; // The pcb frame editor which owns the board
BOARD* m_pcb;
SHAPE_POLY_SET m_board_outlines; // The board outline including cutouts
bool m_board_outline_valid;
DIALOG_DRC* m_drcDialog;
std::vector<DRC_ITEM*> m_unconnected; // list of unconnected pads
std::vector<DRC_ITEM*> m_footprints; // list of footprint warnings
bool m_drcRun; // indicates DRC has been run at least once
bool m_footprintsTested; // indicates footprints were tested in last run
std::vector<DRC_SELECTOR*> m_ruleSelectors;
std::vector<DRC_RULE*> m_rules;
// Temp variables for performance during a single DRC run
//
// wxString's c'tor is surprisingly expensive, and in the world of DRC everything matters
//
wxString m_msg;
wxString m_clearanceSource;
int m_largestClearance;
private:
///> Sets up handlers for various events.
void setTransitions() override;
/**
* Update needed pointers from the one pointer which is known not to change.
*/
void updatePointers();
EDA_UNITS userUnits() const { return m_editFrame->GetUserUnits(); }
/**
* Adds a DRC marker to the PCB through the COMMIT mechanism.
*/
void addMarkerToPcb( BOARD_COMMIT& aCommit, MARKER_PCB* aMarker );
//-----<categorical group tests>-----------------------------------------
/**
* Perform the DRC on all tracks.
*
* This test can take a while, a progress bar can be displayed
* @param aActiveWindow = the active window ued as parent for the progress bar
* @param aShowProgressBar = true to show a progress bar
* (Note: it is shown only if there are many tracks)
*/
void testTracks( BOARD_COMMIT& aCommit, wxWindow * aActiveWindow, bool aShowProgressBar );
void testPadClearances( BOARD_COMMIT& aCommit );
void testUnconnected();
void testZones( BOARD_COMMIT& aCommit );
void testCopperDrawItem( BOARD_COMMIT& aCommit, BOARD_ITEM* aDrawing );
void testCopperTextAndGraphics( BOARD_COMMIT& aCommit );
// Tests for items placed on disabled layers (causing false connections).
void testDisabledLayers( BOARD_COMMIT& aCommit );
/**
* Test that the board outline is contiguous and composed of valid elements
*/
void testOutline( BOARD_COMMIT& aCommit );
//-----<single "item" tests>-----------------------------------------
/**
* Test the clearance between aRefPad and other pads.
*
* The pad list must be sorted by x coordinate.
*
* @param aRefPad is the pad to test
* @param aStart is the first pad of the list to test against aRefPad
* @param aEnd is the end of the list and is not included
* @param x_limit is used to stop the test
* (i.e. when the current pad pos X in list exceeds this limit, because the list
* is sorted by X coordinate)
*/
bool doPadToPadsDrc( BOARD_COMMIT& aCommit, D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd,
int x_limit );
/**
* Test the current segment.
*
* @param aRefSeg The segment to test
* @param aStartIt the iterator to the first track to test
* @param aEndIt the marker for the iterator end
* @param aTestZones true if should do copper zones test. This can be very time consumming
* @param aLayer sets the layer to test against
* @return bool - true if no problems, else false and m_currentMarker is
* filled in with the problem information.
*/
void doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aStartIt,
TRACKS::iterator aEndIt, bool aTestZones, PCB_LAYER_ID aLayer );
/**
* Test a single via for DRC errors
*
* @param aCommit The board commit to add DRC errors
* @param aRefVia The via to test against design settings
*/
void doSingleViaDRC( BOARD_COMMIT& aCommit, VIA* aRefVia );
/**
* Test a single track segment for DRC errors
*
* @param aCommit The board commit to add DRC errors
* @param aRefSeg The track to test against design settings
*/
void doSingleTrackDRC( BOARD_COMMIT& aCommit, TRACK* aRefSeg );
//-----<single tests>----------------------------------------------
/**
* @param aRefPad The reference pad to check
* @param aPad Another pad to check against
* @param aMinClearance is the minimum allowed distance between the pads
* @param aActual [out] it the actual distance (only guaranteed to be set for violations)
* @return bool - true if clearance between aRefPad and aPad is >= aMinClearance, else false
*/
bool checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, int aMinClearance, int* aActual );
/**
* Check the distance from a pad to segment. This function uses several
* instance variable not passed in:
* @param aPad Is the pad involved in the check
* @param aSegmentWidth width of the segment to test
* @param aMinDist Is the minimum clearance needed
* @param aActualDist [out] Is the actual clearance (only guarantted to be set on violations)
*
* @return true distance >= dist_min,
* false if distance < dist_min
*/
bool checkClearanceSegmToPad( const SEG& seg, int segWidth, const D_PAD* pad,
int minClearance, int* aActualDist );
//-----</single tests>---------------------------------------------
public:
/**
* Load the DRC rules. Must be called after the netclasses have been read.
*/
bool LoadRules();
/**
* Fetches a reasonable point for marking a violoation between two non-point objects.
*/
static wxPoint GetLocation( TRACK* aTrack, ZONE_CONTAINER* aConflictZone );
static wxPoint GetLocation( TRACK* aTrack, const SEG& aConflictSeg );
/**
* Open a dialog and prompts the user, then if a test run button is
* clicked, runs the test(s) and creates the MARKERS. The dialog is only
* created if it is not already in existence.
*
* @param aParent is the parent window for wxWidgets. Usually the PCB editor frame
* but can be another dialog
* if aParent == NULL (default), the parent will be the PCB editor frame
* and the dialog will be not modal (just float on parent
* if aParent is specified, the dialog will be modal.
* The modal mode is mandatory if the dialog is created from another dialog, not
* from the PCB editor frame
*/
void ShowDRCDialog( wxWindow* aParent );
int ShowDRCDialog( const TOOL_EVENT& aEvent );
/**
* Check to see if the DRC dialog is currently shown
*
* @return true if the dialog is shown
*/
bool IsDRCDialogShown();
/**
* Deletes this ui dialog box and zeros out its pointer to remember
* the state of the dialog's existence.
*
* @param aReason Indication of which button was clicked to cause the destruction.
* if aReason == wxID_OK, design parameters values which can be entered from the dialog
* will bbe saved in design parameters list
*/
void DestroyDRCDialog( int aReason );
/**
* Run all the tests specified with a previous call to
* SetSettings()
* @param aMessages = a wxTextControl where to display some activity messages. Can be NULL
*/
void RunTests( wxTextCtrl* aMessages = NULL );
};
#endif // DRC_H

File diff suppressed because it is too large Load Diff

View File

@ -1,189 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2010 Dick Hollenbeck, dick@softplc.com
* Copyright (C) 2004-2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2018-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <drc/drc_courtyard_tester.h>
#include <class_module.h>
#include <drc/drc.h>
#include <widgets/ui_common.h>
#include <memory>
DRC_COURTYARD_TESTER::DRC_COURTYARD_TESTER( MARKER_HANDLER aMarkerHandler ) :
DRC_TEST_PROVIDER( std::move( aMarkerHandler ) )
{
}
bool DRC_COURTYARD_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard )
{
// Detects missing (or malformed) footprint courtyards and courtyard incursions (for those
// with a courtyard).
wxString msg;
bool success = true;
// Update courtyard polygons, and test for missing courtyard definition:
for( MODULE* footprint : aBoard.Modules() )
{
if( footprint->BuildPolyCourtyard() )
{
if( !aBoard.GetDesignSettings().Ignore( DRCE_MISSING_COURTYARD )
&& footprint->GetPolyCourtyardFront().OutlineCount() == 0
&& footprint->GetPolyCourtyardBack().OutlineCount() == 0 )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_MISSING_COURTYARD );
drcItem->SetItems( footprint );
HandleMarker( new MARKER_PCB( drcItem, footprint->GetPosition() ) );
success = false;
}
else
{
footprint->GetPolyCourtyardFront().BuildBBoxCaches();
footprint->GetPolyCourtyardBack().BuildBBoxCaches();
}
}
else
{
if( !aBoard.GetDesignSettings().Ignore( DRCE_MALFORMED_COURTYARD ) )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_MALFORMED_COURTYARD );
msg.Printf( drcItem->GetErrorText() + _( " (not a closed shape)" ) );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( footprint );
HandleMarker( new MARKER_PCB( drcItem, footprint->GetPosition() ) );
success = false;
}
}
}
if( !aBoard.GetDesignSettings().Ignore( DRCE_OVERLAPPING_FOOTPRINTS ) )
{
for( auto it1 = aBoard.Modules().begin(); it1 != aBoard.Modules().end(); it1++ )
{
MODULE* footprint = *it1;
SHAPE_POLY_SET& footprintFront = footprint->GetPolyCourtyardFront();
SHAPE_POLY_SET& footprintBack = footprint->GetPolyCourtyardBack();
if( footprintFront.OutlineCount() == 0 && footprintBack.OutlineCount() == 0 )
continue; // No courtyards defined
for( auto it2 = it1 + 1; it2 != aBoard.Modules().end(); it2++ )
{
MODULE* test = *it2;
SHAPE_POLY_SET& testFront = test->GetPolyCourtyardFront();
SHAPE_POLY_SET& testBack = test->GetPolyCourtyardBack();
SHAPE_POLY_SET intersection;
bool overlap = false;
wxPoint pos;
if( footprintFront.OutlineCount() > 0 && testFront.OutlineCount() > 0
&& footprintFront.BBoxFromCaches().Intersects( testFront.BBoxFromCaches() ) )
{
intersection.RemoveAllContours();
intersection.Append( footprintFront );
// Build the common area between footprint and the test:
intersection.BooleanIntersection( testFront, SHAPE_POLY_SET::PM_FAST );
// If the intersection exists then they overlap
if( intersection.OutlineCount() > 0 )
{
overlap = true;
pos = (wxPoint) intersection.CVertex( 0, 0, -1 );
}
}
if( footprintBack.OutlineCount() > 0 && testBack.OutlineCount() > 0
&& footprintBack.BBoxFromCaches().Intersects( testBack.BBoxFromCaches() ) )
{
intersection.RemoveAllContours();
intersection.Append( footprintBack );
intersection.BooleanIntersection( testBack, SHAPE_POLY_SET::PM_FAST );
if( intersection.OutlineCount() > 0 )
{
overlap = true;
pos = (wxPoint) intersection.CVertex( 0, 0, -1 );
}
}
if( overlap )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_OVERLAPPING_FOOTPRINTS );
drcItem->SetItems( footprint, test );
HandleMarker( new MARKER_PCB( drcItem, pos ) );
success = false;
}
}
}
}
if( !aBoard.GetDesignSettings().Ignore( DRCE_PTH_IN_COURTYARD )
|| !aBoard.GetDesignSettings().Ignore( DRCE_NPTH_IN_COURTYARD ) )
{
for( MODULE* footprint : aBoard.Modules() )
{
SHAPE_POLY_SET& footprintFront = footprint->GetPolyCourtyardFront();
SHAPE_POLY_SET& footprintBack = footprint->GetPolyCourtyardBack();
if( footprintFront.OutlineCount() == 0 && footprintBack.OutlineCount() == 0 )
continue; // No courtyards defined
for( MODULE* candidate : aBoard.Modules() )
{
if( footprint == candidate )
continue;
for( D_PAD* pad : candidate->Pads() )
{
if( pad->GetDrillSize().x == 0 || pad->GetDrillSize().y == 0 )
continue;
wxPoint pos = pad->GetPosition();
if( footprintFront.Contains( pos, -1, 0, true /* use bbox caches */ )
|| footprintBack.Contains( pos, -1, 0, true /* use bbox caches */ ) )
{
int code = pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED ?
DRCE_NPTH_IN_COURTYARD :
DRCE_PTH_IN_COURTYARD;
DRC_ITEM* drcItem = new DRC_ITEM( code );
drcItem->SetItems( footprint, pad );
HandleMarker( new MARKER_PCB( drcItem, pos ) );
success = false;
}
}
}
}
}
return success;
}

View File

@ -1,43 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2018 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef DRC_COURTYARD_OVERLAP__H
#define DRC_COURTYARD_OVERLAP__H
#include <drc/drc_provider.h>
class BOARD;
class DRC_COURTYARD_TESTER : public DRC_TEST_PROVIDER
{
public:
DRC_COURTYARD_TESTER( MARKER_HANDLER aMarkerHandler );
virtual ~DRC_COURTYARD_TESTER() {};
bool RunDRC( EDA_UNITS aUnits, BOARD& aBoard ) override;
};
#endif // DRC_COURTYARD_OVERLAP__H

View File

@ -1,283 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <drc/drc_drilled_hole_tester.h>
#include <class_module.h>
#include <drc/drc.h>
#include <widgets/ui_common.h>
DRC_DRILLED_HOLE_TESTER::DRC_DRILLED_HOLE_TESTER( MARKER_HANDLER aMarkerHandler ) :
DRC_TEST_PROVIDER( std::move( aMarkerHandler ) ),
m_units( EDA_UNITS::MILLIMETRES ),
m_board( nullptr ),
m_largestRadius( 0 )
{
}
bool DRC_DRILLED_HOLE_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard )
{
bool success = true;
// Test drilled holes to minimize drill bit breakage.
//
// Check pad & std. via circular holes for hole-to-hole-min (non-circular holes are milled)
// Check pad & std. via holes for via-min-drill (minimum hole classification)
// Check uvia holes for uvia-min-drill (laser drill classification)
m_units = aUnits;
m_board = &aBoard;
m_holes.clear();
m_largestRadius = 0;
for( MODULE* mod : aBoard.Modules() )
{
for( D_PAD* pad : mod->Pads( ) )
success &= checkPad( pad );
}
for( TRACK* track : aBoard.Tracks() )
{
VIA* via = dynamic_cast<VIA*>( track );
if( via )
{
if( via->GetViaType() == VIATYPE::MICROVIA )
success &= checkMicroVia( via );
else
success &= checkVia( via );
}
}
success &= checkHoles();
return success;
}
bool DRC_DRILLED_HOLE_TESTER::checkPad( D_PAD* aPad )
{
bool success = true;
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
int holeSize = std::min( aPad->GetDrillSize().x, aPad->GetDrillSize().y );
if( holeSize == 0 )
return true;
if( !bds.Ignore( DRCE_TOO_SMALL_PAD_DRILL ) )
{
int minHole = bds.m_MinThroughDrill;
wxString minHoleSource = _( "board minimum" );
DRC_RULE* rule = GetRule( aPad, nullptr, DRC_CONSTRAINT_TYPE_HOLE_SIZE );
if( rule )
{
minHole = rule->m_MinHole;
minHoleSource = wxString::Format( _( "'%s' rule" ), rule->m_Name );
}
if( holeSize < minHole )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_PAD_DRILL );
m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ),
minHoleSource,
MessageTextFromValue( m_units, minHole, true ),
MessageTextFromValue( m_units, holeSize, true ) );
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( aPad );
HandleMarker( new MARKER_PCB( drcItem, aPad->GetPosition() ) );
success = false;
}
}
if( !bds.Ignore( DRCE_DRILLED_HOLES_TOO_CLOSE ) && bds.m_HoleToHoleMin != 0 )
{
if( aPad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
addHole( aPad->GetPosition(), aPad->GetDrillSize().x / 2, aPad );
}
return success;
}
bool DRC_DRILLED_HOLE_TESTER::checkVia( VIA* via )
{
bool success = true;
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
if( !bds.Ignore( DRCE_TOO_SMALL_VIA_DRILL ) )
{
int minHole = bds.m_MinThroughDrill;
wxString minHoleSource = _( "board minimum" );
DRC_RULE* rule = GetRule( via, nullptr, DRC_CONSTRAINT_TYPE_HOLE_SIZE );
if( rule )
{
minHole = rule->m_MinHole;
minHoleSource = wxString::Format( _( "'%s' rule" ), rule->m_Name );
}
if( via->GetDrillValue() < minHole )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_VIA_DRILL );
m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ),
minHoleSource,
MessageTextFromValue( m_units, minHole, true ),
MessageTextFromValue( m_units, via->GetDrillValue(), true ) );
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( via );
HandleMarker( new MARKER_PCB( drcItem, via->GetPosition() ) );
success = false;
}
}
if( !bds.Ignore( DRCE_DRILLED_HOLES_TOO_CLOSE ) && bds.m_HoleToHoleMin != 0 )
{
addHole( via->GetPosition(), via->GetDrillValue() / 2, via );
}
return success;
}
bool DRC_DRILLED_HOLE_TESTER::checkMicroVia( VIA* via )
{
bool success = true;
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
if( !bds.Ignore( DRCE_TOO_SMALL_MICROVIA_DRILL ) )
{
int minHole = bds.m_MicroViasMinDrill;
wxString minHoleSource = _( "board minimum" );
DRC_RULE* rule = GetRule( via, nullptr, DRC_CONSTRAINT_TYPE_HOLE_SIZE );
if( rule )
{
minHole = rule->m_MinHole;
minHoleSource = wxString::Format( _( "'%s' rule" ), rule->m_Name );
}
if( via->GetDrillValue() < minHole )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_MICROVIA_DRILL );
m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ),
minHoleSource,
MessageTextFromValue( m_units, minHole, true ),
MessageTextFromValue( m_units, via->GetDrillValue(), true ) );
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( via );
HandleMarker( new MARKER_PCB( drcItem, via->GetPosition() ) );
success = false;
}
}
return success;
}
void DRC_DRILLED_HOLE_TESTER::addHole( const wxPoint& aLocation, int aRadius, BOARD_ITEM* aOwner )
{
DRILLED_HOLE hole;
hole.m_location = aLocation;
hole.m_drillRadius = aRadius;
hole.m_owner = aOwner;
m_largestRadius = std::max( m_largestRadius, aRadius );
m_holes.push_back( hole );
}
bool DRC_DRILLED_HOLE_TESTER::checkHoles()
{
bool success = true;
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
// No need to check if we're ignoring DRCE_DRILLED_HOLES_TOO_CLOSE; if we are then we
// won't have collected any holes to test.
// Sort holes by X for performance. In the nested iteration we then need to look at
// following holes only while they are within the refHole's neighborhood as defined by
// the refHole radius + the minimum hole-to-hole clearance + the largest radius any of
// the following holes can have.
std::sort( m_holes.begin(), m_holes.end(),
[]( const DRILLED_HOLE& a, const DRILLED_HOLE& b )
{
if( a.m_location.x == b.m_location.x )
return a.m_location.y < b.m_location.y;
else
return a.m_location.x < b.m_location.x;
} );
for( size_t ii = 0; ii < m_holes.size(); ++ii )
{
const DRILLED_HOLE& refHole = m_holes[ ii ];
int neighborhood = refHole.m_drillRadius + bds.m_HoleToHoleMin + m_largestRadius;
for( size_t jj = ii + 1; jj < m_holes.size(); ++jj )
{
const DRILLED_HOLE& checkHole = m_holes[ jj ];
if( refHole.m_location.x + neighborhood < checkHole.m_location.x )
break;
// Holes with identical locations are allowable
if( checkHole.m_location == refHole.m_location )
continue;
int actual = KiROUND( GetLineLength( checkHole.m_location, refHole.m_location ) );
actual = std::max( 0, actual - checkHole.m_drillRadius - refHole.m_drillRadius );
if( actual < bds.m_HoleToHoleMin )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_DRILLED_HOLES_TOO_CLOSE );
m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; actual %s)" ),
MessageTextFromValue( m_units, bds.m_HoleToHoleMin, true ),
MessageTextFromValue( m_units, actual, true ) );
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( refHole.m_owner, checkHole.m_owner );
HandleMarker( new MARKER_PCB( drcItem, refHole.m_location ) );
success = false;
}
}
}
return success;
}

View File

@ -1,68 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef DRC_DRILLED_HOLE_TESTER__H
#define DRC_DRILLED_HOLE_TESTER__H
#include <drc/drc_provider.h>
class BOARD;
class BOARD_ITEM;
class DRC_DRILLED_HOLE_TESTER : public DRC_TEST_PROVIDER
{
public:
DRC_DRILLED_HOLE_TESTER( MARKER_HANDLER aMarkerHandler );
virtual ~DRC_DRILLED_HOLE_TESTER() {};
bool RunDRC( EDA_UNITS aUnits, BOARD& aBoard ) override;
private:
bool checkPad( D_PAD* aPad );
bool checkVia( VIA* aVia );
bool checkMicroVia( VIA* aVia );
void addHole( const wxPoint& aLocation, int aRadius, BOARD_ITEM* aOwner );
bool checkHoles();
private:
struct DRILLED_HOLE
{
wxPoint m_location;
int m_drillRadius = 0;
BOARD_ITEM* m_owner = nullptr;
};
EDA_UNITS m_units;
BOARD* m_board;
std::vector<DRILLED_HOLE> m_holes;
int m_largestRadius;
wxString m_msg; // Construct only once for performance
};
#endif // DRC_DRILLED_HOLE_TESTER__H

View File

@ -1,255 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2007 Dick Hollenbeck, dick@softplc.com
* Copyright (C) 2015-2020 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <vector>
#include <fctsys.h>
#include <common.h>
#include <drc_proto/drc_item.h>
#include <class_board.h>
// These, being statically-defined, require specialized I18N handling. We continue to
// use the _() macro so that string harvesting by the I18N framework doesn't have to be
// specialized, but we don't translate on initialization and instead do it in the getters.
#undef _
#define _(s) s
test::DRC_ITEM test::DRC_ITEM::unconnectedItems( DRCE_UNCONNECTED_ITEMS,
_( "Unconnected items" ),
wxT( "unconnected_items" ) );
test::DRC_ITEM test::DRC_ITEM::shortingItems( DRCE_SHORTING_ITEMS,
_( "Items shorting two nets" ),
wxT( "shorting_items" ) );
test::DRC_ITEM test::DRC_ITEM::itemsNotAllowed( DRCE_ALLOWED_ITEMS,
_( "Items not allowed" ),
wxT( "items_not_allowed" ) );
test::DRC_ITEM test::DRC_ITEM::clearance( DRCE_CLEARANCE,
_( "Clearance violation" ),
wxT( "clearance" ) );
test::DRC_ITEM test::DRC_ITEM::tracksCrossing( DRCE_TRACKS_CROSSING,
_( "Tracks crossing" ),
wxT( "tracks_crossing" ) );
test::DRC_ITEM test::DRC_ITEM::copperEdgeClearance( DRCE_COPPER_EDGE_CLEARANCE,
_( "Board edge clearance violation" ),
wxT( "copper_edge_clearance" ) );
test::DRC_ITEM test::DRC_ITEM::zonesIntersect( DRCE_ZONES_INTERSECT,
_( "Copper areas intersect" ),
wxT( "zones_intersect" ) );
test::DRC_ITEM test::DRC_ITEM::zoneHasEmptyNet( DRCE_ZONE_HAS_EMPTY_NET,
_( "Copper zone net has no pads" ),
wxT( "zone_has_empty_net" ) );
test::DRC_ITEM test::DRC_ITEM::viaDangling( DRCE_DANGLING_VIA,
_( "Via is not connected" ),
wxT( "via_dangling" ) );
test::DRC_ITEM test::DRC_ITEM::trackDangling( DRCE_DANGLING_TRACK,
_( "Track has unconnected end" ),
wxT( "track_dangling" ) );
test::DRC_ITEM test::DRC_ITEM::holeClearance( DRCE_HOLE_CLEARANCE,
_( "Drilled hole clearance violation" ),
wxT( "hole_clearance" ) );
test::DRC_ITEM test::DRC_ITEM::trackWidth( DRCE_TRACK_WIDTH,
_( "Track width outside allowed limits" ),
wxT( "track_width" ) );
test::DRC_ITEM test::DRC_ITEM::viaTooSmall( DRCE_TOO_SMALL_VIA,
_( "Via size too small" ),
wxT( "via_too_small" ) );
test::DRC_ITEM test::DRC_ITEM::annulus( DRCE_ANNULUS,
_( "annulus" ),
wxT( "annulus" ) );
test::DRC_ITEM test::DRC_ITEM::drillTooSmall( DRCE_TOO_SMALL_DRILL,
_( "Drill too small" ),
wxT( "drill_too_small" ) );
test::DRC_ITEM test::DRC_ITEM::viaHoleLargerThanPad( DRCE_VIA_HOLE_BIGGER,
_( "Via hole larger than diameter" ),
wxT( "via_hole_larger_than_pad" ) );
test::DRC_ITEM test::DRC_ITEM::padstack( DRCE_PADSTACK,
_( "Padstack is not valid" ),
wxT( "padstack" ) );
test::DRC_ITEM test::DRC_ITEM::microviaTooSmall( DRCE_TOO_SMALL_MICROVIA,
_( "Micro via size too small" ),
wxT( "microvia_too_small" ) );
test::DRC_ITEM test::DRC_ITEM::microviaDrillTooSmall( DRCE_TOO_SMALL_MICROVIA_DRILL,
_( "Micro via drill too small" ),
wxT( "microvia_drill_too_small" ) );
test::DRC_ITEM test::DRC_ITEM::keepout( DRCE_KEEPOUT,
_( "Keepout violation" ),
wxT( "keepout" ) );
test::DRC_ITEM test::DRC_ITEM::courtyardsOverlap( DRCE_OVERLAPPING_FOOTPRINTS,
_( "Courtyards overlap" ),
wxT( "courtyards_overlap" ) );
test::DRC_ITEM test::DRC_ITEM::missingCourtyard( DRCE_MISSING_COURTYARD,
_( "Footprint has no courtyard defined" ),
wxT( "missing_courtyard" ) );
test::DRC_ITEM test::DRC_ITEM::malformedCourtyard( DRCE_MALFORMED_COURTYARD,
_( "Footprint has malformed courtyard" ),
wxT( "malformed_courtyard" ) );
test::DRC_ITEM test::DRC_ITEM::pthInsideCourtyard( DRCE_PTH_IN_COURTYARD,
_( "PTH inside courtyard" ),
wxT( "pth_inside_courtyard" ) );
test::DRC_ITEM test::DRC_ITEM::npthInsideCourtyard( DRCE_NPTH_IN_COURTYARD,
_( "NPTH inside courtyard" ),
wxT( "npth_inside_courtyard" ) );
test::DRC_ITEM test::DRC_ITEM::itemOnDisabledLayer( DRCE_DISABLED_LAYER_ITEM,
_( "Item on a disabled layer" ),
wxT( "item_on_disabled_layer" ) );
test::DRC_ITEM test::DRC_ITEM::invalidOutline( DRCE_INVALID_OUTLINE,
_( "Board has malformed outline" ),
wxT( "invalid_outline" ) );
test::DRC_ITEM test::DRC_ITEM::duplicateFootprints( DRCE_DUPLICATE_FOOTPRINT,
_( "Duplicate footprints" ),
wxT( "duplicate_footprints" ) );
test::DRC_ITEM test::DRC_ITEM::missingFootprint( DRCE_MISSING_FOOTPRINT,
_( "Missing footprint" ),
wxT( "missing_footprint" ) );
test::DRC_ITEM test::DRC_ITEM::extraFootprint( DRCE_EXTRA_FOOTPRINT,
_( "Extra footprint" ),
wxT( "extra_footprint" ) );
test::DRC_ITEM test::DRC_ITEM::unresolvedVariable( DRCE_UNRESOLVED_VARIABLE,
_( "Unresolved text variable" ),
wxT( "unresolved_variable" ) );
std::vector<std::reference_wrapper<RC_ITEM>> test::DRC_ITEM::allItemTypes( {
DRC_ITEM::unconnectedItems,
DRC_ITEM::shortingItems,
DRC_ITEM::itemsNotAllowed,
DRC_ITEM::clearance,
DRC_ITEM::tracksCrossing,
DRC_ITEM::copperEdgeClearance,
DRC_ITEM::zonesIntersect,
DRC_ITEM::zoneHasEmptyNet,
DRC_ITEM::viaDangling,
DRC_ITEM::trackDangling,
DRC_ITEM::holeClearance,
DRC_ITEM::trackWidth,
DRC_ITEM::viaTooSmall,
DRC_ITEM::annulus,
DRC_ITEM::drillTooSmall,
DRC_ITEM::viaHoleLargerThanPad,
DRC_ITEM::padstack,
DRC_ITEM::microviaTooSmall,
DRC_ITEM::microviaDrillTooSmall,
DRC_ITEM::keepout,
DRC_ITEM::courtyardsOverlap,
DRC_ITEM::missingCourtyard,
DRC_ITEM::malformedCourtyard,
DRC_ITEM::pthInsideCourtyard,
DRC_ITEM::npthInsideCourtyard,
DRC_ITEM::itemOnDisabledLayer,
DRC_ITEM::invalidOutline,
DRC_ITEM::duplicateFootprints,
DRC_ITEM::missingFootprint,
DRC_ITEM::extraFootprint,
DRC_ITEM::unresolvedVariable
} );
std::shared_ptr<test::DRC_ITEM> test::DRC_ITEM::Create( int aErrorCode )
{
DRC_ITEM *item;
switch( aErrorCode )
{
case DRCE_UNCONNECTED_ITEMS: item = new DRC_ITEM( unconnectedItems ); break;
case DRCE_SHORTING_ITEMS: item = new DRC_ITEM( shortingItems ); break;
case DRCE_ALLOWED_ITEMS: item = new DRC_ITEM( itemsNotAllowed ); break;
case DRCE_CLEARANCE: item = new DRC_ITEM( clearance ); break;
case DRCE_TRACKS_CROSSING: item = new DRC_ITEM( tracksCrossing ); break;
case DRCE_COPPER_EDGE_CLEARANCE: item = new DRC_ITEM( copperEdgeClearance ); break;
case DRCE_ZONES_INTERSECT: item = new DRC_ITEM( zonesIntersect ); break;
case DRCE_ZONE_HAS_EMPTY_NET: item = new DRC_ITEM( zoneHasEmptyNet ); break;
case DRCE_DANGLING_VIA: item = new DRC_ITEM( viaDangling ); break;
case DRCE_DANGLING_TRACK: item = new DRC_ITEM( trackDangling ); break;
case DRCE_HOLE_CLEARANCE: item = new DRC_ITEM( holeClearance ); break;
case DRCE_TRACK_WIDTH: item = new DRC_ITEM( trackWidth ); break;
case DRCE_TOO_SMALL_VIA: item = new DRC_ITEM( viaTooSmall ); break;
case DRCE_ANNULUS: item = new DRC_ITEM( annulus ); break;
case DRCE_TOO_SMALL_DRILL: item = new DRC_ITEM( drillTooSmall ); break;
case DRCE_VIA_HOLE_BIGGER: item = new DRC_ITEM( viaHoleLargerThanPad ); break;
case DRCE_PADSTACK: item = new DRC_ITEM( padstack ); break;
case DRCE_TOO_SMALL_MICROVIA: item = new DRC_ITEM( microviaTooSmall ); break;
case DRCE_TOO_SMALL_MICROVIA_DRILL: item = new DRC_ITEM( microviaDrillTooSmall ); break;
case DRCE_KEEPOUT: item = new DRC_ITEM( keepout ); break;
case DRCE_OVERLAPPING_FOOTPRINTS: item = new DRC_ITEM( courtyardsOverlap ); break;
case DRCE_MISSING_COURTYARD: item = new DRC_ITEM( missingCourtyard ); break;
case DRCE_MALFORMED_COURTYARD: item = new DRC_ITEM( malformedCourtyard ); break;
case DRCE_PTH_IN_COURTYARD: item = new DRC_ITEM( pthInsideCourtyard ); break;
case DRCE_NPTH_IN_COURTYARD: item = new DRC_ITEM( npthInsideCourtyard ); break;
case DRCE_DISABLED_LAYER_ITEM: item = new DRC_ITEM( itemOnDisabledLayer ); break;
case DRCE_INVALID_OUTLINE: item = new DRC_ITEM( invalidOutline ); break;
case DRCE_MISSING_FOOTPRINT: item = new DRC_ITEM( duplicateFootprints ); break;
case DRCE_DUPLICATE_FOOTPRINT: item = new DRC_ITEM( missingFootprint ); break;
case DRCE_EXTRA_FOOTPRINT: item = new DRC_ITEM( extraFootprint ); break;
case DRCE_UNRESOLVED_VARIABLE: item = new DRC_ITEM( unresolvedVariable ); break;
default:
wxFAIL_MSG( wxString::Format( "Unknown DRC error code %d", aErrorCode ) );
return nullptr;
}
return std::shared_ptr<test::DRC_ITEM>( item );
}
std::shared_ptr<test::DRC_ITEM> test::DRC_ITEM::Create( const wxString& aErrorKey )
{
for( const RC_ITEM& item : allItemTypes )
{
if( aErrorKey == item.GetSettingsKey() )
return std::shared_ptr<DRC_ITEM>( new DRC_ITEM( static_cast<const DRC_ITEM&>( item ) ) );
}
// This can happen if a project has old-format exclusions. Just drop these items.
return nullptr;
}

View File

@ -1,351 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <drc/drc_keepout_tester.h>
#include <class_module.h>
#include <drc/drc.h>
DRC_KEEPOUT_TESTER::DRC_KEEPOUT_TESTER( MARKER_HANDLER aMarkerHandler ) :
DRC_TEST_PROVIDER( std::move( aMarkerHandler ) ),
m_units( EDA_UNITS::MILLIMETRES ),
m_board( nullptr ),
m_zone( nullptr ),
m_keepoutFlags( 0 )
{
}
bool DRC_KEEPOUT_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard )
{
bool success = true;
m_units = aUnits;
m_board = &aBoard;
// Get a list of all zones to inspect, from both board and footprints
std::list<ZONE_CONTAINER*> areasToInspect = m_board->GetZoneList( true );
// Test keepout areas for vias, tracks and pads inside keepout areas
for( ZONE_CONTAINER* area : areasToInspect )
{
m_keepoutFlags = area->GetKeepouts( &m_sources );
if( m_keepoutFlags > 0 )
{
m_zone = area;
m_zoneBBox = area->GetBoundingBox();
success &= checkTracksAndVias();
success &= checkFootprints();
success &= checkDrawings();
}
}
return success;
}
bool DRC_KEEPOUT_TESTER::checkTracksAndVias()
{
constexpr int VIA_MASK = DISALLOW_VIAS | DISALLOW_MICRO_VIAS | DISALLOW_BB_VIAS;
constexpr int CHECK_VIAS_MASK = VIA_MASK | DISALLOW_HOLES;
constexpr int CHECK_TRACKS_AND_VIAS_MASK = CHECK_VIAS_MASK | DISALLOW_TRACKS;
if(( m_keepoutFlags & CHECK_TRACKS_AND_VIAS_MASK ) == 0 )
return true;
bool success = true;
for( TRACK* segm : m_board->Tracks() )
{
if( !m_zoneBBox.Intersects( segm->GetBoundingBox() ) )
continue;
if( segm->Type() == PCB_TRACE_T && ( m_keepoutFlags & DISALLOW_TRACKS ) != 0 )
{
// Ignore if the keepout zone is not on the same layer
if( !m_zone->IsOnLayer( segm->GetLayer() ) )
continue;
int widths = segm->GetWidth() / 2;
SEG trackSeg( segm->GetStart(), segm->GetEnd() );
SEG::ecoord center2center_squared = m_zone->Outline()->SquaredDistance( trackSeg );
if( center2center_squared <= SEG::Square( widths) )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_INSIDE_KEEPOUT );
m_msg.Printf( drcItem->GetErrorText() + _( " (%s)" ),
m_sources.at(DISALLOW_TRACKS ) );
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( segm, m_zone );
HandleMarker( new MARKER_PCB( drcItem, DRC::GetLocation( segm, m_zone ) ) );
success = false;
}
}
else if( segm->Type() == PCB_VIA_T && ( m_keepoutFlags & CHECK_VIAS_MASK ) != 0 )
{
VIA* via = static_cast<VIA*>( segm );
int errorCode = 0;
int sourceId = 0;
if( ( m_keepoutFlags & DISALLOW_VIAS ) > 0 )
{
errorCode = DRCE_VIA_INSIDE_KEEPOUT;
sourceId = DISALLOW_VIAS;
}
else if( via->GetViaType() == VIATYPE::MICROVIA
&& ( m_keepoutFlags & DISALLOW_MICRO_VIAS ) > 0 )
{
errorCode = DRCE_MICROVIA_INSIDE_KEEPOUT;
sourceId = DISALLOW_MICRO_VIAS;
}
else if( via->GetViaType() == VIATYPE::BLIND_BURIED
&& ( m_keepoutFlags & DISALLOW_BB_VIAS ) > 0 )
{
errorCode = DRCE_BBVIA_INSIDE_KEEPOUT;
sourceId = DISALLOW_BB_VIAS;
}
else if( ( m_keepoutFlags & DISALLOW_HOLES ) > 0 )
{
errorCode = DRCE_HOLE_INSIDE_KEEPOUT;
sourceId = DISALLOW_HOLES;
}
else
continue;
int widths = via->GetWidth() / 2;
wxPoint viaPos = via->GetPosition();
if( errorCode == DRCE_HOLE_INSIDE_KEEPOUT )
widths = via->GetDrillValue() / 2;
SEG::ecoord center2center_squared = m_zone->Outline()->SquaredDistance( viaPos );
if( center2center_squared <= SEG::Square( widths ) )
{
DRC_ITEM* drcItem = new DRC_ITEM( errorCode );
m_msg.Printf( drcItem->GetErrorText() + _( " (%s)" ), m_sources.at( sourceId ) );
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( segm, m_zone );
HandleMarker( new MARKER_PCB( drcItem, DRC::GetLocation( segm, m_zone ) ) );
success = false;
}
}
}
return success;
}
bool DRC_KEEPOUT_TESTER::checkFootprints()
{
constexpr int CHECK_PADS_MASK = DISALLOW_PADS | DISALLOW_HOLES;
constexpr int CHECK_FOOTPRINTS_MASK = CHECK_PADS_MASK | DISALLOW_FOOTPRINTS;
if(( m_keepoutFlags & CHECK_FOOTPRINTS_MASK ) == 0 )
return true;
bool success = true;
for( MODULE* fp : m_board->Modules() )
{
if( !m_zoneBBox.Intersects( fp->GetBoundingBox() ) )
continue;
if( ( m_keepoutFlags & DISALLOW_FOOTPRINTS ) > 0
&& ( fp->IsFlipped() ? m_zone->CommonLayerExists( LSET::BackMask() )
: m_zone->CommonLayerExists( LSET::FrontMask() ) ) )
{
SHAPE_POLY_SET poly;
if( fp->BuildPolyCourtyard() )
poly = fp->IsFlipped() ? fp->GetPolyCourtyardBack() : fp->GetPolyCourtyardFront();
if( poly.OutlineCount() == 0 )
poly = fp->GetBoundingPoly();
// Build the common area between footprint and the keepout area:
poly.BooleanIntersection( *m_zone->Outline(), SHAPE_POLY_SET::PM_FAST );
// If it's not empty then we have a violation
if( poly.OutlineCount() )
{
const VECTOR2I& pt = poly.CVertex( 0, 0, -1 );
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_FOOTPRINT_INSIDE_KEEPOUT );
m_msg.Printf( drcItem->GetErrorText() + _( " (%s)" ),
m_sources.at( DISALLOW_FOOTPRINTS ) );
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( fp, m_zone );
HandleMarker( new MARKER_PCB( drcItem, (wxPoint) pt ) );
success = false;
}
}
if( ( m_keepoutFlags & CHECK_PADS_MASK ) > 0 )
{
success &= checkPads( fp );
}
}
return success;
}
bool DRC_KEEPOUT_TESTER::checkPads( MODULE* aModule )
{
bool success = true;
for( D_PAD* pad : aModule->Pads() )
{
if( !m_zone->CommonLayerExists( pad->GetLayerSet() ) )
continue;
// Fast test to detect a pad inside the keepout area bounding box.
EDA_RECT padBBox( pad->ShapePos(), wxSize() );
padBBox.Inflate( pad->GetBoundingRadius() );
if( !m_zoneBBox.Intersects( padBBox ) )
continue;
if( ( m_keepoutFlags & DISALLOW_PADS ) > 0 )
{
SHAPE_POLY_SET outline;
pad->TransformShapeWithClearanceToPolygon( outline, 0 );
// Build the common area between pad and the keepout area:
outline.BooleanIntersection( *m_zone->Outline(), SHAPE_POLY_SET::PM_FAST );
// If it's not empty then we have a violation
if( outline.OutlineCount() )
{
const VECTOR2I& pt = outline.CVertex( 0, 0, -1 );
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_PAD_INSIDE_KEEPOUT );
m_msg.Printf( drcItem->GetErrorText() + _( " (%s)" ),
m_sources.at( DISALLOW_PADS ) );
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( pad, m_zone );
HandleMarker( new MARKER_PCB( drcItem, (wxPoint) pt ) );
success = false;
}
}
else if( ( m_keepoutFlags & DISALLOW_HOLES ) > 0 )
{
wxPoint slotStart, slotEnd;
int slotWidth;
pad->GetOblongGeometry( pad->GetDrillSize(), &slotStart, &slotEnd, &slotWidth );
slotStart += pad->GetPosition();
slotEnd += pad->GetPosition();
SEG slotSeg( slotStart, slotEnd );
SHAPE_POLY_SET* outline = const_cast<SHAPE_POLY_SET*>( &m_zone->GetFilledPolysList() );
SEG::ecoord center2center_sq = outline->SquaredDistance( slotSeg );
if( center2center_sq <= SEG::Square( slotWidth) )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_HOLE_INSIDE_KEEPOUT );
m_msg.Printf( drcItem->GetErrorText() + _( " (%s)" ),
m_sources.at( DISALLOW_HOLES ) );
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( pad, m_zone );
HandleMarker( new MARKER_PCB( drcItem, pad->GetPosition() ) );
success = false;
}
}
}
return success;
}
bool DRC_KEEPOUT_TESTER::checkDrawings()
{
constexpr int CHECK_DRAWINGS_MASK = DISALLOW_TEXTS | DISALLOW_GRAPHICS;
constexpr KICAD_T graphicTypes[] = { PCB_LINE_T, PCB_DIMENSION_T, PCB_TARGET_T, EOT };
if(( m_keepoutFlags & CHECK_DRAWINGS_MASK ) == 0 )
return true;
bool success = true;
for( BOARD_ITEM* drawing : m_board->Drawings() )
{
if( !m_zoneBBox.Intersects( drawing->GetBoundingBox() ) )
continue;
int errorCode = 0;
int sourceId = 0;
if( drawing->IsType( graphicTypes ) && ( m_keepoutFlags & DISALLOW_GRAPHICS ) > 0 )
{
errorCode = DRCE_GRAPHICS_INSIDE_KEEPOUT;
sourceId = DISALLOW_GRAPHICS;
}
else if( drawing->Type() == PCB_TEXT_T && ( m_keepoutFlags & DISALLOW_TEXTS ) > 0 )
{
errorCode = DRCE_TEXT_INSIDE_KEEPOUT;
sourceId = DISALLOW_TEXTS;
}
else
continue;
SHAPE_POLY_SET poly;
drawing->TransformShapeWithClearanceToPolygon( poly, 0 );
// Build the common area between footprint and the keepout area:
poly.BooleanIntersection( *m_zone->Outline(), SHAPE_POLY_SET::PM_FAST );
// If it's not empty then we have a violation
if( poly.OutlineCount() )
{
const VECTOR2I& pt = poly.CVertex( 0, 0, -1 );
DRC_ITEM* drcItem = new DRC_ITEM( errorCode );
m_msg.Printf( drcItem->GetErrorText() + _( " (%s)" ), m_sources.at( sourceId ) );
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( drawing, m_zone );
HandleMarker( new MARKER_PCB( drcItem, (wxPoint) pt ) );
success = false;
}
}
return success;
}

View File

@ -1,61 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef DRC_KEEPOUT_TESTER__H
#define DRC_KEEPOUT_TESTER__H
#include <drc/drc_provider.h>
class BOARD;
class DRC_KEEPOUT_TESTER : public DRC_TEST_PROVIDER
{
public:
DRC_KEEPOUT_TESTER( MARKER_HANDLER aMarkerHandler );
virtual ~DRC_KEEPOUT_TESTER() {};
bool RunDRC( EDA_UNITS aUnits, BOARD& aBoard ) override;
private:
bool checkTracksAndVias();
bool checkFootprints();
bool checkPads( MODULE* aModule );
bool checkDrawings();
private:
EDA_UNITS m_units;
BOARD* m_board;
// Temp variables for use while testing:
ZONE_CONTAINER* m_zone;
EDA_RECT m_zoneBBox;
int m_keepoutFlags; // bitset of DISALLOW_* flags
std::map<int, wxString> m_sources; // map of DISALLOW_* flag to source
wxString m_msg; // avoid lots of calls to wxString's c'tor.
};
#endif // DRC_KEEPOUT_TESTER__H

View File

@ -1,115 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2009-2018 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
* Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file class_marker_pcb.h
* @brief Markers used to show a drc problem on boards.
*/
#ifndef CLASS_MARKER_PCB_H
#define CLASS_MARKER_PCB_H
#include <class_board_item.h>
#include <marker_base.h>
class DRC_ITEM;
// Coordinates count for the basic shape marker
#define MARKER_SHAPE_POINT_COUNT 9
class MSG_PANEL_ITEM;
class MARKER_PCB : public BOARD_ITEM, public MARKER_BASE
{
public:
MARKER_PCB( DRC_ITEM* aItem, const wxPoint& aPosition );
~MARKER_PCB();
static inline bool ClassOf( const EDA_ITEM* aItem )
{
return aItem && PCB_MARKER_T == aItem->Type();
}
const KIID GetUUID() const override { return m_Uuid; }
wxString Serialize() const;
static MARKER_PCB* Deserialize( const wxString& data );
void Move(const wxPoint& aMoveVector) override
{
m_Pos += aMoveVector;
}
void Rotate( const wxPoint& aRotCentre, double aAngle ) override;
void Flip( const wxPoint& aCentre, bool aFlipLeftRight ) override;
wxPoint GetPosition() const override { return m_Pos; }
void SetPosition( const wxPoint& aPos ) override { m_Pos = aPos; }
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override
{
return HitTestMarker( aPosition, aAccuracy );
}
GAL_LAYER_ID GetColorLayer() const;
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
bool Matches( wxFindReplaceData& aSearchData, void* aAuxData ) override
{
return BOARD_ITEM::Matches( m_rcItem->GetErrorMessage(), aSearchData );
}
wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
BITMAP_DEF GetMenuImage() const override;
const BOX2I ViewBBox() const override;
const EDA_RECT GetBoundingBox() const override;
void ViewGetLayers( int aLayers[], int& aCount ) const override;
#if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
#endif
/** Get class name
* @return string "MARKER_PCB"
*/
virtual wxString GetClass() const override
{
return wxT( "MARKER_PCB" );
}
protected:
KIGFX::COLOR4D getColor() const override;
};
#endif // CLASS_MARKER_PCB_H

View File

@ -1,162 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <drc/drc_netclass_tester.h>
DRC_NETCLASS_TESTER::DRC_NETCLASS_TESTER( MARKER_HANDLER aMarkerHandler ) :
DRC_TEST_PROVIDER( std::move( aMarkerHandler ) ),
m_units( EDA_UNITS::MILLIMETRES ),
m_board( nullptr )
{
}
bool DRC_NETCLASS_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard )
{
m_units = aUnits;
m_board = &aBoard;
bool success = true;
NETCLASSES& netclasses = m_board->GetDesignSettings().m_NetClasses;
success &= checkNetClass( netclasses.GetDefault() );
for( NETCLASSES::const_iterator i = netclasses.begin(); i != netclasses.end(); ++i )
success &= checkNetClass( i->second );
return success;
}
bool DRC_NETCLASS_TESTER::checkNetClass( const NETCLASSPTR& nc )
{
bool ret = true;
const BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
if( nc->GetClearance() < bds.m_MinClearance )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_NETCLASS_CLEARANCE );
m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; %s netclass %s)" ),
MessageTextFromValue( m_units, bds.m_MinClearance, true ),
nc->GetName(),
MessageTextFromValue( m_units, nc->GetClearance(), true ) );
drcItem->SetErrorMessage( m_msg );
HandleMarker( new MARKER_PCB( drcItem, wxPoint() ) );
ret = false;
}
if( nc->GetTrackWidth() < bds.m_TrackMinWidth )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_NETCLASS_TRACKWIDTH );
m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; %s netclass %s)" ),
MessageTextFromValue( m_units, bds.m_TrackMinWidth, true ),
nc->GetName(),
MessageTextFromValue( m_units, nc->GetTrackWidth(), true ) );
drcItem->SetErrorMessage( m_msg );
HandleMarker( new MARKER_PCB( drcItem, wxPoint() ) );
ret = false;
}
if( nc->GetViaDiameter() < bds.m_ViasMinSize )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_NETCLASS_VIASIZE );
m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; %s netclass %s)" ),
MessageTextFromValue( m_units, bds.m_ViasMinSize, true ),
nc->GetName(),
MessageTextFromValue( m_units, nc->GetViaDiameter(), true ) );
drcItem->SetErrorMessage( m_msg );
HandleMarker( new MARKER_PCB( drcItem, wxPoint() ) );
ret = false;
}
if( nc->GetViaDrill() < bds.m_MinThroughDrill )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_NETCLASS_VIADRILLSIZE );
m_msg.Printf( drcItem->GetErrorText() + _( " (board min through hole %s; %s netclass %s)" ),
MessageTextFromValue( m_units, bds.m_MinThroughDrill, true ),
nc->GetName(),
MessageTextFromValue( m_units, nc->GetViaDrill(), true ) );
drcItem->SetErrorMessage( m_msg );
HandleMarker( new MARKER_PCB( drcItem, wxPoint() ) );
ret = false;
}
int ncViaAnnulus = ( nc->GetViaDiameter() - nc->GetViaDrill() ) / 2;
if( ncViaAnnulus < bds.m_ViasMinAnnulus )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_NETCLASS_VIAANNULUS );
m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; %s netclass %s)" ),
MessageTextFromValue( m_units, bds.m_ViasMinAnnulus, true ),
nc->GetName(),
MessageTextFromValue( m_units, ncViaAnnulus, true ) );
drcItem->SetErrorMessage( m_msg );
HandleMarker( new MARKER_PCB( drcItem, wxPoint() ) );
ret = false;
}
if( nc->GetuViaDiameter() < bds.m_MicroViasMinSize )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_NETCLASS_uVIASIZE );
m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; %s netclass %s)" ),
MessageTextFromValue( m_units, bds.m_MicroViasMinSize, true ),
nc->GetName(),
MessageTextFromValue( m_units, nc->GetuViaDiameter(), true ) );
drcItem->SetErrorMessage( m_msg );
HandleMarker( new MARKER_PCB( drcItem, wxPoint() ) );
ret = false;
}
if( nc->GetuViaDrill() < bds.m_MicroViasMinDrill )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_NETCLASS_uVIADRILLSIZE );
m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; %s netclass %s)" ),
MessageTextFromValue( m_units, bds.m_MicroViasMinDrill, true ),
nc->GetName(),
MessageTextFromValue( m_units, nc->GetuViaDrill(), true ) );
drcItem->SetErrorMessage( m_msg );
HandleMarker( new MARKER_PCB( drcItem, wxPoint() ) );
ret = false;
}
return ret;
}

View File

@ -1,54 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef DRC_NETCLASS_TESTER__H
#define DRC_NETCLASS_TESTER__H
#include <drc/drc_provider.h>
class BOARD;
class BOARD_ITEM;
class DRC_NETCLASS_TESTER : public DRC_TEST_PROVIDER
{
public:
DRC_NETCLASS_TESTER( MARKER_HANDLER aMarkerHandler );
virtual ~DRC_NETCLASS_TESTER() {};
bool RunDRC( EDA_UNITS aUnits, BOARD& aBoard ) override;
private:
bool checkNetClass( const NETCLASSPTR& nc );
private:
EDA_UNITS m_units;
BOARD* m_board;
wxString m_msg; // Construct only once for performance
};
#endif // DRC_NETCLASS_TESTER__H

View File

@ -29,8 +29,8 @@
#include <wx/cmdline.h>
#include <pcbnew_utils/board_file_utils.h>
#include <drc_proto/drc_engine.h>
#include <pcbnew/drc/drc_engine.h>
#include <pcbnew/drc/drc_rule_parser.h>
#include <reporter.h>
#include <widgets/progress_reporter.h>
@ -184,6 +184,51 @@ PROJECT_CONTEXT loadKicadProject( wxString filename )
}
class TEST_DRC_ENGINE : public DRC_ENGINE
{
public:
TEST_DRC_ENGINE( BOARD* aBoard, BOARD_DESIGN_SETTINGS* aSettings ) :
DRC_ENGINE( aBoard, aSettings )
{ }
bool LoadRules( wxFileName aPath )
{
if( aPath.FileExists() )
{
m_ruleConditions.clear();
m_rules.clear();
FILE* fp = wxFopen( aPath.GetFullPath(), wxT( "rt" ) );
if( fp )
{
try
{
DRC_RULES_PARSER parser( m_board, fp, aPath.GetFullPath() );
parser.Parse( m_rules, nullptr );
}
catch( PARSE_ERROR& pe )
{
// Don't leave possibly malformed stuff around for us to trip over
m_ruleConditions.clear();
m_rules.clear();
//wxSafeYield( m_editFrame );
//m_editFrame->ShowBoardSetupDialog( _( "Rules" ), pe.What(), ID_RULES_EDITOR,
// pe.lineNumber, pe.byteIndex );
throw;
return false;
}
}
}
return true;
}
};
int main( int argc, char *argv[] )
{
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
@ -200,7 +245,7 @@ int main( int argc, char *argv[] )
test::DRC_ENGINE drcEngine( project.board.get(), &project.board->GetDesignSettings() );
TEST_DRC_ENGINE drcEngine( project.board.get(), &project.board->GetDesignSettings() );
CONSOLE_LOG consoleLog;

View File

@ -1,466 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <fctsys.h>
#include <class_board.h>
#include <class_board_item.h>
#include <drc_proto/drc_rule.h>
#include <drc_proto/drc_rule_parser.h>
#include <drc_rules_lexer.h>
#include <drc_proto/drc_engine.h> // drc_dbg
#include <pcb_expr_evaluator.h>
#include <reporter.h>
using namespace DRCRULE_T;
test::DRC_RULES_PARSER::DRC_RULES_PARSER( BOARD* aBoard, const wxString& aSource,
const wxString& aSourceDescr ) :
DRC_RULES_LEXER( aSource.ToStdString(), aSourceDescr ),
m_board( aBoard ),
m_requiredVersion( 0 ),
m_tooRecent( false ),
m_reporter( nullptr )
{
}
test::DRC_RULES_PARSER::DRC_RULES_PARSER( BOARD* aBoard, FILE* aFile, const wxString& aFilename ) :
DRC_RULES_LEXER( aFile, aFilename ),
m_board( aBoard ),
m_requiredVersion( 0 ),
m_tooRecent( false ),
m_reporter( nullptr )
{
}
void test::DRC_RULES_PARSER::reportError( const wxString& aMessage )
{
wxString rest;
wxString first = aMessage.BeforeFirst( '|', &rest );
wxString msg = wxString::Format( _( "ERROR: <a href='%d:%d'>%s</a>%s" ),
CurLineNumber(),
CurOffset(),
first,
rest );
m_reporter->Report( msg, RPT_SEVERITY_ERROR );
}
void test::DRC_RULES_PARSER::parseUnknown()
{
int depth = 1;
for( T token = NextTok(); token != T_EOF; token = NextTok() )
{
if( token == T_LEFT )
depth++;
if( token == T_RIGHT )
{
if( --depth == 0 )
break;
}
}
}
void test::DRC_RULES_PARSER::Parse( std::vector<DRC_RULE*>& aRules, REPORTER* aReporter )
{
bool haveVersion = false;
wxString msg;
m_reporter = aReporter;
for( T token = NextTok(); token != T_EOF; token = NextTok() )
{
if( token != T_LEFT )
reportError( _( "Missing '('." ) );
token = NextTok();
if( !haveVersion && token != T_version )
{
reportError( _( "Missing version statement." ) );
haveVersion = true; // don't keep on reporting it
}
switch( token )
{
case T_version:
haveVersion = true;
token = NextTok();
if( (int) token == DSN_RIGHT )
{
reportError( _( "Missing version number." ) );
break;
}
if( (int) token == DSN_NUMBER )
{
m_requiredVersion = (int)strtol( CurText(), NULL, 10 );
m_tooRecent = ( m_requiredVersion > DRC_RULE_FILE_VERSION );
token = NextTok();
}
else
{
msg.Printf( _( "Unrecognized item '%s'.| Expected version number" ), FromUTF8() );
reportError( msg );
}
if( (int) token != DSN_RIGHT )
{
msg.Printf( _( "Unrecognized item '%s'." ), FromUTF8() );
reportError( msg );
parseUnknown();
}
break;
case T_rule:
aRules.push_back( parseDRC_RULE() );
break;
default:
msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ),
FromUTF8(), "'rule', 'version'" );
reportError( msg );
parseUnknown();
}
}
if( !m_reporter->HasMessage() )
m_reporter->Report( _( "No errors found." ), RPT_SEVERITY_INFO );
m_reporter = nullptr;
}
test::DRC_RULE* test::DRC_RULES_PARSER::parseDRC_RULE()
{
DRC_RULE* rule = new DRC_RULE();
T token = NextTok();
wxString msg;
if( !IsSymbol( token ) )
reportError( _( "Missing rule name." ) );
rule->SetName( FromUTF8() );
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token != T_LEFT )
reportError( _( "Missing '('." ) );
token = NextTok();
switch( token )
{
case T_constraint:
parseConstraint( rule );
break;
case T_condition:
token = NextTok();
if( (int) token == DSN_RIGHT )
{
reportError( _( "Missing condition expression." ) );
break;
}
if( IsSymbol( token ) )
{
auto condition = new DRC_RULE_CONDITION;
condition->SetExpression( FromUTF8() );
rule->SetCondition( condition );
}
else
{
msg.Printf( _( "Unrecognized item '%s'.| Expected quoted expression." ),
FromUTF8() );
reportError( msg );
}
if( (int) NextTok() != DSN_RIGHT )
{
reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) );
parseUnknown();
}
break;
case T_layer:
rule->SetLayerCondition( parseLayer() );
break;
default:
msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ),
FromUTF8(),
"'constraint', 'condition', 'disallow'" );
reportError( msg );
parseUnknown();
}
}
return rule;
}
void test::DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
{
DRC_CONSTRAINT constraint;
int value;
wxString msg;
T token = NextTok();
if( (int) token == DSN_RIGHT )
{
msg.Printf( _( "Missing constraint type.| Expected %s." ),
"'clearance', 'track_width', 'annulus_width', 'hole', 'disallow'" );
reportError( msg );
return;
}
switch( token )
{
case T_clearance: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_CLEARANCE; break;
case T_hole_clearance: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE; break;
case T_edge_clearance: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE; break;
case T_hole: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_HOLE_SIZE; break;
case T_courtyard_clearance: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE; break;
case T_silk_to_pad: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_SILK_TO_PAD; break;
case T_silk_to_silk: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_SILK_TO_SILK; break;
case T_track_width: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_TRACK_WIDTH; break;
case T_annulus_width: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH; break;
case T_disallow: constraint.m_Type = test::DRC_CONSTRAINT_TYPE_DISALLOW; break;
default:
msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ),
FromUTF8(),
"'clearance', 'track_width', 'annulus_width', 'hole', 'disallow'."
);
reportError( msg );
}
if( constraint.m_Type == DRC_CONSTRAINT_TYPE_DISALLOW )
{
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( (int) token == DSN_STRING )
token = GetCurStrAsToken();
switch( token )
{
case T_track: constraint.m_DisallowFlags |= DISALLOW_TRACKS; break;
case T_via: constraint.m_DisallowFlags |= DISALLOW_VIAS; break;
case T_micro_via: constraint.m_DisallowFlags |= DISALLOW_MICRO_VIAS; break;
case T_buried_via: constraint.m_DisallowFlags |= DISALLOW_BB_VIAS; break;
case T_pad: constraint.m_DisallowFlags |= DISALLOW_PADS; break;
case T_zone: constraint.m_DisallowFlags |= DISALLOW_ZONES; break;
case T_text: constraint.m_DisallowFlags |= DISALLOW_TEXTS; break;
case T_graphic: constraint.m_DisallowFlags |= DISALLOW_GRAPHICS; break;
case T_hole: constraint.m_DisallowFlags |= DISALLOW_HOLES; break;
case T_footprint: constraint.m_DisallowFlags |= DISALLOW_FOOTPRINTS; break;
default:
msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ),
FromUTF8(),
"'track', 'via', 'micro_via', "
"'blind_via', 'pad', 'zone', 'text', 'graphic', 'hole'."
);
reportError( msg );
parseUnknown();
}
}
return;
}
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token != T_LEFT )
reportError( _( "Missing '('." ) );
token = NextTok();
switch( token )
{
case T_min:
token = NextTok();
if( (int) token == DSN_RIGHT )
{
reportError( _( "Missing min value." ) );
break;
}
parseValueWithUnits( FromUTF8(), value );
constraint.Value().SetMin( value );
if( (int) NextTok() != DSN_RIGHT )
{
reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) );
parseUnknown();
}
break;
case T_max:
token = NextTok();
if( (int) token == DSN_RIGHT )
{
reportError( _( "Missing max value." ) );
break;
}
parseValueWithUnits( FromUTF8(), value );
constraint.Value().SetMax( value );
if( (int) NextTok() != DSN_RIGHT )
{
reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) );
parseUnknown();
}
break;
case T_opt:
token = NextTok();
if( (int) token == DSN_RIGHT )
{
reportError( _( "Missing opt value." ) );
break;
}
parseValueWithUnits( FromUTF8(), value );
constraint.Value().SetOpt( value );
if( (int) NextTok() != DSN_RIGHT )
{
reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) );
parseUnknown();
}
break;
/* fixme: bring these back?
case T_enable:
rule->m_Enabled = parseInt("enabled");
NeedRIGHT();
break;
case T_severity:
token = NextTok();
switch( token )
{
case T_error:
case T_warning:
case T_ignore: break; // fixme
default:
Expecting( "error, warning or ignore" );
break;
}
NeedRIGHT();
break;
*/
default:
msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ),
FromUTF8(), "'min', 'max', 'opt'" );
reportError( msg );
parseUnknown();
}
}
aRule->AddConstraint( constraint );
}
void test::DRC_RULES_PARSER::parseValueWithUnits( const wxString& aExpr, int& aResult )
{
PCB_EXPR_EVALUATOR evaluator;
evaluator.Evaluate( aExpr );
if( evaluator.IsErrorPending() )
{
auto err = evaluator.GetError();
wxString str;
str.Printf( "Error: %s (line %d, offset %d)", err.message, CurLineNumber(), err.srcPos + CurOffset() );
m_reporter->Report( str, RPT_SEVERITY_ERROR );
return;
}
aResult = evaluator.Result();
};
LSET test::DRC_RULES_PARSER::parseLayer()
{
LSET retVal;
int token = NextTok();
if( (int) token == DSN_RIGHT )
{
reportError( _( "Missing layer name or type." ) );
return LSET::AllCuMask();
}
else if( token == T_outer )
{
retVal = LSET::ExternalCuMask();
}
else if( token == T_inner )
{
retVal = LSET::InternalCuMask();
}
else
{
wxString layerName = FromUTF8();
PCB_LAYER_ID layer = ENUM_MAP<PCB_LAYER_ID>::Instance().ToEnum( layerName );
if( layer == UNDEFINED_LAYER )
reportError( wxString::Format( _( "Unrecognized layer '%s' " ), layerName ) );
retVal.set( layer );
}
if( (int) NextTok() != DSN_RIGHT )
{
reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) );
parseUnknown();
}
return retVal;
}

View File

@ -1,71 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef DRC_RULE_PARSER_H
#define DRC_RULE_PARSER_H
#include <core/typeinfo.h>
#include <netclass.h>
#include <layers_id_colors_and_visibility.h>
#include <drc_proto/drc_rule.h>
#include <drc_rules_lexer.h>
class BOARD_ITEM;
namespace test {
class DRC_RULE_CONDITION;
class DRC_RULE;
#define DRC_RULE_FILE_VERSION 20200610
class DRC_RULES_PARSER : public DRC_RULES_LEXER
{
public:
DRC_RULES_PARSER( BOARD* aBoard, const wxString& aSource, const wxString& aSourceDescr );
DRC_RULES_PARSER( BOARD* aBoard, FILE* aFile, const wxString& aFilename );
void Parse( std::vector<DRC_RULE*>& aRules, REPORTER* aReporter );
private:
DRC_RULE* parseDRC_RULE();
void parseConstraint( DRC_RULE* aRule );
void parseValueWithUnits( const wxString& aExpr, int& aResult );
LSET parseLayer();
void parseUnknown();
void reportError( const wxString& aMessage );
private:
BOARD* m_board;
int m_requiredVersion;
bool m_tooRecent;
REPORTER* m_reporter;
};
};
#endif // DRC_RULE_PARSER_H

View File

@ -27,10 +27,11 @@
#include <common.h>
#include <drc_proto/drc_engine.h>
#include <drc_proto/drc_item.h>
#include <drc_proto/drc_rule.h>
#include <drc_proto/drc_test_provider.h>
#include <drc/drc_engine.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc_test_provider.h>
/*
@ -69,7 +70,7 @@ public:
return "Tests pad/via annular rings";
}
virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
};
}; // namespace test
@ -77,8 +78,7 @@ public:
bool test::DRC_TEST_PROVIDER_ANNULUS::Run()
{
if( !m_drcEngine->HasCorrectRulesForId(
test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH ) )
if( !m_drcEngine->HasCorrectRulesForId( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH ) )
{
ReportAux( "No annulus constraints found. Skipping check." );
return false;
@ -96,8 +96,7 @@ bool test::DRC_TEST_PROVIDER_ANNULUS::Run()
if( !via )
return true;
test::DRC_CONSTRAINT constraint = m_drcEngine->EvalRulesForItems(
test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH, via );
DRC_CONSTRAINT constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH, via );
accountCheck( constraint );
@ -121,7 +120,7 @@ bool test::DRC_TEST_PROVIDER_ANNULUS::Run()
wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (%s; actual annulus %s, constraint %s %s)" ),
constraint.GetParentRule()->GetName(),
constraint.GetParentRule()->m_Name,
MessageTextFromValue( userUnits(), annulus, true ),
fail_min ? _( "minimum" ) : _( "maximum" ),
MessageTextFromValue( userUnits(), fail_min ? v_min : v_max, true ) );
@ -148,8 +147,7 @@ bool test::DRC_TEST_PROVIDER_ANNULUS::Run()
}
std::set<test::DRC_CONSTRAINT_TYPE_T>
test::DRC_TEST_PROVIDER_ANNULUS::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_ANNULUS::GetMatchingConstraintIds() const
{
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH };
}
@ -157,5 +155,5 @@ test::DRC_TEST_PROVIDER_ANNULUS::GetMatchingConstraintIds() const
namespace detail
{
static test::DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_ANNULUS> dummy;
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_ANNULUS> dummy;
}

View File

@ -29,15 +29,15 @@
#include <convert_basic_shapes_to_polygon.h>
#include <geometry/polygon_test_point_inside.h>
#include <geometry/seg.h>
#include <geometry/shape_poly_set.h>
#include <geometry/shape_rect.h>
#include <drc_proto/drc_engine.h>
#include <drc/drc_engine.h>
#include <drc_proto/drc_test_provider_clearance_base.h>
#include <drc_proto/drc_item.h>
#include <drc_proto/drc_rule.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
const int UI_EPSILON = Mils2iu( 5 );

View File

@ -29,7 +29,7 @@
#include <class_board.h>
#include <drc_proto/drc_test_provider.h>
#include <pcbnew/drc/drc_test_provider.h>
namespace test {
@ -37,10 +37,10 @@ class DRC_TEST_PROVIDER_CLEARANCE_BASE : public DRC_TEST_PROVIDER
{
public:
DRC_TEST_PROVIDER_CLEARANCE_BASE () :
DRC_TEST_PROVIDER(),
m_board( nullptr ),
m_largestClearance( 0 ),
m_boardOutlineValid( false )
DRC_TEST_PROVIDER(),
m_board( nullptr ),
m_largestClearance( 0 ),
m_boardOutlineValid( false )
{
}

View File

@ -27,10 +27,11 @@
#include <connectivity/connectivity_data.h>
#include <connectivity/connectivity_algo.h>
#include <drc_proto/drc_engine.h>
#include <drc_proto/drc_item.h>
#include <drc_proto/drc_rule.h>
#include <drc_proto/drc_test_provider.h>
#include <drc/drc_engine.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc_test_provider.h>
/*
@ -67,7 +68,7 @@ public:
return "Tests board connectivity";
}
virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
};
}; // namespace test
@ -164,8 +165,7 @@ bool test::DRC_TEST_PROVIDER_CONNECTIVITY::Run()
}
std::set<test::DRC_CONSTRAINT_TYPE_T>
test::DRC_TEST_PROVIDER_CONNECTIVITY::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_CONNECTIVITY::GetMatchingConstraintIds() const
{
return {};
}
@ -173,5 +173,5 @@ test::DRC_TEST_PROVIDER_CONNECTIVITY::GetMatchingConstraintIds() const
namespace detail
{
static test::DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_CONNECTIVITY> dummy;
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_CONNECTIVITY> dummy;
}

View File

@ -26,18 +26,17 @@
#include <class_drawsegment.h>
#include <class_pad.h>
#include <convert_basic_shapes_to_polygon.h>
#include <geometry/polygon_test_point_inside.h>
#include <geometry/seg.h>
#include <geometry/shape_poly_set.h>
#include <geometry/shape_rect.h>
#include <geometry/shape_segment.h>
#include <drc_proto/drc_engine.h>
#include <drc_proto/drc_item.h>
#include <pcbnew/drc/drc_engine.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <drc_proto/drc_rtree.h>
#include <drc_proto/drc_rule.h>
#include <drc/drc_rule.h>
#include <drc_proto/drc_test_provider_clearance_base.h>
/*
@ -77,7 +76,7 @@ public:
return "Tests copper item clearance";
}
virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
private:
void testPadClearances();
@ -99,7 +98,8 @@ bool test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::Run()
m_board = m_drcEngine->GetBoard();
DRC_CONSTRAINT worstClearanceConstraint;
if( m_drcEngine->QueryWorstConstraint( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, worstClearanceConstraint, DRCCQ_LARGEST_MINIMUM ) )
if( m_drcEngine->QueryWorstConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE,
worstClearanceConstraint, DRCCQ_LARGEST_MINIMUM ) )
{
m_largestClearance = worstClearanceConstraint.GetValue().Min();
}
@ -199,7 +199,8 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testCopperDrawItem( BOARD_ITEM* a
if( !track->IsOnLayer( aItem->GetLayer() ) )
continue;
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, aItem, track, aItem->GetLayer() );
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE,
aItem, track, aItem->GetLayer() );
auto minClearance = constraint.GetValue().Min();
int actual = INT_MAX;
wxPoint pos;
@ -224,7 +225,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testCopperDrawItem( BOARD_ITEM* a
wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
constraint.GetParentRule()->GetName(),
constraint.GetParentRule()->m_Name,
MessageTextFromValue( userUnits(), minClearance, true ),
MessageTextFromValue( userUnits(), actual, true ) );
@ -246,7 +247,8 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testCopperDrawItem( BOARD_ITEM* a
if( drawItem && pad->GetParent() == drawItem->GetParent() )
continue;
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, aItem, pad );
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE,
aItem, pad );
auto minClearance = constraint.GetValue().Min();
accountCheck( constraint );
@ -270,7 +272,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testCopperDrawItem( BOARD_ITEM* a
wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
constraint.GetParentRule()->GetName(),
constraint.GetParentRule()->m_Name,
MessageTextFromValue( userUnits(), minClearance, true ),
MessageTextFromValue( userUnits(), actual, true ) );
@ -358,7 +360,8 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACK
// fixme: hole to hole clearance moved elsewhere
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, aRefSeg, pad );
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE,
aRefSeg, pad );
auto minClearance = constraint.GetValue().Min();
int clearanceAllowed = minClearance - bds.GetDRCEpsilon();
int actual;
@ -432,7 +435,8 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACK
if( !trackBB.Intersects( refSegBB ) )
continue;
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, aRefSeg, track );
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE,
aRefSeg, track );
auto minClearance = constraint.GetValue().Min();
accountCheck( constraint );
@ -500,7 +504,8 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACK
// fixme: per-layer onLayer() property
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, aRefSeg, zone );
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE,
aRefSeg, zone );
auto minClearance = constraint.GetValue().Min();
int widths = refSegWidth / 2;
@ -521,7 +526,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACK
wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
constraint.GetParentRule()->GetName(),
constraint.GetParentRule()->m_Name,
MessageTextFromValue( userUnits(), minClearance, true ),
MessageTextFromValue( userUnits(), actual, true ) );
@ -637,7 +642,8 @@ bool test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doPadToPadsDrc( D_PAD* aRefPad, D
continue;
}
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, aRefPad, pad );
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE,
aRefPad, pad );
auto minClearance = constraint.GetValue().Min();
accountCheck( constraint );
@ -721,8 +727,9 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZones()
// Examine a candidate zone: compare zoneToTest to zoneRef
// Get clearance used in zone to zone test.
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE, zoneRef, zoneToTest );
auto zone2zoneClearance = constraint.GetValue().Min();
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE,
zoneRef, zoneToTest );
int zone2zoneClearance = constraint.GetValue().Min();
accountCheck( constraint );
@ -840,7 +847,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZones()
}
std::set<test::DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::GetMatchingConstraintIds() const
{
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE };
}
@ -848,5 +855,5 @@ std::set<test::DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::
namespace detail
{
static test::DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_COPPER_CLEARANCE> dummy;
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_COPPER_CLEARANCE> dummy;
}

View File

@ -28,15 +28,15 @@
#include <convert_basic_shapes_to_polygon.h>
#include <geometry/polygon_test_point_inside.h>
#include <geometry/seg.h>
#include <geometry/shape_poly_set.h>
#include <geometry/shape_rect.h>
#include <geometry/shape_segment.h>
#include <drc_proto/drc_engine.h>
#include <drc_proto/drc_item.h>
#include <drc_proto/drc_rule.h>
#include <drc/drc_engine.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc_proto/drc_test_provider_clearance_base.h>
/*
@ -76,7 +76,7 @@ public:
return "Tests components' courtyard clearance";
}
virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
private:
@ -217,7 +217,7 @@ bool test::DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::Run()
}
std::set<test::DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::GetMatchingConstraintIds() const
{
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE };
}
@ -225,5 +225,5 @@ std::set<test::DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_COURTYARD_CLEARANC
namespace detail
{
static test::DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_COURTYARD_CLEARANCE> dummy;
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_COURTYARD_CLEARANCE> dummy;
}

View File

@ -26,10 +26,11 @@
#include <geometry/shape.h>
#include <drc_proto/drc_engine.h>
#include <drc_proto/drc_item.h>
#include <drc_proto/drc_rule.h>
#include <drc_proto/drc_test_provider.h>
#include <drc/drc_engine.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc_test_provider.h>
/*
"Disallow" test. Goes through all items, matching types/conditions drop errors.
@ -63,7 +64,7 @@ public:
return "Tests for disallowed items (e.g. keepouts)";
}
virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
private:
};
@ -73,7 +74,7 @@ private:
bool test::DRC_TEST_PROVIDER_DISALLOW::Run()
{
if( !m_drcEngine->HasCorrectRulesForId( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_DISALLOW ) )
if( !m_drcEngine->HasCorrectRulesForId( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_DISALLOW ) )
{
ReportAux( "No disallow constraints found. Skipping check." );
return false;
@ -83,29 +84,23 @@ bool test::DRC_TEST_PROVIDER_DISALLOW::Run()
auto checkItem = [&] ( BOARD_ITEM *item ) -> bool
{
test::DRC_CONSTRAINT constraint = m_drcEngine->EvalRulesForItems(
test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_DISALLOW, item );
DRC_CONSTRAINT constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_DISALLOW,
item );
if( constraint.Allowed() )
return true;
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ALLOWED_ITEMS );
wxString msg;
if( ( constraint.GetAllowedLayers() & item->GetLayerSet() ).any() )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ALLOWED_ITEMS );
wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (%s)" ), constraint.GetParentRule()->m_Name );
msg.Printf(
drcItem->GetErrorText() + _( " (%s)" ), constraint.GetParentRule()->GetName() );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( item );
drcItem->SetViolatingRule( constraint.GetParentRule() );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( item );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, item->GetPosition() );
ReportWithMarker( drcItem, item->GetPosition() );
if( isErrorLimitExceeded( DRCE_ALLOWED_ITEMS ) )
return false;
if( isErrorLimitExceeded( DRCE_ALLOWED_ITEMS ) )
return false;
}
return true;
};
@ -117,8 +112,7 @@ bool test::DRC_TEST_PROVIDER_DISALLOW::Run()
}
std::set<test::DRC_CONSTRAINT_TYPE_T>
test::DRC_TEST_PROVIDER_DISALLOW::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_DISALLOW::GetMatchingConstraintIds() const
{
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_DISALLOW };
}
@ -126,5 +120,5 @@ test::DRC_TEST_PROVIDER_DISALLOW::GetMatchingConstraintIds() const
namespace detail
{
static test::DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_DISALLOW> dummy;
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_DISALLOW> dummy;
}

View File

@ -22,21 +22,17 @@
*/
#include <common.h>
#include <class_board.h>
#include <class_drawsegment.h>
#include <class_pad.h>
#include <convert_basic_shapes_to_polygon.h>
#include <geometry/polygon_test_point_inside.h>
#include <geometry/seg.h>
#include <geometry/shape_poly_set.h>
#include <geometry/shape_rect.h>
#include <geometry/shape_segment.h>
#include <drc_proto/drc_engine.h>
#include <drc_proto/drc_item.h>
#include <drc_proto/drc_rule.h>
#include <pcbnew/drc/drc_engine.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc.h>
#include <drc_proto/drc_test_provider_clearance_base.h>
/*
@ -75,7 +71,7 @@ public:
return "Tests items vs board edge clearance";
}
virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
private:
};
@ -88,7 +84,9 @@ bool test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
m_board = m_drcEngine->GetBoard();
DRC_CONSTRAINT worstClearanceConstraint;
if( m_drcEngine->QueryWorstConstraint( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE, worstClearanceConstraint, DRCCQ_LARGEST_MINIMUM ) )
if( m_drcEngine->QueryWorstConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE,
worstClearanceConstraint, DRCCQ_LARGEST_MINIMUM ) )
{
m_largestClearance = worstClearanceConstraint.GetValue().Min();
}
@ -132,12 +130,15 @@ bool test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
for( auto boardItem : boardItems )
{
drc_dbg(10, "RefT %d %p %s %d\n", outlineItem->Type(), outlineItem, outlineItem->GetClass(), outlineItem->GetLayer() );
drc_dbg(10, "BoardT %d %p %s %d\n", boardItem->Type(), boardItem, boardItem->GetClass(), boardItem->GetLayer() );
drc_dbg( 10, "RefT %d %p %s %d\n", outlineItem->Type(), outlineItem,
outlineItem->GetClass(), outlineItem->GetLayer() );
drc_dbg( 10, "BoardT %d %p %s %d\n", boardItem->Type(), boardItem,
boardItem->GetClass(), boardItem->GetLayer() );
auto shape = boardItem->GetEffectiveShape();
test::DRC_CONSTRAINT constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE, outlineItem, boardItem );
DRC_CONSTRAINT constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE,
outlineItem, boardItem );
int minClearance = constraint.GetValue().Min();
int actual;
@ -149,7 +150,7 @@ bool test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
constraint.GetParentRule()->GetName(),
constraint.GetParentRule()->m_Name,
MessageTextFromValue( userUnits(), minClearance, true ),
MessageTextFromValue( userUnits(), actual, true ) );
@ -177,7 +178,7 @@ bool test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
}
std::set<test::DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::GetMatchingConstraintIds() const
{
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE };
}
@ -185,5 +186,5 @@ std::set<test::DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::Ge
namespace detail
{
static test::DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_EDGE_CLEARANCE> dummy;
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_EDGE_CLEARANCE> dummy;
}

View File

@ -26,17 +26,15 @@
#include <class_drawsegment.h>
#include <class_pad.h>
#include <convert_basic_shapes_to_polygon.h>
#include <geometry/polygon_test_point_inside.h>
#include <geometry/seg.h>
#include <geometry/shape_poly_set.h>
#include <geometry/shape_rect.h>
#include <geometry/shape_segment.h>
#include <drc_proto/drc_engine.h>
#include <drc_proto/drc_item.h>
#include <drc_proto/drc_rule.h>
#include <drc/drc_engine.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc.h>
#include <drc_proto/drc_test_provider_clearance_base.h>
/*
@ -75,7 +73,7 @@ public:
return "Tests clearance of holes (via/pad drills)";
}
virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
private:
void addHole( const VECTOR2I& aLocation, int aRadius, BOARD_ITEM* aOwner );
@ -112,7 +110,8 @@ bool test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::Run()
DRC_CONSTRAINT worstClearanceConstraint;
if( m_drcEngine->QueryWorstConstraint( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE, worstClearanceConstraint, DRCCQ_LARGEST_MINIMUM ) )
if( m_drcEngine->QueryWorstConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE,
worstClearanceConstraint, DRCCQ_LARGEST_MINIMUM ) )
{
m_largestClearance = worstClearanceConstraint.GetValue().Min();
}
@ -271,11 +270,13 @@ bool test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::doPadToPadHoleDrc( D_PAD* aRefPad,
{
// pad under testing has a hole, test this hole against pad reference
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE, aRefPad, pad );
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE,
aRefPad, pad );
auto minClearance = constraint.GetValue().Min();
int actual;
drc_dbg(10,"check pad %p rule '%s' cl %d\n", pad, constraint.GetParentRule()->GetName(), minClearance );
drc_dbg( 10, "check pad %p rule '%s' cl %d\n",
pad, constraint.GetParentRule()->m_Name, minClearance );
accountCheck( constraint.GetParentRule() );
@ -304,13 +305,15 @@ bool test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::doPadToPadHoleDrc( D_PAD* aRefPad,
if( aRefPad->GetDrillSize().x ) // pad reference has a hole
{
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE, aRefPad, pad );
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE,
aRefPad, pad );
auto minClearance = constraint.GetValue().Min();
int actual;
accountCheck( constraint.GetParentRule() );
drc_dbg(10,"check pad %p rule '%s' cl %d\n", aRefPad, constraint.GetParentRule()->GetName(), minClearance );
drc_dbg( 10,"check pad %p rule '%s' cl %d\n", aRefPad,
constraint.GetParentRule()->m_Name, minClearance );
auto padShape = pad->GetEffectiveShape();
if( padShape->Collide( aRefPad->GetEffectiveHoleShape(), minClearance, &actual ) )
@ -389,7 +392,8 @@ void test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::testHoles2Holes()
int actual = ( checkHole.m_location - refHole.m_location ).EuclideanNorm();
actual = std::max( 0, actual - checkHole.m_drillRadius - refHole.m_drillRadius );
DRC_CONSTRAINT constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE, refHole.m_owner, checkHole.m_owner );
DRC_CONSTRAINT constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE,
refHole.m_owner, checkHole.m_owner );
int minClearance = constraint.GetValue().Min();
accountCheck( constraint.GetParentRule() );
@ -417,7 +421,7 @@ void test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::testHoles2Holes()
}
std::set<test::DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::GetMatchingConstraintIds() const
{
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE };
}
@ -425,5 +429,5 @@ std::set<test::DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::Ge
namespace detail
{
static test::DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_HOLE_CLEARANCE> dummy;
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_HOLE_CLEARANCE> dummy;
}

View File

@ -28,15 +28,15 @@
#include <convert_basic_shapes_to_polygon.h>
#include <geometry/polygon_test_point_inside.h>
#include <geometry/seg.h>
#include <geometry/shape_poly_set.h>
#include <geometry/shape_rect.h>
#include <geometry/shape_segment.h>
#include <drc_proto/drc_engine.h>
#include <drc_proto/drc_item.h>
#include <drc_proto/drc_rule.h>
#include <drc/drc_engine.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc.h>
#include <drc_proto/drc_test_provider_clearance_base.h>
@ -76,7 +76,7 @@ public:
return "Tests sizes of drilled holes (via/pad drills)";
}
virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
private:
bool checkVia( VIA* via );
@ -135,7 +135,7 @@ bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( D_PAD* aPad )
if( holeSize == 0 )
return true;
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE, aPad );
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE, aPad );
auto minHole = constraint.GetValue().Min();
accountCheck( constraint );
@ -164,7 +164,7 @@ bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( D_PAD* aPad )
bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via )
{
auto constraint = m_drcEngine->EvalRulesForItems( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE, via );
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE, via );
auto minHole = constraint.GetValue().Min();
accountCheck( constraint );
@ -194,7 +194,7 @@ bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via )
}
std::set<test::DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_HOLE_SIZE::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_HOLE_SIZE::GetMatchingConstraintIds() const
{
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE };
}
@ -202,5 +202,5 @@ std::set<test::DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_HOLE_SIZE::GetMatc
namespace detail
{
static test::DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_HOLE_SIZE> dummy;
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_HOLE_SIZE> dummy;
}

View File

@ -25,10 +25,11 @@
#include <class_track.h>
#include <common.h>
#include <drc_proto/drc_engine.h>
#include <drc_proto/drc_item.h>
#include <drc_proto/drc_rule.h>
#include <drc_proto/drc_test_provider.h>
#include <pcbnew/drc/drc_engine.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc_test_provider.h>
#include <kiway.h>
#include <netlist_reader/pcb_netlist.h>
@ -73,7 +74,7 @@ public:
return "Performs layout-vs-schematics integity check";
}
virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
private:
@ -202,7 +203,7 @@ bool test::DRC_TEST_PROVIDER_LVS::Run()
}
std::set<test::DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_LVS::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_LVS::GetMatchingConstraintIds() const
{
return {};
}
@ -210,5 +211,5 @@ std::set<test::DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_LVS::GetMatchingCo
namespace detail
{
static test::DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_LVS> dummy;
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_LVS> dummy;
}

View File

@ -28,10 +28,11 @@
#include <class_module.h>
#include <class_pcb_text.h>
#include <drc_proto/drc_engine.h>
#include <drc_proto/drc_item.h>
#include <drc_proto/drc_rule.h>
#include <drc_proto/drc_test_provider.h>
#include <pcbnew/drc/drc_engine.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <pcbnew/drc/drc_test_provider.h>
#include <ws_draw_item.h>
#include <ws_proxy_view_item.h>
@ -74,7 +75,7 @@ public:
return "Misc checks (board outline, missing textvars)";
}
virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
private:
void testOutline();
@ -206,7 +207,7 @@ bool test::DRC_TEST_PROVIDER_MISC::Run()
}
std::set<test::DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_MISC::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_MISC::GetMatchingConstraintIds() const
{
return {};
}
@ -214,5 +215,5 @@ std::set<test::DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_MISC::GetMatchingC
namespace detail
{
static test::DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_MISC> dummy;
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_MISC> dummy;
}

View File

@ -28,15 +28,15 @@
#include <convert_basic_shapes_to_polygon.h>
#include <geometry/polygon_test_point_inside.h>
#include <geometry/seg.h>
#include <geometry/shape_poly_set.h>
#include <geometry/shape_rect.h>
#include <geometry/shape_segment.h>
#include <drc_proto/drc_engine.h>
#include <drc_proto/drc_item.h>
#include <drc_proto/drc_rule.h>
#include <pcbnew/drc/drc_engine.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc_proto/drc_test_provider_clearance_base.h>
/*
@ -73,7 +73,7 @@ public:
return "Tests for silkscreen covering components pads";
}
virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
private:
};
@ -88,7 +88,8 @@ bool test::DRC_TEST_PROVIDER_SILK_TO_PAD::Run()
DRC_CONSTRAINT worstClearanceConstraint;
m_largestClearance = 0;
if( m_drcEngine->QueryWorstConstraint( test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_SILK_TO_PAD, worstClearanceConstraint, DRCCQ_LARGEST_MINIMUM ) )
if( m_drcEngine->QueryWorstConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_SILK_TO_PAD,
worstClearanceConstraint, DRCCQ_LARGEST_MINIMUM ) )
{
m_largestClearance = worstClearanceConstraint.m_Value.Min();
}
@ -96,21 +97,20 @@ bool test::DRC_TEST_PROVIDER_SILK_TO_PAD::Run()
ReportAux( "Worst clearance : %d nm", m_largestClearance );
ReportStage( ("Testing pads vs silkscreen clearance"), 0, 2 );
std::vector<DRAWSEGMENT*> boardOutline;
std::vector<BOARD_ITEM*> boardItems;
auto queryBoardOutlineItems = [&] ( BOARD_ITEM *item ) -> int
{
boardOutline.push_back( dyn_cast<DRAWSEGMENT*>( item ) );
};
auto queryBoardOutlineItems =
[&]( BOARD_ITEM *item ) -> int
{
boardOutline.push_back( dyn_cast<DRAWSEGMENT*>( item ) );
};
auto queryBoardGeometryItems = [&] ( BOARD_ITEM *item ) -> int
{
boardItems.push_back( item );
};
auto queryBoardGeometryItems =
[&]( BOARD_ITEM *item ) -> int
{
boardItems.push_back( item );
};
forEachGeometryItem( { PCB_LINE_T }, LSET( Edge_Cuts ), queryBoardOutlineItems );
forEachGeometryItem( {}, LSET::AllTechMask() | LSET::AllCuMask(), queryBoardGeometryItems );
@ -156,7 +156,7 @@ bool test::DRC_TEST_PROVIDER_SILK_TO_PAD::Run()
}
std::set<test::DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::GetMatchingConstraintIds() const
{
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE };
}
@ -164,5 +164,5 @@ std::set<test::DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::Ge
namespace detail
{
static test::DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_EDGE_CLEARANCE> dummy;
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_EDGE_CLEARANCE> dummy;
}

View File

@ -25,10 +25,11 @@
#include <class_track.h>
#include <common.h>
#include <drc_proto/drc_engine.h>
#include <drc_proto/drc_item.h>
#include <drc_proto/drc_rule.h>
#include <drc_proto/drc_test_provider.h>
#include <drc/drc_engine.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc_test_provider.h>
/*
@ -63,7 +64,7 @@ public:
return "Tests track widths";
}
virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
};
}; // namespace test
@ -71,8 +72,7 @@ public:
bool test::DRC_TEST_PROVIDER_TRACK_WIDTH::Run()
{
if( !m_drcEngine->HasCorrectRulesForId(
test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_TRACK_WIDTH ) )
if( !m_drcEngine->HasCorrectRulesForId( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_TRACK_WIDTH ) )
{
ReportAux( "No track width constraints found. Skipping check." );
return false;
@ -95,8 +95,8 @@ bool test::DRC_TEST_PROVIDER_TRACK_WIDTH::Run()
p0 = ( trk->GetStart() + trk->GetEnd() ) / 2;
}
test::DRC_CONSTRAINT constraint = m_drcEngine->EvalRulesForItems(
test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_TRACK_WIDTH, item );
DRC_CONSTRAINT constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_TRACK_WIDTH,
item );
bool fail_min = false, fail_max = false;
int constraintWidth;
@ -119,7 +119,7 @@ bool test::DRC_TEST_PROVIDER_TRACK_WIDTH::Run()
wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (%s; width %s, constraint %s %s)" ),
constraint.GetParentRule()->GetName(),
constraint.GetParentRule()->m_Name,
MessageTextFromValue( userUnits(), width, true ),
fail_min ? _( "minimum" ) : _( "maximum" ),
MessageTextFromValue( userUnits(), constraintWidth, true ) );
@ -146,8 +146,7 @@ bool test::DRC_TEST_PROVIDER_TRACK_WIDTH::Run()
}
std::set<test::DRC_CONSTRAINT_TYPE_T>
test::DRC_TEST_PROVIDER_TRACK_WIDTH::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_TRACK_WIDTH::GetMatchingConstraintIds() const
{
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_TRACK_WIDTH };
}
@ -155,5 +154,5 @@ test::DRC_TEST_PROVIDER_TRACK_WIDTH::GetMatchingConstraintIds() const
namespace detail
{
static test::DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_TRACK_WIDTH> dummy;
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_TRACK_WIDTH> dummy;
}

View File

@ -25,10 +25,11 @@
#include <class_track.h>
#include <common.h>
#include <drc_proto/drc_engine.h>
#include <drc_proto/drc_item.h>
#include <drc_proto/drc_rule.h>
#include <drc_proto/drc_test_provider.h>
#include <drc/drc_engine.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc_test_provider.h>
/*
@ -65,7 +66,7 @@ public:
return "Tests via diameters";
}
virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
};
}; // namespace test
@ -73,8 +74,7 @@ public:
bool test::DRC_TEST_PROVIDER_VIA_DIAMETER::Run()
{
if( !m_drcEngine->HasCorrectRulesForId(
test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_VIA_DIAMETER ) )
if( !m_drcEngine->HasCorrectRulesForId( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_VIA_DIAMETER ) )
{
ReportAux( "No diameter constraints found. Skipping check." );
return false;
@ -89,8 +89,7 @@ bool test::DRC_TEST_PROVIDER_VIA_DIAMETER::Run()
if( !via )
return true;
test::DRC_CONSTRAINT constraint = m_drcEngine->EvalRulesForItems(
test::DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_VIA_DIAMETER, item );
DRC_CONSTRAINT constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_VIA_DIAMETER, item );
bool fail_min = false, fail_max = false;
int constraintDiameter;
@ -114,7 +113,7 @@ bool test::DRC_TEST_PROVIDER_VIA_DIAMETER::Run()
wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (%s; diameter %s, constraint %s %s)" ),
constraint.GetParentRule()->GetName(),
constraint.GetParentRule()->m_Name,
MessageTextFromValue( userUnits(), diameter, true ),
fail_min ? _( "minimum" ) : _( "maximum" ),
MessageTextFromValue( userUnits(), constraintDiameter, true ) );
@ -141,8 +140,7 @@ bool test::DRC_TEST_PROVIDER_VIA_DIAMETER::Run()
}
std::set<test::DRC_CONSTRAINT_TYPE_T>
test::DRC_TEST_PROVIDER_VIA_DIAMETER::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_VIA_DIAMETER::GetMatchingConstraintIds() const
{
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_VIA_DIAMETER };
}
@ -150,5 +148,5 @@ test::DRC_TEST_PROVIDER_VIA_DIAMETER::GetMatchingConstraintIds() const
namespace detail
{
static test::DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_VIA_DIAMETER> dummy;
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_VIA_DIAMETER> dummy;
}

View File

@ -25,7 +25,7 @@
#ifndef DRC_TEXTVAR_TESTER__H
#define DRC_TEXTVAR_TESTER__H
#include <drc/drc_provider.h>
#include <drc/drc_results_provider.h>
class BOARD;

View File

@ -1,90 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <fctsys.h>
#include <netlist_reader/pcb_netlist.h>
#include <drc/footprint_tester.h>
void TestFootprints( NETLIST& aNetlist, BOARD* aBoard, std::vector<std::shared_ptr<DRC_ITEM> >& aDRCList )
{
wxString msg;
auto comp = []( const MODULE* x, const MODULE* y )
{
return x->GetReference().CmpNoCase( y->GetReference() ) < 0;
};
auto mods = std::set<MODULE*, decltype( comp )>( comp );
if( !aBoard->GetDesignSettings().Ignore( DRCE_DUPLICATE_FOOTPRINT ) )
{
// Search for duplicate footprints on the board
for( MODULE* mod : aBoard->Modules() )
{
auto ins = mods.insert( mod );
if( !ins.second )
{
DRC_ITEM* item = new DRC_ITEM( DRCE_DUPLICATE_FOOTPRINT );
item->SetItems( mod, *ins.first );
aDRCList.push_back( item );
}
}
}
if( !aBoard->GetDesignSettings().Ignore( DRCE_MISSING_FOOTPRINT ) )
{
// Search for component footprints in the netlist but not on the board.
for( unsigned ii = 0; ii < aNetlist.GetCount(); ii++ )
{
COMPONENT* component = aNetlist.GetComponent( ii );
MODULE* module = aBoard->FindModuleByReference( component->GetReference() );
if( module == NULL )
{
msg.Printf( _( "Missing footprint %s (%s)" ),
component->GetReference(),
component->GetValue() );
DRC_ITEM* item = new DRC_ITEM( DRCE_MISSING_FOOTPRINT );
item->SetErrorMessage( msg );
aDRCList.push_back( item );
}
}
}
if( !aBoard->GetDesignSettings().Ignore( DRCE_EXTRA_FOOTPRINT ) )
{
// Search for component footprints found on board but not in netlist.
for( auto module : mods )
{
COMPONENT* component = aNetlist.GetComponentByReference( module->GetReference() );
if( component == NULL )
{
DRC_ITEM* item = new DRC_ITEM( DRCE_EXTRA_FOOTPRINT );
item->SetItems( module );
aDRCList.push_back( item );
}
}
}
}

View File

@ -1,34 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef FOOTPRINT_TESTER_H
#define FOOTPRINT_TESTER_H
#include <drc/drc.h>
class BOARD;
void TestFootprints( NETLIST& aNetlist, BOARD* aBoard, std::vector<DRC_ITEM*>& aDRCList );
#endif // FOOTPRINT_TESTER_H

View File

@ -78,7 +78,7 @@ public:
markers.push_back( std::unique_ptr<MARKER_PCB>( aMarker ) );
};
std::unique_ptr<DRC_TEST_PROVIDER> drc_prov = createDrcProvider( aBoard, marker_handler );
std::unique_ptr<LEGACY_DRC_TEST_PROVIDER> drc_prov = createDrcProvider( aBoard, marker_handler );
DRC_DURATION duration;
{
@ -106,8 +106,8 @@ private:
*/
virtual void setDesignSettings( BOARD_DESIGN_SETTINGS& aSettings ) const = 0;
virtual std::unique_ptr<DRC_TEST_PROVIDER> createDrcProvider(
BOARD& aBoard, DRC_TEST_PROVIDER::MARKER_HANDLER aHandler ) = 0;
virtual std::unique_ptr<LEGACY_DRC_TEST_PROVIDER> createDrcProvider(
BOARD& aBoard, LEGACY_DRC_TEST_PROVIDER::MARKER_HANDLER aHandler ) = 0;
void reportDuration( const DRC_DURATION& aDuration ) const
{
@ -164,8 +164,8 @@ private:
aSettings.m_DRCSeverities[ DRCE_OVERLAPPING_FOOTPRINTS ] = RPT_SEVERITY_ERROR;
}
std::unique_ptr<DRC_TEST_PROVIDER> createDrcProvider(
BOARD& aBoard, DRC_TEST_PROVIDER::MARKER_HANDLER aHandler ) override
std::unique_ptr<LEGACY_DRC_TEST_PROVIDER> createDrcProvider(
BOARD& aBoard, LEGACY_DRC_TEST_PROVIDER::MARKER_HANDLER aHandler ) override
{
return std::make_unique<DRC_COURTYARD_TESTER>( aHandler );
}
@ -198,8 +198,8 @@ private:
aSettings.m_DRCSeverities[ DRCE_OVERLAPPING_FOOTPRINTS ] = RPT_SEVERITY_IGNORE;
}
std::unique_ptr<DRC_TEST_PROVIDER> createDrcProvider(
BOARD& aBoard, DRC_TEST_PROVIDER::MARKER_HANDLER aHandler ) override
std::unique_ptr<LEGACY_DRC_TEST_PROVIDER> createDrcProvider(
BOARD& aBoard, LEGACY_DRC_TEST_PROVIDER::MARKER_HANDLER aHandler ) override
{
return std::make_unique<DRC_COURTYARD_TESTER>( aHandler );
}