From 8ef7252330fd06ab0ce8184606b74b7e44b422f5 Mon Sep 17 00:00:00 2001 From: Thomas Pointhuber Date: Sat, 19 Feb 2022 16:45:55 +0100 Subject: [PATCH] altium: Don't use string concatenation for paths pointing in the compound file * std::vector do not need to be split apart again * supports backslash in footprint names --- common/plugins/altium/altium_parser.cpp | 42 ++++++++----- common/plugins/altium/altium_parser.h | 10 ++- .../sch_plugins/altium/sch_altium_plugin.cpp | 4 +- .../altium/altium_circuit_maker_plugin.cpp | 38 +++++------ .../altium/altium_circuit_studio_plugin.cpp | 38 +++++------ .../plugins/altium/altium_designer_plugin.cpp | 51 ++++++++------- pcbnew/plugins/altium/altium_pcb.cpp | 63 ++++++++++++------- pcbnew/plugins/altium/altium_pcb.h | 3 +- 8 files changed, 144 insertions(+), 105 deletions(-) diff --git a/common/plugins/altium/altium_parser.cpp b/common/plugins/altium/altium_parser.cpp index 13cb1dbe46..122945df16 100644 --- a/common/plugins/altium/altium_parser.cpp +++ b/common/plugins/altium/altium_parser.cpp @@ -27,12 +27,24 @@ #include #include #include +#include #include #include #include #include +// Helper for debug logging +std::string FormatPath( const std::vector& aVectorPath ) +{ + return std::accumulate( aVectorPath.cbegin(), aVectorPath.cend(), std::string(), + []( const std::string& ss, const std::string& s ) + { + return ss.empty() ? s : ss + '\\' + s; + } ); +} + + ALTIUM_COMPOUND_FILE::ALTIUM_COMPOUND_FILE( const wxString& aFilePath ) { // Open file @@ -96,13 +108,12 @@ FindStreamSingleLevel( const CFB::CompoundFileReader& aReader, } } } ); - return ret; } const CFB::COMPOUND_FILE_ENTRY* -ALTIUM_COMPOUND_FILE::FindStream( const std::string& aStreamPath ) const +ALTIUM_COMPOUND_FILE::FindStream( const std::vector& aStreamPath ) const { if( !m_reader ) { @@ -111,24 +122,23 @@ ALTIUM_COMPOUND_FILE::FindStream( const std::string& aStreamPath ) const const CFB::COMPOUND_FILE_ENTRY* currentDirEntry = m_reader->GetRootEntry(); - size_t startCh = 0; - size_t delimiter = aStreamPath.find( '\\', startCh ); - while( delimiter != std::string::npos ) + auto it = aStreamPath.cbegin(); + while( currentDirEntry != nullptr ) { - std::string directoryName = aStreamPath.substr( startCh, delimiter ); - currentDirEntry = - FindStreamSingleLevel( *m_reader.get(), currentDirEntry, directoryName, false ); - if( currentDirEntry == nullptr ) - { - return nullptr; - } + const std::string& name = *it; - startCh = delimiter + 1; - delimiter = aStreamPath.find( '\\', startCh ); + if( ++it == aStreamPath.cend() ) + { + return FindStreamSingleLevel( *m_reader.get(), currentDirEntry, name, true ); + } + else + { + currentDirEntry = + FindStreamSingleLevel( *m_reader.get(), currentDirEntry, name, false ); + } } - std::string fileName = aStreamPath.substr( startCh, delimiter ); - return FindStreamSingleLevel( *m_reader.get(), currentDirEntry, fileName, true ); + return nullptr; } diff --git a/common/plugins/altium/altium_parser.h b/common/plugins/altium/altium_parser.h index c0ba718cc6..9389ca873f 100644 --- a/common/plugins/altium/altium_parser.h +++ b/common/plugins/altium/altium_parser.h @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -39,6 +40,13 @@ class CompoundFileReader; struct COMPOUND_FILE_ENTRY; } // namespace CFB +/** + * Helper for debug logging (vector -> string) + * @param aVectorPath path + * @return path formated as string + */ +std::string FormatPath( const std::vector& aVectorPath ); + class ALTIUM_COMPOUND_FILE { @@ -55,7 +63,7 @@ public: const CFB::CompoundFileReader& GetCompoundFileReader() const { return *m_reader; } - const CFB::COMPOUND_FILE_ENTRY* FindStream( const std::string& aStreamPath ) const; + const CFB::COMPOUND_FILE_ENTRY* FindStream( const std::vector& aStreamPath ) const; private: std::unique_ptr m_reader; diff --git a/eeschema/sch_plugins/altium/sch_altium_plugin.cpp b/eeschema/sch_plugins/altium/sch_altium_plugin.cpp index 0e08281285..b50d4179e1 100644 --- a/eeschema/sch_plugins/altium/sch_altium_plugin.cpp +++ b/eeschema/sch_plugins/altium/sch_altium_plugin.cpp @@ -306,7 +306,7 @@ void SCH_ALTIUM_PLUGIN::ParseAltiumSch( const wxString& aFileName ) void SCH_ALTIUM_PLUGIN::ParseStorage( const ALTIUM_COMPOUND_FILE& aAltiumSchFile ) { - const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.FindStream( "Storage" ); + const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.FindStream( { "Storage" } ); if( file == nullptr ) return; @@ -342,7 +342,7 @@ void SCH_ALTIUM_PLUGIN::ParseStorage( const ALTIUM_COMPOUND_FILE& aAltiumSchFile void SCH_ALTIUM_PLUGIN::ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile ) { - const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.FindStream( "FileHeader" ); + const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.FindStream( { "FileHeader" } ); if( file == nullptr ) THROW_IO_ERROR( "FileHeader not found" ); diff --git a/pcbnew/plugins/altium/altium_circuit_maker_plugin.cpp b/pcbnew/plugins/altium/altium_circuit_maker_plugin.cpp index b2c72064ad..5c809c6540 100644 --- a/pcbnew/plugins/altium/altium_circuit_maker_plugin.cpp +++ b/pcbnew/plugins/altium/altium_circuit_maker_plugin.cpp @@ -77,25 +77,25 @@ BOARD* ALTIUM_CIRCUIT_MAKER_PLUGIN::Load( const wxString& aFileName, BOARD* aApp // clang-format off const std::map mapping = { { ALTIUM_PCB_DIR::FILE_HEADER, "FileHeader" }, - { ALTIUM_PCB_DIR::ARCS6, "1CEEB63FB33847F8AFC4485F64735E\\" }, - { ALTIUM_PCB_DIR::BOARD6, "96B09F5C6CEE434FBCE0DEB3E88E70\\" }, - { ALTIUM_PCB_DIR::BOARDREGIONS, "E3A544335C30403A991912052C936F\\" }, - { ALTIUM_PCB_DIR::CLASSES6, "4F71DD45B09143988210841EA1C28D\\" }, - { ALTIUM_PCB_DIR::COMPONENTS6, "F9D060ACC7DD4A85BC73CB785BAC81\\" }, - { ALTIUM_PCB_DIR::COMPONENTBODIES6, "44D9487C98CE4F0EB46AB6E9CDAF40\\" }, // or: A0DB41FBCB0D49CE8C32A271AA7EF5 ? - { ALTIUM_PCB_DIR::DIMENSIONS6, "068B9422DBB241258BA2DE9A6BA1A6\\" }, - { ALTIUM_PCB_DIR::FILLS6, "6FFE038462A940E9B422EFC8F5D85E\\" }, - { ALTIUM_PCB_DIR::MODELS, "0DB009C021D946C88F1B3A32DAE94B\\" }, - { ALTIUM_PCB_DIR::NETS6, "35D7CF51BB9B4875B3A138B32D80DC\\" }, - { ALTIUM_PCB_DIR::PADS6, "4F501041A9BC4A06BDBDAB67D3820E\\" }, - { ALTIUM_PCB_DIR::POLYGONS6, "A1931C8B0B084A61AA45146575FDD3\\" }, - { ALTIUM_PCB_DIR::REGIONS6, "F513A5885418472886D3EF18A09E46\\" }, - { ALTIUM_PCB_DIR::RULES6, "C27718A40C94421388FAE5BD7785D7\\" }, - { ALTIUM_PCB_DIR::SHAPEBASEDREGIONS6,"BDAA2C70289849078C8EBEEC7F0848\\" }, - { ALTIUM_PCB_DIR::TEXTS6, "A34BC67C2A5F408D8F377378C5C5E2\\" }, - { ALTIUM_PCB_DIR::TRACKS6, "412A754DBB864645BF01CD6A80C358\\" }, - { ALTIUM_PCB_DIR::VIAS6, "C87A685A0EFA4A90BEEFD666198B56\\" }, - { ALTIUM_PCB_DIR::WIDESTRINGS6, "C1C6540EA23C48D3BF8F9A4ABB9D6D\\" } + { ALTIUM_PCB_DIR::ARCS6, "1CEEB63FB33847F8AFC4485F64735E" }, + { ALTIUM_PCB_DIR::BOARD6, "96B09F5C6CEE434FBCE0DEB3E88E70" }, + { ALTIUM_PCB_DIR::BOARDREGIONS, "E3A544335C30403A991912052C936F" }, + { ALTIUM_PCB_DIR::CLASSES6, "4F71DD45B09143988210841EA1C28D" }, + { ALTIUM_PCB_DIR::COMPONENTS6, "F9D060ACC7DD4A85BC73CB785BAC81" }, + { ALTIUM_PCB_DIR::COMPONENTBODIES6, "44D9487C98CE4F0EB46AB6E9CDAF40" }, // or: A0DB41FBCB0D49CE8C32A271AA7EF5 ? + { ALTIUM_PCB_DIR::DIMENSIONS6, "068B9422DBB241258BA2DE9A6BA1A6" }, + { ALTIUM_PCB_DIR::FILLS6, "6FFE038462A940E9B422EFC8F5D85E" }, + { ALTIUM_PCB_DIR::MODELS, "0DB009C021D946C88F1B3A32DAE94B" }, + { ALTIUM_PCB_DIR::NETS6, "35D7CF51BB9B4875B3A138B32D80DC" }, + { ALTIUM_PCB_DIR::PADS6, "4F501041A9BC4A06BDBDAB67D3820E" }, + { ALTIUM_PCB_DIR::POLYGONS6, "A1931C8B0B084A61AA45146575FDD3" }, + { ALTIUM_PCB_DIR::REGIONS6, "F513A5885418472886D3EF18A09E46" }, + { ALTIUM_PCB_DIR::RULES6, "C27718A40C94421388FAE5BD7785D7" }, + { ALTIUM_PCB_DIR::SHAPEBASEDREGIONS6,"BDAA2C70289849078C8EBEEC7F0848" }, + { ALTIUM_PCB_DIR::TEXTS6, "A34BC67C2A5F408D8F377378C5C5E2" }, + { ALTIUM_PCB_DIR::TRACKS6, "412A754DBB864645BF01CD6A80C358" }, + { ALTIUM_PCB_DIR::VIAS6, "C87A685A0EFA4A90BEEFD666198B56" }, + { ALTIUM_PCB_DIR::WIDESTRINGS6, "C1C6540EA23C48D3BF8F9A4ABB9D6D" } }; // clang-format on diff --git a/pcbnew/plugins/altium/altium_circuit_studio_plugin.cpp b/pcbnew/plugins/altium/altium_circuit_studio_plugin.cpp index 7241057acf..f5952ba32f 100644 --- a/pcbnew/plugins/altium/altium_circuit_studio_plugin.cpp +++ b/pcbnew/plugins/altium/altium_circuit_studio_plugin.cpp @@ -77,25 +77,25 @@ BOARD* ALTIUM_CIRCUIT_STUDIO_PLUGIN::Load( const wxString& aFileName, BOARD* aAp // clang-format off const std::map mapping = { { ALTIUM_PCB_DIR::FILE_HEADER, "FileHeader" }, - { ALTIUM_PCB_DIR::ARCS6, "00C595EB90524FFC8C3BD9670020A2\\" }, - { ALTIUM_PCB_DIR::BOARD6, "88857D7F1DF64F7BBB61848C965636\\" }, - { ALTIUM_PCB_DIR::BOARDREGIONS, "8957CF30F167408D9D263D23FE7C89\\" }, - { ALTIUM_PCB_DIR::CLASSES6, "847EFBF87A5149B1AA326A52AD6357\\" }, - { ALTIUM_PCB_DIR::COMPONENTS6, "465416896A15486999A39C643935D2\\" }, - { ALTIUM_PCB_DIR::COMPONENTBODIES6, "1849D9B5512D452A93EABF4E40B122\\" }, // or B6AD30D75241498BA2536EBF001752 ? - { ALTIUM_PCB_DIR::DIMENSIONS6, "16C81DBC13C447FF8B42A426677F3C\\" }, - { ALTIUM_PCB_DIR::FILLS6, "4E83BDC3253747F08E9006D7F57020\\" }, - { ALTIUM_PCB_DIR::MODELS, "C0F7599ECC6A4D648DF5BB557679AF\\" }, - { ALTIUM_PCB_DIR::NETS6, "D95A0DA2FE9047779A5194C127F30B\\" }, - { ALTIUM_PCB_DIR::PADS6, "47D69BC5107A4B8DB8DAA23E39C238\\" }, - { ALTIUM_PCB_DIR::POLYGONS6, "D7038392280E4E229B9D9B5426B295\\" }, - { ALTIUM_PCB_DIR::REGIONS6, "FFDDC21382BB42FE8A7D0C328D272C\\" }, - { ALTIUM_PCB_DIR::RULES6, "48B2FA96DB7546818752B34373D6C6\\" }, - { ALTIUM_PCB_DIR::SHAPEBASEDREGIONS6, "D5F54B536E124FB89E2D51B1121508\\" }, - { ALTIUM_PCB_DIR::TEXTS6, "349ABBB211DB4F5B8AE41B1B49555A\\" }, - { ALTIUM_PCB_DIR::TRACKS6, "530C20C225354B858B2578CAB8C08D\\" }, - { ALTIUM_PCB_DIR::VIAS6, "CA5F5989BCDB404DA70A9D1D3D5758\\" }, - { ALTIUM_PCB_DIR::WIDESTRINGS6, "87FBF0C5BC194B909FF42199450A76\\" } + { ALTIUM_PCB_DIR::ARCS6, "00C595EB90524FFC8C3BD9670020A2" }, + { ALTIUM_PCB_DIR::BOARD6, "88857D7F1DF64F7BBB61848C965636" }, + { ALTIUM_PCB_DIR::BOARDREGIONS, "8957CF30F167408D9D263D23FE7C89" }, + { ALTIUM_PCB_DIR::CLASSES6, "847EFBF87A5149B1AA326A52AD6357" }, + { ALTIUM_PCB_DIR::COMPONENTS6, "465416896A15486999A39C643935D2" }, + { ALTIUM_PCB_DIR::COMPONENTBODIES6, "1849D9B5512D452A93EABF4E40B122" }, // or B6AD30D75241498BA2536EBF001752 ? + { ALTIUM_PCB_DIR::DIMENSIONS6, "16C81DBC13C447FF8B42A426677F3C" }, + { ALTIUM_PCB_DIR::FILLS6, "4E83BDC3253747F08E9006D7F57020" }, + { ALTIUM_PCB_DIR::MODELS, "C0F7599ECC6A4D648DF5BB557679AF" }, + { ALTIUM_PCB_DIR::NETS6, "D95A0DA2FE9047779A5194C127F30B" }, + { ALTIUM_PCB_DIR::PADS6, "47D69BC5107A4B8DB8DAA23E39C238" }, + { ALTIUM_PCB_DIR::POLYGONS6, "D7038392280E4E229B9D9B5426B295" }, + { ALTIUM_PCB_DIR::REGIONS6, "FFDDC21382BB42FE8A7D0C328D272C" }, + { ALTIUM_PCB_DIR::RULES6, "48B2FA96DB7546818752B34373D6C6" }, + { ALTIUM_PCB_DIR::SHAPEBASEDREGIONS6, "D5F54B536E124FB89E2D51B1121508" }, + { ALTIUM_PCB_DIR::TEXTS6, "349ABBB211DB4F5B8AE41B1B49555A" }, + { ALTIUM_PCB_DIR::TRACKS6, "530C20C225354B858B2578CAB8C08D" }, + { ALTIUM_PCB_DIR::VIAS6, "CA5F5989BCDB404DA70A9D1D3D5758" }, + { ALTIUM_PCB_DIR::WIDESTRINGS6, "87FBF0C5BC194B909FF42199450A76" } }; // clang-format on diff --git a/pcbnew/plugins/altium/altium_designer_plugin.cpp b/pcbnew/plugins/altium/altium_designer_plugin.cpp index c5eced658f..f21110103e 100644 --- a/pcbnew/plugins/altium/altium_designer_plugin.cpp +++ b/pcbnew/plugins/altium/altium_designer_plugin.cpp @@ -77,26 +77,26 @@ BOARD* ALTIUM_DESIGNER_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendTo // clang-format off const std::map mapping = { { ALTIUM_PCB_DIR::FILE_HEADER, "FileHeader" }, - { ALTIUM_PCB_DIR::ARCS6, "Arcs6\\" }, - { ALTIUM_PCB_DIR::BOARD6, "Board6\\" }, - { ALTIUM_PCB_DIR::BOARDREGIONS, "BoardRegions\\" }, - { ALTIUM_PCB_DIR::CLASSES6, "Classes6\\" }, - { ALTIUM_PCB_DIR::COMPONENTS6, "Components6\\" }, - { ALTIUM_PCB_DIR::COMPONENTBODIES6, "ComponentBodies6\\" }, - { ALTIUM_PCB_DIR::DIMENSIONS6, "Dimensions6\\" }, - { ALTIUM_PCB_DIR::EXTENDPRIMITIVEINFORMATION, "ExtendedPrimitiveInformation\\" }, - { ALTIUM_PCB_DIR::FILLS6, "Fills6\\" }, - { ALTIUM_PCB_DIR::MODELS, "Models\\" }, - { ALTIUM_PCB_DIR::NETS6, "Nets6\\" }, - { ALTIUM_PCB_DIR::PADS6, "Pads6\\" }, - { ALTIUM_PCB_DIR::POLYGONS6, "Polygons6\\" }, - { ALTIUM_PCB_DIR::REGIONS6, "Regions6\\" }, - { ALTIUM_PCB_DIR::RULES6, "Rules6\\" }, - { ALTIUM_PCB_DIR::SHAPEBASEDREGIONS6, "ShapeBasedRegions6\\" }, - { ALTIUM_PCB_DIR::TEXTS6, "Texts6\\" }, - { ALTIUM_PCB_DIR::TRACKS6, "Tracks6\\" }, - { ALTIUM_PCB_DIR::VIAS6, "Vias6\\" }, - { ALTIUM_PCB_DIR::WIDESTRINGS6, "WideStrings6\\" } + { ALTIUM_PCB_DIR::ARCS6, "Arcs6" }, + { ALTIUM_PCB_DIR::BOARD6, "Board6" }, + { ALTIUM_PCB_DIR::BOARDREGIONS, "BoardRegions" }, + { ALTIUM_PCB_DIR::CLASSES6, "Classes6" }, + { ALTIUM_PCB_DIR::COMPONENTS6, "Components6" }, + { ALTIUM_PCB_DIR::COMPONENTBODIES6, "ComponentBodies6" }, + { ALTIUM_PCB_DIR::DIMENSIONS6, "Dimensions6" }, + { ALTIUM_PCB_DIR::EXTENDPRIMITIVEINFORMATION, "ExtendedPrimitiveInformation" }, + { ALTIUM_PCB_DIR::FILLS6, "Fills6" }, + { ALTIUM_PCB_DIR::MODELS, "Models" }, + { ALTIUM_PCB_DIR::NETS6, "Nets6" }, + { ALTIUM_PCB_DIR::PADS6, "Pads6" }, + { ALTIUM_PCB_DIR::POLYGONS6, "Polygons6" }, + { ALTIUM_PCB_DIR::REGIONS6, "Regions6" }, + { ALTIUM_PCB_DIR::RULES6, "Rules6" }, + { ALTIUM_PCB_DIR::SHAPEBASEDREGIONS6, "ShapeBasedRegions6" }, + { ALTIUM_PCB_DIR::TEXTS6, "Texts6" }, + { ALTIUM_PCB_DIR::TRACKS6, "Tracks6" }, + { ALTIUM_PCB_DIR::VIAS6, "Vias6" }, + { ALTIUM_PCB_DIR::WIDESTRINGS6, "WideStrings6" } }; // clang-format on @@ -144,11 +144,12 @@ void ALTIUM_DESIGNER_PLUGIN::FootprintEnumerate( wxArrayString& aFootprintNames try { - std::string streamName = "Library\\Data"; + const std::vector streamName = { "Library", "Data" }; const CFB::COMPOUND_FILE_ENTRY* libraryData = altiumLibFile.FindStream( streamName ); if( libraryData == nullptr ) { - THROW_IO_ERROR( wxString::Format( _( "File not found: '%s'." ), streamName ) ); + THROW_IO_ERROR( + wxString::Format( _( "File not found: '%s'." ), FormatPath( streamName ) ) ); } ALTIUM_PARSER parser( altiumLibFile, libraryData ); @@ -167,12 +168,14 @@ void ALTIUM_DESIGNER_PLUGIN::FootprintEnumerate( wxArrayString& aFootprintNames if( parser.HasParsingError() ) { - THROW_IO_ERROR( wxString::Format( "%s stream was not parsed correctly", streamName ) ); + THROW_IO_ERROR( wxString::Format( "%s stream was not parsed correctly", + FormatPath( streamName ) ) ); } if( parser.GetRemainingBytes() != 0 ) { - THROW_IO_ERROR( wxString::Format( "%s stream is not fully parsed", streamName ) ); + THROW_IO_ERROR( + wxString::Format( "%s stream is not fully parsed", FormatPath( streamName ) ) ); } } catch( CFB::CFBException& exception ) diff --git a/pcbnew/plugins/altium/altium_pcb.cpp b/pcbnew/plugins/altium/altium_pcb.cpp index 30e997a666..ab2d2cce96 100644 --- a/pcbnew/plugins/altium/altium_pcb.cpp +++ b/pcbnew/plugins/altium/altium_pcb.cpp @@ -387,7 +387,7 @@ void ALTIUM_PCB::Parse( const ALTIUM_COMPOUND_FILE& altiumPcbFi { true, ALTIUM_PCB_DIR::MODELS, [this, aFileMapping]( const ALTIUM_COMPOUND_FILE& aFile, auto fileHeader ) { - wxString dir( aFileMapping.at( ALTIUM_PCB_DIR::MODELS ) ); + std::vector dir{ aFileMapping.at( ALTIUM_PCB_DIR::MODELS ) }; this->ParseModelsData( aFile, fileHeader, dir ); } }, { true, ALTIUM_PCB_DIR::COMPONENTBODIES6, @@ -493,8 +493,7 @@ void ALTIUM_PCB::Parse( const ALTIUM_COMPOUND_FILE& altiumPcbFi continue; } - std::string mappedFile = mappedDirectory->second + "Header"; - + const std::vector mappedFile{ mappedDirectory->second, "Header" }; const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.FindStream( mappedFile ); if( file == nullptr ) { @@ -506,7 +505,7 @@ void ALTIUM_PCB::Parse( const ALTIUM_COMPOUND_FILE& altiumPcbFi if( reader.HasParsingError() ) { - wxLogError( _( "'%s' was not parsed correctly." ), mappedFile ); + wxLogError( _( "'%s' was not parsed correctly." ), FormatPath( mappedFile ) ); continue; } @@ -514,7 +513,7 @@ void ALTIUM_PCB::Parse( const ALTIUM_COMPOUND_FILE& altiumPcbFi if( reader.GetRemainingBytes() != 0 ) { - wxLogError( _( "'%s' was not fully parsed." ), mappedFile ); + wxLogError( _( "'%s' was not fully parsed." ), FormatPath( mappedFile ) ); continue; } } @@ -539,17 +538,16 @@ void ALTIUM_PCB::Parse( const ALTIUM_COMPOUND_FILE& altiumPcbFi continue; } - std::string mappedFile = mappedDirectory->second; - + std::vector mappedFile{ mappedDirectory->second }; if( directory != ALTIUM_PCB_DIR::FILE_HEADER ) - mappedFile += "Data"; + mappedFile.emplace_back( "Data" ); const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.FindStream( mappedFile ); if( file != nullptr ) fp( altiumPcbFile, file ); else if( isRequired ) - wxLogError( _( "File not found: '%s'." ), mappedFile ); + wxLogError( _( "File not found: '%s'." ), FormatPath( mappedFile ) ); } // fixup zone priorities since Altium stores them in the opposite order @@ -650,6 +648,7 @@ void ALTIUM_PCB::Parse( const ALTIUM_COMPOUND_FILE& altiumPcbFi m_board->SetModified(); } + FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile, const wxString& aFootprintName ) { @@ -669,11 +668,12 @@ FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile // ParseWideStrings6Data( altiumLibFile, unicodeStringsData ); // } - std::string streamName = aFootprintName.ToStdString() + "\\Data"; + const std::vector streamName{ aFootprintName.ToStdString(), "Data" }; const CFB::COMPOUND_FILE_ENTRY* footprintData = altiumLibFile.FindStream( streamName ); if( footprintData == nullptr ) { - THROW_IO_ERROR( wxString::Format( _( "File not found: '%s'." ), streamName ) ); + THROW_IO_ERROR( + wxString::Format( _( "File not found: '%s'." ), FormatPath( streamName ) ) ); } ALTIUM_PARSER parser( altiumLibFile, footprintData ); @@ -685,7 +685,8 @@ FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile LIB_ID fpID = AltiumToKiCadLibID( "", footprintName ); // TODO: library name footprint->SetFPID( fpID ); - std::string parametersStreamName = aFootprintName.ToStdString() + "\\Parameters"; + const std::vector parametersStreamName{ aFootprintName.ToStdString(), + "Parameters" }; const CFB::COMPOUND_FILE_ENTRY* parametersData = altiumLibFile.FindStream( parametersStreamName ); if( parametersData != nullptr ) @@ -698,10 +699,20 @@ FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile } else { - wxLogError( _( "File not found: '%s'." ), parametersStreamName ); + wxLogError( _( "File not found: '%s'." ), FormatPath( parametersStreamName ) ); footprint->SetDescription( wxT( "" ) ); } + const std::vector extendedPrimitiveInformationStreamName{ + aFootprintName.ToStdString(), "ExtendedPrimitiveInformation", "Data" + }; + const CFB::COMPOUND_FILE_ENTRY* extendedPrimitiveInformationData = + altiumLibFile.FindStream( extendedPrimitiveInformationStreamName ); + if( extendedPrimitiveInformationData != nullptr ) + { + // TODO: implement + } + footprint->SetReference( wxT( "REF**" ) ); footprint->SetValue( footprintName ); footprint->Reference().SetVisible( true ); // TODO: extract visibility information @@ -767,12 +778,14 @@ FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile if( parser.HasParsingError() ) { - THROW_IO_ERROR( wxString::Format( wxT( "%s stream was not parsed correctly" ), streamName ) ); + THROW_IO_ERROR( wxString::Format( wxT( "%s stream was not parsed correctly" ), + FormatPath( streamName ) ) ); } if( parser.GetRemainingBytes() != 0 ) { - THROW_IO_ERROR( wxString::Format( wxT( "%s stream is not fully parsed" ), streamName ) ); + THROW_IO_ERROR( wxString::Format( wxT( "%s stream is not fully parsed" ), + FormatPath( streamName ) ) ); } return footprint.release(); @@ -1156,9 +1169,10 @@ void ALTIUM_PCB::ParseComponentsBodies6Data( const ALTIUM_COMPOUND_FILE& aAl if( modelTuple == m_models.end() ) { - THROW_IO_ERROR( wxString::Format( wxT( "ComponentsBodies6 stream tries to access " - "model id %s which does not exist" ), - elem.modelId ) ); + wxLogError( wxT( "ComponentsBodies6 stream tries to access model id %s which does not " + "exist" ), + elem.modelId ); + continue; } FOOTPRINT* footprint = m_components.at( elem.component ); @@ -1538,7 +1552,8 @@ void ALTIUM_PCB::ParseDimensions6Data( const ALTIUM_COMPOUND_FILE& aAltiumPc void ALTIUM_PCB::ParseModelsData( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile, - const CFB::COMPOUND_FILE_ENTRY* aEntry, const wxString& aRootDir ) + const CFB::COMPOUND_FILE_ENTRY* aEntry, + const std::vector& aRootDir ) { if( m_progressReporter ) m_progressReporter->Report( _( "Loading 3D models..." ) ); @@ -1583,7 +1598,9 @@ void ALTIUM_PCB::ParseModelsData( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile checkpoint(); AMODEL elem( reader ); - wxString stepPath = wxString::Format( aRootDir + wxT( "%d" ), idx ); + std::vector stepPath = aRootDir; + stepPath.emplace_back( std::to_string( idx ) ); + bool validName = !elem.name.IsEmpty() && elem.name.IsAscii() && wxString::npos == elem.name.find_first_of( invalidChars ); wxString storageName = !validName ? wxString::Format( wxT( "model_%d" ), idx ) @@ -1592,12 +1609,12 @@ void ALTIUM_PCB::ParseModelsData( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile idx++; - const CFB::COMPOUND_FILE_ENTRY* stepEntry = - aAltiumPcbFile.FindStream( stepPath.ToStdString() ); + const CFB::COMPOUND_FILE_ENTRY* stepEntry = aAltiumPcbFile.FindStream( stepPath ); if( stepEntry == nullptr ) { - wxLogError( _( "File not found: '%s'. 3D-model not imported." ), stepPath ); + wxLogError( _( "File not found: '%s'. 3D-model not imported." ), + FormatPath( stepPath ) ); continue; } diff --git a/pcbnew/plugins/altium/altium_pcb.h b/pcbnew/plugins/altium/altium_pcb.h index 486f6c2d4c..a383764dad 100644 --- a/pcbnew/plugins/altium/altium_pcb.h +++ b/pcbnew/plugins/altium/altium_pcb.h @@ -136,7 +136,8 @@ private: void ParseDimensions6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY* aEntry ); void ParseModelsData( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile, - const CFB::COMPOUND_FILE_ENTRY* aEntry, const wxString& aRootDir ); + const CFB::COMPOUND_FILE_ENTRY* aEntry, + const std::vector& aRootDir ); void ParseNets6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY* aEntry ); void ParsePolygons6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile,