Fix import of legacy stroked zone fill + add parsing of segments fills

This commit is contained in:
Roberto Fernandez Bautista 2023-07-30 20:55:55 +02:00
parent f00a68576e
commit 54f401c72c
1 changed files with 66 additions and 60 deletions

View File

@ -5110,6 +5110,7 @@ ZONE* PCB_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent )
// bigger scope since each filled_polygon is concatenated in here
std::map<PCB_LAYER_ID, SHAPE_POLY_SET> pts;
std::map<PCB_LAYER_ID, std::vector<SEG>> 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)