mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-04-20 23:11:41 +00:00
Custom rule severities.
ADDED severity token to custom rule syntax. Each rule can now define its own severity. Fixes https://gitlab.com/kicad/code/kicad/issues/6148
This commit is contained in:
parent
fcb013e5d7
commit
5f37c2b247
common
include
pcbnew
board.cpp
dialogs
drc
drc_engine.cppdrc_engine.hdrc_results_provider.cppdrc_rule.cppdrc_rule.hdrc_rule_parser.cppdrc_rule_parser.hdrc_test_provider.hdrc_test_provider_annular_width.cppdrc_test_provider_connectivity.cppdrc_test_provider_copper_clearance.cppdrc_test_provider_courtyard_clearance.cppdrc_test_provider_diff_pair_coupling.cppdrc_test_provider_disallow.cppdrc_test_provider_edge_clearance.cppdrc_test_provider_hole_size.cppdrc_test_provider_hole_to_hole.cppdrc_test_provider_library_parity.cppdrc_test_provider_matched_length.cppdrc_test_provider_mechanical_clearance.cppdrc_test_provider_misc.cppdrc_test_provider_schematic_parity.cppdrc_test_provider_silk_clearance.cppdrc_test_provider_sliver_checker.cppdrc_test_provider_solder_mask.cppdrc_test_provider_text_dims.cppdrc_test_provider_track_width.cppdrc_test_provider_via_diameter.cppdrc_test_provider_zone_connections.cpp
pcb_display_options.cpppcb_edit_frame.cpppcb_marker.cpppcb_marker.hpython/scripting
qa
@ -9,12 +9,15 @@ diff_pair_gap
|
||||
diff_pair_uncoupled
|
||||
disallow
|
||||
edge_clearance
|
||||
error
|
||||
exclusion
|
||||
footprint
|
||||
graphic
|
||||
hole
|
||||
hole_clearance
|
||||
hole_size
|
||||
hole_to_hole
|
||||
ignore
|
||||
inner
|
||||
layer
|
||||
length
|
||||
@ -31,6 +34,7 @@ outer
|
||||
pad
|
||||
pth
|
||||
rule
|
||||
severity
|
||||
silk_clearance
|
||||
skew
|
||||
solid
|
||||
@ -46,5 +50,6 @@ version
|
||||
via
|
||||
via_count
|
||||
via_diameter
|
||||
warning
|
||||
zone
|
||||
zone_connection
|
||||
|
@ -83,10 +83,11 @@ wxString RC_ITEM::ShowReport( EDA_UNITS aUnits, SEVERITY aSeverity,
|
||||
|
||||
switch( aSeverity )
|
||||
{
|
||||
case RPT_SEVERITY_ERROR: severity = wxT( "Severity: error" ); break;
|
||||
case RPT_SEVERITY_WARNING: severity = wxT( "Severity: warning" ); break;
|
||||
case RPT_SEVERITY_ACTION: severity = wxT( "Severity: action" ); break;
|
||||
case RPT_SEVERITY_INFO: severity = wxT( "Severity: info" ); break;
|
||||
case RPT_SEVERITY_ERROR: severity = wxT( "Severity: error" ); break;
|
||||
case RPT_SEVERITY_WARNING: severity = wxT( "Severity: warning" ); break;
|
||||
case RPT_SEVERITY_ACTION: severity = wxT( "Severity: action" ); break;
|
||||
case RPT_SEVERITY_INFO: severity = wxT( "Severity: info" ); break;
|
||||
case RPT_SEVERITY_EXCLUSION: severity = wxT( "Severity: exclusion" ); break;
|
||||
default: ;
|
||||
};
|
||||
|
||||
@ -349,20 +350,25 @@ void RC_TREE_MODEL::GetValue( wxVariant& aVariant,
|
||||
{
|
||||
wxString prefix;
|
||||
|
||||
if( rcItem->GetParent() && rcItem->GetParent()->IsExcluded() )
|
||||
prefix = _( "Excluded " );
|
||||
|
||||
switch( m_editFrame->GetSeverity( rcItem->GetErrorCode() ) )
|
||||
if( rcItem->GetParent() )
|
||||
{
|
||||
case RPT_SEVERITY_ERROR: prefix += _( "Error: " ); break;
|
||||
case RPT_SEVERITY_WARNING: prefix += _( "Warning: " ); break;
|
||||
SEVERITY severity = rcItem->GetParent()->GetSeverity();
|
||||
|
||||
case RPT_SEVERITY_EXCLUSION:
|
||||
case RPT_SEVERITY_UNDEFINED:
|
||||
case RPT_SEVERITY_INFO:
|
||||
case RPT_SEVERITY_ACTION:
|
||||
case RPT_SEVERITY_IGNORE:
|
||||
break;
|
||||
if( severity == RPT_SEVERITY_EXCLUSION )
|
||||
{
|
||||
if( m_editFrame->GetSeverity( rcItem->GetErrorCode() ) == RPT_SEVERITY_WARNING )
|
||||
prefix = _( "Excluded warning: " );
|
||||
else
|
||||
prefix = _( "Excluded error: " );
|
||||
}
|
||||
else if( severity == RPT_SEVERITY_WARNING )
|
||||
{
|
||||
prefix = _( "Warning: " );
|
||||
}
|
||||
else
|
||||
{
|
||||
prefix = _( "Error: " );
|
||||
}
|
||||
}
|
||||
|
||||
aVariant = prefix + rcItem->GetErrorMessage();
|
||||
@ -416,7 +422,8 @@ bool RC_TREE_MODEL::GetAttr( wxDataViewItem const& aItem,
|
||||
ret = true;
|
||||
}
|
||||
|
||||
if( node->m_RcItem->GetParent() && node->m_RcItem->GetParent()->IsExcluded() )
|
||||
if( node->m_RcItem->GetParent()
|
||||
&& node->m_RcItem->GetParent()->GetSeverity() == RPT_SEVERITY_EXCLUSION )
|
||||
{
|
||||
wxColour textColour = wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOXTEXT );
|
||||
double brightness = KIGFX::COLOR4D( textColour ).GetBrightness();
|
||||
@ -493,7 +500,10 @@ void RC_TREE_MODEL::DeleteItems( bool aCurrentOnly, bool aIncludeExclusions, boo
|
||||
{
|
||||
std::shared_ptr<RC_ITEM> rcItem = m_rcItemsProvider->GetItem( i );
|
||||
MARKER_BASE* marker = rcItem->GetParent();
|
||||
bool excluded = marker ? marker->IsExcluded() : false;
|
||||
bool excluded = false;
|
||||
|
||||
if( marker && marker->GetSeverity() == RPT_SEVERITY_EXCLUSION )
|
||||
excluded = true;
|
||||
|
||||
if( aCurrentOnly && itemDeleted && lastGood >= 0 )
|
||||
break;
|
||||
|
@ -95,6 +95,8 @@ public:
|
||||
bool IsExcluded() const { return m_excluded; }
|
||||
void SetExcluded( bool aExcluded ) { m_excluded = aExcluded; }
|
||||
|
||||
virtual SEVERITY GetSeverity() const { return RPT_SEVERITY_UNDEFINED; }
|
||||
|
||||
/**
|
||||
* @return the #RC_ITEM held within this marker so that its interface may be used.
|
||||
*/
|
||||
|
@ -18,11 +18,11 @@
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _REPORT_SEVERITY_H_
|
||||
#define _REPORT_SEVERITY_H_
|
||||
#ifndef REPORT_SEVERITY_H
|
||||
#define REPORT_SEVERITY_H
|
||||
|
||||
// Note: On windows, SEVERITY_ERROR collides with a system declaration,
|
||||
// so we used RPT_SEVERITY _xxx instead of SEVERITY _xxx
|
||||
// so we used RPT_SEVERITY_xxx instead of SEVERITY_xxx
|
||||
enum SEVERITY {
|
||||
RPT_SEVERITY_UNDEFINED = 0x00,
|
||||
RPT_SEVERITY_INFO = 0x01,
|
||||
@ -33,4 +33,4 @@ enum SEVERITY {
|
||||
RPT_SEVERITY_IGNORE = 0x20
|
||||
};
|
||||
|
||||
#endif // _REPORT_SEVERITY_H_
|
||||
#endif // REPORT_SEVERITY_H
|
||||
|
@ -823,8 +823,8 @@ void BOARD::DeleteMARKERs( bool aWarningsAndErrors, bool aExclusions )
|
||||
|
||||
for( PCB_MARKER* marker : m_markers )
|
||||
{
|
||||
if( ( marker->IsExcluded() && aExclusions )
|
||||
|| ( !marker->IsExcluded() && aWarningsAndErrors ) )
|
||||
if( ( marker->GetSeverity() == RPT_SEVERITY_EXCLUSION && aExclusions )
|
||||
|| ( marker->GetSeverity() != RPT_SEVERITY_EXCLUSION && aWarningsAndErrors ) )
|
||||
{
|
||||
delete marker;
|
||||
}
|
||||
|
@ -822,7 +822,7 @@ void DIALOG_DRC::ExcludeMarker()
|
||||
RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( m_markerDataView->GetCurrentItem() );
|
||||
PCB_MARKER* marker = dynamic_cast<PCB_MARKER*>( node->m_RcItem->GetParent() );
|
||||
|
||||
if( marker && !marker->IsExcluded() )
|
||||
if( marker && !marker->GetSeverity() == RPT_SEVERITY_EXCLUSION )
|
||||
{
|
||||
marker->SetExcluded( true );
|
||||
m_frame->GetCanvas()->GetView()->Update( marker );
|
||||
@ -876,7 +876,10 @@ bool DIALOG_DRC::writeReport( const wxString& aFullFileName )
|
||||
for( int i = 0; i < count; ++i )
|
||||
{
|
||||
const std::shared_ptr<RC_ITEM>& item = m_markersProvider->GetItem( i );
|
||||
SEVERITY severity = bds.GetSeverity( item->GetErrorCode() );
|
||||
SEVERITY severity = item->GetParent()->GetSeverity();
|
||||
|
||||
if( severity == RPT_SEVERITY_EXCLUSION )
|
||||
severity = bds.GetSeverity( item->GetErrorCode() );
|
||||
|
||||
fprintf( fp, "%s", TO_UTF8( item->ShowReport( units, severity, itemMap ) ) );
|
||||
}
|
||||
|
@ -240,7 +240,7 @@ void DIALOG_PLOT::reInitDialog()
|
||||
|
||||
for( PCB_MARKER* marker : m_parent->GetBoard()->Markers() )
|
||||
{
|
||||
if( marker->IsExcluded() )
|
||||
if( marker->GetSeverity() == RPT_SEVERITY_EXCLUSION )
|
||||
exclusions++;
|
||||
else
|
||||
knownViolations++;
|
||||
|
@ -275,7 +275,8 @@ void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent )
|
||||
{
|
||||
tokens = "condition|"
|
||||
"constraint|"
|
||||
"layer";
|
||||
"layer|"
|
||||
"severity";
|
||||
}
|
||||
else if( sexprs.top() == "constraint" )
|
||||
{
|
||||
@ -345,6 +346,13 @@ void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent )
|
||||
{
|
||||
tokens = "warning|error|ignore|exclusion";
|
||||
}
|
||||
else if( sexprs.top() == "severity" )
|
||||
{
|
||||
tokens = "error "
|
||||
"exclusion "
|
||||
"ignore "
|
||||
"warning";
|
||||
}
|
||||
}
|
||||
else if( context == STRING && !sexprs.empty() && sexprs.top() == "condition" )
|
||||
{
|
||||
|
@ -15,6 +15,8 @@
|
||||
|
||||
(layer "<layer_name>")
|
||||
|
||||
(severity <severity_name>)
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
@ -69,6 +71,15 @@ Note: `clearance` and `hole_clearance` rules are not run against items of the sa
|
||||
|
||||
<br>
|
||||
|
||||
### Severity Names
|
||||
|
||||
* warning
|
||||
* error
|
||||
* exclusion
|
||||
* ignore
|
||||
|
||||
<br>
|
||||
|
||||
### Examples
|
||||
|
||||
(version 1)
|
||||
|
@ -42,6 +42,11 @@
|
||||
#include <geometry/shape_null.h>
|
||||
|
||||
|
||||
// wxListBox's performance degrades horrifically with very large datasets. It's not clear
|
||||
// they're useful to the user anyway.
|
||||
#define ERROR_LIMIT_MAX 199
|
||||
|
||||
|
||||
void drcPrintDebugMessage( int level, const wxString& msg, const char *function, int line )
|
||||
{
|
||||
wxString valueStr;
|
||||
@ -73,7 +78,7 @@ DRC_ENGINE::DRC_ENGINE( BOARD* aBoard, BOARD_DESIGN_SETTINGS *aSettings ) :
|
||||
m_errorLimits.resize( DRCE_LAST + 1 );
|
||||
|
||||
for( int ii = DRCE_FIRST; ii <= DRCE_LAST; ++ii )
|
||||
m_errorLimits[ ii ] = INT_MAX;
|
||||
m_errorLimits[ ii ] = ERROR_LIMIT_MAX;
|
||||
}
|
||||
|
||||
|
||||
@ -502,43 +507,28 @@ void DRC_ENGINE::compileRules()
|
||||
{
|
||||
ReportAux( wxString::Format( "Compiling Rules (%d rules): ", (int) m_rules.size() ) );
|
||||
|
||||
std::set<DRC_CONSTRAINT_T> constraintTypes;
|
||||
|
||||
for( DRC_TEST_PROVIDER* provider : m_testProviders )
|
||||
for( DRC_RULE* rule : m_rules )
|
||||
{
|
||||
for( DRC_CONSTRAINT_T constraintType : provider->GetConstraintTypes() )
|
||||
constraintTypes.insert( constraintType );
|
||||
}
|
||||
DRC_RULE_CONDITION* condition = nullptr;
|
||||
|
||||
for( DRC_CONSTRAINT_T constraintType : constraintTypes )
|
||||
{
|
||||
if( m_constraintMap.find( constraintType ) == m_constraintMap.end() )
|
||||
m_constraintMap[ constraintType ] = new std::vector<DRC_ENGINE_CONSTRAINT*>();
|
||||
|
||||
for( DRC_RULE* rule : m_rules )
|
||||
if( rule->m_Condition && !rule->m_Condition->GetExpression().IsEmpty() )
|
||||
{
|
||||
DRC_RULE_CONDITION* condition = nullptr;
|
||||
condition = rule->m_Condition;
|
||||
condition->Compile( nullptr );
|
||||
}
|
||||
|
||||
if( rule->m_Condition && !rule->m_Condition->GetExpression().IsEmpty() )
|
||||
{
|
||||
condition = rule->m_Condition;
|
||||
condition->Compile( nullptr, 0, 0 ); // fixme
|
||||
}
|
||||
for( const DRC_CONSTRAINT& constraint : rule->m_Constraints )
|
||||
{
|
||||
if( !m_constraintMap.count( constraint.m_Type ) )
|
||||
m_constraintMap[ constraint.m_Type ] = new std::vector<DRC_ENGINE_CONSTRAINT*>();
|
||||
|
||||
for( const DRC_CONSTRAINT& constraint : rule->m_Constraints )
|
||||
{
|
||||
if( constraint.m_Type == constraintType )
|
||||
{
|
||||
DRC_ENGINE_CONSTRAINT* engineConstraint = new DRC_ENGINE_CONSTRAINT;
|
||||
DRC_ENGINE_CONSTRAINT* engineConstraint = new DRC_ENGINE_CONSTRAINT;
|
||||
|
||||
engineConstraint->layerTest = rule->m_LayerCondition;
|
||||
engineConstraint->condition = condition;
|
||||
|
||||
engineConstraint->constraint = constraint;
|
||||
engineConstraint->parentRule = rule;
|
||||
m_constraintMap[ constraintType ]->push_back( engineConstraint );
|
||||
}
|
||||
}
|
||||
engineConstraint->layerTest = rule->m_LayerCondition;
|
||||
engineConstraint->condition = condition;
|
||||
engineConstraint->constraint = constraint;
|
||||
engineConstraint->parentRule = rule;
|
||||
m_constraintMap[ constraint.m_Type ]->push_back( engineConstraint );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -594,7 +584,7 @@ void DRC_ENGINE::InitEngine( const wxFileName& aRulePath )
|
||||
}
|
||||
|
||||
for( int ii = DRCE_FIRST; ii < DRCE_LAST; ++ii )
|
||||
m_errorLimits[ ii ] = INT_MAX;
|
||||
m_errorLimits[ ii ] = ERROR_LIMIT_MAX;
|
||||
|
||||
m_rulesValid = true;
|
||||
}
|
||||
@ -612,7 +602,7 @@ void DRC_ENGINE::RunTests( EDA_UNITS aUnits, bool aReportAllTrackErrors, bool aT
|
||||
if( m_designSettings->Ignore( ii ) )
|
||||
m_errorLimits[ ii ] = 0;
|
||||
else
|
||||
m_errorLimits[ ii ] = INT_MAX;
|
||||
m_errorLimits[ ii ] = ERROR_LIMIT_MAX;
|
||||
}
|
||||
|
||||
m_board->IncrementTimeStamp(); // Invalidate all caches
|
||||
@ -670,15 +660,13 @@ void DRC_ENGINE::RunTests( EDA_UNITS aUnits, bool aReportAllTrackErrors, bool aT
|
||||
|
||||
for( DRC_TEST_PROVIDER* provider : m_testProviders )
|
||||
{
|
||||
if( !provider->IsEnabled() )
|
||||
continue;
|
||||
if( provider->IsEnabled() )
|
||||
{
|
||||
ReportAux( wxString::Format( "Run DRC provider: '%s'", provider->GetName() ) );
|
||||
|
||||
drc_dbg( 0, "Running test provider: '%s'\n", provider->GetName() );
|
||||
|
||||
ReportAux( wxString::Format( "Run DRC provider: '%s'", provider->GetName() ) );
|
||||
|
||||
if( !provider->Run() )
|
||||
break;
|
||||
if( !provider->Run() )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,6 @@ public:
|
||||
*/
|
||||
void RunTests( EDA_UNITS aUnits, bool aReportAllTrackErrors, bool aTestFootprints );
|
||||
|
||||
|
||||
bool IsErrorLimitExceeded( int error_code );
|
||||
|
||||
DRC_CONSTRAINT EvalRules( DRC_CONSTRAINT_T aConstraintType, const BOARD_ITEM* a,
|
||||
@ -168,7 +167,7 @@ public:
|
||||
|
||||
bool QueryWorstConstraint( DRC_CONSTRAINT_T aRuleId, DRC_CONSTRAINT& aConstraint );
|
||||
|
||||
std::vector<DRC_TEST_PROVIDER* > GetTestProviders() const { return m_testProviders; };
|
||||
std::vector<DRC_TEST_PROVIDER*> GetTestProviders() const { return m_testProviders; };
|
||||
|
||||
DRC_TEST_PROVIDER* GetTestProvider( const wxString& name ) const;
|
||||
|
||||
|
@ -28,20 +28,11 @@ void BOARD_DRC_ITEMS_PROVIDER::SetSeverities( int aSeverities )
|
||||
{
|
||||
m_severities = aSeverities;
|
||||
|
||||
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
||||
|
||||
m_filteredMarkers.clear();
|
||||
|
||||
for( PCB_MARKER* marker : m_board->Markers() )
|
||||
{
|
||||
SEVERITY markerSeverity;
|
||||
|
||||
if( marker->IsExcluded() )
|
||||
markerSeverity = RPT_SEVERITY_EXCLUSION;
|
||||
else
|
||||
markerSeverity = bds.GetSeverity( marker->GetRCItem()->GetErrorCode() );
|
||||
|
||||
if( markerSeverity & m_severities )
|
||||
if( marker->GetSeverity() & m_severities )
|
||||
m_filteredMarkers.push_back( marker );
|
||||
}
|
||||
}
|
||||
@ -52,20 +43,11 @@ int BOARD_DRC_ITEMS_PROVIDER::GetCount( int aSeverity ) const
|
||||
if( aSeverity < 0 )
|
||||
return m_filteredMarkers.size();
|
||||
|
||||
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
||||
|
||||
int count = 0;
|
||||
|
||||
for( PCB_MARKER* marker : m_board->Markers() )
|
||||
{
|
||||
SEVERITY markerSeverity;
|
||||
|
||||
if( marker->IsExcluded() )
|
||||
markerSeverity = RPT_SEVERITY_EXCLUSION;
|
||||
else
|
||||
markerSeverity = bds.GetSeverity( marker->GetRCItem()->GetErrorCode() );
|
||||
|
||||
if( markerSeverity == aSeverity )
|
||||
if( marker->GetSeverity() == aSeverity )
|
||||
count++;
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,8 @@ DRC_RULE::DRC_RULE() :
|
||||
m_Unary( false ),
|
||||
m_Implicit( false ),
|
||||
m_LayerCondition( LSET::AllLayersMask() ),
|
||||
m_Condition( nullptr )
|
||||
m_Condition( nullptr ),
|
||||
m_Severity( RPT_SEVERITY_UNDEFINED )
|
||||
{
|
||||
}
|
||||
|
||||
@ -42,7 +43,8 @@ DRC_RULE::DRC_RULE( const wxString& aName ) :
|
||||
m_Implicit( false ),
|
||||
m_Name( aName ),
|
||||
m_LayerCondition( LSET::AllLayersMask() ),
|
||||
m_Condition( nullptr )
|
||||
m_Condition( nullptr ),
|
||||
m_Severity( RPT_SEVERITY_UNDEFINED )
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <zones.h>
|
||||
#include <libeval_compiler/libeval_compiler.h>
|
||||
#include <wx/intl.h>
|
||||
#include <widgets/report_severity.h>
|
||||
|
||||
class BOARD_ITEM;
|
||||
class PCB_EXPR_UCODE;
|
||||
@ -109,6 +110,7 @@ public:
|
||||
LSET m_LayerCondition;
|
||||
DRC_RULE_CONDITION* m_Condition;
|
||||
std::vector<DRC_CONSTRAINT> m_Constraints;
|
||||
SEVERITY m_Severity;
|
||||
};
|
||||
|
||||
|
||||
@ -152,6 +154,14 @@ class DRC_CONSTRAINT
|
||||
return m_name;
|
||||
}
|
||||
|
||||
SEVERITY GetSeverity() const
|
||||
{
|
||||
if( m_parentRule )
|
||||
return m_parentRule->m_Severity;
|
||||
else
|
||||
return RPT_SEVERITY_UNDEFINED;
|
||||
}
|
||||
|
||||
public:
|
||||
DRC_CONSTRAINT_T m_Type;
|
||||
MINOPTMAX<int> m_Value;
|
||||
|
@ -226,6 +226,10 @@ DRC_RULE* DRC_RULES_PARSER::parseDRC_RULE()
|
||||
rule->m_LayerCondition = parseLayer();
|
||||
break;
|
||||
|
||||
case T_severity:
|
||||
rule->m_Severity = parseSeverity();
|
||||
break;
|
||||
|
||||
case T_EOF:
|
||||
reportError( _( "Incomplete statement." ) );
|
||||
return rule;
|
||||
@ -575,3 +579,38 @@ LSET DRC_RULES_PARSER::parseLayer()
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
SEVERITY DRC_RULES_PARSER::parseSeverity()
|
||||
{
|
||||
SEVERITY retVal = RPT_SEVERITY_UNDEFINED;
|
||||
wxString msg;
|
||||
|
||||
T token = NextTok();
|
||||
|
||||
if( (int) token == DSN_RIGHT || token == T_EOF )
|
||||
{
|
||||
reportError( _( "Missing severity name." ) );
|
||||
return RPT_SEVERITY_UNDEFINED;
|
||||
}
|
||||
|
||||
switch( token )
|
||||
{
|
||||
case T_ignore: retVal = RPT_SEVERITY_IGNORE; break;
|
||||
case T_warning: retVal = RPT_SEVERITY_WARNING; break;
|
||||
case T_error: retVal = RPT_SEVERITY_ERROR; break;
|
||||
case T_exclusion: retVal = RPT_SEVERITY_EXCLUSION; break;
|
||||
|
||||
default:
|
||||
msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ),
|
||||
FromUTF8(),
|
||||
"ignore, warning, error or exclusion" );
|
||||
reportError( msg );
|
||||
parseUnknown();
|
||||
}
|
||||
|
||||
if( (int) NextTok() != DSN_RIGHT )
|
||||
reportError( _( "Missing ')'." ) );
|
||||
|
||||
return retVal;
|
||||
}
|
@ -51,6 +51,7 @@ private:
|
||||
void parseConstraint( DRC_RULE* aRule );
|
||||
void parseValueWithUnits( const wxString& aExpr, int& aResult );
|
||||
LSET parseLayer();
|
||||
SEVERITY parseSeverity();
|
||||
void parseUnknown();
|
||||
|
||||
void reportError( const wxString& aMessage );
|
||||
|
@ -89,8 +89,6 @@ public:
|
||||
virtual const wxString GetName() const;
|
||||
virtual const wxString GetDescription() const;
|
||||
|
||||
virtual std::set<DRC_CONSTRAINT_T> GetConstraintTypes() const = 0;
|
||||
|
||||
bool IsEnabled() const
|
||||
{
|
||||
return m_enabled;
|
||||
|
@ -61,8 +61,6 @@ public:
|
||||
{
|
||||
return "Tests pad/via annular rings";
|
||||
}
|
||||
|
||||
virtual std::set<DRC_CONSTRAINT_T> GetConstraintTypes() const override;
|
||||
};
|
||||
|
||||
|
||||
@ -106,6 +104,9 @@ bool DRC_TEST_PROVIDER_ANNULAR_WIDTH::Run()
|
||||
bool fail_min = false;
|
||||
bool fail_max = false;
|
||||
|
||||
if( constraint.GetSeverity() == RPT_SEVERITY_IGNORE )
|
||||
return true;
|
||||
|
||||
if( constraint.Value().HasMin() )
|
||||
{
|
||||
v_min = constraint.Value().Min();
|
||||
@ -162,12 +163,6 @@ bool DRC_TEST_PROVIDER_ANNULAR_WIDTH::Run()
|
||||
}
|
||||
|
||||
|
||||
std::set<DRC_CONSTRAINT_T> DRC_TEST_PROVIDER_ANNULAR_WIDTH::GetConstraintTypes() const
|
||||
{
|
||||
return { ANNULAR_WIDTH_CONSTRAINT };
|
||||
}
|
||||
|
||||
|
||||
namespace detail
|
||||
{
|
||||
static DRC_REGISTER_TEST_PROVIDER<DRC_TEST_PROVIDER_ANNULAR_WIDTH> dummy;
|
||||
|
@ -63,8 +63,6 @@ public:
|
||||
{
|
||||
return "Tests board connectivity";
|
||||
}
|
||||
|
||||
virtual std::set<DRC_CONSTRAINT_T> GetConstraintTypes() const override;
|
||||
};
|
||||
|
||||
|
||||
@ -173,12 +171,6 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
|
||||
}
|
||||
|
||||
|
||||
std::set<DRC_CONSTRAINT_T> DRC_TEST_PROVIDER_CONNECTIVITY::GetConstraintTypes() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
namespace detail
|
||||
{
|
||||
static DRC_REGISTER_TEST_PROVIDER<DRC_TEST_PROVIDER_CONNECTIVITY> dummy;
|
||||
|
@ -78,8 +78,6 @@ public:
|
||||
return "Tests copper item clearance";
|
||||
}
|
||||
|
||||
virtual std::set<DRC_CONSTRAINT_T> GetConstraintTypes() const override;
|
||||
|
||||
private:
|
||||
bool testTrackAgainstItem( PCB_TRACK* track, SHAPE* trackShape, PCB_LAYER_ID layer,
|
||||
BOARD_ITEM* other );
|
||||
@ -92,7 +90,7 @@ private:
|
||||
|
||||
void testZonesToZones();
|
||||
|
||||
void testItemAgainstZones( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer );
|
||||
void testItemAgainstZone( BOARD_ITEM* aItem, ZONE* aZone, PCB_LAYER_ID aLayer );
|
||||
|
||||
private:
|
||||
DRC_RTREE m_copperTree;
|
||||
@ -280,7 +278,7 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track,
|
||||
clearance = constraint.GetValue().Min();
|
||||
}
|
||||
|
||||
if( clearance >= 0 )
|
||||
if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && clearance >= 0 )
|
||||
{
|
||||
// Special processing for track:track intersections
|
||||
if( track->Type() == PCB_TRACE_T && other->Type() == PCB_TRACE_T )
|
||||
@ -347,25 +345,27 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track,
|
||||
constraint = m_drcEngine->EvalRules( HOLE_CLEARANCE_CONSTRAINT, other, track, layer );
|
||||
clearance = constraint.GetValue().Min();
|
||||
|
||||
if( clearance > 0 && trackShape->Collide( holeShape.get(),
|
||||
std::max( 0, clearance - m_drcEpsilon ),
|
||||
&actual, &pos ) )
|
||||
if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && clearance > 0 )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
|
||||
if( trackShape->Collide( holeShape.get(), std::max( 0, clearance - m_drcEpsilon ),
|
||||
&actual, &pos ) )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
|
||||
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), clearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), clearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetItems( track, other );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetItems( track, other );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
reportViolation( drce, (wxPoint) pos );
|
||||
reportViolation( drce, (wxPoint) pos );
|
||||
|
||||
if( !m_drcEngine->GetReportAllTrackErrors() )
|
||||
return false;
|
||||
if( !m_drcEngine->GetReportAllTrackErrors() )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -374,71 +374,115 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track,
|
||||
}
|
||||
|
||||
|
||||
void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testItemAgainstZones( BOARD_ITEM* aItem,
|
||||
void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testItemAgainstZone( BOARD_ITEM* aItem, ZONE* aZone,
|
||||
PCB_LAYER_ID aLayer )
|
||||
{
|
||||
for( ZONE* zone : m_copperZones )
|
||||
{
|
||||
if( !zone->GetLayerSet().test( aLayer ) )
|
||||
continue;
|
||||
if( !aZone->GetLayerSet().test( aLayer ) )
|
||||
return;
|
||||
|
||||
if( zone->GetNetCode() && aItem->IsConnected() )
|
||||
if( aZone->GetNetCode() && aItem->IsConnected() )
|
||||
{
|
||||
if( aZone->GetNetCode() == static_cast<BOARD_CONNECTED_ITEM*>( aItem )->GetNetCode() )
|
||||
return;
|
||||
}
|
||||
|
||||
if( !aItem->GetBoundingBox().Intersects( aZone->GetCachedBoundingBox() ) )
|
||||
return;
|
||||
|
||||
bool testClearance = !m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE );
|
||||
bool testHoles = !m_drcEngine->IsErrorLimitExceeded( DRCE_HOLE_CLEARANCE );
|
||||
|
||||
if( !testClearance && !testHoles )
|
||||
return;
|
||||
|
||||
DRC_RTREE* zoneTree = m_board->m_CopperZoneRTrees[ aZone ].get();
|
||||
EDA_RECT itemBBox = aItem->GetBoundingBox();
|
||||
DRC_CONSTRAINT constraint;
|
||||
int clearance = -1;
|
||||
int actual;
|
||||
VECTOR2I pos;
|
||||
|
||||
if( zoneTree && testClearance )
|
||||
{
|
||||
constraint = m_drcEngine->EvalRules( CLEARANCE_CONSTRAINT, aItem, aZone, aLayer );
|
||||
clearance = constraint.GetValue().Min();
|
||||
}
|
||||
|
||||
if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && clearance >= 0 )
|
||||
{
|
||||
std::shared_ptr<SHAPE> itemShape = aItem->GetEffectiveShape( aLayer );
|
||||
|
||||
if( aItem->Type() == PCB_PAD_T )
|
||||
{
|
||||
if( zone->GetNetCode() == static_cast<BOARD_CONNECTED_ITEM*>( aItem )->GetNetCode() )
|
||||
continue;
|
||||
PAD* pad = static_cast<PAD*>( aItem );
|
||||
|
||||
if( !pad->FlashLayer( aLayer ) )
|
||||
{
|
||||
if( pad->GetDrillSize().x == 0 && pad->GetDrillSize().y == 0 )
|
||||
return;
|
||||
|
||||
const SHAPE_SEGMENT* hole = pad->GetEffectiveHoleShape();
|
||||
int size = hole->GetWidth();
|
||||
|
||||
// Note: drill size represents finish size, which means the actual hole
|
||||
// size is the plating thickness larger.
|
||||
if( pad->GetAttribute() == PAD_ATTRIB::PTH )
|
||||
size += m_board->GetDesignSettings().GetHolePlatingThickness();
|
||||
|
||||
itemShape = std::make_shared<SHAPE_SEGMENT>( hole->GetSeg(), size );
|
||||
}
|
||||
}
|
||||
|
||||
if( aItem->GetBoundingBox().Intersects( zone->GetCachedBoundingBox() ) )
|
||||
if( zoneTree->QueryColliding( itemBBox, itemShape.get(), aLayer,
|
||||
std::max( 0, clearance - m_drcEpsilon ), &actual, &pos ) )
|
||||
{
|
||||
bool testClearance = !m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE );
|
||||
bool testHoles = !m_drcEngine->IsErrorLimitExceeded( DRCE_HOLE_CLEARANCE );
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
|
||||
|
||||
if( !testClearance && !testHoles )
|
||||
return;
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), clearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
DRC_RTREE* zoneTree = m_board->m_CopperZoneRTrees[ zone ].get();
|
||||
EDA_RECT itemBBox = aItem->GetBoundingBox();
|
||||
DRC_CONSTRAINT constraint;
|
||||
int clearance = -1;
|
||||
int actual;
|
||||
VECTOR2I pos;
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetItems( aItem, aZone );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
if( zoneTree && testClearance )
|
||||
reportViolation( drce, (wxPoint) pos );
|
||||
}
|
||||
}
|
||||
|
||||
if( zoneTree && testHoles && ( aItem->Type() == PCB_VIA_T || aItem->Type() == PCB_PAD_T ) )
|
||||
{
|
||||
std::unique_ptr<SHAPE_SEGMENT> holeShape;
|
||||
|
||||
if( aItem->Type() == PCB_VIA_T )
|
||||
{
|
||||
PCB_VIA* via = static_cast<PCB_VIA*>( aItem );
|
||||
pos = via->GetPosition();
|
||||
|
||||
if( via->GetLayerSet().Contains( aLayer ) )
|
||||
holeShape.reset( new SHAPE_SEGMENT( pos, pos, via->GetDrill() ) );
|
||||
}
|
||||
else if( aItem->Type() == PCB_PAD_T )
|
||||
{
|
||||
PAD* pad = static_cast<PAD*>( aItem );
|
||||
|
||||
if( pad->GetDrillSize().x )
|
||||
holeShape.reset( new SHAPE_SEGMENT( *pad->GetEffectiveHoleShape() ) );
|
||||
}
|
||||
|
||||
if( holeShape )
|
||||
{
|
||||
constraint = m_drcEngine->EvalRules( HOLE_CLEARANCE_CONSTRAINT, aItem, aZone, aLayer );
|
||||
clearance = constraint.GetValue().Min();
|
||||
|
||||
if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && clearance >= 0 )
|
||||
{
|
||||
constraint = m_drcEngine->EvalRules( CLEARANCE_CONSTRAINT, aItem, zone, aLayer );
|
||||
clearance = constraint.GetValue().Min();
|
||||
}
|
||||
|
||||
if( clearance >= 0 )
|
||||
{
|
||||
std::shared_ptr<SHAPE> itemShape = aItem->GetEffectiveShape( aLayer );
|
||||
|
||||
if( aItem->Type() == PCB_PAD_T )
|
||||
if( zoneTree->QueryColliding( itemBBox, holeShape.get(), aLayer,
|
||||
std::max( 0, clearance - m_drcEpsilon ),
|
||||
&actual, &pos ) )
|
||||
{
|
||||
PAD* pad = static_cast<PAD*>( aItem );
|
||||
|
||||
if( !pad->FlashLayer( aLayer ) )
|
||||
{
|
||||
if( pad->GetDrillSize().x == 0 && pad->GetDrillSize().y == 0 )
|
||||
continue;
|
||||
|
||||
const SHAPE_SEGMENT* hole = pad->GetEffectiveHoleShape();
|
||||
int size = hole->GetWidth();
|
||||
|
||||
// Note: drill size represents finish size, which means the actual hole
|
||||
// size is the plating thickness larger.
|
||||
if( pad->GetAttribute() == PAD_ATTRIB::PTH )
|
||||
size += m_board->GetDesignSettings().GetHolePlatingThickness();
|
||||
|
||||
itemShape = std::make_shared<SHAPE_SEGMENT>( hole->GetSeg(), size );
|
||||
}
|
||||
}
|
||||
|
||||
if( zoneTree && zoneTree->QueryColliding( itemBBox, itemShape.get(), aLayer,
|
||||
std::max( 0, clearance - m_drcEpsilon ),
|
||||
&actual, &pos ) )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
|
||||
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
@ -446,58 +490,12 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testItemAgainstZones( BOARD_ITEM* aItem
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetItems( aItem, zone );
|
||||
drce->SetItems( aItem, aZone );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
reportViolation( drce, (wxPoint) pos );
|
||||
}
|
||||
}
|
||||
|
||||
if( testHoles && ( aItem->Type() == PCB_VIA_T || aItem->Type() == PCB_PAD_T ) )
|
||||
{
|
||||
std::unique_ptr<SHAPE_SEGMENT> holeShape;
|
||||
|
||||
if( aItem->Type() == PCB_VIA_T )
|
||||
{
|
||||
PCB_VIA* via = static_cast<PCB_VIA*>( aItem );
|
||||
pos = via->GetPosition();
|
||||
|
||||
if( via->GetLayerSet().Contains( aLayer ) )
|
||||
holeShape.reset( new SHAPE_SEGMENT( pos, pos, via->GetDrill() ) );
|
||||
}
|
||||
else if( aItem->Type() == PCB_PAD_T )
|
||||
{
|
||||
PAD* pad = static_cast<PAD*>( aItem );
|
||||
|
||||
if( pad->GetDrillSize().x )
|
||||
holeShape.reset( new SHAPE_SEGMENT( *pad->GetEffectiveHoleShape() ) );
|
||||
}
|
||||
|
||||
if( holeShape )
|
||||
{
|
||||
constraint = m_drcEngine->EvalRules( HOLE_CLEARANCE_CONSTRAINT, aItem, zone,
|
||||
aLayer );
|
||||
clearance = constraint.GetValue().Min();
|
||||
|
||||
if( zoneTree && zoneTree->QueryColliding( itemBBox, holeShape.get(), aLayer,
|
||||
std::max( 0, clearance - m_drcEpsilon ),
|
||||
&actual, &pos ) )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
|
||||
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), clearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetItems( aItem, zone );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
reportViolation( drce, (wxPoint) pos );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -561,7 +559,8 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances()
|
||||
},
|
||||
m_largestClearance );
|
||||
|
||||
testItemAgainstZones( track, layer );
|
||||
for( ZONE* zone : m_copperZones )
|
||||
testItemAgainstZone( track, zone, layer );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -667,23 +666,25 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem( PAD* pad, SHAPE* pa
|
||||
constraint = m_drcEngine->EvalRules( CLEARANCE_CONSTRAINT, pad, other, layer );
|
||||
clearance = constraint.GetValue().Min();
|
||||
|
||||
if( clearance > 0 && padShape->Collide( otherShape.get(),
|
||||
std::max( 0, clearance - m_drcEpsilon ),
|
||||
&actual, &pos ) )
|
||||
if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && clearance > 0 )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
|
||||
if( padShape->Collide( otherShape.get(), std::max( 0, clearance - m_drcEpsilon ),
|
||||
&actual, &pos ) )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
|
||||
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), clearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), clearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetItems( pad, other );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetItems( pad, other );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
reportViolation( drce, (wxPoint) pos );
|
||||
testHoles = false; // No need for multiple violations
|
||||
reportViolation( drce, (wxPoint) pos );
|
||||
testHoles = false; // No need for multiple violations
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -691,6 +692,9 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem( PAD* pad, SHAPE* pa
|
||||
{
|
||||
constraint = m_drcEngine->EvalRules( HOLE_CLEARANCE_CONSTRAINT, pad, other, layer );
|
||||
clearance = constraint.GetValue().Min();
|
||||
|
||||
if( constraint.GetSeverity() == RPT_SEVERITY_IGNORE )
|
||||
testHoles = false;
|
||||
}
|
||||
|
||||
if( testHoles && otherPad && pad->FlashLayer( layer ) && otherPad->GetDrillSize().x )
|
||||
@ -819,7 +823,8 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadClearances( )
|
||||
},
|
||||
m_largestClearance );
|
||||
|
||||
testItemAgainstZones( pad, layer );
|
||||
for( ZONE* zone : m_copperZones )
|
||||
testItemAgainstZone( pad, zone, layer );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -832,6 +837,8 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
|
||||
|
||||
SHAPE_POLY_SET buffer;
|
||||
SHAPE_POLY_SET* boardOutline = nullptr;
|
||||
DRC_CONSTRAINT constraint;
|
||||
int zone2zoneClearance;
|
||||
|
||||
if( m_board->GetBoardPolygonOutlines( buffer ) )
|
||||
boardOutline = &buffer;
|
||||
@ -858,45 +865,41 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
|
||||
if( !reportProgress( layer_id * m_copperZones.size() + ia, B_Cu * m_copperZones.size(), delta ) )
|
||||
break;
|
||||
|
||||
ZONE* zoneRef = m_copperZones[ia];
|
||||
ZONE* zoneA = m_copperZones[ia];
|
||||
|
||||
if( !zoneRef->IsOnLayer( layer ) )
|
||||
if( !zoneA->IsOnLayer( layer ) )
|
||||
continue;
|
||||
|
||||
// If we are testing a single zone, then iterate through all other zones
|
||||
// Otherwise, we have already tested the zone combination
|
||||
for( size_t ia2 = ia + 1; ia2 < m_copperZones.size(); ia2++ )
|
||||
{
|
||||
ZONE* zoneToTest = m_copperZones[ia2];
|
||||
|
||||
if( zoneRef == zoneToTest )
|
||||
continue;
|
||||
ZONE* zoneB = m_copperZones[ia2];
|
||||
|
||||
// test for same layer
|
||||
if( !zoneToTest->IsOnLayer( layer ) )
|
||||
if( !zoneB->IsOnLayer( layer ) )
|
||||
continue;
|
||||
|
||||
// Test for same net
|
||||
if( zoneRef->GetNetCode() == zoneToTest->GetNetCode()
|
||||
&& zoneRef->GetNetCode() >= 0 )
|
||||
if( zoneA->GetNetCode() == zoneB->GetNetCode() && zoneA->GetNetCode() >= 0 )
|
||||
continue;
|
||||
|
||||
// test for different priorities
|
||||
if( zoneRef->GetPriority() != zoneToTest->GetPriority() )
|
||||
if( zoneA->GetPriority() != zoneB->GetPriority() )
|
||||
continue;
|
||||
|
||||
// rule areas may overlap at will
|
||||
if( zoneRef->GetIsRuleArea() || zoneToTest->GetIsRuleArea() )
|
||||
if( zoneA->GetIsRuleArea() || zoneB->GetIsRuleArea() )
|
||||
continue;
|
||||
|
||||
// Examine a candidate zone: compare zoneToTest to zoneRef
|
||||
// Examine a candidate zone: compare zoneB to zoneA
|
||||
|
||||
// Get clearance used in zone to zone test.
|
||||
auto constraint = m_drcEngine->EvalRules( CLEARANCE_CONSTRAINT, zoneRef, zoneToTest,
|
||||
layer );
|
||||
int zone2zoneClearance = constraint.GetValue().Min();
|
||||
constraint = m_drcEngine->EvalRules( CLEARANCE_CONSTRAINT, zoneA, zoneB, layer );
|
||||
zone2zoneClearance = constraint.GetValue().Min();
|
||||
|
||||
// test for some corners of zoneRef inside zoneToTest
|
||||
if( constraint.GetSeverity() == RPT_SEVERITY_IGNORE )
|
||||
continue;
|
||||
|
||||
// test for some corners of zoneA inside zoneB
|
||||
for( auto iterator = smoothed_polys[ia].IterateWithHoles(); iterator; iterator++ )
|
||||
{
|
||||
VECTOR2I currentVertex = *iterator;
|
||||
@ -905,14 +908,14 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
|
||||
if( smoothed_polys[ia2].Contains( currentVertex ) )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_ZONES_INTERSECT );
|
||||
drce->SetItems( zoneRef, zoneToTest );
|
||||
drce->SetItems( zoneA, zoneB );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
reportViolation( drce, pt );
|
||||
}
|
||||
}
|
||||
|
||||
// test for some corners of zoneToTest inside zoneRef
|
||||
// test for some corners of zoneB inside zoneA
|
||||
for( auto iterator = smoothed_polys[ia2].IterateWithHoles(); iterator; iterator++ )
|
||||
{
|
||||
VECTOR2I currentVertex = *iterator;
|
||||
@ -921,7 +924,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
|
||||
if( smoothed_polys[ia].Contains( currentVertex ) )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_ZONES_INTERSECT );
|
||||
drce->SetItems( zoneToTest, zoneRef );
|
||||
drce->SetItems( zoneB, zoneA );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
reportViolation( drce, pt );
|
||||
@ -955,12 +958,9 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
|
||||
bx2 = testSegment.B.x;
|
||||
by2 = testSegment.B.y;
|
||||
|
||||
int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2,
|
||||
0,
|
||||
ax1, ay1, ax2, ay2,
|
||||
0,
|
||||
zone2zoneClearance,
|
||||
&pt.x, &pt.y );
|
||||
int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2, 0,
|
||||
ax1, ay1, ax2, ay2, 0,
|
||||
zone2zoneClearance, &pt.x, &pt.y );
|
||||
|
||||
if( d < zone2zoneClearance )
|
||||
{
|
||||
@ -974,7 +974,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
|
||||
|
||||
for( const std::pair<const wxPoint, int>& conflict : conflictPoints )
|
||||
{
|
||||
int actual = conflict.second;
|
||||
int actual = conflict.second;
|
||||
std::shared_ptr<DRC_ITEM> drce;
|
||||
|
||||
if( actual <= 0 )
|
||||
@ -993,7 +993,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
}
|
||||
|
||||
drce->SetItems( zoneRef, zoneToTest );
|
||||
drce->SetItems( zoneA, zoneB );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
reportViolation( drce, conflict.first );
|
||||
@ -1004,12 +1004,6 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
|
||||
}
|
||||
|
||||
|
||||
std::set<DRC_CONSTRAINT_T> DRC_TEST_PROVIDER_COPPER_CLEARANCE::GetConstraintTypes() const
|
||||
{
|
||||
return { CLEARANCE_CONSTRAINT, HOLE_CLEARANCE_CONSTRAINT };
|
||||
}
|
||||
|
||||
|
||||
namespace detail
|
||||
{
|
||||
static DRC_REGISTER_TEST_PROVIDER<DRC_TEST_PROVIDER_COPPER_CLEARANCE> dummy;
|
||||
|
@ -67,8 +67,6 @@ public:
|
||||
return "Tests footprints' courtyard clearance";
|
||||
}
|
||||
|
||||
virtual std::set<DRC_CONSTRAINT_T> GetConstraintTypes() const override;
|
||||
|
||||
private:
|
||||
bool testFootprintCourtyardDefinitions();
|
||||
|
||||
@ -198,54 +196,58 @@ bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances()
|
||||
if( frontA.OutlineCount() > 0 && frontB.OutlineCount() > 0
|
||||
&& frontBBox.Intersects( frontB.BBoxFromCaches() ) )
|
||||
{
|
||||
constraint = m_drcEngine->EvalRules( COURTYARD_CLEARANCE_CONSTRAINT, fpA, fpB,
|
||||
F_Cu );
|
||||
constraint = m_drcEngine->EvalRules( COURTYARD_CLEARANCE_CONSTRAINT, fpA, fpB, F_Cu );
|
||||
clearance = constraint.GetValue().Min();
|
||||
|
||||
if( clearance >= 0 && frontA.Collide( &frontB, clearance, &actual, &pos ) )
|
||||
if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && clearance >= 0 )
|
||||
{
|
||||
auto drce = DRC_ITEM::Create( DRCE_OVERLAPPING_FOOTPRINTS );
|
||||
|
||||
if( clearance > 0 )
|
||||
if( frontA.Collide( &frontB, clearance, &actual, &pos ) )
|
||||
{
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), clearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
auto drce = DRC_ITEM::Create( DRCE_OVERLAPPING_FOOTPRINTS );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
if( clearance > 0 )
|
||||
{
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), clearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
}
|
||||
|
||||
drce->SetItems( fpA, fpB );
|
||||
reportViolation( drce, (wxPoint) pos );
|
||||
}
|
||||
|
||||
drce->SetItems( fpA, fpB );
|
||||
reportViolation( drce, (wxPoint) pos );
|
||||
}
|
||||
}
|
||||
|
||||
if( backA.OutlineCount() > 0 && backB.OutlineCount() > 0
|
||||
&& backBBox.Intersects( backB.BBoxFromCaches() ) )
|
||||
{
|
||||
constraint = m_drcEngine->EvalRules( COURTYARD_CLEARANCE_CONSTRAINT, fpA, fpB,
|
||||
B_Cu );
|
||||
constraint = m_drcEngine->EvalRules( COURTYARD_CLEARANCE_CONSTRAINT, fpA, fpB, B_Cu );
|
||||
clearance = constraint.GetValue().Min();
|
||||
|
||||
if( clearance >= 0 && backA.Collide( &backB, clearance, &actual, &pos ) )
|
||||
if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && clearance >= 0 )
|
||||
{
|
||||
auto drce = DRC_ITEM::Create( DRCE_OVERLAPPING_FOOTPRINTS );
|
||||
|
||||
if( clearance > 0 )
|
||||
if( backA.Collide( &backB, clearance, &actual, &pos ) )
|
||||
{
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), clearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
auto drce = DRC_ITEM::Create( DRCE_OVERLAPPING_FOOTPRINTS );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
if( clearance > 0 )
|
||||
{
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), clearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
}
|
||||
|
||||
drce->SetItems( fpA, fpB );
|
||||
reportViolation( drce, (wxPoint) pos );
|
||||
}
|
||||
|
||||
drce->SetItems( fpA, fpB );
|
||||
reportViolation( drce, (wxPoint) pos );
|
||||
}
|
||||
}
|
||||
|
||||
@ -317,12 +319,6 @@ bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::Run()
|
||||
}
|
||||
|
||||
|
||||
std::set<DRC_CONSTRAINT_T> DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::GetConstraintTypes() const
|
||||
{
|
||||
return { COURTYARD_CLEARANCE_CONSTRAINT };
|
||||
}
|
||||
|
||||
|
||||
namespace detail
|
||||
{
|
||||
static DRC_REGISTER_TEST_PROVIDER<DRC_TEST_PROVIDER_COURTYARD_CLEARANCE> dummy;
|
||||
|
@ -74,10 +74,7 @@ public:
|
||||
return "Tests differential pair coupling";
|
||||
}
|
||||
|
||||
virtual std::set<DRC_CONSTRAINT_T> GetConstraintTypes() const override;
|
||||
|
||||
private:
|
||||
|
||||
BOARD* m_board;
|
||||
};
|
||||
|
||||
@ -297,7 +294,7 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
|
||||
auto constraint = m_drcEngine->EvalRules( constraintsToCheck[ i ], item,
|
||||
nullptr, item->GetLayer() );
|
||||
|
||||
if( constraint.IsNull() )
|
||||
if( constraint.IsNull() || constraint.GetSeverity() == RPT_SEVERITY_IGNORE )
|
||||
continue;
|
||||
|
||||
drc_dbg( 10, "cns %d item %p\n", constraintsToCheck[i], item );
|
||||
@ -316,8 +313,8 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
|
||||
|
||||
m_board->GetConnectivity()->GetFromToCache()->Rebuild( m_board );
|
||||
|
||||
forEachGeometryItem( { PCB_TRACE_T, PCB_VIA_T, PCB_ARC_T },
|
||||
LSET::AllCuMask(), evaluateDpConstraints );
|
||||
forEachGeometryItem( { PCB_TRACE_T, PCB_VIA_T, PCB_ARC_T }, LSET::AllCuMask(),
|
||||
evaluateDpConstraints );
|
||||
|
||||
drc_dbg( 10, "dp rule matches %d\n", (int) dpRuleMatches.size() );
|
||||
|
||||
@ -420,9 +417,6 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
|
||||
if( val.HasMax() && gap > val.Max() )
|
||||
insideRange = false;
|
||||
|
||||
// if(val.HasMin() && val.HasMax() )
|
||||
// drc_dbg(10, "Vmin %d vmax %d\n", val.Min(), val.Max() );
|
||||
|
||||
cpair.couplingOK = insideRange;
|
||||
}
|
||||
else
|
||||
@ -515,12 +509,6 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
|
||||
}
|
||||
|
||||
|
||||
std::set<DRC_CONSTRAINT_T> test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::GetConstraintTypes() const
|
||||
{
|
||||
return { DIFF_PAIR_GAP_CONSTRAINT, DIFF_PAIR_MAX_UNCOUPLED_CONSTRAINT };
|
||||
}
|
||||
|
||||
|
||||
namespace detail
|
||||
{
|
||||
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING> dummy;
|
||||
|
@ -58,8 +58,6 @@ public:
|
||||
{
|
||||
return "Tests for disallowed items (e.g. keepouts)";
|
||||
}
|
||||
|
||||
virtual std::set<DRC_CONSTRAINT_T> GetConstraintTypes() const override;
|
||||
};
|
||||
|
||||
|
||||
@ -80,7 +78,7 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
|
||||
auto constraint = m_drcEngine->EvalRules( DISALLOW_CONSTRAINT, item, nullptr,
|
||||
UNDEFINED_LAYER );
|
||||
|
||||
if( constraint.m_DisallowFlags )
|
||||
if( constraint.m_DisallowFlags && constraint.GetSeverity() != RPT_SEVERITY_IGNORE )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ALLOWED_ITEMS );
|
||||
|
||||
@ -168,12 +166,6 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
|
||||
}
|
||||
|
||||
|
||||
std::set<DRC_CONSTRAINT_T> DRC_TEST_PROVIDER_DISALLOW::GetConstraintTypes() const
|
||||
{
|
||||
return { DISALLOW_CONSTRAINT };
|
||||
}
|
||||
|
||||
|
||||
namespace detail
|
||||
{
|
||||
static DRC_REGISTER_TEST_PROVIDER<DRC_TEST_PROVIDER_DISALLOW> dummy;
|
||||
|
@ -68,8 +68,6 @@ public:
|
||||
return "Tests items vs board edge clearance";
|
||||
}
|
||||
|
||||
virtual std::set<DRC_CONSTRAINT_T> GetConstraintTypes() const override;
|
||||
|
||||
private:
|
||||
bool testAgainstEdge( BOARD_ITEM* item, SHAPE* itemShape, BOARD_ITEM* other,
|
||||
DRC_CONSTRAINT_T aConstraintType, PCB_DRC_CODE aErrorCode );
|
||||
@ -88,26 +86,29 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::testAgainstEdge( BOARD_ITEM* item, SHAPE*
|
||||
int actual;
|
||||
VECTOR2I pos;
|
||||
|
||||
if( minClearance >= 0 && itemShape->Collide( edgeShape.get(), minClearance, &actual, &pos ) )
|
||||
if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE && minClearance >= 0 )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( aErrorCode );
|
||||
|
||||
// Only report clearance info if there is any; otherwise it's just a straight collision
|
||||
if( minClearance > 0 )
|
||||
if( itemShape->Collide( edgeShape.get(), minClearance, &actual, &pos ) )
|
||||
{
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), minClearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( aErrorCode );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
// Only report clearance info if there is any; otherwise it's just a straight collision
|
||||
if( minClearance > 0 )
|
||||
{
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), minClearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
}
|
||||
|
||||
drce->SetItems( edge->m_Uuid, item->m_Uuid );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
reportViolation( drce, (wxPoint) pos );
|
||||
return false; // don't report violations with multiple edges; one is enough
|
||||
}
|
||||
|
||||
drce->SetItems( edge->m_Uuid, item->m_Uuid );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
reportViolation( drce, (wxPoint) pos );
|
||||
return false; // don't report violations with multiple edges; one is enough
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -281,12 +282,6 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
|
||||
}
|
||||
|
||||
|
||||
std::set<DRC_CONSTRAINT_T> DRC_TEST_PROVIDER_EDGE_CLEARANCE::GetConstraintTypes() const
|
||||
{
|
||||
return { EDGE_CLEARANCE_CONSTRAINT, SILK_CLEARANCE_CONSTRAINT };
|
||||
}
|
||||
|
||||
|
||||
namespace detail
|
||||
{
|
||||
static DRC_REGISTER_TEST_PROVIDER<DRC_TEST_PROVIDER_EDGE_CLEARANCE> dummy;
|
||||
|
@ -60,8 +60,6 @@ public:
|
||||
return "Tests sizes of drilled holes (via/pad drills)";
|
||||
}
|
||||
|
||||
virtual std::set<DRC_CONSTRAINT_T> GetConstraintTypes() const override;
|
||||
|
||||
private:
|
||||
void checkVia( PCB_VIA* via, bool aExceedMicro, bool aExceedStd );
|
||||
void checkPad( PAD* aPad );
|
||||
@ -144,6 +142,9 @@ void DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( PAD* aPad )
|
||||
bool fail_max = false;
|
||||
int constraintValue;
|
||||
|
||||
if( constraint.GetSeverity() == RPT_SEVERITY_IGNORE )
|
||||
return;
|
||||
|
||||
if( constraint.Value().HasMin() && holeMinor < constraint.Value().Min() )
|
||||
{
|
||||
fail_min = true;
|
||||
@ -209,6 +210,9 @@ void DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( PCB_VIA* via, bool aExceedMicro, boo
|
||||
bool fail_max = false;
|
||||
int constraintValue;
|
||||
|
||||
if( constraint.GetSeverity() == RPT_SEVERITY_IGNORE )
|
||||
return;
|
||||
|
||||
if( constraint.Value().HasMin() && via->GetDrillValue() < constraint.Value().Min() )
|
||||
{
|
||||
fail_min = true;
|
||||
@ -249,12 +253,6 @@ void DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( PCB_VIA* via, bool aExceedMicro, boo
|
||||
}
|
||||
|
||||
|
||||
std::set<DRC_CONSTRAINT_T> DRC_TEST_PROVIDER_HOLE_SIZE::GetConstraintTypes() const
|
||||
{
|
||||
return { HOLE_SIZE_CONSTRAINT };
|
||||
}
|
||||
|
||||
|
||||
namespace detail
|
||||
{
|
||||
static DRC_REGISTER_TEST_PROVIDER<DRC_TEST_PROVIDER_HOLE_SIZE> dummy;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user