Fix handling of self-intersecting polygons

We allow temporary self-intersection but before committing, we reduce
the polygon to a single outline (optionally with holes)

Fixes https://gitlab.com/kicad/code/kicad/issues/12806
This commit is contained in:
Seth Hillbrand 2022-11-01 13:08:16 -07:00
parent 07ef5d3343
commit ed309e20da
3 changed files with 43 additions and 3 deletions

View File

@ -381,7 +381,7 @@ bool DIALOG_PAD_PRIMITIVE_POLY_PROPS::doValidate( bool aRemoveRedundantCorners )
if( valid && polyline.SelfIntersecting() )
{
m_warningText->SetLabel( _( "Polygon can not be self-intersecting" ) );
m_warningText->SetLabel( _( "Self-intersecting polygons are not allowed" ) );
valid = false;
}

View File

@ -624,6 +624,29 @@ int PCB_POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
getViewControls()->SetAutoPan( false );
setAltConstraint( false );
if( item->IsType( { PCB_ZONE_T, PCB_FP_ZONE_T } ) )
{
SHAPE_POLY_SET* outline = static_cast<ZONE*>(item)->Outline();
outline->Simplify( SHAPE_POLY_SET::PM_FAST );
for( int ii = outline->OutlineCount(); ii > 1; --ii )
outline->DeletePolygon( ii - 1 );
updateItem();
}
else if( item->IsType( { PCB_SHAPE_LOCATE_POLY_T } ) )
{
SHAPE_POLY_SET& outline = static_cast<PCB_SHAPE*>( item )->GetPolyShape();
outline.Simplify( SHAPE_POLY_SET::PM_FAST );
for( int ii = outline.OutlineCount(); ii > 1; --ii )
outline.DeletePolygon( ii - 1 );
updateItem();
}
commit.Push( _( "Drag a corner" ) );
inDrag = false;
frame()->UndoRedoBlock( false );
@ -1669,7 +1692,7 @@ bool PCB_POINT_EDITOR::validatePolygon( SHAPE_POLY_SET& aPoly ) const
{
m_statusPopup.reset( new STATUS_TEXT_POPUP( getEditFrame<PCB_BASE_EDIT_FRAME>() ) );
m_statusPopup->SetTextColor( wxColour( 255, 0, 0 ) );
m_statusPopup->SetText( _( "Self-intersecting polygons are not allowed." ) );
m_statusPopup->SetText( _( "Self-intersecting polygons are not allowed" ) );
}
if( valid )
@ -2405,6 +2428,17 @@ int PCB_POINT_EDITOR::removeCorner( const TOOL_EVENT& aEvent )
setEditedPoint( nullptr );
// Do not allow self-intersecting polygons
polygon->Simplify( SHAPE_POLY_SET::PM_FAST );
if( polygon->OutlineCount() > 1 )
{
for( int ii = polygon->OutlineCount(); ii > 1; --ii )
polygon->DeletePolygon( ii );
updateItem();
}
commit.Push( _( "Remove a zone/polygon corner" ) );
// Refresh zone hatching

View File

@ -355,9 +355,15 @@ void ZONE_CREATE_HELPER::OnComplete( const POLYGON_GEOM_MANAGER& aMgr )
}
outline->Outline( 0 ).SetClosed( true );
outline->RemoveNullSegments();
outline->Simplify( SHAPE_POLY_SET::PM_FAST );
// Do not allow self-intersecting polygons
if( outline->OutlineCount() > 1 )
{
for( int ii = outline->OutlineCount(); ii > 1; --ii )
outline->DeletePolygon( ii );
}
// hand the zone over to the committer
commitZone( std::move( m_zone ) );
m_zone = nullptr;