Adjust isErrorLimitExceeded so it can be used for severity==IGNORE.

This commit is contained in:
Jeff Young 2020-09-12 20:28:22 +01:00
parent 9f85730987
commit 5d9301d394
17 changed files with 222 additions and 208 deletions

View File

@ -35,7 +35,7 @@
#include <drc/drc_rule.h>
#include <drc/drc_item.h>
#include <drc/drc_test_provider.h>
#include "drc.h"
void drcPrintDebugMessage( int level, wxString msg, const char *function, int line )
{
@ -61,6 +61,7 @@ DRC_ENGINE::DRC_ENGINE( BOARD* aBoard, BOARD_DESIGN_SETTINGS *aSettings ) :
m_reporter( nullptr ),
m_progressReporter( nullptr )
{
m_errorLimits.resize( DRCE_LAST );
}
@ -307,11 +308,12 @@ bool DRC_ENGINE::CompileRules()
ReportAux( wxString::Format( "- Provider: '%s': ", provider->GetName() ) );
drc_dbg(7, "do prov %s", provider->GetName() );
for ( auto id : provider->GetMatchingConstraintIds() )
for ( DRC_CONSTRAINT_TYPE_T id : provider->GetMatchingConstraintIds() )
{
drc_dbg(7, "do id %d", id);
if( m_constraintMap.find(id) == m_constraintMap.end() )
m_constraintMap[id] = new CONSTRAINT_SET;
drc_dbg( 7, "do id %d", id );
if( m_constraintMap.find( id ) == m_constraintMap.end() )
m_constraintMap[ id ] = new CONSTRAINT_SET;
m_constraintMap[ id ]->provider = provider;
@ -364,9 +366,7 @@ bool DRC_ENGINE::CompileRules()
ReportAux( wxString::Format( " |- constraint: %s",
formatConstraint( constraint ) ) );
}
}
}
}
}
@ -428,6 +428,9 @@ void DRC_ENGINE::InitEngine( wxFileName aRulePath )
inferLegacyRules();
CompileRules();
for( int ii = DRCE_FIRST; ii < DRCE_LAST; ++ii )
m_errorLimits[ ii ] = INT_MAX;
}
@ -435,6 +438,14 @@ void DRC_ENGINE::RunTests( )
{
m_drcReport = std::make_shared<DRC_REPORT>();
for( int ii = DRCE_FIRST; ii < DRCE_LAST; ++ii )
{
if( m_designSettings->Ignore( ii ) )
m_errorLimits[ ii ] = 0;
else
m_errorLimits[ ii ] = INT_MAX;
}
for( DRC_TEST_PROVIDER* provider : m_testProviders )
{
bool skipProvider = false;

View File

@ -119,35 +119,17 @@ public:
DRC_ENGINE( BOARD* aBoard, BOARD_DESIGN_SETTINGS* aSettings );
~DRC_ENGINE();
void SetSchematicNetlist( NETLIST* aNetlist )
{
m_schematicNetlist = aNetlist;
}
void SetSchematicNetlist( NETLIST* aNetlist ) { m_schematicNetlist = aNetlist; }
NETLIST* GetSchematicNetlist() const { return m_schematicNetlist; }
NETLIST* GetSchematicNetlist() const
{
return m_schematicNetlist;
}
// JEY TODO: why isn't this called?
void SetWorksheet( KIGFX::WS_PROXY_VIEW_ITEM* aWorksheet ) { m_worksheet = aWorksheet; }
KIGFX::WS_PROXY_VIEW_ITEM* GetWorksheet() const { return m_worksheet; }
void SetWorksheet( KIGFX::WS_PROXY_VIEW_ITEM* aWorksheet )
{
m_worksheet = aWorksheet;
}
// JEY TODO: rationalize old progress report style with new...
void SetProgressReporter( PROGRESS_REPORTER* aProgRep ) { m_progressReporter = aProgRep; }
KIGFX::WS_PROXY_VIEW_ITEM* GetWorksheet() const
{
return m_worksheet;
}
void SetProgressReporter( PROGRESS_REPORTER* aProgRep )
{
m_progressReporter = aProgRep;
}
void SetLogReporter( REPORTER* aReporter )
{
m_reporter = aReporter;
}
void SetLogReporter( REPORTER* aReporter ) { m_reporter = aReporter; }
bool LoadRules( wxFileName aPath );
@ -157,14 +139,15 @@ public:
void SetErrorLimit( int aLimit );
BOARD_DESIGN_SETTINGS* GetDesignSettings() const
{
return m_designSettings;
}
BOARD_DESIGN_SETTINGS* GetDesignSettings() const { return m_designSettings; }
BOARD* GetBoard() const
BOARD* GetBoard() const { return m_board; }
bool IsErrorLimitExceeded( int error_code )
{
return m_board;
m_errorLimits[ error_code ] -= 1;
return m_errorLimits[ error_code ] <= 0;
}
DRC_CONSTRAINT EvalRulesForItems( DRC_CONSTRAINT_TYPE_T ruleID, BOARD_ITEM* a,
@ -190,7 +173,7 @@ public:
bool CompileRules();
void Report( std::shared_ptr<DRC_ITEM> aItem, ::MARKER_PCB *Marker );
void Report( std::shared_ptr<DRC_ITEM> aItem, MARKER_PCB *Marker );
void ReportProgress( double aProgress );
void ReportStage ( const wxString& aStageName, int index, int total );
void ReportAux( const wxString& aStr );
@ -221,8 +204,6 @@ private:
DRC_TEST_PROVIDER* provider;
};
typedef std::unordered_map<DRC_CONSTRAINT_TYPE_T, CONSTRAINT_SET*> CONSTRAINT_MAP;
void inferLegacyRules();
void loadTestProviders();
DRC_RULE* createInferredRule( const wxString& name, std::set<BOARD_ITEM*> items, int priority );
@ -238,8 +219,11 @@ protected:
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;
std::vector<int> m_errorLimits;
std::unordered_map<EDA_ITEM*, CONSTRAINT_SET*> m_implicitRules;
std::unordered_map<DRC_CONSTRAINT_TYPE_T, CONSTRAINT_SET*> m_constraintMap;
REPORTER* m_reporter;
PROGRESS_REPORTER* m_progressReporter;

View File

@ -49,7 +49,9 @@ enum DRC_CONSTRAINT_TYPE_T
DRC_CONSTRAINT_TYPE_TRACK_WIDTH,
DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH,
DRC_CONSTRAINT_TYPE_DISALLOW,
DRC_CONSTRAINT_TYPE_VIA_DIAMETER
DRC_CONSTRAINT_TYPE_VIA_DIAMETER,
DRC_CONSTRAINT_TYPE_COUNT
};
enum DRC_DISALLOW_T

View File

@ -7,9 +7,11 @@ DRC_TEST_PROVIDER::DRC_TEST_PROVIDER() :
{
}
const wxString DRC_TEST_PROVIDER::GetName() const { return "<no name test>"; }
const wxString DRC_TEST_PROVIDER::GetDescription() const { return ""; }
void DRC_TEST_PROVIDER::Report( std::shared_ptr<DRC_ITEM> item )
{
item->SetViolatingTest( this );
@ -24,6 +26,7 @@ void DRC_TEST_PROVIDER::ReportWithMarker( std::shared_ptr<DRC_ITEM> item, VECTOR
m_drcEngine->Report( item, marker );
}
void DRC_TEST_PROVIDER::ReportWithMarker( std::shared_ptr<DRC_ITEM> item, wxPoint aMarkerPos )
{
item->SetViolatingTest( this );
@ -31,17 +34,20 @@ void DRC_TEST_PROVIDER::ReportWithMarker( std::shared_ptr<DRC_ITEM> item, wxPoin
m_drcEngine->Report( item, marker ); // fixme: create marker
}
void DRC_TEST_PROVIDER::ReportProgress( double aProgress )
{
m_drcEngine->ReportProgress( aProgress );
}
void DRC_TEST_PROVIDER::ReportStage ( const wxString& aStageName, int index, int total )
{
m_drcEngine->ReportStage( aStageName, index, total );
ReportAux( aStageName );
}
void DRC_TEST_PROVIDER::ReportAux( wxString fmt, ... )
{
va_list vargs;
@ -52,17 +58,13 @@ void DRC_TEST_PROVIDER::ReportAux( wxString fmt, ... )
m_drcEngine->ReportAux( str );
}
bool DRC_TEST_PROVIDER::isErrorLimitExceeded( int error_code )
{
// fixme: implement error limit (or timeout)
return false;
}
EDA_UNITS DRC_TEST_PROVIDER::userUnits() const
{
return m_drcEngine->UserUnits();
}
void DRC_TEST_PROVIDER::accountCheck( const DRC_RULE* ruleToTest )
{
auto it = m_stats.find( ruleToTest );
@ -73,6 +75,7 @@ void DRC_TEST_PROVIDER::accountCheck( const DRC_RULE* ruleToTest )
it->second++;
}
void DRC_TEST_PROVIDER::accountCheck( const DRC_CONSTRAINT& constraintToTest )
{
accountCheck( constraintToTest.GetParentRule() );
@ -86,7 +89,7 @@ void DRC_TEST_PROVIDER::reportRuleStatistics()
m_drcEngine->ReportAux("Rule hit statistics: ");
for( const std::pair<const DRC_RULE*, int>& stat : m_stats )
for( const std::pair<const DRC_RULE* const, int>& stat : m_stats )
{
m_drcEngine->ReportAux( wxString::Format( " - rule '%s': %d hits ",
stat.first->m_Name,
@ -94,8 +97,9 @@ void DRC_TEST_PROVIDER::reportRuleStatistics()
}
}
int 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, LSET aLayers,
const std::function<bool( BOARD_ITEM*)>& aFunc )
{
BOARD *brd = m_drcEngine->GetBoard();
std::bitset<MAX_STRUCT_TYPE_ID> typeMask;
@ -104,16 +108,12 @@ int DRC_TEST_PROVIDER::forEachGeometryItem( const std::vector<KICAD_T> aTypes, c
if( aTypes.size() == 0 )
{
for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
{
typeMask[i] = true;
}
typeMask[ i ] = true;
}
else
{
for( int i = 0; i < aTypes.size(); i++ )
{
typeMask[ aTypes[i] ] = 1;
}
for( KICAD_T aType : aTypes )
typeMask[ aType ] = true;
}
/* case PCB_TRACE_T:

View File

@ -108,13 +108,12 @@ public:
}
protected:
int forEachGeometryItem( const std::vector<KICAD_T> aTypes, const LSET aLayers,
std::function<bool(BOARD_ITEM*)> aFunc );
int forEachGeometryItem( const std::vector<KICAD_T>& aTypes, LSET aLayers,
const std::function<bool(BOARD_ITEM*)>& aFunc );
virtual void reportRuleStatistics();
virtual void accountCheck( const DRC_RULE* ruleToTest );
virtual void accountCheck( const DRC_CONSTRAINT& constraintToTest );
virtual bool isErrorLimitExceeded( int error_code );
EDA_UNITS userUnits() const;
DRC_ENGINE* m_drcEngine;

View File

@ -79,6 +79,9 @@ bool DRC_TEST_PROVIDER_ANNULUS::Run()
auto checkAnnulus =
[&]( BOARD_ITEM* item ) -> bool
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_ANNULUS ) )
return false;
int v_min;
int v_max;
VIA* via = dyn_cast<VIA*>( item );
@ -123,10 +126,6 @@ bool DRC_TEST_PROVIDER_ANNULUS::Run()
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, via->GetPosition() );
if( isErrorLimitExceeded( DRCE_ANNULUS ) )
return false;
}
return true;

View File

@ -81,27 +81,27 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
for( TRACK* track : board->Tracks() )
{
bool exceedT = isErrorLimitExceeded( DRCE_DANGLING_TRACK );
bool exceedV = isErrorLimitExceeded( DRCE_DANGLING_VIA );
bool exceedT = m_drcEngine->IsErrorLimitExceeded( DRCE_DANGLING_TRACK );
bool exceedV = m_drcEngine->IsErrorLimitExceeded( DRCE_DANGLING_VIA );
if( exceedV && exceedT )
break;
else if( track->Type() == PCB_VIA_T && exceedV )
continue;
else if( track->Type() == PCB_TRACE_T && exceedT )
continue;
// Test for dangling items
int code = track->Type() == PCB_VIA_T ? DRCE_DANGLING_VIA : DRCE_DANGLING_TRACK;
wxPoint pos;
if( track->Type() == PCB_VIA_T && exceedV )
continue;
else if( track->Type() == PCB_TRACE_T && exceedT )
continue;
if( connectivity->TestTrackEndpointDangling( track, &pos ) )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( code );
drcItem->SetItems( track );
ReportWithMarker( drcItem, pos );
}
if( exceedV && exceedT )
break;
}
ReportStage( _( "Testing starved zones" ), 0, 2 );
@ -109,6 +109,9 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
/* test starved zones */
for( ZONE_CONTAINER* zone : board->Zones() )
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_ZONE_HAS_EMPTY_NET ) )
break;
if( !zone->IsOnCopperLayer() )
continue;
@ -123,9 +126,6 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ZONE_HAS_EMPTY_NET );
drcItem->SetItems( zone );
ReportWithMarker( drcItem, zone->GetPosition() );
if( isErrorLimitExceeded( DRCE_ZONE_HAS_EMPTY_NET ) )
break;
}
}
@ -137,12 +137,12 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
for( const CN_EDGE& edge : edges )
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_UNCONNECTED_ITEMS ) )
break;
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_UNCONNECTED_ITEMS );
drcItem->SetItems( edge.GetSourceNode()->Parent(), edge.GetTargetNode()->Parent() );
ReportWithMarker( drcItem, edge.GetSourceNode()->Pos() );
if( isErrorLimitExceeded( DRCE_UNCONNECTED_ITEMS ) )
break;
}
reportRuleStatistics();

