ZONE_CREATE_HELPER: fixed crash when adding a cutout to a zone

Fixes: lp:1783541
* https://bugs.launchpad.net/kicad/+bug/1783541
This commit is contained in:
Tomasz Wlostowski 2018-07-26 15:29:37 +02:00
parent bbfc1eb12c
commit a9af4d0141
1 changed files with 26 additions and 21 deletions

View File

@ -112,27 +112,32 @@ std::unique_ptr<ZONE_CONTAINER> ZONE_CREATE_HELPER::createZoneFromExisting(
void ZONE_CREATE_HELPER::performZoneCutout( ZONE_CONTAINER& aZone, ZONE_CONTAINER& aCutout ) void ZONE_CREATE_HELPER::performZoneCutout( ZONE_CONTAINER& aZone, ZONE_CONTAINER& aCutout )
{ {
BOARD_COMMIT commit ( &m_tool );
BOARD* board = m_tool.getModel<BOARD>(); BOARD* board = m_tool.getModel<BOARD>();
int curr_hole = aZone.Outline()->NewHole( 0 ); std::vector<ZONE_CONTAINER*> newZones;
SHAPE_POLY_SET originalOutline ( *aZone.Outline() );
// Copy cutout corners into existing zone, in the new hole originalOutline.BooleanSubtract( *aCutout.Outline(), SHAPE_POLY_SET::PM_FAST );
for( int ii = 0; ii < aCutout.GetNumCorners(); ii++ )
for( int i = 0; i < originalOutline.OutlineCount(); i++ )
{ {
aZone.Outline()->Append( aCutout.GetCornerPosition( ii ), 0, curr_hole ); auto newZoneOutline = new SHAPE_POLY_SET;
newZoneOutline->AddOutline( originalOutline.Outline(i) );
auto newZone = new ZONE_CONTAINER( aZone );
newZone->SetOutline( newZoneOutline );
newZone->SetLocalFlags( 1 );
newZone->Hatch( );
newZones.push_back( newZone );
commit.Add( newZone );
} }
// Be sure the current corner list is closed commit.Remove( &aZone );
aZone.Outline()->Hole( 0, curr_hole ).SetClosed( true ); commit.Push( _("Add a zone cutout") );
// Combine holes and simplify the new outline: ZONE_FILLER filler( board );
board->OnAreaPolygonModified( nullptr, &aZone ); filler.Fill( newZones );
// Re-fill if needed
if( aZone.IsFilled() )
{
ZONE_FILLER filler( board );
filler.Fill( { &aZone } );
}
} }
@ -141,20 +146,18 @@ void ZONE_CREATE_HELPER::commitZone( std::unique_ptr<ZONE_CONTAINER> aZone )
auto& frame = *m_tool.getEditFrame<PCB_EDIT_FRAME>(); auto& frame = *m_tool.getEditFrame<PCB_EDIT_FRAME>();
auto board = m_tool.getModel<BOARD>(); auto board = m_tool.getModel<BOARD>();
BOARD_COMMIT bCommit( &m_tool );
switch ( m_params.m_mode ) switch ( m_params.m_mode )
{ {
case DRAWING_TOOL::ZONE_MODE::CUTOUT: case DRAWING_TOOL::ZONE_MODE::CUTOUT:
// For cutouts, subtract from the source // For cutouts, subtract from the source
bCommit.Modify( m_params.m_sourceZone );
performZoneCutout( *m_params.m_sourceZone, *aZone ); performZoneCutout( *m_params.m_sourceZone, *aZone );
bCommit.Push( _( "Add a zone cutout" ) );
m_params.m_sourceZone->Hatch();
break; break;
case DRAWING_TOOL::ZONE_MODE::ADD: case DRAWING_TOOL::ZONE_MODE::ADD:
case DRAWING_TOOL::ZONE_MODE::SIMILAR: case DRAWING_TOOL::ZONE_MODE::SIMILAR:
{
BOARD_COMMIT bCommit( &m_tool );
aZone->Hatch(); aZone->Hatch();
if( !m_params.m_keepout ) if( !m_params.m_keepout )
@ -166,9 +169,11 @@ void ZONE_CREATE_HELPER::commitZone( std::unique_ptr<ZONE_CONTAINER> aZone )
bCommit.Add( aZone.release() ); bCommit.Add( aZone.release() );
bCommit.Push( _( "Add a zone" ) ); bCommit.Push( _( "Add a zone" ) );
break; break;
}
case DRAWING_TOOL::ZONE_MODE::GRAPHIC_POLYGON: case DRAWING_TOOL::ZONE_MODE::GRAPHIC_POLYGON:
{ {
BOARD_COMMIT bCommit( &m_tool );
BOARD_ITEM_CONTAINER* parent = frame.GetModel(); BOARD_ITEM_CONTAINER* parent = frame.GetModel();
auto poly = m_tool.m_editModules ? new EDGE_MODULE( (MODULE *) parent ) : new DRAWSEGMENT(); auto poly = m_tool.m_editModules ? new EDGE_MODULE( (MODULE *) parent ) : new DRAWSEGMENT();
@ -203,7 +208,7 @@ bool ZONE_CREATE_HELPER::OnFirstPoint( POLYGON_GEOM_MANAGER& aMgr )
const auto& settings = *m_parentView.GetPainter()->GetSettings(); const auto& settings = *m_parentView.GetPainter()->GetSettings();
COLOR4D color = settings.GetColor( nullptr, m_zone->GetLayer() ); COLOR4D color = settings.GetColor( nullptr, m_zone->GetLayer() );
m_previewItem.SetStrokeColor( color ); m_previewItem.SetStrokeColor( COLOR4D::WHITE );
m_previewItem.SetFillColor( color.WithAlpha( 0.2 ) ); m_previewItem.SetFillColor( color.WithAlpha( 0.2 ) );
m_parentView.SetVisible( &m_previewItem, true ); m_parentView.SetVisible( &m_previewItem, true );