Faster algorithm for zone-to-zone connectivity test.

This commit is contained in:
Jeff Young 2020-09-23 18:51:52 +01:00
parent ac4978cf8a
commit 1f284111b0
1 changed files with 35 additions and 24 deletions

View File

@ -659,41 +659,52 @@ void CN_VISITOR::checkZoneZoneConnection( CN_ZONE* aZoneA, CN_ZONE* aZoneB )
if( aZoneB->Net() != aZoneA->Net() ) if( aZoneB->Net() != aZoneA->Net() )
return; // we only test zones belonging to the same 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;
for( PCB_LAYER_ID layer : LSET( parentA->GetLayerSet() & parentB->GetLayerSet() ).Seq() ) for( PCB_LAYER_ID layer : LSET( parentA->GetLayerSet() & parentB->GetLayerSet() ).Seq() )
{ {
SHAPE_POLY_SET testA = parentA->GetFilledPolysList( layer ); const SHAPE_LINE_CHAIN& outline =
const SHAPE_POLY_SET* testB = &parentB->GetFilledPolysList( layer ); parentA->GetFilledPolysList( layer ).COutline( aZoneA->SubpolyIndex() );
if( parentA->GetFilledPolysUseThickness() && parentA->GetMinThickness() > 0 ) for( int i = 0; i < outline.PointCount(); i++ )
{ {
int halfThickness = parentA->GetMinThickness() / 2; if( !boxB.Contains( outline.CPoint( i ) ) )
int numSegs = GetArcToSegmentCount( halfThickness, ARC_HIGH_DEF, 360.0 ); continue;
testA.Inflate( halfThickness, numSegs ); if( aZoneB->ContainsPoint( outline.CPoint( i ), radiusA ) )
}
if( parentB->GetFilledPolysUseThickness() && parentB->GetMinThickness() > 0 )
{
static SHAPE_POLY_SET temp;
temp = parentB->GetFilledPolysList( layer );
int halfThickness = parentB->GetMinThickness() / 2;
int numSegs = GetArcToSegmentCount( halfThickness, ARC_HIGH_DEF, 360.0 );
temp.Inflate( halfThickness, numSegs );
testB = &temp;
}
testA.BooleanIntersection( *testB, SHAPE_POLY_SET::PM_FAST );
if( !testA.IsEmpty() )
{ {
aZoneA->Connect( aZoneB ); aZoneA->Connect( aZoneB );
aZoneB->Connect( aZoneA ); aZoneB->Connect( aZoneA );
return; return;
} }
} }
const SHAPE_LINE_CHAIN& outline2 =
parentB->GetFilledPolysList( layer ).COutline( aZoneB->SubpolyIndex() );
for( int i = 0; i < outline2.PointCount(); i++ )
{
if( !boxA.Contains( outline2.CPoint( i ) ) )
continue;
if( aZoneA->ContainsPoint( outline2.CPoint( i ), radiusB ) )
{
aZoneA->Connect( aZoneB );
aZoneB->Connect( aZoneA );
return;
}
}
}
} }