KiCad PCB EDA Suite
pns_diff_pair.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 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 
23 #ifndef __PNS_DIFF_PAIR_H
24 #define __PNS_DIFF_PAIR_H
25 
26 #include <vector>
27 
28 #include <geometry/shape.h>
30 
31 #include "pns_line.h"
32 #include "pns_via.h"
33 
34 #include "ranged_num.h"
35 
36 namespace PNS {
37 
38 class DIFF_PAIR;
39 
47 class DP_GATEWAY {
48 public:
49  DP_GATEWAY( const VECTOR2I& aAnchorP,
50  const VECTOR2I& aAnchorN,
51  bool aIsDiagonal,
52  int aAllowedEntryAngles = DIRECTION_45::ANG_OBTUSE,
53  int aPriority = 0 )
54  : m_anchorP( aAnchorP ),
55  m_anchorN( aAnchorN ),
56  m_isDiagonal( aIsDiagonal ),
57  m_allowedEntryAngles( aAllowedEntryAngles ),
58  m_priority( aPriority )
59  {
60  m_hasEntryLines = false;
61  }
62 
64  {
65  }
66 
72  bool IsDiagonal() const
73  {
74  return m_isDiagonal;
75  }
76 
77  const VECTOR2I& AnchorP() const { return m_anchorP; }
78 
79  const VECTOR2I& AnchorN() const { return m_anchorN; }
80 
87  int AllowedAngles () const { return m_allowedEntryAngles; }
88 
94  int Priority() const
95  {
96  return m_priority;
97  }
98 
99  void SetPriority(int aPriority)
100  {
101  m_priority = aPriority;
102  }
103 
104  void SetEntryLines( const SHAPE_LINE_CHAIN& aEntryP, const SHAPE_LINE_CHAIN& aEntryN )
105  {
106  m_entryP = aEntryP;
107  m_entryN = aEntryN;
108  m_hasEntryLines = true;
109  }
110 
111  const SHAPE_LINE_CHAIN& EntryP() const { return m_entryP; }
112  const SHAPE_LINE_CHAIN& EntryN() const { return m_entryN; }
113  const DIFF_PAIR Entry() const ;
114 
115  void Reverse();
116 
117  bool HasEntryLines () const
118  {
119  return m_hasEntryLines;
120  }
121 
122 private:
129 };
130 
137 {
138 public:
140  m_primP( NULL ), m_primN( NULL ) {};
141 
142  DP_PRIMITIVE_PAIR( const DP_PRIMITIVE_PAIR& aOther );
143  DP_PRIMITIVE_PAIR( ITEM* aPrimP, ITEM* aPrimN );
144  DP_PRIMITIVE_PAIR( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN );
145 
147 
148  void SetAnchors( const VECTOR2I& aAnchorP, const VECTOR2I& aAnchorN );
149 
150  const VECTOR2I& AnchorP() const { return m_anchorP; }
151  const VECTOR2I& AnchorN() const { return m_anchorN; }
152 
154 
155  ITEM* PrimP() const { return m_primP; }
156  ITEM* PrimN() const { return m_primN; }
157 
158  bool Directional() const;
159 
160  DIRECTION_45 DirP() const;
161  DIRECTION_45 DirN() const;
162 
163 
164  void CursorOrientation( const VECTOR2I& aCursorPos, VECTOR2I& aMidpoint, VECTOR2I& aDirection ) const;
165 
166  void dump()
167  {
168  printf( "-- Prim-P %p anchor [%d, %d]\n", m_primP, m_anchorP.x, m_anchorP.y );
169  printf( "-- Prim-N %p anchor [%d, %d]\n", m_primN, m_anchorN.x, m_anchorN.y );
170  }
171 
172 private:
173  DIRECTION_45 anchorDirection( ITEM* aItem, const VECTOR2I& aP ) const;
174 
178 };
179 
187 {
188  public:
189  DP_GATEWAYS( int aGap ):
190  m_gap( aGap ), m_viaGap( aGap )
191  {
192  // Do not leave unitialized members, and keep static analyser quiet:
193  m_viaDiameter = 0;
194  m_fitVias = true;
195  }
196 
197  void SetGap( int aGap )
198  {
199  m_gap = aGap;
200  m_viaGap = aGap;
201  }
202 
203  void Clear()
204  {
205  m_gateways.clear();
206  }
207 
208  void SetFitVias( bool aEnable, int aDiameter = 0, int aViaGap = -1 )
209  {
210  m_fitVias = aEnable;
211  m_viaDiameter = aDiameter;
212  if(aViaGap < 0)
213  m_viaGap = m_gap;
214  else
215  m_viaGap = aViaGap;
216  }
217 
218 
219  void BuildForCursor( const VECTOR2I& aCursorPos );
220  void BuildOrthoProjections( DP_GATEWAYS &aEntries, const VECTOR2I& aCursorPos, int aOrthoScore );
221  void BuildGeneric( const VECTOR2I& p0_p, const VECTOR2I& p0_n, bool aBuildEntries = false, bool aViaMode = false );
222  void BuildFromPrimitivePair( DP_PRIMITIVE_PAIR aPair, bool aPreferDiagonal );
223 
224  bool FitGateways( DP_GATEWAYS& aEntry, DP_GATEWAYS& aTarget, bool aPrefDiagonal, DIFF_PAIR& aDp );
225 
226  std::vector<DP_GATEWAY>& Gateways()
227  {
228  return m_gateways;
229  }
230 
231  const std::vector<DP_GATEWAY>& CGateways() const
232  {
233  return m_gateways;
234  }
235 
236  void FilterByOrientation( int aAngleMask, DIRECTION_45 aRefOrientation );
237 
238  private:
240  {
243  int score;
244  };
245 
246  bool checkDiagonalAlignment( const VECTOR2I& a, const VECTOR2I& b ) const;
247  void buildDpContinuation( DP_PRIMITIVE_PAIR aPair, bool aIsDiagonal );
248  void buildEntries( const VECTOR2I& p0_p, const VECTOR2I& p0_n );
249 
250  int m_gap;
251  int m_viaGap;
253  bool m_fitVias;
254 
255  std::vector<DP_GATEWAY> m_gateways;
256 };
257 
258 
265 class DIFF_PAIR : public ITEM {
266 
267 public:
269  COUPLED_SEGMENTS ( const SEG& aCoupledP, const SEG& aParentP, int aIndexP,
270  const SEG& aCoupledN, const SEG& aParentN, int aIndexN ) :
271  coupledP( aCoupledP ),
272  coupledN( aCoupledN ),
273  parentP( aParentP ),
274  parentN( aParentN ),
275  indexP( aIndexP ),
276  indexN( aIndexN )
277  {}
278 
283  int indexP;
284  int indexN;
285  };
286 
287  typedef std::vector<COUPLED_SEGMENTS> COUPLED_SEGMENTS_VEC;
288 
290  {
291  // Initialize some members, to avoid uninitialized variables.
292  m_net_p = 0;
293  m_net_n = 0;;
294  m_width = 0;
295  m_gap = 0;
296  m_viaGap = 0;
298  m_chamferLimit = 0;
299  }
300 
301  DIFF_PAIR( int aGap ) :
302  ITEM( DIFF_PAIR_T ),
303  m_hasVias( false )
304  {
305  m_gapConstraint = aGap;
306 
307  // Initialize other members, to avoid uninitialized variables.
308  m_net_p = 0;
309  m_net_n = 0;;
310  m_width = 0;
311  m_gap = 0;
312  m_viaGap = 0;
314  m_chamferLimit = 0;
315  }
316 
317  DIFF_PAIR( const SHAPE_LINE_CHAIN &aP, const SHAPE_LINE_CHAIN& aN, int aGap = 0 ):
318  ITEM( DIFF_PAIR_T ),
319  m_n( aN ),
320  m_p( aP ),
321  m_hasVias( false )
322  {
323  m_gapConstraint = aGap;
324 
325  // Initialize other members, to avoid uninitialized variables.
326  m_net_p = 0;
327  m_net_n = 0;;
328  m_width = 0;
329  m_gap = 0;
330  m_viaGap = 0;
332  m_chamferLimit = 0;
333  }
334 
335  DIFF_PAIR( const LINE &aLineP, const LINE &aLineN, int aGap = 0 ):
336  ITEM( DIFF_PAIR_T ),
337  m_line_p( aLineP ),
338  m_line_n( aLineN ),
339  m_hasVias( false )
340  {
341  m_gapConstraint = aGap;
342  m_net_p = aLineP.Net();
343  m_net_n = aLineN.Net();
344  m_p = aLineP.CLine();
345  m_n = aLineN.CLine();
346 
347  // Do not leave unitialized members, and keep static analyser quiet:
348  m_width = 0;
349  m_gap = 0;
350  m_viaGap = 0;
352  m_chamferLimit = 0;
353  }
354 
355  static inline bool ClassOf( const ITEM* aItem )
356  {
357  return aItem && DIFF_PAIR_T == aItem->Kind();
358  }
359 
360  DIFF_PAIR* Clone() const override { assert( false ); return NULL; }
361 
362  static DIFF_PAIR* AssembleDp( LINE *aLine );
363 
364  void SetShape( const SHAPE_LINE_CHAIN &aP, const SHAPE_LINE_CHAIN& aN, bool aSwapLanes = false )
365  {
366  if( aSwapLanes )
367  {
368  m_p = aN;
369  m_n = aP;
370  }
371  else
372  {
373  m_p = aP;
374  m_n = aN;
375  }
376  }
377 
378  void SetShape( const DIFF_PAIR& aPair )
379  {
380  m_p = aPair.m_p;
381  m_n = aPair.m_n;
382  }
383 
384  void SetNets( int aP, int aN )
385  {
386  m_net_p = aP;
387  m_net_n = aN;
388  }
389 
390  void SetWidth( int aWidth )
391  {
392  m_width = aWidth;
393  }
394 
395  int Width() const { return m_width; }
396 
397  void SetGap( int aGap )
398  {
399  m_gap = aGap;
400  m_gapConstraint = RANGED_NUM<int>( m_gap, 10000, 10000 );
401  }
402 
403  int Gap() const
404  {
405  return m_gap;
406  }
407 
408  void AppendVias( const VIA &aViaP, const VIA& aViaN )
409  {
410  m_hasVias = true;
411  m_via_p = aViaP;
412  m_via_n = aViaN;
413  }
414 
415  void RemoveVias()
416  {
417  m_hasVias = false;
418  }
419 
420  bool EndsWithVias() const
421  {
422  return m_hasVias;
423  }
424 
425  int NetP() const
426  {
427  return m_net_p;
428  }
429 
430  int NetN() const
431  {
432  return m_net_n;
433  }
434 
436  {
437  if( !m_line_p.IsLinked() )
439 
440  return m_line_p;
441  }
442 
444  {
445  if( !m_line_n.IsLinked() )
447 
448  return m_line_n;
449  }
450 
452 
453  double CoupledLength() const;
454  double TotalLength() const;
455  double CoupledLengthFactor() const;
456  double Skew() const;
457 
458  void CoupledSegmentPairs( COUPLED_SEGMENTS_VEC& aPairs ) const;
459 
460  void Clear()
461  {
462  m_n.Clear();
463  m_p.Clear();
464  }
465 
466  void Append( const DIFF_PAIR& aOther )
467  {
468  m_n.Append( aOther.m_n );
469  m_p.Append( aOther.m_p );
470  }
471 
472  bool Empty() const
473  {
474  return ( m_n.SegmentCount() == 0 ) || ( m_p.SegmentCount() == 0 );
475  }
476 
477  const SHAPE_LINE_CHAIN& CP() const { return m_p; }
478  const SHAPE_LINE_CHAIN& CN() const { return m_n; }
479 
480  bool BuildInitial( const DP_GATEWAY& aEntry, const DP_GATEWAY& aTarget, bool aPrefDiagonal );
481  bool CheckConnectionAngle( const DIFF_PAIR &aOther, int allowedAngles ) const;
482  int CoupledLength( const SEG& aP, const SEG& aN ) const;
483 
484  int64_t CoupledLength( const SHAPE_LINE_CHAIN& aP, const SHAPE_LINE_CHAIN& aN ) const;
485 
487  {
488  return m_gapConstraint;
489  }
490 
491 private:
492  void updateLine( LINE &aLine, const SHAPE_LINE_CHAIN& aShape, int aNet, VIA& aVia )
493  {
494  aLine.SetShape( aShape );
495  aLine.SetWidth( m_width );
496  aLine.SetNet( aNet );
497  aLine.SetLayer( Layers().Start() );
498 
499  if( m_hasVias )
500  aLine.AppendVia( aVia );
501  }
502 
506 
507  bool m_hasVias;
509  int m_width;
510  int m_gap;
511  int m_viaGap;
515 };
516 
517 }
518 
519 #endif
const SHAPE_LINE_CHAIN & CLine() const
Const accessor to the underlying shape
Definition: pns_line.h:123
DIFF_PAIR(const SHAPE_LINE_CHAIN &aP, const SHAPE_LINE_CHAIN &aN, int aGap=0)
void CursorOrientation(const VECTOR2I &aCursorPos, VECTOR2I &aMidpoint, VECTOR2I &aDirection) const
const SHAPE_LINE_CHAIN & EntryP() const
double CoupledLength() const
Class ITEM.
Definition: pns_item.h:53
void buildEntries(const VECTOR2I &p0_p, const VECTOR2I &p0_n)
DP_PRIMITIVE_PAIR & operator=(const DP_PRIMITIVE_PAIR &aOther)
int NetP() const
bool FitGateways(DP_GATEWAYS &aEntry, DP_GATEWAYS &aTarget, bool aPrefDiagonal, DIFF_PAIR &aDp)
const RANGED_NUM< int > GapConstraint() const
int Width() const
void BuildForCursor(const VECTOR2I &aCursorPos)
bool checkDiagonalAlignment(const VECTOR2I &a, const VECTOR2I &b) const
const DIFF_PAIR Entry() const
const VECTOR2I & AnchorN() const
Definition: pns_diff_pair.h:79
const LAYER_RANGE & Layers() const
Function Layers()
Definition: pns_item.h:207
void SetShape(const SHAPE_LINE_CHAIN &aP, const SHAPE_LINE_CHAIN &aN, bool aSwapLanes=false)
void SetPriority(int aPriority)
Definition: pns_diff_pair.h:99
VECTOR2I m_anchorN
const VECTOR2I & AnchorN() const
void BuildFromPrimitivePair(DP_PRIMITIVE_PAIR aPair, bool aPreferDiagonal)
int AllowedAngles() const
Function AllowedAngles()
Definition: pns_diff_pair.h:87
void SetLayer(int aLayer)
Function SetLayer()
Definition: pns_item.h:197
void AppendVias(const VIA &aViaP, const VIA &aViaN)
double TotalLength() const
RANGED_NUM< int > m_gapConstraint
std::vector< DP_GATEWAY > m_gateways
SHAPE_LINE_CHAIN m_entryN
void FilterByOrientation(int aAngleMask, DIRECTION_45 aRefOrientation)
std::vector< DP_GATEWAY > & Gateways()
void Append(const DIFF_PAIR &aOther)
const SHAPE_LINE_CHAIN & CN() const
void AppendVia(const VIA &aVia)
Definition: pns_line.cpp:738
DIRECTION_45 DirN() const
DIFF_PAIR(int aGap)
ITEM * PrimP() const
bool BuildInitial(const DP_GATEWAY &aEntry, const DP_GATEWAY &aTarget, bool aPrefDiagonal)
void SetEntryLines(const SHAPE_LINE_CHAIN &aEntryP, const SHAPE_LINE_CHAIN &aEntryN)
VECTOR2I m_anchorP
bool IsDiagonal() const
Function IsDiagonal()
Definition: pns_diff_pair.h:72
static bool ClassOf(const ITEM *aItem)
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
void SetWidth(int aWidth)
Sets line width
Definition: pns_line.h:153
void SetNet(int aNet)
Function SetNet()
Definition: pns_item.h:167
void SetShape(const SHAPE_LINE_CHAIN &aLine)
Assigns a shape to the line (a polyline/line chain)
Definition: pns_line.h:105
int NetN() const
ITEM * PrimN() const
bool Empty() const
void SetGap(int aGap)
std::vector< COUPLED_SEGMENTS > COUPLED_SEGMENTS_VEC
DIRECTION_45 anchorDirection(ITEM *aItem, const VECTOR2I &aP) const
void SetFitVias(bool aEnable, int aDiameter=0, int aViaGap=-1)
const VECTOR2I & AnchorP() const
Definition: pns_diff_pair.h:77
SHAPE_LINE_CHAIN m_p
bool CheckConnectionAngle(const DIFF_PAIR &aOther, int allowedAngles) const
const VECTOR2I & AnchorP() const
Class DIRECTION_45.
Definition: direction45.h:33
int Gap() const
double Skew() const
void updateLine(LINE &aLine, const SHAPE_LINE_CHAIN &aShape, int aNet, VIA &aVia)
SHAPE_LINE_CHAIN m_entryP
bool EndsWithVias() const
static DIFF_PAIR * AssembleDp(LINE *aLine)
const SHAPE_LINE_CHAIN & EntryN() const
bool HasEntryLines() const
void SetWidth(int aWidth)
void SetGap(int aGap)
DP_GATEWAYS(int aGap)
int Priority() const
Function Priority()
Definition: pns_diff_pair.h:94
SHAPE_LINE_CHAIN m_n
DIFF_PAIR * Clone() const override
Function Clone()
const std::vector< DP_GATEWAY > & CGateways() const
PnsKind Kind() const
Function Kind()
Definition: pns_item.h:120
void buildDpContinuation(DP_PRIMITIVE_PAIR aPair, bool aIsDiagonal)
Definition: seg.h:37
Class DIFF_PAIR.
void BuildOrthoProjections(DP_GATEWAYS &aEntries, const VECTOR2I &aCursorPos, int aOrthoScore)
void CoupledSegmentPairs(COUPLED_SEGMENTS_VEC &aPairs) const
Class DP_PRIMITIVE_PAIR.
DIRECTION_45 DirP() const
Class SHAPE_LINE_CHAIN.
DIFF_PAIR(const LINE &aLineP, const LINE &aLineN, int aGap=0)
int Net() const
Function Net()
Definition: pns_item.h:177
DP_GATEWAY(const VECTOR2I &aAnchorP, const VECTOR2I &aAnchorN, bool aIsDiagonal, int aAllowedEntryAngles=DIRECTION_45::ANG_OBTUSE, int aPriority=0)
Definition: pns_diff_pair.h:49
void Clear()
Function Clear() Removes all points from the line chain.
double CoupledLengthFactor() const
void BuildGeneric(const VECTOR2I &p0_p, const VECTOR2I &p0_n, bool aBuildEntries=false, bool aViaMode=false)
Class DP_GATEWAYS.
Push and Shove diff pair dimensions (gap) settings dialog.
COUPLED_SEGMENTS(const SEG &aCoupledP, const SEG &aParentP, int aIndexP, const SEG &aCoupledN, const SEG &aParentN, int aIndexN)
int SegmentCount() const
Function SegmentCount()
void SetShape(const DIFF_PAIR &aPair)
Class DP_GATEWAY.
Definition: pns_diff_pair.h:47
DP_PRIMITIVE_PAIR EndingPrimitives()
void SetAnchors(const VECTOR2I &aAnchorP, const VECTOR2I &aAnchorN)
const SHAPE_LINE_CHAIN & CP() const
void SetNets(int aP, int aN)
bool IsLinked() const
Definition: pns_line.h:186