KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_pns_via_layer_span.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
21
22#include <board.h>
23#include <footprint.h>
24#include <pad.h>
25#include <pcb_track.h>
28
29#include <router/pns_itemset.h>
31#include <router/pns_line.h>
32#include <router/pns_node.h>
34#include <router/pns_router.h>
37#include <router/pns_via.h>
38
39#include <memory>
40
41
54
55
56BOOST_FIXTURE_TEST_CASE( DiffPairThroughViaSpansWholeBoard, VIA_LAYER_SPAN_FIXTURE )
57{
58 KI_TEST::LoadBoard( m_settingsManager, "issue24772/fw16_MCIO8i", m_board );
59 BOOST_REQUIRE( m_board );
60 BOOST_REQUIRE_EQUAL( m_board->GetCopperLayerCount(), 6 );
61
62 FOOTPRINT* connector = m_board->FindFootprintByReference( wxT( "MCIO1" ) );
63 BOOST_REQUIRE( connector );
64
65 PAD* padP = connector->FindPadByNumber( wxT( "B5" ) );
66 BOOST_REQUIRE( padP );
67
68 PNS::ROUTER router;
70 PNS::ROUTING_SETTINGS routingSettings( nullptr, "" );
71
72 iface.SetBoard( m_board.get() );
73 router.SetInterface( &iface );
74 router.ClearWorld();
75 router.SyncWorld();
76 router.LoadSettings( &routingSettings );
78
79 // The reporter routed with a layer pair of In1.Cu and In4.Cu, which is what exposed the bug
80 const int pnsTop = iface.GetPNSLayerFromBoardLayer( In1_Cu );
81 const int pnsBottom = iface.GetPNSLayerFromBoardLayer( In4_Cu );
82 const int pnsFront = iface.GetPNSLayerFromBoardLayer( F_Cu );
83 const int pnsBack = iface.GetPNSLayerFromBoardLayer( B_Cu );
84
85 BOOST_REQUIRE_NE( pnsTop, pnsFront );
86 BOOST_REQUIRE_NE( pnsBottom, pnsBack );
87
88 const VECTOR2I startPoint = padP->GetPosition();
89 PNS::ITEM* startItem = router.GetWorld()->FindItemByParent( padP );
90
91 BOOST_REQUIRE( startItem );
92
93 PNS::SIZES_SETTINGS sizes( router.Sizes() );
95 BOOST_REQUIRE( iface.ImportSizes( sizes, startItem, nullptr, startPoint ) );
96
97 sizes.ClearLayerPairs();
98 sizes.AddLayerPair( pnsTop, pnsBottom );
100 router.UpdateSizes( sizes );
101
102 router.Settings().SetAllowDRCViolations( true );
103
104 BOOST_REQUIRE( router.StartRouting( startPoint, startItem, pnsFront ) );
105
106 router.ToggleViaPlacement();
107 BOOST_REQUIRE( router.IsPlacingVia() );
108
109 // Pull the head away from the connector so the placer has room to build a trace with a via
110 const VECTOR2I endPoint = startPoint + VECTOR2I( 0, pcbIUScale.mmToIU( 5.0 ) );
111 BOOST_REQUIRE( router.Move( endPoint, nullptr ) );
112
113 const PNS::VIA* headVia = nullptr;
114
115 const PNS::ITEM_SET traces = router.Placer()->Traces();
116
117 for( const PNS::ITEM* item : traces.CItems() )
118 {
119 if( item->Kind() != PNS::ITEM::LINE_T )
120 continue;
121
122 const PNS::LINE* line = static_cast<const PNS::LINE*>( item );
123
124 if( line->EndsWithVia() )
125 {
126 headVia = &line->Via();
127 break;
128 }
129 }
130
131 BOOST_REQUIRE( headVia );
132 BOOST_CHECK( headVia->ViaType() == VIATYPE::THROUGH );
133
134 // Before the fix the span followed the layer pair, so the via missed F.Cu and B.Cu
135 BOOST_CHECK_EQUAL( headVia->Layers().Start(), pnsFront );
136 BOOST_CHECK_EQUAL( headVia->Layers().End(), pnsBack );
137 BOOST_CHECK_EQUAL( headVia->HoleLayers().Start(), pnsFront );
138 BOOST_CHECK_EQUAL( headVia->HoleLayers().End(), pnsBack );
139
140 router.StopRouting();
141}
142
143
149BOOST_FIXTURE_TEST_CASE( SyncedViaHoleLayersMatchCopperLayers, VIA_LAYER_SPAN_FIXTURE )
150{
151 KI_TEST::LoadBoard( m_settingsManager, "issue24772/fw16_MCIO8i", m_board );
152 BOOST_REQUIRE( m_board );
153
154 PNS::ROUTER router;
156
157 iface.SetBoard( m_board.get() );
158 router.SetInterface( &iface );
159 router.ClearWorld();
160 router.SyncWorld();
161
162 int viaCount = 0;
163
164 for( const PCB_TRACK* track : m_board->Tracks() )
165 {
166 if( track->Type() != PCB_VIA_T )
167 continue;
168
169 const PNS::ITEM* item = router.GetWorld()->FindItemByParent( track );
170
171 if( !item || item->Kind() != PNS::ITEM::VIA_T )
172 continue;
173
174 const PNS::VIA* via = static_cast<const PNS::VIA*>( item );
175
176 BOOST_REQUIRE_EQUAL( via->HoleLayers().Start(), via->Layers().Start() );
177 BOOST_REQUIRE_EQUAL( via->HoleLayers().End(), via->Layers().End() );
178 viaCount++;
179 }
180
181 BOOST_CHECK_GT( viaCount, 0 );
182}
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:121
PAD * FindPadByNumber(const wxString &aPadNumber, PAD *aSearchAfterMe=nullptr) const
Return a PAD with a matching number.
Definition pad.h:61
VECTOR2I GetPosition() const override
Definition pad.cpp:246
const std::vector< ITEM * > & CItems() const
Definition pns_itemset.h:96
Base class for PNS router board items.
Definition pns_item.h:98
const PNS_LAYER_RANGE & Layers() const
Definition pns_item.h:212
PnsKind Kind() const
Return the type (kind) of the item.
Definition pns_item.h:173
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
Definition pns_line.h:62
VIA & Via()
Definition pns_line.h:207
bool EndsWithVia() const
Definition pns_line.h:199
ITEM * FindItemByParent(const BOARD_ITEM *aParent)
virtual const ITEM_SET Traces()=0
Function Traces()
void SetMode(ROUTER_MODE aMode)
void StopRouting()
PLACEMENT_ALGO * Placer()
Definition pns_router.h:252
void ClearWorld()
void UpdateSizes(const SIZES_SETTINGS &aSizes)
Applies stored settings.
void LoadSettings(ROUTING_SETTINGS *aSettings)
Changes routing settings to ones passed in the parameter.
Definition pns_router.h:242
void SetInterface(ROUTER_IFACE *aIface)
void SyncWorld()
bool IsPlacingVia() const
ROUTING_SETTINGS & Settings()
Definition pns_router.h:228
bool StartRouting(const VECTOR2I &aP, ITEM *aItem, int aLayer)
SIZES_SETTINGS & Sizes()
Definition pns_router.h:247
void ToggleViaPlacement()
NODE * GetWorld() const
Definition pns_router.h:200
bool Move(const VECTOR2I &aP, ITEM *aItem)
Contain all persistent settings of the router, such as the mode, optimization effort,...
void SetAllowDRCViolations(bool aViolate)
void SetViaType(VIATYPE aViaType)
void AddLayerPair(int aL1, int aL2)
VIATYPE ViaType() const
Definition pns_via.h:219
const PNS_LAYER_RANGE & HoleLayers() const
Definition pns_via.h:258
void SetBoard(BOARD *aBoard)
void SetStartLayerFromPCBNew(PCB_LAYER_ID aLayer)
int GetPNSLayerFromBoardLayer(PCB_LAYER_ID aLayer) const override
bool ImportSizes(PNS::SIZES_SETTINGS &aSizes, PNS::ITEM *aStartItem, PNS::NET_HANDLE aNet, VECTOR2D aStartPosition) override
int Start() const
int End() const
@ B_Cu
Definition layer_ids.h:61
@ In4_Cu
Definition layer_ids.h:65
@ In1_Cu
Definition layer_ids.h:62
@ F_Cu
Definition layer_ids.h:60
void LoadBoard(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< BOARD > &aBoard)
@ PNS_MODE_ROUTE_DIFF_PAIR
Definition pns_router.h:69
Regression coverage for https://gitlab.com/kicad/code/kicad/-/issues/24772.
std::unique_ptr< BOARD > m_board
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_FIXTURE_TEST_CASE(DiffPairThroughViaSpansWholeBoard, VIA_LAYER_SPAN_FIXTURE)
BOOST_CHECK_EQUAL(result, "25.4")
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition typeinfo.h:89
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683