Improve zone-layer-connections terminology and comments.
This makes it clearer that the overrides are not inverses of each other -- one overrides the flashing state and the other overrides the connection state (to other zones, not to everything). Also fixes a bug where we were failing to check the force-no-connect for pads.
This commit is contained in:
parent
c122fd0e36
commit
f2f54fe926
|
@ -41,11 +41,23 @@ class SHAPE;
|
|||
class PCB_GROUP;
|
||||
|
||||
|
||||
enum ZONE_LAYER_CONNECTION
|
||||
/**
|
||||
* Conditionally flashed vias and pads that interact with zones of different priority can be
|
||||
* very squirrelly.
|
||||
*
|
||||
* In particular, when filling a higher-priority zone that does -not- connect to a via/pad, we
|
||||
* don't know whether or not a lower-priority zone will subsequently connect -- so we can't
|
||||
* determine clearance because we don't know what the final flashing state will be.
|
||||
*
|
||||
* We therefore force the flashing state if the highest-priority zone with the same net -can-
|
||||
* connect (whether or not it does in the end), and otherwise force the zone-connection state
|
||||
* to no-connection (even though a lower priority zone -might- have otherwise connected to it.
|
||||
*/
|
||||
enum ZONE_LAYER_OVERRIDE
|
||||
{
|
||||
ZLC_UNRESOLVED,
|
||||
ZLC_CONNECTED,
|
||||
ZLC_UNCONNECTED
|
||||
ZLO_NONE,
|
||||
ZLO_FORCE_FLASHED,
|
||||
ZLO_FORCE_NO_ZONE_CONNECTION
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -745,15 +745,21 @@ void CN_VISITOR::checkZoneItemConnection( CN_ZONE_LAYER* aZoneLayer, CN_ITEM* aI
|
|||
{
|
||||
PAD* pad = static_cast<PAD*>( item );
|
||||
|
||||
if( pad->ConditionallyFlashed( layer ) && pad->ZoneConnectionCache( layer ) == ZLC_UNCONNECTED )
|
||||
if( pad->ConditionallyFlashed( layer )
|
||||
&& pad->GetZoneLayerOverride( layer ) == ZLO_FORCE_NO_ZONE_CONNECTION )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if( item->Type() == PCB_VIA_T )
|
||||
{
|
||||
PCB_VIA* via = static_cast<PCB_VIA*>( item );
|
||||
|
||||
if( via->ConditionallyFlashed( layer ) && via->ZoneConnectionCache( layer ) == ZLC_UNCONNECTED )
|
||||
if( via->ConditionallyFlashed( layer )
|
||||
&& via->GetZoneLayerOverride( layer ) == ZLO_FORCE_NO_ZONE_CONNECTION )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for( int i = 0; i < aItem->AnchorCount(); ++i )
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2023 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
|
||||
|
@ -105,8 +105,8 @@ PAD::PAD( FOOTPRINT* parent ) :
|
|||
m_removeUnconnectedLayer = false;
|
||||
m_keepTopBottomLayer = true;
|
||||
|
||||
for( size_t ii = 0; ii < arrayDim( m_zoneLayerConnections ); ++ii )
|
||||
m_zoneLayerConnections[ ii ] = ZLC_UNCONNECTED;
|
||||
for( size_t ii = 0; ii < arrayDim( m_zoneLayerOverrides ); ++ii )
|
||||
m_zoneLayerOverrides[ ii ] = ZLO_NONE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -314,27 +314,12 @@ bool PAD::FlashLayer( int aLayer, bool aOnlyCheckIfPermitted ) const
|
|||
static std::initializer_list<KICAD_T> types = { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T,
|
||||
PCB_PAD_T };
|
||||
|
||||
// Only the highest priority zone that a via interacts with on any given layer gets
|
||||
// to determine if it is connected or not. This keeps us from deciding it's not
|
||||
// flashed when filling the first zone, and then later having another zone connect to
|
||||
// it, causing it to become flashed, resulting in the first zone having insufficient
|
||||
// clearance.
|
||||
// See https://gitlab.com/kicad/code/kicad/-/issues/11299.
|
||||
if( m_zoneLayerConnections[ aLayer ] == ZLC_CONNECTED )
|
||||
{
|
||||
if( m_zoneLayerOverrides[ aLayer ] == ZLO_FORCE_FLASHED )
|
||||
return true;
|
||||
}
|
||||
else if( m_zoneLayerConnections[ aLayer ] == ZLC_UNCONNECTED )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else /* ZLC_UNRESOLVED */
|
||||
{
|
||||
if( aOnlyCheckIfPermitted )
|
||||
return true;
|
||||
else
|
||||
return board->GetConnectivity()->IsConnectedOnLayer( this, aLayer, types );
|
||||
}
|
||||
else if( aOnlyCheckIfPermitted )
|
||||
return true;
|
||||
else
|
||||
return board->GetConnectivity()->IsConnectedOnLayer( this, aLayer, types );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
22
pcbnew/pad.h
22
pcbnew/pad.h
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2023 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
|
||||
|
@ -739,21 +739,21 @@ public:
|
|||
|
||||
virtual const BOX2I ViewBBox() const override;
|
||||
|
||||
void ClearZoneConnectionCache()
|
||||
void ClearZoneLayerOverrides()
|
||||
{
|
||||
for( size_t ii = 0; ii < arrayDim( m_zoneLayerConnections ); ++ii )
|
||||
m_zoneLayerConnections[ ii ] = ZLC_UNRESOLVED;
|
||||
for( size_t ii = 0; ii < arrayDim( m_zoneLayerOverrides ); ++ii )
|
||||
m_zoneLayerOverrides[ ii ] = ZLO_NONE;
|
||||
}
|
||||
|
||||
const ZONE_LAYER_CONNECTION& ZoneConnectionCache( PCB_LAYER_ID aLayer ) const
|
||||
const ZONE_LAYER_OVERRIDE& GetZoneLayerOverride( PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
return m_zoneLayerConnections[ aLayer ];
|
||||
return m_zoneLayerOverrides[ aLayer ];
|
||||
}
|
||||
|
||||
void SetZoneConnectionCache( PCB_LAYER_ID aLayer, ZONE_LAYER_CONNECTION aConnection )
|
||||
void SetZoneLayerOverride( PCB_LAYER_ID aLayer, ZONE_LAYER_OVERRIDE aOverride )
|
||||
{
|
||||
std::unique_lock<std::mutex> cacheLock( m_zoneLayerConnectionsMutex );
|
||||
m_zoneLayerConnections[ aLayer ] = aConnection;
|
||||
std::unique_lock<std::mutex> cacheLock( m_zoneLayerOverridesMutex );
|
||||
m_zoneLayerOverrides[ aLayer ] = aOverride;
|
||||
}
|
||||
|
||||
#if defined(DEBUG)
|
||||
|
@ -874,8 +874,8 @@ private:
|
|||
// while 90° will produce a +.
|
||||
int m_thermalGap;
|
||||
|
||||
std::mutex m_zoneLayerConnectionsMutex;
|
||||
ZONE_LAYER_CONNECTION m_zoneLayerConnections[B_Cu + 1];
|
||||
std::mutex m_zoneLayerOverridesMutex;
|
||||
ZONE_LAYER_OVERRIDE m_zoneLayerOverrides[B_Cu + 1];
|
||||
};
|
||||
|
||||
#endif // PAD_H
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2023 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
|
||||
|
@ -89,8 +89,8 @@ PCB_VIA::PCB_VIA( BOARD_ITEM* aParent ) :
|
|||
m_removeUnconnectedLayer = false;
|
||||
m_keepStartEndLayer = true;
|
||||
|
||||
for( size_t ii = 0; ii < arrayDim( m_zoneLayerConnections ); ++ii )
|
||||
m_zoneLayerConnections[ ii ] = ZLC_UNCONNECTED;
|
||||
for( size_t ii = 0; ii < arrayDim( m_zoneLayerOverrides ); ++ii )
|
||||
m_zoneLayerOverrides[ ii ] = ZLO_NONE;
|
||||
|
||||
m_isFree = false;
|
||||
}
|
||||
|
@ -654,15 +654,10 @@ bool PCB_VIA::FlashLayer( int aLayer ) const
|
|||
static std::initializer_list<KICAD_T> connectedTypes = { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T,
|
||||
PCB_PAD_T };
|
||||
|
||||
// Only the highest priority zone that a via interacts with on any given layer gets to
|
||||
// determine if it is connected or not. This keeps us from deciding it's not flashed when
|
||||
// filling the first zone, and then later having another zone connect to it, causing it to
|
||||
// become flashed, resulting in the first zone having insufficient clearance.
|
||||
// See https://gitlab.com/kicad/code/kicad/-/issues/11299.
|
||||
if( m_zoneLayerConnections[ aLayer ] == ZLC_CONNECTED )
|
||||
if( m_zoneLayerOverrides[ aLayer ] == ZLO_FORCE_FLASHED )
|
||||
return true;
|
||||
|
||||
return board->GetConnectivity()->IsConnectedOnLayer( this, aLayer, connectedTypes );
|
||||
else
|
||||
return board->GetConnectivity()->IsConnectedOnLayer( this, aLayer, connectedTypes );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
|
||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2023 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
|
||||
|
@ -553,21 +553,21 @@ public:
|
|||
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
|
||||
FLASHING aFlash = FLASHING::DEFAULT ) const override;
|
||||
|
||||
void ClearZoneConnectionCache()
|
||||
void ClearZoneLayerOverrides()
|
||||
{
|
||||
for( size_t ii = 0; ii < arrayDim( m_zoneLayerConnections ); ++ii )
|
||||
m_zoneLayerConnections[ ii ] = ZLC_UNRESOLVED;
|
||||
for( size_t ii = 0; ii < arrayDim( m_zoneLayerOverrides ); ++ii )
|
||||
m_zoneLayerOverrides[ ii ] = ZLO_NONE;
|
||||
}
|
||||
|
||||
const ZONE_LAYER_CONNECTION& ZoneConnectionCache( PCB_LAYER_ID aLayer ) const
|
||||
const ZONE_LAYER_OVERRIDE& GetZoneLayerOverride( PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
return m_zoneLayerConnections[ aLayer ];
|
||||
return m_zoneLayerOverrides[ aLayer ];
|
||||
}
|
||||
|
||||
void SetZoneConnectionCache( PCB_LAYER_ID aLayer, ZONE_LAYER_CONNECTION aConnection )
|
||||
void SetZoneLayerOverride( PCB_LAYER_ID aLayer, ZONE_LAYER_OVERRIDE aOverride )
|
||||
{
|
||||
std::unique_lock<std::mutex> cacheLock( m_zoneLayerConnectionsMutex );
|
||||
m_zoneLayerConnections[ aLayer ] = aConnection;
|
||||
std::unique_lock<std::mutex> cacheLock( m_zoneLayerOverridesMutex );
|
||||
m_zoneLayerOverrides[ aLayer ] = aOverride;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -587,8 +587,8 @@ private:
|
|||
bool m_keepStartEndLayer; ///< Keep the start and end annular rings
|
||||
bool m_isFree; ///< "Free" vias don't get their nets auto-updated
|
||||
|
||||
std::mutex m_zoneLayerConnectionsMutex;
|
||||
ZONE_LAYER_CONNECTION m_zoneLayerConnections[B_Cu + 1];
|
||||
std::mutex m_zoneLayerOverridesMutex;
|
||||
ZONE_LAYER_OVERRIDE m_zoneLayerOverrides[B_Cu + 1];
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -5025,6 +5025,9 @@ PAD* PCB_PARSER::parsePAD( FOOTPRINT* aParent )
|
|||
break;
|
||||
|
||||
case T_zone_layer_connections:
|
||||
for( PCB_LAYER_ID layer : pad->GetLayerSet().Seq() )
|
||||
pad->SetZoneLayerOverride( layer, ZLO_FORCE_NO_ZONE_CONNECTION );
|
||||
|
||||
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||
{
|
||||
PCB_LAYER_ID layer = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
|
||||
|
@ -5032,7 +5035,7 @@ PAD* PCB_PARSER::parsePAD( FOOTPRINT* aParent )
|
|||
if( layer < F_Cu || layer > B_Cu )
|
||||
Expecting( "copper layer name" );
|
||||
|
||||
pad->SetZoneConnectionCache( layer, ZLC_CONNECTED );
|
||||
pad->SetZoneLayerOverride( layer, ZLO_FORCE_FLASHED );
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -5449,6 +5452,9 @@ PCB_VIA* PCB_PARSER::parsePCB_VIA()
|
|||
break;
|
||||
|
||||
case T_zone_layer_connections:
|
||||
for( PCB_LAYER_ID layer : via->GetLayerSet().Seq() )
|
||||
via->SetZoneLayerOverride( layer, ZLO_FORCE_NO_ZONE_CONNECTION );
|
||||
|
||||
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||
{
|
||||
PCB_LAYER_ID layer = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
|
||||
|
@ -5456,7 +5462,7 @@ PCB_VIA* PCB_PARSER::parsePCB_VIA()
|
|||
if( layer < F_Cu || layer > B_Cu )
|
||||
Expecting( "copper layer name" );
|
||||
|
||||
via->SetZoneConnectionCache( layer, ZLC_CONNECTED );
|
||||
via->SetZoneLayerOverride( layer, ZLO_FORCE_FLASHED );
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -1535,7 +1535,7 @@ void PCB_PLUGIN::format( const PAD* aPad, int aNestLevel ) const
|
|||
|
||||
for( LSEQ cu = board->GetEnabledLayers().CuStack(); cu; ++cu )
|
||||
{
|
||||
if( aPad->ZoneConnectionCache( *cu ) == ZLC_CONNECTED )
|
||||
if( aPad->GetZoneLayerOverride( *cu ) == ZLO_FORCE_FLASHED )
|
||||
m_out->Print( 0, " %s", m_out->Quotew( LSET::Name( *cu ) ).c_str() );
|
||||
}
|
||||
|
||||
|
@ -2085,7 +2085,7 @@ void PCB_PLUGIN::format( const PCB_TRACK* aTrack, int aNestLevel ) const
|
|||
|
||||
for( LSEQ cu = board->GetEnabledLayers().CuStack(); cu; ++cu )
|
||||
{
|
||||
if( via->ZoneConnectionCache( *cu ) == ZLC_CONNECTED )
|
||||
if( via->GetZoneLayerOverride( *cu ) == ZLO_FORCE_FLASHED )
|
||||
m_out->Print( 0, " %s", m_out->Quotew( LSET::Name( *cu ) ).c_str() );
|
||||
}
|
||||
|
||||
|
|
|
@ -225,7 +225,7 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
|
|||
{
|
||||
PCB_VIA* via = static_cast<PCB_VIA*>( track );
|
||||
|
||||
via->ClearZoneConnectionCache();
|
||||
via->ClearZoneLayerOverrides();
|
||||
|
||||
if( !via->GetRemoveUnconnected() )
|
||||
continue;
|
||||
|
@ -249,16 +249,16 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
|
|||
|
||||
if( isInPourKeepoutArea( bbox, layer, center ) )
|
||||
{
|
||||
via->SetZoneConnectionCache( layer, ZLC_UNCONNECTED );
|
||||
via->SetZoneLayerOverride( layer, ZLO_FORCE_NO_ZONE_CONNECTION );
|
||||
}
|
||||
else
|
||||
{
|
||||
ZONE* zone = findHighestPriorityZone( bbox, layer, netcode, viaTestFn );
|
||||
|
||||
if( zone && zone->GetNetCode() == via->GetNetCode() )
|
||||
via->SetZoneConnectionCache( layer, ZLC_CONNECTED );
|
||||
via->SetZoneLayerOverride( layer, ZLO_FORCE_FLASHED );
|
||||
else
|
||||
via->SetZoneConnectionCache( layer, ZLC_UNCONNECTED );
|
||||
via->SetZoneLayerOverride( layer, ZLO_FORCE_NO_ZONE_CONNECTION );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -269,7 +269,7 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
|
|||
{
|
||||
for( PAD* pad : footprint->Pads() )
|
||||
{
|
||||
pad->ClearZoneConnectionCache();
|
||||
pad->ClearZoneLayerOverrides();
|
||||
|
||||
if( !pad->GetRemoveUnconnected() )
|
||||
continue;
|
||||
|
@ -291,16 +291,16 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
|
|||
|
||||
if( isInPourKeepoutArea( bbox, layer, center ) )
|
||||
{
|
||||
pad->SetZoneConnectionCache( layer, ZLC_UNCONNECTED );
|
||||
pad->SetZoneLayerOverride( layer, ZLO_FORCE_NO_ZONE_CONNECTION );
|
||||
}
|
||||
else
|
||||
{
|
||||
ZONE* zone = findHighestPriorityZone( bbox, layer, netcode, padTestFn );
|
||||
|
||||
if( zone && zone->GetNetCode() == pad->GetNetCode() )
|
||||
pad->SetZoneConnectionCache( layer, ZLC_CONNECTED );
|
||||
pad->SetZoneLayerOverride( layer, ZLO_FORCE_FLASHED );
|
||||
else
|
||||
pad->SetZoneConnectionCache( layer, ZLC_UNCONNECTED );
|
||||
pad->SetZoneLayerOverride( layer, ZLO_FORCE_NO_ZONE_CONNECTION );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -890,7 +890,9 @@ void ZONE_FILLER::knockoutThermalReliefs( const ZONE* aZone, PCB_LAYER_ID aLayer
|
|||
if( !padBBox.Intersects( aZone->GetBoundingBox() ) )
|
||||
continue;
|
||||
|
||||
if( pad->GetNetCode() != aZone->GetNetCode() || pad->GetNetCode() <= 0 )
|
||||
if( pad->GetNetCode() != aZone->GetNetCode()
|
||||
|| pad->GetNetCode() <= 0
|
||||
|| pad->GetZoneLayerOverride( aLayer ) == ZLO_FORCE_NO_ZONE_CONNECTION )
|
||||
{
|
||||
// collect these for knockout in buildCopperItemClearances()
|
||||
aNoConnectionPads.push_back( pad );
|
||||
|
@ -1057,7 +1059,7 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE* aZone, PCB_LAYER_ID aLa
|
|||
{
|
||||
PCB_VIA* via = static_cast<PCB_VIA*>( aTrack );
|
||||
|
||||
if( via->ZoneConnectionCache( aLayer ) == ZLC_UNCONNECTED )
|
||||
if( via->GetZoneLayerOverride( aLayer ) == ZLO_FORCE_NO_ZONE_CONNECTION )
|
||||
sameNet = false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue