PCB_BASE_FRAME::FocusOnItem(): avoid extremely long calculation time for zones.

The algo used to calculate a focus point on a zone can be *extremely* time
consuming when using the filled areas in zone (can be matter of minutes and more).
So we use now only the zone outlines usually having not a lot of vertices.
This commit is contained in:
jean-pierre charras 2022-01-10 18:14:19 +01:00
parent 73a2984963
commit cfe93e34a2
2 changed files with 28 additions and 5 deletions

View File

@ -354,11 +354,31 @@ void PCB_BASE_FRAME::FocusOnItem( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer )
case PCB_FP_DIM_CENTER_T:
case PCB_FP_DIM_RADIAL_T:
case PCB_FP_DIM_ORTHOGONAL_T:
case PCB_ZONE_T:
aItem->TransformShapeWithClearanceToPolygon( itemPoly, aLayer, 0, Millimeter2iu( 0.1 ),
ERROR_INSIDE );
break;
case PCB_ZONE_T:
{
ZONE* zone = static_cast<ZONE*>( aItem );
#if 0
// Using the filled area shapes to find a Focus point can give good results, but
// unfortunately the calculations are highly time consuming, even for not very
// large areas (can be easily a few minutes for large areas).
// so we used only the zone outline that usually do not have too many vertices.
zone->TransformShapeWithClearanceToPolygon( itemPoly, aLayer, 0, Millimeter2iu( 0.1 ),
ERROR_INSIDE );
if( itemPoly.IsEmpty() )
itemPoly = *zone->Outline();
#else
// much faster calculation time when using only the zone outlines
itemPoly = *zone->Outline();
#endif
break;
}
default:
{
BOX2I item_bbox = aItem->GetBoundingBox();
@ -396,7 +416,7 @@ void PCB_BASE_FRAME::FocusOnItem( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer )
while( !itemPoly.IsEmpty() )
{
focusPt = (wxPoint) itemPoly.BBox().Centre();
itemPoly.Deflate( step, 4 );
itemPoly.Deflate( step, 4, SHAPE_POLY_SET::CHAMFER_ACUTE_CORNERS );
}
FocusOnLocation( focusPt );

View File

@ -1375,9 +1375,12 @@ void ZONE::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
aCornerBuffer = m_FilledPolysList.at( aLayer );
// Rebuild filled areas only if clearance is not 0
if( aClearance )
{
int numSegs = GetArcToSegmentCount( aClearance, aError, 360.0 );
aCornerBuffer.Inflate( aClearance, numSegs );
aCornerBuffer.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
aCornerBuffer.InflateWithLinkedHoles( aClearance, numSegs, SHAPE_POLY_SET::PM_FAST );
}
}