Add DRC tests for minimum drill size (based on min via size).

This commit is contained in:
Jeff Young 2020-05-04 20:08:42 +01:00
parent 1b5a6f8698
commit e39d145d72
8 changed files with 191 additions and 135 deletions

View File

@ -23,19 +23,19 @@ PANEL_SETUP_FEATURE_CONSTRAINTS_BASE::PANEL_SETUP_FEATURE_CONSTRAINTS_BASE( wxWi
fgSizerViaOpt->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_bitmapBlindBuried = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerViaOpt->Add( m_bitmapBlindBuried, 0, wxALL, 5 );
fgSizerViaOpt->Add( m_bitmapBlindBuried, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_OptAllowBlindBuriedVias = new wxCheckBox( this, wxID_ANY, _("Allow blind/buried vias"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizerViaOpt->Add( m_OptAllowBlindBuriedVias, 0, wxTOP|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
fgSizerViaOpt->Add( m_OptAllowBlindBuriedVias, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_bitmap_uVia = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerViaOpt->Add( m_bitmap_uVia, 0, wxALL, 5 );
fgSizerViaOpt->Add( m_bitmap_uVia, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_OptAllowMicroVias = new wxCheckBox( this, wxID_ANY, _("Allow micro vias (uVias)"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizerViaOpt->Add( m_OptAllowMicroVias, 0, wxTOP|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
fgSizerViaOpt->Add( m_OptAllowMicroVias, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
sbFeatureRules->Add( fgSizerViaOpt, 0, wxEXPAND, 5 );
sbFeatureRules->Add( fgSizerViaOpt, 0, wxEXPAND|wxTOP, 5 );
sbFeatureRules->Add( 0, 5, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
@ -136,7 +136,7 @@ PANEL_SETUP_FEATURE_CONSTRAINTS_BASE::PANEL_SETUP_FEATURE_CONSTRAINTS_BASE( wxWi
m_TrackMinWidthTitle = new wxStaticText( this, wxID_ANY, _("Minimum track width:"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT );
m_TrackMinWidthTitle->Wrap( -1 );
fgFeatureConstraints->Add( m_TrackMinWidthTitle, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxBOTTOM, 5 );
fgFeatureConstraints->Add( m_TrackMinWidthTitle, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_TrackMinWidthCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_TrackMinWidthCtrl->SetMinSize( wxSize( 120,-1 ) );
@ -145,7 +145,7 @@ PANEL_SETUP_FEATURE_CONSTRAINTS_BASE::PANEL_SETUP_FEATURE_CONSTRAINTS_BASE( wxWi
m_TrackMinWidthUnits = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT );
m_TrackMinWidthUnits->Wrap( -1 );
fgFeatureConstraints->Add( m_TrackMinWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxBOTTOM, 5 );
fgFeatureConstraints->Add( m_TrackMinWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
fgFeatureConstraints->Add( 0, 0, 1, wxEXPAND|wxTOP|wxBOTTOM, 5 );
@ -167,7 +167,7 @@ PANEL_SETUP_FEATURE_CONSTRAINTS_BASE::PANEL_SETUP_FEATURE_CONSTRAINTS_BASE( wxWi
fgFeatureConstraints->Add( m_ViaMinTitle, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_SetViasMinSizeCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgFeatureConstraints->Add( m_SetViasMinSizeCtrl, 0, wxEXPAND|wxALL, 5 );
fgFeatureConstraints->Add( m_SetViasMinSizeCtrl, 0, wxEXPAND|wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_ViaMinUnits = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT );
m_ViaMinUnits->Wrap( -1 );
@ -181,7 +181,7 @@ PANEL_SETUP_FEATURE_CONSTRAINTS_BASE::PANEL_SETUP_FEATURE_CONSTRAINTS_BASE( wxWi
fgFeatureConstraints->Add( m_ViaMinDrillTitle, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_SetViasMinDrillCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgFeatureConstraints->Add( m_SetViasMinDrillCtrl, 0, wxEXPAND|wxALL, 5 );
fgFeatureConstraints->Add( m_SetViasMinDrillCtrl, 0, wxEXPAND|wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_ViaMinDrillUnits = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT );
m_ViaMinDrillUnits->Wrap( -1 );
@ -207,7 +207,7 @@ PANEL_SETUP_FEATURE_CONSTRAINTS_BASE::PANEL_SETUP_FEATURE_CONSTRAINTS_BASE( wxWi
fgFeatureConstraints->Add( m_uviaMinSizeLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_uviaMinSizeCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgFeatureConstraints->Add( m_uviaMinSizeCtrl, 0, wxEXPAND|wxALL, 5 );
fgFeatureConstraints->Add( m_uviaMinSizeCtrl, 0, wxEXPAND|wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_uviaMinSizeUnits = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT );
m_uviaMinSizeUnits->Wrap( -1 );
@ -221,7 +221,7 @@ PANEL_SETUP_FEATURE_CONSTRAINTS_BASE::PANEL_SETUP_FEATURE_CONSTRAINTS_BASE( wxWi
fgFeatureConstraints->Add( m_uviaMinDrillLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_uviaMinDrillCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgFeatureConstraints->Add( m_uviaMinDrillCtrl, 0, wxEXPAND|wxALL, 5 );
fgFeatureConstraints->Add( m_uviaMinDrillCtrl, 0, wxEXPAND|wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_uviaMinDrillUnits = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT );
m_uviaMinDrillUnits->Wrap( -1 );
@ -244,14 +244,14 @@ PANEL_SETUP_FEATURE_CONSTRAINTS_BASE::PANEL_SETUP_FEATURE_CONSTRAINTS_BASE( wxWi
m_HoleToHoleTitle = new wxStaticText( this, wxID_ANY, _("Hole to hole clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
m_HoleToHoleTitle->Wrap( -1 );
fgFeatureConstraints->Add( m_HoleToHoleTitle, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxTOP, 5 );
fgFeatureConstraints->Add( m_HoleToHoleTitle, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_SetHoleToHoleCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgFeatureConstraints->Add( m_SetHoleToHoleCtrl, 0, wxEXPAND|wxALL, 5 );
fgFeatureConstraints->Add( m_SetHoleToHoleCtrl, 0, wxEXPAND|wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_HoleToHoleUnits = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_HoleToHoleUnits->Wrap( -1 );
fgFeatureConstraints->Add( m_HoleToHoleUnits, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxTOP, 5 );
fgFeatureConstraints->Add( m_HoleToHoleUnits, 0, wxALIGN_CENTER_VERTICAL, 5 );
fgFeatureConstraints->Add( 0, 0, 1, wxEXPAND|wxTOP|wxBOTTOM, 5 );
@ -270,14 +270,14 @@ PANEL_SETUP_FEATURE_CONSTRAINTS_BASE::PANEL_SETUP_FEATURE_CONSTRAINTS_BASE( wxWi
m_EdgeClearanceLabel = new wxStaticText( this, wxID_ANY, _("Copper edge clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
m_EdgeClearanceLabel->Wrap( -1 );
fgFeatureConstraints->Add( m_EdgeClearanceLabel, 0, wxTOP|wxBOTTOM|wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 );
fgFeatureConstraints->Add( m_EdgeClearanceLabel, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_EdgeClearanceCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgFeatureConstraints->Add( m_EdgeClearanceCtrl, 0, wxALL|wxEXPAND, 5 );
m_EdgeClearanceUnits = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_EdgeClearanceUnits->Wrap( -1 );
fgFeatureConstraints->Add( m_EdgeClearanceUnits, 0, wxTOP|wxBOTTOM|wxRIGHT, 5 );
fgFeatureConstraints->Add( m_EdgeClearanceUnits, 0, wxALIGN_CENTER_VERTICAL, 5 );
sbFeatureConstraints->Add( fgFeatureConstraints, 1, wxEXPAND|wxTOP|wxLEFT, 5 );

View File

@ -65,7 +65,7 @@
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="flag">wxEXPAND|wxTOP</property>
<property name="proportion">0</property>
<object class="wxFlexGridSizer" expanded="1">
<property name="cols">2</property>
@ -81,7 +81,7 @@
<property name="vgap">0</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxStaticBitmap" expanded="1">
<property name="BottomDockable">1</property>
@ -139,7 +139,7 @@
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxTOP|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="0">
<property name="BottomDockable">1</property>
@ -203,7 +203,7 @@
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxStaticBitmap" expanded="1">
<property name="BottomDockable">1</property>
@ -261,7 +261,7 @@
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxTOP|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="0">
<property name="BottomDockable">1</property>
@ -1116,7 +1116,7 @@
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxBOTTOM</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
@ -1241,7 +1241,7 @@
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxBOTTOM</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
@ -1461,7 +1461,7 @@
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="flag">wxEXPAND|wxALL|wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxTextCtrl" expanded="0">
<property name="BottomDockable">1</property>
@ -1705,7 +1705,7 @@
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="flag">wxEXPAND|wxALL|wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxTextCtrl" expanded="0">
<property name="BottomDockable">1</property>
@ -1989,7 +1989,7 @@
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="flag">wxEXPAND|wxALL|wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxTextCtrl" expanded="0">
<property name="BottomDockable">1</property>
@ -2233,7 +2233,7 @@
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="flag">wxEXPAND|wxALL|wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxTextCtrl" expanded="0">
<property name="BottomDockable">1</property>
@ -2456,7 +2456,7 @@
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxTOP</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
@ -2517,7 +2517,7 @@
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="flag">wxEXPAND|wxALL|wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxTextCtrl" expanded="0">
<property name="BottomDockable">1</property>
@ -2581,7 +2581,7 @@
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxTOP</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
@ -2740,7 +2740,7 @@
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxTOP|wxBOTTOM|wxRIGHT|wxALIGN_CENTER_VERTICAL</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
@ -2865,7 +2865,7 @@
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxTOP|wxBOTTOM|wxRIGHT</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>

View File

@ -152,6 +152,12 @@ bool DRC::IsDRCDialogShown()
void DRC::addMarkerToPcb( MARKER_PCB* aMarker )
{
if( m_pcb->GetDesignSettings().Ignore( aMarker->GetRCItem()->GetErrorCode() ) )
{
delete aMarker;
return;
}
BOARD_COMMIT commit( m_pcbEditorFrame );
commit.Add( aMarker );
commit.Push( wxEmptyString, false, false );
@ -437,7 +443,7 @@ void DRC::RunTests( wxTextCtrl* aMessages )
testZones();
// find and gather unconnected pads.
if( m_doUnconnectedTest )
if( m_doUnconnectedTest && !m_pcb->GetDesignSettings().Ignore( DRCE_UNCONNECTED_ITEMS ) )
{
if( aMessages )
{
@ -508,7 +514,8 @@ void DRC::RunTests( wxTextCtrl* aMessages )
}
// Check if there are items on disabled layers
testDisabledLayers();
if( !m_pcb->GetDesignSettings().Ignore( DRCE_DISABLED_LAYER_ITEM ) )
testDisabledLayers();
if( aMessages )
{
@ -704,15 +711,13 @@ void DRC::testPad2Pad()
void DRC::testDrilledHoles()
{
int holeToHoleMin = m_pcb->GetDesignSettings().m_HoleToHoleMin;
BOARD_DESIGN_SETTINGS& dsnSettings = m_pcb->GetDesignSettings();
if( holeToHoleMin == 0 ) // No min setting turns testing off.
return;
// Test drilled hole clearances to minimize drill bit breakage.
// Test drilled holes to minimize drill bit breakage.
//
// Notes: slots are milled, so we're only concerned with circular holes
// microvias are laser-drilled, so we're only concerned with standard vias
// Check pad & std. via circular holes for hole-to-hole-min (non-circular holes are milled)
// Check pad & std. via holes for via-min-drill (minimum hole classification)
// Check uvia holes for uvia-min-drill (laser drill classification)
struct DRILLED_HOLE
{
@ -729,7 +734,28 @@ void DRC::testDrilledHoles()
{
for( D_PAD* pad : mod->Pads( ) )
{
if( pad->GetDrillSize().x && pad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
int minDimension = std::min( pad->GetDrillSize().x, pad->GetDrillSize().y );
if( minDimension == 0 )
continue;
if( !dsnSettings.Ignore( DRCE_TOO_SMALL_PAD_DRILL )
&& minDimension < dsnSettings.m_ViasMinDrill )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_PAD_DRILL );
msg.Printf( drcItem->GetErrorText() + _( " (board min via drill %s; actual %s)" ),
MessageTextFromValue( userUnits(), dsnSettings.m_ViasMinDrill, true ),
MessageTextFromValue( userUnits(), minDimension, true ) );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( pad );
MARKER_PCB* marker = new MARKER_PCB( drcItem, pad->GetPosition() );
addMarkerToPcb( marker );
}
if( pad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
{
hole.m_location = pad->GetPosition();
hole.m_drillRadius = pad->GetDrillSize().x / 2;
@ -742,8 +768,46 @@ void DRC::testDrilledHoles()
for( TRACK* track : m_pcb->Tracks() )
{
VIA* via = dynamic_cast<VIA*>( track );
if( via && via->GetViaType() == VIATYPE::THROUGH )
if( !via )
continue;
if( via->GetViaType() == VIATYPE::MICROVIA )
{
if( !dsnSettings.Ignore( DRCE_TOO_SMALL_MICROVIA_DRILL )
&& via->GetDrillValue() < dsnSettings.m_MicroViasMinDrill )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_MICROVIA_DRILL );
msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; actual %s)" ),
MessageTextFromValue( userUnits(), dsnSettings.m_MicroViasMinDrill, true ),
MessageTextFromValue( userUnits(), via->GetDrillValue(), true ) );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( via );
MARKER_PCB* marker = new MARKER_PCB( drcItem, via->GetPosition() );
addMarkerToPcb( marker );
}
}
else
{
if( !dsnSettings.Ignore( DRCE_TOO_SMALL_MICROVIA_DRILL )
&& via->GetDrillValue() < dsnSettings.m_ViasMinDrill )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_VIA_DRILL );
msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; actual %s)" ),
MessageTextFromValue( userUnits(), dsnSettings.m_ViasMinDrill, true ),
MessageTextFromValue( userUnits(), via->GetDrillValue(), true ) );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( via );
MARKER_PCB* marker = new MARKER_PCB( drcItem, via->GetPosition() );
addMarkerToPcb( marker );
}
hole.m_location = via->GetPosition();
hole.m_drillRadius = via->GetDrillValue() / 2;
hole.m_owner = via;
@ -751,6 +815,9 @@ void DRC::testDrilledHoles()
}
}
if( dsnSettings.m_HoleToHoleMin == 0 || dsnSettings.Ignore( DRCE_DRILLED_HOLES_TOO_CLOSE ) )
return;
for( size_t ii = 0; ii < holes.size(); ++ii )
{
const DRILLED_HOLE& refHole = holes[ ii ];
@ -766,12 +833,12 @@ void DRC::testDrilledHoles()
int actual = KiROUND( GetLineLength( checkHole.m_location, refHole.m_location ) );
actual = std::max( 0, actual - checkHole.m_drillRadius - refHole.m_drillRadius );
if( actual < holeToHoleMin )
if( actual < dsnSettings.m_HoleToHoleMin )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_DRILLED_HOLES_TOO_CLOSE );
msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; actual %s)" ),
MessageTextFromValue( userUnits(), holeToHoleMin, true ),
MessageTextFromValue( userUnits(), dsnSettings.m_HoleToHoleMin, true ),
MessageTextFromValue( userUnits(), actual, true ) );
drcItem->SetErrorMessage( msg );
@ -870,26 +937,29 @@ void DRC::testZones()
// In recent Pcbnew versions, the netcode is always >= 0, but an internal net name
// is stored, and initialized from the file or the zone properties editor.
// if it differs from the net name from net code, there is a DRC issue
for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
if( !m_pcb->GetDesignSettings().Ignore( DRCE_SUSPICIOUS_NET_FOR_ZONE_OUTLINE ) )
{
ZONE_CONTAINER* zone = m_pcb->GetArea( ii );
if( !zone->IsOnCopperLayer() )
continue;
int netcode = zone->GetNetCode();
// a netcode < 0 or > 0 and no pad in net is a error or strange
// perhaps a "dead" net, which happens when all pads in this net were removed
// Remark: a netcode < 0 should not happen (this is more a bug somewhere)
int pads_in_net = ( netcode > 0 ) ? m_pcb->GetConnectivity()->GetPadCount( netcode ) : 1;
if( ( netcode < 0 ) || pads_in_net == 0 )
for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_SUSPICIOUS_NET_FOR_ZONE_OUTLINE );
drcItem->SetItems( zone );
ZONE_CONTAINER* zone = m_pcb->GetArea( ii );
MARKER_PCB* marker = new MARKER_PCB( drcItem, zone->GetPosition() );
addMarkerToPcb( marker );
if( !zone->IsOnCopperLayer() )
continue;
int netcode = zone->GetNetCode();
// a netcode < 0 or > 0 and no pad in net is a error or strange
// perhaps a "dead" net, which happens when all pads in this net were removed
// Remark: a netcode < 0 should not happen (this is more a bug somewhere)
int pads_in_net = ( netcode > 0 ) ? m_pcb->GetConnectivity()->GetPadCount( netcode ) : 1;
if( ( netcode < 0 ) || pads_in_net == 0 )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_SUSPICIOUS_NET_FOR_ZONE_OUTLINE );
drcItem->SetItems( zone );
MARKER_PCB* marker = new MARKER_PCB( drcItem, zone->GetPosition() );
addMarkerToPcb( marker );
}
}
}
@ -1618,53 +1688,62 @@ void DRC::TestFootprints( NETLIST& aNetlist, BOARD* aPCB, EDA_UNITS aUnits,
{
wxString msg;
// Search for duplicate footprints on the board
auto comp = []( const MODULE* x, const MODULE* y )
{
return x->GetReference().CmpNoCase( y->GetReference() ) < 0;
};
auto mods = std::set<MODULE*, decltype( comp )>( comp );
for( MODULE* mod : aPCB->Modules() )
if( !aPCB->GetDesignSettings().Ignore( DRCE_DUPLICATE_FOOTPRINT ) )
{
auto ins = mods.insert( mod );
if( !ins.second )
// Search for duplicate footprints on the board
for( MODULE* mod : aPCB->Modules() )
{
DRC_ITEM* item = new DRC_ITEM( DRCE_DUPLICATE_FOOTPRINT );
item->SetItems( mod, *ins.first );
aDRCList.push_back( item );
auto ins = mods.insert( mod );
if( !ins.second )
{
DRC_ITEM* item = new DRC_ITEM( DRCE_DUPLICATE_FOOTPRINT );
item->SetItems( mod, *ins.first );
aDRCList.push_back( item );
}
}
}
// Search for component footprints in the netlist but not on the board.
for( unsigned ii = 0; ii < aNetlist.GetCount(); ii++ )
if( !aPCB->GetDesignSettings().Ignore( DRCE_MISSING_FOOTPRINT ) )
{
COMPONENT* component = aNetlist.GetComponent( ii );
MODULE* module = aPCB->FindModuleByReference( component->GetReference() );
if( module == NULL )
// Search for component footprints in the netlist but not on the board.
for( unsigned ii = 0; ii < aNetlist.GetCount(); ii++ )
{
msg.Printf( _( "Missing footprint %s (%s)" ),
component->GetReference(),
component->GetValue() );
COMPONENT* component = aNetlist.GetComponent( ii );
MODULE* module = aPCB->FindModuleByReference( component->GetReference() );
DRC_ITEM* item = new DRC_ITEM( DRCE_MISSING_FOOTPRINT );
item->SetErrorMessage( msg );
aDRCList.push_back( item );
if( module == NULL )
{
msg.Printf( _( "Missing footprint %s (%s)" ),
component->GetReference(),
component->GetValue() );
DRC_ITEM* item = new DRC_ITEM( DRCE_MISSING_FOOTPRINT );
item->SetErrorMessage( msg );
aDRCList.push_back( item );
}
}
}
// Search for component footprints found on board but not in netlist.
for( auto module : mods )
if( !aPCB->GetDesignSettings().Ignore( DRCE_EXTRA_FOOTPRINT ) )
{
COMPONENT* component = aNetlist.GetComponentByReference( module->GetReference() );
if( component == NULL )
// Search for component footprints found on board but not in netlist.
for( auto module : mods )
{
DRC_ITEM* item = new DRC_ITEM( DRCE_EXTRA_FOOTPRINT );
item->SetItems( module );
aDRCList.push_back( item );
COMPONENT* component = aNetlist.GetComponentByReference( module->GetReference() );
if( component == NULL )
{
DRC_ITEM* item = new DRC_ITEM( DRCE_EXTRA_FOOTPRINT );
item->SetItems( module );
aDRCList.push_back( item );
}
}
}
}

View File

@ -59,6 +59,7 @@ enum PCB_DRC_CODE {
DRCE_TOO_SMALL_VIA, ///< Too small via size
DRCE_TOO_SMALL_MICROVIA, ///< Too small micro via size
DRCE_TOO_SMALL_VIA_DRILL, ///< Too small via drill
DRCE_TOO_SMALL_PAD_DRILL, ///< Too small via drill
DRCE_TOO_SMALL_MICROVIA_DRILL, ///< Too small micro via drill
DRCE_NETCLASS_TRACKWIDTH, ///< netclass has TrackWidth < board.m_designSettings->m_TrackMinWidth
DRCE_NETCLASS_CLEARANCE, ///< netclass has Clearance < board.m_designSettings->m_TrackClearance

View File

@ -173,21 +173,6 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
MARKER_PCB* marker = new MARKER_PCB( drcItem, refvia->GetPosition() );
addMarkerToPcb( marker );
}
if( refvia->GetDrillValue() < dsnSettings.m_MicroViasMinDrill )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_MICROVIA_DRILL );
msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; actual %s)" ),
MessageTextFromValue( userUnits(), dsnSettings.m_MicroViasMinDrill, true ),
MessageTextFromValue( userUnits(), refvia->GetDrillValue(), true ) );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( refvia );
MARKER_PCB* marker = new MARKER_PCB( drcItem, refvia->GetPosition() );
addMarkerToPcb( marker );
}
}
else
{
@ -205,21 +190,6 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
MARKER_PCB* marker = new MARKER_PCB( drcItem, refvia->GetPosition() );
addMarkerToPcb( marker );
}
if( refvia->GetDrillValue() < dsnSettings.m_ViasMinDrill )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_VIA_DRILL );
msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; actual %s)" ),
MessageTextFromValue( userUnits(), dsnSettings.m_ViasMinDrill, true ),
MessageTextFromValue( userUnits(), refvia->GetDrillValue(), true ) );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( refvia );
MARKER_PCB* marker = new MARKER_PCB( drcItem, refvia->GetPosition() );
addMarkerToPcb( marker );
}
}
// test if via's hole is bigger than its diameter

View File

@ -91,6 +91,8 @@ wxString DRC_ITEM::GetErrorText( int aCode ) const
return wxString( _( "Micro via size too small" ) );
case DRCE_TOO_SMALL_VIA_DRILL:
return wxString( _( "Via drill too small" ) );
case DRCE_TOO_SMALL_PAD_DRILL:
return wxString( _( "Pad drill too small" ) );
case DRCE_TOO_SMALL_MICROVIA_DRILL:
return wxString( _( "Micro via drill too small" ) );
case DRCE_DRILLED_HOLES_TOO_CLOSE:

View File

@ -247,8 +247,8 @@ BOARD* EAGLE_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, const
doc = xmlDocument.GetRoot();
m_min_trace = INT_MAX;
m_min_hole = INT_MAX;
m_min_via = INT_MAX;
m_min_via_hole = INT_MAX;
loadAllSections( doc );
@ -260,8 +260,8 @@ BOARD* EAGLE_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, const
if( m_min_via < designSettings.m_ViasMinSize )
designSettings.m_ViasMinSize = m_min_via;
if( m_min_via_hole < designSettings.m_ViasMinDrill )
designSettings.m_ViasMinDrill = m_min_via_hole;
if( m_min_hole < designSettings.m_ViasMinDrill )
designSettings.m_ViasMinDrill = m_min_hole;
if( m_rules->mdWireWire )
{
@ -308,10 +308,10 @@ BOARD* EAGLE_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, const
void EAGLE_PLUGIN::init( const PROPERTIES* aProperties )
{
m_hole_count = 0;
m_min_trace = 0;
m_min_via = 0;
m_min_via_hole = 0;
m_hole_count = 0;
m_min_trace = 0;
m_min_hole = 0;
m_min_via = 0;
m_xpath->clear();
m_pads_to_nets.clear();
@ -1406,7 +1406,7 @@ void EAGLE_PLUGIN::orientModuleText( MODULE* m, const EELEMENT& e,
}
MODULE* EAGLE_PLUGIN::makeModule( wxXmlNode* aPackage, const wxString& aPkgName ) const
MODULE* EAGLE_PLUGIN::makeModule( wxXmlNode* aPackage, const wxString& aPkgName )
{
std::unique_ptr<MODULE> m( new MODULE( m_board ) );
@ -1524,11 +1524,12 @@ void EAGLE_PLUGIN::packageWire( MODULE* aModule, wxXmlNode* aTree ) const
}
void EAGLE_PLUGIN::packagePad( MODULE* aModule, wxXmlNode* aTree ) const
void EAGLE_PLUGIN::packagePad( MODULE* aModule, wxXmlNode* aTree )
{
// this is thru hole technology here, no SMDs
EPAD e( aTree );
int shape = EPAD::UNDEF;
int drillz = e.drill.ToPcbUnits();
D_PAD* pad = new D_PAD( aModule );
aModule->Add( pad );
@ -1541,9 +1542,12 @@ void EAGLE_PLUGIN::packagePad( MODULE* aModule, wxXmlNode* aTree ) const
else if( aModule->GetLayer() == B_Cu && m_rules->psBottom != EPAD::UNDEF )
shape = m_rules->psBottom;
pad->SetDrillSize( wxSize( e.drill.ToPcbUnits(), e.drill.ToPcbUnits() ) );
pad->SetDrillSize( wxSize( drillz, drillz ) );
pad->SetLayerSet( LSET::AllCuMask() );
if( drillz < m_min_hole )
m_min_hole = drillz;
// Solder mask
if( !e.stop || *e.stop == true ) // enabled by default
pad->SetLayerSet( pad->GetLayerSet().set( B_Mask ).set( F_Mask ) );
@ -2173,8 +2177,8 @@ void EAGLE_PLUGIN::loadSignals( wxXmlNode* aSignals )
if( kidiam < m_min_via )
m_min_via = kidiam;
if( drillz < m_min_via_hole )
m_min_via_hole = drillz;
if( drillz < m_min_hole )
m_min_hole = drillz;
if( layer_front_most == F_Cu && layer_back_most == B_Cu )
via->SetViaType( VIATYPE::THROUGH );

View File

@ -188,8 +188,8 @@ private:
BOARD* m_board; ///< which BOARD is being worked on, no ownership here
int m_min_trace; ///< smallest trace we find on Load(), in BIU.
int m_min_hole; ///< smallest diameter hole we find on Load(), in BIU.
int m_min_via; ///< smallest via we find on Load(), in BIU.
int m_min_via_hole; ///< smallest via diameter hole we find on Load(), in BIU.
wxString m_lib_path;
wxDateTime m_mod_time;
@ -267,10 +267,10 @@ private:
* Function makeModule
* creates a MODULE from an Eagle package.
*/
MODULE* makeModule( wxXmlNode* aPackage, const wxString& aPkgName ) const;
MODULE* makeModule( wxXmlNode* aPackage, const wxString& aPkgName );
void packageWire( MODULE* aModule, wxXmlNode* aTree ) const;
void packagePad( MODULE* aModule, wxXmlNode* aTree ) const;
void packagePad( MODULE* aModule, wxXmlNode* aTree );
void packageText( MODULE* aModule, wxXmlNode* aTree ) const;
void packageRectangle( MODULE* aModule, wxXmlNode* aTree ) const;
void packagePolygon( MODULE* aModule, wxXmlNode* aTree ) const;