ADDED footprint checks for SMD pad consistency.

Fixes https://gitlab.com/kicad/code/kicad/issues/11736
This commit is contained in:
Jeff Young 2022-09-03 23:26:27 +01:00
parent 12171603d5
commit d5cf7828fa
4 changed files with 84 additions and 1 deletions

View File

@ -178,6 +178,12 @@ void DIALOG_FOOTPRINT_CHECKER::runChecks()
} );
}
footprint->CheckSMDSide(
[&]( const PAD* aPadA, const PAD* aPadB, const wxString& aMsg )
{
errorHandler( aPadA, aPadB, nullptr, DRCE_FOOTPRINT, aMsg, aPadA->GetPosition() );
} );
m_checksRun = true;
m_markersTreeModel->Update( m_markersProvider, m_severities );

View File

@ -138,6 +138,14 @@ bool DRC_TEST_PROVIDER_FOOTPRINT_CHECKS::Run()
footprint->GetPosition(), footprint->GetLayer() );
} );
}
footprint->CheckSMDSide(
[&]( const PAD* aPadA, const PAD* aPadB, const wxString& aMsg )
{
errorHandler( aPadA, aPadB, nullptr, DRCE_FOOTPRINT, aMsg,
aPadA->GetPosition(), aPadA->GetPrincipalLayer() );
} );
}
return !m_drcEngine->IsCancelled();

View File

@ -2339,6 +2339,41 @@ void FOOTPRINT::CheckPads( const std::function<void( const PAD*, int,
aErrorHandler( pad, DRCE_PADSTACK, _( "(PTH pad's hole leaves no copper)" ) );
}
}
if( pad->GetAttribute() == PAD_ATTRIB::SMD )
{
if( pad->IsOnLayer( F_Cu ) && pad->IsOnLayer( B_Cu ) )
{
aErrorHandler( pad, DRCE_PADSTACK,
_( "(SMD pad appears on both front and back copper)" ) );
}
else if( pad->IsOnLayer( F_Cu ) )
{
if( pad->IsOnLayer( B_Mask ) )
{
aErrorHandler( pad, DRCE_PADSTACK,
_( "(SMD pad copper and mask layers don't match)" ) );
}
else if( pad->IsOnLayer( B_Paste ) )
{
aErrorHandler( pad, DRCE_PADSTACK,
_( "(SMD pad copper and paste layers don't match)" ) );
}
}
else if( pad->IsOnLayer( B_Cu ) )
{
if( pad->IsOnLayer( F_Mask ) )
{
aErrorHandler( pad, DRCE_PADSTACK,
_( "(SMD pad copper and mask layers don't match)" ) );
}
else if( pad->IsOnLayer( F_Paste ) )
{
aErrorHandler( pad, DRCE_PADSTACK,
_( "(SMD pad copper and paste layers don't match)" ) );
}
}
}
}
}
@ -2536,11 +2571,36 @@ void FOOTPRINT::CheckNetTiePadGroups( const std::function<void( const wxString&
}
void FOOTPRINT::CheckSMDSide( const std::function<void( const PAD*, const PAD*,
const wxString& aMsg )>& aErrorHandler )
{
PAD* firstFront = nullptr;
PAD* firstBack = nullptr;
for( PAD* pad : Pads() )
{
if( pad->GetAttribute() == PAD_ATTRIB::SMD )
{
if( pad->IsOnLayer( F_Cu ) && !firstFront )
firstFront = pad;
else if( pad->IsOnLayer( B_Cu ) && !firstBack )
firstBack = pad;
}
}
if( firstFront && firstBack )
{
aErrorHandler( firstFront, firstBack,
_( "(footprint contains SMD pads on both front and back)" ) );
}
}
void FOOTPRINT::SwapData( BOARD_ITEM* aImage )
{
wxASSERT( aImage->Type() == PCB_FOOTPRINT_T );
std::swap( *((FOOTPRINT*) this), *((FOOTPRINT*) aImage) );
std::swap( *this, *static_cast<FOOTPRINT*>( aImage ) );
}

View File

@ -413,6 +413,15 @@ public:
*/
void CheckNetTiePadGroups( const std::function<void( const wxString& )>& aErrorHandler );
/**
* Sanity check SMD pads. A footprint containing both front and back copper SMD pads is
* highly suspicious.
*
* @param aErrorHandler callback to handle the error messages generated
*/
void CheckSMDSide( const std::function<void( const PAD*,
const PAD*,
const wxString& aMsg )>& aErrorHandler );
/**
* Generate pads shapes on layer \a aLayer as polygons and adds these polygons to
* \a aCornerBuffer.