Move SHAPE_POLY_SET::Inflate's error spec from a seg-count to a max-deviation.

1) Also reorders parameters to make sure the compiler helps out.

2) This also makes it harder to mess up the discrepency between
   BOX2I/wxRECT/etc::Inflate() and SHAPE_POLY_SET::Inflate.

3) Also fixes a couple of bugs where the corner strategy was passed
   in as a segCount.

4) Also fixes a couple of bugs where the error wasn't forced to the
   outside to match the ERROR_LOCATION.

5) Also fixes a couple of bugs where the seg count was specified
   without regard to an already passed-in max deviation
This commit is contained in:
Jeff Young 2023-05-29 15:28:48 +01:00
parent 7f250870fe
commit 65e53b8ecd
14 changed files with 83 additions and 81 deletions

View File

@ -438,7 +438,7 @@ void BOARD_ADAPTER::createPadWithMargin( const PAD* aPad, CONTAINER_2D_BASE* aCo
if( !poly.IsEmpty() )
{
if( clearance.x )
poly.Inflate( clearance.x, 32 );
poly.Inflate( clearance.x, SHAPE_POLY_SET::ROUND_ALL_CORNERS, maxError );
// Add the PAD polygon
ConvertPolygonToTriangles( poly, *aContainer, m_biuTo3Dunits, *aPad );

View File

@ -1002,19 +1002,19 @@ public:
* the outline.
*
* @param aAmount is the number of units to offset edges.
* @param aCircleSegCount is the number of segments per 360 degrees to use in curve approx
* @param aCornerStrategy #ALLOW_ACUTE_CORNERS to preserve all angles,
* #CHAMFER_ACUTE_CORNERS to chop angles less than 90°,
* #ROUND_ACUTE_CORNERS to round off angles less than 90°,
* #ROUND_ALL_CORNERS to round regardless of angles
* @param aMaxError is the allowable deviation when rounding corners with an approximated
* polygon
*/
void Inflate( int aAmount, int aCircleSegCount,
CORNER_STRATEGY aCornerStrategy = ROUND_ALL_CORNERS, bool aSimplify = false );
void Inflate( int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError,
bool aSimplify = false );
void Deflate( int aAmount, int aCircleSegmentsCount,
CORNER_STRATEGY aCornerStrategy = CHAMFER_ALL_CORNERS )
void Deflate( int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError )
{
Inflate( -aAmount, aCircleSegmentsCount, aCornerStrategy );
Inflate( -aAmount, aCornerStrategy, aMaxError );
}
/**

View File

@ -1096,13 +1096,15 @@ void SHAPE_POLY_SET::inflate2( int aAmount, int aCircleSegCount, CORNER_STRATEGY
}
void SHAPE_POLY_SET::Inflate( int aAmount, int aCircleSegCount, CORNER_STRATEGY aCornerStrategy,
bool aSimplify )
void SHAPE_POLY_SET::Inflate( int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError,
bool aSimplify )
{
int segCount = GetArcToSegmentCount( aAmount, aMaxError, FULL_CIRCLE );
if( ADVANCED_CFG::GetCfg().m_UseClipper2 )
inflate2( aAmount, aCircleSegCount, aCornerStrategy, aSimplify );
inflate2( aAmount, segCount, aCornerStrategy, aSimplify );
else
inflate1( aAmount, aCircleSegCount, aCornerStrategy );
inflate1( aAmount, segCount, aCornerStrategy );
}

View File

@ -190,8 +190,9 @@ bool DRC_TEST_PROVIDER_TEXT_DIMS::Run()
if( glyphArea == 0 )
continue;
poly.Inflate( constraint.Value().Min() / 2, 16 );
poly.Simplify( SHAPE_POLY_SET::PM_FAST );
poly.Inflate( constraint.Value().Min() / 2,
SHAPE_POLY_SET::CHAMFER_ALL_CORNERS, ARC_LOW_DEF, true );
double resultingGlyphArea = poly.Area();
if( ( std::abs( resultingGlyphArea - glyphArea ) / glyphArea ) > 0.1 )

View File

@ -1952,13 +1952,13 @@ double FOOTPRINT::GetCoverageArea( const BOARD_ITEM* aItem, const GENERAL_COLLEC
{
const PCB_TEXT* text = static_cast<const PCB_TEXT*>( aItem );
text->TransformTextToPolySet( poly, textMargin, ARC_LOW_DEF, ERROR_OUTSIDE );
text->TransformTextToPolySet( poly, textMargin, ARC_LOW_DEF, ERROR_INSIDE );
}
else if( aItem->Type() == PCB_TEXTBOX_T )
{
const PCB_TEXTBOX* tb = static_cast<const PCB_TEXTBOX*>( aItem );
tb->TransformTextToPolySet( poly, textMargin, ARC_LOW_DEF, ERROR_OUTSIDE );
tb->TransformTextToPolySet( poly, textMargin, ARC_LOW_DEF, ERROR_INSIDE );
}
else if( aItem->Type() == PCB_SHAPE_T )
{
@ -2138,14 +2138,14 @@ void FOOTPRINT::BuildCourtyardCaches( OUTLINE_ERROR_HANDLER* aErrorHandler )
if( !list_front.size() && !list_back.size() )
return;
int errorMax = pcbIUScale.mmToIU( 0.02 ); // max error for polygonization
int maxError = pcbIUScale.mmToIU( 0.02 ); // max error for polygonization
int chainingEpsilon = pcbIUScale.mmToIU( 0.02 ); // max dist from one endPt to next startPt
if( ConvertOutlineToPolygon( list_front, m_courtyard_cache_front, errorMax, chainingEpsilon,
if( ConvertOutlineToPolygon( list_front, m_courtyard_cache_front, maxError, chainingEpsilon,
true, aErrorHandler ) )
{
// Touching courtyards, or courtyards -at- the clearance distance are legal.
m_courtyard_cache_front.Inflate( -1, SHAPE_POLY_SET::CHAMFER_ACUTE_CORNERS );
m_courtyard_cache_front.Inflate( -1, SHAPE_POLY_SET::CHAMFER_ACUTE_CORNERS, maxError );
m_courtyard_cache_front.CacheTriangulation( false );
}
@ -2154,11 +2154,11 @@ void FOOTPRINT::BuildCourtyardCaches( OUTLINE_ERROR_HANDLER* aErrorHandler )
SetFlags( MALFORMED_F_COURTYARD );
}
if( ConvertOutlineToPolygon( list_back, m_courtyard_cache_back, errorMax, chainingEpsilon,
if( ConvertOutlineToPolygon( list_back, m_courtyard_cache_back, maxError, chainingEpsilon,
true, aErrorHandler ) )
{
// Touching courtyards, or courtyards -at- the clearance distance are legal.
m_courtyard_cache_back.Inflate( -1, SHAPE_POLY_SET::CHAMFER_ACUTE_CORNERS );
m_courtyard_cache_back.Inflate( -1, SHAPE_POLY_SET::CHAMFER_ACUTE_CORNERS, maxError );
m_courtyard_cache_back.CacheTriangulation( false );
}

View File

@ -1592,7 +1592,7 @@ bool PAD::TransformHoleToPolygon( SHAPE_POLY_SET& aBuffer, int aClearance, int a
void PAD::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth ) const
int aMaxError, ERROR_LOC aErrorLoc, bool ignoreLineWidth ) const
{
wxASSERT_MSG( !ignoreLineWidth, wxT( "IgnoreLineWidth has no meaning for pads." ) );
@ -1613,7 +1613,7 @@ void PAD::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
// Note: dx == dy is not guaranteed for circle pads in legacy boards
if( dx == dy || ( GetShape() == PAD_SHAPE::CIRCLE ) )
{
TransformCircleToPolygon( aBuffer, padShapePos, dx + aClearance, aError, aErrorLoc,
TransformCircleToPolygon( aBuffer, padShapePos, dx + aClearance, aMaxError, aErrorLoc,
pad_min_seg_per_circle_count );
}
else
@ -1624,7 +1624,7 @@ void PAD::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
RotatePoint( delta, m_orient );
TransformOvalToPolygon( aBuffer, padShapePos - delta, padShapePos + delta,
( half_width + aClearance ) * 2, aError, aErrorLoc,
( half_width + aClearance ) * 2, aMaxError, aErrorLoc,
pad_min_seg_per_circle_count );
}
@ -1638,7 +1638,7 @@ void PAD::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
SHAPE_POLY_SET outline;
TransformTrapezoidToPolygon( outline, padShapePos, m_size, m_orient, ddx, ddy, aClearance,
aError, aErrorLoc );
aMaxError, aErrorLoc );
aBuffer.Append( outline );
break;
}
@ -1653,7 +1653,7 @@ void PAD::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
GetRoundRectCornerRadius(),
doChamfer ? GetChamferRectRatio() : 0,
doChamfer ? GetChamferPositions() : 0,
aClearance, aError, aErrorLoc );
aClearance, aMaxError, aErrorLoc );
aBuffer.Append( outline );
break;
}
@ -1665,19 +1665,12 @@ void PAD::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
outline.Rotate( m_orient );
outline.Move( VECTOR2I( m_pos ) );
if( aClearance )
if( aClearance > 0 || aErrorLoc == ERROR_OUTSIDE )
{
int numSegs = std::max( GetArcToSegmentCount( aClearance, aError, FULL_CIRCLE ),
pad_min_seg_per_circle_count );
int clearance = aClearance;
if( aErrorLoc == ERROR_OUTSIDE )
{
int actual_error = CircleToEndSegmentDeltaRadius( clearance, numSegs );
clearance += GetCircleToPolyCorrection( actual_error );
}
aClearance += aMaxError;
outline.Inflate( clearance, numSegs );
outline.Inflate( aClearance, SHAPE_POLY_SET::ROUND_ALL_CORNERS, aMaxError );
outline.Fracture( SHAPE_POLY_SET::PM_FAST );
}

View File

@ -466,7 +466,7 @@ void PCB_TEXT::buildBoundingHull( SHAPE_POLY_SET* aBuffer, const SHAPE_POLY_SET&
}
void PCB_TEXT::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance, int aError,
void PCB_TEXT::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance, int aMaxError,
ERROR_LOC aErrorLoc ) const
{
KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
@ -485,7 +485,7 @@ void PCB_TEXT::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance,
// Stroke callback
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
{
TransformOvalToPolygon( textShape, aPt1, aPt2, penWidth, aError, aErrorLoc );
TransformOvalToPolygon( textShape, aPt1, aPt2, penWidth, aMaxError, aErrorLoc );
},
// Triangulation callback
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 )
@ -511,11 +511,12 @@ void PCB_TEXT::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance,
}
else
{
if( aClearance > 0 )
if( aClearance > 0 || aErrorLoc == ERROR_OUTSIDE )
{
// Number of segments to approximate a circle when inflating a polygon
const int circleSegmentsCount = 16;
textShape.Inflate( aClearance, circleSegmentsCount );
if( aErrorLoc == ERROR_OUTSIDE )
aClearance += aMaxError;
textShape.Inflate( aClearance, SHAPE_POLY_SET::ROUND_ALL_CORNERS, aMaxError );
}
aBuffer.Append( textShape );
@ -524,12 +525,12 @@ void PCB_TEXT::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance,
void PCB_TEXT::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
int aClearance, int aError, ERROR_LOC aErrorLoc,
int aClearance, int aMaxError, ERROR_LOC aErrorLoc,
bool aIgnoreLineWidth ) const
{
SHAPE_POLY_SET poly;
TransformTextToPolySet( poly, 0, GetBoard()->GetDesignSettings().m_MaxError, ERROR_INSIDE );
TransformTextToPolySet( poly, 0, aMaxError, aErrorLoc );
buildBoundingHull( &aBuffer, poly, aClearance );
}

View File

@ -137,13 +137,13 @@ public:
* Circles and arcs are approximated by segments.
* @param aBuffer SHAPE_POLY_SET to store the polygon corners
* @param aClearance the clearance around the text
* @param aError the maximum error to allow when approximating curves
* @param aMaxError the maximum error to allow when approximating curves
*/
void TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance, int aError,
void TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance, int aMaxError,
ERROR_LOC aErrorLoc ) const;
void TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
int aError, ERROR_LOC aErrorLoc,
int aMaxError, ERROR_LOC aErrorLoc,
bool aIgnoreLineWidth = false ) const override;
// @copydoc BOARD_ITEM::GetEffectiveShape

