altium: introduce progress reporting, fix possible nullptr when reading 3D models

This commit is contained in:
Thomas Pointhuber 2021-06-26 12:49:58 +02:00
parent 95ec9c786c
commit e6c047896c
5 changed files with 226 additions and 67 deletions

View File

@ -78,28 +78,28 @@ BOARD* ALTIUM_CIRCUIT_MAKER_PLUGIN::Load( const wxString& aFileName, BOARD* aApp
// clang-format off
const std::map<ALTIUM_PCB_DIR, std::string> 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;
}

View File

@ -78,28 +78,28 @@ BOARD* ALTIUM_CIRCUIT_STUDIO_PLUGIN::Load( const wxString& aFileName, BOARD* aAp
// clang-format off
const std::map<ALTIUM_PCB_DIR, std::string> 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;
}

View File

@ -78,28 +78,28 @@ BOARD* ALTIUM_DESIGNER_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendTo
// clang-format off
const std::map<ALTIUM_PCB_DIR, std::string> 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;
}

View File

@ -51,9 +51,10 @@
#include <wx/mstream.h>
#include <wx/wfstream.h>
#include <wx/zstream.h>
#include <widgets/progress_reporter.h>
void ParseAltiumPcb( BOARD* aBoard, const wxString& aFileName,
void ParseAltiumPcb( BOARD* aBoard, const wxString& aFileName, PROGRESS_REPORTER* aProgressReporter,
const std::map<ALTIUM_PCB_DIR, std::string>& 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<ALTIUM_PCB_DIR, std::string>& 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<bool, ALTIUM_PCB_DIR, PARSE_FUNCTION_POINTER_fp>& 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<uint32_t>();
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<bool, ALTIUM_PCB_DIR, PARSE_FUNCTION_POINTER_fp>& 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<ALTIUM_VERTICE>& 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<size_t>( stepEntry->size );
std::unique_ptr<char[]> 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 );

View File

@ -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<ALTIUM_PCB_DIR, std::string>& aFileMapping );
void ParseAltiumPcb( BOARD* aBoard, const wxString& aFileName, PROGRESS_REPORTER* aProgressReporter,
const std::map<ALTIUM_PCB_DIR, std::string>& aFileMapping );
namespace CFB
@ -114,13 +115,15 @@ typedef std::function<void( const CFB::CompoundFileReader&, const CFB::COMPOUND_
class ALTIUM_PCB
{
public:
explicit ALTIUM_PCB( BOARD* aBoard );
explicit ALTIUM_PCB( BOARD* aBoard, PROGRESS_REPORTER* aProgressReporter );
~ALTIUM_PCB();
void Parse( const CFB::CompoundFileReader& aReader,
const std::map<ALTIUM_PCB_DIR, std::string>& 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<ALTIUM_LAYER, ZONE*> 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;
};