Stop trying to zero-out offset of custom-shaped pads.

It causes *way* to many issues.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/15555

(cherry picked from commit 68c839b214)
This commit is contained in:
Jeff Young 2023-09-01 13:21:10 +01:00
parent c8e49599ce
commit 889689e31a
3 changed files with 28 additions and 47 deletions

View File

@ -890,9 +890,7 @@ void DIALOG_PAD_PROPERTIES::OnPadShapeSelection( wxCommandEvent& event )
m_sizeY.Enable( m_PadShapeSelector->GetSelection() != CHOICE_SHAPE_CIRCLE m_sizeY.Enable( m_PadShapeSelector->GetSelection() != CHOICE_SHAPE_CIRCLE
&& m_PadShapeSelector->GetSelection() != CHOICE_SHAPE_CUSTOM_CIRC_ANCHOR ); && m_PadShapeSelector->GetSelection() != CHOICE_SHAPE_CUSTOM_CIRC_ANCHOR );
m_offsetShapeOpt->Enable( m_PadShapeSelector->GetSelection() != CHOICE_SHAPE_CIRCLE m_offsetShapeOpt->Enable( m_PadShapeSelector->GetSelection() != CHOICE_SHAPE_CIRCLE );
&& m_PadShapeSelector->GetSelection() != CHOICE_SHAPE_CUSTOM_CIRC_ANCHOR
&& m_PadShapeSelector->GetSelection() != CHOICE_SHAPE_CUSTOM_RECT_ANCHOR );
if( !m_offsetShapeOpt->IsEnabled() ) if( !m_offsetShapeOpt->IsEnabled() )
m_offsetShapeOpt->SetValue( false ); m_offsetShapeOpt->SetValue( false );

View File

