diff --git a/pcbnew/plugins/altium/altium_circuit_maker_plugin.cpp b/pcbnew/plugins/altium/altium_circuit_maker_plugin.cpp index 9c03d0a21a..fd7cedaf81 100644 --- a/pcbnew/plugins/altium/altium_circuit_maker_plugin.cpp +++ b/pcbnew/plugins/altium/altium_circuit_maker_plugin.cpp @@ -78,28 +78,28 @@ 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\\Data" }, - { ALTIUM_PCB_DIR::BOARD6, "96B09F5C6CEE434FBCE0DEB3E88E70\\Data" }, - { ALTIUM_PCB_DIR::BOARDREGIONS, "E3A544335C30403A991912052C936F\\Data" }, - { ALTIUM_PCB_DIR::CLASSES6, "4F71DD45B09143988210841EA1C28D\\Data" }, - { ALTIUM_PCB_DIR::COMPONENTS6, "F9D060ACC7DD4A85BC73CB785BAC81\\Data" }, - { ALTIUM_PCB_DIR::COMPONENTBODIES6, "44D9487C98CE4F0EB46AB6E9CDAF40\\Data" }, // or: A0DB41FBCB0D49CE8C32A271AA7EF5 ? - { ALTIUM_PCB_DIR::DIMENSIONS6, "068B9422DBB241258BA2DE9A6BA1A6\\Data" }, - { ALTIUM_PCB_DIR::FILLS6, "6FFE038462A940E9B422EFC8F5D85E\\Data" }, - { ALTIUM_PCB_DIR::MODELS, "0DB009C021D946C88F1B3A32DAE94B\\Data" }, - { ALTIUM_PCB_DIR::NETS6, "35D7CF51BB9B4875B3A138B32D80DC\\Data" }, - { ALTIUM_PCB_DIR::PADS6, "4F501041A9BC4A06BDBDAB67D3820E\\Data" }, - { ALTIUM_PCB_DIR::POLYGONS6, "A1931C8B0B084A61AA45146575FDD3\\Data" }, - { ALTIUM_PCB_DIR::REGIONS6, "F513A5885418472886D3EF18A09E46\\Data" }, - { ALTIUM_PCB_DIR::RULES6, "C27718A40C94421388FAE5BD7785D7\\Data" }, - { ALTIUM_PCB_DIR::SHAPEBASEDREGIONS6,"BDAA2C70289849078C8EBEEC7F0848\\Data" }, - { ALTIUM_PCB_DIR::TEXTS6, "A34BC67C2A5F408D8F377378C5C5E2\\Data" }, - { ALTIUM_PCB_DIR::TRACKS6, "412A754DBB864645BF01CD6A80C358\\Data" }, - { ALTIUM_PCB_DIR::VIAS6, "C87A685A0EFA4A90BEEFD666198B56\\Data" } + { 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\\" } }; // clang-format on - ParseAltiumPcb( m_board, aFileName, mapping ); + ParseAltiumPcb( m_board, aFileName, aProgressReporter, mapping ); return m_board; } diff --git a/pcbnew/plugins/altium/altium_circuit_studio_plugin.cpp b/pcbnew/plugins/altium/altium_circuit_studio_plugin.cpp index 5be855d1d8..3ccd1ef1e8 100644 --- a/pcbnew/plugins/altium/altium_circuit_studio_plugin.cpp +++ b/pcbnew/plugins/altium/altium_circuit_studio_plugin.cpp @@ -78,28 +78,28 @@ 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\\Data" }, - { ALTIUM_PCB_DIR::BOARD6, "88857D7F1DF64F7BBB61848C965636\\Data" }, - { ALTIUM_PCB_DIR::BOARDREGIONS, "8957CF30F167408D9D263D23FE7C89\\Data" }, - { ALTIUM_PCB_DIR::CLASSES6, "847EFBF87A5149B1AA326A52AD6357\\Data" }, - { ALTIUM_PCB_DIR::COMPONENTS6, "465416896A15486999A39C643935D2\\Data" }, - { ALTIUM_PCB_DIR::COMPONENTBODIES6, "1849D9B5512D452A93EABF4E40B122\\Data" }, // or B6AD30D75241498BA2536EBF001752 ? - { ALTIUM_PCB_DIR::DIMENSIONS6, "16C81DBC13C447FF8B42A426677F3C\\Data" }, - { ALTIUM_PCB_DIR::FILLS6, "4E83BDC3253747F08E9006D7F57020\\Data" }, - { ALTIUM_PCB_DIR::MODELS, "C0F7599ECC6A4D648DF5BB557679AF\\Data" }, - { ALTIUM_PCB_DIR::NETS6, "D95A0DA2FE9047779A5194C127F30B\\Data" }, - { ALTIUM_PCB_DIR::PADS6, "47D69BC5107A4B8DB8DAA23E39C238\\Data" }, - { ALTIUM_PCB_DIR::POLYGONS6, "D7038392280E4E229B9D9B5426B295\\Data" }, - { ALTIUM_PCB_DIR::REGIONS6, "FFDDC21382BB42FE8A7D0C328D272C\\Data" }, - { ALTIUM_PCB_DIR::RULES6, "48B2FA96DB7546818752B34373D6C6\\Data" }, - { ALTIUM_PCB_DIR::SHAPEBASEDREGIONS6, "D5F54B536E124FB89E2D51B1121508\\Data" }, - { ALTIUM_PCB_DIR::TEXTS6, "349ABBB211DB4F5B8AE41B1B49555A\\Data" }, - { ALTIUM_PCB_DIR::TRACKS6, "530C20C225354B858B2578CAB8C08D\\Data" }, - { ALTIUM_PCB_DIR::VIAS6, "CA5F5989BCDB404DA70A9D1D3D5758\\Data" } + { 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\\" } }; // clang-format on - ParseAltiumPcb( m_board, aFileName, mapping ); + ParseAltiumPcb( m_board, aFileName, aProgressReporter, mapping ); return m_board; } diff --git a/pcbnew/plugins/altium/altium_designer_plugin.cpp b/pcbnew/plugins/altium/altium_designer_plugin.cpp index 8796a9dcac..450a658419 100644 --- a/pcbnew/plugins/altium/altium_designer_plugin.cpp +++ b/pcbnew/plugins/altium/altium_designer_plugin.cpp @@ -78,28 +78,28 @@ 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\\Data" }, - { ALTIUM_PCB_DIR::BOARD6, "Board6\\Data" }, - { ALTIUM_PCB_DIR::BOARDREGIONS, "BoardRegions\\Data" }, - { ALTIUM_PCB_DIR::CLASSES6, "Classes6\\Data" }, - { ALTIUM_PCB_DIR::COMPONENTS6, "Components6\\Data" }, - { ALTIUM_PCB_DIR::COMPONENTBODIES6, "ComponentBodies6\\Data" }, - { ALTIUM_PCB_DIR::DIMENSIONS6, "Dimensions6\\Data" }, - { ALTIUM_PCB_DIR::FILLS6, "Fills6\\Data" }, - { ALTIUM_PCB_DIR::MODELS, "Models\\Data" }, - { ALTIUM_PCB_DIR::NETS6, "Nets6\\Data" }, - { ALTIUM_PCB_DIR::PADS6, "Pads6\\Data" }, - { ALTIUM_PCB_DIR::POLYGONS6, "Polygons6\\Data" }, - { ALTIUM_PCB_DIR::REGIONS6, "Regions6\\Data" }, - { ALTIUM_PCB_DIR::RULES6, "Rules6\\Data" }, - { ALTIUM_PCB_DIR::SHAPEBASEDREGIONS6, "ShapeBasedRegions6\\Data" }, - { ALTIUM_PCB_DIR::TEXTS6, "Texts6\\Data" }, - { ALTIUM_PCB_DIR::TRACKS6, "Tracks6\\Data" }, - { ALTIUM_PCB_DIR::VIAS6, "Vias6\\Data" } + { 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::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\\" } }; // clang-format on - ParseAltiumPcb( m_board, aFileName, mapping ); + ParseAltiumPcb( m_board, aFileName, aProgressReporter, mapping ); return m_board; } diff --git a/pcbnew/plugins/altium/altium_pcb.cpp b/pcbnew/plugins/altium/altium_pcb.cpp index 38cd1fd0bc..31d7ddf84a 100644 --- a/pcbnew/plugins/altium/altium_pcb.cpp +++ b/pcbnew/plugins/altium/altium_pcb.cpp @@ -51,9 +51,10 @@ #include #include #include +#include -void ParseAltiumPcb( BOARD* aBoard, const wxString& aFileName, +void ParseAltiumPcb( BOARD* aBoard, const wxString& aFileName, PROGRESS_REPORTER* aProgressReporter, const std::map& aFileMapping ) { // Open file @@ -90,7 +91,7 @@ void ParseAltiumPcb( BOARD* aBoard, const wxString& aFileName, CFB::CompoundFileReader reader( buffer.get(), bytesRead ); // Parse File - ALTIUM_PCB pcb( aBoard ); + ALTIUM_PCB pcb( aBoard, aProgressReporter ); pcb.Parse( reader, aFileMapping ); } catch( CFB::CFBException& exception ) @@ -309,9 +310,13 @@ PCB_LAYER_ID ALTIUM_PCB::GetKicadLayer( ALTIUM_LAYER aAltiumLayer ) const } -ALTIUM_PCB::ALTIUM_PCB( BOARD* aBoard ) +ALTIUM_PCB::ALTIUM_PCB( BOARD* aBoard, PROGRESS_REPORTER* aProgressReporter ) { m_board = aBoard; + m_progressReporter = aProgressReporter; + m_doneCount = 0; + m_lastProgressCount = 0; + m_totalCount = 0; m_num_nets = 0; m_highest_pour_index = 0; } @@ -320,6 +325,25 @@ ALTIUM_PCB::~ALTIUM_PCB() { } +void ALTIUM_PCB::checkpoint() +{ + const unsigned PROGRESS_DELTA = 250; + + if( m_progressReporter ) + { + if( ++m_doneCount > m_lastProgressCount + PROGRESS_DELTA ) + { + m_progressReporter->SetCurrentProgress( ( (double) m_doneCount ) + / std::max( 1U, m_totalCount ) ); + + if( !m_progressReporter->KeepRefreshing() ) + THROW_IO_ERROR( ( "Open cancelled by user." ) ); + + m_lastProgressCount = m_doneCount; + } + } +} + void ALTIUM_PCB::Parse( const CFB::CompoundFileReader& aReader, const std::map& aFileMapping ) { @@ -340,7 +364,6 @@ void ALTIUM_PCB::Parse( const CFB::CompoundFileReader& aReader, { true, ALTIUM_PCB_DIR::MODELS, [this, aFileMapping]( auto aReader, auto fileHeader ) { wxString dir( aFileMapping.at( ALTIUM_PCB_DIR::MODELS ) ); - dir.RemoveLast( 4 ); // Remove "Data" from the path this->ParseModelsData( aReader, fileHeader, dir ); } }, { true, ALTIUM_PCB_DIR::COMPONENTBODIES6, @@ -405,6 +428,51 @@ void ALTIUM_PCB::Parse( const CFB::CompoundFileReader& aReader, } } }; + if( m_progressReporter != nullptr ) + { + // Count number of records we will read for the progress reporter + for( const std::tuple& cur : parserOrder ) + { + bool isRequired; + ALTIUM_PCB_DIR directory; + PARSE_FUNCTION_POINTER_fp fp; + std::tie( isRequired, directory, fp ) = cur; + + if( directory == ALTIUM_PCB_DIR::FILE_HEADER ) + { + continue; + } + + const auto& mappedDirectory = aFileMapping.find( directory ); + if( mappedDirectory == aFileMapping.end() ) + { + continue; + } + + std::string mappedFile = mappedDirectory->second + "Header"; + + const CFB::COMPOUND_FILE_ENTRY* file = FindStream( aReader, mappedFile.c_str() ); + if( file == nullptr ) + { + continue; + } + + ALTIUM_PARSER reader( aReader, file ); + uint32_t numOfRecords = reader.Read(); + if( reader.HasParsingError() ) + { + wxLogError( "'%s' was not parsed correctly", mappedFile ); + continue; + } + m_totalCount += numOfRecords; + if( reader.GetRemainingBytes() != 0 ) + { + wxLogError( "'%s' is not fully parsed", mappedFile ); + continue; + } + } + } + // Parse data in specified order for( const std::tuple& cur : parserOrder ) { @@ -422,15 +490,20 @@ void ALTIUM_PCB::Parse( const CFB::CompoundFileReader& aReader, continue; } - const CFB::COMPOUND_FILE_ENTRY* file = - FindStream( aReader, mappedDirectory->second.c_str() ); + std::string mappedFile = mappedDirectory->second; + if( directory != ALTIUM_PCB_DIR::FILE_HEADER ) + { + mappedFile += "Data"; + } + + const CFB::COMPOUND_FILE_ENTRY* file = FindStream( aReader, mappedFile.c_str() ); if( file != nullptr ) { fp( aReader, file ); } else if( isRequired ) { - wxLogError( wxString::Format( _( "File not found: '%s'" ), mappedDirectory->second ) ); + wxLogError( wxString::Format( _( "File not found: '%s'" ), mappedFile ) ); } } @@ -551,8 +624,12 @@ void ALTIUM_PCB::ParseFileHeader( const CFB::CompoundFileReader& aReader, void ALTIUM_PCB::ParseBoard6Data( const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry ) { + if( m_progressReporter ) + m_progressReporter->Report( "Parse: Board Data" ); + ALTIUM_PARSER reader( aReader, aEntry ); + checkpoint(); ABOARD6 elem( reader ); if( reader.GetRemainingBytes() != 0 ) @@ -756,10 +833,14 @@ void ALTIUM_PCB::HelperCreateBoardOutline( const std::vector& aV void ALTIUM_PCB::ParseClasses6Data( const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry ) { + if( m_progressReporter ) + m_progressReporter->Report( "Parse: Net Classes" ); + ALTIUM_PARSER reader( aReader, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { + checkpoint(); ACLASS6 elem( reader ); if( elem.kind == ALTIUM_CLASS_KIND::NET_CLASS ) @@ -792,11 +873,15 @@ void ALTIUM_PCB::ParseClasses6Data( const CFB::CompoundFileReader& aReader, void ALTIUM_PCB::ParseComponents6Data( const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry ) { + if( m_progressReporter ) + m_progressReporter->Report( "Parse: Components" ); + ALTIUM_PARSER reader( aReader, aEntry ); uint16_t componentId = 0; while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { + checkpoint(); ACOMPONENT6 elem( reader ); FOOTPRINT* footprint = new FOOTPRINT( m_board ); @@ -835,10 +920,14 @@ void ALTIUM_PCB::ParseComponents6Data( const CFB::CompoundFileReader& aReader, void ALTIUM_PCB::ParseComponentsBodies6Data( const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry ) { + if( m_progressReporter ) + m_progressReporter->Report( "Parse: Components 3D Models" ); + ALTIUM_PARSER reader( aReader, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { + checkpoint(); ACOMPONENTBODY6 elem( reader ); // TODO: implement if( elem.component == ALTIUM_COMPONENT_NONE ) @@ -1114,10 +1203,14 @@ void ALTIUM_PCB::HelperParseDimensions6Center( const ADIMENSION6& aElem ) void ALTIUM_PCB::ParseDimensions6Data( const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry ) { + if( m_progressReporter ) + m_progressReporter->Report( "Parse: Dimension Drawings" ); + ALTIUM_PARSER reader( aReader, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { + checkpoint(); ADIMENSION6 elem( reader ); switch( elem.kind ) @@ -1151,6 +1244,9 @@ void ALTIUM_PCB::ParseDimensions6Data( const CFB::CompoundFileReader& aReader, void ALTIUM_PCB::ParseModelsData( const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry, const wxString aRootDir ) { + if( m_progressReporter ) + m_progressReporter->Report( "Parse: 3D Models" ); + ALTIUM_PARSER reader( aReader, aEntry ); if( reader.GetRemainingBytes() == 0 ) @@ -1187,11 +1283,18 @@ void ALTIUM_PCB::ParseModelsData( const CFB::CompoundFileReader& aReader, int idx = 0; while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { + checkpoint(); AMODEL elem( reader ); wxString stepPath = aRootDir + std::to_string( idx++ ); const CFB::COMPOUND_FILE_ENTRY* stepEntry = FindStream( aReader, stepPath.c_str() ); + if( stepEntry == nullptr ) + { + wxLogError( wxString::Format( _( "File not found: '%s' -> 3D-model not imported." ), + stepPath ) ); + continue; + } size_t stepSize = static_cast( stepEntry->size ); std::unique_ptr stepContent( new char[stepSize] ); @@ -1228,11 +1331,15 @@ void ALTIUM_PCB::ParseModelsData( const CFB::CompoundFileReader& aReader, void ALTIUM_PCB::ParseNets6Data( const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry ) { + if( m_progressReporter ) + m_progressReporter->Report( "Parse: Nets" ); + ALTIUM_PARSER reader( aReader, aEntry ); wxASSERT( m_num_nets == 0 ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { + checkpoint(); ANET6 elem( reader ); m_board->Add( new NETINFO_ITEM( m_board, elem.name, ++m_num_nets ), ADD_MODE::APPEND ); @@ -1247,10 +1354,14 @@ void ALTIUM_PCB::ParseNets6Data( const CFB::CompoundFileReader& aReader, void ALTIUM_PCB::ParsePolygons6Data( const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry ) { + if( m_progressReporter ) + m_progressReporter->Report( "Parse: Polygons" ); + ALTIUM_PARSER reader( aReader, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { + checkpoint(); APOLYGON6 elem( reader ); PCB_LAYER_ID klayer = GetKicadLayer( elem.layer ); @@ -1376,10 +1487,14 @@ void ALTIUM_PCB::ParsePolygons6Data( const CFB::CompoundFileReader& aReader, void ALTIUM_PCB::ParseRules6Data( const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry ) { + if( m_progressReporter ) + m_progressReporter->Report( "Parse: Rules" ); + ALTIUM_PARSER reader( aReader, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { + checkpoint(); ARULE6 elem( reader ); m_rules[elem.kind].emplace_back( elem ); @@ -1404,10 +1519,14 @@ void ALTIUM_PCB::ParseRules6Data( const CFB::CompoundFileReader& aReader, void ALTIUM_PCB::ParseBoardRegionsData( const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry ) { + if( m_progressReporter ) + m_progressReporter->Report( "Parse: Board Regions" ); + ALTIUM_PARSER reader( aReader, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { + checkpoint(); AREGION6 elem( reader, false ); // TODO: implement? @@ -1422,10 +1541,14 @@ void ALTIUM_PCB::ParseBoardRegionsData( const CFB::CompoundFileReader& aReader, void ALTIUM_PCB::ParseShapeBasedRegions6Data( const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry ) { + if( m_progressReporter ) + m_progressReporter->Report( "Parse: Zones" ); + ALTIUM_PARSER reader( aReader, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { + checkpoint(); AREGION6 elem( reader, true ); if( elem.kind == ALTIUM_REGION_KIND::BOARD_CUTOUT ) @@ -1532,6 +1655,9 @@ void ALTIUM_PCB::ParseShapeBasedRegions6Data( const CFB::CompoundFileReader& aRe void ALTIUM_PCB::ParseRegions6Data( const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry ) { + if( m_progressReporter ) + m_progressReporter->Report( "Parse: Zone Fills" ); + ALTIUM_PARSER reader( aReader, aEntry ); for( ZONE* zone : m_polygons ) @@ -1542,6 +1668,7 @@ void ALTIUM_PCB::ParseRegions6Data( const CFB::CompoundFileReader& aReader, while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { + checkpoint(); AREGION6 elem( reader, false ); if( elem.subpolyindex != ALTIUM_POLYGON_NONE ) @@ -1616,10 +1743,14 @@ void ALTIUM_PCB::ParseRegions6Data( const CFB::CompoundFileReader& aReader, void ALTIUM_PCB::ParseArcs6Data( const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry ) { + if( m_progressReporter ) + m_progressReporter->Report( "Parse: Arcs" ); + ALTIUM_PARSER reader( aReader, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { + checkpoint(); AARC6 elem( reader ); if( elem.is_polygonoutline || elem.subpolyindex != ALTIUM_POLYGON_NONE ) @@ -1751,10 +1882,14 @@ void ALTIUM_PCB::ParseArcs6Data( const CFB::CompoundFileReader& aReader, void ALTIUM_PCB::ParsePads6Data( const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry ) { + if( m_progressReporter ) + m_progressReporter->Report( "Parse: Pads" ); + ALTIUM_PARSER reader( aReader, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { + checkpoint(); APAD6 elem( reader ); // It is possible to place altium pads on non-copper layers -> we need to interpolate them using drawings! @@ -2160,10 +2295,14 @@ void ALTIUM_PCB::HelperParsePad6NonCopper( const APAD6& aElem ) void ALTIUM_PCB::ParseVias6Data( const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry ) { + if( m_progressReporter ) + m_progressReporter->Report( "Parse: Vias" ); + ALTIUM_PARSER reader( aReader, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { + checkpoint(); AVIA6 elem( reader ); PCB_VIA* via = new PCB_VIA( m_board ); @@ -2216,10 +2355,14 @@ void ALTIUM_PCB::ParseVias6Data( const CFB::CompoundFileReader& aReader, void ALTIUM_PCB::ParseTracks6Data( const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry ) { + if( m_progressReporter ) + m_progressReporter->Report( "Parse: Tracks" ); + ALTIUM_PARSER reader( aReader, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { + checkpoint(); ATRACK6 elem( reader ); if( elem.is_polygonoutline || elem.subpolyindex != ALTIUM_POLYGON_NONE ) @@ -2318,10 +2461,14 @@ void ALTIUM_PCB::ParseTracks6Data( const CFB::CompoundFileReader& aReader, void ALTIUM_PCB::ParseTexts6Data( const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry ) { + if( m_progressReporter ) + m_progressReporter->Report( "Parse: Text" ); + ALTIUM_PARSER reader( aReader, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { + checkpoint(); ATEXT6 elem( reader ); if( elem.fonttype == ALTIUM_TEXT_TYPE::BARCODE ) @@ -2500,10 +2647,14 @@ void ALTIUM_PCB::ParseTexts6Data( const CFB::CompoundFileReader& aReader, void ALTIUM_PCB::ParseFills6Data( const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry ) { + if( m_progressReporter ) + m_progressReporter->Report( "Parse: Rectangles" ); + ALTIUM_PARSER reader( aReader, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { + checkpoint(); AFILL6 elem( reader ); wxPoint p11( elem.pos1.x, elem.pos1.y ); diff --git a/pcbnew/plugins/altium/altium_pcb.h b/pcbnew/plugins/altium/altium_pcb.h index 9e767b9b6e..ac7b4af364 100644 --- a/pcbnew/plugins/altium/altium_pcb.h +++ b/pcbnew/plugins/altium/altium_pcb.h @@ -85,6 +85,7 @@ class BOARD; class PCB_SHAPE; class FOOTPRINT; class ZONE; +class PROGRESS_REPORTER; /** @@ -94,8 +95,8 @@ class ZONE; * @param aFileName file name of board file * @param aFileMapping mapping how altium stream names are mapped */ -void ParseAltiumPcb( BOARD* aBoard, const wxString& aFileName, - const std::map& aFileMapping ); +void ParseAltiumPcb( BOARD* aBoard, const wxString& aFileName, PROGRESS_REPORTER* aProgressReporter, + const std::map& aFileMapping ); namespace CFB @@ -114,13 +115,15 @@ typedef std::function& aFileMapping ); private: + void checkpoint(); + PCB_LAYER_ID GetKicadLayer( ALTIUM_LAYER aAltiumLayer ) const; int GetNetCode( uint16_t aId ) const; const ARULE6* GetRule( ALTIUM_RULE_KIND aKind, const wxString& aName ) const; @@ -192,6 +195,11 @@ private: std::map m_outer_plane; + PROGRESS_REPORTER* m_progressReporter; ///< optional; may be nullptr + unsigned m_doneCount; + unsigned m_lastProgressCount; + unsigned m_totalCount; ///< for progress reporting + /// Altium stores pour order across all layers int m_highest_pour_index; };