Hook up netclasses and board minimums to new DRC engine.

Improves implicit rule reporting.
Makes some internal names more consistent.
Moves DRC_REPORT to the test framework.
Removes priority (which isn't supported in the grammar)
This commit is contained in:
Jeff Young 2020-09-13 11:37:20 +01:00
parent d47d119d5f
commit 748bee1bc7
23 changed files with 288 additions and 339 deletions

View File

@ -19,7 +19,7 @@ DIALOG_HTML_REPORTER::DIALOG_HTML_REPORTER( wxWindow* parent, wxWindowID id, con
bMainSizer = new wxBoxSizer( wxVERTICAL );
m_Reporter = new WX_HTML_REPORT_BOX( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO|wxBORDER_SIMPLE );
m_Reporter->SetMinSize( wxSize( 480,360 ) );
m_Reporter->SetMinSize( wxSize( 640,360 ) );
bMainSizer->Add( m_Reporter, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 10 );

View File

@ -95,7 +95,7 @@
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">480,360</property>
<property name="minimum_size">640,360</property>
<property name="moveable">1</property>
<property name="name">m_Reporter</property>
<property name="pane_border">1</property>

View File

@ -66,32 +66,12 @@ DRC_ENGINE::~DRC_ENGINE()
}
DRC_REPORT::~DRC_REPORT()
{
}
/*void DRC_ENGINE::AddMarker( MARKER_PCB* aMarker )
{
if( m_designSettings->Ignore( aMarker->GetRCItem()->GetErrorCode() ) )
{
delete aMarker;
return;
}
m_markers.push_back( aMarker );
}*/
DRC_RULE* DRC_ENGINE::createInferredRule( const wxString& name, std::set<BOARD_ITEM*> items, int priority )
DRC_RULE* DRC_ENGINE::createImplicitRule( const wxString& name )
{
DRC_RULE *rule = new DRC_RULE;
rule->m_Name = name;
if (! items.empty() )
rule->FillSpecificItemSet( items );
rule->SetPriority( priority );
rule->m_Implicit = true;
addRule( rule );
@ -99,145 +79,123 @@ DRC_RULE* DRC_ENGINE::createInferredRule( const wxString& name, std::set<BOARD_I
}
void DRC_ENGINE::inferLegacyRules()
void DRC_ENGINE::loadImplicitRules()
{
int priorityRangeMin = INT_MIN + 10000;
int priorityRangeMax = INT_MAX - 10000;
ReportAux( wxString::Format( "Building implicit rules (per-item/class overrides, etc...)" ) );
ReportAux( wxString::Format( "Inferring implicit rules (per-item/class overrides, etc...)" ) );
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
// 1) global defaults
DRC_RULE* rule = createInferredRule( "inferred-defaults", {}, priorityRangeMin );
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
DRC_RULE* rule = createImplicitRule( _( "board setup > design rules > constraints" ));
DRC_CONSTRAINT clearanceConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE );
DRC_CONSTRAINT clearanceConstraint( DRC_CONSTRAINT_TYPE_CLEARANCE );
clearanceConstraint.Value().SetMin( bds.m_MinClearance );
rule->AddConstraint( clearanceConstraint );
DRC_CONSTRAINT widthConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_TRACK_WIDTH );
DRC_CONSTRAINT widthConstraint( DRC_CONSTRAINT_TYPE_TRACK_WIDTH );
widthConstraint.Value().SetMin( bds.m_TrackMinWidth );
rule->AddConstraint( widthConstraint );
DRC_CONSTRAINT drillConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE );
DRC_CONSTRAINT drillConstraint( DRC_CONSTRAINT_TYPE_HOLE_SIZE );
drillConstraint.Value().SetMin( bds.m_MinThroughDrill );
rule->AddConstraint( drillConstraint );
DRC_CONSTRAINT annulusConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH );
DRC_CONSTRAINT annulusConstraint( DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH );
annulusConstraint.Value().SetMin( bds.m_ViasMinAnnulus );
rule->AddConstraint( annulusConstraint );
DRC_CONSTRAINT diameterConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_VIA_DIAMETER );
DRC_CONSTRAINT diameterConstraint( DRC_CONSTRAINT_TYPE_VIA_DIAMETER );
diameterConstraint.Value().SetMin( bds.m_ViasMinSize );
rule->AddConstraint( diameterConstraint );
DRC_CONSTRAINT edgeClearanceConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE );
DRC_CONSTRAINT edgeClearanceConstraint( DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE );
edgeClearanceConstraint.Value().SetMin( bds.m_CopperEdgeClearance );
rule->AddConstraint( edgeClearanceConstraint );
DRC_CONSTRAINT holeClearanceConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE );
DRC_CONSTRAINT holeClearanceConstraint( DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE );
holeClearanceConstraint.Value().SetMin( bds.m_HoleToHoleMin );
rule->AddConstraint( holeClearanceConstraint );
DRC_CONSTRAINT courtyardClearanceConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE );
DRC_CONSTRAINT courtyardClearanceConstraint( DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE );
holeClearanceConstraint.Value().SetMin( 0 );
rule->AddConstraint( courtyardClearanceConstraint );
// 2) micro-via specific defaults (new DRC doesn't treat microvias in any special way)
priorityRangeMin++;
DRC_RULE* uViaRule = createImplicitRule( _( "board setup > design rules > constraints" ));
auto isMicroViaCondition = new DRC_RULE_CONDITION ( "A.type == 'Via' && A.isMicroVia()" );
DRC_RULE* uViaRule = createInferredRule( "inferred-microvia-defaults", {}, priorityRangeMin );
uViaRule->m_Condition = new DRC_RULE_CONDITION ( "A.Via_Type == 'micro_via'" );
uViaRule->m_Condition = isMicroViaCondition;
DRC_CONSTRAINT uViaDrillConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE );
DRC_CONSTRAINT uViaDrillConstraint( DRC_CONSTRAINT_TYPE_HOLE_SIZE );
uViaDrillConstraint.Value().SetMin( bds.m_MicroViasMinDrill );
uViaRule->AddConstraint( uViaDrillConstraint );
DRC_CONSTRAINT uViaDiameterConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_VIA_DIAMETER );
DRC_CONSTRAINT uViaDiameterConstraint( 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()" );
DRC_RULE* blindBuriedViaRule = createInferredRule( "inferred-blind-buried-via-defaults", {}, priorityRangeMin );
DRC_CONSTRAINT disallowConstraint( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_DISALLOW );
blindBuriedViaRule->m_Condition = isBlindBuriedViaCondition;
if( !bds.m_MicroViasAllowed )
{
DRC_CONSTRAINT disallowConstraint( DRC_CONSTRAINT_TYPE_DISALLOW );
disallowConstraint.m_DisallowFlags = DRC_DISALLOW_MICRO_VIAS;
uViaRule->AddConstraint( disallowConstraint );
}
if( !bds.m_BlindBuriedViaAllowed )
{
blindBuriedViaRule->AddConstraint( disallowConstraint );
DRC_RULE* bbViaRule = createImplicitRule( _( "board setup > design rules > constraints" ));
bbViaRule->m_Condition = new DRC_RULE_CONDITION ( "A.Via_Type == 'buried_via'" );
DRC_CONSTRAINT disallowConstraint( DRC_CONSTRAINT_TYPE_DISALLOW );
disallowConstraint.m_DisallowFlags = DRC_DISALLOW_BB_VIAS;
bbViaRule->AddConstraint( disallowConstraint );
}
// 3) per-netclass rules
struct NETCLASS_ENTRY
{
wxString name;
int clearance;
int width;
};
std::vector<NETCLASS_ENTRY> netclassesByClearance, netclassesByWidth;
m_board->SynchronizeNetsAndNetClasses();
// fixme: make this conditional for standalone tests
bds.SetNetClasses( nullptr ); // load legacy
std::vector<NETCLASSPTR> netclasses;
m_board->SynchronizeNetsAndNetClasses();
netclasses.push_back( bds.GetNetClasses().GetDefault() );
for( const auto& netclass : bds.GetNetClasses() )
for( const std::pair<const wxString, NETCLASSPTR>& netclass : bds.GetNetClasses() )
netclasses.push_back( netclass.second );
ReportAux( wxString::Format( "Importing %d legacy net classes", (int) netclasses.size() ) );
int i = 0;
ReportAux( wxString::Format( "Building %d implicit netclass rules", (int) netclasses.size() ) );
for( const NETCLASSPTR& nc : netclasses )
{
wxString className = nc->GetName();
wxString expr = wxString::Format( "A.NetClass == '%s' || B.NetClass == '%s'",
className,
className );
const auto expr = wxString::Format( "A.NetClass == '%s' || B.NetClass == '%s'", className, className );
auto inNetclassCondition = new DRC_RULE_CONDITION ( expr );
DRC_RULE_CONDITION* inNetclassCondition = new DRC_RULE_CONDITION ( expr );
DRC_RULE* netclassRule = createInferredRule( wxString::Format( "inferred-netclass-clearance-%s", className ),
{}, priorityRangeMin + i );
DRC_RULE* netclassRule = createImplicitRule( wxString::Format( _( "netclass '%s'" ),
className ));
netclassRule->m_Condition = inNetclassCondition;
DRC_CONSTRAINT ncClearanceConstraint ( DRC_CONSTRAINT_TYPE_CLEARANCE );
ncClearanceConstraint.Value().SetMin( nc->GetClearance() );
netclassRule->AddConstraint( ncClearanceConstraint );
// Only add netclass clearances if they're larger than board minimums. That way
// board minimums will still enforce a global minimum.
netclassRule = createInferredRule( wxString::Format( "inferred-netclass-width-%s", className ),
{}, priorityRangeMin + i );
if( nc->GetClearance() > bds.m_MinClearance )
{
DRC_CONSTRAINT ncClearanceConstraint( DRC_CONSTRAINT_TYPE_CLEARANCE );
ncClearanceConstraint.Value().SetMin( nc->GetClearance() );
netclassRule->AddConstraint( ncClearanceConstraint );
}
netclassRule->m_Condition = inNetclassCondition;
DRC_CONSTRAINT ncWidthConstraint ( DRC_CONSTRAINT_TYPE_TRACK_WIDTH );
ncWidthConstraint.Value().SetMin( nc->GetTrackWidth() );
netclassRule->AddConstraint( ncWidthConstraint );
// TODO: should we import diff pair gaps/widths here?
i++;
if( nc->GetTrackWidth() > bds.m_TrackMinWidth )
{
DRC_CONSTRAINT ncWidthConstraint( DRC_CONSTRAINT_TYPE_TRACK_WIDTH );
ncWidthConstraint.Value().SetMin( nc->GetTrackWidth() );
netclassRule->AddConstraint( ncWidthConstraint );
}
}
//clearanceConstraint.SetMin( )
//rule->AddConstraint( )
}
static wxString formatConstraint( const DRC_CONSTRAINT& constraint )
@ -249,21 +207,24 @@ static wxString formatConstraint( const DRC_CONSTRAINT& constraint )
std::function<wxString(const DRC_CONSTRAINT&)> formatter;
};
auto formatMinMax = []( const DRC_CONSTRAINT& c ) -> wxString {
wxString str;
const auto value = c.GetValue();
auto formatMinMax =
[]( const DRC_CONSTRAINT& c ) -> wxString
{
wxString str;
const auto value = c.GetValue();
if ( value.HasMin() )
str += wxString::Format(" min: %d", value.Min() );
if ( value.HasOpt() )
str += wxString::Format(" opt: %d", value.Opt() );
if ( value.HasMax() )
str += wxString::Format(" max: %d", value.Max() );
if ( value.HasMin() )
str += wxString::Format(" min: %d", value.Min() );
if ( value.HasOpt() )
str += wxString::Format(" opt: %d", value.Opt() );
if ( value.HasMax() )
str += wxString::Format(" max: %d", value.Max() );
return str;
};
return str;
};
std::vector<Formatter> formats = {
std::vector<Formatter> formats =
{
{ DRC_CONSTRAINT_TYPE_UNKNOWN, "unknown", nullptr },
{ DRC_CONSTRAINT_TYPE_CLEARANCE, "clearance", formatMinMax },
{ DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE, "hole_clearance", formatMinMax },
@ -278,7 +239,7 @@ static wxString formatConstraint( const DRC_CONSTRAINT& constraint )
{ DRC_CONSTRAINT_TYPE_VIA_DIAMETER, "via_diameter", formatMinMax }
};
for( auto& fmt : formats)
for( auto& fmt : formats )
{
if( fmt.type == constraint.m_Type )
{
@ -343,7 +304,7 @@ bool DRC_ENGINE::CompileRules()
ReportAux( wxString::Format( "- Provider: '%s': ", provider->GetName() ) );
drc_dbg(7, "do prov %s", provider->GetName() );
for ( DRC_CONSTRAINT_TYPE_T id : provider->GetMatchingConstraintIds() )
for ( DRC_CONSTRAINT_TYPE_T id : provider->GetConstraintTypes() )
{
drc_dbg( 7, "do id %d", id );
@ -421,7 +382,7 @@ void DRC_ENGINE::InitEngine( const wxFileName& aRulePath )
}
LoadRules( aRulePath );
inferLegacyRules();
loadImplicitRules();
CompileRules();
@ -430,9 +391,9 @@ void DRC_ENGINE::InitEngine( const wxFileName& aRulePath )
}
void DRC_ENGINE::RunTests( )
void DRC_ENGINE::RunTests( DRC_VIOLATION_HANDLER aViolationHandler )
{
m_drcReport = std::make_shared<DRC_REPORT>();
m_violationHandler = std::move( aViolationHandler );
for( int ii = DRCE_FIRST; ii < DRCE_LAST; ++ii )
{
@ -445,13 +406,13 @@ void DRC_ENGINE::RunTests( )
for( DRC_TEST_PROVIDER* provider : m_testProviders )
{
bool skipProvider = false;
auto matchingConstraints = provider->GetMatchingConstraintIds();
auto providedConstraints = provider->GetConstraintTypes();
if( matchingConstraints.size() )
if( providedConstraints.size() )
{
for( auto ruleID : matchingConstraints )
for( DRC_CONSTRAINT_TYPE_T constraintType : providedConstraints )
{
if( !HasCorrectRulesForId( ruleID ) )
if( !HasRulesForConstraintType( constraintType ) )
{
ReportAux( wxString::Format( "DRC provider '%s' has no rules provided. Skipping run.",
provider->GetName() ) );
@ -493,7 +454,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI
REPORT( wxString::Format( _( "Local override on %s; clearance: %s." ),
a->GetSelectMenuText( aReporter->GetUnits() ),
StringFromValue( aReporter->GetUnits(), overrideA, true ) ) );
StringFromValue( aReporter->GetUnits(), overrideA, true ) ) )
}
if( bc && bc->GetLocalClearanceOverrides( nullptr ) > 0 )
@ -502,13 +463,13 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI
REPORT( wxString::Format( _( "Local override on %s; clearance: %s." ),
b->GetSelectMenuText( aReporter->GetUnits() ),
StringFromValue( aReporter->GetUnits(), overrideB, true ) ) );
StringFromValue( aReporter->GetUnits(), overrideB, true ) ) )
// If both overridden, report on which wins
if( overrideA )
{
REPORT( wxString::Format( _( "Clearance: %s." ),
std::max( overrideA, overrideB ) ) );
std::max( overrideA, overrideB ) ) )
}
}
@ -522,32 +483,52 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI
CONSTRAINT_SET* ruleset = m_constraintMap[ aConstraintId ];
for( int ii = ruleset->sortedConstraints.size() - 1; ii >= 0; --ii )
for( size_t ii = ruleset->sortedConstraints.size() - 1; ii >= 0; --ii )
{
const CONSTRAINT_WITH_CONDITIONS* rcons = ruleset->sortedConstraints[ ii ];
REPORT( wxString::Format( _( "Checking rule \"%s\"." ),
rcons->parentRule->m_Name ) );
bool implicit = rcons->parentRule && rcons->parentRule->m_Implicit;
REPORT( wxString::Format( _( "Checking %s %s." ),
implicit ? _( "" ) : _( "rule" ),
rcons->parentRule->m_Name ) )
if( aLayer != UNDEFINED_LAYER && !rcons->layerTest.test( aLayer ) )
{
REPORT( wxString::Format( _( "Rule layer \"%s\" not matched." ),
rcons->parentRule->m_LayerSource ) );
REPORT( "Rule not applied." );
rcons->parentRule->m_LayerSource ) )
REPORT( "Rule not applied." )
continue;
}
bool result = rcons->condition->EvaluateFor( a, b, aLayer, aReporter );
const wxString& expression = rcons->condition->GetExpression();
if( result )
if( expression.IsEmpty() )
{
REPORT( _( "Rule applied." ) );
REPORT( implicit ? _( "Unconditional constraint applied." )
: _( "Unconditional rule applied." ) )
return rcons->constraint;
}
else
{
REPORT( _( "Condition not satisfied; rule not applied." ) );
REPORT( "" );
// Don't report on implicit rule conditions; they're stuff we made up.
if( !implicit )
REPORT( _( "Checking rule condition \"" + expression + "\"." ) )
if( rcons->condition->EvaluateFor( a, b, aLayer, aReporter ) )
{
REPORT( implicit ? _( "Constraint applied." )
: _( "Rule applied." ) )
return rcons->constraint;
}
else
{
REPORT( implicit ? _( "Membership not satisfied; constraint not applied." )
: _( "Condition not satisfied; rule not applied." ) )
REPORT( "" )
}
}
}
@ -562,10 +543,8 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI
}
void DRC_ENGINE::Report( const std::shared_ptr<DRC_ITEM>& aItem, MARKER_PCB *aMarker )
void DRC_ENGINE::ReportViolation( const std::shared_ptr<DRC_ITEM>& aItem, wxPoint aPos )
{
m_drcReport->AddItem( aItem, aMarker );
if( m_reporter )
{
wxString msg = wxString::Format( "Test '%s': %s (code %d)",
@ -582,13 +561,12 @@ void DRC_ENGINE::Report( const std::shared_ptr<DRC_ITEM>& aItem, MARKER_PCB *aMa
wxString violatingItemsStr = "Violating items: ";
if( aMarker )
{
m_reporter->Report( wxString::Format( " |- violating position (%d, %d)",
aMarker->GetPos().x,
aMarker->GetPos().y ) );
}
m_reporter->Report( wxString::Format( " |- violating position (%d, %d)",
aPos.x,
aPos.y ) );
}
m_violationHandler( aItem, aPos );
}
void DRC_ENGINE::ReportAux ( const wxString& aStr )
@ -652,7 +630,7 @@ std::vector<DRC_CONSTRAINT> DRC_ENGINE::QueryConstraintsById( DRC_CONSTRAINT_TYP
}
bool DRC_ENGINE::HasCorrectRulesForId( DRC_CONSTRAINT_TYPE_T constraintID )
bool DRC_ENGINE::HasRulesForConstraintType( 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;

View File

@ -24,31 +24,21 @@
#ifndef DRC_ENGINE_H
#define DRC_ENGINE_H
#include <board_commit.h>
#include <class_board.h>
#include <class_marker_pcb.h>
#include <class_track.h>
#include <geometry/seg.h>
#include <geometry/shape_poly_set.h>
#include <memory>
#include <tools/pcb_tool_base.h>
#include <vector>
#include <unordered_map>
#include <drc/drc_rule.h>
class BOARD_DESIGN_SETTINGS;
class DRC_TEST_PROVIDER;
class PCB_EDIT_FRAME;
class DIALOG_DRC;
class BOARD_ITEM;
class BOARD;
class D_PAD;
class ZONE_CONTAINER;
class TRACK;
class MARKER_PCB;
class NETCLASS;
class EDA_TEXT;
class DRAWSEGMENT;
class NETLIST;
class PROGRESS_REPORTER;
class REPORTER;
@ -75,34 +65,9 @@ enum DRC_CONSTRAINT_QUERY_T
// fixme: more to come I guess...
};
typedef
std::function<void( const std::shared_ptr<DRC_ITEM>& aItem, wxPoint aPos )> DRC_VIOLATION_HANDLER;
class DRC_REPORT
{
public:
struct ENTRY
{
std::shared_ptr<DRC_ITEM> m_item;
MARKER_PCB* m_marker;
};
typedef std::vector<ENTRY> ENTRIES;
DRC_REPORT() {};
~DRC_REPORT();
void AddItem( std::shared_ptr<DRC_ITEM> aItem, ::MARKER_PCB *aMarker = nullptr)
{
ENTRY ent;
ent.m_item = aItem;
ent.m_marker = aMarker;
m_entries.push_back(ent);
}
const ENTRIES& GetReportEntries() const { return m_entries; };
private:
ENTRIES m_entries;
};
/**
* Design Rule Checker object that performs all the DRC tests. The output of
@ -135,7 +100,7 @@ public:
void InitEngine( const wxFileName& aRulePath );
void RunTests();
void RunTests( DRC_VIOLATION_HANDLER aDRCItemHandler );
BOARD_DESIGN_SETTINGS* GetDesignSettings() const { return m_designSettings; }
@ -155,7 +120,7 @@ public:
std::vector<DRC_CONSTRAINT> QueryConstraintsById( DRC_CONSTRAINT_TYPE_T ruleID );
bool HasCorrectRulesForId( DRC_CONSTRAINT_TYPE_T ruleID );
bool HasRulesForConstraintType( DRC_CONSTRAINT_TYPE_T constraintID );
EDA_UNITS UserUnits() const
{
@ -171,13 +136,11 @@ public:
bool CompileRules();
void Report( const std::shared_ptr<DRC_ITEM>& aItem, MARKER_PCB *Marker );
void ReportViolation( const std::shared_ptr<DRC_ITEM>& aItem, wxPoint aPos );
void ReportProgress( double aProgress );
void ReportStage ( const wxString& aStageName, int index, int total );
void ReportAux( const wxString& aStr );
std::shared_ptr<DRC_REPORT> GetReport() const { return m_drcReport; }
bool QueryWorstConstraint( DRC_CONSTRAINT_TYPE_T aRuleId, DRC_CONSTRAINT& aConstraint,
DRC_CONSTRAINT_QUERY_T aQueryType );
@ -203,9 +166,9 @@ private:
DRC_TEST_PROVIDER* provider;
};
void inferLegacyRules();
void loadImplicitRules();
void loadTestProviders();
DRC_RULE* createInferredRule( const wxString& name, std::set<BOARD_ITEM*> items, int priority );
DRC_RULE* createImplicitRule( const wxString& name );
protected:
BOARD_DESIGN_SETTINGS* m_designSettings;
@ -213,21 +176,18 @@ protected:
KIGFX::WS_PROXY_VIEW_ITEM* m_worksheet;
NETLIST* m_schematicNetlist;
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::vector<int> m_errorLimits;
std::unordered_map<EDA_ITEM*, CONSTRAINT_SET*> m_implicitRules;
// constraint -> rule -> provider
std::unordered_map<DRC_CONSTRAINT_TYPE_T, CONSTRAINT_SET*> m_constraintMap;
DRC_VIOLATION_HANDLER m_violationHandler;
REPORTER* m_reporter;
PROGRESS_REPORTER* m_progressReporter;
// condition -> rule -> provider
wxString m_msg; // Allocating strings gets expensive enough to want to avoid it
};

View File

@ -23,9 +23,10 @@
#include <fctsys.h>
#include <class_board.h>
#include <class_board_item.h>
#include <drc/drc_rule.h>
#include <drc/drc_rule_condition.h>
#include <drc/drc_engine.h>
const DRC_CONSTRAINT* GetConstraint( const BOARD_ITEM* aItem, const BOARD_ITEM* bItem,
@ -78,9 +79,9 @@ const DRC_CONSTRAINT* GetConstraint( const BOARD_ITEM* aItem, const BOARD_ITEM*
DRC_RULE::DRC_RULE() :
m_Unary( false ),
m_Implicit( false ),
m_LayerCondition( LSET::AllLayersMask() ),
m_Condition( nullptr ),
m_Priority( 0 )
m_Condition( nullptr )
{
}

View File

@ -99,39 +99,21 @@ 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( const 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;
bool m_Implicit;
wxString m_Name;
wxString m_LayerSource;
LSET m_LayerCondition;
DRC_RULE_CONDITION* m_Condition;
std::vector<DRC_CONSTRAINT> m_Constraints;
int m_Priority; // 0 indicates automatic priority generation fixme: use enum
};
@ -156,9 +138,14 @@ class DRC_CONSTRAINT
wxString GetName() const
{
if( m_parentRule )
return wxString::Format( _( "rule %s" ), m_parentRule->m_Name );
else
return m_name;
{
if( m_parentRule->m_Implicit )
return m_parentRule->m_Name;
else
return wxString::Format( _( "rule %s" ), m_parentRule->m_Name );
}
return m_name;
}
public:

View File

@ -44,20 +44,13 @@ DRC_RULE_CONDITION::~DRC_RULE_CONDITION()
bool DRC_RULE_CONDITION::EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB,
PCB_LAYER_ID aLayer, REPORTER* aReporter )
{
#define REPORT( s ) { if( aReporter ) { aReporter->Report( s ); } }
if( GetExpression().IsEmpty() )
{
REPORT( _( "Unconditional constraint." ) );
return true;
}
REPORT( _( "Checking rule condition \"" + GetExpression() + "\"." ) );
if( !m_ucode )
{
REPORT( _( "ERROR in expression." ) );
if( aReporter )
aReporter->Report( _( "ERROR in expression." ) );
return false;
}
@ -69,12 +62,11 @@ bool DRC_RULE_CONDITION::EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM
ctx.SetItems( a, b );
ctx.SetErrorCallback( [&]( const wxString& aMessage, int aOffset )
{
REPORT( _( "ERROR: " ) + aMessage );
if( aReporter )
aReporter->Report( _( "ERROR: " ) + aMessage );
} );
return m_ucode->Run( &ctx )->AsDouble() != 0.0;
#undef REPORT
}

View File

@ -1,6 +1,33 @@
/*
* 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 <drc/drc_engine.h>
#include <drc/drc_item.h>
#include <drc/drc_test_provider.h>
#include <class_track.h>
#include <class_module.h>
#include <class_pad.h>
#include <class_zone.h>
DRC_TEST_PROVIDER::DRC_TEST_PROVIDER() :
m_drcEngine( nullptr )
@ -12,26 +39,10 @@ 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 )
void DRC_TEST_PROVIDER::ReportViolation( std::shared_ptr<DRC_ITEM> aItem, wxPoint aPos )
{
item->SetViolatingTest( this );
m_drcEngine->Report( item, nullptr );
}
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 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
aItem->SetViolatingTest( this );
m_drcEngine->ReportViolation( aItem, aPos );
}
@ -116,9 +127,6 @@ int DRC_TEST_PROVIDER::forEachGeometryItem( const std::vector<KICAD_T>& aTypes,
typeMask[ aType ] = true;
}
/* case PCB_TRACE_T:
case PCB_VIA_T:
case PCB_ARC_T:*/
for( TRACK* item : brd->Tracks() )
{
if( (item->GetLayerSet() & aLayers).any() )
@ -141,11 +149,6 @@ int DRC_TEST_PROVIDER::forEachGeometryItem( const std::vector<KICAD_T>& aTypes,
}
}
/* case PCB_DIMENSION_T:
case PCB_LINE_T:
case PCB_TEXT_T:
case PCB_TARGET_T:
*/
for( BOARD_ITEM* item : brd->Drawings() )
{
if( (item->GetLayerSet() & aLayers).any() )

View File

@ -93,14 +93,11 @@ public:
virtual const wxString GetDescription() const;
virtual void ReportAux( 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 );
virtual void ReportViolation( std::shared_ptr<DRC_ITEM> item, wxPoint aMarkerPos );
virtual void ReportProgress( double aProgress );
virtual void ReportStage ( const wxString& aStageName, int index, int total );
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const = 0;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetConstraintTypes() const = 0;
virtual bool IsRuleDriven() const
{

View File

@ -62,13 +62,13 @@ public:
return "Tests pad/via annular rings";
}
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetConstraintTypes() const override;
};
bool DRC_TEST_PROVIDER_ANNULUS::Run()
{
if( !m_drcEngine->HasCorrectRulesForId( DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH ) )
if( !m_drcEngine->HasRulesForConstraintType( DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH ) )
{
ReportAux( "No annulus constraints found. Skipping check." );
return false;
@ -125,7 +125,7 @@ bool DRC_TEST_PROVIDER_ANNULUS::Run()
drcItem->SetItems( item );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, via->GetPosition() );
ReportViolation( drcItem, via->GetPosition() );
}
return true;
@ -139,9 +139,9 @@ bool DRC_TEST_PROVIDER_ANNULUS::Run()
}
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_ANNULUS::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_ANNULUS::GetConstraintTypes() const
{
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH };
return { DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH };
}

