From 411c9707ee5ced8a571f7dcd4391da6643a33694 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Tue, 7 Mar 2023 15:45:28 +0100 Subject: [PATCH] specctra export: fix handling of multi-layer zones. (from master branch) --- .../specctra_export.cpp | 166 ++++++++++-------- 1 file changed, 89 insertions(+), 77 deletions(-) diff --git a/pcbnew/specctra_import_export/specctra_export.cpp b/pcbnew/specctra_import_export/specctra_export.cpp index 72cdf6f0dd..211fc10e63 100644 --- a/pcbnew/specctra_import_export/specctra_export.cpp +++ b/pcbnew/specctra_import_export/specctra_export.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2007-2015 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 2015-2022 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2023 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -1226,104 +1226,116 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) continue; // Currently, we export only copper layers - if( ! IsCopperLayer( zone->GetLayer() ) ) + if( ! zone->IsOnCopperLayer() ) continue; - COPPER_PLANE* plane = new COPPER_PLANE( m_pcb->structure ); + // Now, build zone polygon on each copper layer where the zone + // is living (zones can live on many copper layers) + const int copperCount = aBoard->GetCopperLayerCount(); - m_pcb->structure->planes.push_back( plane ); - - PATH* mainPolygon = new PATH( plane, T_polygon ); - - plane->SetShape( mainPolygon ); - plane->name = TO_UTF8( zone->GetNetname() ); - - if( plane->name.size() == 0 ) + for( int layer = 0; layer < copperCount; layer++ ) { - char name[32]; + if( layer == copperCount-1 ) + layer = B_Cu; - // This is one of those no connection zones, netcode=0, and it has no name. - // Create a unique, bogus netname. - NET* no_net = new NET( m_pcb->network ); + if( !zone->IsOnLayer( PCB_LAYER_ID( layer ) ) ) + continue; + COPPER_PLANE* plane = new COPPER_PLANE( m_pcb->structure ); - sprintf( name, "@:no_net_%d", netlessZones++ ); - no_net->net_id = name; + m_pcb->structure->planes.push_back( plane ); - // add the bogus net name to network->nets. - m_pcb->network->nets.push_back( no_net ); + PATH* mainPolygon = new PATH( plane, T_polygon ); - // use the bogus net name in the netless zone. - plane->name = no_net->net_id; - } + plane->SetShape( mainPolygon ); + plane->name = TO_UTF8( zone->GetNetname() ); - mainPolygon->layer_id = m_layerIds[ m_kicadLayer2pcb[ zone->GetLayer() ] ]; - - // Handle the main outlines - SHAPE_POLY_SET::ITERATOR iterator; - wxPoint startpoint; - bool is_first_point = true; - - for( iterator = zone->IterateWithHoles(); iterator; iterator++ ) - { - wxPoint point( iterator->x, iterator->y ); - - if( is_first_point ) + if( plane->name.size() == 0 ) { - startpoint = point; - is_first_point = false; + char name[32]; + + // This is one of those no connection zones, netcode=0, and it has no name. + // Create a unique, bogus netname. + NET* no_net = new NET( m_pcb->network ); + + sprintf( name, "@:no_net_%d", netlessZones++ ); + no_net->net_id = name; + + // add the bogus net name to network->nets. + m_pcb->network->nets.push_back( no_net ); + + // use the bogus net name in the netless zone. + plane->name = no_net->net_id; } - mainPolygon->AppendPoint( mapPt( point ) ); + mainPolygon->layer_id = m_layerIds[ m_kicadLayer2pcb[ layer ] ]; - // this was the end of the main polygon - if( iterator.IsEndContour() ) + // Handle the main outlines + SHAPE_POLY_SET::ITERATOR iterator; + wxPoint startpoint; + bool is_first_point = true; + + for( iterator = zone->IterateWithHoles(); iterator; iterator++ ) { - // Close polygon - mainPolygon->AppendPoint( mapPt( startpoint ) ); - break; - } - } + wxPoint point( iterator->x, iterator->y ); - WINDOW* window = 0; - PATH* cutout = 0; + if( is_first_point ) + { + startpoint = point; + is_first_point = false; + } - bool isStartContour = true; + mainPolygon->AppendPoint( mapPt( point ) ); - // handle the cutouts - for( iterator++; iterator; iterator++ ) - { - if( isStartContour ) - { - is_first_point = true; - window = new WINDOW( plane ); - plane->AddWindow( window ); - - cutout = new PATH( window, T_polygon ); - window->SetShape( cutout ); - cutout->layer_id = m_layerIds[ m_kicadLayer2pcb[ zone->GetLayer() ] ]; + // this was the end of the main polygon + if( iterator.IsEndContour() ) + { + // Close polygon + mainPolygon->AppendPoint( mapPt( startpoint ) ); + break; + } } - // If the point in this iteration is the last of the contour, the next iteration - // will start with a new contour. - isStartContour = iterator.IsEndContour(); + WINDOW* window = 0; + PATH* cutout = 0; - wxASSERT( window ); - wxASSERT( cutout ); + bool isStartContour = true; - wxPoint point(iterator->x, iterator->y ); - - if( is_first_point ) + // handle the cutouts + for( iterator++; iterator; iterator++ ) { - startpoint = point; - is_first_point = false; + if( isStartContour ) + { + is_first_point = true; + window = new WINDOW( plane ); + plane->AddWindow( window ); + + cutout = new PATH( window, T_polygon ); + window->SetShape( cutout ); + cutout->layer_id = m_layerIds[ m_kicadLayer2pcb[ layer ] ]; + } + + // If the point in this iteration is the last of the contour, the next iteration + // will start with a new contour. + isStartContour = iterator.IsEndContour(); + + wxASSERT( window ); + wxASSERT( cutout ); + + wxPoint point(iterator->x, iterator->y ); + + if( is_first_point ) + { + startpoint = point; + is_first_point = false; + } + + cutout->AppendPoint( mapPt( point ) ); + + // Close the polygon + if( iterator.IsEndContour() ) + cutout->AppendPoint( mapPt( startpoint ) ); } - - cutout->AppendPoint( mapPt( point ) ); - - // Close the polygon - if( iterator.IsEndContour() ) - cutout->AppendPoint( mapPt( startpoint ) ); - } + } // end build zones by layer } } @@ -1409,7 +1421,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) cutout = new PATH( window, T_polygon ); window->SetShape( cutout ); - cutout->layer_id = m_layerIds[ m_kicadLayer2pcb[ zone->GetLayer() ] ]; + cutout->layer_id = m_layerIds[ m_kicadLayer2pcb[ layer ] ]; } isStartContour = iterator.IsEndContour();