common: include drc_proto keywords in the main DRC parser

This commit is contained in:
Tomasz Wlostowski 2020-08-12 00:15:50 +02:00
parent d937fadd6f
commit 52fefd15e0
15 changed files with 390 additions and 188 deletions

View File

@ -26,3 +26,11 @@ track_width
version
via
zone
edge_clearance
hole_clearance
courtyard_clearance
silk_to_pad
silk_to_silk
match_lengths
match_skew
diff_pair

View File

@ -48,8 +48,15 @@ test::DRC_ENGINE::DRC_ENGINE( BOARD* aBoard, BOARD_DESIGN_SETTINGS *aSettings )
test::DRC_ENGINE::~DRC_ENGINE()
{
for( DRC_ITEM* item : m_drcItems )
delete item;
}
test::DRC_REPORT::~DRC_REPORT()
{
for( auto item : m_entries )
{
if ( item.m_marker )
delete item.m_marker;
}
}
/*void test::DRC_ENGINE::AddMarker( MARKER_PCB* aMarker )
@ -111,31 +118,6 @@ void test::DRC_ENGINE::inferImplicitRules()
}
static const int drc_debug_level = 0;
void test::drc_dbg( int level, const char* fmt, ... )
{
#ifdef DEBUG
long dlevel = drc_debug_level;
wxString dlevelstr;
if( wxGetEnv( "DRC_DEBUG_LEVEL", &dlevelstr ) )
{
dlevelstr.ToLong( &dlevel );
}
if(level < dlevel) // fixme: tom's debugging.
{
va_list ap;
va_start( ap, fmt );
fprintf( stderr, "drc: " );
vfprintf( stderr, fmt, ap );
va_end( ap );
}
#endif
}
bool test::DRC_ENGINE::CompileRules()
{
ReportAux( wxString::Format( "Compiling Rules (%d rules, %d conditions): ", m_rules.size(), m_ruleConditions.size() ) );
@ -176,7 +158,7 @@ bool test::DRC_ENGINE::CompileRules()
{
rcons->conditions.push_back( condition );
bool compileOk = condition->Compile( &NULL_REPORTER::GetInstance() );
bool compileOk = condition->Compile();
ReportAux( wxString::Format( " |- condition: '%s' compile: %s", condition->m_TargetRuleName, compileOk ? "OK" : "ERROR") );
@ -198,6 +180,7 @@ void test::DRC_ENGINE::RunTests( )
{
//m_largestClearance = m_designSettings->GetBiggestClearanceValue();
m_drcReport.reset( new test::DRC_REPORT );
m_testProviders = DRC_TEST_PROVIDER_REGISTRY::Instance().GetTestProviders();
for( auto provider : m_testProviders )
@ -268,22 +251,25 @@ test::DRC_RULE* test::DRC_ENGINE::EvalRulesForItems( test::DRC_RULE_ID_T ruleID,
}
void test::DRC_ENGINE::Report( DRC_ITEM* aItem, ::MARKER_PCB *aMarker )
void test::DRC_ENGINE::Report( std::shared_ptr<DRC_ITEM> aItem, ::MARKER_PCB *aMarker )
{
m_drcItems.push_back( aItem );
m_markers.push_back( aMarker );
m_drcReport->AddItem( aItem, aMarker );
if( m_reporter )
{
m_reporter->Report ( wxString::Format( "Test '%s': violation of rule '%s' : %s (code %d)",
aItem->GetViolatingTest()->GetName(),
aItem->GetViolatingRule()->GetName(),
aItem->GetErrorMessage(),
aItem->GetErrorCode() ), RPT_SEVERITY_ERROR /* fixme */ );
if( aMarker )
{
m_reporter->Report( wxString::Format( " |- violating position (%d, %d)", aMarker->GetPos().x, aMarker->GetPos().y ),
RPT_SEVERITY_ERROR /* fixme */ );
}
aItem->GetViolatingTest()->GetName(),
aItem->GetViolatingRule()->GetName(),
aItem->GetErrorMessage(),
aItem->GetErrorCode() ), RPT_SEVERITY_ERROR /* fixme */ );
wxString violatingItemsStr = "Violating items: ";
if( aMarker )
{
m_reporter->Report( wxString::Format( " |- violating position (%d, %d)", aMarker->GetPos().x, aMarker->GetPos().y ),
RPT_SEVERITY_ERROR /* fixme */ );
}
}
}
@ -358,3 +344,28 @@ bool test::DRC_ENGINE::HasCorrectRulesForId( test::DRC_RULE_ID_T ruleID )
return m_ruleMap[ruleID]->defaultRule != nullptr;
}
bool test::DRC_ENGINE::QueryWorstConstraint( test::DRC_RULE_ID_T aRuleId, test::DRC_CONSTRAINT& aConstraint, test::DRC_CONSTRAINT_QUERY_T aQueryType )
{
if( aQueryType == DRCCQ_LARGEST_MINIMUM )
{
int worst = 0;
for( auto rule : QueryRulesById( test::DRC_RULE_ID_T::DRC_RULE_ID_EDGE_CLEARANCE ) )
{
if( rule->GetConstraint().m_Value.HasMin() )
{
int current = rule->GetConstraint().m_Value.Min();
if( current > worst )
{
worst = current;
aConstraint = rule->GetConstraint();
}
}
}
return worst > 0;
}
return false;
}

