Redo DRC rules to get ready for new system.
This commit is contained in:
parent
2164501b06
commit
416d82727f
|
@ -1,8 +1,10 @@
|
|||
allow
|
||||
annulus_width
|
||||
blind_via
|
||||
board_edge
|
||||
clearance
|
||||
condition
|
||||
constraint
|
||||
disallow
|
||||
track_width
|
||||
graphic
|
||||
hole
|
||||
|
@ -10,10 +12,12 @@ match_area
|
|||
match_layer
|
||||
match_netclass
|
||||
match_type
|
||||
max
|
||||
micro_via
|
||||
min
|
||||
npth
|
||||
opt
|
||||
pad
|
||||
priority
|
||||
pth
|
||||
relaxed
|
||||
rule
|
||||
|
|
|
@ -397,10 +397,6 @@ public:
|
|||
*/
|
||||
int GetSmallestClearanceValue();
|
||||
|
||||
int GetRuleClearance( const BOARD_ITEM* aItem, const NETCLASS* aItemNetclass,
|
||||
const BOARD_ITEM* bItem, const NETCLASS* bItemNetclass,
|
||||
wxString* aSource );
|
||||
|
||||
/**
|
||||
* Function GetCurrentMicroViaSize
|
||||
* @return the current micro via size,
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -23,11 +23,6 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file board_connected_item.cpp
|
||||
* @brief BOARD_CONNECTED_ITEM class functions.
|
||||
*/
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <pcbnew.h>
|
||||
|
||||
|
@ -37,9 +32,6 @@
|
|||
#include <connectivity/connectivity_data.h>
|
||||
|
||||
|
||||
const wxChar* const traceMask = wxT( "BOARD_CONNECTED_ITEM" );
|
||||
|
||||
|
||||
BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ) :
|
||||
BOARD_ITEM( aParent, idtype ), m_netinfo( NETINFO_LIST::OrphanedItem() )
|
||||
{
|
||||
|
@ -79,6 +71,27 @@ bool BOARD_CONNECTED_ITEM::SetNetCode( int aNetCode, bool aNoAssert )
|
|||
}
|
||||
|
||||
|
||||
// This method returns the Default netclass for nets which don't have their own.
|
||||
NETCLASS* BOARD_CONNECTED_ITEM::GetEffectiveNetclass() const
|
||||
{
|
||||
// NB: we must check the net first, as when it is 0 GetNetClass() will return the
|
||||
// orphaned net netclass, not the default netclass.
|
||||
if( m_netinfo->GetNet() == 0 )
|
||||
return GetBoard()->GetDesignSettings().GetDefault();
|
||||
else
|
||||
return GetNetClass();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Clearances exist in a hiearchy:
|
||||
* 1) accumulated board & netclass constraints
|
||||
* 2) last rule whose condition evaluates to true
|
||||
* 4) footprint override
|
||||
* 5) pad override
|
||||
*
|
||||
* The base class handles (1) and (2).
|
||||
*/
|
||||
int BOARD_CONNECTED_ITEM::GetClearance( BOARD_ITEM* aItem, wxString* aSource ) const
|
||||
{
|
||||
BOARD* board = GetBoard();
|
||||
|
@ -87,64 +100,51 @@ int BOARD_CONNECTED_ITEM::GetClearance( BOARD_ITEM* aItem, wxString* aSource ) c
|
|||
if( !board )
|
||||
return 0;
|
||||
|
||||
BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
|
||||
NETCLASS* myNetclass = nullptr;
|
||||
NETCLASS* itemNetclass = nullptr;
|
||||
DRC_RULE* rule = GetRule( this, aItem, CLEARANCE_CONSTRAINT );
|
||||
|
||||
// NB: we must check the net first, as when it is 0 GetNetClass() will return the
|
||||
// orphaned net netclass, not the default netclass.
|
||||
if( m_netinfo->GetNet() == 0 )
|
||||
myNetclass = bds.GetDefault();
|
||||
else
|
||||
myNetclass = GetNetClass();
|
||||
if( rule )
|
||||
{
|
||||
if( aSource )
|
||||
*aSource = wxString::Format( _( "'%s' rule clearance" ), rule->m_Name );
|
||||
|
||||
return rule->m_Clearance.Min;
|
||||
}
|
||||
|
||||
BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
|
||||
int clearance = bds.m_MinClearance;
|
||||
|
||||
if( aSource )
|
||||
*aSource = _( "board minimum" );
|
||||
|
||||
NETCLASS* netclass = GetEffectiveNetclass();
|
||||
|
||||
if( netclass && netclass->GetClearance() > clearance )
|
||||
{
|
||||
clearance = netclass->GetClearance();
|
||||
|
||||
if( aSource )
|
||||
*aSource = wxString::Format( _( "'%s' netclass" ), netclass->GetName() );
|
||||
}
|
||||
|
||||
if( aItem && aItem->IsConnected() )
|
||||
{
|
||||
if( static_cast<BOARD_CONNECTED_ITEM*>( aItem )->GetNet()->GetNet() == 0 )
|
||||
itemNetclass = bds.GetDefault();
|
||||
else
|
||||
itemNetclass = static_cast<BOARD_CONNECTED_ITEM*>( aItem )->GetNetClass();
|
||||
}
|
||||
netclass = static_cast<BOARD_CONNECTED_ITEM*>( aItem )->GetEffectiveNetclass();
|
||||
|
||||
int clearance = bds.GetRuleClearance( this, myNetclass, aItem, itemNetclass, aSource );
|
||||
|
||||
if( myNetclass )
|
||||
{
|
||||
int myClearance = myNetclass->GetClearance();
|
||||
|
||||
if( myClearance > clearance )
|
||||
if( netclass && netclass->GetClearance() > clearance )
|
||||
{
|
||||
clearance = myClearance;
|
||||
clearance = netclass->GetClearance();
|
||||
|
||||
if( aSource )
|
||||
*aSource = wxString::Format( _( "'%s' netclass" ), myNetclass->GetName() );
|
||||
*aSource = wxString::Format( _( "'%s' netclass" ), netclass->GetName() );
|
||||
}
|
||||
}
|
||||
|
||||
if( itemNetclass )
|
||||
if( aItem && aItem->GetLayer() == Edge_Cuts && bds.m_CopperEdgeClearance > clearance )
|
||||
{
|
||||
int itemClearance = myNetclass->GetClearance();
|
||||
clearance = bds.m_CopperEdgeClearance;
|
||||
|
||||
if( itemClearance > clearance )
|
||||
{
|
||||
clearance = itemClearance;
|
||||
|
||||
if( aSource )
|
||||
*aSource = wxString::Format( _( "'%s' netclass" ), itemNetclass->GetName() );
|
||||
}
|
||||
}
|
||||
|
||||
if( aItem && aItem->GetLayer() == Edge_Cuts )
|
||||
{
|
||||
int edgeClearance = bds.m_CopperEdgeClearance;
|
||||
|
||||
if( edgeClearance > clearance )
|
||||
{
|
||||
clearance = edgeClearance;
|
||||
|
||||
if( aSource )
|
||||
*aSource = _( "board edge" );
|
||||
}
|
||||
if( aSource )
|
||||
*aSource = _( "board edge" );
|
||||
}
|
||||
|
||||
return clearance;
|
||||
|
|
|
@ -172,6 +172,15 @@ public:
|
|||
*/
|
||||
NETCLASS* GetNetClass() const;
|
||||
|
||||
/**
|
||||
* Function GetEffectiveNetclass
|
||||
* returns the NETCLASS for this item, or the default netclass if none is defined.
|
||||
*
|
||||
* Note: do NOT return a std::shared_ptr from this. It is used heavily in DRC, and the
|
||||
* std::shared_ptr stuff shows up large in performance profiling.
|
||||
*/
|
||||
NETCLASS* GetEffectiveNetclass() const;
|
||||
|
||||
/**
|
||||
* Function GetNetClassName
|
||||
* returns a pointer to the netclass of the zone.
|
||||
|
|
|
@ -21,11 +21,6 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file board_design_settings.cpp
|
||||
* BOARD_DESIGN_SETTINGS class functions.
|
||||
*/
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <common.h>
|
||||
#include <class_board.h>
|
||||
|
@ -967,7 +962,7 @@ int BOARD_DESIGN_SETTINGS::GetBiggestClearanceValue()
|
|||
clearance = std::max( clearance, netclass.second->GetClearance() );
|
||||
|
||||
for( const DRC_RULE* rule : m_DRCRules )
|
||||
clearance = std::max( clearance, rule->m_Clearance );
|
||||
clearance = std::max( clearance, rule->m_Clearance.Min );
|
||||
|
||||
return clearance;
|
||||
}
|
||||
|
@ -984,58 +979,6 @@ int BOARD_DESIGN_SETTINGS::GetSmallestClearanceValue()
|
|||
}
|
||||
|
||||
|
||||
int BOARD_DESIGN_SETTINGS::GetRuleClearance( const BOARD_ITEM* aItem, const NETCLASS* aNetclass,
|
||||
const BOARD_ITEM* bItem, const NETCLASS* bNetclass,
|
||||
wxString* aSource )
|
||||
{
|
||||
if( !m_matched.empty() )
|
||||
m_matched.clear(); // yes, the difference can be seen in profiles
|
||||
|
||||
if( m_DRCRuleSelectors.size() == 0 )
|
||||
return 0;
|
||||
|
||||
MatchSelectors( m_DRCRuleSelectors, aItem, aNetclass, bItem, bNetclass, &m_matched );
|
||||
|
||||
if( m_matched.size() == 0 )
|
||||
return 0;
|
||||
|
||||
std::sort( m_matched.begin(), m_matched.end(),
|
||||
[]( DRC_SELECTOR* a, DRC_SELECTOR* b ) -> bool
|
||||
{
|
||||
return a->m_Priority < b->m_Priority;
|
||||
});
|
||||
|
||||
int clearance = 0;
|
||||
|
||||
for( DRC_SELECTOR* selector : m_matched )
|
||||
{
|
||||
// ignore hole rules; we're just interested in copper here
|
||||
for( KICAD_T matchType : selector->m_MatchTypes )
|
||||
{
|
||||
if( BaseType( matchType ) == PCB_LOCATE_HOLE_T )
|
||||
continue;
|
||||
}
|
||||
|
||||
if( selector->m_Rule->m_Clearance > 0 )
|
||||
{
|
||||
clearance = std::max( clearance, selector->m_Rule->m_Clearance );
|
||||
|
||||
if( aSource )
|
||||
*aSource = wxString::Format( _( "'%s' rule clearance" ), selector->m_Rule->m_Name );
|
||||
}
|
||||
else if( selector->m_Rule->m_Clearance < 0 )
|
||||
{
|
||||
clearance = std::min( clearance, abs( selector->m_Rule->m_Clearance ) );
|
||||
|
||||
if( aSource )
|
||||
*aSource = wxString::Format( _( "'%s' rule clearance" ), selector->m_Rule->m_Name );
|
||||
}
|
||||
}
|
||||
|
||||
return clearance;
|
||||
}
|
||||
|
||||
|
||||
int BOARD_DESIGN_SETTINGS::GetCurrentMicroViaSize()
|
||||
{
|
||||
NETCLASSPTR netclass = m_NetClasses.Find( m_currentNetClassName );
|
||||
|
@ -1122,26 +1065,11 @@ void BOARD_DESIGN_SETTINGS::SetElementVisibility( GAL_LAYER_ID aElementCategory,
|
|||
|
||||
void BOARD_DESIGN_SETTINGS::SetCopperLayerCount( int aNewLayerCount )
|
||||
{
|
||||
// if( aNewLayerCount < 2 ) aNewLayerCount = 2;
|
||||
|
||||
m_copperLayerCount = aNewLayerCount;
|
||||
|
||||
// ensure consistency with the m_EnabledLayers member
|
||||
#if 0
|
||||
// was:
|
||||
m_enabledLayers &= ~ALL_CU_LAYERS;
|
||||
m_enabledLayers |= LAYER_BACK;
|
||||
|
||||
if( m_copperLayerCount > 1 )
|
||||
m_enabledLayers |= LAYER_FRONT;
|
||||
|
||||
for( LAYER_NUM ii = LAYER_N_2; ii < aNewLayerCount - 1; ++ii )
|
||||
m_enabledLayers |= GetLayerSet( ii );
|
||||
#else
|
||||
// Update only enabled copper layers mask
|
||||
m_enabledLayers &= ~LSET::AllCuMask();
|
||||
m_enabledLayers |= LSET::AllCuMask( aNewLayerCount );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -615,33 +615,25 @@ wxPoint D_PAD::ShapePos() const
|
|||
|
||||
int D_PAD::GetClearance( BOARD_ITEM* aItem, wxString* aSource ) const
|
||||
{
|
||||
int clearance;
|
||||
|
||||
// A pad can have specific clearance that overrides its NETCLASS clearance value
|
||||
if( m_LocalClearance )
|
||||
{
|
||||
clearance = m_LocalClearance;
|
||||
|
||||
if( aSource )
|
||||
*aSource = wxString::Format( _( "pad %s" ), GetName() );
|
||||
|
||||
return m_LocalClearance;
|
||||
}
|
||||
|
||||
// A footprint can have a specific clearance value
|
||||
else if( GetParent() && GetParent()->GetLocalClearance() )
|
||||
if( GetParent() && GetParent()->GetLocalClearance() )
|
||||
{
|
||||
clearance = GetParent()->GetLocalClearance();
|
||||
|
||||
if( aSource )
|
||||
*aSource = wxString::Format( _( "%s footprint" ), GetParent()->GetReference() );
|
||||
|
||||
return GetParent()->GetLocalClearance();
|
||||
}
|
||||
|
||||
// Otherwise use the baseclass method to fetch the netclass and/or rule setting
|
||||
else
|
||||
{
|
||||
clearance = BOARD_CONNECTED_ITEM::GetClearance( aItem, aSource );
|
||||
}
|
||||
|
||||
return clearance;
|
||||
return BOARD_CONNECTED_ITEM::GetClearance( aItem, aSource );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -125,75 +125,52 @@ int TRACK::GetClearance( BOARD_ITEM* aItem, wxString* aSource ) const
|
|||
}
|
||||
|
||||
|
||||
int TRACK::GetMinWidth( wxString* aSource ) const
|
||||
/*
|
||||
* Width constraints exist in a hiearchy:
|
||||
* 1) accumulated board & netclass constraints
|
||||
* 2) last rule whose condition evaluates to true
|
||||
*/
|
||||
void TRACK::GetWidthConstraints( int* aMin, int* aMax, wxString* aSource ) const
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS& bds = GetBoard()->GetDesignSettings();
|
||||
NETCLASS* netclass = nullptr;
|
||||
std::vector<DRC_SELECTOR*> matched;
|
||||
DRC_RULE* rule = GetRule( this, nullptr, TRACK_CONSTRAINT );
|
||||
|
||||
// NB: we must check the net first, as when it is 0 GetNetClass() will return the
|
||||
// orphaned net netclass, not the default netclass.
|
||||
if( m_netinfo->GetNet() == 0 )
|
||||
netclass = bds.GetDefault();
|
||||
else
|
||||
netclass = GetNetClass();
|
||||
|
||||
MatchSelectors( bds.m_DRCRuleSelectors, this, netclass, nullptr, nullptr, &matched );
|
||||
|
||||
int minWidth = bds.m_TrackMinWidth;
|
||||
|
||||
if( aSource )
|
||||
*aSource = _( "board minumum" );
|
||||
|
||||
for( DRC_SELECTOR* selector : matched )
|
||||
if( rule )
|
||||
{
|
||||
if( selector->m_Rule->m_TrackWidth > minWidth )
|
||||
{
|
||||
minWidth = selector->m_Rule->m_TrackWidth;
|
||||
*aMin = rule->m_TrackConstraint.Min;
|
||||
*aMax = rule->m_TrackConstraint.Max;
|
||||
|
||||
if( aSource )
|
||||
*aSource = wxString::Format( _( "'%s' rule" ), selector->m_Rule->m_Name );
|
||||
}
|
||||
if( aSource )
|
||||
*aSource = wxString::Format( _( "'%s' rule" ), rule->m_Name );
|
||||
}
|
||||
else
|
||||
{
|
||||
*aMin = GetBoard()->GetDesignSettings().m_TrackMinWidth;
|
||||
*aMax = INT_MAX / 2;
|
||||
|
||||
return minWidth;
|
||||
if( aSource )
|
||||
*aSource = _( "board minumum" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int VIA::GetMinAnnulus( wxString* aSource ) const
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS& bds = GetBoard()->GetDesignSettings();
|
||||
NETCLASS* netclass = nullptr;
|
||||
std::vector<DRC_SELECTOR*> matched;
|
||||
DRC_RULE* rule = GetRule( this, nullptr, ANNULUS_CONSTRAINT );
|
||||
|
||||
// NB: we must check the net first, as when it is 0 GetNetClass() will return the
|
||||
// orphaned net netclass, not the default netclass.
|
||||
if( m_netinfo->GetNet() == 0 )
|
||||
netclass = bds.GetDefault();
|
||||
else
|
||||
netclass = GetNetClass();
|
||||
|
||||
MatchSelectors( bds.m_DRCRuleSelectors, this, netclass, nullptr, nullptr, &matched );
|
||||
|
||||
int minAnnulus = bds.m_ViasMinAnnulus;
|
||||
|
||||
if( aSource )
|
||||
*aSource = _( "board minumum" );
|
||||
|
||||
MatchSelectors( bds.m_DRCRuleSelectors, this, netclass, nullptr, nullptr, &matched );
|
||||
|
||||
for( DRC_SELECTOR* selector : matched )
|
||||
if( rule )
|
||||
{
|
||||
if( selector->m_Rule->m_AnnulusWidth > minAnnulus )
|
||||
{
|
||||
minAnnulus = selector->m_Rule->m_AnnulusWidth;
|
||||
if( aSource )
|
||||
*aSource = wxString::Format( _( "'%s' rule" ), rule->m_Name );
|
||||
|
||||
if( aSource )
|
||||
*aSource = wxString::Format( _( "'%s' rule" ), selector->m_Rule->m_Name );
|
||||
}
|
||||
return rule->m_MinAnnulusWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( aSource )
|
||||
*aSource = _( "board minumum" );
|
||||
|
||||
return minAnnulus;
|
||||
return GetBoard()->GetDesignSettings().m_ViasMinAnnulus;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -634,7 +611,8 @@ void TRACK::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>
|
|||
msg2.Printf( _( "(from %s)" ), source );
|
||||
aList.emplace_back( msg, msg2, BLACK );
|
||||
|
||||
int minWidth = GetMinWidth( &source );
|
||||
int minWidth, maxWidth;
|
||||
GetWidthConstraints( &minWidth, &maxWidth, &source );
|
||||
|
||||
msg.Printf( _( "Min Width: %s" ), MessageTextFromValue( units, minWidth, true ) );
|
||||
msg2.Printf( _( "(from %s)" ), source );
|
||||
|
|
|
@ -212,7 +212,7 @@ public:
|
|||
*/
|
||||
int GetClearance( BOARD_ITEM* aItem = nullptr, wxString* aSource = nullptr ) const override;
|
||||
|
||||
int GetMinWidth( wxString* aSource ) const;
|
||||
void GetWidthConstraints( int* aMin, int* aMax, wxString* aSource ) const;
|
||||
|
||||
wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
|
||||
|
||||
|
|
|
@ -463,7 +463,58 @@ int ZONE_CONTAINER::GetClearance( BOARD_ITEM* aItem, wxString* aSource ) const
|
|||
if( m_isKeepout )
|
||||
return 0;
|
||||
|
||||
int clearance = BOARD_CONNECTED_ITEM::GetClearance( aItem, aSource );
|
||||
BOARD* board = GetBoard();
|
||||
|
||||
// No clearance if "this" is not (yet) linked to a board
|
||||
if( !board )
|
||||
return 0;
|
||||
|
||||
DRC_RULE* rule = GetRule( this, aItem, CLEARANCE_CONSTRAINT );
|
||||
|
||||
if( rule )
|
||||
{
|
||||
if( aSource )
|
||||
*aSource = wxString::Format( _( "'%s' rule clearance" ), rule->m_Name );
|
||||
|
||||
return rule->m_Clearance.Min;
|
||||
}
|
||||
|
||||
BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
|
||||
int clearance = bds.m_MinClearance;
|
||||
|
||||
if( aSource )
|
||||
*aSource = _( "board minimum" );
|
||||
|
||||
NETCLASS* netclass = GetEffectiveNetclass();
|
||||
|
||||
if( netclass && netclass->GetClearance() > clearance )
|
||||
{
|
||||
clearance = netclass->GetClearance();
|
||||
|
||||
if( aSource )
|
||||
*aSource = wxString::Format( _( "'%s' netclass" ), netclass->GetName() );
|
||||
}
|
||||
|
||||
if( aItem && aItem->IsConnected() )
|
||||
{
|
||||
netclass = static_cast<BOARD_CONNECTED_ITEM*>( aItem )->GetEffectiveNetclass();
|
||||
|
||||
if( netclass && netclass->GetClearance() > clearance )
|
||||
{
|
||||
clearance = netclass->GetClearance();
|
||||
|
||||
if( aSource )
|
||||
*aSource = wxString::Format( _( "'%s' netclass" ), netclass->GetName() );
|
||||
}
|
||||
}
|
||||
|
||||
if( aItem && aItem->GetLayer() == Edge_Cuts && bds.m_CopperEdgeClearance > clearance )
|
||||
{
|
||||
clearance = bds.m_CopperEdgeClearance;
|
||||
|
||||
if( aSource )
|
||||
*aSource = _( "board edge" );
|
||||
}
|
||||
|
||||
if( m_ZoneClearance > clearance )
|
||||
{
|
||||
|
|
|
@ -27,7 +27,7 @@ PANEL_SETUP_NETCLASSES_BASE::PANEL_SETUP_NETCLASSES_BASE( wxWindow* parent, wxWi
|
|||
m_netclassGrid = new WX_GRID( m_netclassesPane, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_DEFAULT|wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL );
|
||||
|
||||
// Grid
|
||||
m_netclassGrid->CreateGrid( 1, 9 );
|
||||
m_netclassGrid->CreateGrid( 1, 10 );
|
||||
m_netclassGrid->EnableEditing( true );
|
||||
m_netclassGrid->EnableGridLines( true );
|
||||
m_netclassGrid->EnableDragGridSize( false );
|
||||
|
@ -41,8 +41,9 @@ PANEL_SETUP_NETCLASSES_BASE::PANEL_SETUP_NETCLASSES_BASE( wxWindow* parent, wxWi
|
|||
m_netclassGrid->SetColSize( 4, 96 );
|
||||
m_netclassGrid->SetColSize( 5, 96 );
|
||||
m_netclassGrid->SetColSize( 6, 96 );
|
||||
m_netclassGrid->SetColSize( 7, 96 );
|
||||
m_netclassGrid->SetColSize( 8, 96 );
|
||||
m_netclassGrid->SetColSize( 7, 60 );
|
||||
m_netclassGrid->SetColSize( 8, 60 );
|
||||
m_netclassGrid->SetColSize( 9, 60 );
|
||||
m_netclassGrid->EnableDragColMove( false );
|
||||
m_netclassGrid->EnableDragColSize( true );
|
||||
m_netclassGrid->SetColLabelSize( 24 );
|
||||
|
@ -53,8 +54,9 @@ PANEL_SETUP_NETCLASSES_BASE::PANEL_SETUP_NETCLASSES_BASE( wxWindow* parent, wxWi
|
|||
m_netclassGrid->SetColLabelValue( 4, _("Via Drill") );
|
||||
m_netclassGrid->SetColLabelValue( 5, _("uVia Size") );
|
||||
m_netclassGrid->SetColLabelValue( 6, _("uVia Drill") );
|
||||
m_netclassGrid->SetColLabelValue( 7, _("dPair Width") );
|
||||
m_netclassGrid->SetColLabelValue( 8, _("dPair Gap") );
|
||||
m_netclassGrid->SetColLabelValue( 7, _("DP Width") );
|
||||
m_netclassGrid->SetColLabelValue( 8, _("DP Gap") );
|
||||
m_netclassGrid->SetColLabelValue( 9, _("DP Via Gap") );
|
||||
m_netclassGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
|
||||
|
||||
// Rows
|
||||
|
|
|
@ -155,10 +155,10 @@
|
|||
<property name="close_button">1</property>
|
||||
<property name="col_label_horiz_alignment">wxALIGN_CENTER</property>
|
||||
<property name="col_label_size">24</property>
|
||||
<property name="col_label_values">"Name" "Clearance" "Track Width" "Via Size" "Via Drill" "uVia Size" "uVia Drill" "dPair Width" "dPair Gap"</property>
|
||||
<property name="col_label_values">"Name" "Clearance" "Track Width" "Via Size" "Via Drill" "uVia Size" "uVia Drill" "DP Width" "DP Gap" "DP Via Gap"</property>
|
||||
<property name="col_label_vert_alignment">wxALIGN_CENTER</property>
|
||||
<property name="cols">9</property>
|
||||
<property name="column_sizes">130,96,96,96,96,96,96,96,96</property>
|
||||
<property name="cols">10</property>
|
||||
<property name="column_sizes">130,96,96,96,96,96,96,60,60,60</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
|
|
|
@ -383,6 +383,8 @@ void DRC::LoadRules()
|
|||
}
|
||||
}
|
||||
|
||||
std::reverse( std::begin( m_ruleSelectors ), std::end( m_ruleSelectors ) );
|
||||
|
||||
BOARD_DESIGN_SETTINGS& bds = m_pcb->GetDesignSettings();
|
||||
bds.m_DRCRuleSelectors = m_ruleSelectors;
|
||||
bds.m_DRCRules = m_rules;
|
||||
|
|
|
@ -65,6 +65,7 @@ enum PCB_DRC_CODE {
|
|||
DRCE_HOLE_NEAR_TRACK, ///< hole too close to track
|
||||
DRCE_DRILLED_HOLES_TOO_CLOSE, ///< overlapping drilled holes break drill bits
|
||||
DRCE_TOO_SMALL_TRACK_WIDTH, ///< Too small track width
|
||||
DRCE_TOO_LARGE_TRACK_WIDTH, ///< Too small track width
|
||||
DRCE_TOO_SMALL_VIA, ///< Too small via size
|
||||
DRCE_TOO_SMALL_VIA_ANNULUS, ///< Via size and drill leave annulus too small
|
||||
DRCE_TOO_SMALL_VIA_DRILL, ///< Too small via drill
|
||||
|
|
|
@ -315,17 +315,32 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS
|
|||
}
|
||||
else // This is a track segment
|
||||
{
|
||||
int minWidth = aRefSeg->GetMinWidth( &m_clearanceSource );
|
||||
int minWidth, maxWidth;
|
||||
aRefSeg->GetWidthConstraints( &minWidth, &maxWidth, &m_clearanceSource );
|
||||
|
||||
int errorCode = 0;
|
||||
int constraintWidth;
|
||||
|
||||
if( refSegWidth < minWidth )
|
||||
{
|
||||
errorCode = DRCE_TOO_SMALL_TRACK_WIDTH;
|
||||
constraintWidth = minWidth;
|
||||
}
|
||||
else if( refSegWidth > maxWidth )
|
||||
{
|
||||
errorCode = DRCE_TOO_LARGE_TRACK_WIDTH;
|
||||
constraintWidth = maxWidth;
|
||||
}
|
||||
|
||||
if( errorCode )
|
||||
{
|
||||
wxPoint refsegMiddle = ( aRefSeg->GetStart() + aRefSeg->GetEnd() ) / 2;
|
||||
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_TRACK_WIDTH );
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( errorCode );
|
||||
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ),
|
||||
m_clearanceSource,
|
||||
MessageTextFromValue( userUnits(), minWidth, true ),
|
||||
MessageTextFromValue( userUnits(), constraintWidth, true ),
|
||||
MessageTextFromValue( userUnits(), refSegWidth, true ) );
|
||||
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
|
|
|
@ -91,21 +91,14 @@ bool DRC_DRILLED_HOLE_TESTER::checkPad( D_PAD* aPad )
|
|||
|
||||
if( !bds.Ignore( DRCE_TOO_SMALL_PAD_DRILL ) )
|
||||
{
|
||||
NETCLASS* netclass = aPad->GetNet()->GetNet() == 0 ? bds.GetDefault()
|
||||
: aPad->GetNetClass();
|
||||
int minHole = bds.m_MinThroughDrill;
|
||||
wxString minHoleSource = _( "board minimum" );
|
||||
DRC_RULE* rule = GetRule( aPad, nullptr, HOLE_CONSTRAINT );
|
||||
|
||||
std::vector<DRC_SELECTOR*> matched;
|
||||
MatchSelectors( bds.m_DRCRuleSelectors, aPad, netclass, nullptr, nullptr, &matched );
|
||||
|
||||
for( DRC_SELECTOR* selector : matched )
|
||||
if( rule )
|
||||
{
|
||||
if( selector->m_Rule->m_Hole > minHole )
|
||||
{
|
||||
minHole = selector->m_Rule->m_Hole;
|
||||
minHoleSource = wxString::Format( _( "'%s' rule" ), selector->m_Rule->m_Name );
|
||||
}
|
||||
minHole = rule->m_MinHole;
|
||||
minHoleSource = wxString::Format( _( "'%s' rule" ), rule->m_Name );
|
||||
}
|
||||
|
||||
if( holeSize < minHole )
|
||||
|
@ -141,21 +134,14 @@ bool DRC_DRILLED_HOLE_TESTER::checkVia( VIA* via )
|
|||
|
||||
if( !bds.Ignore( DRCE_TOO_SMALL_VIA_DRILL ) )
|
||||
{
|
||||
NETCLASS* netclass = via->GetNet()->GetNet() == 0 ? bds.GetDefault()
|
||||
: via->GetNetClass();
|
||||
int minHole = bds.m_MinThroughDrill;
|
||||
wxString minHoleSource = _( "board minimum" );
|
||||
DRC_RULE* rule = GetRule( via, nullptr, HOLE_CONSTRAINT );
|
||||
|
||||
std::vector<DRC_SELECTOR*> matched;
|
||||
MatchSelectors( bds.m_DRCRuleSelectors, via, netclass, nullptr, nullptr, &matched );
|
||||
|
||||
for( DRC_SELECTOR* selector : matched )
|
||||
if( rule )
|
||||
{
|
||||
if( selector->m_Rule->m_Hole > minHole )
|
||||
{
|
||||
minHole = selector->m_Rule->m_Hole;
|
||||
minHoleSource = wxString::Format( _( "'%s' rule" ), selector->m_Rule->m_Name );
|
||||
}
|
||||
minHole = rule->m_MinHole;
|
||||
minHoleSource = wxString::Format( _( "'%s' rule" ), rule->m_Name );
|
||||
}
|
||||
|
||||
if( via->GetDrillValue() < minHole )
|
||||
|
@ -191,21 +177,14 @@ bool DRC_DRILLED_HOLE_TESTER::checkMicroVia( VIA* via )
|
|||
|
||||
if( !bds.Ignore( DRCE_TOO_SMALL_MICROVIA_DRILL ) )
|
||||
{
|
||||
NETCLASS* netclass = via->GetNet()->GetNet() == 0 ? bds.GetDefault()
|
||||
: via->GetNetClass();
|
||||
int minHole = bds.m_MicroViasMinDrill;
|
||||
wxString minHoleSource = _( "board minimum" );
|
||||
DRC_RULE* rule = GetRule( via, nullptr, HOLE_CONSTRAINT );
|
||||
|
||||
std::vector<DRC_SELECTOR*> matched;
|
||||
MatchSelectors( bds.m_DRCRuleSelectors, via, netclass, nullptr, nullptr, &matched );
|
||||
|
||||
for( DRC_SELECTOR* selector : matched )
|
||||
if( rule )
|
||||
{
|
||||
if( selector->m_Rule->m_Hole > minHole )
|
||||
{
|
||||
minHole = selector->m_Rule->m_Hole;
|
||||
minHoleSource = wxString::Format( _( "'%s' rule" ), selector->m_Rule->m_Name );
|
||||
}
|
||||
minHole = rule->m_MinHole;
|
||||
minHoleSource = wxString::Format( _( "'%s' rule" ), rule->m_Name );
|
||||
}
|
||||
|
||||
if( via->GetDrillValue() < minHole )
|
||||
|
|
|
@ -84,6 +84,7 @@ wxString DRC_ITEM::GetErrorText( int aCode, bool aTranslate ) const
|
|||
case DRCE_HOLE_NEAR_PAD: msg = _HKI( "Hole too close to pad" ); break;
|
||||
case DRCE_HOLE_NEAR_TRACK: msg = _HKI( "Hole too close to track" ); break;
|
||||
case DRCE_TOO_SMALL_TRACK_WIDTH: msg = _HKI( "Track width too small" ); break;
|
||||
case DRCE_TOO_LARGE_TRACK_WIDTH: msg = _HKI( "Track width too large" ); break;
|
||||
case DRCE_TOO_SMALL_VIA: msg = _HKI( "Via size too small" ); break;
|
||||
case DRCE_TOO_SMALL_VIA_ANNULUS: msg = _HKI( "Via annulus too small" ); break;
|
||||
case DRCE_TOO_SMALL_MICROVIA: msg = _HKI( "Micro via size too small" ); break;
|
||||
|
|
|
@ -29,31 +29,12 @@
|
|||
#include <class_board_item.h>
|
||||
|
||||
/*
|
||||
* Match tokens:
|
||||
* match_netclass
|
||||
* match_type
|
||||
* match_layer
|
||||
* match_all
|
||||
* match_area
|
||||
* Rule tokens:
|
||||
* disallow
|
||||
* constraint
|
||||
* condition
|
||||
*
|
||||
* (selector (match_area "$board") (rule "OSHParkClass3") (priority 100))
|
||||
*
|
||||
* (selector (match_netclass "HV") (rule "HV_internal"))
|
||||
* (selector (match_netclass "HV") (match_layer "F_Cu") (rule "HV_external"))
|
||||
* (selector (match_netclass "HV") (match_layer "B_Cu") (rule "HV_external"))
|
||||
*
|
||||
* (selector (match_netclass "HV") (match_netclass "HV") (rule "HV2HV"))
|
||||
* (selector (match_netclass "HV") (match_netclass "HV") (match_layer "F_Cu") (rule "HV2HV_external"))
|
||||
* (selector (match_netclass "HV") (match_netclass "HV") (match_layer "B_Cu") (rule "HV2HV_external"))
|
||||
*
|
||||
* TODO: pads for connector pins or wire pads have even larger clearances. How to encode?
|
||||
* User attributes on parent footprint?
|
||||
*
|
||||
* (selector (match_netclass "HV") (match_type "pad") (match_netclass "HV") (match_type "pad") (rule "pad2PadHV"))
|
||||
*
|
||||
* (selector (match_netclass "signal") (match_area "BGA") (rule "neckdown"))
|
||||
*
|
||||
* Type tokens:
|
||||
* Disallow types:
|
||||
* track
|
||||
* via
|
||||
* micro_via
|
||||
|
@ -62,40 +43,46 @@
|
|||
* zone
|
||||
* text
|
||||
* graphic
|
||||
* board_edge
|
||||
* hole
|
||||
* npth
|
||||
* pth
|
||||
*
|
||||
* Rule tokens:
|
||||
* allow
|
||||
* Constraint types:
|
||||
* clearance
|
||||
* annulus_width
|
||||
* track_width
|
||||
* hole
|
||||
*
|
||||
* Rule modifiers:
|
||||
* relaxed
|
||||
*
|
||||
* (rule "HV" (clearance 200) (priority 200))
|
||||
* (rule "HV_external" (clearance 400) (priority 200))
|
||||
* (rule "HV2HV" (clearance 200) (priority 200))
|
||||
* (rule "HV2HV_external" (clearance 500) (priority 200))
|
||||
* (rule "pad2padHV" (clearance 500) (priority 200))
|
||||
* (rule "HV" (constraint clearance (min 200)))
|
||||
* (rule "HV_external" (constraint clearance (min 400)))
|
||||
* (rule "HV2HV" (constraint clearance (min 200)))
|
||||
* (rule "HV2HV_external" (constraint clearance (min 500)))
|
||||
* (rule "pad2padHV" (constraint clearance (min 500)))
|
||||
*
|
||||
* (rule "signal" (clearance 20)) // implied priority of 1
|
||||
* (rule "neckdown" (clearance relaxed 15) (priority 2))
|
||||
* (rule "signal" (constraint clearance (min 20)))
|
||||
* (rule "neckdown" (constraint clearance (min 15)))
|
||||
*
|
||||
* (rule "allowMicrovias" (allow microvia))
|
||||
* (rule "disallowMicrovias" (disallow micro_via))
|
||||
*/
|
||||
|
||||
|
||||
void MatchSelectors( const std::vector<DRC_SELECTOR*>& aSelectors,
|
||||
const BOARD_ITEM* aItem, const NETCLASS* aNetclass,
|
||||
const BOARD_ITEM* bItem, const NETCLASS* bNetclass,
|
||||
std::vector<DRC_SELECTOR*>* aSelected )
|
||||
DRC_RULE* GetRule( const BOARD_ITEM* aItem, const BOARD_ITEM* bItem, int aConstraint )
|
||||
{
|
||||
for( DRC_SELECTOR* candidate : aSelectors )
|
||||
// JEY TODO: the bulk of this will be replaced by Tom's expression evaluator
|
||||
|
||||
BOARD* board = aItem->GetBoard();
|
||||
|
||||
if( !board )
|
||||
return nullptr;
|
||||
|
||||
NETCLASS* aNetclass = nullptr;
|
||||
NETCLASS* bNetclass = nullptr;
|
||||
|
||||
if( aItem->IsConnected() )
|
||||
aNetclass = static_cast<const BOARD_CONNECTED_ITEM*>( aItem )->GetEffectiveNetclass();
|
||||
|
||||
if( bItem && bItem->IsConnected() )
|
||||
bNetclass = static_cast<const BOARD_CONNECTED_ITEM*>( bItem )->GetEffectiveNetclass();
|
||||
|
||||
for( DRC_SELECTOR* candidate : board->GetDesignSettings().m_DRCRuleSelectors )
|
||||
{
|
||||
if( candidate->m_MatchNetclasses.size() == 2 )
|
||||
{
|
||||
|
@ -145,11 +132,8 @@ void MatchSelectors( const std::vector<DRC_SELECTOR*>& aSelectors,
|
|||
{
|
||||
PCB_LAYER_ID matchLayer = candidate->m_MatchLayers[0];
|
||||
|
||||
if( !aItem->GetLayerSet().test( matchLayer )
|
||||
|| ( bItem && !bItem->GetLayerSet().test( matchLayer ) ) )
|
||||
{
|
||||
if( !aItem->GetLayerSet().test( matchLayer ) )
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if( candidate->m_MatchAreas.size() )
|
||||
|
@ -165,8 +149,12 @@ void MatchSelectors( const std::vector<DRC_SELECTOR*>& aSelectors,
|
|||
}
|
||||
|
||||
// All tests done; if we're still here then it matches
|
||||
aSelected->push_back( candidate );
|
||||
|
||||
if( ( candidate->m_Rule->m_ConstraintFlags & aConstraint ) > 0 )
|
||||
return candidate->m_Rule;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -32,26 +32,55 @@
|
|||
class BOARD_ITEM;
|
||||
|
||||
|
||||
#define CLEARANCE_CONSTRAINT (1 << 0)
|
||||
#define ANNULUS_CONSTRAINT (1 << 1)
|
||||
#define TRACK_CONSTRAINT (1 << 2)
|
||||
#define HOLE_CONSTRAINT (1 << 3)
|
||||
|
||||
#define DISALLOW_VIAS (1 << 0)
|
||||
#define DISALLOW_MICRO_VIAS (1 << 1)
|
||||
#define DISALLOW_BB_VIAS (1 << 2)
|
||||
#define DISALLOW_TRACKS (1 << 3)
|
||||
#define DISALLOW_PADS (1 << 4)
|
||||
#define DISALLOW_ZONES (1 << 5)
|
||||
#define DISALLOW_TEXTS (1 << 6)
|
||||
#define DISALLOW_GRAPHICS (1 << 7)
|
||||
#define DISALLOW_HOLES (1 << 8)
|
||||
#define DISALLOW_FOOTPRINTS (1 << 9)
|
||||
|
||||
|
||||
class DRC_RULE
|
||||
{
|
||||
public:
|
||||
DRC_RULE() :
|
||||
m_Clearance( 0 ),
|
||||
m_AnnulusWidth( 0 ),
|
||||
m_TrackWidth( 0 ),
|
||||
m_Hole( 0 )
|
||||
m_ConstraintFlags( 0 ),
|
||||
m_DisallowFlags( 0 ),
|
||||
m_Clearance( { 0, 0, INT_MAX / 2 } ),
|
||||
m_MinAnnulusWidth( 0 ),
|
||||
m_TrackConstraint( { 0, 0, INT_MAX / 2 } ),
|
||||
m_MinHole( 0 )
|
||||
{ }
|
||||
|
||||
struct MINOPTMAX
|
||||
{
|
||||
int Min;
|
||||
int Opt;
|
||||
int Max;
|
||||
};
|
||||
|
||||
public:
|
||||
wxString m_Name;
|
||||
wxString m_Name;
|
||||
int m_ConstraintFlags;
|
||||
int m_DisallowFlags;
|
||||
|
||||
// A 0 value means the property is not modified by this rule.
|
||||
// A positive value is a minimum. A negative value is a relaxed constraint: the minimum
|
||||
// is reduced to the absolute value of the constraint.
|
||||
int m_Clearance;
|
||||
int m_AnnulusWidth;
|
||||
int m_TrackWidth;
|
||||
int m_Hole;
|
||||
// A positive value is a minimum.
|
||||
MINOPTMAX m_Clearance;
|
||||
int m_MinAnnulusWidth;
|
||||
MINOPTMAX m_TrackConstraint;
|
||||
int m_MinHole;
|
||||
|
||||
wxString m_Condition;
|
||||
};
|
||||
|
||||
|
||||
|
@ -74,10 +103,7 @@ public:
|
|||
};
|
||||
|
||||
|
||||
void MatchSelectors( const std::vector<DRC_SELECTOR*>& aSelectors,
|
||||
const BOARD_ITEM* aItem, const NETCLASS* aNetclass,
|
||||
const BOARD_ITEM* bItem, const NETCLASS* bNetclass,
|
||||
std::vector<DRC_SELECTOR*>* aSelected );
|
||||
DRC_RULE* GetRule( const BOARD_ITEM* aItem, const BOARD_ITEM* bItem, int aConstraint );
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -183,14 +183,8 @@ DRC_SELECTOR* DRC_RULES_PARSER::parseDRC_SELECTOR( wxString* aRuleName )
|
|||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_priority:
|
||||
NeedNUMBER( "priority" );
|
||||
selector->m_Priority = (int)strtol( CurText(), NULL, 10 );
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
default:
|
||||
Expecting( "match_netclass, match_type, match_layer, match_area, rule, or priority" );
|
||||
Expecting( "match_netclass, match_type, match_layer, match_area, or rule" );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -211,61 +205,40 @@ DRC_RULE* DRC_RULES_PARSER::parseDRC_RULE()
|
|||
if( token != T_LEFT )
|
||||
Expecting( T_LEFT );
|
||||
|
||||
int sign = 1;
|
||||
token = NextTok();
|
||||
|
||||
switch( token )
|
||||
{
|
||||
case T_allow:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case T_clearance:
|
||||
if( NextTok() == T_relaxed )
|
||||
case T_disallow:
|
||||
switch( NextTok() )
|
||||
{
|
||||
sign = -1;
|
||||
NextTok();
|
||||
case T_track: rule->m_DisallowFlags |= DISALLOW_TRACKS; break;
|
||||
case T_via: rule->m_DisallowFlags |= DISALLOW_VIAS; break;
|
||||
case T_micro_via: rule->m_DisallowFlags |= DISALLOW_MICRO_VIAS; break;
|
||||
case T_blind_via: rule->m_DisallowFlags |= DISALLOW_BB_VIAS; break;
|
||||
case T_pad: rule->m_DisallowFlags |= DISALLOW_PADS; break;
|
||||
case T_zone: rule->m_DisallowFlags |= DISALLOW_ZONES; break;
|
||||
case T_text: rule->m_DisallowFlags |= DISALLOW_TEXTS; break;
|
||||
case T_graphic: rule->m_DisallowFlags |= DISALLOW_GRAPHICS; break;
|
||||
case T_hole: rule->m_DisallowFlags |= DISALLOW_HOLES; break;
|
||||
default: Expecting( "track, via, micro_via, blind_via, pad, zone, text, "
|
||||
"graphic, or hole" );
|
||||
}
|
||||
|
||||
rule->m_Clearance = parseValue( T_clearance ) * sign;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_track_width:
|
||||
if( NextTok() == T_relaxed )
|
||||
{
|
||||
sign = -1;
|
||||
NextTok();
|
||||
}
|
||||
|
||||
rule->m_TrackWidth = parseValue( T_track_width ) * sign;
|
||||
NeedRIGHT();
|
||||
case T_constraint:
|
||||
parseConstraint( rule );
|
||||
break;
|
||||
|
||||
case T_annulus_width:
|
||||
if( NextTok() == T_relaxed )
|
||||
{
|
||||
sign = -1;
|
||||
NextTok();
|
||||
}
|
||||
|
||||
rule->m_AnnulusWidth = parseValue( T_annulus_width ) * sign;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_hole:
|
||||
if( NextTok() == T_relaxed )
|
||||
{
|
||||
sign = -1;
|
||||
NextTok();
|
||||
}
|
||||
|
||||
rule->m_Hole = parseValue( T_hole ) * sign;
|
||||
case T_condition:
|
||||
NeedSYMBOL();
|
||||
rule->m_Condition = FromUTF8();
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
default:
|
||||
Expecting( "allow, clearance, track_width, annulus_width, or hole" );
|
||||
Expecting( "disallow, constraint or condition" );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -273,6 +246,82 @@ DRC_RULE* DRC_RULES_PARSER::parseDRC_RULE()
|
|||
}
|
||||
|
||||
|
||||
void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
|
||||
{
|
||||
T token;
|
||||
int constraintType;
|
||||
int value;
|
||||
|
||||
switch( NextTok() )
|
||||
{
|
||||
case T_clearance: constraintType = CLEARANCE_CONSTRAINT; break;
|
||||
case T_track_width: constraintType = TRACK_CONSTRAINT; break;
|
||||
case T_annulus_width: constraintType = ANNULUS_CONSTRAINT; break;
|
||||
case T_hole: constraintType = HOLE_CONSTRAINT; break;
|
||||
default: Expecting( "clearance, track_width, annulus_width, or hole" ); return;
|
||||
}
|
||||
|
||||
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||
{
|
||||
if( token != T_LEFT )
|
||||
Expecting( T_LEFT );
|
||||
|
||||
token = NextTok();
|
||||
|
||||
switch( token )
|
||||
{
|
||||
case T_min:
|
||||
NextTok();
|
||||
value = parseValue( token );
|
||||
|
||||
switch( constraintType )
|
||||
{
|
||||
case CLEARANCE_CONSTRAINT: aRule->m_Clearance.Min = value; break;
|
||||
case TRACK_CONSTRAINT: aRule->m_TrackConstraint.Min = value; break;
|
||||
case ANNULUS_CONSTRAINT: aRule->m_MinAnnulusWidth = value; break;
|
||||
case HOLE_CONSTRAINT: aRule->m_MinHole = value; break;
|
||||
}
|
||||
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_max:
|
||||
NextTok();
|
||||
value = parseValue( token );
|
||||
|
||||
switch( constraintType )
|
||||
{
|
||||
case CLEARANCE_CONSTRAINT: aRule->m_Clearance.Max = value; break;
|
||||
case TRACK_CONSTRAINT: aRule->m_TrackConstraint.Max = value; break;
|
||||
default: Expecting( "min" );
|
||||
}
|
||||
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_opt:
|
||||
NextTok();
|
||||
value = parseValue( token );
|
||||
|
||||
switch( constraintType )
|
||||
{
|
||||
case CLEARANCE_CONSTRAINT: aRule->m_Clearance.Opt = value; break;
|
||||
case TRACK_CONSTRAINT: aRule->m_TrackConstraint.Opt = value; break;
|
||||
default: Expecting( "min" );
|
||||
}
|
||||
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
default:
|
||||
Expecting( "allow or constraint" );
|
||||
}
|
||||
}
|
||||
|
||||
aRule->m_ConstraintFlags |= constraintType;
|
||||
}
|
||||
|
||||
|
||||
int DRC_RULES_PARSER::parseValue( DRCRULE_T::T aToken )
|
||||
{
|
||||
char* tmp;
|
||||
|
@ -283,20 +332,14 @@ int DRC_RULES_PARSER::parseValue( DRCRULE_T::T aToken )
|
|||
|
||||
if( errno )
|
||||
{
|
||||
wxString error;
|
||||
error.Printf( _( "Invalid floating point number in\nfile: \"%s\"\nline: %d\noffset: %d" ),
|
||||
GetChars( CurSource() ), CurLineNumber(), CurOffset() );
|
||||
|
||||
THROW_IO_ERROR( error );
|
||||
THROW_PARSE_ERROR( _( "Invalid floating point number" ), CurSource(), CurLine(),
|
||||
CurLineNumber(), CurOffset() );
|
||||
}
|
||||
|
||||
if( CurText() == tmp )
|
||||
{
|
||||
wxString error;
|
||||
error.Printf( _( "Missing floating point number in\nfile: \"%s\"\nline: %d\noffset: %d" ),
|
||||
GetChars( CurSource() ), CurLineNumber(), CurOffset() );
|
||||
|
||||
THROW_IO_ERROR( error );
|
||||
THROW_PARSE_ERROR( _( "Missing floating point number" ), CurSource(), CurLine(),
|
||||
CurLineNumber(), CurOffset() );
|
||||
}
|
||||
|
||||
return KiROUND( fval * IU_PER_MM );
|
||||
|
|
|
@ -49,6 +49,7 @@ private:
|
|||
|
||||
DRC_RULE* parseDRC_RULE();
|
||||
|
||||
void parseConstraint( DRC_RULE* aRule );
|
||||
int parseValue( DRCRULE_T::T aToken );
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in New Issue