43#include <compoundfilereader.h>
48 const std::vector<ALTIUM_PROJECT_VARIANT>& aVariants )
50 std::map<wxString, FOOTPRINT*> fpByRef;
51 std::map<KIID, std::vector<FOOTPRINT*>> fpByUid;
55 fpByRef[fp->GetReference()] = fp;
61 if(
path.size() >= 2 )
62 fpByUid[
path.back()].push_back( fp );
69 if( !pv.description.empty() && pv.description != pv.name )
82 if( it != fpByUid.end() && it->second.size() == 1 )
83 target = it->second.front();
90 if( it != fpByRef.end() )
102 if( entry.
kind == 1 )
104 fpVariant->
SetDNP(
true );
108 else if( entry.
kind == 0 )
112 if( key.CmpNoCase( wxS(
"LibReference" ) ) == 0 )
114 else if( key.CmpNoCase( wxS(
"Description" ) ) == 0 )
116 else if( key.CmpNoCase( wxS(
"Footprint" ) ) == 0 )
125 const std::map<wxString, wxString>& aParameters )
133 static const std::set<wxString> reserved = {
134 wxS(
"LAYER" ), wxS(
"FILENAME" ), wxS(
"FILEPATH" ),
135 wxS(
"PROJECTNAME" ), wxS(
"VARIANT" ), wxS(
"VARIANT_DESC" ),
136 wxS(
"ISSUE_DATE" ), wxS(
"CURRENT_DATE" ), wxS(
"CURRENT_TIME_LOCALE" ),
137 wxS(
"CURRENT_TIME_HH_MM_SS" ), wxS(
"REVISION" ), wxS(
"TITLE" ),
138 wxS(
"COMPANY" ), wxS(
"COMMENT1" ), wxS(
"COMMENT2" ),
139 wxS(
"COMMENT3" ), wxS(
"COMMENT4" ), wxS(
"COMMENT5" ),
140 wxS(
"COMMENT6" ), wxS(
"COMMENT7" ), wxS(
"COMMENT8" ),
141 wxS(
"COMMENT9" ), wxS(
"VCSHASH" ), wxS(
"VCSSHORTHASH" ),
142 wxS(
"KICAD_VERSION" ), wxS(
"PAPER" ), wxS(
"SHEETNAME" ),
143 wxS(
"SHEETPATH" ), wxS(
"DRC_WARNING" ), wxS(
"DRC_ERROR" ),
144 wxS(
"ERC_WARNING" ), wxS(
"ERC_ERROR" )
147 std::map<wxString, wxString>& textVars = aProject->
GetTextVars();
150 for(
const auto& [
name, value] : aParameters )
152 if( reserved.count(
name ) )
156 if( textVars.count(
name ) )
159 textVars[
name] = value;
169 const std::map<ALTIUM_PCB_DIR, std::string>& aMapping,
170 const std::map<std::string, UTF8>* aProperties,
PROJECT* aProject,
179 ALTIUM_PCB pcb( aBoard, aProgressReporter, aLayerMappingHandler, aReporter );
180 pcb.
Parse( altiumPcbFile, aMapping, aProperties );
182 catch( CFB::CFBException& exception )
187 if( aProperties && aProperties->count(
"project_file" ) )
189 const wxString& projectFile = aProperties->at(
"project_file" );
193 if( !variants.empty() )
203 PCB_IO( wxS(
"Altium Designer" ) )
215 const std::vector<INPUT_LAYER_DESC>& aInputLayerDescriptionVector )
217 std::map<wxString, PCB_LAYER_ID> retval;
222 retval.insert( { layerDesc.Name, layerDesc.AutoMapLayer } );
255 const std::map<std::string, UTF8>* aProperties,
PROJECT* aProject )
264 const std::map<ALTIUM_PCB_DIR, std::string> mapping = {
299 if( aLibraryPath.IsEmpty() )
302 wxFileName fn( aLibraryPath );
304 if( fn.IsFileReadable() && fn.GetModificationTime().IsValid() )
305 return fn.GetModificationTime().GetValue().GetValue();
325 if( aLibraryPath.Lower().EndsWith( wxS(
".pcblib" ) ) )
327 libFiles.
m_Files.emplace_back( std::make_unique<ALTIUM_PCB_COMPOUND_FILE>( aLibraryPath ) );
329 else if( aLibraryPath.Lower().EndsWith( wxS(
".intlib" ) ) )
331 std::unique_ptr<ALTIUM_PCB_COMPOUND_FILE> lib = std::make_unique<ALTIUM_PCB_COMPOUND_FILE>( aLibraryPath );
333 for(
const auto& [pcbLibName, pcbCfe] : lib->EnumDir(
L"PCBLib" ) )
335 std::unique_ptr<ALTIUM_PCB_COMPOUND_FILE> libFile = std::make_unique<ALTIUM_PCB_COMPOUND_FILE>();
337 if( lib->DecodeIntLibStream( *pcbCfe, libFile.get() ) )
338 libFiles.
m_Files.emplace_back( std::move( libFile ) );
344 catch( CFB::CFBException& exception )
352 const wxString& aLibraryPath,
bool aBestEfforts,
353 const std::map<std::string, UTF8>* aProperties )
362 for( std::unique_ptr<ALTIUM_PCB_COMPOUND_FILE>& altiumLibFile :
m_fplibFiles[aLibraryPath].m_Files )
367 const std::vector<std::string> streamName = {
"Library",
"Data" };
368 const CFB::COMPOUND_FILE_ENTRY* libraryData = altiumLibFile->FindStream( streamName );
370 if( libraryData ==
nullptr )
375 std::map<wxString, wxString> properties = parser.
ReadProperties();
377 uint32_t numberOfFootprints = parser.
Read<uint32_t>();
386 bool footprintListNotTruncated =
true;
388 if ( patternMap.size() < numberOfFootprints )
390 numberOfFootprints = patternMap.size();
391 footprintListNotTruncated =
false;
394 aFootprintNames.Alloc( numberOfFootprints );
396 for(
size_t i = 0; i < numberOfFootprints; i++ )
401 wxString fpPattern( charBuffer, wxConvISO8859_1 );
403 auto it = patternMap.find( fpPattern );
405 if( it != patternMap.end() )
406 aFootprintNames.Add( it->second );
420 catch( CFB::CFBException& exception )
428 const wxString& aFootprintName,
bool aKeepUUID,
429 const std::map<std::string, UTF8>* aProperties )
438 for( std::unique_ptr<ALTIUM_PCB_COMPOUND_FILE>& altiumLibFile :
m_fplibFiles[aLibraryPath].m_Files )
440 altiumLibFile->CacheLibModels();
441 auto [dirName, fpCfe] = altiumLibFile->FindLibFootprintDirName( aFootprintName );
443 if( dirName.IsEmpty() )
451 catch( CFB::CFBException& exception )
456 THROW_IO_ERRORF(
_(
"Footprint '%s' not found in '%s'." ), aFootprintName, aLibraryPath );
462 std::vector<FOOTPRINT*> footprints;
466 footprints.push_back(
static_cast<FOOTPRINT*
>( fp->Clone() ) );
std::string FormatPath(const std::vector< std::string > &aVectorPath)
Helper for debug logging (vector -> string)
@ EXTENDPRIMITIVEINFORMATION
std::vector< ALTIUM_PROJECT_VARIANT > ParseAltiumProjectVariants(const wxString &aPrjPcbPath)
Parse all [ProjectVariantN] sections from an Altium .PrjPcb project file.
std::map< wxString, wxString > ParseAltiumProjectParameters(const wxString &aPrjPcbPath)
Parse all [ParameterN] sections from an Altium .PrjPcb project file.
KIID AltiumUniqueIdToKiid(const wxString &aUniqueId)
Derive a stable KIID from an Altium component unique id.
std::map< wxString, ValueType, DETAIL::CASE_INSENSITIVE_COMPARER > CASE_INSENSITIVE_MAP
size_t GetRemainingBytes() const
wxScopedCharBuffer ReadCharBuffer()
size_t ReadAndSetSubrecordLength()
std::map< wxString, wxString > ReadProperties(std::function< std::map< wxString, wxString >(const std::string &)> handleBinaryData=[](const std::string &) { return std::map< wxString, wxString >();})
std::unique_ptr< FOOTPRINT > ParseFootprint(ALTIUM_PCB_COMPOUND_FILE &altiumLibFile, const wxString &aFootprintName)
void Parse(const ALTIUM_PCB_COMPOUND_FILE &aAltiumPcbFile, const std::map< ALTIUM_PCB_DIR, std::string > &aFileMapping, const std::map< std::string, UTF8 > *aProperties=nullptr)
Information pertinent to a Pcbnew printed circuit board.
void AddVariant(const wxString &aVariantName)
const FOOTPRINTS & Footprints() const
void SetVariantDescription(const wxString &aVariantName, const wxString &aDescription)
RAII class to set and restore the fontconfig reporter.
REPORTER * m_reporter
Reporter to log errors/warnings to, may be nullptr.
PROGRESS_REPORTER * m_progressReporter
Progress reporter to track the progress of the operation, may be nullptr.
virtual bool CanReadLibrary(const wxString &aFileName) const
Checks if this IO object can read the specified library file/directory.
virtual void RegisterCallback(LAYER_MAPPING_HANDLER aLayerMappingHandler)
Register a different handler to be called when mapping of input layers to KiCad layers occurs.
LAYER_MAPPING_HANDLER m_layer_mapping_handler
Callback to get layer mapping.
static LOAD_INFO_REPORTER & GetInstance()
long long GetLibraryTimestamp(const wxString &aLibraryPath) const override
Generate a timestamp representing all the files in the library (including the library directory).
void FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aLibraryPath, bool aBestEfforts, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Return a list of footprint names contained within the library at aLibraryPath.
std::vector< FOOTPRINT * > GetImportedCachedLibraryFootprints() override
Return a container with the cached library footprints generated in the last call to Load.
~PCB_IO_ALTIUM_DESIGNER()
static bool checkFileHeader(const wxString &aFileName)
bool CanReadBoard(const wxString &aFileName) const override
std::unique_ptr< FOOTPRINT > FootprintLoad(const wxString &aLibraryPath, const wxString &aFootprintName, bool aKeepUUID=false, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Load a footprint having aFootprintName from the aLibraryPath containing a library format that this PC...
void loadAltiumLibrary(const wxString &aLibraryPath)
void loadBoard(const wxString &aFileName, BOARD &aBoard, bool aIsNewLoad, const std::map< std::string, UTF8 > *aProperties, PROJECT *aProject=nullptr) override
Parse aFileName into aBoard.
static std::map< wxString, PCB_LAYER_ID > DefaultLayerMappingCallback(const std::vector< INPUT_LAYER_DESC > &aInputLayerDescriptionVector)
Return the automapped layers.
std::map< wxString, ALTIUM_FILE_CACHE > m_fplibFiles
bool CanReadLibrary(const wxString &aFileName) const override
Checks if this IO object can read the specified library file/directory.
BOARD * m_board
The board BOARD being worked on, no ownership here.
virtual bool CanReadBoard(const wxString &aFileName) const
PCB_IO(const wxString &aName)
const std::map< std::string, UTF8 > * m_props
Properties passed via Save() or Load(), no ownership, may be NULL.
A progress reporter interface for use in multi-threaded environments.
Container for project specific data.
void IncrementTextVarsTicker()
virtual std::map< wxString, wxString > & GetTextVars() const
A pure virtual class used to derive REPORTER objects from.
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
#define THROW_IO_ERRORF(msg,...)
const std::vector< uint8_t > COMPOUND_FILE_HEADER
bool fileHasBinaryHeader(const wxString &aFilePath, const std::vector< uint8_t > &aHeader, size_t aOffset)
Check if a file starts with a defined binary header.
void ApplyAltiumProjectVariantsToBoard(BOARD *aBoard, const std::vector< ALTIUM_PROJECT_VARIANT > &aVariants)
Pcbnew PLUGIN for Altium *.PcbDoc format.
void LoadAltiumBoard(const wxString &aFileName, BOARD *aBoard, const std::map< ALTIUM_PCB_DIR, std::string > &aMapping, const std::map< std::string, UTF8 > *aProperties, PROJECT *aProject, PROGRESS_REPORTER *aProgressReporter, LAYER_MAPPING_HANDLER &aLayerMappingHandler, REPORTER *aReporter)
void ApplyAltiumProjectParametersToProject(PROJECT *aProject, const std::map< wxString, wxString > &aParameters)
Register Altium project parameters as KiCad project text variables so that imported board text refere...
void LoadAltiumBoard(const wxString &aFileName, BOARD *aBoard, const std::map< ALTIUM_PCB_DIR, std::string > &aMapping, const std::map< std::string, UTF8 > *aProperties, PROJECT *aProject, PROGRESS_REPORTER *aProgressReporter, LAYER_MAPPING_HANDLER &aLayerMappingHandler, REPORTER *aReporter)
std::function< std::map< wxString, PCB_LAYER_ID >(const std::vector< INPUT_LAYER_DESC > &)> LAYER_MAPPING_HANDLER
Pointer to a function that takes a map of source and KiCad layers and returns a re-mapped version.
A project-level assembly variant parsed from an Altium .PrjPcb file.
A single component variation within an Altium project variant.
std::map< wxString, wxString > alternateFields
std::vector< std::unique_ptr< ALTIUM_PCB_COMPOUND_FILE > > m_Files