View File

@ -53,6 +53,13 @@ class NETLIST;
class PROGRESS_REPORTER;
class REPORTER;
//#ifdef DEBUG
#define drc_dbg(level, fmt, ...) \
wxLogTrace( "drc_proto", fmt, __VA_ARGS__ );
//#else
//#define drc_dbg(level, fmt, ...)
//#endif
namespace test
{
@ -62,6 +69,12 @@ class DRC_RULE;
class DRC_TEST_PROVIDER;
class DRC_CONSTRAINT;
enum DRC_CONSTRAINT_QUERY_T
{
DRCCQ_LARGEST_MINIMUM = 0
// fixme: more to come I guess...
};
/// DRC error codes:
enum PCB_DRC_CODE
{
@ -103,6 +116,33 @@ enum PCB_DRC_CODE
DRCE_LAST = DRCE_UNRESOLVED_VARIABLE
};
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
@ -157,13 +197,19 @@ public:
bool CompileRules();
void Report( DRC_ITEM* aItem, ::MARKER_PCB *Marker );
void Report( std::shared_ptr<DRC_ITEM> aItem, ::MARKER_PCB *Marker );
void ReportProgress( double aProgress );
void ReportStage ( const wxString& aStageName, int index, int total );
void ReportAux( const wxString& aStr );
std::shared_ptr<DRC_REPORT> GetReport() const { return m_drcReport; }
bool QueryWorstConstraint( DRC_RULE_ID_T aRuleId, test::DRC_CONSTRAINT& aConstraint, DRC_CONSTRAINT_QUERY_T aQueryType );
private:
void freeCompiledRules();
struct RULE_WITH_CONDITIONS
@ -187,13 +233,13 @@ private:
BOARD_DESIGN_SETTINGS* m_designSettings;
BOARD* m_board;
std::vector<DRC_ITEM*> m_drcItems;
std::shared_ptr<DRC_REPORT> m_drcReport;
std::vector<DRC_RULE_CONDITION*> m_ruleConditions;
std::vector<DRC_RULE*> m_rules;
std::vector<DRC_TEST_PROVIDER*> m_testProviders;
std::unordered_map<EDA_ITEM*, RULE_SET*> m_implicitRules;
std::vector<::MARKER_PCB*> m_markers;
RULE_MAP m_ruleMap;
REPORTER* m_reporter;
PROGRESS_REPORTER* m_progressReporter;
@ -201,8 +247,6 @@ private:
// condition -> rule -> provider
};
void drc_dbg( int level, const char* fmt, ... );
}; // namespace test
#endif // DRC_H

View File