@ -1681,7 +1681,7 @@ void PAD::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
SHAPE_POLY_SET outline; SHAPE_POLY_SET outline;
MergePrimitivesAsPolygon( &outline, aErrorLoc ); MergePrimitivesAsPolygon( &outline, aErrorLoc );
outline.Rotate( m_orient ); outline.Rotate( m_orient );
outline.Move( VECTOR2I( m_pos ) ); outline.Move( VECTOR2I( padShapePos ) );
if( aClearance ) if( aClearance )
{ {

View File

@ -720,11 +720,8 @@ PCB_LAYER_ID PAD_TOOL::explodePad( PAD* aPad )
shape->SetLocalCoord(); shape->SetLocalCoord();
if( shape->GetShape() != SHAPE_T::POLY ) // Poly's are board-relative shape->Rotate( VECTOR2I( 0, 0 ), aPad->GetOrientation() );
{ shape->Move( aPad->ShapePos() );
shape->Move( aPad->GetPosition() );
shape->Rotate( aPad->GetPosition(), aPad->GetOrientation() );
}
shape->SetLayer( layer ); shape->SetLayer( layer );
@ -748,8 +745,7 @@ std::vector<FP_SHAPE*> PAD_TOOL::RecombinePad( PAD* aPad, bool aIsDryRun, BOARD_
int maxError = board()->GetDesignSettings().m_MaxError; int maxError = board()->GetDesignSettings().m_MaxError;
FOOTPRINT* footprint = static_cast<FOOTPRINT*>( aPad->GetParentFootprint() ); FOOTPRINT* footprint = static_cast<FOOTPRINT*>( aPad->GetParentFootprint() );
// Don't leave an object in the point editor that might no longer exist after // Don't leave an object in the point editor that might no longer exist after recombining.
// recombining the pad.
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
for( BOARD_ITEM* item : footprint->GraphicalItems() ) for( BOARD_ITEM* item : footprint->GraphicalItems() )
@ -823,41 +819,31 @@ std::vector<FP_SHAPE*> PAD_TOOL::RecombinePad( PAD* aPad, bool aIsDryRun, BOARD_
{ {
aCommit.Modify( aPad ); aCommit.Modify( aPad );
// Create a new minimally-sized circular anchor and convert existing pad if( aPad->GetShape() == PAD_SHAPE::CIRCLE || aPad->GetShape() == PAD_SHAPE::RECTANGLE )
// to a polygon primitive
SHAPE_POLY_SET existingOutline;
aPad->TransformShapeToPolygon( existingOutline, layer, 0, maxError, ERROR_INSIDE );
aPad->SetAnchorPadShape( PAD_SHAPE::CIRCLE );
// The actual pad shape may be offset from the pad anchor, so we don't want the anchor
// shape to be overly large (and stick out from under the actual pad shape). Normally
// this means we want the anchor pad to be entirely inside the hole, but offsets are
// also used with SMD pads to control the anchor point for track routing.
if( aPad->GetDrillSizeX() > 0 )
{ {
// For a pad with a hole, just make sure the anchor shape is entirely inside the // Use the existing pad as an anchor
// hole. aPad->SetAnchorPadShape( aPad->GetShape() );
aPad->SetSize( aPad->GetDrillSize() / 2 ); aPad->SetShape( PAD_SHAPE::CUSTOM );
} }
else else
{ {
// For a SMD pad, an offset is usually used to control the anchor point for routing. // Create a new circular anchor and convert existing pad to a polygon primitive
// In this case it will usually be at least 1/2 the minimum track width inside the SHAPE_POLY_SET existingOutline;
// pad. We halve that value again just to be safe. aPad->TransformShapeToPolygon( existingOutline, layer, 0, maxError, ERROR_INSIDE );
aPad->SetSize( VECTOR2I( board()->GetDesignSettings().m_TrackMinWidth / 2,
board()->GetDesignSettings().m_TrackMinWidth / 2 ) ); int minExtent = std::min( aPad->GetSize().x, aPad->GetSize().y );
} aPad->SetAnchorPadShape( PAD_SHAPE::CIRCLE );
aPad->SetSize( VECTOR2I( minExtent, minExtent ) );
aPad->SetShape( PAD_SHAPE::CUSTOM );
PCB_SHAPE* shape = new PCB_SHAPE( nullptr, SHAPE_T::POLY ); PCB_SHAPE* shape = new PCB_SHAPE( nullptr, SHAPE_T::POLY );
shape->SetFilled( true ); shape->SetFilled( true );
shape->SetStroke( STROKE_PARAMS( 0, PLOT_DASH_TYPE::SOLID ) ); shape->SetStroke( STROKE_PARAMS( 0, PLOT_DASH_TYPE::SOLID ) );
shape->SetPolyShape( existingOutline ); shape->SetPolyShape( existingOutline );
shape->Move( - aPad->GetPosition() );
shape->Rotate( VECTOR2I( 0, 0 ), - aPad->GetOrientation() ); shape->Rotate( VECTOR2I( 0, 0 ), - aPad->GetOrientation() );
shape->Move( - aPad->ShapePos() );
aPad->AddPrimitive( shape ); aPad->AddPrimitive( shape );
aPad->SetShape( PAD_SHAPE::CUSTOM ); }
aPad->SetOffset( VECTOR2I( 0, 0 ) );
} }
while( FP_SHAPE* fpShape = findNext( layer ) ) while( FP_SHAPE* fpShape = findNext( layer ) )
@ -904,11 +890,8 @@ std::vector<FP_SHAPE*> PAD_TOOL::RecombinePad( PAD* aPad, bool aIsDryRun, BOARD_
UNIMPLEMENTED_FOR( pcbShape->SHAPE_T_asString() ); UNIMPLEMENTED_FOR( pcbShape->SHAPE_T_asString() );
} }
if( pcbShape->GetShape() != SHAPE_T::POLY ) // Poly's are board-relative pcbShape->Move( - aPad->ShapePos() );
{
pcbShape->Move( - aPad->GetPosition() );
pcbShape->Rotate( VECTOR2I( 0, 0 ), - aPad->GetOrientation() ); pcbShape->Rotate( VECTOR2I( 0, 0 ), - aPad->GetOrientation() );
}
pcbShape->SetIsAnnotationProxy( fpShape->IsAnnotationProxy() ); pcbShape->SetIsAnnotationProxy( fpShape->IsAnnotationProxy() );
aPad->AddPrimitive( pcbShape ); aPad->AddPrimitive( pcbShape );