Don't count removed zone layers

This does 3 things:
1) Removes unused zone layers on load
2) Does not save unused zone layers
3) Removes unused zone layers from connectivity calculation

(1) Prevents existing boards from using unused zone layers for any
connectivity or rendering.  (2) Updates the contents of boards with
removed zone layers to prevent them from propagating.  (3) updates the
connectivity while running pcbnew and removing a zone layer

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17288
This commit is contained in:
Seth Hillbrand 2024-03-05 12:56:30 -08:00
parent d7173dd6d1
commit 6e591f5f91
4 changed files with 37 additions and 10 deletions

View File

@ -195,7 +195,12 @@ bool CN_CONNECTIVITY_ALGO::Add( BOARD_ITEM* aItem )
m_itemMap[zone] = ITEM_MAP_ENTRY();
for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
// Don't check for connections on layers that only exist in the zone but
// were disabled in the board
BOARD* board = zone->GetBoard();
LSET layerset = board->GetEnabledLayers() & zone->GetLayerSet();
for( PCB_LAYER_ID layer : layerset.Seq() )
{
for( CN_ITEM* zitem : m_itemList.Add( zone, layer ) )
m_itemMap[zone].Link( zitem );
@ -446,13 +451,15 @@ void CN_CONNECTIVITY_ALGO::Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter )
m_itemMap[zone] = ITEM_MAP_ENTRY();
markItemNetAsDirty( zone );
for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
// Don't check for connections on layers that only exist in the zone but
// were disabled in the board
BOARD* board = zone->GetBoard();
LSET layerset = board->GetEnabledLayers() & zone->GetLayerSet() & LSET::AllCuMask();
for( PCB_LAYER_ID layer : layerset.Seq() )
{
if( IsCopperLayer( layer ) )
{
for( int j = 0; j < zone->GetFilledPolysList( layer )->OutlineCount(); j++ )
zitems.push_back( new CN_ZONE_LAYER( zone, layer, j ) );
}
for( int j = 0; j < zone->GetFilledPolysList( layer )->OutlineCount(); j++ )
zitems.push_back( new CN_ZONE_LAYER( zone, layer, j ) );
}
}
}

View File

@ -2283,9 +2283,14 @@ void PCB_IO_KICAD_SEXPR::format( const ZONE* aZone, int aNestLevel ) const
KICAD_FORMAT::FormatBool( m_out, 0, "locked", aZone->IsLocked() );
// If a zone exists on multiple layers, format accordingly
if( aZone->GetLayerSet().count() > 1 )
LSET layers = aZone->GetLayerSet();
if( aZone->GetBoard() )
layers &= aZone->GetBoard()->GetEnabledLayers();
if( layers.count() > 1 )
{
formatLayers( aZone->GetLayerSet() );
formatLayers( layers );
}
else
{

View File

@ -1172,6 +1172,18 @@ BOARD* PCB_IO_KICAD_SEXPR_PARSER::parseBOARD_unchecked()
}
}
// Clear unused zone data
{
LSET layers = m_board->GetEnabledLayers();
for( BOARD_ITEM* zone : m_board->Zones() )
{
ZONE* z = static_cast<ZONE*>( zone );
z->SetLayerSet( z->GetLayerSet() & layers );
}
}
return m_board;
}

View File

@ -610,7 +610,10 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
for( ZONE* zone : aZones )
{
LSET zoneCopperLayers = zone->GetLayerSet() & LSET::AllCuMask( MAX_CU_LAYERS );
// Don't check for connections on layers that only exist in the zone but
// were disabled in the board
BOARD* board = zone->GetBoard();
LSET zoneCopperLayers = zone->GetLayerSet() & LSET::AllCuMask() & board->GetEnabledLayers();
// Min-thickness is the web thickness. On the other hand, a blob min-thickness by
// min-thickness is not useful. Since there's no obvious definition of web vs. blob, we