From e6684bf7c79d9b43f8bb6a0ac4c6a6115e2d26db Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sat, 23 Apr 2022 11:33:53 +0100 Subject: [PATCH] Add footprint checks to board-level DRC. Fixes https://gitlab.com/kicad/code/kicad/issues/11437 --- pcbnew/CMakeLists.txt | 1 + .../drc_test_provider_footprint_checks.cpp | 127 ++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 pcbnew/drc/drc_test_provider_footprint_checks.cpp diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index acbe725fc4..38f683a007 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -243,6 +243,7 @@ set( PCBNEW_DRC_SRCS drc/drc_test_provider_mechanical_clearance.cpp drc/drc_test_provider_courtyard_clearance.cpp drc/drc_test_provider_edge_clearance.cpp + drc/drc_test_provider_footprint_checks.cpp drc/drc_test_provider_hole_to_hole.cpp drc/drc_test_provider_hole_size.cpp drc/drc_test_provider_library_parity.cpp diff --git a/pcbnew/drc/drc_test_provider_footprint_checks.cpp b/pcbnew/drc/drc_test_provider_footprint_checks.cpp new file mode 100644 index 0000000000..1ea959f6ba --- /dev/null +++ b/pcbnew/drc/drc_test_provider_footprint_checks.cpp @@ -0,0 +1,127 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include + +/* + Footprint tests: + + - DRCE_FOOTPRINT_TYPE_MISMATCH, + - DRCE_OVERLAPPING_PADS, + - DRCE_PAD_TH_WITH_NO_HOLE, + - DRCE_PADSTACK +*/ + +class DRC_TEST_PROVIDER_FOOTPRINT_CHECKS : public DRC_TEST_PROVIDER +{ +public: + DRC_TEST_PROVIDER_FOOTPRINT_CHECKS() + { + m_isRuleDriven = false; + } + + virtual ~DRC_TEST_PROVIDER_FOOTPRINT_CHECKS() + { + } + + virtual bool Run() override; + + virtual const wxString GetName() const override + { + return wxT( "footprint checks" ); + }; + + virtual const wxString GetDescription() const override + { + return wxT( "Check for common footprint pad and component type errors" ); + } +}; + + +bool DRC_TEST_PROVIDER_FOOTPRINT_CHECKS::Run() +{ + if( !reportPhase( _( "Checking footprints..." ) ) ) + return false; // DRC cancelled + + auto errorHandler = + [&]( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB, int aErrorCode, + const wxString& aMsg, const VECTOR2I& aPt, PCB_LAYER_ID aLayer ) + { + std::shared_ptr drcItem = DRC_ITEM::Create( aErrorCode ); + + if( !aMsg.IsEmpty() ) + drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + aMsg ); + + drcItem->SetItems( aItemA, aItemB ); + reportViolation( drcItem, aPt, aLayer ); + }; + + for( FOOTPRINT* footprint : m_drcEngine->GetBoard()->Footprints() ) + { + if( !m_drcEngine->IsErrorLimitExceeded( DRCE_FOOTPRINT_TYPE_MISMATCH ) ) + { + footprint->CheckFootprintAttributes( + [&]( const wxString& aMsg ) + { + errorHandler( footprint, nullptr, DRCE_FOOTPRINT_TYPE_MISMATCH, aMsg, + footprint->GetPosition(), footprint->GetLayer() ); + } ); + } + + if( !m_drcEngine->IsErrorLimitExceeded( DRCE_PAD_TH_WITH_NO_HOLE ) + || !m_drcEngine->IsErrorLimitExceeded( DRCE_PADSTACK ) ) + { + footprint->CheckPads( + [&]( const PAD* aPad, int aErrorCode, const wxString& aMsg ) + { + if( !m_drcEngine->IsErrorLimitExceeded( aErrorCode ) ) + { + errorHandler( aPad, nullptr, aErrorCode, aMsg, aPad->GetPosition(), + aPad->GetPrincipalLayer() ); + } + } ); + } + + if( !m_drcEngine->IsErrorLimitExceeded( DRCE_OVERLAPPING_PADS ) ) + { + footprint->CheckOverlappingPads( + [&]( const PAD* aPadA, const PAD* aPadB, const VECTOR2I& aPosition ) + { + errorHandler( aPadA, aPadB, DRCE_OVERLAPPING_PADS, wxEmptyString, + aPosition, aPadA->GetPrincipalLayer() ); + } ); + } + } + + return !m_drcEngine->IsCancelled(); +} + + +namespace detail +{ +static DRC_REGISTER_TEST_PROVIDER dummy; +}