Report fp library loading errors with libName & fpName.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/16975

(cherry picked from commit 12922d9434)
This commit is contained in:
Jeff Young 2024-02-19 12:24:13 +00:00 committed by Roberto Fernandez Bautista
parent 17a37a55f0
commit 5c026db27a
3 changed files with 174 additions and 41 deletions

View File

@ -262,14 +262,17 @@ std::vector<PCB_LAYER_ID> ALTIUM_PCB::GetKicadLayersToIterate( ALTIUM_LAYER aAlt
} }
ALTIUM_PCB::ALTIUM_PCB( BOARD* aBoard, PROGRESS_REPORTER* aProgressReporter ) ALTIUM_PCB::ALTIUM_PCB( BOARD* aBoard, PROGRESS_REPORTER* aProgressReporter,
const wxString& aLibrary, const wxString& aFootprintName )
{ {
m_board = aBoard; m_board = aBoard;
m_progressReporter = aProgressReporter; m_progressReporter = aProgressReporter;
m_doneCount = 0; m_doneCount = 0;
m_lastProgressCount = 0; m_lastProgressCount = 0;
m_totalCount = 0; m_totalCount = 0;
m_highest_pour_index = 0; m_highest_pour_index = 0;
m_library = aLibrary;
m_footprintName = aFootprintName;
} }
ALTIUM_PCB::~ALTIUM_PCB() ALTIUM_PCB::~ALTIUM_PCB()
@ -2134,10 +2137,23 @@ void ALTIUM_PCB::ConvertShapeBasedRegions6ToFootprintItem( FOOTPRINT* aFoot
if( klayer == UNDEFINED_LAYER ) if( klayer == UNDEFINED_LAYER )
{ {
wxLogWarning( if( !m_footprintName.IsEmpty() )
_( "Dashed outline found on an Altium layer (%d) with no KiCad equivalent. " {
"It has been moved to KiCad layer Eco1_User." ), wxLogWarning( _( "Loading library '%s':\n"
aElem.layer ); "Footprint %s contains a dashed outline on Altium layer (%d) with "
"no KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
m_library,
m_footprintName,
aElem.layer );
}
else
{
wxLogWarning( _( "Footprint %s contains a dashed outline on Altium layer (%d) with "
"no KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
aFootprint->GetReference(),
aElem.layer );
}
klayer = Eco1_User; klayer = Eco1_User;
} }
@ -2168,7 +2184,20 @@ void ALTIUM_PCB::ConvertShapeBasedRegions6ToFootprintItem( FOOTPRINT* aFoot
} }
else else
{ {
wxLogError( _( "Ignored polygon shape of kind %d (not yet supported)." ), aElem.kind ); if( !m_footprintName.IsEmpty() )
{
wxLogError( _( "Error loading library '%s':\n"
"Footprint %s contains polygon shape of kind %d (not yet supported)." ),
m_library,
m_footprintName,
aElem.kind );
}
else
{
wxLogError( _( "Footprint %s contains polygon shape of kind %d (not yet supported)." ),
aFootprint->GetReference(),
aElem.kind );
}
} }
} }
@ -2721,9 +2750,20 @@ void ALTIUM_PCB::ConvertPads6ToFootprintItemOnCopper( FOOTPRINT* aFootprint, con
if( aElem.layer != ALTIUM_LAYER::MULTI_LAYER ) if( aElem.layer != ALTIUM_LAYER::MULTI_LAYER )
{ {
// TODO: I assume other values are possible as well? // TODO: I assume other values are possible as well?
wxLogError( _( "Footprint %s pad %s is not marked as multilayer, but is a TH pad." ), if( !m_footprintName.IsEmpty() )
aFootprint->GetReference(), {
aElem.name ); wxLogError( _( "Error loading library '%s':\n"
"Footprint %s pad %s is not marked as multilayer, but is a TH pad." ),
m_library,
m_footprintName,
aElem.name );
}
else
{
wxLogError( _( "Footprint %s pad %s is not marked as multilayer, but is a TH pad." ),
aFootprint->GetReference(),
aElem.name );
}
} }
pad->SetAttribute( aElem.plated ? PAD_ATTRIB::PTH : PAD_ATTRIB::NPTH ); pad->SetAttribute( aElem.plated ? PAD_ATTRIB::PTH : PAD_ATTRIB::NPTH );
@ -2742,9 +2782,20 @@ void ALTIUM_PCB::ConvertPads6ToFootprintItemOnCopper( FOOTPRINT* aFootprint, con
break; break;
case ALTIUM_PAD_HOLE_SHAPE::SQUARE: case ALTIUM_PAD_HOLE_SHAPE::SQUARE:
wxLogWarning( _( "Footprint %s pad %s has a square hole (not yet supported)." ), if( !m_footprintName.IsEmpty() )
aFootprint->GetReference(), {
aElem.name ); wxLogWarning( _( "Loading library '%s':\n"
"Footprint %s pad %s has a square hole (not yet supported)." ),
m_library,
m_footprintName,
aElem.name );
}
else
{
wxLogWarning( _( "Footprint %s pad %s has a square hole (not yet supported)." ),
aFootprint->GetReference(),
aElem.name );
}
pad->SetDrillShape( PAD_DRILL_SHAPE_T::PAD_DRILL_SHAPE_CIRCLE ); pad->SetDrillShape( PAD_DRILL_SHAPE_T::PAD_DRILL_SHAPE_CIRCLE );
pad->SetDrillSize( VECTOR2I( aElem.holesize, aElem.holesize ) ); // Workaround pad->SetDrillSize( VECTOR2I( aElem.holesize, aElem.holesize ) ); // Workaround
@ -2769,11 +2820,24 @@ void ALTIUM_PCB::ConvertPads6ToFootprintItemOnCopper( FOOTPRINT* aFootprint, con
} }
else else
{ {
wxLogWarning( _( "Footprint %s pad %s has a hole-rotation of %f degrees. " if( !m_footprintName.IsEmpty() )
"KiCad only supports 90 degree rotations." ), {
aFootprint->GetReference(), wxLogWarning( _( "Loading library '%s':\n"
aElem.name, "Footprint %s pad %s has a hole-rotation of %f degrees. "
slotRotation.AsDegrees() ); "KiCad only supports 90 degree rotations." ),
m_library,
m_footprintName,
aElem.name,
slotRotation.AsDegrees() );
}
else
{
wxLogWarning( _( "Footprint %s pad %s has a hole-rotation of %f degrees. "
"KiCad only supports 90 degree rotations." ),
aFootprint->GetReference(),
aElem.name,
slotRotation.AsDegrees() );
}
} }
break; break;
@ -2781,10 +2845,22 @@ void ALTIUM_PCB::ConvertPads6ToFootprintItemOnCopper( FOOTPRINT* aFootprint, con
default: default:
case ALTIUM_PAD_HOLE_SHAPE::UNKNOWN: case ALTIUM_PAD_HOLE_SHAPE::UNKNOWN:
wxLogError( _( "Footprint %s pad %s uses a hole of unknown kind %d." ), if( !m_footprintName.IsEmpty() )
aFootprint->GetReference(), {
aElem.name, wxLogError( _( "Error loading library '%s':\n"
aElem.sizeAndShape->holeshape ); "Footprint %s pad %s uses a hole of unknown kind %d." ),
m_library,
m_footprintName,
aElem.name,
aElem.sizeAndShape->holeshape );
}
else
{
wxLogError( _( "Footprint %s pad %s uses a hole of unknown kind %d." ),
aFootprint->GetReference(),
aElem.name,
aElem.sizeAndShape->holeshape );
}
pad->SetDrillShape( PAD_DRILL_SHAPE_T::PAD_DRILL_SHAPE_CIRCLE ); pad->SetDrillShape( PAD_DRILL_SHAPE_T::PAD_DRILL_SHAPE_CIRCLE );
pad->SetDrillSize( VECTOR2I( aElem.holesize, aElem.holesize ) ); // Workaround pad->SetDrillSize( VECTOR2I( aElem.holesize, aElem.holesize ) ); // Workaround
@ -2798,8 +2874,20 @@ void ALTIUM_PCB::ConvertPads6ToFootprintItemOnCopper( FOOTPRINT* aFootprint, con
if( aElem.padmode != ALTIUM_PAD_MODE::SIMPLE ) if( aElem.padmode != ALTIUM_PAD_MODE::SIMPLE )
{ {
wxLogError( _( "Footprint %s pad %s uses a complex pad stack (not yet supported.)" ), if( !m_footprintName.IsEmpty() )
aFootprint->GetReference(), aElem.name ); {
wxLogError( _( "Error loading library '%s':\n"
"Footprint %s pad %s uses a complex pad stack (not yet supported)." ),
m_library,
m_footprintName,
aElem.name );
}
else
{
wxLogError( _( "Footprint %s pad %s uses a complex pad stack (not yet supported)." ),
aFootprint->GetReference(),
aElem.name );
}
} }
switch( aElem.topshape ) switch( aElem.topshape )
@ -2835,8 +2923,20 @@ void ALTIUM_PCB::ConvertPads6ToFootprintItemOnCopper( FOOTPRINT* aFootprint, con
case ALTIUM_PAD_SHAPE::UNKNOWN: case ALTIUM_PAD_SHAPE::UNKNOWN:
default: default:
wxLogError( _( "Footprint %s pad %s uses an unknown pad-shape." ), if( !m_footprintName.IsEmpty() )
aFootprint->GetReference(), aElem.name ); {
wxLogError( _( "Error loading library '%s':\n"
"Footprint %s pad %s uses an unknown pad-shape." ),
m_library,
m_footprintName,
aElem.name );
}
else
{
wxLogError( _( "Footprint %s pad %s uses an unknown pad-shape." ),
aFootprint->GetReference(),
aElem.name );
}
break; break;
} }
@ -2913,10 +3013,25 @@ void ALTIUM_PCB::ConvertPads6ToFootprintItemOnNonCopper( FOOTPRINT* aFootprint,
if( klayer == UNDEFINED_LAYER ) if( klayer == UNDEFINED_LAYER )
{ {
wxLogWarning( if( !m_footprintName.IsEmpty() )
_( "Non-copper pad %s found on an Altium layer (%d) with no KiCad equivalent. " {
"It has been moved to KiCad layer Eco1_User." ), wxLogWarning( _( "Loading library '%s':\n"
aElem.name, aElem.layer ); "Footprint %s non-copper pad %s found on an Altium layer (%d) with no "
"KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
m_library,
m_footprintName,
aElem.name,
aElem.layer );
}
else
{
wxLogWarning( _( "Footprint %s non-copper pad %s found on an Altium layer (%d) with no "
"KiCad equivalent. It has been moved to KiCad layer Eco1_User." ),
aFootprint->GetReference(),
aElem.name,
aElem.layer );
}
klayer = Eco1_User; klayer = Eco1_User;
} }
@ -3420,7 +3535,21 @@ void ALTIUM_PCB::ConvertTexts6ToFootprintItem( FOOTPRINT* aFootprint, const ATEX
{ {
if( aElem.fonttype == ALTIUM_TEXT_TYPE::BARCODE ) if( aElem.fonttype == ALTIUM_TEXT_TYPE::BARCODE )
{ {
wxLogError( _( "Ignored barcode on Altium layer %d (not yet supported)." ), aElem.layer ); if( !m_footprintName.IsEmpty() )
{
wxLogError( _( "Error loading library '%s':\n"
"Footprint %s contains barcode on Altium layer %d (not yet supported)." ),
m_library,
m_footprintName,
aElem.layer );
}
else
{
wxLogError( _( "Footprint %s contains barcode on Altium layer %d (not yet supported)." ),
aFootprint->GetReference(),
aElem.layer );
}
return; return;
} }

View File

@ -106,7 +106,9 @@ typedef std::function<void( const ALTIUM_COMPOUND_FILE&, const CFB::COMPOUND_FIL
class ALTIUM_PCB class ALTIUM_PCB
{ {
public: public:
explicit ALTIUM_PCB( BOARD* aBoard, PROGRESS_REPORTER* aProgressReporter ); explicit ALTIUM_PCB( BOARD* aBoard, PROGRESS_REPORTER* aProgressReporter,
const wxString& aLibrary = wxEmptyString,
const wxString& aFootprintName = wxEmptyString);
~ALTIUM_PCB(); ~ALTIUM_PCB();
void Parse( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile, void Parse( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile,
@ -250,10 +252,13 @@ private:
std::map<ALTIUM_LAYER, ZONE*> m_outer_plane; std::map<ALTIUM_LAYER, ZONE*> m_outer_plane;
PROGRESS_REPORTER* m_progressReporter; ///< optional; may be nullptr PROGRESS_REPORTER* m_progressReporter; ///< optional; may be nullptr
unsigned m_doneCount; unsigned m_doneCount;
unsigned m_lastProgressCount; unsigned m_lastProgressCount;
unsigned m_totalCount; ///< for progress reporting unsigned m_totalCount; ///< for progress reporting
wxString m_library; ///< for footprint library loading error reporting
wxString m_footprintName; ///< for footprint library loading error reporting
/// Altium stores pour order across all layers /// Altium stores pour order across all layers
int m_highest_pour_index; int m_highest_pour_index;

View File

@ -266,11 +266,11 @@ FOOTPRINT* PCB_IO_ALTIUM_DESIGNER::FootprintLoad( const wxString& aLibraryPath,
auto it = m_fplibFiles.find( aLibraryPath ); auto it = m_fplibFiles.find( aLibraryPath );
if( it == m_fplibFiles.end() ) if( it == m_fplibFiles.end() )
THROW_IO_ERROR( _( "No footprints in library" ) ); THROW_IO_ERROR( wxString::Format( _( "No footprints in library '%s'" ), aLibraryPath ) );
try try
{ {
for( auto& altiumLibFile : it->second ) for( std::unique_ptr<ALTIUM_COMPOUND_FILE>& altiumLibFile : it->second )
{ {
auto [dirName, fpCfe] = altiumLibFile->FindLibFootprintDirName( aFootprintName ); auto [dirName, fpCfe] = altiumLibFile->FindLibFootprintDirName( aFootprintName );
@ -278,7 +278,7 @@ FOOTPRINT* PCB_IO_ALTIUM_DESIGNER::FootprintLoad( const wxString& aLibraryPath,
continue; continue;
// Parse File // Parse File
ALTIUM_PCB pcb( m_board, nullptr ); ALTIUM_PCB pcb( m_board, nullptr, aLibraryPath, aFootprintName );
return pcb.ParseFootprint( *altiumLibFile, aFootprintName ); return pcb.ParseFootprint( *altiumLibFile, aFootprintName );
} }
} }
@ -287,8 +287,7 @@ FOOTPRINT* PCB_IO_ALTIUM_DESIGNER::FootprintLoad( const wxString& aLibraryPath,
THROW_IO_ERROR( exception.what() ); THROW_IO_ERROR( exception.what() );
} }
THROW_IO_ERROR( THROW_IO_ERROR( wxString::Format( _( "Footprint '%s' not found in '%s'." ),
wxString::Format( _( "Footprint directory not found: '%s'." ), aFootprintName ) ); aFootprintName,
aLibraryPath ) );
return nullptr;
} }