ADDED: CADSTAR .cpa footprint libraries

This commit is contained in:
Roberto Fernandez Bautista 2023-03-13 22:21:24 +01:00
parent c5362c9b0a
commit 6f5321c481
7 changed files with 204 additions and 12 deletions

View File

@ -86,6 +86,7 @@ struct SUPPORTED_FILE_TYPE
enum {
ID_PANEL_FPLIB_ADD_KICADMOD = ID_PCBNEW_END_LIST,
ID_PANEL_FPLIB_ADD_ALTIUM,
ID_PANEL_FPLIB_ADD_CADSTAR,
ID_PANEL_FPLIB_ADD_EAGLE6,
ID_PANEL_FPLIB_ADD_KICADLEGACY,
ID_PANEL_FPLIB_ADD_GEDA,
@ -118,6 +119,12 @@ static const std::map<int, SUPPORTED_FILE_TYPE>& fileTypes()
"Altium (*.PcbLib)", AltiumFootprintLibPathWildcard(), "", true, IO_MGR::ALTIUM_DESIGNER
}
},
{ ID_PANEL_FPLIB_ADD_CADSTAR,
{
wxT( "CADSTAR (*.cpa)" ), CadstarPcbArchiveFileWildcard(), wxT( "" ),
true, IO_MGR::CADSTAR_PCB_ARCHIVE
}
},
{ ID_PANEL_FPLIB_ADD_EAGLE6,
{
wxT( "Eagle 6.x (*.lbr)" ), EagleFootprintLibPathWildcard(), wxT( "" ),
@ -378,6 +385,7 @@ PANEL_FP_LIB_TABLE::PANEL_FP_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent,
choices.Add( IO_MGR::ShowType( IO_MGR::KICAD_SEXP ) );
choices.Add( IO_MGR::ShowType( IO_MGR::LEGACY ) );
choices.Add( IO_MGR::ShowType( IO_MGR::ALTIUM_DESIGNER ) );
choices.Add( IO_MGR::ShowType( IO_MGR::CADSTAR_PCB_ARCHIVE ) );
choices.Add( IO_MGR::ShowType( IO_MGR::EAGLE ) );
choices.Add( IO_MGR::ShowType( IO_MGR::GEDA_PCB ) );

View File

@ -184,6 +184,52 @@ std::vector<FOOTPRINT*> CADSTAR_PCB_ARCHIVE_LOADER::GetLoadedLibraryFootpints()
}
std::vector<std::unique_ptr<FOOTPRINT>> CADSTAR_PCB_ARCHIVE_LOADER::LoadLibrary()
{
// loading the library after parsing takes almost no time in comparison
if( m_progressReporter )
m_progressReporter->SetNumPhases( 2 ); // (0) Read file, (1) Parse file
Parse( true /*aLibrary*/);
// Some memory handling
for( std::pair<SYMDEF_ID, FOOTPRINT*> libItem : m_libraryMap )
{
FOOTPRINT* footprint = libItem.second;
if( footprint )
delete footprint;
}
m_libraryMap.clear();
if( m_board )
delete m_board;
m_board = new BOARD(); // dummy board for loading
loadBoardStackup();
remapUnsureLayers();
loadComponentLibrary();
std::vector<std::unique_ptr<FOOTPRINT>> retval;
for( auto& [id, footprint] : m_libraryMap )
{
footprint->SetParent( nullptr ); // remove association to m_board
retval.emplace_back( footprint );
}
if( m_board )
delete m_board;
// Don't delete the generated footprints, but empty the map
// (the destructor of this class would end up deleting them if not)
m_libraryMap.clear();
return retval;
}
void CADSTAR_PCB_ARCHIVE_LOADER::logBoardStackupWarning(
const wxString& aCadstarLayerName,
const PCB_LAYER_ID& aKiCadLayer )

View File

@ -78,6 +78,13 @@ public:
*/
void Load( BOARD* aBoard, PROJECT* aProject );
/**
* @brief Parse a CADSTAR PCB Archive and load the footprints contained within
* @return Container with all the footprint definitions that were loaded (caller owns them)
*/
std::vector<std::unique_ptr<FOOTPRINT>> LoadLibrary();
/**
* @brief Return a copy of the loaded library footprints (caller owns the objects)
* @return Container with all the footprint definitions that were loaded

View File

@ -30,7 +30,7 @@
#include <wx/translation.h>
void CADSTAR_PCB_ARCHIVE_PARSER::Parse()
void CADSTAR_PCB_ARCHIVE_PARSER::Parse( bool aLibrary )
{
if( m_progressReporter )
m_progressReporter->BeginPhase( 0 ); // Read file
@ -72,13 +72,18 @@ void CADSTAR_PCB_ARCHIVE_PARSER::Parse()
break;
}
if( Header.Format.Type != wxT( "LAYOUT" ) )
if( aLibrary && Header.Format.Type != wxT( "LIBRARY" ) )
{
THROW_IO_ERROR( wxT( "The selected file is not a valid CADSTAR library file." ) );
}
else if( !aLibrary && Header.Format.Type != wxT( "LAYOUT" ) )
{
if( Header.Format.Type == wxT( "LIBRARY" ) )
{
THROW_IO_ERROR( wxT( "The selected file is a CADSTAR library file (as opposed "
"to a layout file). CADSTAR libraries cannot yet be "
"imported into KiCad." ) );
THROW_IO_ERROR(
wxT( "The selected file is a CADSTAR library file (as opposed "
"to a layout file). You can import this library by adding it "
"to the library table." ) );
}
else
{

View File

@ -61,7 +61,7 @@ public:
* @throw IO_ERROR if file could not be opened or there was
* an error while parsing
*/
void Parse();
void Parse( bool aLibrary = false );
typedef wxString MATERIAL_ID;
typedef long PHYSICAL_LAYER_ID;

View File

@ -146,3 +146,105 @@ BOARD* CADSTAR_PCB_ARCHIVE_PLUGIN::Load( const wxString& aFileName, BOARD* aAppe
return m_board;
}
void CADSTAR_PCB_ARCHIVE_PLUGIN::FootprintEnumerate( wxArrayString& aFootprintNames,
const wxString& aLibraryPath,
bool aBestEfforts,
const STRING_UTF8_MAP* aProperties )
{
ensureLoadedLibrary( aLibraryPath );
if( !m_cache.count( aLibraryPath ) )
return; // not found
for( const auto& [name, fp] : m_cache.at( aLibraryPath ) )
aFootprintNames.Add( name );
}
const FOOTPRINT*
CADSTAR_PCB_ARCHIVE_PLUGIN::GetEnumeratedFootprint( const wxString& aLibraryPath,
const wxString& aFootprintName,
const STRING_UTF8_MAP* aProperties )
{
ensureLoadedLibrary( aLibraryPath );
if( !m_cache.count( aLibraryPath ) )
return nullptr;
if( !m_cache.at( aLibraryPath ).count( aFootprintName ) )
return nullptr;
return m_cache.at( aLibraryPath ).at( aFootprintName ).get();
}
bool CADSTAR_PCB_ARCHIVE_PLUGIN::FootprintExists( const wxString& aLibraryPath,
const wxString& aFootprintName,
const STRING_UTF8_MAP* aProperties )
{
ensureLoadedLibrary( aLibraryPath );
if( !m_cache.count( aLibraryPath ) )
return false;
if( !m_cache.at( aLibraryPath ).count( aFootprintName ) )
return false;
return true;
}
FOOTPRINT* CADSTAR_PCB_ARCHIVE_PLUGIN::FootprintLoad( const wxString& aLibraryPath,
const wxString& aFootprintName,
bool aKeepUUID,
const STRING_UTF8_MAP* aProperties )
{
ensureLoadedLibrary( aLibraryPath );
if( !m_cache.count( aLibraryPath ) )
return nullptr;
if( !m_cache.at( aLibraryPath ).count( aFootprintName ) )
return nullptr;
return static_cast<FOOTPRINT*>( m_cache.at( aLibraryPath ).at( aFootprintName )->Duplicate() );
}
long long CADSTAR_PCB_ARCHIVE_PLUGIN::GetLibraryTimestamp( const wxString& aLibraryPath ) const
{
wxFileName fn( aLibraryPath );
if( fn.IsFileReadable() )
return fn.GetModificationTime().GetValue().GetValue();
else
return wxDateTime( 0.0 ).GetValue().GetValue();
}
void CADSTAR_PCB_ARCHIVE_PLUGIN::ensureLoadedLibrary( const wxString& aLibraryPath )
{
if( m_cache.count( aLibraryPath ) )
{
wxCHECK( m_timestamps.count( aLibraryPath ), /*void*/ );
if( m_timestamps.at( aLibraryPath ) == GetLibraryTimestamp( aLibraryPath ) )
return;
}
CADSTAR_PCB_ARCHIVE_LOADER csLoader( aLibraryPath, m_layer_mapping_handler,
false /*don't log stackup warnings*/, nullptr );
NAME_TO_FOOTPRINT_MAP footprintMap;
std::vector<std::unique_ptr<FOOTPRINT>> footprints = csLoader.LoadLibrary();
for( std::unique_ptr<FOOTPRINT>& fp : footprints )
{
footprintMap.insert( { fp->GetFPID().GetLibItemName(), std::move( fp ) } );
}
m_cache.insert( { aLibraryPath, std::move( footprintMap ) } );
m_timestamps[aLibraryPath] = GetLibraryTimestamp( aLibraryPath );
}

View File

@ -44,11 +44,6 @@ public:
const wxString GetFileExtension() const override;
long long GetLibraryTimestamp( const wxString& aLibraryPath ) const override
{
// No support for libraries....
return 0;
}
std::vector<FOOTPRINT*> GetImportedCachedLibraryFootprints() override;
@ -68,13 +63,42 @@ public:
*/
void RegisterLayerMappingCallback( LAYER_MAPPING_HANDLER aLayerMappingHandler ) override;
void FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibraryPath,
bool aBestEfforts, const STRING_UTF8_MAP* aProperties = nullptr ) override;
const FOOTPRINT* GetEnumeratedFootprint( const wxString& aLibraryPath,
const wxString& aFootprintName,
const STRING_UTF8_MAP* aProperties = nullptr ) override;
bool FootprintExists( const wxString& aLibraryPath, const wxString& aFootprintName,
const STRING_UTF8_MAP* aProperties = nullptr ) override;
FOOTPRINT* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
bool aKeepUUID = false,
const STRING_UTF8_MAP* aProperties = nullptr ) override;
long long GetLibraryTimestamp( const wxString& aLibraryPath ) const override;
/**
* CADSTAR Plugin is read-only
* @return Always false
*/
bool IsFootprintLibWritable( const wxString& aLibraryPath ) override { return false; }
CADSTAR_PCB_ARCHIVE_PLUGIN();
~CADSTAR_PCB_ARCHIVE_PLUGIN();
private:
void clearLoadedFootprints();
void ensureLoadedLibrary( const wxString& aLibraryPath );
const STRING_UTF8_MAP* m_props;
typedef std::map<const wxString, std::unique_ptr<FOOTPRINT>> NAME_TO_FOOTPRINT_MAP;
std::map<wxString, NAME_TO_FOOTPRINT_MAP> m_cache;
std::map<wxString, long long> m_timestamps;
const STRING_UTF8_MAP* m_props;
BOARD* m_board;
std::vector<FOOTPRINT*> m_loaded_footprints;
bool m_show_layer_mapping_warnings;