7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-18 16:09:18 +00:00

Fix issue with model parsing

Sometimes we don't get the data elements in order.  Use the stream name
to ensure we have the correct model.

Also give the parser a bit more memory to work with, avoiding unneeded
resizes
This commit is contained in:
Seth Hillbrand 2024-07-16 17:39:49 -07:00
parent c093fe1355
commit 16f41a832c
3 changed files with 1329 additions and 123 deletions
pcbnew/pcb_io/altium
qa/data/pcbnew/plugins/altium/pcblib/Espressif ESP32-WROOM-32.pretty

View File

@ -1345,20 +1345,33 @@ void ALTIUM_PCB::ConvertComponentBody6ToFootprintItem( const ALTIUM_PCB_COMPOUND
EMBEDDED_FILES::EMBEDDED_FILE* file = new EMBEDDED_FILES::EMBEDDED_FILE();
file->name = aElem.modelName;
// Decompress the model data before assigning
std::vector<char> decompressedData;
wxMemoryInputStream compressedStream(model->second.data(), model->second.size());
wxZlibInputStream zlibStream(compressedStream);
decompressedData.reserve(model->second.size() * 2); // Reserve some space, assuming decompressed data is larger
while (!zlibStream.Eof()) {
size_t currentSize = decompressedData.size();
decompressedData.resize(currentSize + 4096); // Increase buffer size
zlibStream.Read(decompressedData.data() + currentSize, 4096);
// Decompress the model data before assigning
std::vector<char> decompressedData;
wxMemoryInputStream compressedStream( model->second.data(), model->second.size() );
wxZlibInputStream zlibStream( compressedStream );
// Reserve some space, assuming decompressed data is larger -- STEP file
// compression is typically 5:1 using zlib like Altium does
decompressedData.resize( model->second.size() * 6 );
size_t offset = 0;
while( !zlibStream.Eof() )
{
zlibStream.Read( decompressedData.data() + offset, decompressedData.size() - offset );
size_t bytesRead = zlibStream.LastRead();
decompressedData.resize(currentSize + bytesRead); // Resize to actual read size
if( !bytesRead )
break;
offset += bytesRead;
if( offset >= decompressedData.size() )
decompressedData.resize( 2 * decompressedData.size() ); // Resizing is expensive, avoid if we can
}
decompressedData.resize( offset );
file->decompressedData = std::move( decompressedData );
file->type = EMBEDDED_FILES::EMBEDDED_FILE::FILE_TYPE::MODEL;
@ -1369,8 +1382,8 @@ void ALTIUM_PCB::ConvertComponentBody6ToFootprintItem( const ALTIUM_PCB_COMPOUND
modelSettings.m_Filename = aFootprint->GetEmbeddedFiles()->GetEmbeddedFileLink( *file );
modelSettings.m_Offset.x = pcbIUScale.IUTomm((int) aElem.modelPosition.x - fpPosition.x );
modelSettings.m_Offset.y = -pcbIUScale.IUTomm((int) aElem.modelPosition.y - fpPosition.y );
modelSettings.m_Offset.x = pcbIUScale.IUTomm( (int) aElem.modelPosition.x - fpPosition.x );
modelSettings.m_Offset.y = -pcbIUScale.IUTomm( (int) aElem.modelPosition.y - fpPosition.y );
modelSettings.m_Offset.z = pcbIUScale.IUTomm( (int) aElem.modelPosition.z + model->first.z_offset );
EDA_ANGLE orientation = aFootprint->GetOrientation();

View File

@ -155,33 +155,37 @@ bool ALTIUM_PCB_COMPOUND_FILE::CacheLibModels()
if( !models_root )
return false;
int idx = 0;
m_reader->EnumFiles(
models_root, 1,
[&]( const CFB::COMPOUND_FILE_ENTRY* stepEntry, const CFB::utf16string&, int ) -> int
{
long fileNumber;
wxString fileName = UTF16ToUTF8( stepEntry->name, stepEntry->nameLen );
m_reader->EnumFiles( models_root, 1, [&]( const CFB::COMPOUND_FILE_ENTRY* stepEntry, const CFB::utf16string&, int ) -> int
{
wxString fileName = UTF16ToUTF8( stepEntry->name, stepEntry->nameLen );
if( !fileName.ToLong( &fileNumber ) )
return 0;
if( !m_reader->IsStream( stepEntry ) || idx >= models.size() )
if( !m_reader->IsStream( stepEntry ) || fileNumber >= long( models.size() ) )
return 0;
size_t stepSize = static_cast<size_t>( stepEntry->size );
std::vector<char> stepContent( stepSize );
// read file into buffer
m_reader->ReadFile( stepEntry, 0, stepContent.data(), stepSize );
if( stepContent.empty() )
return 0;
// We store the models in their original compressed form so as to speed the caching process
// When we parse an individual footprint, we decompress and recompress the model data into
// our format
m_libModelsCache.emplace( models[fileNumber].id,
std::make_pair( std::move( models[fileNumber] ),
std::move( stepContent ) ) );
return 0;
size_t stepSize = static_cast<size_t>( stepEntry->size );
std::vector<char> stepContent( stepSize );
// read file into buffer
m_reader->ReadFile( stepEntry, 0, stepContent.data(), stepSize );
if( stepContent.empty() )
return 0;
// We store the models in their original compressed form so as to speed the caching process
// When we parse an individual footprint, we decompress and recompress the model data into
// our format
m_libModelsCache.emplace( models[idx].id, std::make_pair( std::move( models[idx] ),
std::move( stepContent ) ) );
idx++;
return 0;
} );
} );
return true;
}