Horizon
pns_diff_pair.h
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>
29#include <geometry/shape_line_chain.h>
30
31#include "pns_line.h"
32#include "pns_via.h"
33
34#include "ranged_num.h"
35
36namespace PNS {
37
38class DIFF_PAIR;
39
48public:
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
122private:
123 SHAPE_LINE_CHAIN m_entryP, m_entryN;
124 bool m_hasEntryLines;
125 VECTOR2I m_anchorP, m_anchorN;
126 bool m_isDiagonal;
127 int m_allowedEntryAngles;
128 int m_priority;
129};
130
137{
138public:
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
153 DP_PRIMITIVE_PAIR& operator=( const DP_PRIMITIVE_PAIR& aOther );
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
172private:
173 DIRECTION_45 anchorDirection( ITEM* aItem, const VECTOR2I& aP ) const;
174
175 ITEM* m_primP;
176 ITEM* m_primN;
177 VECTOR2I m_anchorP, m_anchorN;
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( const 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:
239 struct DP_CANDIDATE
240 {
241 SHAPE_LINE_CHAIN p, n;
242 VECTOR2I gw_p, gw_n;
243 int score;
244 };
245
246 bool checkDiagonalAlignment( const VECTOR2I& a, const VECTOR2I& b ) const;
247 void buildDpContinuation( const 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;
252 int m_viaDiameter;
253 bool m_fitVias;
254
255 std::vector<DP_GATEWAY> m_gateways;
256};
257
258
265class DIFF_PAIR : public ITEM {
266
267public:
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
279 SEG coupledP;
280 SEG coupledN;
281 SEG parentP;
282 SEG parentN;
283 int indexP;
284 int indexN;
285 };
286
287 typedef std::vector<COUPLED_SEGMENTS> COUPLED_SEGMENTS_VEC;
288
289 DIFF_PAIR() : ITEM( DIFF_PAIR_T ), m_hasVias( false )
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;
297 m_maxUncoupledLength = 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;
313 m_maxUncoupledLength = 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;
331 m_maxUncoupledLength = 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;
351 m_maxUncoupledLength = 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
435 LINE& PLine()
436 {
437 if( !m_line_p.IsLinked() )
438 updateLine( m_line_p, m_p, m_net_p, m_via_p );
439
440 return m_line_p;
441 }
442
443 LINE& NLine()
444 {
445 if( !m_line_n.IsLinked() )
446 updateLine( m_line_n, m_n, m_net_n, m_via_n );
447
448 return m_line_n;
449 }
450
451 DP_PRIMITIVE_PAIR EndingPrimitives();
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
486 const RANGED_NUM<int> GapConstraint() const
487 {
488 return m_gapConstraint;
489 }
490
491private:
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
503 SHAPE_LINE_CHAIN m_n, m_p;
504 LINE m_line_p, m_line_n;
505 VIA m_via_p, m_via_n;
506
507 bool m_hasVias;
508 int m_net_p, m_net_n;
509 int m_width;
510 int m_gap;
511 int m_viaGap;
512 int m_maxUncoupledLength;
513 int m_chamferLimit;
514 RANGED_NUM<int> m_gapConstraint;
515};
516
517}
518
519#endif
Class DIRECTION_45.
Definition: direction45.h:37
Class DIFF_PAIR.
Definition: pns_diff_pair.h:265
DIFF_PAIR * Clone() const override
Function Clone()
Definition: pns_diff_pair.h:360
Class DP_GATEWAYS.
Definition: pns_diff_pair.h:187
Class DP_GATEWAY.
Definition: pns_diff_pair.h:47
bool IsDiagonal() const
Function IsDiagonal()
Definition: pns_diff_pair.h:72
int AllowedAngles() const
Function AllowedAngles()
Definition: pns_diff_pair.h:87
int Priority() const
Function Priority()
Definition: pns_diff_pair.h:94
Class DP_PRIMITIVE_PAIR.
Definition: pns_diff_pair.h:137
Class ITEM.
Definition: pns_item.h:55
const LAYER_RANGE & Layers() const
Function Layers()
Definition: pns_item.h:215
Definition: pns_line.h:61
Definition: seg.h:37
Class SHAPE_LINE_CHAIN.
Definition: shape_line_chain.h:50
void Clear()
Function Clear() Removes all points from the line chain.
Definition: shape_line_chain.h:151
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
Definition: shape_line_chain.h:383
int SegmentCount() const
Function SegmentCount()
Definition: shape_line_chain.h:203
Definition: pns_diff_pair.h:268