View File

@ -89,7 +89,7 @@ private:
void doTrackDrc( TRACK* aRefSeg, PCB_LAYER_ID aLayer, TRACKS::iterator aStartIt,
TRACKS::iterator aEndIt, bool aTestZones );
bool doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_limit );
void doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_limit );
};
@ -320,12 +320,18 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, PCB_LAYER_I
// Compute the min distance to pads
for( MODULE* mod : m_board->Modules() )
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE ) )
break;
// Don't preflight at the module level. Getting a module's bounding box goes
// through all its pads anyway (so it's no faster), and also all its drawings
// (so it's in fact slower).
for( D_PAD* pad : mod->Pads() )
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE ) )
break;
// Preflight based on bounding boxes.
EDA_RECT inflatedBB = refSegBB;
inflatedBB.Inflate( pad->GetBoundingRadius() + m_largestClearance );
@ -364,9 +370,6 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, PCB_LAYER_I
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pad->GetPosition() );
if( isErrorLimitExceeded( DRCE_CLEARANCE ) )
return;
}
}
}
@ -378,6 +381,9 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, PCB_LAYER_I
// Test the reference segment with other track segments
for( auto it = aStartIt; it != aEndIt; it++ )
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE ) )
break;
TRACK* track = *it;
// No problem if segments have the same net code:
@ -419,9 +425,6 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, PCB_LAYER_I
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, (wxPoint) intersection.get() );
if( isErrorLimitExceeded( DRCE_TRACKS_CROSSING ) )
return;
}
else if( refSeg.Collide( &trackSeg, minClearance - bds.GetDRCEpsilon(), &actual ) )
{
@ -438,9 +441,6 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, PCB_LAYER_I
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pos );
if( isErrorLimitExceeded( DRCE_CLEARANCE ) )
return;
}
}
@ -455,6 +455,9 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, PCB_LAYER_I
for( ZONE_CONTAINER* zone : m_board->Zones() )
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE ) )
break;
if( !zone->GetLayerSet().test( aLayer ) || zone->GetIsKeepout() )
continue;
@ -473,7 +476,6 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, PCB_LAYER_I
accountCheck( constraint );
if( zone->GetFilledPolysList( aLayer ).Collide( testSeg, allowedDist, &actual ) )
{
actual = std::max( 0, actual - halfWidth );
@ -540,7 +542,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadClearances( )
}
}
bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart,
void DRC_TEST_PROVIDER_COPPER_CLEARANCE::doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart,
D_PAD** aEnd, int x_limit )
{
const static LSET all_cu = LSET::AllCuMask();
@ -550,6 +552,12 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::doPadToPadsDrc( D_PAD* aRefPad, D_PAD**
for( D_PAD** pad_list = aStart; pad_list<aEnd; ++pad_list )
{
bool exceedClearance = m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE );
bool exceedShorting = m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE );
if( exceedClearance && exceedShorting )
return;
D_PAD* pad = *pad_list;
if( pad == aRefPad )
@ -570,7 +578,8 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::doPadToPadsDrc( D_PAD* aRefPad, D_PAD**
{
// ...and have nets, then they must be the same net
if( pad->GetNetCode() && aRefPad->GetNetCode()
&& pad->GetNetCode() != aRefPad->GetNetCode() )
&& pad->GetNetCode() != aRefPad->GetNetCode()
&& !exceedShorting )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_SHORTING_ITEMS );
@ -595,6 +604,9 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::doPadToPadsDrc( D_PAD* aRefPad, D_PAD**
for( PCB_LAYER_ID layer : aRefPad->GetLayerSet().Seq() )
{
if( exceedClearance )
break;
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_CLEARANCE,
aRefPad, pad, layer );
int minClearance = constraint.GetValue().Min();
@ -619,12 +631,10 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::doPadToPadsDrc( D_PAD* aRefPad, D_PAD**
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, aRefPad->GetPosition() );
return false;
break;
}
}
}
return true;
}

