From e39d145d72fc3fb04981d7627947adbc5624f3de Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Mon, 4 May 2020 20:08:42 +0100 Subject: [PATCH] Add DRC tests for minimum drill size (based on min via size). --- .../panel_setup_feature_constraints_base.cpp | 32 +-- .../panel_setup_feature_constraints_base.fbp | 32 +-- pcbnew/drc/drc.cpp | 195 ++++++++++++------ pcbnew/drc/drc.h | 1 + pcbnew/drc/drc_clearance_test_functions.cpp | 30 --- pcbnew/drc/drc_item.cpp | 2 + pcbnew/eagle_plugin.cpp | 28 +-- pcbnew/eagle_plugin.h | 6 +- 8 files changed, 191 insertions(+), 135 deletions(-) diff --git a/pcbnew/dialogs/panel_setup_feature_constraints_base.cpp b/pcbnew/dialogs/panel_setup_feature_constraints_base.cpp index dcbf162915..55e61a5bb6 100644 --- a/pcbnew/dialogs/panel_setup_feature_constraints_base.cpp +++ b/pcbnew/dialogs/panel_setup_feature_constraints_base.cpp @@ -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 ); diff --git a/pcbnew/dialogs/panel_setup_feature_constraints_base.fbp b/pcbnew/dialogs/panel_setup_feature_constraints_base.fbp index 02e6b35f22..a04082c326 100644 --- a/pcbnew/dialogs/panel_setup_feature_constraints_base.fbp +++ b/pcbnew/dialogs/panel_setup_feature_constraints_base.fbp @@ -65,7 +65,7 @@ none 5 - wxEXPAND + wxEXPAND|wxTOP 0 2 @@ -81,7 +81,7 @@ 0 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL 0 1 @@ -139,7 +139,7 @@ 5 - wxTOP|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL + wxALIGN_CENTER_VERTICAL|wxALL 0 1 @@ -203,7 +203,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL 0 1 @@ -261,7 +261,7 @@ 5 - wxTOP|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL + wxALIGN_CENTER_VERTICAL|wxALL 0 1 @@ -1116,7 +1116,7 @@ 5 - wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxBOTTOM + wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT 0 1 @@ -1241,7 +1241,7 @@ 5 - wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxBOTTOM + wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT 0 1 @@ -1461,7 +1461,7 @@ 5 - wxEXPAND|wxALL + wxEXPAND|wxALL|wxALIGN_CENTER_VERTICAL 0 1 @@ -1705,7 +1705,7 @@ 5 - wxEXPAND|wxALL + wxEXPAND|wxALL|wxALIGN_CENTER_VERTICAL 0 1 @@ -1989,7 +1989,7 @@ 5 - wxEXPAND|wxALL + wxEXPAND|wxALL|wxALIGN_CENTER_VERTICAL 0 1 @@ -2233,7 +2233,7 @@ 5 - wxEXPAND|wxALL + wxEXPAND|wxALL|wxALIGN_CENTER_VERTICAL 0 1 @@ -2456,7 +2456,7 @@ 5 - wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxTOP + wxALIGN_CENTER_VERTICAL 0 1 @@ -2517,7 +2517,7 @@ 5 - wxEXPAND|wxALL + wxEXPAND|wxALL|wxALIGN_CENTER_VERTICAL 0 1 @@ -2581,7 +2581,7 @@ 5 - wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxTOP + wxALIGN_CENTER_VERTICAL 0 1 @@ -2740,7 +2740,7 @@ 5 - wxTOP|wxBOTTOM|wxRIGHT|wxALIGN_CENTER_VERTICAL + wxALIGN_CENTER_VERTICAL 0 1 @@ -2865,7 +2865,7 @@ 5 - wxTOP|wxBOTTOM|wxRIGHT + wxALIGN_CENTER_VERTICAL 0 1 diff --git a/pcbnew/drc/drc.cpp b/pcbnew/drc/drc.cpp index 6567cc886a..bd69ccc755 100644 --- a/pcbnew/drc/drc.cpp +++ b/pcbnew/drc/drc.cpp @@ -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( 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( 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 ); + } } } } diff --git a/pcbnew/drc/drc.h b/pcbnew/drc/drc.h index ce2afb17ea..0f6d43c241 100644 --- a/pcbnew/drc/drc.h +++ b/pcbnew/drc/drc.h @@ -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 diff --git a/pcbnew/drc/drc_clearance_test_functions.cpp b/pcbnew/drc/drc_clearance_test_functions.cpp index d076bd50a0..fc26904b1a 100644 --- a/pcbnew/drc/drc_clearance_test_functions.cpp +++ b/pcbnew/drc/drc_clearance_test_functions.cpp @@ -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 diff --git a/pcbnew/drc/drc_item.cpp b/pcbnew/drc/drc_item.cpp index 46ac118b0e..a62bcd40c3 100644 --- a/pcbnew/drc/drc_item.cpp +++ b/pcbnew/drc/drc_item.cpp @@ -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: diff --git a/pcbnew/eagle_plugin.cpp b/pcbnew/eagle_plugin.cpp index b46b99aeea..5ca4f8c80e 100644 --- a/pcbnew/eagle_plugin.cpp +++ b/pcbnew/eagle_plugin.cpp @@ -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 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 ); diff --git a/pcbnew/eagle_plugin.h b/pcbnew/eagle_plugin.h index 9af530ce67..b20000f42b 100644 --- a/pcbnew/eagle_plugin.h +++ b/pcbnew/eagle_plugin.h @@ -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;