From e0cf49e73c144f9abd232cbebe81c533445aa2d0 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Fri, 25 Aug 2023 13:04:46 +0100 Subject: [PATCH] Fix previous fix for honouring pad offset. Fixes https://gitlab.com/kicad/code/kicad/-/issues/15494 --- pcbnew/tools/pad_tool.cpp | 84 +++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 44 deletions(-) diff --git a/pcbnew/tools/pad_tool.cpp b/pcbnew/tools/pad_tool.cpp index e3333b03e5..62f9fff652 100644 --- a/pcbnew/tools/pad_tool.cpp +++ b/pcbnew/tools/pad_tool.cpp @@ -752,8 +752,12 @@ PCB_LAYER_ID PAD_TOOL::explodePad( PAD* aPad ) UNIMPLEMENTED_FOR( shape->SHAPE_T_asString() ); } - shape->Move( aPad->GetPosition() ); - shape->Rotate( aPad->GetPosition(), aPad->GetOrientation() ); + if( shape->GetShape() != SHAPE_T::POLY ) // Poly's are board-relative + { + shape->Move( aPad->GetPosition() ); + shape->Rotate( aPad->GetPosition(), aPad->GetOrientation() ); + } + shape->SetLayer( layer ); commit.Add( shape ); @@ -845,49 +849,38 @@ std::vector PAD_TOOL::RecombinePad( PAD* aPad, bool aIsDryRun, BOARD else layer = *aPad->GetLayerSet().UIOrder(); + // If there are intersecting items to combine, we need to first make sure the pad is a + // custom-shape pad. + if( !aIsDryRun && findNext( layer ) && aPad->GetShape() != PAD_SHAPE::CUSTOM ) + { + aCommit.Modify( aPad ); + + // Create a new minimally-sized circular anchor and convert existing pad + // to a polygon primitive + SHAPE_POLY_SET existingOutline; + aPad->TransformShapeToPolygon( existingOutline, layer, 0, maxError, ERROR_INSIDE ); + + aPad->SetAnchorPadShape( PAD_SHAPE::CIRCLE ); + // We're going to remove the offset, so shrink the anchor pad so that it's + // entirely inside the hole (since it won't be offset anymore) + aPad->SetSize( aPad->GetDrillSize() ); + + PCB_SHAPE* shape = new PCB_SHAPE( nullptr, SHAPE_T::POLY ); + shape->SetFilled( true ); + shape->SetStroke( STROKE_PARAMS( 0, PLOT_DASH_TYPE::SOLID ) ); + shape->SetPolyShape( existingOutline ); + shape->Move( - aPad->GetPosition() ); + shape->Rotate( VECTOR2I( 0, 0 ), - aPad->GetOrientation() ); + + aPad->AddPrimitive( shape ); + aPad->SetShape( PAD_SHAPE::CUSTOM ); + aPad->SetOffset( VECTOR2I( 0, 0 ) ); + } + while( PCB_SHAPE* fpShape = findNext( layer ) ) { - // We've found an intersecting item to combine. - // fpShape->SetFlags( SKIP_STRUCT ); - // First convert the pad to a custom-shape pad (if it isn't already) - // - if( !aIsDryRun ) - { - aCommit.Modify( aPad ); - - if( aPad->GetShape() == PAD_SHAPE::RECTANGLE || aPad->GetShape() == PAD_SHAPE::CIRCLE ) - { - aPad->SetAnchorPadShape( aPad->GetShape() ); - } - else if( aPad->GetShape() != PAD_SHAPE::CUSTOM ) - { - // Create a new minimally-sized circular anchor and convert existing pad - // to a polygon primitive - SHAPE_POLY_SET existingOutline; - aPad->TransformShapeToPolygon( existingOutline, layer, 0, maxError, ERROR_INSIDE ); - - aPad->SetAnchorPadShape( PAD_SHAPE::CIRCLE ); - - if( aPad->GetSizeX() > aPad->GetSizeY() ) - aPad->SetSizeX( aPad->GetSizeY() ); - - PCB_SHAPE* shape = new PCB_SHAPE( nullptr, SHAPE_T::POLY ); - shape->SetFilled( true ); - shape->SetStroke( STROKE_PARAMS( 0, PLOT_DASH_TYPE::SOLID ) ); - shape->SetPolyShape( existingOutline ); - shape->Move( - aPad->GetPosition() ); - shape->Rotate( VECTOR2I( 0, 0 ), - aPad->GetOrientation() ); - - aPad->AddPrimitive( shape ); - } - - aPad->SetShape( PAD_SHAPE::CUSTOM ); - } - - // Now add the new shape to the primitives list - // mergedShapes.push_back( fpShape ); if( !aIsDryRun ) @@ -922,15 +915,18 @@ std::vector PAD_TOOL::RecombinePad( PAD* aPad, bool aIsDryRun, BOARD case SHAPE_T::POLY: primitive->SetPolyShape( fpShape->GetPolyShape() ); - primitive->Move( VECTOR2I( 0, 0 ) - aPad->GetOffset() ); break; default: UNIMPLEMENTED_FOR( primitive->SHAPE_T_asString() ); } - primitive->Move( - aPad->GetPosition() ); - primitive->Rotate( VECTOR2I( 0, 0 ), - aPad->GetOrientation() ); + if( primitive->GetShape() != SHAPE_T::POLY ) // Poly's are board-relative + { + primitive->Move( - aPad->GetPosition() ); + primitive->Rotate( VECTOR2I( 0, 0 ), - aPad->GetOrientation() ); + } + primitive->SetIsAnnotationProxy( fpShape->IsAnnotationProxy()); aPad->AddPrimitive( primitive );