@ -196,55 +196,58 @@ std::vector<std::reference_wrapper<RC_ITEM>> test::DRC_ITEM::allItemTypes( {
} );
test::DRC_ITEM* test::DRC_ITEM::Create( int aErrorCode )
std::shared_ptr<test::DRC_ITEM> test::DRC_ITEM::Create( int aErrorCode )
{
DRC_ITEM *item;
switch( aErrorCode )
{
case DRCE_UNCONNECTED_ITEMS: return new DRC_ITEM( unconnectedItems );
case DRCE_SHORTING_ITEMS: return new DRC_ITEM( shortingItems );
case DRCE_ALLOWED_ITEMS: return new DRC_ITEM( itemsNotAllowed );
case DRCE_CLEARANCE: return new DRC_ITEM( clearance );
case DRCE_TRACKS_CROSSING: return new DRC_ITEM( tracksCrossing );
case DRCE_COPPER_EDGE_CLEARANCE: return new DRC_ITEM( copperEdgeClearance );
case DRCE_ZONES_INTERSECT: return new DRC_ITEM( zonesIntersect );
case DRCE_ZONE_HAS_EMPTY_NET: return new DRC_ITEM( zoneHasEmptyNet );
case DRCE_DANGLING_VIA: return new DRC_ITEM( viaDangling );
case DRCE_DANGLING_TRACK: return new DRC_ITEM( trackDangling );
case DRCE_HOLE_CLEARANCE: return new DRC_ITEM( holeClearance );
case DRCE_TRACK_WIDTH: return new DRC_ITEM( trackWidth );
case DRCE_TOO_SMALL_VIA: return new DRC_ITEM( viaTooSmall );
case DRCE_VIA_ANNULUS: return new DRC_ITEM( viaAnnulus );
case DRCE_TOO_SMALL_DRILL: return new DRC_ITEM( drillTooSmall );
case DRCE_VIA_HOLE_BIGGER: return new DRC_ITEM( viaHoleLargerThanPad );
case DRCE_PADSTACK: return new DRC_ITEM( padstack );
case DRCE_TOO_SMALL_MICROVIA: return new DRC_ITEM( microviaTooSmall );
case DRCE_TOO_SMALL_MICROVIA_DRILL: return new DRC_ITEM( microviaDrillTooSmall );
case DRCE_KEEPOUT: return new DRC_ITEM( keepout );
case DRCE_OVERLAPPING_FOOTPRINTS: return new DRC_ITEM( courtyardsOverlap );
case DRCE_MISSING_COURTYARD: return new DRC_ITEM( missingCourtyard );
case DRCE_MALFORMED_COURTYARD: return new DRC_ITEM( malformedCourtyard );
case DRCE_PTH_IN_COURTYARD: return new DRC_ITEM( pthInsideCourtyard );
case DRCE_NPTH_IN_COURTYARD: return new DRC_ITEM( npthInsideCourtyard );
case DRCE_DISABLED_LAYER_ITEM: return new DRC_ITEM( itemOnDisabledLayer );
case DRCE_INVALID_OUTLINE: return new DRC_ITEM( invalidOutline );
case DRCE_MISSING_FOOTPRINT: return new DRC_ITEM( duplicateFootprints );
case DRCE_DUPLICATE_FOOTPRINT: return new DRC_ITEM( missingFootprint );
case DRCE_EXTRA_FOOTPRINT: return new DRC_ITEM( extraFootprint );
case DRCE_UNRESOLVED_VARIABLE: return new DRC_ITEM( unresolvedVariable );
case DRCE_UNCONNECTED_ITEMS: item = new DRC_ITEM( unconnectedItems ); break;
case DRCE_SHORTING_ITEMS: item = new DRC_ITEM( shortingItems ); break;
case DRCE_ALLOWED_ITEMS: item = new DRC_ITEM( itemsNotAllowed ); break;
case DRCE_CLEARANCE: item = new DRC_ITEM( clearance ); break;
case DRCE_TRACKS_CROSSING: item = new DRC_ITEM( tracksCrossing ); break;
case DRCE_COPPER_EDGE_CLEARANCE: item = new DRC_ITEM( copperEdgeClearance ); break;
case DRCE_ZONES_INTERSECT: item = new DRC_ITEM( zonesIntersect ); break;
case DRCE_ZONE_HAS_EMPTY_NET: item = new DRC_ITEM( zoneHasEmptyNet ); break;
case DRCE_DANGLING_VIA: item = new DRC_ITEM( viaDangling ); break;
case DRCE_DANGLING_TRACK: item = new DRC_ITEM( trackDangling ); break;
case DRCE_HOLE_CLEARANCE: item = new DRC_ITEM( holeClearance ); break;
case DRCE_TRACK_WIDTH: item = new DRC_ITEM( trackWidth ); break;
case DRCE_TOO_SMALL_VIA: item = new DRC_ITEM( viaTooSmall ); break;
case DRCE_VIA_ANNULUS: item = new DRC_ITEM( viaAnnulus ); break;
case DRCE_TOO_SMALL_DRILL: item = new DRC_ITEM( drillTooSmall ); break;
case DRCE_VIA_HOLE_BIGGER: item = new DRC_ITEM( viaHoleLargerThanPad ); break;
case DRCE_PADSTACK: item = new DRC_ITEM( padstack ); break;
case DRCE_TOO_SMALL_MICROVIA: item = new DRC_ITEM( microviaTooSmall ); break;
case DRCE_TOO_SMALL_MICROVIA_DRILL: item = new DRC_ITEM( microviaDrillTooSmall ); break;
case DRCE_KEEPOUT: item = new DRC_ITEM( keepout ); break;
case DRCE_OVERLAPPING_FOOTPRINTS: item = new DRC_ITEM( courtyardsOverlap ); break;
case DRCE_MISSING_COURTYARD: item = new DRC_ITEM( missingCourtyard ); break;
case DRCE_MALFORMED_COURTYARD: item = new DRC_ITEM( malformedCourtyard ); break;
case DRCE_PTH_IN_COURTYARD: item = new DRC_ITEM( pthInsideCourtyard ); break;
case DRCE_NPTH_IN_COURTYARD: item = new DRC_ITEM( npthInsideCourtyard ); break;
case DRCE_DISABLED_LAYER_ITEM: item = new DRC_ITEM( itemOnDisabledLayer ); break;
case DRCE_INVALID_OUTLINE: item = new DRC_ITEM( invalidOutline ); break;
case DRCE_MISSING_FOOTPRINT: item = new DRC_ITEM( duplicateFootprints ); break;
case DRCE_DUPLICATE_FOOTPRINT: item = new DRC_ITEM( missingFootprint ); break;
case DRCE_EXTRA_FOOTPRINT: item = new DRC_ITEM( extraFootprint ); break;
case DRCE_UNRESOLVED_VARIABLE: item = new DRC_ITEM( unresolvedVariable ); break;
default:
wxFAIL_MSG( wxString::Format( "Unknown DRC error code %d", aErrorCode ) );
return nullptr;
}
return std::shared_ptr<test::DRC_ITEM>( item );
}
test::DRC_ITEM* test::DRC_ITEM::Create( const wxString& aErrorKey )
std::shared_ptr<test::DRC_ITEM> test::DRC_ITEM::Create( const wxString& aErrorKey )
{
for( const RC_ITEM& item : allItemTypes )
{
if( aErrorKey == item.GetSettingsKey() )
return new DRC_ITEM( static_cast<const DRC_ITEM&>( item ) );
return std::shared_ptr<DRC_ITEM>( new DRC_ITEM( static_cast<const DRC_ITEM&>( item ) ) );
}
// This can happen if a project has old-format exclusions. Just drop these items.

View File

@ -46,7 +46,7 @@ public:
* Constructs a DRC_ITEM for the given error code
* @see DRCE_T
*/
static DRC_ITEM* Create( int aErrorCode );
static std::shared_ptr<DRC_ITEM> Create( int aErrorCode );
/**
* Constructs a DRC item from a given error settings key
@ -54,7 +54,7 @@ public:
* to represent a given error code in settings files and for storing ignored DRC items)
* @return the created item
*/
static DRC_ITEM* Create( const wxString& aErrorKey );
static std::shared_ptr<DRC_ITEM> Create( const wxString& aErrorKey );
static std::vector<std::reference_wrapper<RC_ITEM>> GetItemsWithSeverities()
{

View File

@ -77,9 +77,9 @@ bool test::DRC_RULE_CONDITION::EvaluateFor( const BOARD_ITEM* aItemA, const BOAR
}
bool test::DRC_RULE_CONDITION::Compile( REPORTER* aReporter, int aSourceLine, int aSourceOffset )
bool test::DRC_RULE_CONDITION::Compile( )
{
PCB_EXPR_COMPILER compiler( aReporter, aSourceLine, aSourceOffset );
PCB_EXPR_COMPILER compiler;
if (!m_ucode)
m_ucode = new PCB_EXPR_UCODE;

View File

@ -34,6 +34,7 @@ class BOARD_ITEM;
namespace LIBEVAL
{
class UCODE;
class ERROR_STATUS;
};
class PCB_EXPR_UCODE;
@ -48,9 +49,8 @@ enum class DRC_RULE_ID_T
DRC_RULE_ID_HOLE_CLEARANCE,
DRC_RULE_ID_EDGE_CLEARANCE,
DRC_RULE_ID_HOLE_SIZE,
DRC_RULE_ID_ANNULUS,
DRC_RULE_ID_TRACK,
DRC_RULE_ID_DISALLOW
DRC_RULE_ID_COURTYARD_CLEARANCE,
DRC_RULE_ID_SILK_TO_PAD
};
enum class DRC_RULE_SEVERITY_T
@ -85,10 +85,9 @@ private:
bool m_hasMax = false;
};
class DRC_CONSTRAINT
{
public:
public:
DRC_CONSTRAINT() :
m_Type( DRC_RULE_ID_T::DRC_RULE_ID_UNKNOWN ),
m_DisallowFlags( 0 ),
@ -99,34 +98,15 @@ public:
const MINOPTMAX<int>& GetValue() const { return m_Value; }
bool Allowed() const { return m_Allow; }
public:
DRC_RULE_ID_T m_Type;
MINOPTMAX<int> m_Value;
int m_DisallowFlags;
LSET m_LayerCondition;
public:
DRC_RULE_ID_T m_Type;
MINOPTMAX<int> m_Value;
int m_DisallowFlags;
LSET m_LayerCondition;
bool m_Allow;
bool m_Allow;
};
class DRC_RULE_CONDITION
{
public:
DRC_RULE_CONDITION();
~DRC_RULE_CONDITION();
bool EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB, PCB_LAYER_ID aLayer );
bool Compile( REPORTER* aReporter, int aSourceLine = 0, int aSourceOffset = 0 );
public:
wxString m_Expression;
wxString m_TargetRuleName;
private:
PCB_EXPR_UCODE* m_ucode;
};
class DRC_RULE
{
public:
@ -151,9 +131,9 @@ public:
public:
bool m_Unary;
wxString m_Name;
wxString m_Name;
LSET m_LayerCondition;
wxString m_TestProviderName;
wxString m_TestProviderName;
DRC_RULE_CONDITION m_Condition;
std::vector<DRC_CONSTRAINT> m_Constraints;
@ -161,13 +141,29 @@ public:
bool m_Enabled;
bool m_Conditional;
int m_Priority; // 0 indicates automatic priority generation
DRC_CONSTRAINT m_Constraint; // FIXME: move to m_Constraints
};
//const DRC_CONSTRAINT* GetConstraint( const BOARD_ITEM* aItem, const BOARD_ITEM* bItem,
// int aConstraint, PCB_LAYER_ID aLayer, wxString* aRuleName );
class DRC_RULE_CONDITION
{
public:
DRC_RULE_CONDITION();
~DRC_RULE_CONDITION();
bool EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB );
bool Compile( REPORTER* aReporter, int aSourceLine = 0, int aSourceOffset = 0 );
public:
LSET m_LayerCondition;
wxString m_Expression;
wxString m_TargetRuleName;
private:
PCB_EXPR_UCODE* m_ucode;
};
//DRC_RULE* GetRule( const BOARD_ITEM* aItem, const BOARD_ITEM* bItem, int aConstraint );
}; // namespace test

