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
This commit is contained in:
Seth Hillbrand 2020-08-07 15:57:59 -07:00
parent dcc484e114
commit f615b026d9
2 changed files with 32 additions and 13 deletions

View File

@ -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<const ZONE_CONTAINER*>( aZoneA->Parent() );
const auto testedParent = static_cast<const ZONE_CONTAINER*>( aZoneB->Parent() );
const auto parentA = static_cast<const ZONE_CONTAINER*>( aZoneA->Parent() );
const auto parentB = static_cast<const ZONE_CONTAINER*>( 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<PCB_LAYER_ID>( 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 );

View File

@ -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<ZONE_CONTAINER*> ( 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()