View File

@ -65,7 +65,7 @@ public:
return "Tests board connectivity";
}
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetConstraintTypes() const override;
};
@ -100,7 +100,7 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( code );
drcItem->SetItems( track );
ReportWithMarker( drcItem, pos );
ReportViolation( drcItem, pos );
}
}
@ -125,7 +125,7 @@ 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() );
ReportViolation( drcItem, zone->GetPosition() );
}
}
@ -142,7 +142,7 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
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() );
ReportViolation( drcItem, (wxPoint) edge.GetSourceNode()->Pos() );
}
reportRuleStatistics();
@ -151,7 +151,7 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
}
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_CONNECTIVITY::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_CONNECTIVITY::GetConstraintTypes() const
{
return {};
}

View File

@ -73,7 +73,7 @@ public:
return "Tests copper item clearance";
}
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetConstraintTypes() const override;
private:
void testPadClearances();
@ -230,7 +230,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testCopperDrawItem( BOARD_ITEM* aItem )
drcItem->SetItems( track, aItem );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pos );
ReportViolation( drcItem, pos );
}
}
@ -273,7 +273,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testCopperDrawItem( BOARD_ITEM* aItem )
drcItem->SetItems( pad, aItem );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pad->GetPosition() );
ReportViolation( drcItem, pad->GetPosition() );
}
}
@ -369,7 +369,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, PCB_LAYER_I
drcItem->SetItems( aRefSeg, pad );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pad->GetPosition() );
ReportViolation( drcItem, pad->GetPosition() );
}
}
}
@ -424,7 +424,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, PCB_LAYER_I
drcItem->SetItems( aRefSeg, track );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, (wxPoint) intersection.get() );
ReportViolation( drcItem, (wxPoint) intersection.get() );
}
else if( refSeg.Collide( &trackSeg, minClearance - bds.GetDRCEpsilon(), &actual ) )
{
@ -440,7 +440,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, PCB_LAYER_I
drcItem->SetItems( aRefSeg, track );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pos );
ReportViolation( drcItem, pos );
}
}
@ -490,7 +490,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, PCB_LAYER_I
drcItem->SetItems( aRefSeg, zone );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, getLocation( aLayer, aRefSeg, zone ) );
ReportViolation( drcItem, getLocation( aLayer, aRefSeg, zone ) );
}
}
}
@ -589,7 +589,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::doPadToPadsDrc( D_PAD* aRefPad, D_PAD**
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( pad, aRefPad );
ReportWithMarker( drcItem, aRefPad->GetPosition() );
ReportViolation( drcItem, aRefPad->GetPosition() );
}
continue;
@ -630,7 +630,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::doPadToPadsDrc( D_PAD* aRefPad, D_PAD**
drcItem->SetItems( aRefPad, pad );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, aRefPad->GetPosition() );
ReportViolation( drcItem, aRefPad->GetPosition() );
break;
}
}
@ -711,7 +711,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZones()
drcItem->SetItems( zoneRef, zoneToTest );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pt );
ReportViolation( drcItem, pt );
}
}
@ -727,7 +727,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZones()
drcItem->SetItems( zoneToTest, zoneRef );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pt );
ReportViolation( drcItem, pt );
}
}
@ -799,16 +799,16 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZones()
drcItem->SetItems( zoneRef, zoneToTest );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, conflict.first );
ReportViolation( drcItem, conflict.first );
}
}
}
}
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_COPPER_CLEARANCE::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_COPPER_CLEARANCE::GetConstraintTypes() const
{
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_CLEARANCE };
return { DRC_CONSTRAINT_TYPE_CLEARANCE };
}

