From ab43c3c6b566fd43c97cbd5f96ecac245530d4a2 Mon Sep 17 00:00:00 2001 From: Jeff Young <jeff@rokeby.ie> Date: Tue, 25 Mar 2025 11:37:36 +0000 Subject: [PATCH] Process non-copper keepouts in footprints. Fixes https://gitlab.com/kicad/code/kicad/-/issues/20405 --- pcbnew/zone_filler.cpp | 58 +++++++++++++++++++++++++++--------------- pcbnew/zone_filler.h | 2 +- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/pcbnew/zone_filler.cpp b/pcbnew/zone_filler.cpp index 4eb23bd81e..1dc22f379c 100644 --- a/pcbnew/zone_filler.cpp +++ b/pcbnew/zone_filler.cpp @@ -1936,30 +1936,48 @@ bool ZONE_FILLER::fillNonCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer, aFillPolys = aSmoothedOutline; aFillPolys.BooleanSubtract( clearanceHoles ); + auto subtractKeepout = + [&]( ZONE* candidate ) + { + if( !candidate->GetIsRuleArea() ) + return; + + if( !candidate->HasKeepoutParametersSet() ) + return; + + if( candidate->GetDoNotAllowCopperPour() && candidate->IsOnLayer( aLayer ) ) + { + if( candidate->GetBoundingBox().Intersects( zone_boundingbox ) ) + { + if( candidate->Outline()->ArcCount() == 0 ) + { + aFillPolys.BooleanSubtract( *candidate->Outline() ); + } + else + { + SHAPE_POLY_SET keepoutOutline( *candidate->Outline() ); + keepoutOutline.ClearArcs(); + aFillPolys.BooleanSubtract( keepoutOutline ); + } + } + } + }; + for( ZONE* keepout : m_board->Zones() ) { - if( !keepout->GetIsRuleArea() ) - continue; + if( checkForCancel( m_progressReporter ) ) + return false; - if( !keepout->HasKeepoutParametersSet() ) - continue; + subtractKeepout( keepout ); + } - if( keepout->GetDoNotAllowCopperPour() && keepout->IsOnLayer( aLayer ) ) - { - if( keepout->GetBoundingBox().Intersects( zone_boundingbox ) ) - { - if( keepout->Outline()->ArcCount() == 0 ) - { - aFillPolys.BooleanSubtract( *keepout->Outline() ); - } - else - { - SHAPE_POLY_SET keepoutOutline( *keepout->Outline() ); - keepoutOutline.ClearArcs(); - aFillPolys.BooleanSubtract( keepoutOutline ); - } - } - } + for( FOOTPRINT* footprint : m_board->Footprints() ) + { + if( checkForCancel( m_progressReporter ) ) + return false; + + for( ZONE* keepout : footprint->Zones() ) + subtractKeepout( keepout ); } // Features which are min_width should survive pruning; features that are *less* than diff --git a/pcbnew/zone_filler.h b/pcbnew/zone_filler.h index 3053c977ad..faa730cc00 100644 --- a/pcbnew/zone_filler.h +++ b/pcbnew/zone_filler.h @@ -94,7 +94,7 @@ private: const SHAPE_POLY_SET& aSmoothedOutline, const SHAPE_POLY_SET& aMaxExtents, SHAPE_POLY_SET& aFillPolys ); - bool fillNonCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer, + bool fillNonCopperZone( const ZONE* candidate, PCB_LAYER_ID aLayer, const SHAPE_POLY_SET& aSmoothedOutline, SHAPE_POLY_SET& aFillPolys ); /** * Function buildThermalSpokes