From c1f01877a8d979b47dbf1b434b993a6e51a5ca01 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sat, 28 Oct 2023 13:01:36 +0100 Subject: [PATCH] Improve length calculation for vias. Fixes https://gitlab.com/kicad/code/kicad/-/issues/10690 --- pcbnew/drc/drc_length_report.h | 6 ++-- pcbnew/drc/drc_test_provider.cpp | 4 +-- pcbnew/drc/drc_test_provider.h | 4 +-- .../drc/drc_test_provider_matched_length.cpp | 21 +++++++------ .../drc/drc_test_provider_silk_clearance.cpp | 3 +- pcbnew/pcb_track.cpp | 30 +++++++++++++++++++ pcbnew/pcb_track.h | 8 +++++ 7 files changed, 58 insertions(+), 18 deletions(-) diff --git a/pcbnew/drc/drc_length_report.h b/pcbnew/drc/drc_length_report.h index 0269f52264..1e8654cf64 100644 --- a/pcbnew/drc/drc_length_report.h +++ b/pcbnew/drc/drc_length_report.h @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2004-2020 KiCad Developers. + * Copyright (C) 2004-2023 KiCad Developers. * * 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 @@ -38,10 +38,10 @@ public: wxString to; std::set items; int viaCount; - int totalRoute; + double totalRoute; int totalVia; int totalPadToDie; - int total; + double total; }; DRC_LENGTH_REPORT() diff --git a/pcbnew/drc/drc_test_provider.cpp b/pcbnew/drc/drc_test_provider.cpp index 3491d09257..c30ed07397 100644 --- a/pcbnew/drc/drc_test_provider.cpp +++ b/pcbnew/drc/drc_test_provider.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2020-2022 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2020-2023 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 @@ -352,7 +352,7 @@ bool DRC_TEST_PROVIDER::isInvisibleText( const BOARD_ITEM* aItem ) const wxString DRC_TEST_PROVIDER::formatMsg( const wxString& aFormatString, const wxString& aSource, - int aConstraint, int aActual ) + double aConstraint, double aActual ) { wxString constraint_str = MessageTextFromValue( aConstraint ); wxString actual_str = MessageTextFromValue( aActual ); diff --git a/pcbnew/drc/drc_test_provider.h b/pcbnew/drc/drc_test_provider.h index d8d0e69d79..208e6a5d29 100644 --- a/pcbnew/drc/drc_test_provider.h +++ b/pcbnew/drc/drc_test_provider.h @@ -119,8 +119,8 @@ protected: bool isInvisibleText( const BOARD_ITEM* aItem ) const; - wxString formatMsg( const wxString& aFormatString, const wxString& aSource, int aConstraint, - int aActual ); + wxString formatMsg( const wxString& aFormatString, const wxString& aSource, double aConstraint, + double aActual ); // List of basic (ie: non-compound) geometry items static std::vector s_allBasicItems; diff --git a/pcbnew/drc/drc_test_provider_matched_length.cpp b/pcbnew/drc/drc_test_provider_matched_length.cpp index ab2f4b717b..aba42c3ec9 100644 --- a/pcbnew/drc/drc_test_provider_matched_length.cpp +++ b/pcbnew/drc/drc_test_provider_matched_length.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2004-2022 KiCad Developers. + * Copyright (C) 2004-2023 KiCad Developers. * * 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 @@ -31,7 +31,6 @@ #include #include -#include /* Single-ended matched length + skew + via count test. @@ -66,8 +65,6 @@ public: return wxT( "Tests matched track lengths." ); } - DRC_LENGTH_REPORT BuildLengthReport() const; - private: bool runInternal( bool aDelayReportMode = false ); @@ -81,7 +78,8 @@ private: void checkViaCounts( const DRC_CONSTRAINT& aConstraint, const std::vector& aMatchedConnections ); - BOARD* m_board; +private: + BOARD* m_board; DRC_LENGTH_REPORT m_report; }; @@ -142,16 +140,16 @@ void DRC_TEST_PROVIDER_MATCHED_LENGTH::checkLengths( const DRC_CONSTRAINT& aCons void DRC_TEST_PROVIDER_MATCHED_LENGTH::checkSkews( const DRC_CONSTRAINT& aConstraint, const std::vector& aMatchedConnections ) { - int avgLength = 0; + double avgLength = 0; for( const DRC_LENGTH_REPORT::ENTRY& ent : aMatchedConnections ) avgLength += ent.total; - avgLength /= aMatchedConnections.size(); + avgLength /= (double) aMatchedConnections.size(); for( const auto& ent : aMatchedConnections ) { - int skew = ent.total - avgLength; + int skew = KiROUND( ent.total - avgLength ); if( aConstraint.GetValue().HasMax() && abs( skew ) > aConstraint.GetValue().Max() ) { std::shared_ptr drcItem = DRC_ITEM::Create( DRCE_SKEW_OUT_OF_RANGE ); @@ -302,8 +300,13 @@ bool DRC_TEST_PROVIDER_MATCHED_LENGTH::runInternal( bool aDelayReportMode ) if( bds.m_UseHeightForLengthCalcs ) { const PCB_VIA* v = static_cast( citem ); + PCB_LAYER_ID topmost; + PCB_LAYER_ID bottommost; - ent.totalVia += stackup.GetLayerDistance( v->TopLayer(), v->BottomLayer() ); + v->GetOutermostConnectedLayers( &topmost, &bottommost ); + + if( topmost != UNDEFINED_LAYER && topmost != bottommost ) + ent.totalVia += stackup.GetLayerDistance( topmost, bottommost ); } } else if( citem->Type() == PCB_TRACE_T ) diff --git a/pcbnew/drc/drc_test_provider_silk_clearance.cpp b/pcbnew/drc/drc_test_provider_silk_clearance.cpp index d9868e58a0..b80e08f8a5 100644 --- a/pcbnew/drc/drc_test_provider_silk_clearance.cpp +++ b/pcbnew/drc/drc_test_provider_silk_clearance.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2004-2022 KiCad Developers. + * Copyright (C) 2004-2023 KiCad Developers. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/pcbnew/pcb_track.cpp b/pcbnew/pcb_track.cpp index 04c98d56ef..4a439d5700 100644 --- a/pcbnew/pcb_track.cpp +++ b/pcbnew/pcb_track.cpp @@ -808,6 +808,36 @@ bool PCB_VIA::FlashLayer( int aLayer ) const } +void PCB_VIA::GetOutermostConnectedLayers( PCB_LAYER_ID* aTopmost, + PCB_LAYER_ID* aBottommost ) const +{ + *aTopmost = UNDEFINED_LAYER; + *aBottommost = UNDEFINED_LAYER; + + static std::initializer_list connectedTypes = { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T, + PCB_PAD_T }; + + for( int layer = TopLayer(); layer <= BottomLayer(); ++layer ) + { + bool connected = false; + + if( m_zoneLayerOverrides[ layer ] == ZLO_FORCE_FLASHED ) + connected = true; + else if( GetBoard()->GetConnectivity()->IsConnectedOnLayer( this, layer, connectedTypes ) ) + connected = true; + + if( connected ) + { + if( *aTopmost == UNDEFINED_LAYER ) + *aTopmost = ToLAYER_ID( layer ); + + *aBottommost = ToLAYER_ID( layer ); + } + } + +} + + void PCB_TRACK::ViewGetLayers( int aLayers[], int& aCount ) const { // Show the track and its netname on different layers diff --git a/pcbnew/pcb_track.h b/pcbnew/pcb_track.h index 1044b36031..6a18edac4e 100644 --- a/pcbnew/pcb_track.h +++ b/pcbnew/pcb_track.h @@ -533,6 +533,14 @@ public: */ bool FlashLayer( LSET aLayers ) const; + /** + * Return the top-most and bottom-most connected layers. + * @param aTopmost + * @param aBottommost + */ + void GetOutermostConnectedLayers( PCB_LAYER_ID* aTopmost, + PCB_LAYER_ID* aBottommost ) const; + /** * Set the drill value for vias. *