From 0bc1188897a94e6ab1feba37d9ec65d773c40b98 Mon Sep 17 00:00:00 2001 From: Wayne Stambaugh Date: Sun, 21 Aug 2022 14:56:04 -0400 Subject: [PATCH] Fix Eagle plugin board layer mapping issue. The Eagle plugin layers have to be mapped differently depending on whether a board is being imported or a footprint library is being cached. Footprint libraries can bypass the manual layer remapping step that happens when importing a board. Please note that when loading footprints in the footprint editor and viewer, all layers that do not directly map to KiCad layers are put on the Dwg_User layer so that there is data loss. Users will have to manually remap objects to the correct layer as required. This is less than ideal but until the footprint library table parser supports prompting users to remap unknown layers, it will have to do. Fixes: https://gitlab.com/kicad/code/kicad/-/issues/11839 --- pcbnew/plugins/eagle/eagle_plugin.cpp | 23 ++++++++++++++---- pcbnew/plugins/eagle/eagle_plugin.h | 35 +++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/pcbnew/plugins/eagle/eagle_plugin.cpp b/pcbnew/plugins/eagle/eagle_plugin.cpp index 0e3aabb364..d88736ad91 100644 --- a/pcbnew/plugins/eagle/eagle_plugin.cpp +++ b/pcbnew/plugins/eagle/eagle_plugin.cpp @@ -2920,7 +2920,7 @@ std::map EAGLE_PLUGIN::DefaultLayerMappingCallback( } -void EAGLE_PLUGIN::mapEagleLayersToKicad() +void EAGLE_PLUGIN::mapEagleLayersToKicad( bool aIsLibraryCache ) { std::vector inputDescs; @@ -2930,7 +2930,7 @@ void EAGLE_PLUGIN::mapEagleLayersToKicad() INPUT_LAYER_DESC layerDesc; std::tie( layerDesc.AutoMapLayer, layerDesc.PermittedLayers, layerDesc.Required ) = - defaultKicadLayer( eLayer.number ); + defaultKicadLayer( eLayer.number, aIsLibraryCache ); if( layerDesc.AutoMapLayer == UNDEFINED_LAYER ) continue; // Ignore unused copper layers @@ -2957,7 +2957,8 @@ PCB_LAYER_ID EAGLE_PLUGIN::kicad_layer( int aEagleLayer ) const } -std::tuple EAGLE_PLUGIN::defaultKicadLayer( int aEagleLayer ) const +std::tuple EAGLE_PLUGIN::defaultKicadLayer( int aEagleLayer, + bool aIsLibraryCache ) const { // eagle copper layer: if( aEagleLayer >= 1 && aEagleLayer < int( arrayDim( m_cu_map ) ) ) @@ -3078,7 +3079,19 @@ std::tuple EAGLE_PLUGIN::defaultKicadLayer( int aEagle case EAGLE_LAYER::BTEST: case EAGLE_LAYER::HOLES: default: - kiLayer = UNDEFINED_LAYER; + if( aIsLibraryCache ) + { + if( aEagleLayer != EAGLE_LAYER::MILLING && aEagleLayer != EAGLE_LAYER::TTEST && + aEagleLayer != EAGLE_LAYER::BTEST && aEagleLayer != EAGLE_LAYER::HOLES ) + kiLayer = Dwgs_User; + else + kiLayer = UNDEFINED_LAYER; + } + else + { + kiLayer = UNSELECTED_LAYER; + } + break; } @@ -3191,7 +3204,7 @@ void EAGLE_PLUGIN::cacheLib( const wxString& aLibPath ) m_xpath->push( "eagle.drawing.layers" ); wxXmlNode* layers = drawingChildren["layers"]; loadLayerDefs( layers ); - mapEagleLayersToKicad(); + mapEagleLayersToKicad( true ); m_xpath->pop(); m_xpath->push( "eagle.drawing.library" ); diff --git a/pcbnew/plugins/eagle/eagle_plugin.h b/pcbnew/plugins/eagle/eagle_plugin.h index 5e310e4320..fc5a87b26d 100644 --- a/pcbnew/plugins/eagle/eagle_plugin.h +++ b/pcbnew/plugins/eagle/eagle_plugin.h @@ -191,15 +191,40 @@ private: /// create a font size (fontz) from an eagle font size scalar and KiCad font thickness wxSize kicad_fontz( const ECOORD& d, int aTextThickness ) const; - /// Generate mapping between Eagle na KiCad layers - void mapEagleLayersToKicad(); + /** + * Generate mapping between Eagle and KiCad layers. + * + * @warning It is imperative that this gets called correctly because footprint libraries + * do not get remapped by the user on load. Otherwise, Pcbnew will crash when + * attempting to load footprint libraries that contain layers that do not exist + * in the #EAGLE_LAYER definitions. + * + * @param aIsLibraryCache is the flag to indicate when mapping the footprint library cache + * layers rather than the board layers. + */ + void mapEagleLayersToKicad( bool aIsLibraryCache = false ); /// Convert an Eagle layer to a KiCad layer. PCB_LAYER_ID kicad_layer( int aLayer ) const; - /// Get default KiCad layer corresponding to an Eagle layer of the board, - /// a set of sensible layer mapping options and required flag - std::tuple defaultKicadLayer( int aEagleLayer ) const; + /** + * Get the default KiCad layer corresponding to an Eagle layer of the board, + * a set of sensible layer mapping options and required flag + * + * @note The Eagle MILLING, TTEST, BTEST, and HOLES layers are set to #UNDEFINED_LAYER + * for historical purposes. All other Eagle layers that do not directly map to + * KiCad layers will be set to the #Dwg_User layer when loading Eagle footprint + * libraries to prevent data loss. + * + * @see #EAGLE_LAYER and defaultKiCadLayer(). + * + * @param aEagleLayer is the Eagle layer to map. + * @param aIsLibraryCache is a flag to indicate if the mapping is for board or footprint + * library cache objects. + * @return a tuple containing the mapped layer. + */ + std::tuple defaultKicadLayer( int aEagleLayer, + bool aIsLibraryCache = false ) const; /// Get Eagle layer name by its number const wxString& eagle_layer_name( int aLayer ) const;