KiCad PCB EDA Suite
pns_meander_placer_base.cpp
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 
23 #include "pns_meander.h"
24 #include "pns_router.h"
25 #include "pns_solid.h"
26 
27 namespace PNS {
28 
30  PLACEMENT_ALGO( aRouter )
31 {
32  m_world = NULL;
33  m_currentWidth = 0;
34  m_padToDieLenth = 0;
35 }
36 
37 
39 {
40 }
41 
42 
44 {
45  int a = m_settings.m_maxAmplitude + aSign * m_settings.m_step;
46  a = std::max( a, m_settings.m_minAmplitude );
47 
49 }
50 
51 
53 {
54  int s = m_settings.m_spacing + aSign * m_settings.m_step;
55  s = std::max( s, 2 * m_currentWidth );
56 
58 }
59 
60 
62 {
63  m_settings = aSettings;
64 }
65 
66 
68  const VECTOR2I& aTuneStart,
69  const VECTOR2I& aCursorPos,
70  SHAPE_LINE_CHAIN& aPre,
71  SHAPE_LINE_CHAIN& aTuned,
72  SHAPE_LINE_CHAIN& aPost )
73 {
74  VECTOR2I cp ( aCursorPos );
75 
76  if ( cp == aTuneStart ) // we don't like tuning segments with 0 length
77  {
78  int idx = aOrigin.FindSegment( cp );
79  if( idx >= 0 )
80  {
81  const SEG& s = aOrigin.CSegment( idx );
82  cp += (s.B - s.A).Resize(2);
83  } else
84  cp += VECTOR2I (2, 5); // some arbitrary value that is not 45 degrees oriented
85  }
86 
87  VECTOR2I n = aOrigin.NearestPoint( cp );
88  VECTOR2I m = aOrigin.NearestPoint( aTuneStart );
89 
90  SHAPE_LINE_CHAIN l( aOrigin );
91  l.Split( n );
92  l.Split( m );
93 
94  int i_start = l.Find( m );
95  int i_end = l.Find( n );
96 
97  if( i_start > i_end )
98  {
99  l = l.Reverse();
100  i_start = l.Find( m );
101  i_end = l.Find( n );
102  }
103 
104  aPre = l.Slice( 0, i_start );
105  aPost = l.Slice( i_end, -1 );
106  aTuned = l.Slice( i_start, i_end );
107 
108  aTuned.Simplify();
109 }
110 
111 
112 void MEANDER_PLACER_BASE::tuneLineLength( MEANDERED_LINE& aTuned, long long int aElongation )
113 {
114  long long int remaining = aElongation;
115  bool finished = false;
116 
117  for( MEANDER_SHAPE* m : aTuned.Meanders() )
118  {
119  if( m->Type() != MT_CORNER )
120  {
121  if( remaining >= 0 )
122  remaining -= m->MaxTunableLength() - m->BaselineLength();
123 
124  if( remaining < 0 )
125  {
126  if( !finished )
127  {
128  MEANDER_TYPE newType;
129 
130  if( m->Type() == MT_START || m->Type() == MT_SINGLE )
131  newType = MT_SINGLE;
132  else
133  newType = MT_FINISH;
134 
135  m->SetType( newType );
136  m->Recalculate();
137 
138  finished = true;
139  } else {
140  m->MakeEmpty();
141  }
142  }
143  }
144  }
145 
146  remaining = aElongation;
147  int meanderCount = 0;
148 
149  for(MEANDER_SHAPE* m : aTuned.Meanders())
150  {
151  if( m->Type() != MT_CORNER && m->Type() != MT_EMPTY )
152  {
153  if(remaining >= 0)
154  {
155  remaining -= m->MaxTunableLength() - m->BaselineLength();
156  meanderCount ++;
157  }
158  }
159  }
160 
161  long long int balance = 0;
162 
163  if( meanderCount )
164  balance = -remaining / meanderCount;
165 
166  if( balance >= 0 )
167  {
168  for( MEANDER_SHAPE* m : aTuned.Meanders() )
169  {
170  if( m->Type() != MT_CORNER && m->Type() != MT_EMPTY )
171  {
172  m->Resize( std::max( m->Amplitude() - balance / 2,
173  (long long int) ( m_settings.m_minAmplitude ) ) );
174  }
175  }
176  }
177 }
178 
179 
181 {
182  int length = 0;
183  JOINT start;
184  JOINT end;
185 
186  m_world->FindLineEnds( aLine, start, end );
187 
188  // Extract the length of the pad to die for start and end pads
189  for( auto& link : start.LinkList() )
190  {
191  if( const SOLID* solid = dynamic_cast<const SOLID*>( link.item ) )
192  {
193  // If there are overlapping pads, choose the first with a non-zero length
194  if( solid->GetPadToDie() > 0 )
195  {
196  length += solid->GetPadToDie();
197  break;
198  }
199  }
200  }
201 
202  for( auto& link : end.LinkList() )
203  {
204  if( const SOLID* solid = dynamic_cast<const SOLID*>( link.item ) )
205  {
206  if( solid->GetPadToDie() > 0 )
207  {
208  length += solid->GetPadToDie();
209  break;
210  }
211  }
212  }
213 
214  return length;
215 }
216 
217 
219 {
220  return m_settings;
221 }
222 
223 
225  long long int aValue, long long int aExpected, long long int aTolerance ) const
226 {
227  if( aValue < aExpected - aTolerance )
228  return -1;
229  else if( aValue > aExpected + aTolerance )
230  return 1;
231  else
232  return 0;
233 }
234 
235 }
int Find(const VECTOR2I &aP) const
Function Find()
int GetTotalPadToDieLength(const LINE &aLine) const
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Function NearestPoint()
int FindSegment(const VECTOR2I &aP) const
Function FindSegment()
int Split(const VECTOR2I &aP)
Function Split()
int m_minAmplitude
minimum meandering amplitude
Definition: pns_meander.h:77
MEANDER_SETTINGS.
Definition: pns_meander.h:107
MEANDER_TYPE
Shapes of available meanders.
Definition: pns_meander.h:35
const SHAPE_LINE_CHAIN Slice(int aStartIndex, int aEndIndex=-1) const
Function Slice()
void FindLineEnds(const LINE &aLine, JOINT &aA, JOINT &aB)
finds the joints corresponding to the ends of line aLine
Definition: pns_node.cpp:948
MEANDER_SETTINGS.
Definition: pns_meander.h:57
const SHAPE_LINE_CHAIN Reverse() const
Function Reverse()
VECTOR2< int > VECTOR2I
Definition: vector2d.h:594
virtual void UpdateSettings(const MEANDER_SETTINGS &aSettings)
int m_currentWidth
width of the meandered trace(s)
SHAPE_LINE_CHAIN & Simplify()
Function Simplify()
JOINT.
Definition: pns_joint.h:43
int m_step
amplitude/spacing adjustment step
Definition: pns_meander.h:83
#define NULL
std::vector< MEANDER_SHAPE * > & Meanders()
Function Meanders()
Definition: pns_meander.h:486
NODE * m_world
pointer to world to search colliding items
void tuneLineLength(MEANDERED_LINE &aTuned, long long int aElongation)
Function tuneLineLength()
const LINKED_ITEMS & LinkList() const
Definition: pns_joint.h:196
virtual void SpacingStep(int aSign)
Function SpacingStep()
MEANDERED_LINE.
Definition: pns_meander.h:398
int m_padToDieLenth
total length added by pad to die size
Definition: seg.h:39
MEANDER_SETTINGS m_settings
meandering settings
const SEG CSegment(int aIndex) const
Function CSegment()
SHAPE_LINE_CHAIN.
int compareWithTolerance(long long int aValue, long long int aExpected, long long int aTolerance=0) const
Function compareWithTolerance()
VECTOR2I A
Definition: seg.h:47
virtual void AmplitudeStep(int aSign)
Function AmplitudeStep()
int m_spacing
meandering period/spacing (see dialog picture for explanation)
Definition: pns_meander.h:81
Push and Shove diff pair dimensions (gap) settings dialog.
virtual const MEANDER_SETTINGS & MeanderSettings() const
Function MeanderSettings()
void cutTunedLine(const SHAPE_LINE_CHAIN &aOrigin, const VECTOR2I &aTuneStart, const VECTOR2I &aCursorPos, SHAPE_LINE_CHAIN &aPre, SHAPE_LINE_CHAIN &aTuned, SHAPE_LINE_CHAIN &aPost)
Function cutTunedLine()
int m_maxAmplitude
maximum meandering amplitude
Definition: pns_meander.h:79
VECTOR2I B
Definition: seg.h:48