From 84b1ab7ce0e131c654ca152bcc7c48ddbfbb13f3 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Fri, 28 Feb 2020 11:43:37 -0800 Subject: [PATCH] PCad: Handle arbitrary PCad layer numbers KiCad is limited to 32 signal layers but PCad can number the layers higher than this. Instead of a C-style array, we now hold the layer numbers in a std::map to support arbitrary numbering. Fixes #3949 | https://gitlab.com/kicad/code/kicad/issues/3949 --- pcbnew/pcad2kicadpcb_plugin/pcb.cpp | 53 ++++++++++++++++++++--------- pcbnew/pcad2kicadpcb_plugin/pcb.h | 5 ++- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb.cpp index 40b8a7cdb4..adfeea4396 100644 --- a/pcbnew/pcad2kicadpcb_plugin/pcb.cpp +++ b/pcbnew/pcad2kicadpcb_plugin/pcb.cpp @@ -49,33 +49,46 @@ namespace PCAD2KICAD { PCB_LAYER_ID PCB::GetKiCadLayer( int aPCadLayer ) { - wxASSERT( aPCadLayer >= 0 && aPCadLayer < MAX_PCAD_LAYER_QTY ); - return m_layersMap[aPCadLayer].KiCadLayer; + auto it = m_layersMap.find( aPCadLayer ); + + if( it == m_layersMap.end() ) + THROW_IO_ERROR( wxString::Format( _( "Unknown PCad layer %u" ), unsigned( aPCadLayer ) ) ); + + return it->second.KiCadLayer; } LAYER_TYPE_T PCB::GetLayerType( int aPCadLayer ) { - wxASSERT( aPCadLayer >= 0 && aPCadLayer < MAX_PCAD_LAYER_QTY ); - return m_layersMap[aPCadLayer].layerType; + auto it = m_layersMap.find( aPCadLayer ); + + if( it == m_layersMap.end() ) + THROW_IO_ERROR( wxString::Format( _( "Unknown PCad layer %u" ), unsigned( aPCadLayer ) ) ); + + return it->second.layerType; } wxString PCB::GetLayerNetNameRef( int aPCadLayer ) { - wxASSERT( aPCadLayer >= 0 && aPCadLayer < MAX_PCAD_LAYER_QTY ); - return m_layersMap[aPCadLayer].netNameRef; + auto it = m_layersMap.find( aPCadLayer ); + + if( it == m_layersMap.end() ) + THROW_IO_ERROR( wxString::Format( _( "Unknown PCad layer %u" ), unsigned( aPCadLayer ) ) ); + + return it->second.netNameRef; } PCB::PCB( BOARD* aBoard ) : PCB_MODULE( this, aBoard ) { - int i; - m_defaultMeasurementUnit = wxT( "mil" ); - for( i = 0; i < MAX_PCAD_LAYER_QTY; i++ ) + for( size_t i = 0; i < 8; ++i ) { - m_layersMap[i].KiCadLayer = F_Mask; // default - m_layersMap[i].layerType = LAYER_TYPE_NONSIGNAL; // default - m_layersMap[i].netNameRef = wxT( "" ); // default + TLAYER layer; + layer.KiCadLayer = F_Mask; // default + layer.layerType = LAYER_TYPE_NONSIGNAL; // default + layer.netNameRef = wxT( "" ); // default + + m_layersMap.insert( std::make_pair( i, layer ) ); } m_sizeX = 0; @@ -521,23 +534,26 @@ void PCB::MapLayer( XNODE* aNode ) if( FindNode( aNode, wxT( "layerNum" ) ) ) FindNode( aNode, wxT( "layerNum" ) )->GetNodeContent().ToLong( &num ); - if( num < 0 || num >= MAX_PCAD_LAYER_QTY ) + if( num < 0 ) THROW_IO_ERROR( wxString::Format( wxT( "layerNum = %ld is out of range" ), num ) ); - m_layersMap[(int) num].KiCadLayer = KiCadLayer; + TLAYER newlayer; + newlayer.KiCadLayer = KiCadLayer; if( FindNode( aNode, wxT( "layerType" ) ) ) { layerType = FindNode( aNode, wxT( "layerType" ) )->GetNodeContent().Trim( false ); if( layerType == wxT( "NonSignal" ) ) - m_layersMap[(int) num].layerType = LAYER_TYPE_NONSIGNAL; + newlayer.layerType = LAYER_TYPE_NONSIGNAL; if( layerType == wxT( "Signal" ) ) - m_layersMap[(int) num].layerType = LAYER_TYPE_SIGNAL; + newlayer.layerType = LAYER_TYPE_SIGNAL; if( layerType == wxT( "Plane" ) ) - m_layersMap[(int) num].layerType = LAYER_TYPE_PLANE; + newlayer.layerType = LAYER_TYPE_PLANE; } + m_layersMap.insert( std::make_pair( num, newlayer ) ); + if( FindNode( aNode, wxT( "netNameRef" ) ) ) { FindNode( aNode, wxT( "netNameRef" ) )->GetAttribute( wxT( "Name" ), @@ -733,6 +749,9 @@ void PCB::ParseBoard( wxStatusBar* aStatusBar, wxXmlDocument* aXmlDoc, const wxS aNode->GetAttribute( wxT( "Name" ), &layerName ); layerName = layerName.MakeUpper(); m_layersStackup.Add( layerName ); + + if( m_layersStackup.size() > 32 ) + THROW_IO_ERROR( _( "KiCad only supports 32 signal layers" ) ); } } } diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb.h b/pcbnew/pcad2kicadpcb_plugin/pcb.h index 36dd09bd58..4c2e358f24 100644 --- a/pcbnew/pcad2kicadpcb_plugin/pcb.h +++ b/pcbnew/pcad2kicadpcb_plugin/pcb.h @@ -30,6 +30,7 @@ #ifndef pcb_H_ #define pcb_H_ +#include #include #include @@ -38,15 +39,13 @@ namespace PCAD2KICAD { -#define MAX_PCAD_LAYER_QTY 32 - class PCB : public PCB_MODULE, public PCB_CALLBACKS { public: PCB_COMPONENTS_ARRAY m_pcbComponents; // PCB Modules,Lines,Routes,Texts, .... and so on PCB_NETS_ARRAY m_pcbNetlist; // net objects collection wxString m_defaultMeasurementUnit; - TLAYER m_layersMap[MAX_PCAD_LAYER_QTY]; // flexible layers mapping + std::map m_layersMap; // flexible layers mapping int m_sizeX; int m_sizeY;