View File

@ -84,7 +84,7 @@ void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testFootprintCourtyardDefinitions()
if( footprint->GetPolyCourtyardFront().OutlineCount() == 0
&& footprint->GetPolyCourtyardBack().OutlineCount() == 0 )
{
if( isErrorLimitExceeded( DRCE_MISSING_COURTYARD ) )
if( m_drcEngine->IsErrorLimitExceeded( DRCE_MISSING_COURTYARD ) )
continue;
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_MISSING_COURTYARD );
@ -99,16 +99,16 @@ void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testFootprintCourtyardDefinitions()
}
else
{
if( !isErrorLimitExceeded( DRCE_MALFORMED_COURTYARD) )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_MALFORMED_COURTYARD );
if( m_drcEngine->IsErrorLimitExceeded( DRCE_MALFORMED_COURTYARD) )
continue;
m_msg.Printf( drcItem->GetErrorText() + _( " (not a closed shape)" ) );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_MALFORMED_COURTYARD );
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( footprint );
ReportWithMarker( drcItem, footprint->GetPosition() );
}
m_msg.Printf( drcItem->GetErrorText() + _( " (not a closed shape)" ) );
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( footprint );
ReportWithMarker( drcItem, footprint->GetPosition() );
}
}
}
@ -120,6 +120,9 @@ void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testOverlappingComponentCourtyards()
for( auto it1 = m_board->Modules().begin(); it1 != m_board->Modules().end(); it1++ )
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_OVERLAPPING_FOOTPRINTS) )
break;
MODULE* footprint = *it1;
SHAPE_POLY_SET& footprintFront = footprint->GetPolyCourtyardFront();
SHAPE_POLY_SET& footprintBack = footprint->GetPolyCourtyardBack();
@ -173,9 +176,6 @@ void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testOverlappingComponentCourtyards()
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_OVERLAPPING_FOOTPRINTS );
drcItem->SetItems( footprint, test );
ReportWithMarker ( drcItem, pos );
if( isErrorLimitExceeded( DRCE_OVERLAPPING_FOOTPRINTS ) )
return;
}
}
}

