Add layer remapping ability to Altium imports

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17987
This commit is contained in:
Seth Hillbrand 2024-05-08 15:36:02 -07:00
parent 4218664d88
commit 3024a7c569
10 changed files with 129 additions and 14 deletions

View File

@ -253,25 +253,32 @@ std::vector<PCB_LAYER_ID> ALTIUM_PCB::GetKicadLayersToIterate( ALTIUM_LAYER aAlt
if( klayer == UNDEFINED_LAYER )
{
if( m_reporter )
auto it = m_layerNames.find( aAltiumLayer );
wxString layerName = it != m_layerNames.end() ? it->second : wxString::Format( wxT( "(%d)" ),
(int) aAltiumLayer );
if( m_reporter && altiumLayersWithWarning.insert( aAltiumLayer ).second )
{
m_reporter->Report( wxString::Format(
_( "Altium layer (%d) has no KiCad equivalent. It has been moved to KiCad "
"layer Eco1_User." ), aAltiumLayer ), RPT_SEVERITY_INFO );
_( "Altium layer %s has no KiCad equivalent. It has been moved to KiCad "
"layer Eco1_User." ), layerName ), RPT_SEVERITY_INFO );
}
klayer = Eco1_User;
m_board->SetEnabledLayers( m_board->GetEnabledLayers() | LSET( klayer ) );
}
return { klayer };
}
ALTIUM_PCB::ALTIUM_PCB( BOARD* aBoard, PROGRESS_REPORTER* aProgressReporter, REPORTER* aReporter,
ALTIUM_PCB::ALTIUM_PCB( BOARD* aBoard, PROGRESS_REPORTER* aProgressReporter,
LAYER_MAPPING_HANDLER& aHandler, REPORTER* aReporter,
const wxString& aLibrary, const wxString& aFootprintName )
{
m_board = aBoard;
m_progressReporter = aProgressReporter;
m_layerMappingHandler = aHandler;
m_reporter = aReporter;
m_doneCount = 0;
m_lastProgressCount = 0;
@ -1024,6 +1031,8 @@ void ALTIUM_PCB::ParseBoard6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile
++it;
}
remapUnsureLayers( elem.stackup );
// Set name of all non-cu layers
for( size_t altiumLayerId = static_cast<size_t>( ALTIUM_LAYER::TOP_OVERLAY );
altiumLayerId <= static_cast<size_t>( ALTIUM_LAYER::BOTTOM_SOLDER ); altiumLayerId++ )
@ -1053,6 +1062,72 @@ void ALTIUM_PCB::ParseBoard6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile
}
void ALTIUM_PCB::remapUnsureLayers( std::vector<ABOARD6_LAYER_STACKUP>& aStackup )
{
LSET enabledLayers = m_board->GetEnabledLayers();
LSET validRemappingLayers = enabledLayers | LSET::AllBoardTechMask() |
LSET::UserMask() | LSET::UserDefinedLayers();
std::vector<INPUT_LAYER_DESC> inputLayers;
std::map<wxString, ALTIUM_LAYER> altiumLayerNameMap;
for( size_t ii = 0; ii < aStackup.size(); ii++ )
{
ABOARD6_LAYER_STACKUP& curLayer = aStackup[ii];
ALTIUM_LAYER layer_num = static_cast<ALTIUM_LAYER>( ii + 1 );
INPUT_LAYER_DESC iLdesc;
if( ii > m_board->GetCopperLayerCount() && layer_num != ALTIUM_LAYER::BOTTOM_LAYER
&& !( layer_num >= ALTIUM_LAYER::TOP_OVERLAY
&& layer_num <= ALTIUM_LAYER::BOTTOM_SOLDER )
&& !( layer_num >= ALTIUM_LAYER::MECHANICAL_1
&& layer_num <= ALTIUM_LAYER::MECHANICAL_16 ) )
{
if( layer_num < ALTIUM_LAYER::BOTTOM_LAYER )
continue;
iLdesc.AutoMapLayer = PCB_LAYER_ID::UNDEFINED_LAYER;
}
else
{
iLdesc.AutoMapLayer = GetKicadLayer( layer_num );
}
iLdesc.Name = curLayer.name;
iLdesc.PermittedLayers = validRemappingLayers;
iLdesc.Required = ii < m_board->GetCopperLayerCount() || layer_num == ALTIUM_LAYER::BOTTOM_LAYER;
inputLayers.push_back( iLdesc );
altiumLayerNameMap.insert( { curLayer.name, layer_num } );
m_layerNames.insert( { layer_num, curLayer.name } );
}
if( inputLayers.size() == 0 )
return;
// Callback:
std::map<wxString, PCB_LAYER_ID> reMappedLayers = m_layerMappingHandler( inputLayers );
enabledLayers = LSET();
m_layermap.clear();
for( std::pair<wxString, PCB_LAYER_ID> layerPair : reMappedLayers )
{
if( layerPair.second == PCB_LAYER_ID::UNDEFINED_LAYER )
{
wxFAIL_MSG( wxT( "Unexpected Layer ID" ) );
continue;
}
ALTIUM_LAYER altiumID = altiumLayerNameMap.at( layerPair.first );
m_layermap.insert_or_assign( altiumID, layerPair.second );
enabledLayers |= LSET( layerPair.second );
}
m_board->SetEnabledLayers( enabledLayers );
m_board->SetVisibleLayers( enabledLayers );
}
void ALTIUM_PCB::HelperCreateBoardOutline( const std::vector<ALTIUM_VERTICE>& aVertices )
{
SHAPE_LINE_CHAIN lineChain;

View File

@ -28,6 +28,8 @@
#include <functional>
#include <layer_ids.h>
#include <vector>
#include <pcb_io/common/plugin_common_layer_mapping.h>
#include <altium_parser_pcb.h>
@ -90,7 +92,6 @@ class ZONE;
class PCB_DIM_RADIAL;
class PROGRESS_REPORTER;
namespace CFB
{
struct COMPOUND_FILE_ENTRY;
@ -107,6 +108,7 @@ class ALTIUM_PCB
{
public:
explicit ALTIUM_PCB( BOARD* aBoard, PROGRESS_REPORTER* aProgressReporter,
LAYER_MAPPING_HANDLER& aLayerMappingHandler,
REPORTER* aReporter = nullptr,
const wxString& aLibrary = wxEmptyString,
const wxString& aFootprintName = wxEmptyString);
@ -239,6 +241,8 @@ private:
FOOTPRINT* HelperGetFootprint( uint16_t aComponent ) const;
void remapUnsureLayers( std::vector<ABOARD6_LAYER_STACKUP>& aStackup );
BOARD* m_board;
std::vector<FOOTPRINT*> m_components;
std::vector<ZONE*> m_polygons;
@ -247,12 +251,15 @@ private:
std::map<uint32_t, wxString> m_unicodeStrings;
std::vector<int> m_altiumToKicadNetcodes;
std::map<ALTIUM_LAYER, PCB_LAYER_ID> m_layermap; // used to correctly map copper layers
std::map<ALTIUM_LAYER, wxString> m_layerNames;
std::map<ALTIUM_RULE_KIND, std::vector<ARULE6>> m_rules;
std::map<ALTIUM_RECORD, std::multimap<int, const AEXTENDED_PRIMITIVE_INFORMATION>>
m_extendedPrimitiveInformationMaps;
std::map<ALTIUM_LAYER, ZONE*> m_outer_plane;
LAYER_MAPPING_HANDLER m_layerMappingHandler;
PROGRESS_REPORTER* m_progressReporter; ///< optional; may be nullptr
REPORTER* m_reporter; ///< optional; may be nullptr
unsigned m_doneCount;

View File

@ -41,6 +41,7 @@
PCB_IO_ALTIUM_CIRCUIT_MAKER::PCB_IO_ALTIUM_CIRCUIT_MAKER() : PCB_IO( wxS( "Altium Circuit Maker" ) )
{
RegisterLayerMappingCallback( PCB_IO_ALTIUM_DESIGNER::DefaultLayerMappingCallback );
}
@ -100,7 +101,7 @@ BOARD* PCB_IO_ALTIUM_CIRCUIT_MAKER::LoadBoard( const wxString& aFileName, BOARD*
try
{
// Parse File
ALTIUM_PCB pcb( m_board, m_progressReporter, m_reporter );
ALTIUM_PCB pcb( m_board, m_progressReporter, m_layer_mapping_handler, m_reporter );
pcb.Parse( altiumPcbFile, mapping );
}
catch( CFB::CFBException& exception )

View File

@ -28,8 +28,9 @@
#include <pcb_io/pcb_io.h>
#include <pcb_io/pcb_io_mgr.h>
#include <pcb_io/common/plugin_common_layer_mapping.h>
class PCB_IO_ALTIUM_CIRCUIT_MAKER : public PCB_IO
class PCB_IO_ALTIUM_CIRCUIT_MAKER : public PCB_IO, public LAYER_REMAPPABLE_PLUGIN
{
public:
const IO_BASE::IO_FILE_DESC GetBoardFileDesc() const override

View File

@ -41,6 +41,7 @@
PCB_IO_ALTIUM_CIRCUIT_STUDIO::PCB_IO_ALTIUM_CIRCUIT_STUDIO() : PCB_IO( wxS( "Altium Circuit Studio" ) )
{
RegisterLayerMappingCallback( PCB_IO_ALTIUM_DESIGNER::DefaultLayerMappingCallback );
}
@ -100,7 +101,7 @@ BOARD* PCB_IO_ALTIUM_CIRCUIT_STUDIO::LoadBoard( const wxString& aFileName, BOARD
try
{
// Parse File
ALTIUM_PCB pcb( m_board, m_progressReporter, m_reporter );
ALTIUM_PCB pcb( m_board, m_progressReporter, m_layer_mapping_handler, m_reporter );
pcb.Parse( altiumPcbFile, mapping );
}
catch( CFB::CFBException& exception )

View File

@ -27,8 +27,9 @@
#include <pcb_io/pcb_io.h>
#include <pcb_io/pcb_io_mgr.h>
#include <pcb_io/common/plugin_common_layer_mapping.h>
class PCB_IO_ALTIUM_CIRCUIT_STUDIO : public PCB_IO
class PCB_IO_ALTIUM_CIRCUIT_STUDIO : public PCB_IO, public LAYER_REMAPPABLE_PLUGIN
{
public:
const IO_BASE::IO_FILE_DESC GetBoardFileDesc() const override

View File

@ -43,6 +43,8 @@
PCB_IO_ALTIUM_DESIGNER::PCB_IO_ALTIUM_DESIGNER() : PCB_IO( wxS( "Altium Designer" ) )
{
m_reporter = &WXLOG_REPORTER::GetInstance();
RegisterLayerMappingCallback( PCB_IO_ALTIUM_DESIGNER::DefaultLayerMappingCallback );
}
@ -51,6 +53,21 @@ PCB_IO_ALTIUM_DESIGNER::~PCB_IO_ALTIUM_DESIGNER()
}
std::map<wxString, PCB_LAYER_ID> PCB_IO_ALTIUM_DESIGNER::DefaultLayerMappingCallback(
const std::vector<INPUT_LAYER_DESC>& aInputLayerDescriptionVector )
{
std::map<wxString, PCB_LAYER_ID> retval;
// Just return a the auto-mapped layers
for( INPUT_LAYER_DESC layerDesc : aInputLayerDescriptionVector )
{
retval.insert( { layerDesc.Name, layerDesc.AutoMapLayer } );
}
return retval;
}
bool PCB_IO_ALTIUM_DESIGNER::checkFileHeader( const wxString& aFileName )
{
// Compound File Binary Format header
@ -118,7 +135,7 @@ BOARD* PCB_IO_ALTIUM_DESIGNER::LoadBoard( const wxString& aFileName, BOARD* aApp
try
{
// Parse File
ALTIUM_PCB pcb( m_board, m_progressReporter, m_reporter );
ALTIUM_PCB pcb( m_board, m_progressReporter, m_layer_mapping_handler, m_reporter );
pcb.Parse( altiumPcbFile, mapping );
}
catch( CFB::CFBException& exception )
@ -280,7 +297,7 @@ FOOTPRINT* PCB_IO_ALTIUM_DESIGNER::FootprintLoad( const wxString& aLibraryPath,
continue;
// Parse File
ALTIUM_PCB pcb( m_board, nullptr, m_reporter, aLibraryPath, aFootprintName );
ALTIUM_PCB pcb( m_board, nullptr, m_layer_mapping_handler, m_reporter, aLibraryPath, aFootprintName );
return pcb.ParseFootprint( *altiumLibFile, aFootprintName );
}
}

View File

@ -27,13 +27,14 @@
#include <pcb_io/pcb_io.h>
#include <pcb_io/pcb_io_mgr.h>
#include <pcb_io/common/plugin_common_layer_mapping.h>
#include <map>
#include <memory>
class ALTIUM_COMPOUND_FILE;
class PCB_IO_ALTIUM_DESIGNER : public PCB_IO
class PCB_IO_ALTIUM_DESIGNER : public PCB_IO, public LAYER_REMAPPABLE_PLUGIN
{
public:
// -----<PUBLIC PCB_IO API>--------------------------------------------------
@ -74,6 +75,15 @@ public:
static bool checkFileHeader( const wxString& aFileName );
/**
* Return the automapped layers.
*
* @param aInputLayerDescriptionVector
* @return Auto-mapped layers
*/
static std::map<wxString, PCB_LAYER_ID> DefaultLayerMappingCallback(
const std::vector<INPUT_LAYER_DESC>& aInputLayerDescriptionVector );
private:
std::map<wxString, std::vector<std::unique_ptr<ALTIUM_COMPOUND_FILE>>> m_fplibFiles;

View File

@ -34,6 +34,7 @@
PCB_IO_SOLIDWORKS::PCB_IO_SOLIDWORKS() : PCB_IO( wxS( "Solidworks PCB" ) )
{
m_reporter = &WXLOG_REPORTER::GetInstance();
RegisterLayerMappingCallback( PCB_IO_ALTIUM_DESIGNER::DefaultLayerMappingCallback );
}
@ -121,7 +122,7 @@ BOARD* PCB_IO_SOLIDWORKS::LoadBoard( const wxString& aFileName, BOARD* aAppendTo
try
{
// Parse File
ALTIUM_PCB pcb( m_board, m_progressReporter, m_reporter );
ALTIUM_PCB pcb( m_board, m_progressReporter, m_layer_mapping_handler, m_reporter );
pcb.Parse( altiumPcbFile, mapping );
}
catch( CFB::CFBException& exception )

View File

@ -22,8 +22,9 @@
#include <pcb_io/pcb_io.h>
#include <pcb_io/pcb_io_mgr.h>
#include <pcb_io/common/plugin_common_layer_mapping.h>
class PCB_IO_SOLIDWORKS : public PCB_IO
class PCB_IO_SOLIDWORKS : public PCB_IO, public LAYER_REMAPPABLE_PLUGIN
{
public:
const IO_BASE::IO_FILE_DESC GetBoardFileDesc() const override