CADSTAR PCB: Handle import of pads with different paste and mask sizes

KiCad doesn't yet support full padstacks, but at least we can use the
solder mask / solder paste expansion to import a better result. Also
we can disable the specific layer if the shape has a size of zero.
This commit is contained in:
Roberto Fernandez Bautista 2021-03-25 17:47:40 +00:00
parent 107a1990c9
commit 34a435cd56
1 changed files with 71 additions and 13 deletions

View File

@ -764,19 +764,21 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryPads( const SYMDEF_PCB& aComponent,
PAD* CADSTAR_PCB_ARCHIVE_LOADER::getKiCadPad( const COMPONENT_PAD& aCadstarPad, FOOTPRINT* aParent ) PAD* CADSTAR_PCB_ARCHIVE_LOADER::getKiCadPad( const COMPONENT_PAD& aCadstarPad, FOOTPRINT* aParent )
{ {
PADCODE csPadcode = getPadCode( aCadstarPad.PadCodeID ); PADCODE csPadcode = getPadCode( aCadstarPad.PadCodeID );
wxString errorMSG;
PAD* pad = new PAD( aParent ); PAD* pad = new PAD( aParent );
LSET padLayerSet;
switch( aCadstarPad.Side ) switch( aCadstarPad.Side )
{ {
case PAD_SIDE::MAXIMUM: //Bottom side case PAD_SIDE::MAXIMUM: //Bottom side
pad->SetAttribute( PAD_ATTR_T::PAD_ATTRIB_SMD ); pad->SetAttribute( PAD_ATTR_T::PAD_ATTRIB_SMD );
pad->SetLayerSet( LSET( 3, B_Cu, B_Paste, B_Mask ) ); padLayerSet |= LSET( 3, B_Cu, B_Paste, B_Mask );
break; break;
case PAD_SIDE::MINIMUM: //TOP side case PAD_SIDE::MINIMUM: //TOP side
pad->SetAttribute( PAD_ATTR_T::PAD_ATTRIB_SMD ); pad->SetAttribute( PAD_ATTR_T::PAD_ATTRIB_SMD );
pad->SetLayerSet( LSET( 3, F_Cu, F_Paste, F_Mask ) ); padLayerSet |= LSET( 3, F_Cu, F_Paste, F_Mask );
break; break;
case PAD_SIDE::THROUGH_HOLE: case PAD_SIDE::THROUGH_HOLE:
@ -785,14 +787,63 @@ PAD* CADSTAR_PCB_ARCHIVE_LOADER::getKiCadPad( const COMPONENT_PAD& aCadstarPad,
else else
pad->SetAttribute( PAD_ATTR_T::PAD_ATTRIB_NPTH ); pad->SetAttribute( PAD_ATTR_T::PAD_ATTRIB_NPTH );
pad->SetLayerSet( pad->PTHMask() ); // for now we will assume no paste layers padLayerSet = LSET::AllCuMask() | LSET( 4, F_Mask, B_Mask, F_Paste, B_Paste );
//TODO: We need to read the csPad->Reassigns vector to make sure no paste
break; break;
default: default:
wxFAIL_MSG( "Unknown Pad type" ); wxFAIL_MSG( "Unknown Pad type" );
} }
pad->SetLocalSolderMaskMargin( 0 );
pad->SetLocalSolderPasteMargin( 0 );
pad->SetLocalSolderPasteMarginRatio( 0.0 );
bool complexPadErrorLogged = false;
for( auto& reassign : csPadcode.Reassigns )
{
PCB_LAYER_ID kiLayer = getKiCadLayer( reassign.first );
PAD_SHAPE shape = reassign.second;
if( shape.Size == 0 )
{
padLayerSet.reset( kiLayer );
}
else
{
int newMargin = getKiCadLength( shape.Size - csPadcode.Shape.Size );
if( kiLayer == F_Mask || kiLayer == B_Mask )
{
if( std::abs( pad->GetLocalSolderMaskMargin() ) < std::abs( newMargin ) )
pad->SetLocalSolderMaskMargin( newMargin );
}
else if( kiLayer == F_Paste || kiLayer == B_Paste )
{
if( std::abs( pad->GetLocalSolderPasteMargin() ) < std::abs( newMargin ) )
pad->SetLocalSolderPasteMargin( newMargin );
}
else
{
//TODO fix properly when KiCad supports full padstacks
if( !complexPadErrorLogged )
{
complexPadErrorLogged = true;
errorMSG +=
wxT( "\n - " )
+ wxString::Format(
_( "The CADSTAR pad definition '%s' is a complex pad stack, "
"which is not supported in KiCad. Please review the "
"imported pads as they may require manual correction." ),
csPadcode.Name );
}
}
}
}
pad->SetLayerSet( padLayerSet );
pad->SetName( aCadstarPad.Identifier.IsEmpty() ? pad->SetName( aCadstarPad.Identifier.IsEmpty() ?
wxString::Format( wxT( "%ld" ), aCadstarPad.ID ) : wxString::Format( wxT( "%ld" ), aCadstarPad.ID ) :
aCadstarPad.Identifier ); aCadstarPad.Identifier );
@ -987,15 +1038,12 @@ PAD* CADSTAR_PCB_ARCHIVE_LOADER::getKiCadPad( const COMPONENT_PAD& aCadstarPad,
csPadcode.SlotOrientation = 0; csPadcode.SlotOrientation = 0;
drillOffset = { 0, 0 }; drillOffset = { 0, 0 };
if( m_padcodesTested.find( csPadcode.ID ) == m_padcodesTested.end() ) errorMSG +=
{ wxT( "\n - " )
wxLogError( wxString::Format( + wxString::Format(
_( "The CADSTAR pad definition '%s' has the hole shape outside the " _( "The CADSTAR pad definition '%s' has the hole shape outside the "
"pad shape. The hole has been moved to the center of the pad." ), "pad shape. The hole has been moved to the center of the pad." ),
csPadcode.Name ) ); csPadcode.Name );
m_padcodesTested.insert( csPadcode.ID );
}
} }
} }
@ -1024,6 +1072,16 @@ PAD* CADSTAR_PCB_ARCHIVE_LOADER::getKiCadPad( const COMPONENT_PAD& aCadstarPad,
pad->SetLocked( true ); // Cadstar pads are always locked with respect to the footprint pad->SetLocked( true ); // Cadstar pads are always locked with respect to the footprint
//log warnings:
if( m_padcodesTested.find( csPadcode.ID ) == m_padcodesTested.end() && !errorMSG.IsEmpty() )
{
wxLogError( wxString::Format(
_( "The CADSTAR pad definition '%s' has import errors: %s" ),
csPadcode.Name, errorMSG) );
m_padcodesTested.insert( csPadcode.ID );
}
return pad; return pad;
} }