diff --git a/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.cpp b/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.cpp index d0123a166e..be405578cc 100644 --- a/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.cpp +++ b/pcbnew/plugins/cadstar/cadstar_pcb_archive_loader.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include // std::numeric_limits @@ -801,7 +802,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryCoppers( const SYMDEF_PCB& aComponen if( !found ) anchorPad = aComponent.ComponentPads.at( compCopper.AssociatedPadIDs.front() ); - PAD* pad = new PAD( aFootprint ); + std::unique_ptr pad = std::make_unique( aFootprint ); pad->SetAttribute( PAD_ATTRIB::SMD ); pad->SetLayerSet( LSET( 1, copperLayer ) ); pad->SetNumber( anchorPad.Identifier.IsEmpty() @@ -815,6 +816,9 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryCoppers( const SYMDEF_PCB& aComponen int anchorSize = getKiCadLength( anchorpadcode.Shape.Size ); wxPoint anchorPos = getKiCadPoint( anchorPad.Position ); + if( anchorSize <= 0 ) + anchorSize = 1; + pad->SetShape( PAD_SHAPE::CUSTOM ); pad->SetAnchorPadShape( PAD_SHAPE::CIRCLE ); pad->SetSize( { anchorSize, anchorSize } ); @@ -828,7 +832,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryCoppers( const SYMDEF_PCB& aComponen shapePolys.Move( aFootprint->GetPosition() - anchorPos ); pad->AddPrimitivePoly( shapePolys, 0, true ); - aFootprint->Add( pad, ADD_MODE::APPEND ); // Append so that we get the correct behaviour + aFootprint->Add( pad.release(), ADD_MODE::APPEND ); // Append so that we get the correct behaviour // when finding pads by PAD_ID. See loadNets() m_librarycopperpads[aComponent.ID][anchorPad.ID].push_back( aFootprint->Pads().size() ); @@ -905,9 +909,9 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryPads( const SYMDEF_PCB& aComponent, { for( std::pair padPair : aComponent.ComponentPads ) { - PAD* pad = getKiCadPad( padPair.second, aFootprint ); - aFootprint->Add( pad, ADD_MODE::APPEND ); // Append so that we get correct behaviour - // when finding pads by PAD_ID - see loadNets() + if( PAD* pad = getKiCadPad( padPair.second, aFootprint ) ) + aFootprint->Add( pad, ADD_MODE::APPEND ); // Append so that we get correct behaviour + // when finding pads by PAD_ID - see loadNets() } } @@ -917,7 +921,10 @@ PAD* CADSTAR_PCB_ARCHIVE_LOADER::getKiCadPad( const COMPONENT_PAD& aCadstarPad, PADCODE csPadcode = getPadCode( aCadstarPad.PadCodeID ); wxString errorMSG; - PAD* pad = new PAD( aParent ); + if( csPadcode.Shape.Size <= 0) + return nullptr; + + std::unique_ptr pad = std::make_unique( aParent ); LSET padLayerSet; switch( aCadstarPad.Side ) @@ -1238,7 +1245,7 @@ PAD* CADSTAR_PCB_ARCHIVE_LOADER::getKiCadPad( const COMPONENT_PAD& aCadstarPad, m_padcodesTested.insert( csPadcode.ID ); } - return pad; + return pad.release(); } @@ -1713,11 +1720,14 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadComponents() wxString padNumber = kiPad->GetNumber(); delete kiPad; - kiPad = getKiCadPad( csPad, footprint ); - kiPad->SetNumber( padNumber ); - // Change the pointer in the footprint to the newly created pad - getPadReference( footprint, padEx.ID ) = kiPad; + if( kiPad = getKiCadPad( csPad, footprint ) ) + { + kiPad->SetNumber( padNumber ); + + // Change the pointer in the footprint to the newly created pad + getPadReference( footprint, padEx.ID ) = kiPad; + } } } diff --git a/pcbnew/plugins/eagle/eagle_plugin.cpp b/pcbnew/plugins/eagle/eagle_plugin.cpp index 7ce1dfb6c3..923c03d49d 100644 --- a/pcbnew/plugins/eagle/eagle_plugin.cpp +++ b/pcbnew/plugins/eagle/eagle_plugin.cpp @@ -1892,9 +1892,8 @@ void EAGLE_PLUGIN::packagePad( FOOTPRINT* aFootprint, wxXmlNode* aTree ) int shape = EPAD::UNDEF; int eagleDrillz = e.drill.ToPcbUnits(); - PAD* pad = new PAD( aFootprint ); - aFootprint->Add( pad ); - transferPad( e, pad ); + std::unique_ptr pad = std::make_unique( aFootprint ); + transferPad( e, pad.get() ); if( e.first && *e.first && m_rules->psFirst != EPAD::UNDEF ) shape = m_rules->psFirst; @@ -1980,6 +1979,11 @@ void EAGLE_PLUGIN::packagePad( FOOTPRINT* aFootprint, wxXmlNode* aTree ) { pad->SetOrientation( e.rot->degrees * 10 ); } + + if( pad->GetSizeX() > 0 && pad->GetSizeY() > 0 ) + { + aFootprint->Add( pad.release() ); + } } diff --git a/pcbnew/plugins/fabmaster/import_fabmaster.cpp b/pcbnew/plugins/fabmaster/import_fabmaster.cpp index 0658848313..992cae30f1 100644 --- a/pcbnew/plugins/fabmaster/import_fabmaster.cpp +++ b/pcbnew/plugins/fabmaster/import_fabmaster.cpp @@ -2238,7 +2238,7 @@ bool FABMASTER::loadFootprints( BOARD* aBoard ) auto net_it = netinfo.find( netname ); - PAD* newpad = new PAD( fp ); + std::unique_ptr newpad = std::make_unique( fp ); if( net_it != netinfo.end() ) newpad->SetNet( net_it->second ); @@ -2256,8 +2256,8 @@ bool FABMASTER::loadFootprints( BOARD* aBoard ) if( padstack == pads.end() ) { - ///TODO:Warning - delete newpad; + wxLogError( _( "Unable to locate padstack %s in file %s\n" ), + pin->padstack.c_str(), aBoard->GetFileName().wc_str() ); continue; } else @@ -2409,7 +2409,10 @@ bool FABMASTER::loadFootprints( BOARD* aBoard ) else newpad->SetOrientation( ( src->rotate - pin->rotation ) * 10.0 ); - fp->Add( newpad, ADD_MODE::APPEND ); + if( newpad->GetSizeX() > 0 || newpad->GetSizeY() > 0 ) + { + fp->Add( newpad.release(), ADD_MODE::APPEND ); + } } } diff --git a/pcbnew/plugins/geda/gpcb_plugin.cpp b/pcbnew/plugins/geda/gpcb_plugin.cpp index 32d42fd0f3..4d33a4c332 100644 --- a/pcbnew/plugins/geda/gpcb_plugin.cpp +++ b/pcbnew/plugins/geda/gpcb_plugin.cpp @@ -536,7 +536,7 @@ FOOTPRINT* GPCB_FPL_CACHE::parseFOOTPRINT( LINE_READER* aLineReader ) aLineReader->LineNumber(), 0 ); } - PAD* pad = new PAD( footprint.get() ); + std::unique_ptr pad = std::make_unique( footprint.get() ); static const LSET pad_front( 3, F_Cu, F_Mask, F_Paste ); static const LSET pad_back( 3, B_Cu, B_Mask, B_Paste ); @@ -604,7 +604,11 @@ FOOTPRINT* GPCB_FPL_CACHE::parseFOOTPRINT( LINE_READER* aLineReader ) pad->SetShape( PAD_SHAPE::OVAL ); } - footprint->Add( pad ); + if( pad->GetSizeX() > 0 && pad->GetSizeY() > 0 ) + { + footprint->Add( pad.release() ); + } + continue; } diff --git a/pcbnew/plugins/kicad/pcb_parser.cpp b/pcbnew/plugins/kicad/pcb_parser.cpp index 8b93c00b94..863968f53a 100644 --- a/pcbnew/plugins/kicad/pcb_parser.cpp +++ b/pcbnew/plugins/kicad/pcb_parser.cpp @@ -3479,12 +3479,14 @@ FOOTPRINT* PCB_PARSER::parseFOOTPRINT_unchecked( wxArrayString* aInitialComments case T_pad: { - PAD* pad = parsePAD( footprint.get() ); - pt = pad->GetPos0(); + if( PAD* pad = parsePAD( footprint.get() ) ) + { + pt = pad->GetPos0(); + RotatePoint( &pt, footprint->GetOrientation() ); + pad->SetPosition( pt + footprint->GetPosition() ); + footprint->Add( pad, ADD_MODE::APPEND ); + } - RotatePoint( &pt, footprint->GetOrientation() ); - pad->SetPosition( pt + footprint->GetPosition() ); - footprint->Add( pad, ADD_MODE::APPEND ); break; } @@ -4498,6 +4500,11 @@ PAD* PCB_PARSER::parsePAD( FOOTPRINT* aParent ) if( !pad->GetRemoveUnconnected() ) pad->SetKeepTopBottom( true ); + // Zero-sized pads are not really selectable and likely cause crashes. + // They are not supported by KiCad and are removed on loading + if( pad->GetSizeX() <= 0 || pad->GetSizeY() <= 0 ) + return nullptr; + return pad.release(); } diff --git a/pcbnew/plugins/legacy/legacy_plugin.cpp b/pcbnew/plugins/legacy/legacy_plugin.cpp index 491ee2cc68..c581b9209a 100644 --- a/pcbnew/plugins/legacy/legacy_plugin.cpp +++ b/pcbnew/plugins/legacy/legacy_plugin.cpp @@ -1543,7 +1543,11 @@ void LEGACY_PLUGIN::loadPAD( FOOTPRINT* aFootprint ) pad->SetPosition( padpos + aFootprint->GetPosition() ); - aFootprint->Add( pad.release() ); + if( pad->GetSizeX() > 0 && pad->GetSizeY() > 0 ) + { + aFootprint->Add( pad.release() ); + } + return; // preferred exit } }