Improvements for pads/vias in zones which knockout other zones.
1) Drop tiny islands which might cause connection problems. 2) Cleanup some dead code in filler 3) Don't estabilish a connection to an island that is fully covered by whatever its connecting to. Fixes https://gitlab.com/kicad/code/kicad/issues/11036
This commit is contained in:
parent
878c4d2f6b
commit
fed5bcbdf6
|
@ -413,21 +413,35 @@ bool CONNECTIVITY_DATA::IsConnectedOnLayer( const BOARD_CONNECTED_ITEM *aItem, i
|
||||||
&& connected->Layers().Overlaps( aLayer )
|
&& connected->Layers().Overlaps( aLayer )
|
||||||
&& matchType( connected->Parent()->Type() ) )
|
&& matchType( connected->Parent()->Type() ) )
|
||||||
{
|
{
|
||||||
if( connected->Net() == aItem->GetNetCode() )
|
if( aCheckOptionalFlashing && aItem->Type() == PCB_PAD_T )
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// For optionally-flashed layers we normally want to avoid different-net items
|
|
||||||
// by dropping the flashing. However, if the different-net item collides with
|
|
||||||
// our hole then that's not going to help. Showing the flashing in that case
|
|
||||||
// is clearer (and highlights the probable DRC error better).
|
|
||||||
else if( aCheckOptionalFlashing && aItem->Type() == PCB_PAD_T )
|
|
||||||
{
|
{
|
||||||
const PAD* pad = static_cast<const PAD*>( aItem );
|
const PAD* pad = static_cast<const PAD*>( aItem );
|
||||||
SHAPE_SEGMENT hole( *pad->GetEffectiveHoleShape() );
|
SHAPE_SEGMENT hole( *pad->GetEffectiveHoleShape() );
|
||||||
PCB_LAYER_ID layer = ToLAYER_ID( aLayer );
|
PCB_LAYER_ID layer = ToLAYER_ID( aLayer );
|
||||||
|
|
||||||
return connected->Parent()->GetEffectiveShape( layer )->Collide( &hole );
|
if( connected->Net() != aItem->GetNetCode() )
|
||||||
|
{
|
||||||
|
// Even if the nets aren't the same, we need to check for a physical
|
||||||
|
// connection with the unflashed pad's hole (as its walls are plated).
|
||||||
|
return connected->Parent()->GetEffectiveShape( layer )->Collide( &hole );
|
||||||
|
}
|
||||||
|
else if( CN_ZONE_LAYER* zoneLayer = dynamic_cast<CN_ZONE_LAYER*>( connected ) )
|
||||||
|
{
|
||||||
|
ZONE* zone = static_cast<ZONE*>( zoneLayer->Parent() );
|
||||||
|
int idx = zoneLayer->SubpolyIndex();
|
||||||
|
const SHAPE_LINE_CHAIN& island = zone->GetFill( layer )->COutline( idx );
|
||||||
|
std::shared_ptr<SHAPE> flashing = pad->GetEffectiveShape();
|
||||||
|
|
||||||
|
for( const VECTOR2I& pt : island.CPoints() )
|
||||||
|
{
|
||||||
|
if( !flashing->Collide( pt ) )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the entire island is inside the pad's flashing then the pad won't
|
||||||
|
// *actually* connect to anything *else* so don't consider it connected.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( aCheckOptionalFlashing && aItem->Type() == PCB_VIA_T )
|
else if( aCheckOptionalFlashing && aItem->Type() == PCB_VIA_T )
|
||||||
{
|
{
|
||||||
|
@ -435,8 +449,32 @@ bool CONNECTIVITY_DATA::IsConnectedOnLayer( const BOARD_CONNECTED_ITEM *aItem, i
|
||||||
SHAPE_CIRCLE hole( via->GetCenter(), via->GetDrillValue() / 2 );
|
SHAPE_CIRCLE hole( via->GetCenter(), via->GetDrillValue() / 2 );
|
||||||
PCB_LAYER_ID layer = ToLAYER_ID( aLayer );
|
PCB_LAYER_ID layer = ToLAYER_ID( aLayer );
|
||||||
|
|
||||||
return connected->Parent()->GetEffectiveShape( layer )->Collide( &hole );
|
if( connected->Net() != aItem->GetNetCode() )
|
||||||
|
{
|
||||||
|
// Even if the nets aren't the same, we need to check for a physical
|
||||||
|
// connection with the unflashed via's hole (as its walls are plated).
|
||||||
|
return connected->Parent()->GetEffectiveShape( layer )->Collide( &hole );
|
||||||
|
}
|
||||||
|
else if( CN_ZONE_LAYER* zoneLayer = dynamic_cast<CN_ZONE_LAYER*>( connected ) )
|
||||||
|
{
|
||||||
|
ZONE* zone = static_cast<ZONE*>( zoneLayer->Parent() );
|
||||||
|
int idx = zoneLayer->SubpolyIndex();
|
||||||
|
const SHAPE_LINE_CHAIN& island = zone->GetFill( layer )->COutline( idx );
|
||||||
|
SHAPE_CIRCLE flashing( via->GetCenter(), via->GetWidth() / 2 );
|
||||||
|
|
||||||
|
for( const VECTOR2I& pt : island.CPoints() )
|
||||||
|
{
|
||||||
|
if( !flashing.SHAPE::Collide( pt ) )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the entire island is inside the via's flashing then the via won't
|
||||||
|
// *actually* connect to anything *else* so don't consider it connected.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return connected->Net() == aItem->GetNetCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -314,10 +314,9 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int SubpolyIndex() const
|
int SubpolyIndex() const { return m_subpolyIndex; }
|
||||||
{
|
|
||||||
return m_subpolyIndex;
|
PCB_LAYER_ID GetLayer() const { return m_layer; }
|
||||||
}
|
|
||||||
|
|
||||||
bool ContainsPoint( const VECTOR2I& p ) const
|
bool ContainsPoint( const VECTOR2I& p ) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -373,11 +373,17 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now remove islands outside the board edge
|
// Now remove islands which are either outside the board edge or fail to meet the minimum
|
||||||
|
// area requirements
|
||||||
//
|
//
|
||||||
for( ZONE* zone : aZones )
|
for( ZONE* zone : aZones )
|
||||||
{
|
{
|
||||||
LSET zoneCopperLayers = zone->GetLayerSet() & LSET::AllCuMask( MAX_CU_LAYERS );
|
LSET zoneCopperLayers = zone->GetLayerSet() & LSET::AllCuMask( MAX_CU_LAYERS );
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// arbitrarily choose "at least 2X the area".
|
||||||
|
double minArea = (double) zone->GetMinThickness() * zone->GetMinThickness() * 2;
|
||||||
|
|
||||||
for( PCB_LAYER_ID layer : zoneCopperLayers.Seq() )
|
for( PCB_LAYER_ID layer : zoneCopperLayers.Seq() )
|
||||||
{
|
{
|
||||||
|
@ -390,8 +396,12 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
|
||||||
{
|
{
|
||||||
std::vector<SHAPE_LINE_CHAIN>& island = poly->Polygon( ii );
|
std::vector<SHAPE_LINE_CHAIN>& island = poly->Polygon( ii );
|
||||||
|
|
||||||
if( island.empty() || !m_boardOutline.Contains( island.front().CPoint( 0 ) ) )
|
if( island.empty()
|
||||||
|
|| !m_boardOutline.Contains( island.front().CPoint( 0 ) )
|
||||||
|
|| island.front().Area() < minArea )
|
||||||
|
{
|
||||||
poly->DeletePolygonAndTriangulationData( ii, false );
|
poly->DeletePolygonAndTriangulationData( ii, false );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
poly->UpdateTriangulationDataHash();
|
poly->UpdateTriangulationDataHash();
|
||||||
|
@ -665,10 +675,8 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE* aZone, PCB_LAYER_ID aLa
|
||||||
|
|
||||||
if( aPad->GetNetCode() > 0 && aPad->GetNetCode() == aZone->GetNetCode() )
|
if( aPad->GetNetCode() > 0 && aPad->GetNetCode() == aZone->GetNetCode() )
|
||||||
{
|
{
|
||||||
// For pads having the same netcode as the zone, the net and hole
|
// For unconnected but same-net pads, electrical clearances don't apply.
|
||||||
// clearances have no meanings.
|
// Use the greater of the zone's local clearance and thermal relief.
|
||||||
// So just knock out the greater of the zone's local clearance and
|
|
||||||
// thermal relief.
|
|
||||||
gap = std::max( aZone->GetLocalClearance(), aZone->GetThermalReliefGap() );
|
gap = std::max( aZone->GetLocalClearance(), aZone->GetThermalReliefGap() );
|
||||||
knockoutHoleClearance = false;
|
knockoutHoleClearance = false;
|
||||||
}
|
}
|
||||||
|
@ -715,18 +723,7 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE* aZone, PCB_LAYER_ID aLa
|
||||||
int gap = 0;
|
int gap = 0;
|
||||||
bool checkHoleClearance = true;
|
bool checkHoleClearance = true;
|
||||||
|
|
||||||
if( via->GetNetCode() > 0 && via->GetNetCode() == aZone->GetNetCode() )
|
gap = evalRulesForItems( CLEARANCE_CONSTRAINT, aZone, aTrack, aLayer );
|
||||||
{
|
|
||||||
// For pads having the same netcode as the zone, the net and hole
|
|
||||||
// clearances have no meanings.
|
|
||||||
// So just knock out the zone's local clearance.
|
|
||||||
gap = aZone->GetLocalClearance();
|
|
||||||
checkHoleClearance = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gap = evalRulesForItems( CLEARANCE_CONSTRAINT, aZone, aTrack, aLayer );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( via->FlashLayer( aLayer ) )
|
if( via->FlashLayer( aLayer ) )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue