From 65e53b8ecd21916bf2d16c4ebfabc1103a51b2c9 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Mon, 29 May 2023 15:28:48 +0100 Subject: [PATCH] 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 --- .../3d_canvas/create_3Dgraphic_brd_items.cpp | 2 +- libs/kimath/include/geometry/shape_poly_set.h | 12 ++++----- libs/kimath/src/geometry/shape_poly_set.cpp | 10 ++++--- pcbnew/drc/drc_test_provider_text_dims.cpp | 5 ++-- pcbnew/footprint.cpp | 14 +++++----- pcbnew/pad.cpp | 23 ++++++---------- pcbnew/pcb_text.cpp | 17 ++++++------ pcbnew/pcb_text.h | 6 ++--- pcbnew/pcb_textbox.cpp | 27 ++++++++++++------- pcbnew/pcb_textbox.h | 4 +-- .../cadstar/cadstar_pcb_archive_loader.cpp | 16 +++++------ pcbnew/plugins/eagle/eagle_plugin.cpp | 7 ++--- pcbnew/zone.cpp | 8 +++--- pcbnew/zone_filler.cpp | 13 +++++---- 14 files changed, 83 insertions(+), 81 deletions(-) diff --git a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp index 5bccd86e5e..baa569fed6 100644 --- a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp +++ b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp @@ -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 ); diff --git a/libs/kimath/include/geometry/shape_poly_set.h b/libs/kimath/include/geometry/shape_poly_set.h index 7fd418b95f..1073c9b3c6 100644 --- a/libs/kimath/include/geometry/shape_poly_set.h +++ b/libs/kimath/include/geometry/shape_poly_set.h @@ -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 ); } /** diff --git a/libs/kimath/src/geometry/shape_poly_set.cpp b/libs/kimath/src/geometry/shape_poly_set.cpp index 9c511cf0a3..512bbe458a 100644 --- a/libs/kimath/src/geometry/shape_poly_set.cpp +++ b/libs/kimath/src/geometry/shape_poly_set.cpp @@ -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 ); } diff --git a/pcbnew/drc/drc_test_provider_text_dims.cpp b/pcbnew/drc/drc_test_provider_text_dims.cpp index aaff183d5c..285d964d6e 100644 --- a/pcbnew/drc/drc_test_provider_text_dims.cpp +++ b/pcbnew/drc/drc_test_provider_text_dims.cpp @@ -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 ) diff --git a/pcbnew/footprint.cpp b/pcbnew/footprint.cpp index 793d4bf79b..7f8af9bf39 100644 --- a/pcbnew/footprint.cpp +++ b/pcbnew/footprint.cpp @@ -1952,13 +1952,13 @@ double FOOTPRINT::GetCoverageArea( const BOARD_ITEM* aItem, const GENERAL_COLLEC { const PCB_TEXT* text = static_cast( 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( 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 ); } diff --git a/pcbnew/pad.cpp b/pcbnew/pad.cpp index 6ffeea083d..4370bee2f0 100644 --- a/pcbnew/pad.cpp +++ b/pcbnew/pad.cpp @@ -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 ); } diff --git a/pcbnew/pcb_text.cpp b/pcbnew/pcb_text.cpp index 0e0ac165b7..08ff12172f 100644 --- a/pcbnew/pcb_text.cpp +++ b/pcbnew/pcb_text.cpp @@ -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 ); } diff --git a/pcbnew/pcb_text.h b/pcbnew/pcb_text.h index 886d2f1ab8..c4d319fc19 100644 --- a/pcbnew/pcb_text.h +++ b/pcbnew/pcb_text.h @@ -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 diff --git a/pcbnew/pcb_textbox.cpp b/pcbnew/pcb_textbox.cpp index 8c3f1f57e8..2885a82ea5 100644 --- a/pcbnew/pcb_textbox.cpp +++ b/pcbnew/pcb_textbox.cpp @@ -447,7 +447,7 @@ std::shared_ptr 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 ); } } } diff --git a/pcbnew/pcb_textbox.h b/pcbnew/pcb_textbox.h index 7ea761a009..907e6d7973 100644 --- a/pcbnew/pcb_textbox.h +++ b/pcbnew/pcb_textbox.h @@ -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 diff --git a/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.cpp b/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.cpp index 8909529ea3..d757213777 100644 --- a/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.cpp +++ b/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.cpp @@ -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 ); diff --git a/pcbnew/plugins/eagle/eagle_plugin.cpp b/pcbnew/plugins/eagle/eagle_plugin.cpp index 6e67f10ed6..d1af162d18 100644 --- a/pcbnew/plugins/eagle/eagle_plugin.cpp +++ b/pcbnew/plugins/eagle/eagle_plugin.cpp @@ -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 ); } } diff --git a/pcbnew/zone.cpp b/pcbnew/zone.cpp index 5a0af7e249..6d28d0d4a5 100644 --- a/pcbnew/zone.cpp +++ b/pcbnew/zone.cpp @@ -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 ); diff --git a/pcbnew/zone_filler.cpp b/pcbnew/zone_filler.cpp index 544fcaa687..9ed25c6c44 100644 --- a/pcbnew/zone_filler.cpp +++ b/pcbnew/zone_filler.cpp @@ -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;