KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pns_meander.h
Go to the documentation of this file.
1/*
2 * KiRouter - a push-and-(sometimes-)shove PCB router
3 *
4 * Copyright (C) 2013-2015 CERN
5 * Copyright (C) 2016-2022 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * @author Tomasz Wlostowski <[email protected]>
8 *
9 * This program is free software: you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation, either version 3 of the License, or (at your
12 * option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23#ifndef __PNS_MEANDER_H
24#define __PNS_MEANDER_H
25
26#include <math/vector2d.h>
27#include <core/minoptmax.h>
28
29#include <geometry/shape.h>
31
32namespace PNS {
33
34class MEANDER_PLACER_BASE;
35class MEANDERED_LINE;
36
39 MT_SINGLE, // _|^|_, single-sided
40 MT_START, // _|^|
41 MT_FINISH, // |^|_
42 MT_TURN, // |^| or |_|
43 MT_CHECK_START, // try fitting a start type, but don't produce a line
44 MT_CHECK_FINISH, // try fitting a finish type, but don't produce a line
45 MT_CORNER, // line corner
46 MT_ARC, // arc corner
47 MT_EMPTY // no meander (straight line)
48};
49
52 MEANDER_STYLE_ROUND = 1, // rounded (90 degree arc)
53 MEANDER_STYLE_CHAMFER // chamfered (45 degree segment)
54};
55
58{
62};
63
68{
69#define DEFAULT_TOLERANCE 100000
70
71public:
72
74 {
75 m_minAmplitude = 100000;
76 m_maxAmplitude = 1000000;
77 m_step = 50000;
78 m_lenPadToDie = 0;
79 m_spacing = 600000;
80 SetTargetLength( 100000000 );
81 SetTargetSkew( 0 );
85 m_singleSided = false;
88 m_keepEndpoints = false;
89 }
90
91 void SetTargetLength( long long int aOpt )
92 {
93 m_targetLength.SetOpt( aOpt );
96 }
97
98 void SetTargetLength( const MINOPTMAX<int>& aConstraint )
99 {
100 SetTargetLength( aConstraint.Opt() );
101
102 if( aConstraint.HasMin() )
103 m_targetLength.SetMin( aConstraint.Min() );
104
105 if( aConstraint.HasMax() )
106 m_targetLength.SetMax( aConstraint.Max() );
107 }
108
109 void SetTargetSkew( int aOpt )
110 {
111 m_targetSkew.SetOpt( aOpt );
114 }
115
116 void SetTargetSkew( const MINOPTMAX<int>& aConstraint )
117 {
118 SetTargetSkew( aConstraint.Opt() );
119
120 if( aConstraint.HasMin() )
121 m_targetSkew.SetMin( aConstraint.Min() );
122
123 if( aConstraint.HasMax() )
124 m_targetSkew.SetMax( aConstraint.Max() );
125 }
126
129
132
135
138
141
144
147
149
152
155
158
161
164
167};
168
173{
174public:
181 MEANDER_SHAPE( MEANDER_PLACER_BASE* aPlacer, int aWidth, bool aIsDual = false ) :
182 m_placer( aPlacer ),
183 m_dual( aIsDual ),
184 m_width( aWidth ),
186 {
187 // Do not leave uninitialized members, and keep static analyzer quiet:
189 m_amplitude = 0;
190 m_targetBaseLen = 0;
191 m_side = false;
192 m_baseIndex = 0;
193 m_currentTarget = nullptr;
195 }
196
200 void SetType( MEANDER_TYPE aType )
201 {
202 m_type = aType;
203 }
204
209 {
210 return m_type;
211 }
212
216 void SetBaseIndex( int aIndex )
217 {
218 m_baseIndex = aIndex;
219 }
220
224 int BaseIndex() const
225 {
226 return m_baseIndex;
227 }
228
232 int Amplitude() const
233 {
234 return m_amplitude;
235 }
236
244 void MakeCorner( const VECTOR2I& aP1, const VECTOR2I& aP2 = VECTOR2I( 0, 0 ) );
245
253 void MakeArc( const SHAPE_ARC& aArc1, const SHAPE_ARC& aArc2 = SHAPE_ARC() );
254
261 void Resize( int aAmpl );
262
266 void Recalculate();
267
271 bool IsDual() const
272 {
273 return m_dual;
274 }
275
279 bool Side() const
280 {
281 return m_side;
282 }
283
287 VECTOR2I End() const
288 {
289 return m_clippedBaseSeg.B;
290 }
291
295 const SHAPE_LINE_CHAIN& CLine( int aShape ) const
296 {
297 return m_shapes[aShape];
298 }
299
303 void MakeEmpty();
304
315 bool Fit( MEANDER_TYPE aType, const SEG& aSeg, const VECTOR2I& aP, bool aSide );
316
322 const SEG& BaseSegment() const
323 {
324 return m_clippedBaseSeg;
325 }
326
330 int BaselineLength() const;
331
335 long long int CurrentLength() const;
336
340 long long int MinTunableLength() const;
341
345 int MinAmplitude() const;
346
350 const MEANDER_SETTINGS& Settings() const;
351
355 int Width() const
356 {
357 return m_width;
358 }
359
366 void SetBaselineOffset( int aOffset )
367 {
368 m_baselineOffset = aOffset;
369 }
370
377 void SetTargetBaselineLength( int aLength ) { m_targetBaseLen = aLength; }
378
379private:
380 friend class MEANDERED_LINE;
381
383 void start( SHAPE_LINE_CHAIN* aTarget, const VECTOR2D& aWhere, const VECTOR2D& aDir );
384
386 void forward( int aLength );
387
389 void turn( const EDA_ANGLE& aAngle );
390
392 void miter( int aRadius, bool aSide );
393
395 void uShape( int aSides, int aCorner, int aTop );
396
398 SHAPE_LINE_CHAIN makeMiterShape( const VECTOR2D& aP, const VECTOR2D& aDir, bool aSide );
399
401 SHAPE_LINE_CHAIN genMeanderShape( const VECTOR2D& aP, const VECTOR2D& aDir, bool aSide,
402 MEANDER_TYPE aType, int aBaselineOffset = 0 );
403
405 void updateBaseSegment();
406
408 int cornerRadius() const;
409
411 int spacing() const;
412
415
418
420 bool m_dual;
421
424
427
430
433
436
439
442
445
447 bool m_side;
448
451
454
457
460
463};
464
465
470{
471public:
473 {
474 // Do not leave uninitialized members, and keep static analyzer quiet:
475 m_placer = nullptr;
476 m_dual = false;
477 m_width = 0;
479 }
480
485 MEANDERED_LINE( MEANDER_PLACER_BASE* aPlacer, bool aIsDual = false ) :
486 m_placer( aPlacer ),
487 m_dual( aIsDual )
488 {
489 // Do not leave uninitialized members, and keep static analyzer quiet:
490 m_width = 0;
492 }
493
495 {
496 Clear();
497 }
498
506 void AddCorner( const VECTOR2I& aA, const VECTOR2I& aB = VECTOR2I( 0, 0 ) );
507
515 void AddArc( const SHAPE_ARC& aArc1, const SHAPE_ARC& aArc2 = SHAPE_ARC() );
516
524 void AddArcAndPt( const SHAPE_ARC& aArc1, const VECTOR2I& aPt2 );
525
533 void AddPtAndArc( const VECTOR2I& aPt1, const SHAPE_ARC& aArc2 );
534
540 void AddMeander( MEANDER_SHAPE* aShape );
541
545 void Clear();
546
550 void SetWidth( int aWidth )
551 {
552 m_width = aWidth;
553 }
554
562 void MeanderSegment( const SEG& aSeg, bool aSide, int aBaseIndex = 0 );
563
565 void SetBaselineOffset( int aOffset )
566 {
567 m_baselineOffset = aOffset;
568 }
569
573 std::vector<MEANDER_SHAPE*>& Meanders()
574 {
575 return m_meanders;
576 }
577
585 bool CheckSelfIntersections( MEANDER_SHAPE* aShape, int aClearance );
586
590 const MEANDER_SETTINGS& Settings() const;
591
592private:
594
596 std::vector<MEANDER_SHAPE*> m_meanders;
597
598 bool m_dual;
601};
602
603}
604
605#endif // __PNS_MEANDER_H
T Min() const
Definition: minoptmax.h:33
void SetMin(T v)
Definition: minoptmax.h:41
bool HasMax() const
Definition: minoptmax.h:38
void SetOpt(T v)
Definition: minoptmax.h:43
bool HasMin() const
Definition: minoptmax.h:37
void SetMax(T v)
Definition: minoptmax.h:42
T Max() const
Definition: minoptmax.h:34
T Opt() const
Definition: minoptmax.h:35
Represent a set of meanders fitted over a single or two lines.
Definition: pns_meander.h:470
void AddMeander(MEANDER_SHAPE *aShape)
Add a new meander shape to the meandered line.
MEANDER_PLACER_BASE * m_placer
Definition: pns_meander.h:595
void SetBaselineOffset(int aOffset)
Set the parallel offset between the base segment and the meandered line.
Definition: pns_meander.h:565
void SetWidth(int aWidth)
Set the line width.
Definition: pns_meander.h:550
void AddCorner(const VECTOR2I &aA, const VECTOR2I &aB=VECTOR2I(0, 0))
Create a dummy meander shape representing a line corner.
void Clear()
Clear the line geometry, removing all corners and meanders.
std::vector< MEANDER_SHAPE * > m_meanders
Definition: pns_meander.h:596
void MeanderSegment(const SEG &aSeg, bool aSide, int aBaseIndex=0)
Fit maximum amplitude meanders on a given segment and adds to the current line.
Definition: pns_meander.cpp:43
void AddArc(const SHAPE_ARC &aArc1, const SHAPE_ARC &aArc2=SHAPE_ARC())
Create a dummy meander shape representing an arc corner.
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.
const MEANDER_SETTINGS & Settings() const
Definition: pns_meander.cpp:37
MEANDERED_LINE(MEANDER_PLACER_BASE *aPlacer, bool aIsDual=false)
Definition: pns_meander.h:485
std::vector< MEANDER_SHAPE * > & Meanders()
Definition: pns_meander.h:573
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...
Dimensions for the meandering algorithm.
Definition: pns_meander.h:68
int m_minAmplitude
Maximum meandering amplitude.
Definition: pns_meander.h:128
void SetTargetLength(long long int aOpt)
Definition: pns_meander.h:91
int m_cornerRadiusPercentage
Place meanders on one side.
Definition: pns_meander.h:154
MEANDER_SIDE m_initialSide
Allowable tuning error.
Definition: pns_meander.h:160
bool m_singleSided
Initial side when placing meanders at segment.
Definition: pns_meander.h:157
MINOPTMAX< long long int > m_targetLength
Target skew value for diff pair de-skewing.
Definition: pns_meander.h:143
void SetTargetSkew(int aOpt)
Definition: pns_meander.h:109
int m_lengthTolerance
Keep vertices between pre, tuned and post parts of the line.
Definition: pns_meander.h:163
int m_step
Length PadToDie.
Definition: pns_meander.h:137
MINOPTMAX< int > m_targetSkew
Definition: pns_meander.h:146
MEANDER_STYLE m_cornerStyle
Rounding percentage (0 - 100).
Definition: pns_meander.h:151
void SetTargetSkew(const MINOPTMAX< int > &aConstraint)
Minimum meandering amplitude.
Definition: pns_meander.h:116
int m_maxAmplitude
Meandering period/spacing (see dialog picture for explanation).
Definition: pns_meander.h:131
bool m_overrideCustomRules
Type of corners for the meandered line.
Definition: pns_meander.h:148
void SetTargetLength(const MINOPTMAX< int > &aConstraint)
Definition: pns_meander.h:98
int m_lenPadToDie
Desired length of the tuned line/diff pair (this is in nm, so allow more than board width).
Definition: pns_meander.h:140
int m_spacing
Amplitude/spacing adjustment step.
Definition: pns_meander.h:134
The geometry of a single meander.
Definition: pns_meander.h:173
MEANDER_TYPE m_type
The placer that placed this meander.
Definition: pns_meander.h:414
int MinAmplitude() const
MEANDER_PLACER_BASE * m_placer
Dual or single line.
Definition: pns_meander.h:417
SEG m_baseSeg
Base segment (clipped).
Definition: pns_meander.h:441
MEANDER_SHAPE(MEANDER_PLACER_BASE *aPlacer, int aWidth, bool aIsDual=false)
Definition: pns_meander.h:181
SEG m_clippedBaseSeg
Side (true = right).
Definition: pns_meander.h:444
int Amplitude() const
Definition: pns_meander.h:232
void SetType(MEANDER_TYPE aType)
Set the type of the meander.
Definition: pns_meander.h:200
int m_targetBaseLen
First point of the meandered line.
Definition: pns_meander.h:435
VECTOR2I End() const
Definition: pns_meander.h:287
SHAPE_LINE_CHAIN genMeanderShape(const VECTOR2D &aP, const VECTOR2D &aDir, bool aSide, MEANDER_TYPE aType, int aBaselineOffset=0)
Recalculate the clipped baseline after the parameters of the meander have been changed.
void start(SHAPE_LINE_CHAIN *aTarget, const VECTOR2D &aWhere, const VECTOR2D &aDir)
Move turtle forward by aLength.
void SetBaseIndex(int aIndex)
Set an auxiliary index of the segment being meandered in its original LINE.
Definition: pns_meander.h:216
int m_baselineOffset
Average radius of meander corners (for correction of DP meanders).
Definition: pns_meander.h:429
VECTOR2D m_currentDir
The current turtle position.
Definition: pns_meander.h:456
int m_width
Amplitude of the meander.
Definition: pns_meander.h:423
int BaseIndex() const
Definition: pns_meander.h:224
VECTOR2D m_currentPos
The line the turtle is drawing on.
Definition: pns_meander.h:459
SHAPE_LINE_CHAIN m_shapes[2]
Index of the meandered segment in the base line.
Definition: pns_meander.h:450
long long int CurrentLength() const
bool m_side
The actual shapes (0 used for single, both for dual).
Definition: pns_meander.h:447
bool Side() const
Definition: pns_meander.h:279
void updateBaseSegment()
Return sanitized corner radius value.
SHAPE_LINE_CHAIN makeMiterShape(const VECTOR2D &aP, const VECTOR2D &aDir, bool aSide)
Produce a meander shape of given type.
void MakeArc(const SHAPE_ARC &aArc1, const SHAPE_ARC &aArc2=SHAPE_ARC())
Create a dummy meander shape representing an arc corner.
void SetTargetBaselineLength(int aLength)
Sets the target length of the baseline.
Definition: pns_meander.h:377
int m_baseIndex
The current turtle direction.
Definition: pns_meander.h:453
SHAPE_LINE_CHAIN * m_currentTarget
Definition: pns_meander.h:462
bool m_dual
Width of the line.
Definition: pns_meander.h:420
void Recalculate()
Recalculate the line chain representing the meander's shape.
void miter(int aRadius, bool aSide)
Tell the turtle to draw an U-like shape.
long long int MinTunableLength() const
void Resize(int aAmpl)
Change the amplitude of the meander shape to aAmpl and recalculates the resulting line chain.
int m_meanCornerRadius
Minimum length of the base segment to target when resizing.
Definition: pns_meander.h:432
int Width() const
Definition: pns_meander.h:355
int spacing() const
The type of meander.
bool IsDual() const
Definition: pns_meander.h:271
int m_amplitude
Offset wrs the base segment (dual only).
Definition: pns_meander.h:426
int cornerRadius() const
Return sanitized spacing value.
void turn(const EDA_ANGLE &aAngle)
Tell the turtle to draw a mitered corner of given radius and turn direction.
void SetBaselineOffset(int aOffset)
Set the parallel offset between the base segment and the meandered line.
Definition: pns_meander.h:366
void forward(int aLength)
Turn the turtle by aAngle.
MEANDER_TYPE Type() const
Definition: pns_meander.h:208
VECTOR2I m_p0
Base segment (unclipped).
Definition: pns_meander.h:438
const MEANDER_SETTINGS & Settings() const
Definition: pns_meander.cpp:31
void MakeEmpty()
Replace the meander with straight bypass line(s), effectively clearing it.
bool Fit(MEANDER_TYPE aType, const SEG &aSeg, const VECTOR2I &aP, bool aSide)
Attempt to fit a meander of a given type onto a segment, avoiding collisions with other board feature...
void uShape(int aSides, int aCorner, int aTop)
Generate a 90-degree circular arc.
const SHAPE_LINE_CHAIN & CLine(int aShape) const
Definition: pns_meander.h:295
int BaselineLength() const
const SEG & BaseSegment() const
Return the base segment the meander was fitted to.
Definition: pns_meander.h:322
void MakeCorner(const VECTOR2I &aP1, const VECTOR2I &aP2=VECTOR2I(0, 0))
Create a dummy meander shape representing a line corner.
Definition: seg.h:42
VECTOR2I B
Definition: seg.h:50
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
Push and Shove diff pair dimensions (gap) settings dialog.
MEANDER_TYPE
Shapes of available meanders.
Definition: pns_meander.h:38
@ MT_ARC
Definition: pns_meander.h:46
@ MT_TURN
Definition: pns_meander.h:42
@ MT_CHECK_START
Definition: pns_meander.h:43
@ MT_CHECK_FINISH
Definition: pns_meander.h:44
@ MT_START
Definition: pns_meander.h:40
@ MT_FINISH
Definition: pns_meander.h:41
@ MT_EMPTY
Definition: pns_meander.h:47
@ MT_CORNER
Definition: pns_meander.h:45
@ MT_SINGLE
Definition: pns_meander.h:39
MEANDER_SIDE
Definition: pns_meander.h:58
@ MEANDER_SIDE_RIGHT
Definition: pns_meander.h:61
@ MEANDER_SIDE_DEFAULT
Definition: pns_meander.h:60
@ MEANDER_SIDE_LEFT
Definition: pns_meander.h:59
MEANDER_STYLE
Definition: pns_meander.h:51
@ MEANDER_STYLE_ROUND
Definition: pns_meander.h:52
@ MEANDER_STYLE_CHAMFER
Definition: pns_meander.h:53
#define DEFAULT_TOLERANCE
Definition: pns_meander.h:69
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588