From f615b026d9b0416ef2dd796062345980205ebaf6 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Fri, 7 Aug 2020 15:57:59 -0700 Subject: [PATCH] pcbnew: Account for zone expansion in conn Connecting zone-to-zone, we need to allow for the stroke-width in old-style polygons. Also, speed up the calculation by skipping zone points that do not fall inside the matching BBox Fixes https://gitlab.com/kicad/code/kicad/issues/5043 --- pcbnew/connectivity/connectivity_algo.cpp | 35 ++++++++++++++++------- pcbnew/connectivity/connectivity_items.h | 10 +++++-- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/pcbnew/connectivity/connectivity_algo.cpp b/pcbnew/connectivity/connectivity_algo.cpp index 21d6053ca3..62d26fc72e 100644 --- a/pcbnew/connectivity/connectivity_algo.cpp +++ b/pcbnew/connectivity/connectivity_algo.cpp @@ -655,13 +655,10 @@ void CN_VISITOR::checkZoneItemConnection( CN_ZONE* aZone, CN_ITEM* aItem ) void CN_VISITOR::checkZoneZoneConnection( CN_ZONE* aZoneA, CN_ZONE* aZoneB ) { - const auto refParent = static_cast( aZoneA->Parent() ); - const auto testedParent = static_cast( aZoneB->Parent() ); + const auto parentA = static_cast( aZoneA->Parent() ); + const auto parentB = static_cast( aZoneB->Parent() ); - if( testedParent->Type () != PCB_ZONE_AREA_T ) - return; - - if( aZoneB == aZoneA || refParent == testedParent ) + if( aZoneB == aZoneA || parentA == parentB ) return; if( aZoneA->Layer() != aZoneB->Layer() ) @@ -670,13 +667,28 @@ void CN_VISITOR::checkZoneZoneConnection( CN_ZONE* aZoneA, CN_ZONE* aZoneB ) if( aZoneB->Net() != aZoneA->Net() ) return; // we only test zones belonging to the same net + const BOX2I& boxA = aZoneA->BBox(); + const BOX2I& boxB = aZoneB->BBox(); + + int radiusA = 0; + int radiusB = 0; + + if( parentA->GetFilledPolysUseThickness() ) + radiusA = ( parentA->GetMinThickness() + 1 ) / 2; + + if( parentB->GetFilledPolysUseThickness() ) + radiusB = ( parentB->GetMinThickness() + 1 ) / 2; + PCB_LAYER_ID layer = static_cast( aZoneA->Layer() ); - const auto& outline = refParent->GetFilledPolysList( layer ).COutline( aZoneA->SubpolyIndex() ); + const auto& outline = parentA->GetFilledPolysList( layer ).COutline( aZoneA->SubpolyIndex() ); for( int i = 0; i < outline.PointCount(); i++ ) { - if( aZoneB->ContainsPoint( outline.CPoint( i ), 0 ) ) + if( !boxB.Contains( outline.CPoint( i ) ) ) + continue; + + if( aZoneB->ContainsPoint( outline.CPoint( i ), radiusA ) ) { aZoneA->Connect( aZoneB ); aZoneB->Connect( aZoneA ); @@ -685,11 +697,14 @@ void CN_VISITOR::checkZoneZoneConnection( CN_ZONE* aZoneA, CN_ZONE* aZoneB ) } const auto& outline2 = - testedParent->GetFilledPolysList( layer ).COutline( aZoneB->SubpolyIndex() ); + parentB->GetFilledPolysList( layer ).COutline( aZoneB->SubpolyIndex() ); for( int i = 0; i < outline2.PointCount(); i++ ) { - if( aZoneA->ContainsPoint( outline2.CPoint( i ), 0 ) ) + if( !boxA.Contains( outline2.CPoint( i ) ) ) + continue; + + if( aZoneA->ContainsPoint( outline2.CPoint( i ), radiusB ) ) { aZoneA->Connect( aZoneB ); aZoneB->Connect( aZoneA ); diff --git a/pcbnew/connectivity/connectivity_items.h b/pcbnew/connectivity/connectivity_items.h index 058759bfff..75990c2bdc 100644 --- a/pcbnew/connectivity/connectivity_items.h +++ b/pcbnew/connectivity/connectivity_items.h @@ -375,11 +375,15 @@ public: return ContainsPoint( anchor->Pos(), 0 ); } - bool ContainsPoint( const VECTOR2I p, int aAccuracy ) const + bool ContainsPoint( const VECTOR2I p, int aAccuracy = 0 ) const { auto zone = static_cast ( Parent() ); - int clearance = zone->GetFilledPolysUseThickness() ? zone->GetMinThickness() / 2 : 0; - return m_cachedPoly->ContainsPoint( p, clearance + aAccuracy ); + int clearance = ( aAccuracy + 1 ) / 2; + + if( zone->GetFilledPolysUseThickness() ) + clearance += ( zone->GetMinThickness() + 1 ) / 2; + + return m_cachedPoly->ContainsPoint( p, clearance ); } const BOX2I& BBox()