View File

@ -77,6 +77,9 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
auto checkItem = [&]( BOARD_ITEM *item ) -> bool
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_ALLOWED_ITEMS ) )
return false;
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_DISALLOW, item );
if( constraint.m_DisallowFlags )
@ -91,9 +94,6 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, item->GetPosition() );
if( isErrorLimitExceeded( DRCE_ALLOWED_ITEMS ) )
return false;
}
return true;

View File

@ -93,17 +93,19 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
std::vector<DRAWSEGMENT*> boardOutline;
std::vector<BOARD_ITEM*> boardItems;
auto queryBoardOutlineItems = [&] ( BOARD_ITEM *item ) -> bool
{
boardOutline.push_back( dyn_cast<DRAWSEGMENT*>( item ) );
return true;
};
auto queryBoardOutlineItems =
[&]( BOARD_ITEM *item ) -> bool
{
boardOutline.push_back( dyn_cast<DRAWSEGMENT*>( item ) );
return true;
};
auto queryBoardGeometryItems = [&] ( BOARD_ITEM *item ) -> bool
{
boardItems.push_back( item );
return true;
};
auto queryBoardGeometryItems =
[&]( BOARD_ITEM *item ) -> bool
{
boardItems.push_back( item );
return true;
};
forEachGeometryItem( { PCB_LINE_T }, LSET( Edge_Cuts ), queryBoardOutlineItems );
forEachGeometryItem( {}, LSET::AllTechMask() | LSET::AllCuMask(), queryBoardGeometryItems );
@ -111,16 +113,20 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
wxString val;
wxGetEnv( "WXTRACE", &val);
drc_dbg(2,"outline: %d items, board: %d items\n", boardOutline.size(), boardItems.size() );
bool stop = false;
drc_dbg( 2,"outline: %d items, board: %d items\n", boardOutline.size(), boardItems.size() );
for( DRAWSEGMENT* outlineItem : boardOutline )
{
if( m_drcEngine->IsErrorLimitExceeded( DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE ) )
break;
const std::shared_ptr<SHAPE>& refShape = outlineItem->GetEffectiveShape();
for( BOARD_ITEM* boardItem : boardItems )
{
if( m_drcEngine->IsErrorLimitExceeded( DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE ) )
break;
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,
@ -149,17 +155,8 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, refShape->Centre() );
if( isErrorLimitExceeded( DRCE_COPPER_EDGE_CLEARANCE ) )
{
stop = true;
break;
}
}
}
if( stop )
break;
}
reportRuleStatistics();

