Performance enhancements for DRC.
This commit is contained in:
parent
d72a778f19
commit
05855a5a1c
|
@ -214,6 +214,9 @@ public:
|
|||
std::vector<DRC_SELECTOR*> m_DRCRuleSelectors;
|
||||
std::vector<DRC_RULE*> m_DRCRules;
|
||||
|
||||
// Temporary storage for rule matching.
|
||||
std::vector<DRC_SELECTOR*> m_matched;
|
||||
|
||||
bool m_MicroViasAllowed; ///< true to allow micro vias
|
||||
bool m_BlindBuriedViaAllowed; ///< true to allow blind/buried vias
|
||||
VIATYPE m_CurrentViaType; ///< (VIA_BLIND_BURIED, VIA_THROUGH, VIA_MICROVIA)
|
||||
|
@ -331,9 +334,9 @@ public:
|
|||
* Function GetDefault
|
||||
* @return the default netclass.
|
||||
*/
|
||||
inline NETCLASSPTR GetDefault() const
|
||||
inline NETCLASS* GetDefault() const
|
||||
{
|
||||
return m_NetClasses.GetDefault();
|
||||
return m_NetClasses.GetDefaultPtr();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -234,6 +234,9 @@ set( PCBNEW_MICROWAVE_SRCS
|
|||
set( PCBNEW_DRC_SRCS
|
||||
drc/drc_courtyard_tester.cpp
|
||||
drc/drc_drilled_hole_tester.cpp
|
||||
drc/drc_keepout_tester.cpp
|
||||
drc/drc_netclass_tester.cpp
|
||||
drc/drc_textvar_tester.cpp
|
||||
drc/drc.cpp
|
||||
drc/drc_clearance_test_functions.cpp
|
||||
drc/drc_rule_parser.cpp
|
||||
|
|
|
@ -81,57 +81,56 @@ bool BOARD_CONNECTED_ITEM::SetNetCode( int aNetCode, bool aNoAssert )
|
|||
|
||||
int BOARD_CONNECTED_ITEM::GetClearance( BOARD_ITEM* aItem, wxString* aSource ) const
|
||||
{
|
||||
BOARD* board = GetBoard();
|
||||
|
||||
// No clearance if "this" is not (yet) linked to a board therefore no available netclass
|
||||
if( !board )
|
||||
return 0;
|
||||
|
||||
BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
|
||||
NETCLASS* myNetclass = nullptr;
|
||||
NETCLASS* itemNetclass = nullptr;
|
||||
BOARD_DESIGN_SETTINGS* bds = nullptr;
|
||||
|
||||
// NB: we must check the net first, as when it is 0 GetNetClass() will return the
|
||||
// orphaned net netclass, not the default netclass.
|
||||
if( GetBoard() )
|
||||
if( m_netinfo->GetNet() == 0 )
|
||||
myNetclass = bds.GetDefault();
|
||||
else
|
||||
myNetclass = GetNetClass();
|
||||
|
||||
if( aItem && aItem->IsConnected() )
|
||||
{
|
||||
if( m_netinfo->GetNet() == 0 )
|
||||
myNetclass = GetBoard()->GetDesignSettings().GetDefault().get();
|
||||
if( static_cast<BOARD_CONNECTED_ITEM*>( aItem )->GetNet()->GetNet() == 0 )
|
||||
itemNetclass = bds.GetDefault();
|
||||
else
|
||||
myNetclass = GetNetClass().get();
|
||||
|
||||
bds = &GetBoard()->GetDesignSettings();
|
||||
}
|
||||
// No clearance if "this" is not (yet) linked to a board therefore no available netclass
|
||||
|
||||
if( aItem && aItem->GetBoard() && dynamic_cast<BOARD_CONNECTED_ITEM*>( aItem ) )
|
||||
{
|
||||
if( dynamic_cast<BOARD_CONNECTED_ITEM*>( aItem )->GetNet()->GetNet() == 0 )
|
||||
itemNetclass = GetBoard()->GetDesignSettings().GetDefault().get();
|
||||
else
|
||||
itemNetclass = dynamic_cast<BOARD_CONNECTED_ITEM*>( aItem )->GetNetClass().get();
|
||||
|
||||
bds = &aItem->GetBoard()->GetDesignSettings();
|
||||
itemNetclass = static_cast<BOARD_CONNECTED_ITEM*>( aItem )->GetNetClass();
|
||||
}
|
||||
|
||||
int myClearance = myNetclass ? myNetclass->GetClearance() : 0;
|
||||
int itemClearance = itemNetclass ? itemNetclass->GetClearance() : 0;
|
||||
wxString ruleSource;
|
||||
int ruleClearance = bds ? bds->GetRuleClearance( this, myNetclass,
|
||||
aItem, itemNetclass, &ruleSource ) : 0;
|
||||
int clearance = std::max( std::max( myClearance, itemClearance ), ruleClearance );
|
||||
int clearance = bds.GetRuleClearance( this, myNetclass, aItem, itemNetclass, aSource );
|
||||
|
||||
if( aSource )
|
||||
if( myNetclass )
|
||||
{
|
||||
if( clearance == myClearance && myNetclass )
|
||||
int myClearance = myNetclass->GetClearance();
|
||||
|
||||
if( myClearance > clearance )
|
||||
{
|
||||
*aSource = wxString::Format( _( "'%s' netclass clearance" ), myNetclass->GetName() );
|
||||
clearance = myClearance;
|
||||
|
||||
if( aSource )
|
||||
*aSource = wxString::Format( _( "'%s' netclass clearance" ), myNetclass->GetName() );
|
||||
}
|
||||
else if( clearance == itemClearance && itemNetclass )
|
||||
}
|
||||
|
||||
if( itemNetclass )
|
||||
{
|
||||
int itemClearance = myNetclass->GetClearance();
|
||||
|
||||
if( itemClearance > clearance )
|
||||
{
|
||||
*aSource = wxString::Format( _( "'%s' netclass clearance" ), itemNetclass->GetName() );
|
||||
}
|
||||
else if( clearance == ruleClearance && !ruleSource.IsEmpty() )
|
||||
{
|
||||
*aSource = wxString::Format( _( "'%s' rule clearance" ), ruleSource );
|
||||
}
|
||||
else
|
||||
{
|
||||
*aSource = _( "No netclass" );
|
||||
clearance = itemClearance;
|
||||
|
||||
if( aSource )
|
||||
*aSource = wxString::Format( _( "'%s' netclass clearance" ), itemNetclass->GetName() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,9 +138,11 @@ int BOARD_CONNECTED_ITEM::GetClearance( BOARD_ITEM* aItem, wxString* aSource ) c
|
|||
}
|
||||
|
||||
|
||||
NETCLASSPTR BOARD_CONNECTED_ITEM::GetNetClass() const
|
||||
// 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* BOARD_CONNECTED_ITEM::GetNetClass() const
|
||||
{
|
||||
NETCLASSPTR netclass = m_netinfo->GetNetClass();
|
||||
NETCLASS* netclass = m_netinfo->GetNetClass();
|
||||
|
||||
if( netclass )
|
||||
return netclass;
|
||||
|
|
|
@ -163,11 +163,14 @@ public:
|
|||
*/
|
||||
virtual int GetClearance( BOARD_ITEM* aItem = nullptr, wxString* aSource = nullptr ) const;
|
||||
|
||||
/**
|
||||
* Function GetNetClass
|
||||
* returns the NETCLASS for this item.
|
||||
*/
|
||||
std::shared_ptr<NETCLASS> GetNetClass() const;
|
||||
/**
|
||||
* Function GetNetClassPtr
|
||||
* returns the NETCLASS for this item.
|
||||
*
|
||||
* 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* GetNetClass() const;
|
||||
|
||||
/**
|
||||
* Function GetNetClassName
|
||||
|
|
|
@ -961,9 +961,9 @@ bool BOARD_DESIGN_SETTINGS::SetCurrentNetClass( const wxString& aNetClassName )
|
|||
|
||||
int BOARD_DESIGN_SETTINGS::GetBiggestClearanceValue()
|
||||
{
|
||||
int clearance = m_NetClasses.GetDefault()->GetClearance();
|
||||
int clearance = GetDefault()->GetClearance();
|
||||
|
||||
for( const std::pair<wxString, NETCLASSPTR>& netclass : m_NetClasses.NetClasses() )
|
||||
for( const std::pair<const wxString, NETCLASSPTR>& netclass : m_NetClasses.NetClasses() )
|
||||
clearance = std::max( clearance, netclass.second->GetClearance() );
|
||||
|
||||
for( const DRC_RULE* rule : m_DRCRules )
|
||||
|
@ -975,9 +975,9 @@ int BOARD_DESIGN_SETTINGS::GetBiggestClearanceValue()
|
|||
|
||||
int BOARD_DESIGN_SETTINGS::GetSmallestClearanceValue()
|
||||
{
|
||||
int clearance = m_NetClasses.GetDefault()->GetClearance();
|
||||
int clearance = GetDefault()->GetClearance();
|
||||
|
||||
for( const std::pair<wxString, NETCLASSPTR>& netclass : m_NetClasses.NetClasses() )
|
||||
for( const std::pair<const wxString, NETCLASSPTR>& netclass : m_NetClasses.NetClasses() )
|
||||
clearance = std::min( clearance, netclass.second->GetClearance() );
|
||||
|
||||
return clearance;
|
||||
|
@ -988,11 +988,18 @@ int BOARD_DESIGN_SETTINGS::GetRuleClearance( const BOARD_ITEM* aItem, const NETC
|
|||
const BOARD_ITEM* bItem, const NETCLASS* bNetclass,
|
||||
wxString* aSource )
|
||||
{
|
||||
std::vector<DRC_SELECTOR*> matched;
|
||||
if( !m_matched.empty() )
|
||||
m_matched.clear(); // yes, the difference can be seen in profiles
|
||||
|
||||
MatchSelectors( m_DRCRuleSelectors, aItem, aNetclass, bItem, bNetclass, &matched );
|
||||
if( m_DRCRuleSelectors.size() == 0 )
|
||||
return 0;
|
||||
|
||||
std::sort( matched.begin(), matched.end(),
|
||||
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;
|
||||
|
@ -1000,7 +1007,7 @@ int BOARD_DESIGN_SETTINGS::GetRuleClearance( const BOARD_ITEM* aItem, const NETC
|
|||
|
||||
int clearance = 0;
|
||||
|
||||
for( DRC_SELECTOR* selector : matched )
|
||||
for( DRC_SELECTOR* selector : m_matched )
|
||||
{
|
||||
// ignore hole rules; we're just interested in copper here
|
||||
for( KICAD_T matchType : selector->m_MatchTypes )
|
||||
|
@ -1012,12 +1019,12 @@ int BOARD_DESIGN_SETTINGS::GetRuleClearance( const BOARD_ITEM* aItem, const NETC
|
|||
if( selector->m_Rule->m_Clearance > 0 )
|
||||
{
|
||||
clearance = std::max( clearance, selector->m_Rule->m_Clearance );
|
||||
*aSource = selector->m_Rule->m_Name;
|
||||
*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 ) );
|
||||
*aSource = selector->m_Rule->m_Name;
|
||||
*aSource = wxString::Format( _( "'%s' rule clearance" ), selector->m_Rule->m_Name );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ BOARD::BOARD() :
|
|||
}
|
||||
|
||||
// Initialize default netclass.
|
||||
NETCLASSPTR defaultClass = m_designSettings.GetDefault();
|
||||
NETCLASS* defaultClass = m_designSettings.GetDefault();
|
||||
defaultClass->SetDescription( _( "This is the default net class." ) );
|
||||
m_designSettings.SetCurrentNetClass( defaultClass->GetName() );
|
||||
|
||||
|
@ -752,6 +752,9 @@ BOARD_ITEM* BOARD::GetItem( const KIID& aID )
|
|||
if( marker->m_Uuid == aID )
|
||||
return marker;
|
||||
|
||||
if( m_Uuid == aID )
|
||||
return this;
|
||||
|
||||
// Not found; weak reference has been deleted.
|
||||
if( !g_DeletedItem )
|
||||
g_DeletedItem = new DELETED_BOARD_ITEM();
|
||||
|
|
|
@ -131,7 +131,7 @@ int VIA::GetDrillValue() const
|
|||
return m_Drill;
|
||||
|
||||
// Use the default value from the Netclass
|
||||
NETCLASSPTR netclass = GetNetClass();
|
||||
NETCLASS* netclass = GetNetClass();
|
||||
|
||||
if( GetViaType() == VIATYPE::MICROVIA )
|
||||
return netclass->GetuViaDrill();
|
||||
|
@ -540,7 +540,7 @@ void TRACK::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>
|
|||
}
|
||||
}
|
||||
|
||||
NETCLASSPTR netclass = GetNetClass();
|
||||
NETCLASS* netclass = GetNetClass();
|
||||
|
||||
if( netclass )
|
||||
{
|
||||
|
|
|
@ -465,15 +465,11 @@ int ZONE_CONTAINER::GetClearance( BOARD_ITEM* aItem, wxString* aSource ) const
|
|||
|
||||
// The actual zone clearance is the biggest of the zone netclass clearance
|
||||
// and the zone clearance setting in the zone properties dialog.
|
||||
int zoneClearance = m_ZoneClearance;
|
||||
wxString source;
|
||||
int clearance = BOARD_CONNECTED_ITEM::GetClearance( aItem, &source );
|
||||
int zoneClearance = m_ZoneClearance;
|
||||
int clearance = BOARD_CONNECTED_ITEM::GetClearance( aItem, aSource );
|
||||
|
||||
if( clearance > zoneClearance )
|
||||
{
|
||||
if( aSource )
|
||||
*aSource = source;
|
||||
|
||||
return clearance;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -170,7 +170,7 @@ void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::buildFilterLists()
|
|||
wxArrayString netclassNames;
|
||||
NETCLASSES& netclasses = m_brd->GetDesignSettings().m_NetClasses;
|
||||
|
||||
netclassNames.push_back(netclasses.GetDefault()->GetName() );
|
||||
netclassNames.push_back( netclasses.GetDefaultPtr()->GetName() );
|
||||
|
||||
for( NETCLASSES::const_iterator nc = netclasses.begin(); nc != netclasses.end(); ++nc )
|
||||
netclassNames.push_back( nc->second->GetName() );
|
||||
|
@ -199,7 +199,7 @@ void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::buildNetclassesGrid()
|
|||
m_netclassGrid->SetCellValue( 0, GRID_uVIADRILL, _( "uVia Drill" ) );
|
||||
|
||||
NETCLASSES& netclasses = m_brd->GetDesignSettings().m_NetClasses;
|
||||
NETCLASSPTR defaultNetclass = m_brd->GetDesignSettings().GetDefault();
|
||||
NETCLASS* defaultNetclass = m_brd->GetDesignSettings().GetDefault();
|
||||
m_netclassGrid->AppendRows( netclasses.GetCount() + 1 );
|
||||
|
||||
m_netclassGrid->SetCellValue( 1, GRID_NAME, defaultNetclass->GetName() );
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -25,6 +25,7 @@
|
|||
#ifndef DRC_H
|
||||
#define DRC_H
|
||||
|
||||
#include <board_commit.h>
|
||||
#include <class_board.h>
|
||||
#include <class_track.h>
|
||||
#include <class_marker_pcb.h>
|
||||
|
@ -173,6 +174,13 @@ private:
|
|||
std::vector<DRC_SELECTOR*> m_ruleSelectors;
|
||||
std::vector<DRC_RULE*> m_rules;
|
||||
|
||||
// wxString's c'tor is surprisingly expensive, and in the world of DRC everything matters
|
||||
wxString m_msg;
|
||||
wxString m_clearanceSource;
|
||||
|
||||
// Used during a single DRC run
|
||||
int m_largestClearance;
|
||||
|
||||
///> Sets up handlers for various events.
|
||||
void setTransitions() override;
|
||||
|
||||
|
@ -188,26 +196,16 @@ private:
|
|||
/**
|
||||
* Adds a DRC marker to the PCB through the COMMIT mechanism.
|
||||
*/
|
||||
void addMarkerToPcb( MARKER_PCB* aMarker );
|
||||
|
||||
/**
|
||||
* Fetches a reasonable point for marking a violoation between two non-point objects.
|
||||
*/
|
||||
wxPoint getLocation( TRACK* aTrack, ZONE_CONTAINER* aConflictZone ) const;
|
||||
wxPoint getLocation( TRACK* aTrack, const SEG& aConflictSeg ) const;
|
||||
void addMarkerToPcb( BOARD_COMMIT& aCommit, MARKER_PCB* aMarker );
|
||||
|
||||
//-----<categorical group tests>-----------------------------------------
|
||||
|
||||
/**
|
||||
* Go through each NETCLASS and verifies that its clearance, via size, track width, and
|
||||
* track clearance are larger than those in board.m_designSettings.
|
||||
* This is necessary because the actual DRC checks are run against the NETCLASS
|
||||
* limits, so in order enforce global limits, we first check the NETCLASSes against
|
||||
* the global limits.
|
||||
* @return bool - true if succes, else false but only after
|
||||
* reporting _all_ NETCLASS violations.
|
||||
* Tests whether distance between zones complies with the DRC rules.
|
||||
*
|
||||
* @return Errors count
|
||||
*/
|
||||
bool testNetClasses();
|
||||
int testZoneToZoneOutlines( BOARD_COMMIT& aCommit );
|
||||
|
||||
/**
|
||||
* Perform the DRC on all tracks.
|
||||
|
@ -217,40 +215,28 @@ private:
|
|||
* @param aShowProgressBar = true to show a progress bar
|
||||
* (Note: it is shown only if there are many tracks)
|
||||
*/
|
||||
void testTracks( wxWindow * aActiveWindow, bool aShowProgressBar );
|
||||
void testTracks( BOARD_COMMIT& aCommit, wxWindow * aActiveWindow, bool aShowProgressBar );
|
||||
|
||||
void testPad2Pad();
|
||||
|
||||
void testDrilledHoles();
|
||||
void testPad2Pad( BOARD_COMMIT& aCommit );
|
||||
|
||||
void testUnconnected();
|
||||
|
||||
void testZones();
|
||||
void testZones( BOARD_COMMIT& aCommit );
|
||||
|
||||
void testKeepoutAreas();
|
||||
void testCopperDrawItem( BOARD_COMMIT& aCommit, BOARD_ITEM* aDrawing );
|
||||
|
||||
// aTextItem is type BOARD_ITEM* to accept either TEXTE_PCB or TEXTE_MODULE
|
||||
void testCopperTextItem( BOARD_ITEM* aTextItem );
|
||||
|
||||
void testCopperDrawItem( DRAWSEGMENT* aDrawing );
|
||||
|
||||
void testCopperTextAndGraphics();
|
||||
void testCopperTextAndGraphics( BOARD_COMMIT& aCommit );
|
||||
|
||||
// Tests for items placed on disabled layers (causing false connections).
|
||||
void testDisabledLayers();
|
||||
|
||||
// Test for any unresolved text variable references
|
||||
void testTextVars();
|
||||
void testDisabledLayers( BOARD_COMMIT& aCommit );
|
||||
|
||||
/**
|
||||
* Test that the board outline is contiguous and composed of valid elements
|
||||
*/
|
||||
void testOutline();
|
||||
void testOutline( BOARD_COMMIT& aCommit );
|
||||
|
||||
//-----<single "item" tests>-----------------------------------------
|
||||
|
||||
bool doNetClass( const std::shared_ptr<NETCLASS>& aNetClass, wxString& msg );
|
||||
|
||||
/**
|
||||
* Test the clearance between aRefPad and other pads.
|
||||
*
|
||||
|
@ -263,7 +249,8 @@ private:
|
|||
* (i.e. when the current pad pos X in list exceeds this limit, because the list
|
||||
* is sorted by X coordinate)
|
||||
*/
|
||||
bool doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_limit );
|
||||
bool doPadToPadsDrc( BOARD_COMMIT& aCommit, D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd,
|
||||
int x_limit );
|
||||
|
||||
/**
|
||||
* Test the current segment.
|
||||
|
@ -275,13 +262,8 @@ private:
|
|||
* @return bool - true if no problems, else false and m_currentMarker is
|
||||
* filled in with the problem information.
|
||||
*/
|
||||
void doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterator aEndIt,
|
||||
bool aTestZones );
|
||||
|
||||
/**
|
||||
* Test for footprint courtyard overlaps.
|
||||
*/
|
||||
void doCourtyardsDrc();
|
||||
void doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aStartIt,
|
||||
TRACKS::iterator aEndIt, bool aTestZones );
|
||||
|
||||
//-----<single tests>----------------------------------------------
|
||||
|
||||
|
@ -314,13 +296,6 @@ private:
|
|||
//-----</single tests>---------------------------------------------
|
||||
|
||||
public:
|
||||
/**
|
||||
* Tests whether distance between zones complies with the DRC rules.
|
||||
*
|
||||
* @return Errors count
|
||||
*/
|
||||
int TestZoneToZoneOutlines();
|
||||
|
||||
/**
|
||||
* Test the board footprints against a netlist. Will report DRCE_MISSING_FOOTPRINT,
|
||||
* DRCE_DUPLICATE_FOOTPRINT and DRCE_EXTRA_FOOTPRINT errors in aDRCList.
|
||||
|
@ -328,6 +303,12 @@ public:
|
|||
static void TestFootprints( NETLIST& aNetlist, BOARD* aPCB, EDA_UNITS aUnits,
|
||||
std::vector<DRC_ITEM*>& aDRCList );
|
||||
|
||||
/**
|
||||
* Fetches a reasonable point for marking a violoation between two non-point objects.
|
||||
*/
|
||||
static wxPoint GetLocation( TRACK* aTrack, ZONE_CONTAINER* aConflictZone );
|
||||
static wxPoint GetLocation( TRACK* aTrack, const SEG& aConflictSeg );
|
||||
|
||||
/**
|
||||
* Open a dialog and prompts the user, then if a test run button is
|
||||
* clicked, runs the test(s) and creates the MARKERS. The dialog is only
|
||||
|
|
|
@ -136,19 +136,20 @@ bool poly2segmentDRC( wxPoint* aTref, int aTrefCount, wxPoint aSegStart, wxPoint
|
|||
}
|
||||
|
||||
|
||||
void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterator aEndIt,
|
||||
bool aTestZones )
|
||||
void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aStartIt,
|
||||
TRACKS::iterator aEndIt, bool aTestZones )
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS& bds = m_pcb->GetDesignSettings();
|
||||
std::vector<DRC_SELECTOR*> matched;
|
||||
|
||||
wxString msg;
|
||||
SEG refSeg( aRefSeg->GetStart(), aRefSeg->GetEnd() );
|
||||
LSET layerMask = aRefSeg->GetLayerSet();
|
||||
NETCLASS* netclass = aRefSeg->GetNet()->GetNet() == 0 ? bds.GetDefault().get()
|
||||
: aRefSeg->GetNetClass().get();
|
||||
EDA_RECT refSegBB = aRefSeg->GetBoundingBox();
|
||||
int refSegWidth = aRefSeg->GetWidth();
|
||||
SEG refSeg( aRefSeg->GetStart(), aRefSeg->GetEnd() );
|
||||
PCB_LAYER_ID refLayer = aRefSeg->GetLayer();
|
||||
LSET refLayerSet = aRefSeg->GetLayerSet();
|
||||
|
||||
NETCLASS* netclass = aRefSeg->GetNet()->GetNet() == 0 ? bds.GetDefault()
|
||||
: aRefSeg->GetNetClass();
|
||||
EDA_RECT refSegBB = aRefSeg->GetBoundingBox();
|
||||
int refSegWidth = aRefSeg->GetWidth();
|
||||
|
||||
MatchSelectors( bds.m_DRCRuleSelectors, aRefSeg, netclass, nullptr, nullptr, &matched );
|
||||
|
||||
|
@ -159,17 +160,16 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
|
||||
if( aRefSeg->Type() == PCB_VIA_T )
|
||||
{
|
||||
VIA *refvia = static_cast<VIA*>( aRefSeg );
|
||||
int viaAnnulus = ( refvia->GetWidth() - refvia->GetDrill() ) / 2;
|
||||
int minAnnulus;
|
||||
wxString minAnnulusSource;
|
||||
VIA *refvia = static_cast<VIA*>( aRefSeg );
|
||||
int viaAnnulus = ( refvia->GetWidth() - refvia->GetDrill() ) / 2;
|
||||
int minAnnulus;
|
||||
|
||||
for( DRC_SELECTOR* selector : matched )
|
||||
{
|
||||
if( selector->m_Rule->m_AnnulusWidth > minAnnulus )
|
||||
{
|
||||
minAnnulus = selector->m_Rule->m_AnnulusWidth;
|
||||
minAnnulusSource = wxString::Format( _( "'%s' rule" ), selector->m_Rule->m_Name );
|
||||
m_clearanceSource = wxString::Format( _( "'%s' rule" ), selector->m_Rule->m_Name );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,31 +180,31 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_VIA_ANNULUS );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (%s minimum %s; actual %s)" ),
|
||||
minAnnulusSource,
|
||||
MessageTextFromValue( userUnits(), minAnnulus, true ),
|
||||
MessageTextFromValue( userUnits(), viaAnnulus, true ) );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (%s minimum %s; actual %s)" ),
|
||||
m_clearanceSource,
|
||||
MessageTextFromValue( userUnits(), minAnnulus, true ),
|
||||
MessageTextFromValue( userUnits(), viaAnnulus, true ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( refvia );
|
||||
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, refvia->GetPosition() );
|
||||
addMarkerToPcb( marker );
|
||||
addMarkerToPcb( aCommit, marker );
|
||||
}
|
||||
|
||||
if( refvia->GetWidth() < bds.m_MicroViasMinSize )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_MICROVIA );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; actual %s)" ),
|
||||
MessageTextFromValue( userUnits(), bds.m_MicroViasMinSize, true ),
|
||||
MessageTextFromValue( userUnits(), refvia->GetWidth(), true ) );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; actual %s)" ),
|
||||
MessageTextFromValue( userUnits(), bds.m_MicroViasMinSize, true ),
|
||||
MessageTextFromValue( userUnits(), refvia->GetWidth(), true ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( refvia );
|
||||
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, refvia->GetPosition() );
|
||||
addMarkerToPcb( marker );
|
||||
addMarkerToPcb( aCommit, marker );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -212,38 +212,38 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
if( bds.m_ViasMinAnnulus > minAnnulus )
|
||||
{
|
||||
minAnnulus = bds.m_ViasMinAnnulus;
|
||||
minAnnulusSource = _( "board" );
|
||||
m_clearanceSource = _( "board" );
|
||||
}
|
||||
|
||||
if( viaAnnulus < minAnnulus )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_VIA_ANNULUS );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (%s minimum %s; actual %s)" ),
|
||||
minAnnulusSource,
|
||||
MessageTextFromValue( userUnits(), minAnnulus, true ),
|
||||
MessageTextFromValue( userUnits(), viaAnnulus, true ) );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (%s minimum %s; actual %s)" ),
|
||||
m_clearanceSource,
|
||||
MessageTextFromValue( userUnits(), minAnnulus, true ),
|
||||
MessageTextFromValue( userUnits(), viaAnnulus, true ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( refvia );
|
||||
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, refvia->GetPosition() );
|
||||
addMarkerToPcb( marker );
|
||||
addMarkerToPcb( aCommit, marker );
|
||||
}
|
||||
|
||||
if( refvia->GetWidth() < bds.m_ViasMinSize )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_VIA );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; actual %s)" ),
|
||||
MessageTextFromValue( userUnits(), bds.m_ViasMinSize, true ),
|
||||
MessageTextFromValue( userUnits(), refvia->GetWidth(), true ) );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; actual %s)" ),
|
||||
MessageTextFromValue( userUnits(), bds.m_ViasMinSize, true ),
|
||||
MessageTextFromValue( userUnits(), refvia->GetWidth(), true ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( refvia );
|
||||
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, refvia->GetPosition() );
|
||||
addMarkerToPcb( marker );
|
||||
addMarkerToPcb( aCommit, marker );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,15 +254,15 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_VIA_HOLE_BIGGER );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (diameter %s; drill %s)" ),
|
||||
MessageTextFromValue( userUnits(), refvia->GetWidth(), true ),
|
||||
MessageTextFromValue( userUnits(), refvia->GetDrillValue(), true ) );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (diameter %s; drill %s)" ),
|
||||
MessageTextFromValue( userUnits(), refvia->GetWidth(), true ),
|
||||
MessageTextFromValue( userUnits(), refvia->GetDrillValue(), true ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( refvia );
|
||||
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, refvia->GetPosition() );
|
||||
addMarkerToPcb( marker );
|
||||
addMarkerToPcb( aCommit, marker );
|
||||
}
|
||||
|
||||
// test if the type of via is allowed due to design rules
|
||||
|
@ -270,12 +270,12 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_MICROVIA_NOT_ALLOWED );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (board design rule constraints)" ) );
|
||||
drcItem->SetErrorMessage( msg );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (board design rule constraints)" ) );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( refvia );
|
||||
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, refvia->GetPosition() );
|
||||
addMarkerToPcb( marker );
|
||||
addMarkerToPcb( aCommit, marker );
|
||||
}
|
||||
|
||||
// test if the type of via is allowed due to design rules
|
||||
|
@ -283,12 +283,12 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_BURIED_VIA_NOT_ALLOWED );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (board design rule constraints)" ) );
|
||||
drcItem->SetErrorMessage( msg );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (board design rule constraints)" ) );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( refvia );
|
||||
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, refvia->GetPosition() );
|
||||
addMarkerToPcb( marker );
|
||||
addMarkerToPcb( aCommit, marker );
|
||||
}
|
||||
|
||||
// For microvias: test if they are blind vias and only between 2 layers
|
||||
|
@ -313,30 +313,30 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_MICROVIA_TOO_MANY_LAYERS );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (%s and %s not adjacent)" ),
|
||||
m_pcb->GetLayerName( layer1 ),
|
||||
m_pcb->GetLayerName( layer2 ) );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (%s and %s not adjacent)" ),
|
||||
m_pcb->GetLayerName( layer1 ),
|
||||
m_pcb->GetLayerName( layer2 ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( refvia );
|
||||
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, refvia->GetPosition() );
|
||||
addMarkerToPcb( marker );
|
||||
addMarkerToPcb( aCommit, marker );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else // This is a track segment
|
||||
{
|
||||
int minWidth = bds.m_TrackMinWidth;
|
||||
wxString minWidthSource = _( "board" );
|
||||
int minWidth = bds.m_TrackMinWidth;
|
||||
m_clearanceSource = _( "board" );
|
||||
|
||||
for( DRC_SELECTOR* selector : matched )
|
||||
{
|
||||
if( selector->m_Rule->m_TrackWidth > minWidth )
|
||||
{
|
||||
minWidth = selector->m_Rule->m_AnnulusWidth;
|
||||
minWidthSource = wxString::Format( _( "'%s' rule" ), selector->m_Rule->m_Name );
|
||||
m_clearanceSource = wxString::Format( _( "'%s' rule" ), selector->m_Rule->m_Name );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -346,16 +346,16 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_TRACK_WIDTH );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (%s minimum %s; actual %s)" ),
|
||||
minWidthSource,
|
||||
MessageTextFromValue( userUnits(), bds.m_TrackMinWidth, true ),
|
||||
MessageTextFromValue( userUnits(), refSegWidth, true ) );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (%s minimum %s; actual %s)" ),
|
||||
m_clearanceSource,
|
||||
MessageTextFromValue( userUnits(), bds.m_TrackMinWidth, true ),
|
||||
MessageTextFromValue( userUnits(), refSegWidth, true ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( aRefSeg );
|
||||
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, refsegMiddle );
|
||||
addMarkerToPcb( marker );
|
||||
addMarkerToPcb( aCommit, marker );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -375,12 +375,12 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
{
|
||||
// Preflight based on bounding boxes.
|
||||
EDA_RECT inflatedBB = refSegBB;
|
||||
inflatedBB.Inflate( pad->GetBoundingRadius() + aRefSeg->GetClearance( pad, nullptr ) );
|
||||
inflatedBB.Inflate( pad->GetBoundingRadius() + m_largestClearance );
|
||||
|
||||
if( !inflatedBB.Contains( pad->GetPosition() ) )
|
||||
continue;
|
||||
|
||||
if( !( pad->GetLayerSet() & layerMask ).any() )
|
||||
if( !( pad->GetLayerSet() & refLayerSet ).any() )
|
||||
continue;
|
||||
|
||||
// No need to check pads with the same net as the refSeg.
|
||||
|
@ -389,8 +389,7 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
|
||||
if( pad->GetDrillSize().x > 0 )
|
||||
{
|
||||
wxString clearanceSource;
|
||||
int minClearance = aRefSeg->GetClearance( nullptr, &clearanceSource );
|
||||
int minClearance = aRefSeg->GetClearance( nullptr, &m_clearanceSource );
|
||||
|
||||
/* Treat an oval hole as a line segment along the hole's major axis,
|
||||
* shortened by half its minor axis.
|
||||
|
@ -415,41 +414,41 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
int actual = std::max( 0.0, sqrt( center2center_squared ) - widths );
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_NEAR_HOLE );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ),
|
||||
clearanceSource,
|
||||
MessageTextFromValue( userUnits(), minClearance, true ),
|
||||
MessageTextFromValue( userUnits(), actual, true ) );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ),
|
||||
m_clearanceSource,
|
||||
MessageTextFromValue( userUnits(), minClearance, true ),
|
||||
MessageTextFromValue( userUnits(), actual, true ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( aRefSeg, pad );
|
||||
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, getLocation( aRefSeg, slotSeg ) );
|
||||
addMarkerToPcb( marker );
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, GetLocation( aRefSeg, slotSeg ) );
|
||||
addMarkerToPcb( aCommit, marker );
|
||||
|
||||
if( !m_reportAllTrackErrors )
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
wxString clearanceSource;
|
||||
int minClearance = aRefSeg->GetClearance( pad, &clearanceSource );
|
||||
int actual;
|
||||
int minClearance = aRefSeg->GetClearance( pad, &m_clearanceSource );
|
||||
int actual;
|
||||
|
||||
if( !checkClearanceSegmToPad( refSeg, refSegWidth, pad, minClearance, &actual ) )
|
||||
{
|
||||
actual = std::max( 0, actual );
|
||||
SEG padSeg( pad->GetPosition(), pad->GetPosition() );
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_NEAR_PAD );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ),
|
||||
clearanceSource,
|
||||
MessageTextFromValue( userUnits(), minClearance, true ),
|
||||
MessageTextFromValue( userUnits(), actual, true ) );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ),
|
||||
m_clearanceSource,
|
||||
MessageTextFromValue( userUnits(), minClearance, true ),
|
||||
MessageTextFromValue( userUnits(), actual, true ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( aRefSeg, pad );
|
||||
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, getLocation( aRefSeg, padSeg ) );
|
||||
addMarkerToPcb( marker );
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, GetLocation( aRefSeg, padSeg ) );
|
||||
addMarkerToPcb( aCommit, marker );
|
||||
|
||||
if( !m_reportAllTrackErrors )
|
||||
return;
|
||||
|
@ -471,21 +470,39 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
continue;
|
||||
|
||||
// No problem if tracks are on different layers:
|
||||
if( !( layerMask & track->GetLayerSet() ).any() )
|
||||
// Note that while the general case of GetLayerSet intersection always works,
|
||||
// the others are much faster.
|
||||
bool sameLayers;
|
||||
|
||||
if( aRefSeg->Type() == PCB_VIA_T )
|
||||
{
|
||||
if( track->Type() == PCB_VIA_T )
|
||||
sameLayers = ( refLayerSet & track->GetLayerSet() ).any();
|
||||
else
|
||||
sameLayers = refLayerSet.test( track->GetLayer() );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( track->Type() == PCB_VIA_T )
|
||||
sameLayers = track->GetLayerSet().test( refLayer );
|
||||
else
|
||||
sameLayers = track->GetLayer() == refLayer;
|
||||
}
|
||||
|
||||
if( !sameLayers )
|
||||
continue;
|
||||
|
||||
// Preflight based on inflated bounding boxes:
|
||||
// Preflight based on worst-case inflated bounding boxes:
|
||||
EDA_RECT trackBB = track->GetBoundingBox();
|
||||
trackBB.Inflate( aRefSeg->GetClearance( track, nullptr ) );
|
||||
trackBB.Inflate( m_largestClearance );
|
||||
|
||||
if( !trackBB.Intersects( refSegBB ) )
|
||||
continue;
|
||||
|
||||
wxString clearanceSource;
|
||||
int minClearance = aRefSeg->GetClearance( track, &clearanceSource );
|
||||
SEG trackSeg( track->GetStart(), track->GetEnd() );
|
||||
int widths = ( refSegWidth + track->GetWidth() ) / 2;
|
||||
int center2centerAllowed = minClearance + widths;
|
||||
int minClearance = aRefSeg->GetClearance( track, &m_clearanceSource );
|
||||
SEG trackSeg( track->GetStart(), track->GetEnd() );
|
||||
int widths = ( refSegWidth + track->GetWidth() ) / 2;
|
||||
int center2centerAllowed = minClearance + widths;
|
||||
|
||||
// Avoid square-roots if possible (for performance)
|
||||
SEG::ecoord center2center_squared = refSeg.SquaredDistance( trackSeg );
|
||||
|
@ -495,11 +512,11 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
if( intersection )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACKS_CROSSING );
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( aRefSeg, track );
|
||||
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, (wxPoint) intersection.get() );
|
||||
addMarkerToPcb( marker );
|
||||
addMarkerToPcb( aCommit, marker );
|
||||
|
||||
if( !m_reportAllTrackErrors )
|
||||
return;
|
||||
|
@ -518,16 +535,16 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
int actual = std::max( 0.0, sqrt( center2center_squared ) - widths );
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( errorCode );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ),
|
||||
clearanceSource,
|
||||
MessageTextFromValue( userUnits(), minClearance, true ),
|
||||
MessageTextFromValue( userUnits(), actual, true ) );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ),
|
||||
m_clearanceSource,
|
||||
MessageTextFromValue( userUnits(), minClearance, true ),
|
||||
MessageTextFromValue( userUnits(), actual, true ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( aRefSeg, track );
|
||||
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, getLocation( aRefSeg, trackSeg ) );
|
||||
addMarkerToPcb( marker );
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, GetLocation( aRefSeg, trackSeg ) );
|
||||
addMarkerToPcb( aCommit, marker );
|
||||
|
||||
if( !m_reportAllTrackErrors )
|
||||
return;
|
||||
|
@ -547,14 +564,13 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
if( zone->GetFilledPolysList().IsEmpty() || zone->GetIsKeepout() )
|
||||
continue;
|
||||
|
||||
if( !( layerMask & zone->GetLayerSet() ).any() )
|
||||
if( !( refLayerSet & zone->GetLayerSet() ).any() )
|
||||
continue;
|
||||
|
||||
if( zone->GetNetCode() && zone->GetNetCode() == aRefSeg->GetNetCode() )
|
||||
continue;
|
||||
|
||||
wxString clearanceSource;
|
||||
int minClearance = aRefSeg->GetClearance( zone, &clearanceSource );
|
||||
int minClearance = aRefSeg->GetClearance( zone, &m_clearanceSource );
|
||||
int widths = refSegWidth / 2;
|
||||
int center2centerAllowed = minClearance + widths;
|
||||
SHAPE_POLY_SET* outline = const_cast<SHAPE_POLY_SET*>( &zone->GetFilledPolysList() );
|
||||
|
@ -571,16 +587,16 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
int actual = std::max( 0.0, sqrt( center2center_squared ) - widths );
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_NEAR_ZONE );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ),
|
||||
clearanceSource,
|
||||
MessageTextFromValue( userUnits(), minClearance, true ),
|
||||
MessageTextFromValue( userUnits(), actual, true ) );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ),
|
||||
m_clearanceSource,
|
||||
MessageTextFromValue( userUnits(), minClearance, true ),
|
||||
MessageTextFromValue( userUnits(), actual, true ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( aRefSeg, zone );
|
||||
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, getLocation( aRefSeg, zone ) );
|
||||
addMarkerToPcb( marker );
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, GetLocation( aRefSeg, zone ) );
|
||||
addMarkerToPcb( aCommit, marker );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -592,14 +608,13 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
static DRAWSEGMENT dummyEdge;
|
||||
dummyEdge.SetLayer( Edge_Cuts );
|
||||
|
||||
SEG testSeg( aRefSeg->GetStart(), aRefSeg->GetEnd() );
|
||||
wxString clearanceSource;
|
||||
int minClearance = aRefSeg->GetClearance( &dummyEdge, &clearanceSource );
|
||||
SEG testSeg( aRefSeg->GetStart(), aRefSeg->GetEnd() );
|
||||
int minClearance = aRefSeg->GetClearance( &dummyEdge, &m_clearanceSource );
|
||||
|
||||
if( bds.m_CopperEdgeClearance > minClearance )
|
||||
{
|
||||
minClearance = bds.m_CopperEdgeClearance;
|
||||
clearanceSource = _( "board edge" );
|
||||
m_clearanceSource = _( "board edge" );
|
||||
}
|
||||
|
||||
int halfWidth = refSegWidth / 2;
|
||||
|
@ -638,16 +653,16 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
int actual = std::max( 0.0, sqrt( center2center_squared ) - halfWidth );
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_NEAR_EDGE );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
|
||||
clearanceSource,
|
||||
MessageTextFromValue( userUnits(), minClearance, true ),
|
||||
MessageTextFromValue( userUnits(), actual, true ) );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ),
|
||||
m_clearanceSource,
|
||||
MessageTextFromValue( userUnits(), minClearance, true ),
|
||||
MessageTextFromValue( userUnits(), actual, true ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( aRefSeg, edge );
|
||||
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, (wxPoint) pt );
|
||||
addMarkerToPcb( marker );
|
||||
addMarkerToPcb( aCommit, marker );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -934,7 +949,7 @@ bool DRC::checkClearanceSegmToPad( const SEG& refSeg, int refSegWidth, const D_P
|
|||
|
||||
if( padShape.DoCollide( refSeg, minClearance + widths, &actual ) )
|
||||
{
|
||||
*aActualDist = actual - widths;
|
||||
*aActualDist = std::max( 0, actual - widths );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -955,7 +970,7 @@ bool DRC::checkClearanceSegmToPad( const SEG& refSeg, int refSegWidth, const D_P
|
|||
(wxPoint) refSeg.A, (wxPoint) refSeg.B,
|
||||
minClearance + widths, &actual ) )
|
||||
{
|
||||
*aActualDist = actual - widths;
|
||||
*aActualDist = std::max( 0, actual - widths );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ bool DRC_DRILLED_HOLE_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard )
|
|||
for( MODULE* mod : aBoard.Modules() )
|
||||
{
|
||||
for( D_PAD* pad : mod->Pads( ) )
|
||||
success |= checkPad( pad );
|
||||
success &= checkPad( pad );
|
||||
}
|
||||
|
||||
for( TRACK* track : aBoard.Tracks() )
|
||||
|
@ -67,13 +67,13 @@ bool DRC_DRILLED_HOLE_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard )
|
|||
if( via )
|
||||
{
|
||||
if( via->GetViaType() == VIATYPE::MICROVIA )
|
||||
success |= checkMicroVia( via );
|
||||
success &= checkMicroVia( via );
|
||||
else
|
||||
success |= checkVia( via );
|
||||
success &= checkVia( via );
|
||||
}
|
||||
}
|
||||
|
||||
success |= checkHoles();
|
||||
success &= checkHoles();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
@ -81,7 +81,6 @@ bool DRC_DRILLED_HOLE_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard )
|
|||
|
||||
bool DRC_DRILLED_HOLE_TESTER::checkPad( D_PAD* aPad )
|
||||
{
|
||||
wxString msg;
|
||||
bool success = true;
|
||||
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
||||
|
||||
|
@ -92,8 +91,8 @@ 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().get()
|
||||
: aPad->GetNetClass().get();
|
||||
NETCLASS* netclass = aPad->GetNet()->GetNet() == 0 ? bds.GetDefault()
|
||||
: aPad->GetNetClass();
|
||||
int minHole = bds.m_MinThroughDrill;
|
||||
wxString minHoleSource = _( "board" );
|
||||
|
||||
|
@ -113,12 +112,12 @@ bool DRC_DRILLED_HOLE_TESTER::checkPad( D_PAD* aPad )
|
|||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_PAD_DRILL );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (%s min hole %s; actual %s)" ),
|
||||
minHoleSource,
|
||||
MessageTextFromValue( m_units, minHole, true ),
|
||||
MessageTextFromValue( m_units, holeSize, true ) );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (%s min hole %s; actual %s)" ),
|
||||
minHoleSource,
|
||||
MessageTextFromValue( m_units, minHole, true ),
|
||||
MessageTextFromValue( m_units, holeSize, true ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( aPad );
|
||||
|
||||
HandleMarker( new MARKER_PCB( drcItem, aPad->GetPosition() ) );
|
||||
|
@ -137,14 +136,13 @@ bool DRC_DRILLED_HOLE_TESTER::checkPad( D_PAD* aPad )
|
|||
|
||||
bool DRC_DRILLED_HOLE_TESTER::checkVia( VIA* via )
|
||||
{
|
||||
wxString msg;
|
||||
bool success = true;
|
||||
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
||||
|
||||
if( !bds.Ignore( DRCE_TOO_SMALL_VIA_DRILL ) )
|
||||
{
|
||||
NETCLASS* netclass = via->GetNet()->GetNet() == 0 ? bds.GetDefault().get()
|
||||
: via->GetNetClass().get();
|
||||
NETCLASS* netclass = via->GetNet()->GetNet() == 0 ? bds.GetDefault()
|
||||
: via->GetNetClass();
|
||||
int minHole = bds.m_MinThroughDrill;
|
||||
wxString minHoleSource = _( "board" );
|
||||
|
||||
|
@ -164,12 +162,12 @@ bool DRC_DRILLED_HOLE_TESTER::checkVia( VIA* via )
|
|||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_VIA_DRILL );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (%s min hole %s; actual %s)" ),
|
||||
minHoleSource,
|
||||
MessageTextFromValue( m_units, minHole, true ),
|
||||
MessageTextFromValue( m_units, via->GetDrillValue(), true ) );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (%s min hole %s; actual %s)" ),
|
||||
minHoleSource,
|
||||
MessageTextFromValue( m_units, minHole, true ),
|
||||
MessageTextFromValue( m_units, via->GetDrillValue(), true ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( via );
|
||||
|
||||
HandleMarker( new MARKER_PCB( drcItem, via->GetPosition() ) );
|
||||
|
@ -188,14 +186,13 @@ bool DRC_DRILLED_HOLE_TESTER::checkVia( VIA* via )
|
|||
|
||||
bool DRC_DRILLED_HOLE_TESTER::checkMicroVia( VIA* via )
|
||||
{
|
||||
wxString msg;
|
||||
bool success = true;
|
||||
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
||||
|
||||
if( !bds.Ignore( DRCE_TOO_SMALL_MICROVIA_DRILL ) )
|
||||
{
|
||||
NETCLASS* netclass = via->GetNet()->GetNet() == 0 ? bds.GetDefault().get()
|
||||
: via->GetNetClass().get();
|
||||
NETCLASS* netclass = via->GetNet()->GetNet() == 0 ? bds.GetDefault()
|
||||
: via->GetNetClass();
|
||||
int minHole = bds.m_MicroViasMinDrill;
|
||||
wxString minHoleSource = _( "board" );
|
||||
|
||||
|
@ -215,12 +212,12 @@ bool DRC_DRILLED_HOLE_TESTER::checkMicroVia( VIA* via )
|
|||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_MICROVIA_DRILL );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (%s minimum %s; actual %s)" ),
|
||||
minHoleSource,
|
||||
MessageTextFromValue( m_units, minHole, true ),
|
||||
MessageTextFromValue( m_units, via->GetDrillValue(), true ) );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (%s minimum %s; actual %s)" ),
|
||||
minHoleSource,
|
||||
MessageTextFromValue( m_units, minHole, true ),
|
||||
MessageTextFromValue( m_units, via->GetDrillValue(), true ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( via );
|
||||
|
||||
HandleMarker( new MARKER_PCB( drcItem, via->GetPosition() ) );
|
||||
|
@ -248,7 +245,6 @@ void DRC_DRILLED_HOLE_TESTER::addHole( const wxPoint& aLocation, int aRadius, BO
|
|||
|
||||
bool DRC_DRILLED_HOLE_TESTER::checkHoles()
|
||||
{
|
||||
wxString msg;
|
||||
bool success = true;
|
||||
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
||||
|
||||
|
@ -291,11 +287,11 @@ bool DRC_DRILLED_HOLE_TESTER::checkHoles()
|
|||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_DRILLED_HOLES_TOO_CLOSE );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; actual %s)" ),
|
||||
MessageTextFromValue( m_units, bds.m_HoleToHoleMin, true ),
|
||||
MessageTextFromValue( m_units, actual, true ) );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; actual %s)" ),
|
||||
MessageTextFromValue( m_units, bds.m_HoleToHoleMin, true ),
|
||||
MessageTextFromValue( m_units, actual, true ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( refHole.m_owner, checkHole.m_owner );
|
||||
|
||||
HandleMarker( new MARKER_PCB( drcItem, refHole.m_location ) );
|
||||
|
|
|
@ -61,6 +61,8 @@ private:
|
|||
BOARD* m_board;
|
||||
std::vector<DRILLED_HOLE> m_holes;
|
||||
int m_largestRadius;
|
||||
|
||||
wxString m_msg; // Construct only once for performance
|
||||
};
|
||||
|
||||
#endif // DRC_DRILLED_HOLE_TESTER__H
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 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
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#include <drc/drc_keepout_tester.h>
|
||||
|
||||
#include <class_module.h>
|
||||
#include <drc/drc.h>
|
||||
|
||||
|
||||
DRC_KEEPOUT_TESTER::DRC_KEEPOUT_TESTER( MARKER_HANDLER aMarkerHandler ) :
|
||||
DRC_TEST_PROVIDER( std::move( aMarkerHandler ) ),
|
||||
m_units( EDA_UNITS::MILLIMETRES ),
|
||||
m_board( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool DRC_KEEPOUT_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard )
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
m_units = aUnits;
|
||||
m_board = &aBoard;
|
||||
|
||||
// Get a list of all zones to inspect, from both board and footprints
|
||||
std::list<ZONE_CONTAINER*> areasToInspect = m_board->GetZoneList( true );
|
||||
|
||||
// Test keepout areas for vias, tracks and pads inside keepout areas
|
||||
for( ZONE_CONTAINER* area : areasToInspect )
|
||||
{
|
||||
if( area->GetIsKeepout() )
|
||||
{
|
||||
if( area->GetDoNotAllowTracks() || area->GetDoNotAllowVias() )
|
||||
success &= checkTracksAndVias( area );
|
||||
|
||||
if( area->GetDoNotAllowPads() || area->GetDoNotAllowFootprints() )
|
||||
success &= checkFootprints( area );
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
bool DRC_KEEPOUT_TESTER::checkTracksAndVias( ZONE_CONTAINER* aKeepout )
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
for( TRACK* segm : m_board->Tracks() )
|
||||
{
|
||||
if( segm->Type() == PCB_TRACE_T && aKeepout->GetDoNotAllowTracks() )
|
||||
{
|
||||
// Ignore if the keepout zone is not on the same layer
|
||||
if( !aKeepout->IsOnLayer( segm->GetLayer() ) )
|
||||
continue;
|
||||
|
||||
int widths = segm->GetWidth() / 2;
|
||||
SEG trackSeg( segm->GetStart(), segm->GetEnd() );
|
||||
SEG::ecoord center2center_squared = aKeepout->Outline()->SquaredDistance( trackSeg );
|
||||
|
||||
if( center2center_squared <= SEG::Square( widths) )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_INSIDE_KEEPOUT );
|
||||
drcItem->SetItems( segm, aKeepout );
|
||||
|
||||
HandleMarker( new MARKER_PCB( drcItem, DRC::GetLocation( segm, aKeepout ) ) );
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
else if( segm->Type() == PCB_VIA_T && aKeepout->GetDoNotAllowVias() )
|
||||
{
|
||||
if( !aKeepout->CommonLayerExists( segm->GetLayerSet() ) )
|
||||
continue;
|
||||
|
||||
int widths = segm->GetWidth() / 2;
|
||||
wxPoint viaPos = segm->GetPosition();
|
||||
SEG::ecoord center2center_squared = aKeepout->Outline()->SquaredDistance( viaPos );
|
||||
|
||||
if( center2center_squared <= SEG::Square( widths) )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_VIA_INSIDE_KEEPOUT );
|
||||
drcItem->SetItems( segm, aKeepout );
|
||||
|
||||
HandleMarker( new MARKER_PCB( drcItem, DRC::GetLocation( segm, aKeepout ) ) );
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
bool DRC_KEEPOUT_TESTER::checkFootprints( ZONE_CONTAINER* aKeepout )
|
||||
{
|
||||
bool success = true;
|
||||
EDA_RECT areaBBox = aKeepout->GetBoundingBox();
|
||||
bool checkFront = aKeepout->CommonLayerExists( LSET::FrontMask() );
|
||||
bool checkBack = aKeepout->CommonLayerExists( LSET::BackMask() );
|
||||
|
||||
for( MODULE* fp : m_board->Modules() )
|
||||
{
|
||||
if( aKeepout->GetDoNotAllowFootprints() && ( fp->IsFlipped() ? checkBack : checkFront ) )
|
||||
{
|
||||
// Fast test to detect a footprint inside the keepout area bounding box.
|
||||
if( areaBBox.Intersects( fp->GetBoundingBox() ) )
|
||||
{
|
||||
SHAPE_POLY_SET outline;
|
||||
|
||||
if( fp->BuildPolyCourtyard() )
|
||||
{
|
||||
outline = fp->IsFlipped() ? fp->GetPolyCourtyardBack()
|
||||
: fp->GetPolyCourtyardFront();
|
||||
}
|
||||
|
||||
if( outline.OutlineCount() == 0 )
|
||||
outline = fp->GetBoundingPoly();
|
||||
|
||||
// Build the common area between footprint and the keepout area:
|
||||
outline.BooleanIntersection( *aKeepout->Outline(), SHAPE_POLY_SET::PM_FAST );
|
||||
|
||||
// If it's not empty then we have a violation
|
||||
if( outline.OutlineCount() )
|
||||
{
|
||||
const VECTOR2I& pt = outline.CVertex( 0, 0, -1 );
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_FOOTPRINT_INSIDE_KEEPOUT );
|
||||
drcItem->SetItems( fp, aKeepout );
|
||||
|
||||
HandleMarker( new MARKER_PCB( drcItem, (wxPoint) pt ) );
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( aKeepout->GetDoNotAllowPads() )
|
||||
{
|
||||
for( D_PAD* pad : fp->Pads() )
|
||||
{
|
||||
if( !aKeepout->CommonLayerExists( pad->GetLayerSet() ) )
|
||||
continue;
|
||||
|
||||
// Fast test to detect a pad inside the keepout area bounding box.
|
||||
EDA_RECT padBBox( pad->ShapePos(), wxSize() );
|
||||
padBBox.Inflate( pad->GetBoundingRadius() );
|
||||
|
||||
if( areaBBox.Intersects( padBBox ) )
|
||||
{
|
||||
SHAPE_POLY_SET outline;
|
||||
pad->TransformShapeWithClearanceToPolygon( outline, 0 );
|
||||
|
||||
// Build the common area between pad and the keepout area:
|
||||
outline.BooleanIntersection( *aKeepout->Outline(), SHAPE_POLY_SET::PM_FAST );
|
||||
|
||||
// If it's not empty then we have a violation
|
||||
if( outline.OutlineCount() )
|
||||
{
|
||||
const VECTOR2I& pt = outline.CVertex( 0, 0, -1 );
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_PAD_INSIDE_KEEPOUT );
|
||||
drcItem->SetItems( pad, aKeepout );
|
||||
|
||||
HandleMarker( new MARKER_PCB( drcItem, (wxPoint) pt ) );
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 KiCad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef DRC_KEEPOUT_TESTER__H
|
||||
#define DRC_KEEPOUT_TESTER__H
|
||||
|
||||
#include <drc/drc_provider.h>
|
||||
|
||||
|
||||
class BOARD;
|
||||
|
||||
|
||||
class DRC_KEEPOUT_TESTER : public DRC_TEST_PROVIDER
|
||||
{
|
||||
public:
|
||||
DRC_KEEPOUT_TESTER( MARKER_HANDLER aMarkerHandler );
|
||||
|
||||
virtual ~DRC_KEEPOUT_TESTER() {};
|
||||
|
||||
bool RunDRC( EDA_UNITS aUnits, BOARD& aBoard ) override;
|
||||
|
||||
private:
|
||||
bool checkTracksAndVias( ZONE_CONTAINER* aKeepout );
|
||||
bool checkFootprints( ZONE_CONTAINER* aKeepout );
|
||||
|
||||
private:
|
||||
EDA_UNITS m_units;
|
||||
BOARD* m_board;
|
||||
};
|
||||
|
||||
#endif // DRC_KEEPOUT_TESTER__H
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 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
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#include <drc/drc_netclass_tester.h>
|
||||
|
||||
|
||||
DRC_NETCLASS_TESTER::DRC_NETCLASS_TESTER( MARKER_HANDLER aMarkerHandler ) :
|
||||
DRC_TEST_PROVIDER( std::move( aMarkerHandler ) ),
|
||||
m_units( EDA_UNITS::MILLIMETRES ),
|
||||
m_board( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool DRC_NETCLASS_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard )
|
||||
{
|
||||
m_units = aUnits;
|
||||
m_board = &aBoard;
|
||||
|
||||
bool success = true;
|
||||
NETCLASSES& netclasses = m_board->GetDesignSettings().m_NetClasses;
|
||||
|
||||
success &= checkNetClass( netclasses.GetDefault() );
|
||||
|
||||
for( NETCLASSES::const_iterator i = netclasses.begin(); i != netclasses.end(); ++i )
|
||||
success &= checkNetClass( i->second );
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
bool DRC_NETCLASS_TESTER::checkNetClass( const NETCLASSPTR& nc )
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
const BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
||||
|
||||
if( nc->GetClearance() < bds.m_MinClearance )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_NETCLASS_CLEARANCE );
|
||||
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; %s netclass %s)" ),
|
||||
MessageTextFromValue( m_units, bds.m_MinClearance, true ),
|
||||
nc->GetName(),
|
||||
MessageTextFromValue( m_units, nc->GetClearance(), true ) );
|
||||
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
HandleMarker( new MARKER_PCB( drcItem, wxPoint() ) );
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if( nc->GetTrackWidth() < bds.m_TrackMinWidth )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_NETCLASS_TRACKWIDTH );
|
||||
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; %s netclass %s)" ),
|
||||
MessageTextFromValue( m_units, bds.m_TrackMinWidth, true ),
|
||||
nc->GetName(),
|
||||
MessageTextFromValue( m_units, nc->GetTrackWidth(), true ) );
|
||||
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
HandleMarker( new MARKER_PCB( drcItem, wxPoint() ) );
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if( nc->GetViaDiameter() < bds.m_ViasMinSize )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_NETCLASS_VIASIZE );
|
||||
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; %s netclass %s)" ),
|
||||
MessageTextFromValue( m_units, bds.m_ViasMinSize, true ),
|
||||
nc->GetName(),
|
||||
MessageTextFromValue( m_units, nc->GetViaDiameter(), true ) );
|
||||
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
HandleMarker( new MARKER_PCB( drcItem, wxPoint() ) );
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if( nc->GetViaDrill() < bds.m_MinThroughDrill )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_NETCLASS_VIADRILLSIZE );
|
||||
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (board min through hole %s; %s netclass %s)" ),
|
||||
MessageTextFromValue( m_units, bds.m_MinThroughDrill, true ),
|
||||
nc->GetName(),
|
||||
MessageTextFromValue( m_units, nc->GetViaDrill(), true ) );
|
||||
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
HandleMarker( new MARKER_PCB( drcItem, wxPoint() ) );
|
||||
ret = false;
|
||||
}
|
||||
|
||||
int ncViaAnnulus = ( nc->GetViaDiameter() - nc->GetViaDrill() ) / 2;
|
||||
|
||||
if( ncViaAnnulus < bds.m_ViasMinAnnulus )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_NETCLASS_VIAANNULUS );
|
||||
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; %s netclass %s)" ),
|
||||
MessageTextFromValue( m_units, bds.m_ViasMinAnnulus, true ),
|
||||
nc->GetName(),
|
||||
MessageTextFromValue( m_units, ncViaAnnulus, true ) );
|
||||
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
HandleMarker( new MARKER_PCB( drcItem, wxPoint() ) );
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if( nc->GetuViaDiameter() < bds.m_MicroViasMinSize )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_NETCLASS_uVIASIZE );
|
||||
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; %s netclass %s)" ),
|
||||
MessageTextFromValue( m_units, bds.m_MicroViasMinSize, true ),
|
||||
nc->GetName(),
|
||||
MessageTextFromValue( m_units, nc->GetuViaDiameter(), true ) );
|
||||
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
HandleMarker( new MARKER_PCB( drcItem, wxPoint() ) );
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if( nc->GetuViaDrill() < bds.m_MicroViasMinDrill )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_NETCLASS_uVIADRILLSIZE );
|
||||
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; %s netclass %s)" ),
|
||||
MessageTextFromValue( m_units, bds.m_MicroViasMinDrill, true ),
|
||||
nc->GetName(),
|
||||
MessageTextFromValue( m_units, nc->GetuViaDrill(), true ) );
|
||||
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
HandleMarker( new MARKER_PCB( drcItem, wxPoint() ) );
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 KiCad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef DRC_NETCLASS_TESTER__H
|
||||
#define DRC_NETCLASS_TESTER__H
|
||||
|
||||
#include <drc/drc_provider.h>
|
||||
|
||||
|
||||
class BOARD;
|
||||
class BOARD_ITEM;
|
||||
|
||||
|
||||
class DRC_NETCLASS_TESTER : public DRC_TEST_PROVIDER
|
||||
{
|
||||
public:
|
||||
DRC_NETCLASS_TESTER( MARKER_HANDLER aMarkerHandler );
|
||||
|
||||
virtual ~DRC_NETCLASS_TESTER() {};
|
||||
|
||||
bool RunDRC( EDA_UNITS aUnits, BOARD& aBoard ) override;
|
||||
|
||||
private:
|
||||
bool checkNetClass( const NETCLASSPTR& nc );
|
||||
|
||||
private:
|
||||
EDA_UNITS m_units;
|
||||
BOARD* m_board;
|
||||
|
||||
wxString m_msg; // Construct only once for performance
|
||||
};
|
||||
|
||||
#endif // DRC_NETCLASS_TESTER__H
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 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
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#include <drc/drc_textvar_tester.h>
|
||||
|
||||
#include <class_module.h>
|
||||
#include <class_pcb_text.h>
|
||||
|
||||
|
||||
DRC_TEXTVAR_TESTER::DRC_TEXTVAR_TESTER( MARKER_HANDLER aMarkerHandler ) :
|
||||
DRC_TEST_PROVIDER( std::move( aMarkerHandler ) ),
|
||||
m_units( EDA_UNITS::MILLIMETRES ),
|
||||
m_board( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool DRC_TEXTVAR_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard )
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
m_units = aUnits;
|
||||
m_board = &aBoard;
|
||||
|
||||
for( MODULE* module : m_board->Modules() )
|
||||
{
|
||||
module->RunOnChildren(
|
||||
[&]( BOARD_ITEM* child )
|
||||
{
|
||||
if( child->Type() == PCB_MODULE_TEXT_T )
|
||||
{
|
||||
TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( child );
|
||||
|
||||
if( text->GetShownText().Matches( wxT( "*${*}*" ) ) )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_UNRESOLVED_VARIABLE );
|
||||
drcItem->SetItems( text );
|
||||
|
||||
HandleMarker( new MARKER_PCB( drcItem, text->GetPosition() ) );
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
for( BOARD_ITEM* drawing : m_board->Drawings() )
|
||||
{
|
||||
if( drawing->Type() == PCB_TEXT_T )
|
||||
{
|
||||
TEXTE_PCB* text = static_cast<TEXTE_PCB*>( drawing );
|
||||
|
||||
if( text->GetShownText().Matches( wxT( "*${*}*" ) ) )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_UNRESOLVED_VARIABLE );
|
||||
drcItem->SetItems( text );
|
||||
|
||||
HandleMarker( new MARKER_PCB( drcItem, text->GetPosition() ) );
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 KiCad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef DRC_TEXTVAR_TESTER__H
|
||||
#define DRC_TEXTVAR_TESTER__H
|
||||
|
||||
#include <drc/drc_provider.h>
|
||||
|
||||
|
||||
class BOARD;
|
||||
|
||||
|
||||
class DRC_TEXTVAR_TESTER : public DRC_TEST_PROVIDER
|
||||
{
|
||||
public:
|
||||
DRC_TEXTVAR_TESTER( MARKER_HANDLER aMarkerHandler );
|
||||
|
||||
virtual ~DRC_TEXTVAR_TESTER() {};
|
||||
|
||||
bool RunDRC( EDA_UNITS aUnits, BOARD& aBoard ) override;
|
||||
|
||||
private:
|
||||
EDA_UNITS m_units;
|
||||
BOARD* m_board;
|
||||
};
|
||||
|
||||
#endif // DRC_TEXTVAR_TESTER__H
|
|
@ -269,8 +269,8 @@ BOARD* EAGLE_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, const
|
|||
|
||||
if( m_rules->mdWireWire )
|
||||
{
|
||||
NETCLASSPTR defaultNetclass = designSettings.GetDefault();
|
||||
int clearance = KiROUND( m_rules->mdWireWire );
|
||||
NETCLASS* defaultNetclass = designSettings.GetDefault();
|
||||
int clearance = KiROUND( m_rules->mdWireWire );
|
||||
|
||||
if( clearance < defaultNetclass->GetClearance() )
|
||||
defaultNetclass->SetClearance( clearance );
|
||||
|
|
|
@ -175,7 +175,7 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent
|
|||
// In viewer, the default net clearance is not known (it depends on the actual board).
|
||||
// So we do not show the default clearance, by setting it to 0
|
||||
// The footprint or pad specific clearance will be shown
|
||||
GetBoard()->GetDesignSettings().GetDefault()->SetClearance(0);
|
||||
GetBoard()->GetDesignSettings().GetDefault()->SetClearance( 0 );
|
||||
|
||||
// Don't show the default board solder mask clearance in the footprint viewer. Only the
|
||||
// footprint or pad clearance setting should be shown if it is not 0.
|
||||
|
|
|
@ -124,7 +124,7 @@ FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway, wxWindow* aParent
|
|||
// In viewer, the default net clearance is not known (it depends on the actual board).
|
||||
// So we do not show the default clearance, by setting it to 0
|
||||
// The footprint or pad specific clearance will be shown
|
||||
GetBoard()->GetDesignSettings().GetDefault()->SetClearance(0);
|
||||
GetBoard()->GetDesignSettings().GetDefault()->SetClearance( 0 );
|
||||
|
||||
disp_opts.m_DisplayPadIsol = true;
|
||||
disp_opts.m_DisplayPadNum = true;
|
||||
|
|
|
@ -832,13 +832,13 @@ void LEGACY_PLUGIN::loadSHEET()
|
|||
|
||||
void LEGACY_PLUGIN::loadSETUP()
|
||||
{
|
||||
NETCLASSPTR netclass_default = m_board->GetDesignSettings().GetDefault();
|
||||
NETCLASS* netclass_default = m_board->GetDesignSettings().GetDefault();
|
||||
// TODO Orson: is it really necessary to first operate on a copy and then apply it?
|
||||
// would not it be better to use reference here and apply all the changes instantly?
|
||||
BOARD_DESIGN_SETTINGS bds = m_board->GetDesignSettings();
|
||||
ZONE_SETTINGS zs = m_board->GetZoneSettings();
|
||||
char* line;
|
||||
char* saveptr;
|
||||
BOARD_DESIGN_SETTINGS bds = m_board->GetDesignSettings();
|
||||
ZONE_SETTINGS zs = m_board->GetZoneSettings();
|
||||
char* line;
|
||||
char* saveptr;
|
||||
|
||||
while( ( line = READLINE( m_reader ) ) != NULL )
|
||||
{
|
||||
|
|
|
@ -270,6 +270,11 @@ public:
|
|||
return m_default;
|
||||
}
|
||||
|
||||
NETCLASS* GetDefaultPtr() const
|
||||
{
|
||||
return m_default.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Add
|
||||
* takes \a aNetclass and puts it into this NETCLASSES container.
|
||||
|
|
|
@ -119,9 +119,15 @@ public:
|
|||
*/
|
||||
void SetClass( const NETCLASSPTR& aNetClass );
|
||||
|
||||
NETCLASSPTR GetNetClass()
|
||||
/**
|
||||
* Function GetNetClass
|
||||
*
|
||||
* 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* GetNetClass()
|
||||
{
|
||||
return m_NetClass;
|
||||
return m_NetClass.get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1432,7 +1432,7 @@ void PCB_PARSER::parseSetup()
|
|||
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as setup." ) );
|
||||
|
||||
T token;
|
||||
NETCLASSPTR defaultNetClass = m_board->GetDesignSettings().GetDefault();
|
||||
NETCLASS* defaultNetClass = m_board->GetDesignSettings().GetDefault();
|
||||
BOARD_DESIGN_SETTINGS& designSettings = m_board->GetDesignSettings();
|
||||
ZONE_SETTINGS zoneSettings = m_board->GetZoneSettings();
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ void SIZES_SETTINGS::Init( BOARD* aBoard, ITEM* aStartItem, int aNet )
|
|||
}
|
||||
|
||||
if( !netClass )
|
||||
netClass = bds.GetDefault();
|
||||
netClass = bds.m_NetClasses.GetDefault();
|
||||
|
||||
m_trackWidth = 0;
|
||||
|
||||
|
|
|
@ -999,15 +999,15 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
|
|||
|
||||
//-----<rules>--------------------------------------------------------
|
||||
{
|
||||
char rule[80];
|
||||
NETCLASSPTR defaultClass = aBoard->GetDesignSettings().GetDefault();
|
||||
char rule[80];
|
||||
NETCLASS* defaultClass = aBoard->GetDesignSettings().GetDefault();
|
||||
|
||||
int defaultTrackWidth = defaultClass->GetTrackWidth();
|
||||
int defaultClearance = defaultClass->GetClearance();
|
||||
int defaultTrackWidth = defaultClass->GetTrackWidth();
|
||||
int defaultClearance = defaultClass->GetClearance();
|
||||
|
||||
double clearance = scale( defaultClearance );
|
||||
double clearance = scale( defaultClearance );
|
||||
|
||||
STRINGS& rules = pcb->structure->rules->rules;
|
||||
STRINGS& rules = pcb->structure->rules->rules;
|
||||
|
||||
sprintf( rule, "(width %.6g)", scale( defaultTrackWidth ) );
|
||||
rules.push_back( rule );
|
||||
|
|
|
@ -53,8 +53,7 @@ int GLOBAL_EDIT_TOOL::CleanupTracksAndVias( const TOOL_EVENT& aEvent )
|
|||
|
||||
|
||||
TRACKS_CLEANER::TRACKS_CLEANER( EDA_UNITS aUnits, BOARD* aPcb, BOARD_COMMIT& aCommit )
|
||||
: m_units( aUnits ),
|
||||
m_brd( aPcb ),
|
||||
: m_brd( aPcb ),
|
||||
m_commit( aCommit ),
|
||||
m_dryRun( true ),
|
||||
m_itemsList( nullptr )
|
||||
|
|
|
@ -99,7 +99,6 @@ private:
|
|||
*/
|
||||
bool testTrackEndpointIsNode( TRACK* aTrack, bool aTstStart );
|
||||
|
||||
EDA_UNITS m_units;
|
||||
BOARD* m_brd;
|
||||
BOARD_COMMIT& m_commit;
|
||||
bool m_dryRun;
|
||||
|
|
Loading…
Reference in New Issue