From 30a63b7b32b231983c5685c03edd0ddea6e1dcd3 Mon Sep 17 00:00:00 2001 From: Roberto Fernandez Bautista Date: Wed, 2 Aug 2023 19:28:26 +0200 Subject: [PATCH] Fix loading of legacy zone fills in .brd files + Don't refill after board import --- pcbnew/files.cpp | 25 ---------------- pcbnew/plugins/kicad/pcb_parser.cpp | 12 ++++---- pcbnew/plugins/legacy/legacy_plugin.cpp | 40 ++++++++++++++----------- 3 files changed, 28 insertions(+), 49 deletions(-) diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index d4039fbbf6..bc8044825c 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -982,31 +982,6 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in GetBoard()->Show( 0, std::cout ); #endif - // Re-fill any zones which had their legacy fills deleted on open - - for( ZONE* zone : GetBoard()->Zones() ) - { - if( zone->GetFlags() & CANDIDATE ) - { - toFill.push_back( zone ); - zone->ClearTempFlags(); - } - } - - if( toFill.size() ) - { - BOARD_COMMIT commit( this ); - ZONE_FILLER filler( GetBoard(), &commit ); - - progressReporter.Report( _( "Converting zone fills" ) ); - filler.SetProgressReporter( &progressReporter ); - - if( filler.Fill( toFill ) ) - commit.Push( _( "Convert Zone(s)" ), SKIP_CONNECTIVITY ); - - rebuildConnectivity(); - } - // from EDA_APPL which was first loaded BOARD only: { /* For an obscure reason the focus is lost after loading a board file diff --git a/pcbnew/plugins/kicad/pcb_parser.cpp b/pcbnew/plugins/kicad/pcb_parser.cpp index 139c6f02e7..f75ee4f6e7 100644 --- a/pcbnew/plugins/kicad/pcb_parser.cpp +++ b/pcbnew/plugins/kicad/pcb_parser.cpp @@ -5271,7 +5271,7 @@ ZONE* PCB_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent ) case T_segment: // deprecated, convert to polygons case T_polygon: - default: + default: zone->SetFillMode( ZONE_FILL_MODE::POLYGONS ); break; } @@ -5557,11 +5557,11 @@ ZONE* PCB_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent ) // Legacy zones only had one layer filledLayer = zone->GetFirstLayer(); - + SEG fillSegment; fillSegment.A = parseXY(); - fillSegment.B = parseXY(); + fillSegment.B = parseXY(); legacySegs[filledLayer].push_back( fillSegment ); @@ -5660,7 +5660,7 @@ ZONE* PCB_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent ) } } } - + for( auto& [layer, polyset] : pts ) zone->SetFilledPolysList( layer, polyset ); @@ -5698,12 +5698,12 @@ ZONE* PCB_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent ) layerFill.BooleanAdd( segPolygon, SHAPE_POLY_SET::PM_FAST ); } - + zone->SetFilledPolysList( layer, layerFill ); zone->CalculateFilledArea(); } } - + // Ensure keepout and non copper zones do not have a net // (which have no sense for these zones) diff --git a/pcbnew/plugins/legacy/legacy_plugin.cpp b/pcbnew/plugins/legacy/legacy_plugin.cpp index ec150ec84c..d886a32ce6 100644 --- a/pcbnew/plugins/legacy/legacy_plugin.cpp +++ b/pcbnew/plugins/legacy/legacy_plugin.cpp @@ -2319,6 +2319,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() ZONE_BORDER_DISPLAY_STYLE outline_hatch = ZONE_BORDER_DISPLAY_STYLE::NO_HATCH; bool endContour = false; + bool segmentFill = false; int holeIndex = -1; // -1 is the main outline; holeIndex >= 0 = hole index char buf[1024]; char* line; @@ -2454,33 +2455,22 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() if( fillmode) { - // SEGMENT fill mode no longer supported. Make sure user is OK with converting - // them. + segmentFill = true; + if( m_showLegacySegmentZoneWarning ) { - KIDIALOG dlg( nullptr, - _( "The legacy segment fill mode is no longer supported.\n" - "Convert zones to smoothed polygon fills?" ), - _( "Legacy Zone Warning" ), - wxYES_NO | wxICON_WARNING ); - - dlg.DoNotShowCheckbox( __FILE__, __LINE__ ); - - if( dlg.ShowModal() == wxID_NO ) - THROW_IO_ERROR( wxT( "CANCEL" ) ); + wxLogWarning( _( "The legacy segment zone fill mode is no longer supported.\n" + "Zone fills will be converted on a best-effort basis." ) ); m_showLegacySegmentZoneWarning = false; } - - // User OK'd; switch to polygon mode - zc->SetFillMode( ZONE_FILL_MODE::POLYGONS ); - m_board->SetModified(); } else { - zc->SetFillMode( ZONE_FILL_MODE::POLYGONS ); + segmentFill = false; } + zc->SetFillMode( ZONE_FILL_MODE::POLYGONS ); zc->SetIsFilled( fillstate == 'S' ); zc->SetThermalReliefGap( thermalReliefGap ); zc->SetThermalReliefSpokeWidth( thermalReliefCopperBridge ); @@ -2545,7 +2535,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() makeNewOutline = end_contour; } - zc->SetFilledPolysList( zc->GetLayer(), polysList ); + zc->SetFilledPolysList( zc->GetFirstLayer(), polysList ); } else if( TESTLINE( "$FILLSEGMENTS" ) ) { @@ -2568,6 +2558,20 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() if( zc->GetIsRuleArea() ) zc->SetNetCode( NETINFO_LIST::UNCONNECTED ); + if( zc->GetMinThickness() > 0 ) + { + // Inflate the fill polygon + PCB_LAYER_ID layer = zc->GetFirstLayer(); + SHAPE_POLY_SET inflatedFill = SHAPE_POLY_SET( *zc->GetFilledPolysList( layer ) ); + + inflatedFill.InflateWithLinkedHoles( zc->GetMinThickness() / 2, + SHAPE_POLY_SET::ROUND_ALL_CORNERS, + ARC_HIGH_DEF / 2, + SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); + + zc->SetFilledPolysList( layer, inflatedFill ); + } + // should always occur, but who knows, a zone without two corners // is no zone at all, it's a spot?