From 5cd88dbd203a442f0640207e4655b33439349071 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sun, 3 Sep 2023 20:43:20 +0100 Subject: [PATCH] Bug fixes for paste margins on custom-shaped pads. Fixes https://gitlab.com/kicad/code/kicad/-/issues/15125 (cherry picked from commit 60419f542a7e9719a0d6164fac1fdf165b9ae319) --- pcbnew/dialogs/dialog_pad_properties.cpp | 2 +- pcbnew/pad.cpp | 26 +++++++++++++++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/pcbnew/dialogs/dialog_pad_properties.cpp b/pcbnew/dialogs/dialog_pad_properties.cpp index e231bbdad2..3b8ad6e2e8 100644 --- a/pcbnew/dialogs/dialog_pad_properties.cpp +++ b/pcbnew/dialogs/dialog_pad_properties.cpp @@ -1250,7 +1250,7 @@ bool DIALOG_PAD_PROPERTIES::padValuesOK() if( m_dummyPad->GetShape() == PAD_SHAPE::CUSTOM ) { - // allow 0-sized anchor pads + pad_size = m_dummyPad->GetBoundingBox().GetSize(); } else if( m_dummyPad->GetShape() == PAD_SHAPE::CIRCLE ) { diff --git a/pcbnew/pad.cpp b/pcbnew/pad.cpp index 6f62fcc8a0..1e8dc15bcb 100644 --- a/pcbnew/pad.cpp +++ b/pcbnew/pad.cpp @@ -942,11 +942,14 @@ VECTOR2I PAD::GetSolderPasteMargin() const pad_margin.y = margin + KiROUND( m_size.y * mratio ); // ensure mask have a size always >= 0 - if( pad_margin.x < -m_size.x / 2 ) - pad_margin.x = -m_size.x / 2; + if( m_padShape != PAD_SHAPE::CUSTOM ) + { + if( pad_margin.x < -m_size.x / 2 ) + pad_margin.x = -m_size.x / 2; - if( pad_margin.y < -m_size.y / 2 ) - pad_margin.y = -m_size.y / 2; + if( pad_margin.y < -m_size.y / 2 ) + pad_margin.y = -m_size.y / 2; + } return pad_margin; } @@ -1683,7 +1686,7 @@ void PAD::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, outline.Rotate( m_orient ); outline.Move( VECTOR2I( padShapePos ) ); - if( aClearance ) + if( aClearance > 0 ) { int numSegs = std::max( GetArcToSegmentCount( aClearance, aError, FULL_CIRCLE ), pad_min_seg_per_circle_count ); @@ -1699,6 +1702,19 @@ void PAD::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, outline.Simplify( SHAPE_POLY_SET::PM_FAST ); outline.Fracture( SHAPE_POLY_SET::PM_FAST ); } + else if( aClearance < 0 ) + { + // Negative clearances are primarily for drawing solder paste layer, so we don't + // worry ourselves overly about which side the error is on. + + int numSegs = std::max( GetArcToSegmentCount( aClearance, aError, FULL_CIRCLE ), + pad_min_seg_per_circle_count ); + + // aClearance is negative so this is actually a deflate + outline.Inflate( aClearance, numSegs ); + outline.Simplify( SHAPE_POLY_SET::PM_FAST ); + outline.Fracture( SHAPE_POLY_SET::PM_FAST ); + } aBuffer.Append( outline ); break;