Replace zone-with-no-pads test with isolated copper test.

The later is far more discriminating.

Fixes https://gitlab.com/kicad/code/kicad/issues/11009
This commit is contained in:
Jeff Young 2022-03-01 11:56:17 +00:00
parent 661488e932
commit 914e706023
3 changed files with 39 additions and 29 deletions

View File

@ -77,12 +77,12 @@ DRC_ITEM DRC_ITEM::edgeClearance( DRCE_EDGE_CLEARANCE,
wxT( "copper_edge_clearance" ) );
DRC_ITEM DRC_ITEM::zonesIntersect( DRCE_ZONES_INTERSECT,
_( "Copper areas intersect" ),
_( "Copper zones intersect" ),
wxT( "zones_intersect" ) );
DRC_ITEM DRC_ITEM::zoneHasEmptyNet( DRCE_ZONE_HAS_EMPTY_NET,
_( "Copper zone net has no pads" ),
wxT( "zone_has_empty_net" ) );
DRC_ITEM DRC_ITEM::isolatedCopper( DRCE_ISOLATED_COPPER,
_( "Isolated copper fill" ),
wxT( "isolated_copper" ) );
DRC_ITEM DRC_ITEM::starvedThermal( DRCE_STARVED_THERMAL,
_( "Thermal relief connection to zone incomplete" ),
@ -292,7 +292,7 @@ std::vector<std::reference_wrapper<RC_ITEM>> DRC_ITEM::allItemTypes( {
DRC_ITEM::heading_misc,
DRC_ITEM::itemsNotAllowed,
DRC_ITEM::zonesIntersect,
DRC_ITEM::zoneHasEmptyNet,
DRC_ITEM::isolatedCopper,
DRC_ITEM::padstack,
DRC_ITEM::pthInsideCourtyard,
DRC_ITEM::npthInsideCourtyard,
@ -318,7 +318,7 @@ std::shared_ptr<DRC_ITEM> DRC_ITEM::Create( int aErrorCode )
case DRCE_TRACKS_CROSSING: return std::make_shared<DRC_ITEM>( tracksCrossing );
case DRCE_EDGE_CLEARANCE: return std::make_shared<DRC_ITEM>( edgeClearance );
case DRCE_ZONES_INTERSECT: return std::make_shared<DRC_ITEM>( zonesIntersect );
case DRCE_ZONE_HAS_EMPTY_NET: return std::make_shared<DRC_ITEM>( zoneHasEmptyNet );
case DRCE_ISOLATED_COPPER: return std::make_shared<DRC_ITEM>( isolatedCopper );
case DRCE_STARVED_THERMAL: return std::make_shared<DRC_ITEM>( starvedThermal );
case DRCE_DANGLING_VIA: return std::make_shared<DRC_ITEM>( viaDangling );
case DRCE_DANGLING_TRACK: return std::make_shared<DRC_ITEM>( trackDangling );

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2007 Dick Hollenbeck, dick@softplc.com
* Copyright (C) 2018-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2018-2022 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
@ -43,8 +43,8 @@ enum PCB_DRC_CODE {
DRCE_CLEARANCE, // items are too close together
DRCE_TRACKS_CROSSING, // tracks are crossing
DRCE_EDGE_CLEARANCE, // a copper item is too close to the board edge
DRCE_ZONES_INTERSECT, // copper area outlines intersect
DRCE_ZONE_HAS_EMPTY_NET, // copper area has a net but no pads in nets, which is suspicious
DRCE_ZONES_INTERSECT, // copper zone outlines intersect
DRCE_ISOLATED_COPPER, // copper fill with no electrical connections
DRCE_STARVED_THERMAL, // insufficient number of thermal spokes connected to zone
DRCE_DANGLING_VIA, // via which isn't connected to anything
DRCE_DANGLING_TRACK, // track with at least one end not connected to anything
@ -156,7 +156,7 @@ private:
static DRC_ITEM tracksCrossing;
static DRC_ITEM edgeClearance;
static DRC_ITEM zonesIntersect;
static DRC_ITEM zoneHasEmptyNet;
static DRC_ITEM isolatedCopper;
static DRC_ITEM starvedThermal;
static DRC_ITEM viaDangling;
static DRC_ITEM trackDangling;

View File

@ -38,7 +38,7 @@
Errors generated:
- DRCE_DANGLING_TRACK
- DRCE_DANGLING_VIA
- DRCE_ZONE_HAS_EMPTY_NET
- DRCE_ISOLATED_COPPER
*/
class DRC_TEST_PROVIDER_CONNECTIVITY : public DRC_TEST_PROVIDER
@ -73,15 +73,23 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
BOARD* board = m_drcEngine->GetBoard();
std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
std::vector<CN_ZONE_ISOLATED_ISLAND_LIST> islandsList;
for( ZONE* zone : board->Zones() )
{
if( !zone->GetIsRuleArea() )
islandsList.emplace_back( CN_ZONE_ISOLATED_ISLAND_LIST( zone ) );
}
// Rebuild just in case. This really needs to be reliable.
connectivity->Clear();
connectivity->Build( board, m_drcEngine->GetProgressReporter() );
connectivity->FindIsolatedCopperIslands( islandsList );
int delta = 100; // This is the number of tests between 2 calls to the progress bar
int ii = 0;
int count = board->Tracks().size() + board->Zones().size();
int count = board->Tracks().size() + islandsList.size();
ii += count; // We gave half of this phase to CONNECTIVITY_DATA::Build()
count += count;
@ -99,7 +107,7 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
continue;
if( !reportProgress( ii++, count, delta ) )
break;
return false; // DRC cancelled
// Test for dangling items
int code = track->Type() == PCB_VIA_T ? DRCE_DANGLING_VIA : DRCE_DANGLING_TRACK;
@ -114,28 +122,30 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
}
/* test starved zones */
for( ZONE* zone : board->Zones() )
for( CN_ZONE_ISOLATED_ISLAND_LIST& zone : islandsList )
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_ZONE_HAS_EMPTY_NET ) )
if( m_drcEngine->IsErrorLimitExceeded( DRCE_ISOLATED_COPPER ) )
break;
if( !zone->IsOnCopperLayer() )
continue;
if( !reportProgress( ii++, count, delta ) )
return false; // DRC cancelled
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 ) ? connectivity->GetPadCount( netcode ) : 1;
if( ( netcode < 0 ) || pads_in_net == 0 )
for( PCB_LAYER_ID layer : zone.m_zone->GetLayerSet().Seq() )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ZONE_HAS_EMPTY_NET );
drcItem->SetItems( zone );
reportViolation( drcItem, zone->GetPosition(), zone->GetLayer() );
if( !zone.m_islands.count( layer ) )
continue;
std::shared_ptr<SHAPE_POLY_SET> poly = zone.m_zone->GetFilledPolysList( layer );
for( int idx : zone.m_islands.at( layer ) )
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_ISOLATED_COPPER ) )
break;
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ISOLATED_COPPER );
drcItem->SetItems( zone.m_zone );
reportViolation( drcItem, poly->Outline( idx ).CPoint( 0 ), layer );
}
}
}