View File

@ -63,7 +63,7 @@ public:
return "Tests components' courtyard clearance";
}
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetConstraintTypes() const override;
private:
void testFootprintCourtyardDefinitions();
@ -89,7 +89,7 @@ void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testFootprintCourtyardDefinitions()
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_MISSING_COURTYARD );
drcItem->SetItems( footprint );
ReportWithMarker( drcItem, footprint->GetPosition() );
ReportViolation( drcItem, footprint->GetPosition() );
}
else
{
@ -108,7 +108,7 @@ void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testFootprintCourtyardDefinitions()
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( footprint );
ReportWithMarker( drcItem, footprint->GetPosition() );
ReportViolation( drcItem, footprint->GetPosition() );
}
}
}
@ -175,7 +175,7 @@ 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 );
ReportViolation( drcItem, pos );
}
}
}
@ -198,9 +198,9 @@ bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::Run()
}
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::GetConstraintTypes() const
{
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE };
return { DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE };
}

View File

@ -61,13 +61,13 @@ public:
return "Tests for disallowed items (e.g. keepouts)";
}
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetConstraintTypes() const override;
};
bool DRC_TEST_PROVIDER_DISALLOW::Run()
{
if( !m_drcEngine->HasCorrectRulesForId( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_DISALLOW ) )
if( !m_drcEngine->HasRulesForConstraintType( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_DISALLOW ) )
{
ReportAux( "No disallow constraints found. Skipping check." );
return false;
@ -93,7 +93,7 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
drcItem->SetItems( item );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, item->GetPosition() );
ReportViolation( drcItem, item->GetPosition() );
}
return true;
@ -107,9 +107,9 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
}
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_DISALLOW::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_DISALLOW::GetConstraintTypes() const
{
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_DISALLOW };
return { DRC_CONSTRAINT_TYPE_DISALLOW };
}