View File

@ -353,11 +353,17 @@ void DRC_TEST_PROVIDER_HOLE_CLEARANCE::testHoles2Holes()
for( size_t ii = 0; ii < m_drilledHoles.size(); ++ii )
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_DRILLED_HOLES_TOO_CLOSE ) )
break;
DRILLED_HOLE& refHole = m_drilledHoles[ ii ];
int neighborhood = refHole.m_drillRadius + m_largestClearance + m_largestRadius;
for( size_t jj = ii + 1; jj < m_drilledHoles.size(); ++jj )
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_DRILLED_HOLES_TOO_CLOSE ) )
break;
DRILLED_HOLE& checkHole = m_drilledHoles[ jj ];
if( refHole.m_location.x + neighborhood < checkHole.m_location.x )
@ -390,9 +396,6 @@ void DRC_TEST_PROVIDER_HOLE_CLEARANCE::testHoles2Holes()
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, refHole.m_location );
if( isErrorLimitExceeded( DRCE_DRILLED_HOLES_TOO_CLOSE ) )
return;
}
}
}

View File

@ -65,8 +65,8 @@ public:
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
private:
bool checkVia( VIA* via );
bool checkPad( D_PAD* aPad );
void checkVia( VIA* via, bool aExceedMicro, bool aExceedStd );
void checkPad( D_PAD* aPad );
BOARD* m_board;
};
@ -80,10 +80,15 @@ bool DRC_TEST_PROVIDER_HOLE_SIZE::Run()
for( MODULE* module : m_board->Modules() )
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_TOO_SMALL_DRILL ) )
break;
for( D_PAD* pad : module->Pads() )
{
if( checkPad( pad ) )
if( m_drcEngine->IsErrorLimitExceeded( DRCE_TOO_SMALL_DRILL ) )
break;
checkPad( pad );
}
}
@ -100,8 +105,13 @@ bool DRC_TEST_PROVIDER_HOLE_SIZE::Run()
for( VIA* via : vias )
{
if( checkVia( via ) )
bool exceedMicro = m_drcEngine->IsErrorLimitExceeded( DRCE_TOO_SMALL_MICROVIA_DRILL );
bool exceedStd = m_drcEngine->IsErrorLimitExceeded( DRCE_TOO_SMALL_DRILL );
if( exceedMicro && exceedStd )
break;
checkVia( via, exceedMicro, exceedStd );
}
reportRuleStatistics();
@ -110,12 +120,12 @@ bool DRC_TEST_PROVIDER_HOLE_SIZE::Run()
}
bool DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( D_PAD* aPad )
void DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( D_PAD* aPad )
{
int holeSize = std::min( aPad->GetDrillSize().x, aPad->GetDrillSize().y );
if( holeSize == 0 )
return true;
return;
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_HOLE_SIZE, aPad );
int minHole = constraint.GetValue().Min();
@ -136,16 +146,29 @@ bool DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( D_PAD* aPad )
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, aPad->GetPosition() );
return isErrorLimitExceeded( DRCE_TOO_SMALL_DRILL );
}
return false;
}
bool DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via )
void DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via, bool aExceedMicro, bool aExceedStd )
{
int errorCode;
if( via->GetViaType() == VIATYPE::MICROVIA )
{
if( aExceedMicro )
return;
errorCode = DRCE_TOO_SMALL_MICROVIA_DRILL;
}
else
{
if( aExceedStd )
return;
errorCode = DRCE_TOO_SMALL_DRILL;
}
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_HOLE_SIZE, via );
int minHole = constraint.GetValue().Min();
@ -153,9 +176,6 @@ bool DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via )
if( via->GetDrillValue() < minHole )
{
int errorCode = via->GetViaType() == VIATYPE::MICROVIA ? DRCE_TOO_SMALL_MICROVIA_DRILL :
DRCE_TOO_SMALL_DRILL;
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( errorCode );
m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ),
@ -168,11 +188,7 @@ bool DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via )
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, via->GetPosition() );
return isErrorLimitExceeded( errorCode );
}
return false;
}