View File

@ -342,9 +342,20 @@ test::DRC_RULE* test::DRC_RULES_PARSER::parseRULE()
void test::DRC_RULES_PARSER::parseValueWithUnits( const wxString& aExpr, int& aResult )
{
PCB_EXPR_EVALUATOR evaluator( m_reporter, CurLineNumber(), CurOffset() );
PCB_EXPR_EVALUATOR evaluator;
evaluator.Evaluate( aExpr );
if( evaluator.IsErrorPending() )
{
auto err = evaluator.GetError();
wxString str;
str.Printf( "Error: %s (line %d, offset %d)", err.message, CurLineNumber(), err.srcPos + CurOffset() );
m_reporter->Report( str, RPT_SEVERITY_ERROR );
return;
}
aResult = evaluator.Result();
};

View File

@ -22,23 +22,25 @@ bool test::DRC_TEST_PROVIDER::IsEnabled() const
const wxString test::DRC_TEST_PROVIDER::GetName() const { return "<no name test>"; }
const wxString test::DRC_TEST_PROVIDER::GetDescription() const { return ""; }
void test::DRC_TEST_PROVIDER::Report( DRC_ITEM* item )
void test::DRC_TEST_PROVIDER::Report( std::shared_ptr<DRC_ITEM> item )
{
item->SetViolatingTest( this );
m_drcEngine->Report( item, nullptr );
}
void test::DRC_TEST_PROVIDER::ReportWithMarker( DRC_ITEM* item, VECTOR2I aMarkerPos )
void test::DRC_TEST_PROVIDER::ReportWithMarker( std::shared_ptr<DRC_ITEM> item, VECTOR2I aMarkerPos )
{
item->SetViolatingTest( this );
m_drcEngine->Report( item, nullptr ); // fixme: create marker
MARKER_PCB* marker = new MARKER_PCB( item, wxPoint( aMarkerPos.x, aMarkerPos.y) );
m_drcEngine->Report( item, marker );
}
void test::DRC_TEST_PROVIDER::ReportWithMarker( DRC_ITEM* item, wxPoint aMarkerPos )
void test::DRC_TEST_PROVIDER::ReportWithMarker( std::shared_ptr<DRC_ITEM> item, wxPoint aMarkerPos )
{
item->SetViolatingTest( this );
m_drcEngine->Report( item, nullptr ); // fixme: create marker
MARKER_PCB* marker = new MARKER_PCB( item, wxPoint( aMarkerPos.x, aMarkerPos.y) );
m_drcEngine->Report( item, marker ); // fixme: create marker
}
void test::DRC_TEST_PROVIDER::ReportProgress( double aProgress )
@ -90,3 +92,130 @@ void test::DRC_TEST_PROVIDER::reportRuleStatistics()
m_drcEngine->ReportAux( wxString::Format( " - rule '%s': %d hits ", stat.first->GetName().c_str(), stat.second ) );
}
}
int test::DRC_TEST_PROVIDER::forEachGeometryItem( const std::vector<KICAD_T> aTypes, const LSET aLayers, std::function<int(BOARD_ITEM*)> aFunc )
{
BOARD *brd = m_drcEngine->GetBoard();
std::bitset<MAX_STRUCT_TYPE_ID> typeMask;
int n = 0;
if( aTypes.size() == 0 )
{
for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
{
typeMask[i] = true;
}
}
else
{
for( int i = 0; i < aTypes.size(); i++ )
{
typeMask[ aTypes[i] ] = 1;
}
}
/* case PCB_TRACE_T:
case PCB_VIA_T:
case PCB_ARC_T:*/
for ( auto item : brd->Tracks() )
{
if( typeMask[ PCB_TRACE_T ] && item->Type() == PCB_TRACE_T )
{
aFunc( item );
n++;
}
else if( typeMask[ PCB_VIA_T ] && item->Type() == PCB_VIA_T )
{
aFunc( item );
n++;
}
else if( typeMask[ PCB_ARC_T ] && item->Type() == PCB_ARC_T )
{
aFunc( item );
n++;
}
}
/* case PCB_DIMENSION_T:
case PCB_LINE_T:
case PCB_TEXT_T:
case PCB_TARGET_T:
*/
for( auto item : brd->Drawings() )
{
if( typeMask[ PCB_DIMENSION_T ] && item->Type() == PCB_DIMENSION_T )
{
aFunc( item );
n++;
}
else if( typeMask[ PCB_LINE_T ] && item->Type() == PCB_LINE_T )
{
aFunc( item );
n++;
}
else if( typeMask[ PCB_TEXT_T ] && item->Type() == PCB_TEXT_T )
{
aFunc( item );
n++;
}
else if( typeMask[ PCB_TARGET_T ] && item->Type() == PCB_TARGET_T )
{
aFunc( item );
n++;
}
}
for( auto item : brd->Zones() )
{
if( typeMask[ PCB_ZONE_AREA_T ] && item->Type() == PCB_ZONE_AREA_T )
{
aFunc( item );
n++;
}
}
for( auto mod : brd->Modules() )
{
if( typeMask[ PCB_MODULE_TEXT_T ] )
{
aFunc( &mod->Reference() );
n++;
aFunc( &mod->Value() );
n++;
}
for( auto pad : mod->Pads() )
{
if( typeMask[ PCB_PAD_T ] && pad->Type() == PCB_PAD_T )
{
aFunc( pad );
n++;
}
}
for( auto dwg : mod->GraphicalItems() )
{
if( typeMask[ PCB_MODULE_TEXT_T ] && dwg->Type() == PCB_MODULE_TEXT_T )
{
aFunc( dwg );
n++;
}
else if( typeMask[ PCB_MODULE_EDGE_T ] && dwg->Type() == PCB_MODULE_EDGE_T )
{
aFunc( dwg );
n++;
}
}
for( auto zone : mod->Zones() )
{
if( typeMask[ PCB_MODULE_ZONE_AREA_T ] && zone->Type() == PCB_MODULE_ZONE_AREA_T )
{
aFunc( zone );
n++;
}
}
}
return n;
}