View File

@ -65,7 +65,7 @@ public:
return "Tests items vs board edge clearance";
}
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetConstraintTypes() const override;
};
@ -154,7 +154,7 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
drcItem->SetItems( outlineItem, boardItem );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, refShape->Centre() );
ReportViolation( drcItem, (wxPoint) refShape->Centre() );
}
}
}
@ -165,7 +165,7 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
}
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_EDGE_CLEARANCE::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_EDGE_CLEARANCE::GetConstraintTypes() const
{
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE };
}

View File

@ -65,7 +65,7 @@ public:
return "Tests clearance of holes (via/pad drills)";
}
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetConstraintTypes() const override;
private:
void addHole( const VECTOR2I& aLocation, int aRadius, BOARD_ITEM* aOwner );
@ -277,7 +277,7 @@ bool DRC_TEST_PROVIDER_HOLE_CLEARANCE::doPadToPadHoleDrc( D_PAD* aRefPad, D_PAD
drcItem->SetItems( pad, aRefPad );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pad->GetPosition() );
ReportViolation( drcItem, pad->GetPosition() );
return false;
}
}
@ -310,7 +310,7 @@ bool DRC_TEST_PROVIDER_HOLE_CLEARANCE::doPadToPadHoleDrc( D_PAD* aRefPad, D_PAD
drcItem->SetItems( aRefPad, pad );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, pad->GetPosition() );
ReportViolation( drcItem, pad->GetPosition() );
return false;
}
}
@ -395,16 +395,16 @@ void DRC_TEST_PROVIDER_HOLE_CLEARANCE::testHoles2Holes()
drcItem->SetItems( refHole.m_owner, checkHole.m_owner );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, refHole.m_location );
ReportViolation( drcItem, (wxPoint) refHole.m_location );
}
}
}
}
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_HOLE_CLEARANCE::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_HOLE_CLEARANCE::GetConstraintTypes() const
{
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE };
return { DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE };
}