View File

@ -81,16 +81,19 @@ void DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
{
BOARD* board = m_drcEngine->GetBoard();
auto comp = []( const MODULE* x, const MODULE* y )
{
return x->GetReference().CmpNoCase( y->GetReference() ) < 0;
};
auto compare = []( const MODULE* x, const MODULE* y )
{
return x->GetReference().CmpNoCase( y->GetReference() ) < 0;
};
auto mods = std::set<MODULE*, decltype( comp )>( comp );
auto mods = std::set<MODULE*, decltype( compare )>( compare );
// Search for duplicate footprints on the board
for( MODULE* mod : board->Modules() )
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_DUPLICATE_FOOTPRINT ) )
break;
auto ins = mods.insert( mod );
if( !ins.second )
@ -99,9 +102,6 @@ void DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
drcItem->SetItems( mod, *ins.first );
ReportWithMarker( drcItem, mod->GetPosition() );
if( isErrorLimitExceeded( DRCE_DUPLICATE_FOOTPRINT ) )
break;
}
}
@ -113,21 +113,25 @@ void DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
if( module == nullptr )
{
m_msg.Printf( _( "Missing footprint %s (%s)" ), component->GetReference(),
component->GetValue() );
if( m_drcEngine->IsErrorLimitExceeded( DRCE_MISSING_FOOTPRINT ) )
break;
m_msg.Printf( _( "Missing footprint %s (%s)" ),
component->GetReference(),
component->GetValue() );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_MISSING_FOOTPRINT );
drcItem->SetErrorMessage( m_msg );
Report( drcItem );
if( isErrorLimitExceeded( DRCE_MISSING_FOOTPRINT ) )
break;
}
else
{
for( D_PAD* pad : module->Pads() )
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_NET_CONFLICT ) )
break;
const COMPONENT_NET& sch_net = component->GetNet( pad->GetName() );
const wxString& pcb_netname = pad->GetNetname();
@ -161,13 +165,13 @@ void DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
drcItem->SetItems( pad );
ReportWithMarker( drcItem, module->GetPosition() );
}
if( isErrorLimitExceeded( DRCE_NET_CONFLICT ) )
break;
}
for( unsigned jj = 0; jj < component->GetNetCount(); ++jj )
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_NET_CONFLICT ) )
break;
const COMPONENT_NET& sch_net = component->GetNet( jj );
if( !module->FindPadByName( sch_net.GetPinName() ) )
@ -180,9 +184,6 @@ void DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
drcItem->SetItems( module );
ReportWithMarker( drcItem, module->GetPosition() );
}
if( isErrorLimitExceeded( DRCE_NET_CONFLICT ) )
break;
}
}
}
@ -190,17 +191,15 @@ void DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
// Search for component footprints found on board but not in netlist.
for( MODULE* module : board->Modules() )
{
COMPONENT* component = aNetlist.GetComponentByReference( module->GetReference() );
if( m_drcEngine->IsErrorLimitExceeded( DRCE_EXTRA_FOOTPRINT ) )
break;
if( component == NULL )
if( !aNetlist.GetComponentByReference( module->GetReference() ) )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_EXTRA_FOOTPRINT );
drcItem->SetItems( module );
ReportWithMarker( drcItem, module->GetPosition() );
if( isErrorLimitExceeded( DRCE_EXTRA_FOOTPRINT ) )
break;
}
}
}

