GerbView issue #4729 : Map loaded Gerbers with Altium file extensions to matching KiCad layers when exporting to PCBNew

This commit is contained in:
PJM 2020-07-04 15:12:49 -07:00
parent 9e669db5b4
commit 06599d8d46
2 changed files with 148 additions and 3 deletions

View File

@ -27,13 +27,14 @@
*/
#include <fctsys.h>
#include <kiface_i.h>
#include <gerber_file_image.h>
#include <gerber_file_image_list.h>
#include <gerbview.h>
#include <gerbview_frame.h>
#include <gerbview_id.h>
#include <gerbview_settings.h>
#include <gerber_file_image.h>
#include <gerber_file_image_list.h>
#include <kiface_i.h>
#include <layers_id_colors_and_visibility.h>
#include <select_layers_to_pcb.h>
@ -204,6 +205,46 @@ void LAYERS_MAP_DIALOG::initDialog()
m_layersList[ii] = text;
}
std::vector<int> gerber2KicadMapping;
// See how many of the loaded Gerbers have Altium file extensions
int numAltiumGerbers = findNumAltiumGerbersLoaded( gerber2KicadMapping );
if( numAltiumGerbers > 0 )
{
// See if the user wants to map the Altium Gerbers to known KiCad PCB layers
int returnVal = wxMessageBox(
_( "Gerbers with known layers: " + wxString::Format( wxT( "%i" ), numAltiumGerbers )
+ "\n\nAssign to matching KiCad PCB layers?" ),
_( "Automatic Layer Assignment" ), wxOK | wxCANCEL | wxOK_DEFAULT );
if( returnVal == wxOK )
{
for( int ii = 0; ii < m_gerberActiveLayersCount; ii++ )
{
int currLayer = gerber2KicadMapping[ii];
// Default to "Do Not Export" for unselected or undefined layer
if( ( currLayer == UNSELECTED_LAYER ) || ( currLayer == UNDEFINED_LAYER ) )
{
m_layersList[ii]->SetLabel( _( "Do not export" ) );
m_layersList[ii]->SetForegroundColour( *wxBLUE );
// Set the layer internally to unselected
m_layersLookUpTable[ii] = UNSELECTED_LAYER;
}
else
{
m_layersList[ii]->SetLabel( GetPCBDefaultLayerName( currLayer ) );
m_layersList[ii]->SetForegroundColour( wxColour( 255, 0, 128 ) );
// Set the layer internally to the matching KiCad layer
m_layersLookUpTable[ii] = currLayer;
}
}
}
}
}
/* Ensure m_exportBoardCopperLayersCount = 2 to BOARD_COPPER_LAYERS_MAX_COUNT
@ -383,3 +424,92 @@ void LAYERS_MAP_DIALOG::OnOkClick( wxCommandEvent& event )
EndModal( wxID_OK );
}
int LAYERS_MAP_DIALOG::findNumAltiumGerbersLoaded( std::vector<int>& aGerber2KicadMapping )
{
// The next comment preserves initializer formatting below it
// clang-format off
// This map contains the known Altium file extensions for Gerbers that we care about,
// along with their corresponding KiCad layer
std::map<wxString, PCB_LAYER_ID> altiumExt{
{ "GTL", F_Cu }, // Top copper
{ "G1", In1_Cu }, // Inner layers 1 - 30
{ "G2", In2_Cu },
{ "G3", In3_Cu },
{ "G4", In4_Cu },
{ "G5", In5_Cu },
{ "G6", In6_Cu },
{ "G7", In7_Cu },
{ "G8", In8_Cu },
{ "G9", In9_Cu },
{ "G10", In10_Cu },
{ "G11", In11_Cu },
{ "G12", In12_Cu },
{ "G13", In13_Cu },
{ "G14", In14_Cu },
{ "G15", In15_Cu },
{ "G16", In16_Cu },
{ "G17", In17_Cu },
{ "G18", In18_Cu },
{ "G19", In19_Cu },
{ "G20", In20_Cu },
{ "G21", In21_Cu },
{ "G22", In22_Cu },
{ "G23", In23_Cu },
{ "G24", In24_Cu },
{ "G25", In25_Cu },
{ "G26", In26_Cu },
{ "G27", In27_Cu },
{ "G28", In28_Cu },
{ "G29", In29_Cu },
{ "G30", In30_Cu },
{ "GBL", B_Cu }, // Bottom copper
{ "GTP", F_Paste }, // Paste top
{ "GBP", B_Paste }, // Paste bottom
{ "GTO", F_SilkS }, // Silkscreen top
{ "GBO", B_SilkS }, // Silkscreen bottom
{ "GTS", F_Mask }, // Soldermask top
{ "GBS", B_Mask }, // Soldermask bottom
{ "GM1", Eco1_User }, // Altium mechanical layer 1
{ "GM2", Eco2_User }, // Altium mechanical layer 2
{ "GKO", Edge_Cuts } // PCB Outline
};
// clang-format on
std::map<wxString, PCB_LAYER_ID>::iterator it;
int numAltiumMatches = 0; // Assume we won't find Altium Gerbers
GERBER_FILE_IMAGE_LIST* images = m_Parent->GetGerberLayout()->GetImagesList();
// Loop through all loaded Gerbers looking for any with Altium specific extensions
for( int ii = 0; ii < m_gerberActiveLayersCount; ii++ )
{
// Get file name of Gerber loaded on this layer.
wxFileName fn( images->GetGbrImage( ii )->m_FileName );
// Get uppercase version of file extension
wxString FileExt = fn.GetExt();
FileExt.MakeUpper();
// Check for matching Altium Gerber file extension we'll handle
it = altiumExt.find( FileExt );
if( it != altiumExt.end() )
{
// We got a match, so store the KiCad layer number
aGerber2KicadMapping.push_back( it->second );
numAltiumMatches++;
}
else
{
// If there's no Altium match, then note the layer as unselected
aGerber2KicadMapping.push_back( UNSELECTED_LAYER );
}
}
// Return number of Altium Gerbers we found. Each index in the passed vector corresponds to
// a loaded Gerber layer, and the entry will contain the index to the matching
// KiCad layer for Altium Gerbers, or "UNSELECTED_LAYER" for the rest.
return numAltiumMatches;
}

View File

@ -63,6 +63,21 @@ private:
void OnGetSetup( wxCommandEvent& event ) override;
void OnResetClick( wxCommandEvent& event ) override;
/**
* Finds number of loaded Gerbers using Altium file extensions
*
* The passed vector<int> will be returned with the same number of elements
* as there are Gerber files. The indices into it are 1:1 with the loaded Gerber
* files. Any Gerber that maps will have it's entry set to the KiCad PCB layer
* number. Gerbers that aren't using Altium extensions or which don't map to an
* equivalent KiCad PCB layer will be set to UNSELECTED_LAYER.
*
* @param aGerber2KicadMapping passed to return KiCad PCB layer number for each Gerber
*
* @return int - The number of loaded Gerbers that have Altium extensions
*/
int findNumAltiumGerbersLoaded( std::vector<int>& aGerber2KicadMapping );
DECLARE_EVENT_TABLE()
};