View File

@ -62,7 +62,7 @@ public:
return "Tests sizes of drilled holes (via/pad drills)";
}
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetConstraintTypes() const override;
private:
void checkVia( VIA* via, bool aExceedMicro, bool aExceedStd );
@ -145,7 +145,7 @@ void DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( D_PAD* aPad )
drcItem->SetItems( aPad );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, aPad->GetPosition() );
ReportViolation( drcItem, aPad->GetPosition() );
}
}
@ -187,14 +187,14 @@ void DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via, bool aExceedMicro, bool aE
drcItem->SetItems( via );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, via->GetPosition() );
ReportViolation( drcItem, via->GetPosition() );
}
}
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_HOLE_SIZE::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_HOLE_SIZE::GetConstraintTypes() const
{
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE };
return { DRC_CONSTRAINT_TYPE_HOLE_SIZE };
}

View File

@ -68,7 +68,7 @@ public:
return "Performs layout-vs-schematics integity check";
}
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetConstraintTypes() const override;
private:
@ -101,7 +101,7 @@ void DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_DUPLICATE_FOOTPRINT );
drcItem->SetItems( mod, *ins.first );
ReportWithMarker( drcItem, mod->GetPosition() );
ReportViolation( drcItem, mod->GetPosition() );
}
}
@ -123,7 +123,7 @@ void DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_MISSING_FOOTPRINT );
drcItem->SetErrorMessage( m_msg );
Report( drcItem );
ReportViolation( drcItem, wxPoint() );
}
else
{
@ -142,7 +142,7 @@ void DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_NET_CONFLICT );
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( pad );
ReportWithMarker( drcItem, module->GetPosition() );
ReportViolation( drcItem, module->GetPosition() );
}
else if( pcb_netname.IsEmpty() && !sch_net.GetNetName().IsEmpty() )
{
@ -152,7 +152,7 @@ void DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_NET_CONFLICT );
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( pad );
ReportWithMarker( drcItem, module->GetPosition() );
ReportViolation( drcItem, module->GetPosition() );
}
else if( pcb_netname != sch_net.GetNetName() )
{
@ -163,7 +163,7 @@ void DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_NET_CONFLICT );
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( pad );
ReportWithMarker( drcItem, module->GetPosition() );
ReportViolation( drcItem, module->GetPosition() );
}
}
@ -182,7 +182,7 @@ void DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_NET_CONFLICT );
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( module );
ReportWithMarker( drcItem, module->GetPosition() );
ReportViolation( drcItem, module->GetPosition() );
}
}
}
@ -199,7 +199,7 @@ void DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_EXTRA_FOOTPRINT );
drcItem->SetItems( module );
ReportWithMarker( drcItem, module->GetPosition() );
ReportViolation( drcItem, module->GetPosition() );
}
}
}
@ -256,7 +256,7 @@ bool DRC_TEST_PROVIDER_LVS::Run()
}
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_LVS::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_LVS::GetConstraintTypes() const
{
return {};
}

