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
(cherry picked from commit 6d84acfacd
)
This commit is contained in:
parent
ff277a36af
commit
a2f845a41c
|
@ -250,8 +250,6 @@ DIALOG_PAD_PRIMITIVE_POLY_PROPS::DIALOG_PAD_PRIMITIVE_POLY_PROPS( wxWindow* aPar
|
||||||
|
|
||||||
SetupStandardButtons();
|
SetupStandardButtons();
|
||||||
|
|
||||||
GetSizer()->SetSizeHints( this );
|
|
||||||
|
|
||||||
m_gridCornersList->Connect( wxEVT_GRID_CELL_CHANGING,
|
m_gridCornersList->Connect( wxEVT_GRID_CELL_CHANGING,
|
||||||
wxGridEventHandler( DIALOG_PAD_PRIMITIVE_POLY_PROPS::onCellChanging ),
|
wxGridEventHandler( DIALOG_PAD_PRIMITIVE_POLY_PROPS::onCellChanging ),
|
||||||
nullptr, this );
|
nullptr, this );
|
||||||
|
|
|
@ -733,7 +733,7 @@ void DIALOG_PAD_PROPERTIES::displayPrimitivesList()
|
||||||
case SHAPE_T::POLY:
|
case SHAPE_T::POLY:
|
||||||
bs_info[0] = "Polygon";
|
bs_info[0] = "Polygon";
|
||||||
bs_info[1] = wxString::Format( _( "corners count %d" ),
|
bs_info[1] = wxString::Format( _( "corners count %d" ),
|
||||||
(int) primitive->GetPolyShape().Outline( 0 ).PointCount() );
|
primitive->GetPolyShape().Outline( 0 ).PointCount() );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1474,7 +1474,7 @@ void DIALOG_PAD_PROPERTIES::redraw()
|
||||||
|
|
||||||
while( select >= 0 )
|
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->SetLayer( SELECTED_ITEMS_LAYER );
|
||||||
dummyShape->Rotate( VECTOR2I( 0, 0), m_dummyPad->GetOrientation() );
|
dummyShape->Rotate( VECTOR2I( 0, 0), m_dummyPad->GetOrientation() );
|
||||||
dummyShape->Move( m_dummyPad->GetPosition() );
|
dummyShape->Move( m_dummyPad->GetPosition() );
|
||||||
|
|
|
@ -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.
|
// If aPoly has holes, convert it to a polygon with no holes.
|
||||||
SHAPE_POLY_SET poly_no_hole;
|
SHAPE_POLY_SET poly_no_hole;
|
||||||
poly_no_hole.Append( aPoly );
|
poly_no_hole.Append( aPoly );
|
||||||
poly_no_hole.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
|
||||||
|
|
||||||
PCB_SHAPE* item = new PCB_SHAPE();
|
if( poly_no_hole.HasHoles() )
|
||||||
item->SetShape( SHAPE_T::POLY );
|
poly_no_hole.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||||
item->SetFilled( aFilled );
|
|
||||||
item->SetPolyShape( poly_no_hole );
|
// There should never be multiple shapes, but if there are, we split them into
|
||||||
item->SetStroke( STROKE_PARAMS( aThickness, PLOT_DASH_TYPE::SOLID ) );
|
// primitives so that we can edit them both.
|
||||||
item->SetParent( this );
|
for( int ii = 0; ii < poly_no_hole.OutlineCount(); ++ii )
|
||||||
m_editPrimitives.emplace_back( item );
|
{
|
||||||
|
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->SetStroke( STROKE_PARAMS( aThickness, PLOT_DASH_TYPE::SOLID ) );
|
||||||
|
item->SetParent( this );
|
||||||
|
m_editPrimitives.emplace_back( item );
|
||||||
|
}
|
||||||
|
|
||||||
SetDirty();
|
SetDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue