Fix segfault when removing the last corner of a cutout
Fixes: lp:1736147 * https://bugs.launchpad.net/kicad/+bug/1736147
This commit is contained in:
parent
1e88695001
commit
f44d4d01ea
|
@ -784,19 +784,46 @@ bool POINT_EDITOR::addCornerCondition( const SELECTION& aSelection )
|
|||
}
|
||||
|
||||
|
||||
// Finds a corresponding vertex in a polygon set
|
||||
static std::pair<bool, SHAPE_POLY_SET::VERTEX_INDEX>
|
||||
findVertex( SHAPE_POLY_SET& aPolySet, const EDIT_POINT& aPoint )
|
||||
{
|
||||
for( auto it = aPolySet.IterateWithHoles(); it; ++it )
|
||||
{
|
||||
auto vertexIdx = it.GetIndex();
|
||||
|
||||
if( aPolySet.Vertex( vertexIdx ) == aPoint.GetPosition() )
|
||||
return std::make_pair( true, vertexIdx );
|
||||
}
|
||||
|
||||
return std::make_pair( false, SHAPE_POLY_SET::VERTEX_INDEX() );
|
||||
}
|
||||
|
||||
|
||||
bool POINT_EDITOR::removeCornerCondition( const SELECTION& )
|
||||
{
|
||||
if( !m_editPoints )
|
||||
if( !m_editPoints || !m_editedPoint )
|
||||
return false;
|
||||
|
||||
EDA_ITEM* item = m_editPoints->GetParent();
|
||||
|
||||
if( item->Type() != PCB_ZONE_AREA_T )
|
||||
if( !item || item->Type() != PCB_ZONE_AREA_T )
|
||||
return false;
|
||||
|
||||
ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*>( item );
|
||||
auto& polyset = *zone->Outline();
|
||||
auto vertex = findVertex( polyset, *m_editedPoint );
|
||||
|
||||
if( zone->GetNumCorners() <= 3 )
|
||||
if( !vertex.first )
|
||||
return false;
|
||||
|
||||
const auto& vertexIdx = vertex.second;
|
||||
|
||||
// Check if there are enough vertices so one can be removed without
|
||||
// degenerating the polygon.
|
||||
// The first condition allows to remove all corners from holes (when there
|
||||
// are only 2 vertices left, a hole is removed).
|
||||
if( vertexIdx.m_contour == 0 && polyset.Polygon( vertexIdx.m_polygon )[vertexIdx.m_contour].PointCount() <= 3 )
|
||||
return false;
|
||||
|
||||
// Remove corner does not work with lines
|
||||
|
@ -931,43 +958,59 @@ int POINT_EDITOR::removeCorner( const TOOL_EVENT& aEvent )
|
|||
if( !item )
|
||||
return 0;
|
||||
|
||||
SHAPE_POLY_SET *outline = nullptr;
|
||||
SHAPE_POLY_SET* polygon = nullptr;
|
||||
|
||||
if( item->Type() == PCB_ZONE_AREA_T)
|
||||
{
|
||||
auto zone = static_cast<ZONE_CONTAINER*>( item );
|
||||
outline = zone->Outline();
|
||||
polygon = zone->Outline();
|
||||
}
|
||||
else if( item->Type() == PCB_LINE_T )
|
||||
{
|
||||
auto ds = static_cast<DRAWSEGMENT*>( item );
|
||||
|
||||
if( ds->GetShape() == S_POLYGON )
|
||||
{
|
||||
outline = &ds->GetPolyShape();
|
||||
}
|
||||
polygon = &ds->GetPolyShape();
|
||||
}
|
||||
|
||||
if( !outline )
|
||||
if( !polygon )
|
||||
return 0;
|
||||
|
||||
PCB_BASE_FRAME* frame = getEditFrame<PCB_BASE_FRAME>();
|
||||
BOARD_COMMIT commit( frame );
|
||||
auto vertex = findVertex( *polygon, *m_editedPoint );
|
||||
|
||||
if( vertex.first )
|
||||
{
|
||||
const auto& vertexIdx = vertex.second;
|
||||
auto& outline = polygon->Polygon( vertexIdx.m_polygon )[vertexIdx.m_contour];
|
||||
|
||||
if( outline.PointCount() > 3 )
|
||||
{
|
||||
// the usual case: remove just the corner when there are >3 vertices
|
||||
commit.Modify( item );
|
||||
polygon->RemoveVertex( vertexIdx );
|
||||
}
|
||||
else
|
||||
{
|
||||
// either remove a hole or the polygon when there are <= 3 corners
|
||||
if( vertexIdx.m_contour > 0 )
|
||||
{
|
||||
// remove hole
|
||||
commit.Modify( item );
|
||||
polygon->RemoveContour( vertexIdx.m_contour );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
commit.Remove( item );
|
||||
}
|
||||
}
|
||||
|
||||
for( int i = 0; i < outline->TotalVertices(); ++i )
|
||||
{
|
||||
if( outline->Vertex( i ) == m_editedPoint->GetPosition() )
|
||||
{
|
||||
outline->RemoveVertex( i );
|
||||
setEditedPoint( NULL );
|
||||
setEditedPoint( nullptr );
|
||||
commit.Push( _( "Remove a zone/polygon corner" ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
updatePoints();
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue