Browse Source

Handle invalid pads more gracefully

Pads generated outside of KiCad may have self-intersecting polygons that
simplify to multiple sets.  We handle this by adding multiple primitives
for such polygons and limiting our fracture calls to only polygons that
have holes

Fixes https://gitlab.com/kicad/code/kicad/issues/10712
6.0.7
Seth Hillbrand 4 years ago
parent
commit
6d84acfacd
  1. 1
      pcbnew/dialogs/dialog_pad_basicshapes_properties.cpp
  2. 4
      pcbnew/dialogs/dialog_pad_properties.cpp
  3. 25
      pcbnew/pad_custom_shape_functions.cpp

1
pcbnew/dialogs/dialog_pad_basicshapes_properties.cpp

@ -246,7 +246,6 @@ DIALOG_PAD_PRIMITIVE_POLY_PROPS::DIALOG_PAD_PRIMITIVE_POLY_PROPS( wxWindow* aPar
TransferDataToWindow();
m_sdbSizerOK->SetDefault();
GetSizer()->SetSizeHints( this );
m_gridCornersList->Connect( wxEVT_GRID_CELL_CHANGING,
wxGridEventHandler( DIALOG_PAD_PRIMITIVE_POLY_PROPS::onCellChanging ),

4
pcbnew/dialogs/dialog_pad_properties.cpp

@ -732,7 +732,7 @@ void DIALOG_PAD_PROPERTIES::displayPrimitivesList()
case SHAPE_T::POLY:
bs_info[0] = "Polygon";
bs_info[1] = wxString::Format( _( "corners count %d" ),
(int) primitive->GetPolyShape().Outline( 0 ).PointCount() );
primitive->GetPolyShape().Outline( 0 ).PointCount() );
break;
default:
@ -1464,7 +1464,7 @@ void DIALOG_PAD_PROPERTIES::redraw()
while( select >= 0 )
{
PCB_SHAPE* dummyShape = (PCB_SHAPE*) m_primitives[select]->Clone();
PCB_SHAPE* dummyShape = static_cast<PCB_SHAPE*>( m_primitives[select]->Clone() );
dummyShape->SetLayer( SELECTED_ITEMS_LAYER );
dummyShape->Rotate( wxPoint( 0, 0), m_dummyPad->GetOrientation() );
dummyShape->Move( m_dummyPad->GetPosition() );

25
pcbnew/pad_custom_shape_functions.cpp

@ -42,15 +42,24 @@ void PAD::AddPrimitivePoly( const SHAPE_POLY_SET& aPoly, int aThickness, bool aF
// If aPoly has holes, convert it to a polygon with no holes.
SHAPE_POLY_SET poly_no_hole;
poly_no_hole.Append( aPoly );
poly_no_hole.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
PCB_SHAPE* item = new PCB_SHAPE();
item->SetShape( SHAPE_T::POLY );
item->SetFilled( aFilled );
item->SetPolyShape( poly_no_hole );
item->SetWidth( aThickness );
item->SetParent( this );
m_editPrimitives.emplace_back( item );
if( poly_no_hole.HasHoles() )
poly_no_hole.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
// There should never be multiple shapes, but if there are, we split them into
// primitives so that we can edit them both.
for( int ii = 0; ii < poly_no_hole.OutlineCount(); ++ii )
{
SHAPE_POLY_SET poly_outline( poly_no_hole.COutline( ii ) );
PCB_SHAPE* item = new PCB_SHAPE();
item->SetShape( SHAPE_T::POLY );
item->SetFilled( aFilled );
item->SetPolyShape( poly_outline );
item->SetWidth( aThickness );
item->SetParent( this );
m_editPrimitives.emplace_back( item );
}
SetDirty();
}

Loading…
Cancel
Save