View File

@ -97,9 +97,9 @@ public:
virtual const wxString GetDescription() const;
virtual void ReportAux( const wxString fmt, ... );
virtual void Report( DRC_ITEM* item );
virtual void ReportWithMarker( DRC_ITEM* item, wxPoint aMarkerPos );
virtual void ReportWithMarker( DRC_ITEM* item, VECTOR2I aMarkerPos );
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 ReportProgress( double aProgress );
virtual void ReportStage ( const wxString& aStageName, int index, int total );
@ -108,6 +108,8 @@ public:
protected:
int forEachGeometryItem( const std::vector<KICAD_T> aTypes, const LSET aLayers, std::function<int(BOARD_ITEM*)> aFunc );
virtual void reportRuleStatistics();
virtual void accountCheck( test::DRC_RULE* ruleToTest );
virtual bool isErrorLimitExceeded( int error_code );

View File

@ -178,7 +178,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testCopperDrawItem( BOARD_ITEM* a
else if( textItem )
{
bbox = textItem->GetTextBox();
itemShape = textItem->GetEffectiveShape();
itemShape = textItem->GetEffectiveTextShape();
}
else
{
@ -215,7 +215,8 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testCopperDrawItem( BOARD_ITEM* a
if( actual < INT_MAX )
{
DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_CLEARANCE );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_CLEARANCE );
wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
@ -258,7 +259,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testCopperDrawItem( BOARD_ITEM* a
if( actual < INT_MAX )
{
DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_CLEARANCE );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_CLEARANCE );
wxString msg;
@ -363,7 +364,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACK
if( padShape->Collide( &refSeg, minClearance - bds.GetDRCEpsilon(), &actual ) )
{
DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_CLEARANCE );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_CLEARANCE );
wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
@ -434,7 +435,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACK
if( OPT_VECTOR2I intersection = refSeg.GetSeg().Intersect( trackSeg.GetSeg() ) )
{
DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_TRACKS_CROSSING );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_TRACKS_CROSSING );
// fixme
drcItem->SetErrorMessage( "FIXME" );
@ -449,7 +450,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACK
else if( refSeg.Collide( &trackSeg, minClearance, &actual ) )
{
wxPoint pos = getLocation( aRefSeg, trackSeg.GetSeg() );
DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_CLEARANCE );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_CLEARANCE );
wxString msg;
@ -507,7 +508,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doTrackDrc( TRACK* aRefSeg, TRACK
if( zone->GetFilledPolysList( layer ).Collide( testSeg, allowedDist, &actual ) )
{
actual = std::max( 0, actual - widths );
DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_CLEARANCE );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_CLEARANCE );
wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
@ -606,7 +607,7 @@ bool test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doPadToPadsDrc( D_PAD* aRefPad, D
// and have the same pad number ( equivalent pads )
if( pad->PadNameEqual( aRefPad ) )
{
DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_SHORTING_ITEMS );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_SHORTING_ITEMS );
wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (nets %s and %s)" ),
pad->GetNetCode(), aRefPad->GetNetCode() );
@ -639,7 +640,7 @@ bool test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::doPadToPadsDrc( D_PAD* aRefPad, D
if( refPadShape->Collide( pad->GetEffectiveShape().get(), clearanceAllowed, &actual ) )
{
DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_CLEARANCE );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_CLEARANCE );
wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
/*m_clearanceSource fixme*/ "",
@ -726,7 +727,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZones()
if( smoothed_polys[ia2].Contains( currentVertex ) )
{
DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_ZONES_INTERSECT );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ZONES_INTERSECT );
drcItem->SetItems( zoneRef, zoneToTest );
drcItem->SetViolatingRule( rule );
@ -742,7 +743,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZones()
if( smoothed_polys[ia].Contains( currentVertex ) )
{
DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_ZONES_INTERSECT );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ZONES_INTERSECT );
drcItem->SetItems( zoneToTest, zoneRef );
drcItem->SetViolatingRule( rule );
@ -797,7 +798,7 @@ void test::DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZones()
for( const std::pair<const wxPoint, int>& conflict : conflictPoints )
{
int actual = conflict.second;
DRC_ITEM* drcItem;
std::shared_ptr<DRC_ITEM> drcItem;
if( actual <= 0 )
{

View File

@ -44,7 +44,9 @@
Errors generated:
- DRCE_COPPER_EDGE_CLEARANCE
TODO: holes to edge check
TODO:
- separate holes to edge check
- tester only looks for edge crossings. it doesn't check if items are inside/outside the board area.
*/
namespace test {
@ -70,7 +72,7 @@ public:
virtual const wxString GetDescription() const override
{
return "Tests copper item vs board edge clearance";
return "Tests items vs board edge clearance";
}
virtual std::set<test::DRC_RULE_ID_T> GetMatchingRuleIds() const override;
@ -83,76 +85,71 @@ private:
bool test::DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
{
auto bds = m_drcEngine->GetDesignSettings();
m_board = m_drcEngine->GetBoard();
DRC_CONSTRAINT worstClearanceConstraint;
m_largestClearance = 0;
for( auto rule : m_drcEngine->QueryRulesById( test::DRC_RULE_ID_T::DRC_RULE_ID_EDGE_CLEARANCE ) )
if( m_drcEngine->QueryWorstConstraint( test::DRC_RULE_ID_T::DRC_RULE_ID_EDGE_CLEARANCE, worstClearanceConstraint, DRCCQ_LARGEST_MINIMUM ) )
{
if( rule->GetConstraint().m_Value.HasMin() )
{
m_largestClearance = std::max( m_largestClearance, rule->GetConstraint().m_Value.Min() );
}
m_largestClearance = worstClearanceConstraint.m_Value.Min();
}
ReportAux( "Worst clearance : %d nm", m_largestClearance );
//m_largestClearance =
ReportStage( ("Testing all items <> Board Edge clearance"), 0, 2 );
std::vector<DRAWSEGMENT*> boardOutline;
std::vector<BOARD_ITEM*> boardItems;
for( auto item : m_board->Drawings() )
auto queryBoardOutlineItems = [&] ( BOARD_ITEM *item ) -> int
{
if( auto dseg = dyn_cast<DRAWSEGMENT*>( item ) )
{
drc_dbg(10,"L %d\n", dseg->GetLayer() );
if( dseg->GetLayer() == Edge_Cuts )
{
drc_dbg(10, "dseg ec %p\n", dseg);
boardOutline.push_back( dseg );
}
}
}
boardOutline.push_back( dyn_cast<DRAWSEGMENT*>( item ) );
};
for ( auto trk : m_board->Tracks() )
auto queryBoardGeometryItems = [&] ( BOARD_ITEM *item ) -> int
{
boardItems.push_back( trk );
}
boardItems.push_back( item );
};
for ( auto zone : m_board->Zones() )
{
boardItems.push_back( zone );
}
for ( auto zone : m_board->Zones() )
{
boardItems.push_back( zone );
}
forEachGeometryItem( { PCB_LINE_T }, LSET( Edge_Cuts ), queryBoardOutlineItems );
forEachGeometryItem( {}, LSET::AllTechMask() | LSET::AllCuMask(), queryBoardGeometryItems );
for ( auto mod : m_board->Modules() )
{
for ( auto dwg : mod->GraphicalItems() )
boardItems.push_back( dwg );
for ( auto pad : mod->Pads() )
boardItems.push_back( pad );
}
drc_dbg(2,"outline: %d items, board: %d items\n", boardOutline.size(), boardItems.size() );
for( auto outlineItem : boardOutline )
{
//printf("RefT %d\n", outlineItem->Type() );
auto refShape = outlineItem->GetEffectiveShape();
for( auto boardItem : boardItems )
{
// printf("BoardT %d\n", boardItem->Type() );
auto shape = boardItem->GetEffectiveShape();
(void) shape;
(void) refShape;
test::DRC_RULE* rule = m_drcEngine->EvalRulesForItems( test::DRC_RULE_ID_T::DRC_RULE_ID_EDGE_CLEARANCE, outlineItem, boardItem );
int minClearance = rule->GetConstraint().GetValue().Min();
int actual;
if( refShape->Collide( shape.get(), minClearance, &actual ) )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_COPPER_EDGE_CLEARANCE );
wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
rule->GetName(),
MessageTextFromValue( userUnits(), minClearance, true ),
MessageTextFromValue( userUnits(), actual, true ) );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( outlineItem, boardItem );
drcItem->SetViolatingRule( rule );
ReportWithMarker( drcItem, refShape->Centre() );
}
}
}

