KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_clip_line_to_via.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#include <board.h>
22#include <footprint.h>
23#include <pad.h>
24#include <pcb_track.h>
26#include <geometry/shape_arc.h>
28
29
31{
36
37 // A circular via at aCenter, big enough that a centre endpoint lands well
38 // inside the pad.
39 std::unique_ptr<PCB_VIA> MakeVia( const VECTOR2I& aCenter )
40 {
41 auto via = std::make_unique<PCB_VIA>( &m_board );
42 via->SetPosition( aCenter );
43 via->SetLayerPair( F_Cu, B_Cu );
44 via->SetDrill( 400000 ); // 0.4 mm
45 via->SetWidth( 1270000 ); // 1.27 mm -> radius 0.635 mm
46 return via;
47 }
48
49 // A circular pad the same size as the via. OptimiseTraceInPad is arc-aware,
50 // so it is the reference.
51 std::unique_ptr<PAD> MakeCircularPad( const VECTOR2I& aCenter )
52 {
53 auto pad = std::make_unique<PAD>( &m_footprint );
54 pad->SetAttribute( PAD_ATTRIB::PTH );
56 pad->SetSize( PADSTACK::ALL_LAYERS, VECTOR2I( 1270000, 1270000 ) );
57 pad->SetPosition( aCenter );
58 pad->SetLayerSet( LSET( { F_Cu } ) );
59 return pad;
60 }
61
64};
65
66
67BOOST_FIXTURE_TEST_SUITE( ClipLineToVia, CLIP_LINE_TO_VIA_FIXTURE )
68
69
70// Control with no arc. Clipping a straight trace forwards and backwards must
71// give the same length. Proves the harness is sound.
72BOOST_AUTO_TEST_CASE( StraightTrace_ForwardBackwardAgree )
73{
74 const VECTOR2I viaCenter( 189190000, 46760000 );
75 auto via = MakeVia( viaCenter );
76
78 chain.Append( viaCenter ); // inside via
79 chain.Append( VECTOR2I( 189190000 + 5000000, 46760000 ) ); // 5 mm away
80
81 SHAPE_LINE_CHAIN chainForward = chain;
82 SHAPE_LINE_CHAIN chainBackward = chain;
83 chainBackward.Reverse();
84
85 BOOST_REQUIRE_EQUAL( chainForward.Length(), chainBackward.Length() );
86
89
90 BOOST_CHECK_CLOSE( static_cast<double>( chainForward.Length() ), static_cast<double>( chainBackward.Length() ),
91 0.5 );
92}
93
94
95// An arc starts at the via centre and exits the pad. The via clip and the
96// arc-aware pad clip use the same circle, so they must report the same length.
97// A gap means the via clip mishandles the arc.
98BOOST_AUTO_TEST_CASE( ArcAtViaCenter_ViaClipMatchesPadClip )
99{
100 const VECTOR2I arcStart( 189190000, 46760000 );
101 const VECTOR2I arcMid( 190382763, 46815467 );
102 const VECTOR2I arcEnd( 189758445, 47833301 );
103
104 SHAPE_LINE_CHAIN baseChain;
105 baseChain.Append( arcStart );
106 SHAPE_ARC arc( arcStart, arcMid, arcEnd, 0 );
107 baseChain.Append( arc );
108
109 const double fullArcLen = static_cast<double>( baseChain.Length() );
110
111 SHAPE_LINE_CHAIN viaChain = baseChain;
112 SHAPE_LINE_CHAIN padChain = baseChain;
113
114 auto via = MakeVia( arcStart );
115 auto pad = MakeCircularPad( arcStart );
116
119
120 const double viaLen = static_cast<double>( viaChain.Length() );
121 const double padLen = static_cast<double>( padChain.Length() );
122
123 BOOST_TEST_MESSAGE( "full arc length (no clip) (mm): " << fullArcLen / 1000000.0 );
124 BOOST_TEST_MESSAGE( "via-clip length (mm): " << viaLen / 1000000.0 );
125 BOOST_TEST_MESSAGE( "pad-clip length (arc-aware)(mm): " << padLen / 1000000.0 );
126 BOOST_TEST_MESSAGE( "via vs pad gap (um): " << ( viaLen - padLen ) / 1000.0 );
127
128 // Via clip should agree with the arc-aware pad clip on identical geometry.
129 BOOST_CHECK_CLOSE( viaLen, padLen, 0.5 );
130}
131
132
133// Merge a straight line joined to an arc and check the total length is kept.
134// Guards the arc-aware merge. An arc that bends into a segment must join one
135// chain, not leave the segment ending at the bend.
136BOOST_AUTO_TEST_CASE( Merge_DoesNotDropArcLength )
137{
138 const VECTOR2I a( 0, 0 );
139 const VECTOR2I b( 5000000, 0 );
140 const VECTOR2I arcMid( 6000000, 1000000 );
141 const VECTOR2I arcEnd( 7000000, 0 );
142
143 SHAPE_LINE_CHAIN straight;
144 straight.Append( a );
145 straight.Append( b );
146
147 SHAPE_LINE_CHAIN arcChain;
148 arcChain.Append( b );
149 SHAPE_ARC arc( b, arcMid, arcEnd, 0 );
150 arcChain.Append( arc );
151
152 const double expected = static_cast<double>( straight.Length() + arcChain.Length() );
153
154 auto makeItems = [&]()
155 {
156 std::vector<LENGTH_DELAY_CALCULATION_ITEM> items;
157
159 s.SetLine( straight );
160 s.SetLayers( F_Cu );
161 s.SetWidth( 200000 );
162
164 c.SetLine( arcChain );
165 c.SetLayers( F_Cu );
166 c.SetWidth( 200000 );
167
168 items.push_back( s );
169 items.push_back( c );
170 return items;
171 };
172
173 LENGTH_DELAY_CALCULATION calc( &m_board );
174
175 constexpr PATH_OPTIMISATIONS noMerge = {
176 .OptimiseVias = false, .MergeTracks = false, .OptimiseTracesInPads = false, .InferViaInPad = false
177 };
178 constexpr PATH_OPTIMISATIONS merge = {
179 .OptimiseVias = false, .MergeTracks = true, .OptimiseTracesInPads = false, .InferViaInPad = false
180 };
181
182 auto i1 = makeItems();
183 auto i2 = makeItems();
184
185 const double lenNoMerge = static_cast<double>( calc.CalculateLength( i1, noMerge, nullptr, nullptr ) );
186 const double lenMerge = static_cast<double>( calc.CalculateLength( i2, merge, nullptr, nullptr ) );
187
188 BOOST_TEST_MESSAGE( "expected (mm): " << expected / 1000000.0 );
189 BOOST_TEST_MESSAGE( "no-merge (mm): " << lenNoMerge / 1000000.0 );
190 BOOST_TEST_MESSAGE( "merge (mm): " << lenMerge / 1000000.0 );
191
192 BOOST_CHECK_CLOSE( lenNoMerge, expected, 0.01 );
193 BOOST_CHECK_CLOSE( lenMerge, lenNoMerge, 0.01 );
194}
195
196
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:372
Lightweight class which holds a pad, via, or a routed trace outline.
void SetLine(const SHAPE_LINE_CHAIN &aLine)
Sets the source SHAPE_LINE_CHAIN of this item.
void SetWidth(const int aWidth)
Sets the line width.
void SetLayers(const PCB_LAYER_ID aStart, const PCB_LAYER_ID aEnd=PCB_LAYER_ID::UNDEFINED_LAYER)
Sets the first and last layers associated with this item.
Class which calculates lengths (and associated routing statistics) in a BOARD context.
int64_t CalculateLength(std::vector< LENGTH_DELAY_CALCULATION_ITEM > &aItems, PATH_OPTIMISATIONS aOptimisations, const PAD *aStartPad=nullptr, const PAD *aEndPad=nullptr) const
Calculates the electrical length of the given items.
static void OptimiseTraceInVia(SHAPE_LINE_CHAIN &aLine, const PCB_VIA *aVia, PCB_LAYER_ID aLayer)
Clips trace portions inside a VIA pad and replaces them with a straight-line segment from the VIA edg...
static void OptimiseTraceInPad(SHAPE_LINE_CHAIN &aLine, const PAD *aPad, PCB_LAYER_ID aPcbLayer)
Optimises the given trace / line to minimise the electrical path length within the given pad.
LSET is a set of PCB_LAYER_IDs.
Definition lset.h:37
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
Definition padstack.h:177
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
const SHAPE_LINE_CHAIN Reverse() const
Reverse point order in the line chain.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
long long int Length() const
Return length of the line chain in Euclidean metric.
@ B_Cu
Definition layer_ids.h:61
@ F_Cu
Definition layer_ids.h:60
@ PTH
Plated through hole pad.
Definition padstack.h:98
std::unique_ptr< PAD > MakeCircularPad(const VECTOR2I &aCenter)
std::unique_ptr< PCB_VIA > MakeVia(const VECTOR2I &aCenter)
Struct to control which optimisations the length calculation code runs on the given path objects.
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_CASE(StraightTrace_ForwardBackwardAgree)
BOOST_AUTO_TEST_SUITE_END()
VECTOR3I expected(15, 30, 45)
BOOST_TEST_MESSAGE("\n=== Real-World Polygon PIP Benchmark ===\n"<< formatTable(table))
const SHAPE_LINE_CHAIN chain
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683