View File

@ -134,15 +134,13 @@ void DRC_TEST_PROVIDER_MISC::testTextVars()
auto checkUnresolvedTextVar =
[&]( EDA_ITEM* item ) -> bool
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_UNRESOLVED_VARIABLE ) )
return false;
EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( item );
wxASSERT( text );
if( text->GetShownText().Matches( wxT( "*${*}*" ) ) )
if( text && text->GetShownText().Matches( wxT( "*${*}*" ) ) )
{
if( isErrorLimitExceeded( DRCE_UNRESOLVED_VARIABLE ) )
return false;
std::shared_ptr<DRC_ITEM>drcItem = DRC_ITEM::Create( DRCE_UNRESOLVED_VARIABLE );
drcItem->SetItems( item );
@ -157,7 +155,7 @@ void DRC_TEST_PROVIDER_MISC::testTextVars()
KIGFX::WS_PROXY_VIEW_ITEM* worksheet = m_drcEngine->GetWorksheet();
WS_DRAW_ITEM_LIST wsItems;
if( !worksheet )
if( !worksheet || m_drcEngine->IsErrorLimitExceeded( DRCE_UNRESOLVED_VARIABLE ) )
return;
wsItems.SetMilsToIUfactor( IU_PER_MILS );
@ -171,18 +169,17 @@ void DRC_TEST_PROVIDER_MISC::testTextVars()
for( WS_DRAW_ITEM_BASE* item = wsItems.GetFirst(); item; item = wsItems.GetNext() )
{
if( WS_DRAW_ITEM_TEXT* text = dynamic_cast<WS_DRAW_ITEM_TEXT*>( item ) )
if( m_drcEngine->IsErrorLimitExceeded( DRCE_UNRESOLVED_VARIABLE ) )
break;
WS_DRAW_ITEM_TEXT* text = dynamic_cast<WS_DRAW_ITEM_TEXT*>( item );
if( text && text->GetShownText().Matches( wxT( "*${*}*" ) ) )
{
if( isErrorLimitExceeded( DRCE_UNRESOLVED_VARIABLE ) )
return;
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_UNRESOLVED_VARIABLE );
drcItem->SetItems( text );
if( text->GetShownText().Matches( wxT( "*${*}*" ) ) )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_UNRESOLVED_VARIABLE );
drcItem->SetItems( text );
ReportWithMarker( drcItem, text->GetPosition() );
}
ReportWithMarker( drcItem, text->GetPosition() );
}
}
}