View File

@ -447,7 +447,7 @@ std::shared_ptr<SHAPE> PCB_TEXTBOX::GetEffectiveShape( PCB_LAYER_ID aLayer, FLAS
}
void PCB_TEXTBOX::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance, int aError,
void PCB_TEXTBOX::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance, int aMaxError,
ERROR_LOC aErrorLoc ) const
{
KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
@ -465,7 +465,7 @@ void PCB_TEXTBOX::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearanc
// Stroke callback
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
{
TransformOvalToPolygon( buffer, aPt1, aPt2, penWidth, aError, aErrorLoc );
TransformOvalToPolygon( buffer, aPt1, aPt2, penWidth, aMaxError, aErrorLoc );
},
// Triangulation callback
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 )
@ -478,17 +478,24 @@ void PCB_TEXTBOX::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearanc
font->Draw( &callback_gal, GetShownText( true ), GetDrawPos(), GetAttributes() );
if( aClearance > 0 )
buffer.Inflate( aClearance, aClearance );
if( aClearance > 0 || aErrorLoc == ERROR_OUTSIDE )
{
if( aErrorLoc == ERROR_OUTSIDE )
aClearance += aMaxError;
buffer.Inflate( aClearance, SHAPE_POLY_SET::ROUND_ALL_CORNERS, aMaxError, true );
}
else
{
buffer.Simplify( SHAPE_POLY_SET::PM_FAST );
}
aBuffer.Append( buffer );
}
void PCB_TEXTBOX::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
int aClearance, int aError, ERROR_LOC aErrorLoc,
int aClearance, int aMaxError, ERROR_LOC aErrorLoc,
bool aIgnoreLineWidth ) const
{
// Don't use PCB_SHAPE::TransformShapeToPolygon. We want to treat the textbox as filled even
@ -508,10 +515,10 @@ void PCB_TEXTBOX::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID
if( width > 0 )
{
// Add in segments
TransformOvalToPolygon( aBuffer, pts[0], pts[1], width, aError, aErrorLoc );
TransformOvalToPolygon( aBuffer, pts[1], pts[2], width, aError, aErrorLoc );
TransformOvalToPolygon( aBuffer, pts[2], pts[3], width, aError, aErrorLoc );
TransformOvalToPolygon( aBuffer, pts[3], pts[0], width, aError, aErrorLoc );
TransformOvalToPolygon( aBuffer, pts[0], pts[1], width, aMaxError, aErrorLoc );
TransformOvalToPolygon( aBuffer, pts[1], pts[2], width, aMaxError, aErrorLoc );
TransformOvalToPolygon( aBuffer, pts[2], pts[3], width, aMaxError, aErrorLoc );
TransformOvalToPolygon( aBuffer, pts[3], pts[0], width, aMaxError, aErrorLoc );
}
}
else if( GetShape() == SHAPE_T::POLY ) // Non-cardinally-rotated rect
@ -528,7 +535,7 @@ void PCB_TEXTBOX::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID
for( int ii = 0; ii < poly.SegmentCount(); ++ii )
{
const SEG& seg = poly.GetSegment( ii );
TransformOvalToPolygon( aBuffer, seg.A, seg.B, width, aError, aErrorLoc );
TransformOvalToPolygon( aBuffer, seg.A, seg.B, width, aMaxError, aErrorLoc );
}
}
}

