diff --git a/pcbnew/plugins/kicad/pcb_parser.cpp b/pcbnew/plugins/kicad/pcb_parser.cpp index 967f7a8a63..139c6f02e7 100644 --- a/pcbnew/plugins/kicad/pcb_parser.cpp +++ b/pcbnew/plugins/kicad/pcb_parser.cpp @@ -5110,6 +5110,7 @@ ZONE* PCB_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent ) // bigger scope since each filled_polygon is concatenated in here std::map pts; + std::map> legacySegs; PCB_LAYER_ID filledLayer; bool addedFilledPolygons = false; bool isStrokedFill = true; @@ -5263,41 +5264,15 @@ ZONE* PCB_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent ) if( token != T_segment && token != T_hatch && token != T_polygon ) Expecting( "segment, hatch or polygon" ); - if( token == T_segment ) // deprecated + switch( token ) { - if( m_showLegacySegmentZoneWarning ) - { - if( Pgm().IsGUI() && m_queryUserCallback ) - { - if( !m_queryUserCallback( - _( "Legacy Zone Warning" ), wxICON_WARNING, - _( "The segment zone fill mode is no longer supported.\n" - "Convert zones to smoothed polygon fills?" ), - _( "Convert" ) ) ) - { - THROW_IO_ERROR( wxT( "CANCEL" ) ); - } - } - else - { - THROW_IO_ERROR( wxT( "Legacy segment zone fill strategy was found; " - "open the board in the PCB Editor to resolve." ) ); - } + case T_hatch: + zone->SetFillMode( ZONE_FILL_MODE::HATCH_PATTERN ); break; - m_showLegacySegmentZoneWarning = false; - } - - zone->SetFlags( CANDIDATE ); - zone->SetFillMode( ZONE_FILL_MODE::POLYGONS ); - m_board->SetModified(); - } - else if( token == T_hatch ) - { - zone->SetFillMode( ZONE_FILL_MODE::HATCH_PATTERN ); - } - else - { - zone->SetFillMode( ZONE_FILL_MODE::POLYGONS ); + case T_segment: // deprecated, convert to polygons + case T_polygon: + default: + zone->SetFillMode( ZONE_FILL_MODE::POLYGONS ); break; } NeedRIGHT(); @@ -5568,6 +5543,8 @@ ZONE* PCB_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent ) case T_fill_segments: { + // Legacy segment fill + for( token = NextTok(); token != T_RIGHT; token = NextTok() ) { if( token != T_LEFT ) @@ -5575,27 +5552,19 @@ ZONE* PCB_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent ) token = NextTok(); - if( token == T_layer ) - { - filledLayer = parseBoardItemLayer(); - NeedRIGHT(); - token = NextTok(); - - if( token != T_LEFT ) - Expecting( T_LEFT ); - - token = NextTok(); - } - else - { - filledLayer = zone->GetLayer(); - } - if( token != T_pts ) Expecting( T_pts ); - ignore_unused( parseXY() ); - ignore_unused( parseXY() ); + // Legacy zones only had one layer + filledLayer = zone->GetFirstLayer(); + + SEG fillSegment; + + fillSegment.A = parseXY(); + fillSegment.B = parseXY(); + + legacySegs[filledLayer].push_back( fillSegment ); + NeedRIGHT(); } @@ -5672,7 +5641,7 @@ ZONE* PCB_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent ) { if( isStrokedFill && !zone->GetIsRuleArea() ) { - if( m_showLegacy5ZoneWarning && m_queryUserCallback ) + if( m_showLegacy5ZoneWarning ) { wxLogWarning( _( "Legacy zone fill strategy is not supported anymore.\nZone fills will " @@ -5683,21 +5652,58 @@ ZONE* PCB_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent ) if( zone->GetMinThickness() > 0 ) { - for( auto& pair : pts ) + for( auto& [layer, polyset] : pts ) { - pair.second.Inflate( zone->GetMinThickness() / 2, - SHAPE_POLY_SET::ROUND_ALL_CORNERS, ARC_HIGH_DEF / 2 ); - - pair.second.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); + polyset.InflateWithLinkedHoles( + zone->GetMinThickness() / 2, SHAPE_POLY_SET::ROUND_ALL_CORNERS, + ARC_HIGH_DEF / 2, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); } } } - - for( auto& pair : pts ) - zone->SetFilledPolysList( pair.first, pair.second ); + + for( auto& [layer, polyset] : pts ) + zone->SetFilledPolysList( layer, polyset ); zone->CalculateFilledArea(); } + else if( legacySegs.size() > 0 ) + { + // No polygons, just segment fill? + // Note RFB: This code might be removed if turns out this never existed for sexpr file format or otherwise we + // should add a test case to the qa folder + + if( m_showLegacySegmentZoneWarning ) + { + 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; + } + + + for( const auto& [layer, segments] : legacySegs ) + { + SHAPE_POLY_SET layerFill; + + if( zone->HasFilledPolysForLayer( layer ) ) + layerFill = SHAPE_POLY_SET( *zone->GetFill( layer ) ); + + for( const auto& seg : segments ) + { + SHAPE_POLY_SET segPolygon; + + TransformOvalToPolygon( segPolygon, seg.A, seg.B, zone->GetMinThickness(), + ARC_HIGH_DEF, ERROR_OUTSIDE ); + + 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)