View File

@ -66,7 +66,7 @@ public:
return "Misc checks (board outline, missing textvars)";
}
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetConstraintTypes() const override;
private:
void testOutline();
@ -93,7 +93,7 @@ void DRC_TEST_PROVIDER_MISC::testOutline()
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( m_board );
ReportWithMarker( drcItem, error_loc );
ReportViolation( drcItem, error_loc );
}
@ -119,7 +119,7 @@ void DRC_TEST_PROVIDER_MISC::testDisabledLayers()
drcItem->SetErrorMessage( m_msg );
drcItem->SetItems( item );
ReportWithMarker( drcItem, item->GetPosition() );
ReportViolation( drcItem, item->GetPosition() );
}
return true;
};
@ -144,7 +144,7 @@ void DRC_TEST_PROVIDER_MISC::testTextVars()
std::shared_ptr<DRC_ITEM>drcItem = DRC_ITEM::Create( DRCE_UNRESOLVED_VARIABLE );
drcItem->SetItems( item );
ReportWithMarker( drcItem, item->GetPosition() );
ReportViolation( drcItem, item->GetPosition() );
}
return true;
};
@ -179,7 +179,7 @@ void DRC_TEST_PROVIDER_MISC::testTextVars()
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_UNRESOLVED_VARIABLE );
drcItem->SetItems( text );
ReportWithMarker( drcItem, text->GetPosition() );
ReportViolation( drcItem, text->GetPosition() );
}
}
}
@ -202,7 +202,7 @@ bool DRC_TEST_PROVIDER_MISC::Run()
}
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_MISC::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_MISC::GetConstraintTypes() const
{
return {};
}

