KiCad PCB EDA Suite
pns_diff_pair_placer.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 
22 #include <class_board.h>
23 #include <class_board_item.h>
24 #include <class_netinfo.h>
25 
26 #include "pns_node.h"
27 #include "pns_walkaround.h"
28 #include "pns_shove.h"
29 #include "pns_utils.h"
30 #include "pns_router.h"
31 #include "pns_diff_pair_placer.h"
32 #include "pns_solid.h"
33 #include "pns_topology.h"
34 #include "pns_debug_decorator.h"
35 
36 namespace PNS {
37 
39  PLACEMENT_ALGO( aRouter )
40 {
41  m_state = RT_START;
42  m_chainedPlacement = false;
43  m_initialDiagonal = false;
44  m_startDiagonal = false;
45  m_fitOk = false;
46  m_netP = 0;
47  m_netN = 0;
48  m_iteration = 0;
49  m_world = NULL;
50  m_shove = NULL;
51  m_currentNode = NULL;
52  m_lastNode = NULL;
53  m_placingVia = false;
54  m_viaDiameter = 0;
55  m_viaDrill = 0;
56  m_currentWidth = 0;
57  m_currentNet = 0;
58  m_currentLayer = 0;
59  m_startsOnVia = false;
60  m_orthoMode = false;
61  m_snapOnTarget = false;
62  m_currentEndItem = NULL;
64  m_idle = true;
65 }
66 
68 {
69  if( m_shove )
70  delete m_shove;
71 }
72 
73 
75 {
76  m_world = aWorld;
77 }
78 
79 const VIA DIFF_PAIR_PLACER::makeVia( const VECTOR2I& aP, int aNet )
80 {
82 
83  VIA v( aP, layers, m_sizes.ViaDiameter(), m_sizes.ViaDrill(), -1, m_sizes.ViaType() );
84  v.SetNet( aNet );
85 
86  return v;
87 }
88 
89 
90 void DIFF_PAIR_PLACER::SetOrthoMode ( bool aOrthoMode )
91 {
92  m_orthoMode = aOrthoMode;
93 
94  if( !m_idle )
95  Move( m_currentEnd, NULL );
96 }
97 
98 
99 bool DIFF_PAIR_PLACER::ToggleVia( bool aEnabled )
100 {
101  m_placingVia = aEnabled;
102 
103  if( !m_idle )
104  Move( m_currentEnd, NULL );
105 
106  return true;
107 }
108 
109 
111 {
112  if( !routeHead( aP ) )
113  return false;
114 
115  bool collP = static_cast<bool>( m_currentNode->CheckColliding( &m_currentTrace.PLine() ) );
116  bool collN = static_cast<bool>( m_currentNode->CheckColliding( &m_currentTrace.NLine() ) );
117 
118  m_fitOk = !( collP || collN ) ;
119 
120  return m_fitOk;
121 }
122 
123 
125 {
126  VIA virtHead = makeVia( aP, -1 );
127 
128  if( m_placingVia )
129  virtHead.SetDiameter( viaGap() + 2 * virtHead.Diameter() );
130  else
131  {
132  virtHead.SetLayer( m_currentLayer );
133  virtHead.SetDiameter( m_sizes.DiffPairGap() + 2 * m_sizes.TrackWidth() );
134  }
135 
136  VECTOR2I lead( 0, 0 );// = aP - m_currentStart ;
137  VECTOR2I force;
138  bool solidsOnly = true;
139 
141  {
142  aNewP = aP;
143  return true;
144  }
145  else if( m_currentMode == RM_Walkaround )
146  {
147  solidsOnly = false;
148  }
149 
150  // fixme: I'm too lazy to do it well. Circular approximaton will do for the moment.
151  if( virtHead.PushoutForce( m_currentNode, lead, force, solidsOnly, 40 ) )
152  {
153  aNewP = aP + force;
154  return true;
155  }
156 
157  return false;
158 }
159 
160 
162  DIFF_PAIR& aWalk, bool aPFirst, bool aWindCw, bool aSolidsOnly )
163 {
164  WALKAROUND walkaround( aNode, Router() );
166 
168  aCurrent->NetP(), aCurrent->NetN(), aCurrent->Gap() );
169 
170  walkaround.SetSolidsOnly( aSolidsOnly );
171  walkaround.SetIterationLimit( Settings().WalkaroundIterationLimit() );
172 
173  SHOVE shove( aNode, Router() );
174  LINE walkP, walkN;
175 
176  aWalk = *aCurrent;
177 
178  int iter = 0;
179 
180  DIFF_PAIR cur( *aCurrent );
181 
182  bool currentIsP = aPFirst;
183 
184  int mask = aSolidsOnly ? ITEM::SOLID_T : ITEM::ANY_T;
185 
186  do
187  {
188  LINE preWalk = ( currentIsP ? cur.PLine() : cur.NLine() );
189  LINE preShove = ( currentIsP ? cur.NLine() : cur.PLine() );
190  LINE postWalk;
191 
192  if( !aNode->CheckColliding ( &preWalk, mask ) )
193  {
194  currentIsP = !currentIsP;
195 
196  if( !aNode->CheckColliding( &preShove, mask ) )
197  break;
198  else
199  continue;
200  }
201 
202  wf1 = walkaround.Route( preWalk, postWalk, false );
203 
204  if( wf1 != WALKAROUND::DONE )
205  return false;
206 
207  LINE postShove( preShove );
208 
209  shove.ForceClearance( true, cur.Gap() - 2 * PNS_HULL_MARGIN );
210 
212 
213  sh1 = shove.ProcessSingleLine( postWalk, preShove, postShove );
214 
215  if( sh1 != SHOVE::SH_OK )
216  return false;
217 
218  postWalk.Line().Simplify();
219  postShove.Line().Simplify();
220 
221  cur.SetShape( postWalk.CLine(), postShove.CLine(), !currentIsP );
222 
223  currentIsP = !currentIsP;
224 
225  if( !aNode->CheckColliding( &postShove, mask ) )
226  break;
227 
228  iter++;
229  }
230  while( iter < 3 );
231 
232  if( iter == 3 )
233  return false;
234 
235  aWalk.SetShape( cur.CP(), cur.CN() );
237 
238  return true;
239 }
240 
241 
242 bool DIFF_PAIR_PLACER::tryWalkDp( NODE* aNode, DIFF_PAIR &aPair, bool aSolidsOnly )
243 {
244  DIFF_PAIR best;
245  double bestScore = 100000000000000.0;
246 
247  for( int attempt = 0; attempt <= 3; attempt++ )
248  {
249  DIFF_PAIR p;
250  NODE *tmp = m_currentNode->Branch();
251 
252  bool pfirst = ( attempt & 1 ) ? true : false;
253  bool wind_cw = ( attempt & 2 ) ? true : false;
254 
255  if( attemptWalk( tmp, &aPair, p, pfirst, wind_cw, aSolidsOnly ) )
256  {
257  // double len = p.TotalLength();
258  double cl = p.CoupledLength();
259  double skew = p.Skew();
260 
261  double score = cl + fabs( skew ) * 3.0;
262 
263  if( score < bestScore )
264  {
265  bestScore = score;
266  best = p;
267  }
268  }
269 
270  delete tmp;
271  }
272 
273  if( bestScore > 0.0 )
274  {
275  OPTIMIZER optimizer( m_currentNode );
276 
277  aPair.SetShape( best );
278  optimizer.Optimize( &aPair );
279 
280  return true;
281  }
282 
283  return false;
284 }
285 
286 
288 {
289  if( !routeHead ( aP ) )
290  return false;
291 
293 
294  return m_fitOk;
295 }
296 
297 
299 {
300  switch( m_currentMode )
301  {
302  case RM_MarkObstacles:
303  return rhMarkObstacles( aP );
304  case RM_Walkaround:
305  return rhWalkOnly( aP );
306  case RM_Shove:
307  return rhShoveOnly( aP );
308  default:
309  break;
310  }
311 
312  return false;
313 }
314 
315 
317 {
319 
320  bool ok = routeHead( aP );
321 
322  m_fitOk = false;
323 
324  if( !ok )
325  return false;
326 
327  if( !tryWalkDp( m_currentNode, m_currentTrace, true ) )
328  return false;
329 
330  LINE pLine( m_currentTrace.PLine() );
331  LINE nLine( m_currentTrace.NLine() );
332  ITEM_SET head;
333 
334  head.Add( &pLine );
335  head.Add( &nLine );
336 
337  SHOVE::SHOVE_STATUS status = m_shove->ShoveMultiLines( head );
338 
340 
341  if( status == SHOVE::SH_OK )
342  {
344 
347  {
348  m_fitOk = true;
349  }
350  }
351 
352  return m_fitOk;
353 }
354 
355 
357 {
358  ITEM_SET t;
359 
360  t.Add( const_cast<LINE*>( &m_currentTrace.PLine() ) );
361  t.Add( const_cast<LINE*>( &m_currentTrace.NLine() ) );
362 
363  return t;
364 }
365 
366 
368 {
370 
371  if( !m_idle )
372  Move( m_currentEnd, NULL );
373 }
374 
375 
376 NODE* DIFF_PAIR_PLACER::CurrentNode( bool aLoopsRemoved ) const
377 {
378  if( m_lastNode )
379  return m_lastNode;
380 
381  return m_currentNode;
382 }
383 
384 
385 bool DIFF_PAIR_PLACER::SetLayer( int aLayer )
386 {
387  if( m_idle )
388  {
389  m_currentLayer = aLayer;
390  return true;
391  } else if( m_chainedPlacement )
392  return false;
393  else if( !m_prevPair )
394  return false;
395  else if( m_prevPair->PrimP() || ( m_prevPair->PrimP()->OfKind( ITEM::VIA_T ) &&
396  m_prevPair->PrimP()->Layers().Overlaps( aLayer ) ) )
397  {
398  m_currentLayer = aLayer;
399  m_start = *m_prevPair;
400  initPlacement();
401  Move( m_currentEnd, NULL );
402  return true;
403  }
404 
405  return false;
406 }
407 
408 
409 int DIFF_PAIR_PLACER::matchDpSuffix( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName )
410 {
411  int rv = 0;
412 
413  if( aNetName.EndsWith( "+" ) )
414  {
415  aComplementNet = "-";
416  rv = 1;
417  }
418  else if( aNetName.EndsWith( "_P" ) )
419  {
420  aComplementNet = "_N";
421  rv = 1;
422  }
423  else if( aNetName.EndsWith( "-" ) )
424  {
425  aComplementNet = "+";
426  rv = -1;
427  }
428  else if( aNetName.EndsWith( "_N" ) )
429  {
430  aComplementNet = "_P";
431  rv = -1;
432  }
433 
434  if( rv != 0 )
435  {
436  aBaseDpName = aNetName.Left( aNetName.Length() - aComplementNet.Length() );
437  }
438 
439  return rv;
440 }
441 
442 
444 {
445  switch( aItem->Kind() )
446  {
447  case ITEM::VIA_T:
448  case ITEM::SOLID_T:
449  return aItem->Anchor( 0 );
450 
451  case ITEM::SEGMENT_T:
452  {
453  SEGMENT* s =static_cast<SEGMENT*>( aItem );
454 
455  JOINT* jA = aNode->FindJoint( s->Seg().A, s );
456  JOINT* jB = aNode->FindJoint( s->Seg().B, s );
457 
458  if( jA->LinkCount() == 1 )
459  return s->Seg().A;
460  else if( jB->LinkCount() == 1 )
461  return s->Seg().B;
462  else
463  return OPT_VECTOR2I();
464  }
465 
466  default:
467  return OPT_VECTOR2I();
468  break;
469  }
470 }
471 
472 
473 
475 {
476  int netP, netN;
477 
478  wxLogTrace( "PNS", "world %p", m_world );
479 
480  bool result = m_world->GetRuleResolver()->DpNetPair( aItem, netP, netN );
481 
482  if( !result )
483  return false;
484 
485  int refNet = aItem->Net();
486  int coupledNet = ( refNet == netP ) ? netN : netP;
487 
488  wxLogTrace( "PNS", "result %d", !!result );
489 
490  OPT_VECTOR2I refAnchor = getDanglingAnchor( m_currentNode, aItem );
491  ITEM* primRef = aItem;
492 
493  wxLogTrace( "PNS", "refAnchor %p", aItem );
494 
495  if( !refAnchor )
496  return false;
497 
498  std::set<ITEM*> coupledItems;
499 
500  m_currentNode->AllItemsInNet( coupledNet, coupledItems );
501  double bestDist = std::numeric_limits<double>::max();
502  bool found = false;
503 
504  for( ITEM* item : coupledItems )
505  {
506  if( item->Kind() == aItem->Kind() )
507  {
508  OPT_VECTOR2I anchor = getDanglingAnchor( m_currentNode, item );
509  if( !anchor )
510  continue;
511 
512  double dist = ( *anchor - *refAnchor ).EuclideanNorm();
513 
514  bool shapeMatches = true;
515 
516  if( item->OfKind( ITEM::SOLID_T ) && item->Layers() != aItem->Layers() )
517  {
518  shapeMatches = false;
519  }
520 
521  if( dist < bestDist && shapeMatches )
522  {
523  found = true;
524  bestDist = dist;
525 
526  if( refNet == netP )
527  {
528  aPair = DP_PRIMITIVE_PAIR ( item, primRef );
529  aPair.SetAnchors( *anchor, *refAnchor );
530  }
531  else
532  {
533  aPair = DP_PRIMITIVE_PAIR( primRef, item );
534  aPair.SetAnchors( *refAnchor, *anchor );
535  }
536  }
537  }
538  }
539 
540  return found;
541 }
542 
543 
545 {
546  return m_sizes.DiffPairViaGap();
547 }
548 
549 
551 {
553 }
554 
555 
556 bool DIFF_PAIR_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem )
557 {
558  VECTOR2I p( aP );
559 
560  if( !aStartItem )
561  {
562  Router()->SetFailureReason( _( "Can't start a differential pair "
563  " in the middle of nowhere." ) );
564  return false;
565  }
566 
567  setWorld( Router()->GetWorld() );
569 
570  if( !findDpPrimitivePair( aP, aStartItem, m_start ) )
571  {
572  Router()->SetFailureReason( _( "Unable to find complementary differential pair "
573  "net. Make sure the names of the nets belonging "
574  "to a differential pair end with either _N/_P or +/-." ) );
575  return false;
576  }
577 
578  m_netP = m_start.PrimP()->Net();
579  m_netN = m_start.PrimN()->Net();
580 
581  #if 0
582  // FIXME: this also needs to be factored out but not so important right now
583  // Check if the current track/via gap & track width settings are violated
584  BOARD* brd = NULL; // FIXME Router()->GetBoard();
585  NETCLASSPTR netclassP = brd->FindNet( m_netP )->GetNetClass();
586  NETCLASSPTR netclassN = brd->FindNet( m_netN )->GetNetClass();
587  int clearance = std::min( m_sizes.DiffPairGap(), m_sizes.DiffPairViaGap() );
588 
589  if( clearance < netclassP->GetClearance() || clearance < netclassN->GetClearance() )
590  {
591  Router()->SetFailureReason( _( "Current track/via gap setting violates "
592  "design rules for this net." ) );
593  return false;
594  }
595 
597  {
598  Router()->SetFailureReason( _( "Current track width setting violates design rules." ) );
599  return false;
600  }
601  #endif
602 
603  m_currentStart = p;
604  m_currentEnd = p;
605  m_placingVia = false;
606  m_chainedPlacement = false;
607 
608  initPlacement();
609 
610  return true;
611 }
612 
613 
615 {
616  m_idle = false;
617  m_orthoMode = false;
618  m_currentEndItem = NULL;
620 
621  NODE* world = Router()->GetWorld();
622 
623  world->KillChildren();
624  NODE* rootNode = world->Branch();
625 
626  setWorld( rootNode );
627 
628  m_lastNode = NULL;
629  m_currentNode = rootNode;
631 
632  if( m_shove )
633  delete m_shove;
634 
635  m_shove = NULL;
636 
638  {
639  m_shove = new SHOVE( m_currentNode, Router() );
640  }
641 }
642 
643 
645 {
646  m_fitOk = false;
647 
648  DP_GATEWAYS gwsEntry( gap() );
649  DP_GATEWAYS gwsTarget( gap() );
650 
651  if( !m_prevPair )
653 
655 
656  DP_PRIMITIVE_PAIR target;
657 
658  if( findDpPrimitivePair( aP, m_currentEndItem, target ) )
659  {
660  gwsTarget.BuildFromPrimitivePair( target, m_startDiagonal );
661  m_snapOnTarget = true;
662  }
663  else
664  {
665  VECTOR2I fp;
666 
667  if( !propagateDpHeadForces( aP, fp ) )
668  return false;
669 
670  VECTOR2I midp, dirV;
671  m_prevPair->CursorOrientation( fp, midp, dirV );
672 
673  VECTOR2I fpProj = SEG( midp, midp + dirV ).LineProject( fp );
674  int lead_dist = ( fpProj - fp ).EuclideanNorm();
675 
676  gwsTarget.SetFitVias( m_placingVia, m_sizes.ViaDiameter(), viaGap() );
677 
678  if( lead_dist > m_sizes.DiffPairGap() + m_sizes.DiffPairWidth() )
679  {
680  gwsTarget.BuildForCursor( fp );
681  }
682  else
683  {
684  gwsTarget.BuildForCursor( fpProj );
686  }
687 
688  m_snapOnTarget = false;
689  }
690 
694 
695  bool result = gwsEntry.FitGateways( gwsEntry, gwsTarget, m_startDiagonal, m_currentTrace );
696 
697  if( result )
698  {
702 
703  if( m_placingVia )
704  {
706  makeVia( m_currentTrace.CN().CPoint( -1 ), m_netN ) );
707  }
708 
709  return true;
710  }
711 
712  return false;
713 }
714 
715 
716 bool DIFF_PAIR_PLACER::Move( const VECTOR2I& aP , ITEM* aEndItem )
717 {
718  m_currentEndItem = aEndItem;
719  m_fitOk = false;
720 
721  delete m_lastNode;
722  m_lastNode = NULL;
723 
724  if( !route( aP ) )
725  return false;
726 
727  NODE* latestNode = m_currentNode;
728  m_lastNode = latestNode->Branch();
729 
730  assert( m_lastNode != NULL );
731  m_currentEnd = aP;
732 
734 
735  return true;
736 }
737 
738 
740 {
741  m_sizes = aSizes;
742 
743  if( !m_idle )
744  {
745  initPlacement();
746  Move( m_currentEnd, NULL );
747  }
748 }
749 
750 
751 bool DIFF_PAIR_PLACER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem )
752 {
753  if( !m_fitOk )
754  return false;
755 
756  if( m_currentTrace.CP().SegmentCount() < 1 ||
757  m_currentTrace.CN().SegmentCount() < 1 )
758  return false;
759 
760  if( m_currentTrace.CP().SegmentCount() > 1 )
761  m_initialDiagonal = !DIRECTION_45( m_currentTrace.CP().CSegment( -2 ) ).IsDiagonal();
762 
763  TOPOLOGY topo( m_lastNode );
764 
766  {
769 
770  if( newP.SegmentCount() > 1 && newN.SegmentCount() > 1 )
771  {
772  newP.Remove( -1, -1 );
773  newN.Remove( -1, -1 );
774  }
775 
776  m_currentTrace.SetShape( newP, newN );
777  }
778 
780  {
783  m_chainedPlacement = false;
784  }
785  else
786  {
788  }
789 
790  LINE lineP( m_currentTrace.PLine() );
791  LINE lineN( m_currentTrace.NLine() );
792 
793  m_lastNode->Add( lineP );
794  m_lastNode->Add( lineN );
795 
796  topo.SimplifyLine( &lineP );
797  topo.SimplifyLine( &lineN );
798 
800 
802 
803  m_lastNode = NULL;
804  m_placingVia = false;
805 
806  if( m_snapOnTarget )
807  {
808  m_idle = true;
809  return true;
810  }
811  else
812  {
813  initPlacement();
814  return false;
815  }
816 }
817 
818 
819 void DIFF_PAIR_PLACER::GetModifiedNets( std::vector<int> &aNets ) const
820 {
821  aNets.push_back( m_netP );
822  aNets.push_back( m_netN );
823 }
824 
825 
827 {
828  SHAPE_LINE_CHAIN ratLineN, ratLineP;
829  TOPOLOGY topo( m_lastNode );
830 
831  if( topo.LeadingRatLine( &m_currentTrace.PLine(), ratLineP ) )
832  {
833  Dbg()->AddLine( ratLineP, 1, 10000 );
834  }
835 
836  if( topo.LeadingRatLine ( &m_currentTrace.NLine(), ratLineN ) )
837  {
838  Dbg()->AddLine( ratLineN, 3, 10000 );
839  }
840 }
841 
842 
843 const std::vector<int> DIFF_PAIR_PLACER::CurrentNets() const
844 {
845  std::vector<int> rv;
846  rv.push_back( m_netP );
847  rv.push_back( m_netN );
848  return rv;
849 }
850 
851 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:104
const SHAPE_LINE_CHAIN & CLine() const
Const accessor to the underlying shape
Definition: pns_line.h:123
bool rhWalkOnly(const VECTOR2I &aP)
route step, walkaround mode
double CoupledLength() const
PNS_MODE Mode() const
Returns the routing mode.
Class ITEM.
Definition: pns_item.h:53
int NetP() const
bool FitGateways(DP_GATEWAYS &aEntry, DP_GATEWAYS &aTarget, bool aPrefDiagonal, DIFF_PAIR &aDp)
const VIA & Via() const
Definition: pns_line.h:253
void BuildForCursor(const VECTOR2I &aCursorPos)
VECTOR2I & B
Definition: seg.h:52
bool attemptWalk(NODE *aNode, DIFF_PAIR *aCurrent, DIFF_PAIR &aWalk, bool aPFirst, bool aWindCw, bool aSolidsOnly)
Class NODE.
Definition: pns_node.h:137
const LAYER_RANGE & Layers() const
Function Layers()
Definition: pns_item.h:207
VIATYPE_T ViaType() const
void SetShape(const SHAPE_LINE_CHAIN &aP, const SHAPE_LINE_CHAIN &aN, bool aSwapLanes=false)
Class SHOVE.
Definition: pns_shove.h:46
void GetModifiedNets(std::vector< int > &aNets) const override
Function GetModifiedNets.
void BuildFromPrimitivePair(DP_PRIMITIVE_PAIR aPair, bool aPreferDiagonal)
void SetLayer(int aLayer)
Function SetLayer()
Definition: pns_item.h:197
bool route(const VECTOR2I &aP)
Function route()
void AppendVias(const VIA &aViaP, const VIA &aViaN)
Classes BOARD_ITEM and BOARD_CONNECTED_ITEM.
bool rhShoveOnly(const VECTOR2I &aP)
route step, shove mode
DEBUG_DECORATOR * Dbg() const
Definition: pns_algo_base.h:70
Class BOARD to handle a board.
Ignore collisions, mark obstacles
VECTOR2I LineProject(const VECTOR2I &aP) const
Function LineProject()
Definition: seg.h:364
int m_iteration
current algorithm iteration
int Diameter() const
Definition: pns_via.h:109
int matchDpSuffix(wxString aNetName, wxString &aComplementNet, wxString &aBaseDpName)
void FilterByOrientation(int aAngleMask, DIRECTION_45 aRefOrientation)
SHOVE_STATUS ProcessSingleLine(LINE &aCurrent, LINE &aObstacle, LINE &aShoved)
Definition: pns_shove.cpp:259
void AllItemsInNet(int aNet, std::set< ITEM * > &aItems)
Definition: pns_node.cpp:1234
bool PushoutForce(NODE *aNode, const VECTOR2I &aDirection, VECTOR2I &aForce, bool aSolidsOnly=true, int aMaxIterations=10)
Definition: pns_via.cpp:31
SHOVE * m_shove
The shove engine
static const int dist[10][10]
Definition: dist.cpp:57
#define PNS_HULL_MARGIN
Class LINE.
Definition: pns_line.h:58
const SHAPE_LINE_CHAIN & CN() const
int m_viaDiameter
current via diameter
WALKAROUND_STATUS Route(const LINE &aInitialPath, LINE &aWalkPath, bool aOptimize=true)
ROUTING_SETTINGS & Settings() const
Returns current router settings
NODE * CurrentNode(bool aLoopsRemoved=false) const override
Function CurrentNode()
NODE * m_world
pointer to world to search colliding items
ITEM * PrimP() const
const VIA makeVia(const VECTOR2I &aP, int aNet)
void Add(const LINE &aLine)
Definition: pns_itemset.cpp:32
bool routeHead(const VECTOR2I &aP)
NODE * Branch()
Function Branch()
Definition: pns_node.cpp:109
NODE * GetWorld() const
Definition: pns_router.h:134
Class PLACEMENT_ALGO.
void SetNet(int aNet)
Function SetNet()
Definition: pns_item.h:167
int m_viaDrill
current via drill
int NetN() const
void SetDiameter(int aDiameter)
Definition: pns_via.h:114
SHAPE_LINE_CHAIN & Simplify()
Function Simplify()
virtual void AddLine(const SHAPE_LINE_CHAIN &aLine, int aType=0, int aWidth=0)
const SEG CSegment(int aIndex) const
Function CSegment()
ITEM * PrimN() const
Class JOINT.
Definition: pns_joint.h:44
VECTOR2I & A
Definition: seg.h:51
void SetGap(int aGap)
bool propagateDpHeadForces(const VECTOR2I &aP, VECTOR2I &aNewP)
bool FixRoute(const VECTOR2I &aP, ITEM *aEndItem) override
Function FixRoute()
void KillChildren()
Destroys all child nodes. Applicable only to the root node.
Definition: pns_node.cpp:1227
void SetFitVias(bool aEnable, int aDiameter=0, int aViaGap=-1)
bool LeadingRatLine(const LINE *aTrack, SHAPE_LINE_CHAIN &aRatLine)
bool ToggleVia(bool aEnabled) override
Function ToggleVia()
int LinkCount(int aMask=-1) const
Definition: pns_joint.h:192
Class DIRECTION_45.
Definition: direction45.h:33
int Gap() const
int m_TrackMinWidth
track min value for width ((min copper size value
void UpdateSizes(const SIZES_SETTINGS &aSizes) override
Function UpdateSizes()
double Skew() const
bool Start(const VECTOR2I &aP, ITEM *aStartItem) override
Function Start()
const ITEM_SET Traces() override
Function Traces()
void SetFailureReason(const wxString &aReason)
Definition: pns_router.h:204
boost::optional< DP_PRIMITIVE_PAIR > m_prevPair
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:530
bool EndsWithVias() const
bool m_placingVia
Are we placing a via?
DIFF_PAIR_PLACER(ROUTER *aRouter)
int DiffPairViaGap() const
void SetSolidsOnly(bool aSolidsOnly)
void SetWidth(int aWidth)
void Remove(int aStartIndex, int aEndIndex)
Function Remove()
virtual bool DpNetPair(ITEM *aItem, int &aNetP, int &aNetN)=0
ROUTER * Router() const
Returns the instance of our router
Definition: pns_algo_base.h:49
boost::optional< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:35
JOINT * FindJoint(const VECTOR2I &aPos, int aLayer, int aNet)
Function FindJoint()
Definition: pns_node.cpp:968
SHAPE_LINE_CHAIN & Line()
Modifiable accessor to the underlying shape
Definition: pns_line.h:117
bool SimplifyLine(LINE *aLine)
PnsKind Kind() const
Function Kind()
Definition: pns_item.h:120
std::unique_ptr< typename std::remove_const< T >::type > Clone(const T &aItem)
Definition: pns_item.h:367
Definition: seg.h:37
Class DIFF_PAIR.
bool findDpPrimitivePair(const VECTOR2I &aP, ITEM *aItem, DP_PRIMITIVE_PAIR &aPair)
RULE_RESOLVER * GetRuleResolver() const
Definition: pns_router.h:154
void FlipPosture() override
Function FlipPosture()
Only walkaround
NODE * m_currentNode
Current world state
void updateLeadingRatLine()
Function updateLeadingRatLine()
bool Move(const VECTOR2I &aP, ITEM *aEndItem) override
Function Move()
void ForceClearance(bool aEnabled, int aClearance)
Definition: pns_shove.h:74
RULE_RESOLVER * GetRuleResolver()
Definition: pns_node.h:168
void CommitRouting(NODE *aNode)
Definition: pns_router.cpp:324
Class DP_PRIMITIVE_PAIR.
#define max(a, b)
Definition: auxiliary.h:86
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:166
Class SHAPE_LINE_CHAIN.
NETCLASSPTR GetNetClass()
OPT_OBSTACLE CheckColliding(const ITEM *aItem, int aKindMask=ITEM::ANY_T)
Function CheckColliding()
Definition: pns_node.cpp:427
void initPlacement()
Function startPlacement()
virtual VECTOR2I Anchor(int n) const
Definition: pns_item.h:326
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
int Net() const
Function Net()
Definition: pns_item.h:177
bool SetLayer(int aLayer) override
Function SetLayer()
Class OPTIMIZER.
Definition: pns_optimizer.h:90
const std::vector< int > CurrentNets() const override
Function CurrentNets()
const SEG & Seg() const
Definition: pns_segment.h:93
bool tryWalkDp(NODE *aNode, DIFF_PAIR &aPair, bool aSolidsOnly)
void SetOrthoMode(bool aOrthoMode) override
Function SetOrthoMode()
void setWorld(NODE *aWorld)
Function setWorld()
SHOVE_STATUS ShoveMultiLines(const ITEM_SET &aHeadSet)
Definition: pns_shove.cpp:1179
static bool Optimize(LINE *aLine, int aEffortLevel, NODE *aWorld)
a quick shortcut to optmize a line without creating and setting up an optimizer
int DiffPairWidth() const
Class DP_GATEWAYS.
virtual void OverrideClearance(bool aEnable, int aNetA=0, int aNetB=0, int aClearance=0)=0
Push and Shove diff pair dimensions (gap) settings dialog.
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
int m_currentWidth
current track width
void Add(std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant=false)
Function Add()
Definition: pns_node.cpp:596
int SegmentCount() const
Function SegmentCount()
NODE * CurrentNode()
Definition: pns_shove.cpp:1393
void SetIterationLimit(const int aIterLimit)
Class LAYER_RANGE.
Definition: pns_layerset.h:32
DP_PRIMITIVE_PAIR EndingPrimitives()
void SetAnchors(const VECTOR2I &aAnchorP, const VECTOR2I &aAnchorN)
const SHAPE_LINE_CHAIN & CP() const
#define min(a, b)
Definition: auxiliary.h:85
NODE * m_lastNode
Postprocessed world state (including marked collisions & removed loops)
void SetNets(int aP, int aN)
OPT_VECTOR2I getDanglingAnchor(NODE *aNode, ITEM *aItem)
bool rhMarkObstacles(const VECTOR2I &aP)
route step, mark obstacles mode