View File

@ -76,6 +76,9 @@ bool DRC_TEST_PROVIDER_TRACK_WIDTH::Run()
auto checkTrackWidth =
[&]( BOARD_ITEM* item ) -> bool
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_TRACK_WIDTH ) )
return false;
int actual;
VECTOR2I p0;
@ -123,10 +126,6 @@ bool DRC_TEST_PROVIDER_TRACK_WIDTH::Run()
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, p0 );
if( isErrorLimitExceeded( DRCE_TRACK_WIDTH ) )
return false;
}
return true;

View File

@ -21,7 +21,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
//#include <common.h>
#include <class_track.h>
#include <drc/drc_engine.h>
#include <drc/drc.h>
@ -78,7 +77,10 @@ bool DRC_TEST_PROVIDER_VIA_DIAMETER::Run()
auto checkViaDiameter =
[&]( BOARD_ITEM* item ) -> bool
{
auto via = dyn_cast<VIA*>( item );
if( m_drcEngine->IsErrorLimitExceeded( DRCE_VIA_DIAMETER ) )
return false;
VIA* via = dyn_cast<VIA*>( item );
// fixme: move to pad stack check?
if( !via )
@ -118,10 +120,6 @@ bool DRC_TEST_PROVIDER_VIA_DIAMETER::Run()
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, via->GetPosition() );
if( isErrorLimitExceeded( DRCE_VIA_DIAMETER ) )
return false;
}
return true;