View File

@ -59,13 +59,13 @@ public:
return "Tests track widths";
}
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetConstraintTypes() const override;
};
bool DRC_TEST_PROVIDER_TRACK_WIDTH::Run()
{
if( !m_drcEngine->HasCorrectRulesForId( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_TRACK_WIDTH ) )
if( !m_drcEngine->HasRulesForConstraintType( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_TRACK_WIDTH ) )
{
ReportAux( "No track width constraints found. Skipping check." );
return false;
@ -79,8 +79,8 @@ bool DRC_TEST_PROVIDER_TRACK_WIDTH::Run()
if( m_drcEngine->IsErrorLimitExceeded( DRCE_TRACK_WIDTH ) )
return false;
int actual;
VECTOR2I p0;
int actual;
wxPoint p0;
if( ARC* arc = dyn_cast<ARC*>( item ) )
{
@ -125,7 +125,7 @@ bool DRC_TEST_PROVIDER_TRACK_WIDTH::Run()
drcItem->SetItems( item );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, p0 );
ReportViolation( drcItem, p0 );
}
return true;
@ -139,9 +139,9 @@ bool DRC_TEST_PROVIDER_TRACK_WIDTH::Run()
}
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_TRACK_WIDTH::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_TRACK_WIDTH::GetConstraintTypes() const
{
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_TRACK_WIDTH };
return { DRC_CONSTRAINT_TYPE_TRACK_WIDTH };
}

