KiCad PCB EDA Suite
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
pns_dp_meander_placer.cpp
Go to the documentation of this file.
1/*
2 * KiRouter - a push-and-(sometimes-)shove PCB router
3 *
4 * Copyright (C) 2013-2014 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <optional>
23
24#include "pns_node.h"
25#include "pns_itemset.h"
26#include "pns_topology.h"
28#include "pns_diff_pair.h"
29#include "pns_router.h"
30#include "pns_solid.h"
31
32namespace PNS {
33
35 MEANDER_PLACER_BASE( aRouter )
36{
37 m_world = nullptr;
38 m_currentNode = nullptr;
39
42
45
46 // Init temporary variables (do not leave uninitialized members)
47 m_initialSegment = nullptr;
48 m_lastLength = 0;
49 m_lastDelay = 0;
51
52 m_netClass = nullptr;
53}
54
55
57{
58}
59
60
62{
63 return m_currentTraceP;
64}
65
66
68{
69 return m_originPair;
70}
71
72
73NODE* DP_MEANDER_PLACER::CurrentNode( bool aLoopsRemoved ) const
74{
75 if( !m_currentNode )
76 return m_world;
77
78 return m_currentNode;
79}
80
81
82bool DP_MEANDER_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem )
83{
84 if( !aStartItem || !aStartItem->OfKind( ITEM::SEGMENT_T | ITEM::ARC_T ) )
85 {
86 Router()->SetFailureReason( _( "Please select a track whose length you want to tune." ) );
87 return false;
88 }
89
90 m_initialSegment = static_cast<LINKED_ITEM*>( aStartItem );
91 m_currentNode = nullptr;
93
94 m_world = Router()->GetWorld()->Branch();
95
96 TOPOLOGY topo( m_world );
97
99 {
100 Router()->SetFailureReason( _( "Unable to find complementary differential pair "
101 "net for length tuning. Make sure the names of the nets "
102 "belonging to a differential pair end with either _N/_P "
103 "or +/-." ) );
104 return false;
105 }
106
107 if( m_originPair.Gap() < 0 )
108 m_originPair.SetGap( Router()->Sizes().DiffPairGap() );
109
111 return false;
112
113 m_tunedPathP = topo.AssembleTuningPath( Router()->GetInterface(), m_originPair.PLine().GetLink( 0 ), &m_startPad_p,
114 &m_endPad_p );
115
118
119 if( m_startPad_p )
120 {
123 }
124
125 if( m_endPad_p )
126 {
129 }
130
131 m_tunedPathN = topo.AssembleTuningPath( Router()->GetInterface(), m_originPair.NLine().GetLink( 0 ), &m_startPad_n,
132 &m_endPad_n );
133
136
137 if( m_startPad_n )
138 {
141 }
142
143 if( m_endPad_n )
144 {
147 }
148
151
153
154 const BOARD_CONNECTED_ITEM* conItem = static_cast<BOARD_CONNECTED_ITEM*>( aStartItem->GetSourceItem() );
155 m_netClass = conItem->GetEffectiveNetClass();
156
158
159 return true;
160}
161
162
164{
165}
166
167
169{
172 return std::max( totalP, totalN );
173}
174
175
177{
178 const int64_t totalP = m_padToDieDelayP + lineDelay( m_tunedPathP, m_startPad_p, m_endPad_p );
179 const int64_t totalN = m_padToDieDelayP + lineDelay( m_tunedPathN, m_startPad_n, m_endPad_n );
180 return std::max( totalP, totalN );
181}
182
183
185{
186 const VECTOR2I a( ( aCoupledSegs.coupledP.A + aCoupledSegs.coupledN.A ) / 2 );
187 const VECTOR2I b( ( aCoupledSegs.coupledP.B + aCoupledSegs.coupledN.B ) / 2 );
188
189 return SEG( a, b );
190}
191
192
194{
195 VECTOR2I midp = ( aPair.coupledP.A + aPair.coupledN.A ) / 2;
196
197 //DrawDebugPoint(midp, 6);
198
199 return aPair.coupledP.Side( midp ) > 0;
200}
201
202
203bool DP_MEANDER_PLACER::Move( const VECTOR2I& aP, ITEM* aEndItem )
204{
206
207 if( m_currentStart == aP )
208 return false;
209
210 DIFF_PAIR::COUPLED_SEGMENTS_VEC coupledSegments;
211
212 if( m_currentNode )
213 delete m_currentNode;
214
216
217 SHAPE_LINE_CHAIN preP, tunedP, postP;
218 SHAPE_LINE_CHAIN preN, tunedN, postN;
219
220 m_originPair.CP().Split( m_currentStart, aP, preP, tunedP, postP );
221 m_originPair.CN().Split( m_currentStart, aP, preN, tunedN, postN );
222
223 auto updateStatus =
224 [&]()
225 {
230 else
232 };
233
234 DIFF_PAIR tuned( m_originPair );
235
236 tuned.SetShape( tunedP, tunedN );
237
238 tuned.CoupledSegmentPairs( coupledSegments );
239
240 if( coupledSegments.size() == 0 )
241 {
242 // Tuning started at an uncoupled area of the DP; we won't get a valid result until the
243 // cursor is moved far enough along a coupled area. Prevent the track from disappearing and
244 // the length from being zero by just using the original.
248 updateStatus();
249
250 return false;
251 }
252
253 m_result = MEANDERED_LINE( this, true );
254 m_result.SetWidth( tuned.Width() );
255
256 int offset = ( tuned.Gap() + tuned.Width() ) / 2;
257
258 if( pairOrientation( coupledSegments[0] ) )
259 offset *= -1;
260
261 m_result.SetBaselineOffset( offset );
262
263 for( const ITEM* item : m_tunedPathP.CItems() )
264 {
265 if( const LINE* l = dyn_cast<const LINE*>( item ) )
266 {
267 PNS_DBG( Dbg(), AddShape, &l->CLine(), YELLOW, 10000, wxT( "tuned-path-p" ) );
268
269 m_router->GetInterface()->DisplayPathLine( l->CLine(), 1 );
270 }
271 }
272
273 for( const ITEM* item : m_tunedPathN.CItems() )
274 {
275 if( const LINE* l = dyn_cast<const LINE*>( item ) )
276 {
277 PNS_DBG( Dbg(), AddShape, &l->CLine(), YELLOW, 10000, wxT( "tuned-path-n" ) );
278
279 m_router->GetInterface()->DisplayPathLine( l->CLine(), 1 );
280 }
281 }
282
283 int curIndexP = 0, curIndexN = 0;
284
285 for( const DIFF_PAIR::COUPLED_SEGMENTS& sp : coupledSegments )
286 {
287 SEG base = baselineSegment( sp );
288 bool side = false;
289
290 if( m_settings.m_initialSide == 0 )
291 side = base.Side( aP ) < 0;
292 else
293 side = m_settings.m_initialSide < 0;
294
295 PNS_DBG( Dbg(), AddShape, base, GREEN, 10000, wxT( "dp-baseline" ) );
296
297 while( sp.indexP >= curIndexP && curIndexP != -1 )
298 {
299 if( tunedP.IsArcSegment( curIndexP ) )
300 {
301 ssize_t arcIndex = tunedP.ArcIndex( curIndexP );
302
303 m_result.AddArcAndPt( tunedP.Arc( arcIndex ), tunedN.CPoint( curIndexN ) );
304 }
305 else
306 {
307 m_result.AddCorner( tunedP.CPoint( curIndexP ), tunedN.CPoint( curIndexN ) );
308 }
309
310 curIndexP = tunedP.NextShape( curIndexP );
311 }
312
313 while( sp.indexN >= curIndexN && curIndexN != -1 )
314 {
315 if( tunedN.IsArcSegment( curIndexN ) )
316 {
317 ssize_t arcIndex = tunedN.ArcIndex( curIndexN );
318
319 m_result.AddPtAndArc( tunedP.CPoint( sp.indexP ), tunedN.Arc( arcIndex ) );
320 }
321 else
322 {
323 m_result.AddCorner( tunedP.CPoint( sp.indexP ), tunedN.CPoint( curIndexN ) );
324 }
325
326 curIndexN = tunedN.NextShape( curIndexN );
327 }
328
329 m_result.MeanderSegment( base, side );
330 }
331
332 while( curIndexP < tunedP.PointCount() && curIndexP != -1 )
333 {
334 if( tunedP.IsArcSegment( curIndexP ) )
335 {
336 ssize_t arcIndex = tunedP.ArcIndex( curIndexP );
337
338 m_result.AddArcAndPt( tunedP.Arc( arcIndex ), tunedN.CPoint( curIndexN ) );
339 }
340 else
341 {
342 m_result.AddCorner( tunedP.CPoint( curIndexP ), tunedN.CPoint( curIndexN ) );
343 }
344
345 curIndexP = tunedP.NextShape( curIndexP );
346 }
347
348 while( curIndexN < tunedN.PointCount() && curIndexN != -1 )
349 {
350 if( tunedN.IsArcSegment( curIndexN ) )
351 {
352 ssize_t arcIndex = tunedN.ArcIndex( curIndexN );
353
354 m_result.AddPtAndArc( tunedP.CPoint( -1 ), tunedN.Arc( arcIndex ) );
355 }
356 else
357 {
358 m_result.AddCorner( tunedP.CPoint( -1 ), tunedN.CPoint( curIndexN ) );
359 }
360
361 curIndexN = tunedN.NextShape( curIndexN );
362 }
363
364 m_result.AddCorner( tunedP.CPoint( -1 ), tunedN.CPoint( -1 ) );
365
366 long long int dpLen = origPathLength();
367 int64_t dpDelay = origPathDelay();
368
370
371 if( dpLen > m_settings.m_targetLength.Max() )
372 {
374 m_lastLength = dpLen;
375 m_lastDelay = dpDelay;
376 }
377 else
378 {
379 m_lastLength = dpLen - std::max( tunedP.Length(), tunedN.Length() );
380
382 {
383 int64_t tunedPDelay = m_router->GetInterface()->CalculateDelayForShapeLineChain(
384 tunedP, GetOriginPair().Width(), true, GetOriginPair().Gap(), m_router->GetCurrentLayer(),
385 m_netClass );
386 int64_t tunedNDelay = m_router->GetInterface()->CalculateDelayForShapeLineChain(
387 tunedN, GetOriginPair().Width(), true, GetOriginPair().Gap(), m_router->GetCurrentLayer(),
388 m_netClass );
389
390 m_lastDelay = dpDelay - std::max( tunedPDelay, tunedNDelay );
391 }
392
394 }
395
396 if( m_lastStatus != TOO_LONG )
397 {
398 tunedP.Clear();
399 tunedN.Clear();
400
401 for( MEANDER_SHAPE* m : m_result.Meanders() )
402 {
403 if( m->Type() != MT_EMPTY )
404 {
405 tunedP.Append( m->CLine( 0 ) );
406 tunedN.Append( m->CLine( 1 ) );
407 }
408 }
409
410 m_lastLength += std::max( tunedP.Length(), tunedN.Length() );
411
413 {
414 int64_t tunedPDelay = m_router->GetInterface()->CalculateDelayForShapeLineChain(
415 tunedP, GetOriginPair().Width(), true, GetOriginPair().Gap(), m_router->GetCurrentLayer(),
416 m_netClass );
417 int64_t tunedNDelay = m_router->GetInterface()->CalculateDelayForShapeLineChain(
418 tunedN, GetOriginPair().Width(), true, GetOriginPair().Gap(), m_router->GetCurrentLayer(),
419 m_netClass );
420
421 m_lastDelay += std::max( tunedPDelay, tunedNDelay );
422 }
423
424 updateStatus();
425 }
426
429
431 {
432 preP.Simplify();
433 tunedP.Simplify();
434 postP.Simplify();
435
436 m_finalShapeP.Append( preP );
437 m_finalShapeP.Append( tunedP );
438 m_finalShapeP.Append( postP );
439
440 preN.Simplify();
441 tunedN.Simplify();
442 postN.Simplify();
443
444 m_finalShapeN.Append( preN );
445 m_finalShapeN.Append( tunedN );
446 m_finalShapeN.Append( postN );
447 }
448 else
449 {
450 m_finalShapeP.Append( preP );
451 m_finalShapeP.Append( tunedP );
452 m_finalShapeP.Append( postP );
454
455 m_finalShapeN.Append( preN );
456 m_finalShapeN.Append( tunedN );
457 m_finalShapeN.Append( postN );
459 }
460
461 return true;
462}
463
464
465bool DP_MEANDER_PLACER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinish )
466{
469
470 m_currentNode->Add( lP );
471 m_currentNode->Add( lN );
472
474
475 return true;
476}
477
478
480{
482 return true;
483}
484
485
487{
488 return m_originPair.CP().SegmentCount() > 0 || m_originPair.CN().SegmentCount() > 0;
489}
490
491
493{
494 if( m_currentNode )
496
497 m_currentNode = nullptr;
498 return true;
499}
500
501
503{
504 LINE l1( m_originPair.PLine(), aShape->CLine( 0 ) );
505 LINE l2( m_originPair.NLine(), aShape->CLine( 1 ) );
506
507 if( m_currentNode->CheckColliding( &l1 ) )
508 return false;
509
510 if( m_currentNode->CheckColliding( &l2 ) )
511 return false;
512
513 int w = aShape->Width();
514 int clearance = w + w * 3;
515
516 return m_result.CheckSelfIntersections( aShape, clearance );
517}
518
519
521{
524
525 ITEM_SET traces;
526
527 traces.Add( &m_currentTraceP );
528 traces.Add( &m_currentTraceN );
529
530 return traces;
531}
532
533
535{
536 ITEM_SET lines;
537
538 for( ITEM* item : m_tunedPathN )
539 lines.Add( item );
540
541 for( ITEM* item : m_tunedPathP )
542 lines.Add( item );
543
544 return lines;
545}
546
547
549{
550 return m_currentStart;
551}
552
553
555{
556 return m_currentEnd;
557}
558
559
561{
562 return m_initialSegment->Layers().Start();
563}
564
565
567{
568 if( m_lastLength )
569 return m_lastLength;
570 else
571 return origPathLength();
572}
573
574
576{
577 if( m_lastDelay )
578 return m_lastDelay;
579 else
580 return origPathDelay();
581}
582
583
585{
586 return m_lastStatus;
587}
588
589
590const std::vector<NET_HANDLE> DP_MEANDER_PLACER::CurrentNets() const
591{
592 std::vector<NET_HANDLE> rv;
593 rv.push_back( m_originPair.NetP() );
594 rv.push_back( m_originPair.NetN() );
595 return rv;
596}
597
598
600{
601 // If this is a time domain tuning, calculate the target length for the desired total delay
603 {
604 const int64_t curDelay = origPathDelay();
605
606 const int64_t desiredDelayMin = m_settings.m_targetLengthDelay.Min();
607 const int64_t desiredDelayOpt = m_settings.m_targetLengthDelay.Opt();
608 const int64_t desiredDelayMax = m_settings.m_targetLengthDelay.Max();
609
610 const int64_t delayDifferenceOpt = desiredDelayOpt - curDelay;
611
612 const int64_t curLength = origPathLength();
613 const int64_t lengthDiffMin = m_router->GetInterface()->CalculateLengthForDelay(
614 desiredDelayOpt - desiredDelayMin, GetOriginPair().Width(), true, GetOriginPair().Gap(),
616 int64_t lengthDiffOpt = m_router->GetInterface()->CalculateLengthForDelay(
617 std::abs( delayDifferenceOpt ), GetOriginPair().Width(), true, GetOriginPair().Gap(),
619 const int64_t lengthDiffMax = m_router->GetInterface()->CalculateLengthForDelay(
620 desiredDelayMax - desiredDelayOpt, GetOriginPair().Width(), true, GetOriginPair().Gap(),
622
623 lengthDiffOpt = delayDifferenceOpt > 0 ? lengthDiffOpt : -lengthDiffOpt;
624
625 m_settings.m_targetLength.SetMin( curLength + lengthDiffOpt - lengthDiffMin );
626 m_settings.m_targetLength.SetOpt( curLength + lengthDiffOpt );
627 m_settings.m_targetLength.SetMax( curLength + lengthDiffOpt + lengthDiffMax );
628 }
629}
630}
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
virtual NETCLASS * GetEffectiveNetClass() const
Return the NETCLASS for this item.
T Min() const
Definition: minoptmax.h:33
void SetMin(T v)
Definition: minoptmax.h:41
void SetOpt(T v)
Definition: minoptmax.h:43
void SetMax(T v)
Definition: minoptmax.h:42
T Max() const
Definition: minoptmax.h:34
T Opt() const
Definition: minoptmax.h:35
ROUTER * Router() const
Return current router settings.
Definition: pns_algo_base.h:54
ROUTER * m_router
Definition: pns_algo_base.h:87
DEBUG_DECORATOR * Dbg() const
Definition: pns_algo_base.h:78
Basic class for a differential pair.
const SHAPE_LINE_CHAIN & CN() const
int Width() const
std::vector< COUPLED_SEGMENTS > COUPLED_SEGMENTS_VEC
void SetShape(const SHAPE_LINE_CHAIN &aP, const SHAPE_LINE_CHAIN &aN, bool aSwapLanes=false)
int Gap() const
NET_HANDLE NetP() const
void SetGap(int aGap)
const SHAPE_LINE_CHAIN & CP() const
void CoupledSegmentPairs(COUPLED_SEGMENTS_VEC &aPairs) const
NET_HANDLE NetN() const
bool Start(const VECTOR2I &aP, ITEM *aStartItem) override
Start routing a single track at point aP, taking item aStartItem as anchor (unless NULL).
bool CheckFit(MEANDER_SHAPE *aShape) override
Checks if it's OK to place the shape aShape (i.e.
const ITEM_SET Traces() override
Function Traces()
bool pairOrientation(const DIFF_PAIR::COUPLED_SEGMENTS &aPair)
DP_MEANDER_PLACER(ROUTER *aRouter)
void calculateTimeDomainTargets()
Current routing start point (end of tail, beginning of head).
VECTOR2I m_currentStart
Current world state.
bool FixRoute(const VECTOR2I &aP, ITEM *aEndItem, bool aForceFinish=false) override
Commit the currently routed track to the parent node, taking aP as the final end point and aEndItem a...
int CurrentLayer() const override
Function CurrentLayer()
TUNING_STATUS TuningStatus() const override
Return the tuning status (too short, too long, etc.) of the trace(s) being tuned.
long long int TuningLengthResult() const override
Return the resultant length or skew of the tuned traces.
const SEG baselineSegment(const DIFF_PAIR::COUPLED_SEGMENTS &aCoupledSegs)
const DIFF_PAIR & GetOriginPair()
const ITEM_SET TunedPath() override
bool HasPlacedAnything() const override
bool Move(const VECTOR2I &aP, ITEM *aEndItem) override
Move the end of the currently routed trace to the point aP, taking aEndItem as anchor (if not NULL).
const VECTOR2I & CurrentEnd() const override
Function CurrentEnd()
const VECTOR2I & CurrentStart() const override
Function CurrentStart()
int64_t TuningDelayResult() const override
Return the resultant delay or skew of the tuned traces.
long long int origPathLength() const
const std::vector< NET_HANDLE > CurrentNets() const override
Function CurrentNets()
NODE * CurrentNode(bool aLoopsRemoved=false) const override
Return the most recent world state.
void Add(const LINE &aLine)
Definition: pns_itemset.cpp:33
const std::vector< ITEM * > & CItems() const
Definition: pns_itemset.h:88
Base class for PNS router board items.
Definition: pns_item.h:98
const PNS_LAYER_RANGE & Layers() const
Definition: pns_item.h:212
BOARD_ITEM * GetSourceItem() const
Definition: pns_item.h:202
@ SEGMENT_T
Definition: pns_item.h:107
bool OfKind(int aKindMask) const
Definition: pns_item.h:181
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
Definition: pns_line.h:62
int SegmentCount() const
Definition: pns_line.h:140
Represent a set of meanders fitted over a single or two lines.
Definition: pns_meander.h:447
void SetBaselineOffset(int aOffset)
Set the parallel offset between the base segment and the meandered line.
Definition: pns_meander.h:542
void SetWidth(int aWidth)
Set the line width.
Definition: pns_meander.h:527
void AddCorner(const VECTOR2I &aA, const VECTOR2I &aB=VECTOR2I(0, 0))
Create a dummy meander shape representing a line corner.
void MeanderSegment(const SEG &aSeg, bool aSide, int aBaseIndex=0)
Fit maximum amplitude meanders on a given segment and adds to the current line.
void AddArcAndPt(const SHAPE_ARC &aArc1, const VECTOR2I &aPt2)
Create a dummy meander shape representing an arc corner.
bool CheckSelfIntersections(MEANDER_SHAPE *aShape, int aClearance)
Check if the given shape is intersecting with any other meander in the current line.
std::vector< MEANDER_SHAPE * > & Meanders()
Definition: pns_meander.h:550
void AddPtAndArc(const VECTOR2I &aPt1, const SHAPE_ARC &aArc2)
Create a dummy meander shape representing an arc corner.
Base class for Single trace & Differential pair meandering tools, as both of them share a lot of code...
void tuneLineLength(MEANDERED_LINE &aTuned, long long int aElongation)
Take a set of meanders in aTuned and tunes their length to extend the original line length by aElonga...
TUNING_STATUS
< Result of the length tuning operation
int m_currentWidth
Meander settings.
MEANDER_SETTINGS m_settings
The current end point.
int64_t lineDelay(const ITEM_SET &aLine, const SOLID *aStartPad, const SOLID *aEndPad) const
Calculate the total delay of the line represented by an item set (tracks and vias)
NODE * m_world
Width of the meandered trace(s).
VECTOR2I getSnappedStartPoint(LINKED_ITEM *aStartItem, VECTOR2I aStartPoint)
long long int lineLength(const ITEM_SET &aLine, const SOLID *aStartPad, const SOLID *aEndPad) const
Calculate the total length of the line represented by an item set (tracks and vias)
bool m_isTimeDomain
The net class this meander pattern belongs to.
Definition: pns_meander.h:140
MEANDER_SIDE m_initialSide
Allowable tuning error.
Definition: pns_meander.h:131
MINOPTMAX< long long int > m_targetLength
Desired propagation delay of the tuned line.
Definition: pns_meander.h:108
bool m_keepEndpoints
Calculate tuning in the time domain.
Definition: pns_meander.h:137
MINOPTMAX< long long int > m_targetLengthDelay
Target skew value for diff pair de-skewing.
Definition: pns_meander.h:111
The geometry of a single meander.
Definition: pns_meander.h:150
int Width() const
Definition: pns_meander.h:332
const SHAPE_LINE_CHAIN & CLine(int aShape) const
Definition: pns_meander.h:272
Keep the router "world" - i.e.
Definition: pns_node.h:232
NODE * Branch()
Create a lightweight copy (called branch) of self that tracks the changes (added/removed items) wrs t...
Definition: pns_node.cpp:143
OPT_OBSTACLE CheckColliding(const ITEM *aItem, int aKindMask=ITEM::ANY_T)
Check if the item collides with anything else in the world, and if found, returns the obstacle.
Definition: pns_node.cpp:410
bool Add(std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant=false)
Add an item to the current node.
Definition: pns_node.cpp:665
void KillChildren()
Definition: pns_node.cpp:1546
void Remove(ARC *aArc)
Remove an item from this branch.
Definition: pns_node.cpp:909
virtual void DisplayPathLine(const SHAPE_LINE_CHAIN &aLine, int aImportance)=0
virtual int64_t CalculateDelayForShapeLineChain(const SHAPE_LINE_CHAIN &aShape, int aWidth, bool aIsDiffPairCoupled, int aDiffPairCouplingGap, int aPNSLayer, const NETCLASS *aNetClass)=0
virtual int64_t CalculateLengthForDelay(int64_t aDesiredDelay, int aWidth, bool aIsDiffPairCoupled, int aDiffPairCouplingGap, int aPNSLayer, const NETCLASS *aNetClass)=0
ROUTER_IFACE * GetInterface() const
Definition: pns_router.h:232
void SetFailureReason(const wxString &aReason)
Definition: pns_router.h:227
void CommitRouting()
Definition: pns_router.cpp:921
int GetCurrentLayer() const
NODE * GetWorld() const
Definition: pns_router.h:178
int GetPadToDie() const
Definition: pns_solid.h:120
int GetPadToDieDelay() const
Definition: pns_solid.h:123
const DIFF_PAIR AssembleDiffPair(SEGMENT *aStart)
const ITEM_SET AssembleTuningPath(ROUTER_IFACE *aRouterIface, ITEM *aStart, SOLID **aStartPad=nullptr, SOLID **aEndPad=nullptr)
Like AssembleTrivialPath, but follows the track length algorithm, which discards segments that are fu...
int Start() const
Definition: pns_layerset.h:86
Definition: seg.h:42
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50
int Side(const VECTOR2I &aP) const
Determine on which side of directed line passing via segment ends point aP lies.
Definition: seg.h:143
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
const SHAPE_ARC & Arc(size_t aArc) const
int Split(const VECTOR2I &aP, bool aExact=false)
Insert the point aP belonging to one of the our segments, splitting the adjacent segment in two.
void Simplify(int aMaxError=0)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
int PointCount() const
Return the number of points (vertices) in this line chain.
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
void Clear()
Remove all points from the line chain.
int NextShape(int aPointIndex) const
Return the vertex index of the next shape in the chain, or -1 if aPointIndex is the last shape.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
int SegmentCount() const
Return the number of segments in this line chain.
bool IsArcSegment(size_t aSegment) const
long long int Length() const
Return length of the line chain in Euclidean metric.
@ GREEN
Definition: color4d.h:57
@ YELLOW
Definition: color4d.h:67
#define _(s)
Push and Shove diff pair dimensions (gap) settings dialog.
@ MT_EMPTY
Definition: pns_meander.h:47
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:393
#define PNS_DBG(dbg, method,...)
int clearance