specctra export: fix handling of multi-layer zones.

(from master branch)
This commit is contained in:
jean-pierre charras 2023-03-07 15:45:28 +01:00
parent ee0ba17c03
commit 411c9707ee
1 changed files with 89 additions and 77 deletions

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2007-2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2007-2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -1226,104 +1226,116 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
continue; continue;
// Currently, we export only copper layers // Currently, we export only copper layers
if( ! IsCopperLayer( zone->GetLayer() ) ) if( ! zone->IsOnCopperLayer() )
continue; 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 ); for( int layer = 0; layer < copperCount; layer++ )
PATH* mainPolygon = new PATH( plane, T_polygon );
plane->SetShape( mainPolygon );
plane->name = TO_UTF8( zone->GetNetname() );
if( plane->name.size() == 0 )
{ {
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. if( !zone->IsOnLayer( PCB_LAYER_ID( layer ) ) )
// Create a unique, bogus netname. continue;
NET* no_net = new NET( m_pcb->network ); COPPER_PLANE* plane = new COPPER_PLANE( m_pcb->structure );
sprintf( name, "@:no_net_%d", netlessZones++ ); m_pcb->structure->planes.push_back( plane );
no_net->net_id = name;
// add the bogus net name to network->nets. PATH* mainPolygon = new PATH( plane, T_polygon );
m_pcb->network->nets.push_back( no_net );
// use the bogus net name in the netless zone. plane->SetShape( mainPolygon );
plane->name = no_net->net_id; plane->name = TO_UTF8( zone->GetNetname() );
}
mainPolygon->layer_id = m_layerIds[ m_kicadLayer2pcb[ zone->GetLayer() ] ]; if( plane->name.size() == 0 )
// 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 )
{ {
startpoint = point; char name[32];
is_first_point = false;
// 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 // Handle the main outlines
if( iterator.IsEndContour() ) SHAPE_POLY_SET::ITERATOR iterator;
wxPoint startpoint;
bool is_first_point = true;
for( iterator = zone->IterateWithHoles(); iterator; iterator++ )
{ {
// Close polygon wxPoint point( iterator->x, iterator->y );
mainPolygon->AppendPoint( mapPt( startpoint ) );
break;
}
}
WINDOW* window = 0; if( is_first_point )
PATH* cutout = 0; {
startpoint = point;
is_first_point = false;
}
bool isStartContour = true; mainPolygon->AppendPoint( mapPt( point ) );
// handle the cutouts // this was the end of the main polygon
for( iterator++; iterator; iterator++ ) if( iterator.IsEndContour() )
{ {
if( isStartContour ) // Close polygon
{ mainPolygon->AppendPoint( mapPt( startpoint ) );
is_first_point = true; break;
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() ] ];
} }
// If the point in this iteration is the last of the contour, the next iteration WINDOW* window = 0;
// will start with a new contour. PATH* cutout = 0;
isStartContour = iterator.IsEndContour();
wxASSERT( window ); bool isStartContour = true;
wxASSERT( cutout );
wxPoint point(iterator->x, iterator->y ); // handle the cutouts
for( iterator++; iterator; iterator++ )
if( is_first_point )
{ {
startpoint = point; if( isStartContour )
is_first_point = false; {
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 ) );
} }
} // end build zones by layer
cutout->AppendPoint( mapPt( point ) );
// Close the polygon
if( iterator.IsEndContour() )
cutout->AppendPoint( mapPt( startpoint ) );
}
} }
} }
@ -1409,7 +1421,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
cutout = new PATH( window, T_polygon ); cutout = new PATH( window, T_polygon );
window->SetShape( cutout ); window->SetShape( cutout );
cutout->layer_id = m_layerIds[ m_kicadLayer2pcb[ zone->GetLayer() ] ]; cutout->layer_id = m_layerIds[ m_kicadLayer2pcb[ layer ] ];
} }
isStartContour = iterator.IsEndContour(); isStartContour = iterator.IsEndContour();