View File

@ -60,13 +60,13 @@ public:
return "Tests via diameters";
}
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetConstraintTypes() const override;
};
bool DRC_TEST_PROVIDER_VIA_DIAMETER::Run()
{
if( !m_drcEngine->HasCorrectRulesForId( DRC_CONSTRAINT_TYPE_VIA_DIAMETER ) )
if( !m_drcEngine->HasRulesForConstraintType( DRC_CONSTRAINT_TYPE_VIA_DIAMETER ) )
{
ReportAux( "No diameter constraints found. Skipping check." );
return false;
@ -119,7 +119,7 @@ bool DRC_TEST_PROVIDER_VIA_DIAMETER::Run()
drcItem->SetItems( item );
drcItem->SetViolatingRule( constraint.GetParentRule() );
ReportWithMarker( drcItem, via->GetPosition() );
ReportViolation( drcItem, via->GetPosition() );
}
return true;
@ -133,9 +133,9 @@ bool DRC_TEST_PROVIDER_VIA_DIAMETER::Run()
}
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_VIA_DIAMETER::GetMatchingConstraintIds() const
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_VIA_DIAMETER::GetConstraintTypes() const
{
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_VIA_DIAMETER };
return { DRC_CONSTRAINT_TYPE_VIA_DIAMETER };
}

View File

@ -30,6 +30,7 @@
#include <pcbnew_utils/board_file_utils.h>
#include <pcbnew/drc/drc_engine.h>
#include <pcbnew/class_board.h>
#include <pcbnew/drc/drc_rule_parser.h>
#include <reporter.h>
#include <widgets/progress_reporter.h>
@ -159,6 +160,35 @@ private:
};
class DRC_REPORT
{
public:
struct ENTRY
{
std::shared_ptr<DRC_ITEM> m_item;
MARKER_PCB* m_marker;
};
typedef std::vector<ENTRY> ENTRIES;
DRC_REPORT() {};
~DRC_REPORT();
void AddItem( std::shared_ptr<DRC_ITEM> aItem, MARKER_PCB *aMarker = nullptr )
{
ENTRY ent;
ent.m_item = aItem;
ent.m_marker = aMarker;
m_entries.push_back(ent);
}
const ENTRIES& GetReportEntries() const { return m_entries; };
private:
ENTRIES m_entries;
};
struct PROJECT_CONTEXT {
PROJECT* project;
std::shared_ptr<BOARD> board;
@ -215,9 +245,10 @@ int main( int argc, char *argv[] )
drcEngine.InitEngine( rulesFilepath );
drcEngine.RunTests();
auto report = drcEngine.GetReport();
drcEngine.RunTests(
[&]( const std::shared_ptr<DRC_ITEM>& aItem, wxPoint aPos )
{
} );
return 0;
}

View File

@ -73,7 +73,7 @@ public:
return "Tests for silkscreen covering components pads";
}
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetConstraintTypes() const override;
private:
};
@ -147,7 +147,7 @@ bool test::DRC_TEST_PROVIDER_SILK_TO_PAD::Run()
drcItem->SetItems( outlineItem, boardItem );
drcItem->SetViolatingRule( rule );
ReportWithMarker( drcItem, refShape->Centre() );
ReportViolation( drcItem, refShape->Centre() );
}
}
}