View File

@ -280,7 +280,7 @@ bool test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::doPadToPadHoleDrc( D_PAD* aRefPad,
// fixme: pad stacks...
if( refPadShape->Collide( pad->GetEffectiveHoleShape(), minClearance, &actual ) )
{
DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
wxString msg;
@ -312,7 +312,7 @@ bool test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::doPadToPadHoleDrc( D_PAD* aRefPad,
auto padShape = pad->GetEffectiveShape();
if( padShape->Collide( aRefPad->GetEffectiveHoleShape(), minClearance, &actual ) )
{
DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
@ -393,7 +393,7 @@ void test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::testHoles2Holes()
if( actual < minClearance )
{
DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
wxString msg;
msg.Printf( drcItem->GetErrorText() + _( " (clearance %s; actual %s)" ),

View File

@ -141,7 +141,7 @@ bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( D_PAD* aPad )
if( holeSize < minHole )
{
wxString msg;
DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_TOO_SMALL_DRILL );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_TOO_SMALL_DRILL );
msg.Printf( drcItem->GetErrorText() + _( " (%s; actual %s)" ),
MessageTextFromValue( userUnits(), minHole, true ),
@ -173,7 +173,7 @@ bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via )
int errorCode = via->GetViaType() == VIATYPE::MICROVIA ? DRCE_TOO_SMALL_MICROVIA_DRILL :
DRCE_TOO_SMALL_DRILL;
DRC_ITEM* drcItem = DRC_ITEM::Create( errorCode );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( errorCode );
msg.Printf( drcItem->GetErrorText() + _( " (%s; actual %s)" ),
MessageTextFromValue( userUnits(), minHole, true ),

View File

@ -25,7 +25,7 @@
#include <netlist_reader/pcb_netlist.h>
#include <drc/footprint_tester.h>
void TestFootprints( NETLIST& aNetlist, BOARD* aBoard, std::vector<DRC_ITEM*>& aDRCList )
void TestFootprints( NETLIST& aNetlist, BOARD* aBoard, std::vector<std::shared_ptr<DRC_ITEM> >& aDRCList )
{
wxString msg;