diff --git a/pcbnew/connectivity/connectivity_algo.cpp b/pcbnew/connectivity/connectivity_algo.cpp index 7fec51b664..b7b6083e0d 100644 --- a/pcbnew/connectivity/connectivity_algo.cpp +++ b/pcbnew/connectivity/connectivity_algo.cpp @@ -681,6 +681,9 @@ void CN_VISITOR::checkZoneItemConnection( CN_ZONE_LAYER* aZoneLayer, CN_ITEM* aI void CN_VISITOR::checkZoneZoneConnection( CN_ZONE_LAYER* aZoneLayerA, CN_ZONE_LAYER* aZoneLayerB ) { + const ZONE* zoneA = static_cast( aZoneLayerA->Parent() ); + const ZONE* zoneB = static_cast( aZoneLayerB->Parent() ); + if( aZoneLayerA->Layer() != aZoneLayerB->Layer() ) return; @@ -695,10 +698,36 @@ void CN_VISITOR::checkZoneZoneConnection( CN_ZONE_LAYER* aZoneLayerA, CN_ZONE_LA PCB_LAYER_ID layer = static_cast( aZoneLayerA->Layer() ); - if( aZoneLayerA->Collide( aZoneLayerB->Parent()->GetEffectiveShape( layer ).get() ) ) + const SHAPE_LINE_CHAIN& outline = + zoneA->GetFilledPolysList( layer ).COutline( aZoneLayerA->SubpolyIndex() ); + + for( int i = 0; i < outline.PointCount(); i++ ) { - aZoneLayerA->Connect( aZoneLayerB ); - aZoneLayerB->Connect( aZoneLayerA ); + if( !boxB.Contains( outline.CPoint( i ) ) ) + continue; + + if( aZoneLayerB->ContainsPoint( outline.CPoint( i ) ) ) + { + aZoneLayerA->Connect( aZoneLayerB ); + aZoneLayerB->Connect( aZoneLayerA ); + return; + } + } + + const SHAPE_LINE_CHAIN& outline2 = + zoneB->GetFilledPolysList( layer ).COutline( aZoneLayerB->SubpolyIndex() ); + + for( int i = 0; i < outline2.PointCount(); i++ ) + { + if( !boxA.Contains( outline2.CPoint( i ) ) ) + continue; + + if( aZoneLayerA->ContainsPoint( outline2.CPoint( i ) ) ) + { + aZoneLayerA->Connect( aZoneLayerB ); + aZoneLayerB->Connect( aZoneLayerA ); + return; + } } } diff --git a/pcbnew/connectivity/connectivity_items.h b/pcbnew/connectivity/connectivity_items.h index eba83a531f..6b90197592 100644 --- a/pcbnew/connectivity/connectivity_items.h +++ b/pcbnew/connectivity/connectivity_items.h @@ -313,6 +313,29 @@ public: return m_subpolyIndex; } + bool ContainsPoint( const VECTOR2I& p ) const + { + int min[2] = { p.x, p.y }; + int max[2] = { p.x, p.y }; + bool collision = false; + + auto visitor = + [&]( const SHAPE* aShape ) -> bool + { + if( aShape->Collide( p ) ) + { + collision = true; + return false; + } + + return true; + }; + + m_rTree.Search( min, max, visitor ); + + return collision; + } + PCB_LAYER_ID GetLayer() { return m_layer; } virtual int AnchorCount() const override;