View File

@ -114,11 +114,11 @@ public:
* @param aClearance = the clearance around the text
* @param aError = the maximum error to allow when approximating curves
*/
void TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance, int aError,
void TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance, int aMaxError,
ERROR_LOC aErrorLoc ) const;
void TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
int aError, ERROR_LOC aErrorLoc,
int aMaxError, ERROR_LOC aErrorLoc,
bool aIgnoreLineWidth = false ) const override;
// @copydoc BOARD_ITEM::GetEffectiveShape

View File

@ -2139,7 +2139,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadCoppers()
{
fill = getPolySetFromCadstarShape( csCopper.Shape, -1 );
fill.ClearArcs();
fill.Inflate( copperWidth / 2, 32 );
fill.Inflate( copperWidth / 2, SHAPE_POLY_SET::ROUND_ALL_CORNERS, ARC_HIGH_DEF );
}
if( pouredZone->HasFilledPolysForLayer( getKiCadLayer( csCopper.LayerID ) ) )
@ -3033,10 +3033,7 @@ SHAPE_POLY_SET CADSTAR_PCB_ARCHIVE_LOADER::getPolySetFromCadstarShape( const SHA
polySet.ClearArcs();
if( aLineThickness > 0 )
{
polySet.Inflate( aLineThickness / 2, 32,
SHAPE_POLY_SET::CORNER_STRATEGY::ROUND_ALL_CORNERS );
}
polySet.Inflate( aLineThickness / 2, SHAPE_POLY_SET::ROUND_ALL_CORNERS, ARC_HIGH_DEF );
#ifdef DEBUG
for( int i = 0; i < polySet.OutlineCount(); ++i )
@ -3730,7 +3727,8 @@ bool CADSTAR_PCB_ARCHIVE_LOADER::calculateZonePriorities( PCB_LAYER_ID& aLayer )
[&]( ZONE* aLowerZone, ZONE* aHigherZone ) -> double
{
SHAPE_POLY_SET intersectShape( *aHigherZone->Outline() );
intersectShape.Inflate( inflateValue( aLowerZone, aHigherZone ) , 32 );
intersectShape.Inflate( inflateValue( aLowerZone, aHigherZone ),
SHAPE_POLY_SET::ROUND_ALL_CORNERS, ARC_HIGH_DEF );
SHAPE_POLY_SET lowerZoneFill( *aLowerZone->GetFilledPolysList( aLayer ) );
SHAPE_POLY_SET lowerZoneOutline( *aLowerZone->Outline() );
@ -3748,10 +3746,12 @@ bool CADSTAR_PCB_ARCHIVE_LOADER::calculateZonePriorities( PCB_LAYER_ID& aLayer )
[&]( ZONE* aZoneA, ZONE* aZoneB ) -> double
{
SHAPE_POLY_SET outLineA( *aZoneA->Outline() );
outLineA.Inflate( inflateValue( aZoneA, aZoneB ), 32 );
outLineA.Inflate( inflateValue( aZoneA, aZoneB ), SHAPE_POLY_SET::ROUND_ALL_CORNERS,
ARC_HIGH_DEF );
SHAPE_POLY_SET outLineB( *aZoneA->Outline() );
outLineB.Inflate( inflateValue( aZoneA, aZoneB ), 32 );
outLineB.Inflate( inflateValue( aZoneA, aZoneB ), SHAPE_POLY_SET::ROUND_ALL_CORNERS,
ARC_HIGH_DEF );
outLineA.BooleanIntersection( outLineB, SHAPE_POLY_SET::PM_FAST );

View File

@ -1492,7 +1492,8 @@ ZONE* EAGLE_PLUGIN::loadPolygon( wxXmlNode* aPolyNode )
// We trace the zone such that the copper is completely inside.
if( p.width.ToPcbUnits() > 0 )
{
polygon.Inflate( p.width.ToPcbUnits() / 2, 32, SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS );
polygon.Inflate( p.width.ToPcbUnits() / 2, SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS,
ARC_HIGH_DEF );
polygon.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
}
@ -2233,8 +2234,8 @@ void EAGLE_PLUGIN::packagePolygon( FOOTPRINT* aFootprint, wxXmlNode* aTree ) con
dwg->SetPolyPoints( pts );
dwg->Rotate( { 0, 0 }, aFootprint->GetOrientation() );
dwg->Move( aFootprint->GetPosition() );
dwg->GetPolyShape().Inflate( p.width.ToPcbUnits() / 2, 32,
SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS );
dwg->GetPolyShape().Inflate( p.width.ToPcbUnits() / 2,
SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS, ARC_HIGH_DEF );
}
}

View File

@ -1231,7 +1231,7 @@ bool ZONE::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly, PCB_LAYER_ID aLayer
if( aSmoothedPolyWithApron )
{
SHAPE_POLY_SET poly = maxExtents->CloneDropTriangulation();
poly.Inflate( m_ZoneMinThickness, 64 );
poly.Inflate( m_ZoneMinThickness, SHAPE_POLY_SET::ROUND_ALL_CORNERS, maxError );
*aSmoothedPolyWithApron = aSmoothedPoly;
aSmoothedPolyWithApron->BooleanIntersection( poly, SHAPE_POLY_SET::PM_FAST );
}
@ -1292,12 +1292,10 @@ void ZONE::TransformSmoothedOutlineToPolygon( SHAPE_POLY_SET& aBuffer, int aClea
if( board )
maxError = board->GetDesignSettings().m_MaxError;
int segCount = GetArcToSegmentCount( aClearance, maxError, FULL_CIRCLE );
if( aErrorLoc == ERROR_OUTSIDE )
aClearance += aMaxError;
aClearance += maxError;
polybuffer.Inflate( aClearance, segCount );
polybuffer.Inflate( aClearance, SHAPE_POLY_SET::ROUND_ALL_CORNERS, maxError );
}
polybuffer.Fracture( SHAPE_POLY_SET::PM_FAST );

View File

@ -1391,7 +1391,6 @@ bool ZONE_FILLER::fillCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer, PCB_LA
// deflating/inflating.
int half_min_width = aZone->GetMinThickness() / 2;
int epsilon = pcbIUScale.mmToIU( 0.001 );
int numSegs = GetArcToSegmentCount( half_min_width, m_maxError, FULL_CIRCLE );
// Solid polygons are deflated and inflated during calculations. Deflating doesn't cause
// issues, but inflate is tricky as it can create excessively long and narrow spikes for
@ -1456,10 +1455,10 @@ bool ZONE_FILLER::fillCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer, PCB_LA
// Prune features that don't meet minimum-width criteria
if( half_min_width - epsilon > epsilon )
{
testAreas.Deflate( half_min_width - epsilon, numSegs, fastCornerStrategy );
testAreas.Deflate( half_min_width - epsilon, fastCornerStrategy, m_maxError );
DUMP_POLYS_TO_COPPER_LAYER( testAreas, In5_Cu, wxT( "spoke-test-deflated" ) );
testAreas.Inflate( half_min_width - epsilon, numSegs, fastCornerStrategy );
testAreas.Inflate( half_min_width - epsilon, fastCornerStrategy, m_maxError );
DUMP_POLYS_TO_COPPER_LAYER( testAreas, In6_Cu, wxT( "spoke-test-reinflated" ) );
}
@ -1526,7 +1525,7 @@ bool ZONE_FILLER::fillCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer, PCB_LA
*/
if( half_min_width - epsilon > epsilon )
aFillPolys.Deflate( half_min_width - epsilon, numSegs, fastCornerStrategy );
aFillPolys.Deflate( half_min_width - epsilon, fastCornerStrategy, m_maxError );
// Min-thickness is the web thickness. On the other hand, a blob min-thickness by
// min-thickness is not useful. Since there's no obvious definition of web vs. blob, we
@ -1563,7 +1562,7 @@ bool ZONE_FILLER::fillCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer, PCB_LA
*/
if( half_min_width - epsilon > epsilon )
aFillPolys.Inflate( half_min_width - epsilon, numSegs, cornerStrategy, true );
aFillPolys.Inflate( half_min_width - epsilon, cornerStrategy, m_maxError, true );
DUMP_POLYS_TO_COPPER_LAYER( aFillPolys, In15_Cu, wxT( "after-reinflating" ) );
@ -1663,7 +1662,7 @@ bool ZONE_FILLER::fillNonCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer,
int epsilon = pcbIUScale.mmToIU( 0.001 );
int numSegs = GetArcToSegmentCount( half_min_width, m_maxError, FULL_CIRCLE );
aFillPolys.Deflate( half_min_width - epsilon, numSegs );
aFillPolys.Deflate( half_min_width - epsilon, SHAPE_POLY_SET::CHAMFER_ALL_CORNERS, m_maxError );
// Remove the non filled areas due to the hatch pattern
if( aZone->GetFillMode() == ZONE_FILL_MODE::HATCH_PATTERN )
@ -1674,7 +1673,7 @@ bool ZONE_FILLER::fillNonCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer,
// Re-inflate after pruning of areas that don't meet minimum-width criteria
if( half_min_width - epsilon > epsilon )
aFillPolys.Inflate( half_min_width - epsilon, numSegs );
aFillPolys.Inflate( half_min_width - epsilon, SHAPE_POLY_SET::ROUND_ALL_CORNERS, m_maxError );
aFillPolys.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
return true;