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