KiCad PCB EDA Suite
pns_router.cpp
Go to the documentation of this file.
1 /*
2  * KiRouter - a push-and-(sometimes-)shove PCB router
3  *
4  * Copyright (C) 2013-2014 CERN
5  * Copyright (C) 2016-2021 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 <cstdio>
23 #include <memory>
24 #include <vector>
25 
26 #include <view/view.h>
27 #include <view/view_group.h>
29 
31 
32 #include <pcb_painter.h>
33 #include <pcbnew_settings.h>
34 #include <pad.h>
35 #include <zone.h>
36 
37 #include <geometry/shape.h>
38 
39 #include "pns_node.h"
40 #include "pns_line_placer.h"
41 #include "pns_line.h"
42 #include "pns_solid.h"
43 #include "pns_utils.h"
44 #include "pns_router.h"
45 #include "pns_shove.h"
46 #include "pns_dragger.h"
47 #include "pns_component_dragger.h"
48 #include "pns_topology.h"
49 #include "pns_diff_pair_placer.h"
50 #include "pns_meander_placer.h"
52 #include "pns_dp_meander_placer.h"
53 
54 namespace PNS {
55 
56 // an ugly singleton for drawing debug items within the router context.
57 // To be fixed sometime in the future.
58 static ROUTER* theRouter;
59 
61 {
62  theRouter = this;
63 
64  m_state = IDLE;
66 
67  m_logger = new LOGGER;
68 
69  // Initialize all other variables:
70  m_lastNode = nullptr;
71  m_iterLimit = 0;
72  m_settings = nullptr;
73  m_iface = nullptr;
75 }
76 
77 
79 {
80  return theRouter;
81 }
82 
83 
85 {
86  ClearWorld();
87  theRouter = nullptr;
88  delete m_logger;
89 }
90 
91 
93 {
94  ClearWorld();
95 
96  m_world = std::make_unique<NODE>( );
97  m_iface->SyncWorld( m_world.get() );
98  m_world->FixupVirtualVias();
99 }
100 
101 
103 {
104  if( m_world )
105  {
106  m_world->KillChildren();
107  m_world.reset();
108  }
109 
110  m_placer.reset();
111 }
112 
113 
115 {
116  return m_state != IDLE;
117 }
118 
119 
120 const ITEM_SET ROUTER::QueryHoverItems( const VECTOR2I& aP, bool aUseClearance )
121 {
122  if( m_state == IDLE || m_placer == nullptr )
123  {
124  if( aUseClearance )
125  {
126  SEGMENT test( SEG( aP, aP ), -1 );
127  test.SetWidth( 1 );
128  test.SetLayers( LAYER_RANGE::All() );
129  NODE::OBSTACLES obs;
130  m_world->QueryColliding( &test, obs, ITEM::ANY_T, -1, false );
131 
132  PNS::ITEM_SET ret;
133 
134  for( OBSTACLE& obstacle : obs )
135  ret.Add( obstacle.m_item, false );
136 
137  return ret;
138  }
139  else
140  {
141  return m_world->HitTest( aP );
142  }
143  }
144  else
145  return m_placer->CurrentNode()->HitTest( aP );
146 }
147 
148 
149 bool ROUTER::StartDragging( const VECTOR2I& aP, ITEM* aItem, int aDragMode )
150 {
151  return StartDragging( aP, ITEM_SET( aItem ), aDragMode );
152 }
153 
154 
155 bool ROUTER::StartDragging( const VECTOR2I& aP, ITEM_SET aStartItems, int aDragMode )
156 {
157  if( aStartItems.Empty() )
158  return false;
159 
160  if( aStartItems.Count( ITEM::SOLID_T ) == aStartItems.Size() )
161  {
162  m_dragger = std::make_unique<COMPONENT_DRAGGER>( this );
164  }
165  else
166  {
167  if( aDragMode & DM_FREE_ANGLE )
169  else
170  m_forceMarkObstaclesMode = false;
171 
172  m_dragger = std::make_unique<DRAGGER>( this );
173  }
174 
175  m_dragger->SetMode( aDragMode );
176  m_dragger->SetWorld( m_world.get() );
177  m_dragger->SetLogger( m_logger );
178  m_dragger->SetDebugDecorator( m_iface->GetDebugDecorator() );
179 
180  if( m_logger )
181  m_logger->Clear();
182 
183  if( m_logger && aStartItems.Size() )
184  {
185  m_logger->Log( LOGGER::EVT_START_DRAG, aP, aStartItems[0] );
186  }
187 
188  if( m_dragger->Start( aP, aStartItems ) )
189  {
191  return true;
192  }
193  else
194  {
195  m_dragger.reset();
196  m_state = IDLE;
197  return false;
198  }
199 }
200 
201 
202 bool ROUTER::isStartingPointRoutable( const VECTOR2I& aWhere, ITEM* aStartItem, int aLayer )
203 {
204  if( Settings().AllowDRCViolations() )
205  return true;
206 
208  {
210  {
211  SetFailureReason( _( "Diff pair gap is less than board minimum clearance." ) );
212  return false;
213  }
214  }
215 
216  ITEM_SET candidates = QueryHoverItems( aWhere );
217 
218  for( ITEM* item : candidates.Items() )
219  {
220  if( !item->IsRoutable() && item->Layers().Overlaps( aLayer ) )
221  {
222  BOARD_ITEM* parent = item->Parent();
223 
224  switch( parent->Type() )
225  {
226  case PCB_PAD_T:
227  {
228  PAD* pad = static_cast<PAD*>( parent );
229 
230  if( pad->GetAttribute() == PAD_ATTRIB::NPTH )
231  SetFailureReason( _( "Cannot start routing from a non-plated hole." ) );
232  }
233  break;
234 
235  case PCB_ZONE_T:
236  case PCB_FP_ZONE_T:
237  {
238  ZONE* zone = static_cast<ZONE*>( parent );
239 
240  if( !zone->GetZoneName().IsEmpty() )
241  {
242  SetFailureReason( wxString::Format( _( "Rule area '%s' disallows tracks." ),
243  zone->GetZoneName() ) );
244  }
245  else
246  {
247  SetFailureReason( _( "Rule area disallows tracks." ) );
248  }
249  }
250  break;
251 
252  case PCB_TEXT_T:
253  case PCB_FP_TEXT_T:
254  SetFailureReason( _( "Cannot start routing from a text item." ) );
255  break;
256 
257  case PCB_SHAPE_T:
258  case PCB_FP_SHAPE_T:
259  SetFailureReason( _( "Cannot start routing from a graphic." ) );
260 
261  default:
262  break;
263  }
264 
265  return false;
266  }
267  }
268 
269  VECTOR2I startPoint = aStartItem ? aStartItem->Anchor( 0 ) : aWhere;
270 
271  if( aStartItem && aStartItem->OfKind( ITEM::SEGMENT_T | ITEM::ARC_T ) )
272  {
273  VECTOR2I otherEnd = aStartItem->Anchor( 1 );
274 
275  if( ( otherEnd - aWhere ).SquaredEuclideanNorm()
276  < ( startPoint - aWhere ).SquaredEuclideanNorm() )
277  {
278  startPoint = otherEnd;
279  }
280  }
281 
283  {
284  SHAPE_LINE_CHAIN dummyStartSeg;
285  LINE dummyStartLine;
286 
287  dummyStartSeg.Append( startPoint );
288  dummyStartSeg.Append( startPoint, true );
289 
290  dummyStartLine.SetShape( dummyStartSeg );
291  dummyStartLine.SetLayer( aLayer );
292  dummyStartLine.SetNet( aStartItem ? aStartItem->Net() : 0 );
293  dummyStartLine.SetWidth( m_sizes.TrackWidth() );
294 
295  if( m_world->CheckColliding( &dummyStartLine, ITEM::ANY_T ) )
296  {
297  ITEM_SET dummyStartSet( &dummyStartLine );
298  NODE::ITEM_VECTOR highlightedItems;
299 
300  markViolations( m_world.get(), dummyStartSet, highlightedItems );
301 
302  for( ITEM* item : highlightedItems )
303  m_iface->HideItem( item );
304 
305  SetFailureReason( _( "The routing start point violates DRC." ) );
306  return false;
307  }
308  }
309  else if( m_mode == PNS_MODE_ROUTE_DIFF_PAIR )
310  {
311  if( !aStartItem )
312  {
313  SetFailureReason( _( "Cannot start a differential pair in the middle of nowhere." ) );
314  return false;
315  }
316 
317  DP_PRIMITIVE_PAIR dpPair;
318  wxString errorMsg;
319 
320  if( !DIFF_PAIR_PLACER::FindDpPrimitivePair( m_world.get(), startPoint, aStartItem, dpPair,
321  &errorMsg ) )
322  {
323  SetFailureReason( errorMsg );
324  return false;
325  }
326 
327  SHAPE_LINE_CHAIN dummyStartSegA;
328  SHAPE_LINE_CHAIN dummyStartSegB;
329  LINE dummyStartLineA;
330  LINE dummyStartLineB;
331 
332  dummyStartSegA.Append( dpPair.AnchorN() );
333  dummyStartSegA.Append( dpPair.AnchorN(), true );
334 
335  dummyStartSegB.Append( dpPair.AnchorP() );
336  dummyStartSegB.Append( dpPair.AnchorP(), true );
337 
338  dummyStartLineA.SetShape( dummyStartSegA );
339  dummyStartLineA.SetLayer( aLayer );
340  dummyStartLineA.SetNet( dpPair.PrimN()->Net() );
341  dummyStartLineA.SetWidth( m_sizes.DiffPairWidth() );
342 
343  dummyStartLineB.SetShape( dummyStartSegB );
344  dummyStartLineB.SetLayer( aLayer );
345  dummyStartLineB.SetNet( dpPair.PrimP()->Net() );
346  dummyStartLineB.SetWidth( m_sizes.DiffPairWidth() );
347 
348  if( m_world->CheckColliding( &dummyStartLineA, ITEM::ANY_T )
349  || m_world->CheckColliding( &dummyStartLineB, ITEM::ANY_T ) )
350  {
351  ITEM_SET dummyStartSet;
352  NODE::ITEM_VECTOR highlightedItems;
353 
354  dummyStartSet.Add( dummyStartLineA );
355  dummyStartSet.Add( dummyStartLineB );
356  markViolations( m_world.get(), dummyStartSet, highlightedItems );
357 
358  for( ITEM* item : highlightedItems )
359  m_iface->HideItem( item );
360 
361  SetFailureReason( _( "The routing start point violates DRC." ) );
362  return false;
363  }
364  }
365 
366  return true;
367 }
368 
369 
370 bool ROUTER::StartRouting( const VECTOR2I& aP, ITEM* aStartItem, int aLayer )
371 {
372  if( !isStartingPointRoutable( aP, aStartItem, aLayer ) )
373  return false;
374 
375  m_forceMarkObstaclesMode = false;
376 
377  switch( m_mode )
378  {
380  m_placer = std::make_unique<LINE_PLACER>( this );
381  break;
382 
384  m_placer = std::make_unique<DIFF_PAIR_PLACER>( this );
385  break;
386 
388  m_placer = std::make_unique<MEANDER_PLACER>( this );
389  break;
390 
392  m_placer = std::make_unique<DP_MEANDER_PLACER>( this );
393  break;
394 
396  m_placer = std::make_unique<MEANDER_SKEW_PLACER>( this );
397  break;
398 
399  default:
400  return false;
401  }
402 
403  m_placer->UpdateSizes( m_sizes );
404  m_placer->SetLayer( aLayer );
405  m_placer->SetDebugDecorator( m_iface->GetDebugDecorator() );
406  m_placer->SetLogger( m_logger );
407 
408  if( m_logger )
409  {
410  m_logger->Clear();
411  m_logger->Log( LOGGER::EVT_START_ROUTE, aP, aStartItem );
412  }
413 
414  if( m_placer->Start( aP, aStartItem ) )
415  {
417  return true;
418  }
419  else
420  {
421  m_state = IDLE;
422  return false;
423  }
424 }
425 
426 
427 void ROUTER::Move( const VECTOR2I& aP, ITEM* endItem )
428 {
429  if( m_logger )
430  m_logger->Log( LOGGER::EVT_MOVE, aP, endItem );
431 
432  switch( m_state )
433  {
434  case ROUTE_TRACK:
435  movePlacing( aP, endItem );
436  break;
437 
438  case DRAG_SEGMENT:
439  moveDragging( aP, endItem );
440  break;
441 
442  default:
443  break;
444  }
445 }
446 
447 
448 void ROUTER::moveDragging( const VECTOR2I& aP, ITEM* aEndItem )
449 {
450  m_iface->EraseView();
451 
452  m_dragger->Drag( aP );
453  ITEM_SET dragged = m_dragger->Traces();
454 
455  updateView( m_dragger->CurrentNode(), dragged, true );
456 }
457 
458 
459 void ROUTER::markViolations( NODE* aNode, ITEM_SET& aCurrent, NODE::ITEM_VECTOR& aRemoved )
460 {
461  auto updateItem =
462  [&]( ITEM* currentItem, ITEM* itemToMark )
463  {
464  std::unique_ptr<ITEM> tmp( itemToMark->Clone() );
465  int clearance;
466  bool removeOriginal = true;
467 
468  if( itemToMark->Marker() & MK_HOLE )
469  clearance = aNode->GetHoleClearance( currentItem, itemToMark );
470  else
471  clearance = aNode->GetClearance( currentItem, itemToMark );
472 
473  if( itemToMark->Layers().IsMultilayer() && !currentItem->Layers().IsMultilayer() )
474  tmp->SetLayer( currentItem->Layer() );
475 
476  if( itemToMark->Kind() == ITEM::SOLID_T )
477  {
478  if( ( itemToMark->Marker() & PNS::MK_HOLE )
479  || !m_iface->IsFlashedOnLayer( itemToMark, itemToMark->Layer() ) )
480  {
481  SOLID* solid = static_cast<SOLID*>( tmp.get() );
482  solid->SetShape( solid->Hole()->Clone() );
483 
484  // Leave the pad flashing around the highlighted hole
485  removeOriginal = false;
486  }
487  }
488 
489  m_iface->DisplayItem( tmp.get(), clearance );
490 
491  if( removeOriginal )
492  aRemoved.push_back( itemToMark );
493  };
494 
495  for( ITEM* item : aCurrent.Items() )
496  {
497  NODE::OBSTACLES obstacles;
498 
499  aNode->QueryColliding( item, obstacles, ITEM::ANY_T );
500 
501  if( item->OfKind( ITEM::LINE_T ) )
502  {
503  LINE* l = static_cast<LINE*>( item );
504 
505  if( l->EndsWithVia() )
506  {
507  VIA v( l->Via() );
508  aNode->QueryColliding( &v, obstacles, ITEM::ANY_T );
509  }
510  }
511 
512  for( OBSTACLE& obs : obstacles )
513  {
514  obs.m_item->Mark( obs.m_item->Marker() | MK_VIOLATION );
515  updateItem( item, obs.m_item );
516  }
517 
518  if( item->Kind() == ITEM::LINE_T )
519  {
520  LINE* line = static_cast<LINE*>( item );
521 
522  // Show clearance on any blocking obstacles
523  if( line->GetBlockingObstacle() )
524  updateItem( item, line->GetBlockingObstacle() );
525  }
526  }
527 }
528 
529 
530 void ROUTER::updateView( NODE* aNode, ITEM_SET& aCurrent, bool aDragging )
531 {
532  NODE::ITEM_VECTOR removed, added;
533  NODE::OBSTACLES obstacles;
534 
535  if( !aNode )
536  return;
537 
539  markViolations( aNode, aCurrent, removed );
540 
541  aNode->GetUpdatedItems( removed, added );
542 
543  for( ITEM* item : added )
544  {
545  int clearance = GetRuleResolver()->Clearance( item, nullptr );
546  m_iface->DisplayItem( item, clearance, aDragging );
547  }
548 
549  for( ITEM* item : removed )
550  m_iface->HideItem( item );
551 }
552 
553 
554 void ROUTER::UpdateSizes( const SIZES_SETTINGS& aSizes )
555 {
556  m_sizes = aSizes;
557 
558  // Change track/via size settings
559  if( m_state == ROUTE_TRACK )
560  {
561  m_placer->UpdateSizes( m_sizes );
562  }
563 }
564 
565 
566 void ROUTER::movePlacing( const VECTOR2I& aP, ITEM* aEndItem )
567 {
568  m_iface->EraseView();
569 
570  m_placer->Move( aP, aEndItem );
571  ITEM_SET current = m_placer->Traces();
572 
573  for( const ITEM* item : current.CItems() )
574  {
575  if( !item->OfKind( ITEM::LINE_T ) )
576  continue;
577 
578  const LINE* l = static_cast<const LINE*>( item );
579  int clearance = GetRuleResolver()->Clearance( item, nullptr );
580 
581  m_iface->DisplayItem( l, clearance );
582 
583  if( l->EndsWithVia() )
584  {
585  const VIA& via = l->Via();
586  int viaClearance = GetRuleResolver()->Clearance( &via, nullptr );
587  int holeClearance = GetRuleResolver()->HoleClearance( &via, nullptr );
588 
589  if( holeClearance + via.Drill() / 2 > viaClearance + via.Diameter() / 2 )
590  viaClearance = holeClearance + via.Drill() / 2 - via.Diameter() / 2;
591 
592  m_iface->DisplayItem( &l->Via(), viaClearance );
593  }
594  }
595 
596  //ITEM_SET tmp( &current );
597 
598  updateView( m_placer->CurrentNode( true ), current );
599 }
600 
601 
603 {
604  if( m_state == ROUTE_TRACK && !m_placer->HasPlacedAnything() )
605  return;
606 
607  NODE::ITEM_VECTOR removed;
608  NODE::ITEM_VECTOR added;
609  NODE::ITEM_VECTOR changed;
610 
611  aNode->GetUpdatedItems( removed, added );
612 
613  for( ITEM* item : removed )
614  {
615  bool is_changed = false;
616 
617  // Items in remove/add that share the same parent are just updated versions
618  // We move them to the updated vector to preserve attributes such as UUID and pad data
619  if( item->Parent() )
620  {
621  for( NODE::ITEM_VECTOR::iterator added_it = added.begin();
622  added_it != added.end(); ++added_it )
623  {
624  if( ( *added_it )->Parent() && ( *added_it )->Parent() == item->Parent() )
625  {
626  changed.push_back( *added_it );
627  added.erase( added_it );
628  is_changed = true;
629  break;
630  }
631  }
632  }
633 
634  if( !is_changed && !item->IsVirtual() )
635  m_iface->RemoveItem( item );
636  }
637 
638  for( ITEM* item : added )
639  {
640  if( !item->IsVirtual() )
641  {
642  m_iface->AddItem( item );
643  }
644  }
645 
646  for( ITEM* item : changed )
647  {
648  if( !item->IsVirtual() )
649  {
650  m_iface->UpdateItem( item );
651  }
652  }
653 
654  m_iface->Commit();
655  m_world->Commit( aNode );
656 }
657 
658 
659 bool ROUTER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinish )
660 {
661  bool rv = false;
662 
663  if( m_logger )
664  m_logger->Log( LOGGER::EVT_FIX, aP, aEndItem );
665 
666  switch( m_state )
667  {
668  case ROUTE_TRACK:
669  rv = m_placer->FixRoute( aP, aEndItem, aForceFinish );
670  break;
671 
672  case DRAG_SEGMENT:
673  rv = m_dragger->FixRoute();
674  break;
675 
676  default:
677  break;
678  }
679 
680  return rv;
681 }
682 
683 
685 {
686  if( !RoutingInProgress() )
687  return;
688 
689  m_placer->UnfixRoute();
690 }
691 
692 
694 {
695  if( m_state == ROUTE_TRACK )
696  m_placer->CommitPlacement();
697 
698  StopRouting();
699 }
700 
701 
703 {
704  // Update the ratsnest with new changes
705 
706  if( m_placer )
707  {
708  std::vector<int> nets;
709  m_placer->GetModifiedNets( nets );
710 
711  // Update the ratsnest with new changes
712  for( int n : nets )
713  m_iface->UpdateNet( n );
714  }
715 
716  if( !RoutingInProgress() )
717  return;
718 
719  m_placer.reset();
720  m_dragger.reset();
721 
722  m_iface->EraseView();
723 
724  m_state = IDLE;
725  m_world->KillChildren();
726  m_world->ClearRanks();
727 }
728 
729 
731 {
732  m_iface->EraseView();
733 }
734 
735 
737 {
738  if( m_state == ROUTE_TRACK )
739  {
740  m_placer->FlipPosture();
741  }
742 }
743 
744 
745 bool ROUTER::SwitchLayer( int aLayer )
746 {
747  if( m_state == ROUTE_TRACK )
748  return m_placer->SetLayer( aLayer );
749 
750  return false;
751 }
752 
753 
755 {
756  if( m_state == ROUTE_TRACK )
757  {
758  bool toggle = !m_placer->IsPlacingVia();
759  m_placer->ToggleVia( toggle );
760  }
761 }
762 
763 
764 const std::vector<int> ROUTER::GetCurrentNets() const
765 {
766  if( m_placer )
767  return m_placer->CurrentNets();
768  else if( m_dragger )
769  return m_dragger->CurrentNets();
770 
771  return std::vector<int>();
772 }
773 
774 
776 {
777  if( m_placer )
778  return m_placer->CurrentLayer();
779  else if( m_dragger )
780  return m_dragger->CurrentLayer();
781 
782  return -1;
783 }
784 
785 
787 {
788  return m_logger;
789 }
790 
791 
793 {
794  if( !m_placer )
795  return false;
796 
797  return m_placer->IsPlacingVia();
798 }
799 
800 
802 {
804 
805  switch( m_settings->GetCornerMode() )
806  {
808  newMode = CORNER_MODE::ROUNDED_45;
809  break;
810 
811  default:
812  break;
813  }
814 
815  m_settings->SetCornerMode( newMode );
816 }
817 
818 
819 void ROUTER::SetOrthoMode( bool aEnable )
820 {
821  if( !m_placer )
822  return;
823 
824  m_placer->SetOrthoMode( aEnable );
825 }
826 
827 
829 {
830  m_mode = aMode;
831 }
832 
833 
835 {
836  m_iface = aIface;
837 }
838 
839 void ROUTER::BreakSegment( ITEM *aItem, const VECTOR2I& aP )
840 {
841  NODE *node = m_world->Branch();
842 
843  LINE_PLACER placer( this );
844 
845  if( placer.SplitAdjacentSegments( node, aItem, aP ) )
846  {
847  CommitRouting( node );
848  }
849  else
850  {
851  delete node;
852  }
853 }
854 
855 }
Base class for PNS router board items.
Definition: pns_item.h:55
int Count(int aKindMask=-1) const
Definition: pns_itemset.h:114
void moveDragging(const VECTOR2I &aP, ITEM *aItem)
Definition: pns_router.cpp:448
virtual int Layer() const
Definition: pns_item.h:156
bool Empty() const
Definition: pns_itemset.h:130
Keep the router "world" - i.e.
Definition: pns_node.h:144
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:80
bool IsMultilayer() const
Definition: pns_layerset.h:77
void SetLayer(int aLayer)
Definition: pns_item.h:155
const ITEM_SET QueryHoverItems(const VECTOR2I &aP, bool aUseClearance=false)
Definition: pns_router.cpp:120
void SetCornerMode(CORNER_MODE aMode)
void CommitRouting()
Definition: pns_router.cpp:693
H/V/45 with filleted corners.
RULE_RESOLVER * GetRuleResolver() const
Definition: pns_router.h:169
void ClearViewDecorations()
Definition: pns_router.cpp:730
ENTRIES & Items()
Definition: pns_itemset.h:135
Single track placement algorithm.
virtual void HideItem(ITEM *aItem)=0
bool isStartingPointRoutable(const VECTOR2I &aWhere, ITEM *aItem, int aLayer)
Definition: pns_router.cpp:202
void SyncWorld()
Definition: pns_router.cpp:92
bool IsPlacingVia() const
Definition: pns_router.cpp:792
void ToggleRounded()
Definition: pns_router.cpp:801
class PCB_TEXT, text on a layer
Definition: typeinfo.h:91
std::unique_ptr< PLACEMENT_ALGO > m_placer
Definition: pns_router.h:230
BOX2I m_visibleViewArea
Definition: pns_router.h:224
const std::vector< int > GetCurrentNets() const
Definition: pns_router.cpp:764
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:93
class PAD, a pad in a footprint
Definition: typeinfo.h:89
int m_iterLimit
Definition: pns_router.h:236
virtual int Clearance(const ITEM *aA, const ITEM *aB)=0
int Size() const
Definition: pns_itemset.h:160
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
Definition: pns_line.h:60
ROUTING_SETTINGS * m_settings
Definition: pns_router.h:239
virtual void AddItem(ITEM *aItem)=0
int GetHoleClearance(const ITEM *aA, const ITEM *aB) const
Definition: pns_node.cpp:113
void Add(const LINE &aLine)
Definition: pns_itemset.cpp:32
void SetOrthoMode(bool aEnable)
Definition: pns_router.cpp:819
bool EndsWithVia() const
Definition: pns_line.h:191
void ToggleViaPlacement()
Definition: pns_router.cpp:754
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
static LAYER_RANGE All()
Definition: pns_layerset.h:109
std::unique_ptr< NODE > m_world
Definition: pns_router.h:227
void ClearWorld()
Definition: pns_router.cpp:102
std::unique_ptr< DRAG_ALGO > m_dragger
Definition: pns_router.h:231
void SetWidth(int aWidth)
Return line width.
Definition: pns_line.h:149
void SetNet(int aNet)
Definition: pns_item.h:149
void UndoLastSegment()
Definition: pns_router.cpp:684
void SetShape(const SHAPE_LINE_CHAIN &aLine)
Return the shape of the line.
Definition: pns_line.h:126
virtual void SyncWorld(NODE *aNode)=0
virtual void DisplayItem(const ITEM *aItem, int aClearance, bool aEdit=false)=0
virtual void UpdateNet(int aNetCode)=0
like PAD_PTH, but not plated
int GetClearance(const ITEM *aA, const ITEM *aB) const
Definition: pns_node.cpp:101
void BreakSegment(ITEM *aItem, const VECTOR2I &aP)
Definition: pns_router.cpp:839
void updateView(NODE *aNode, ITEM_SET &aCurrent, bool aDragging=false)
Definition: pns_router.cpp:530
NODE * m_lastNode
Definition: pns_router.h:228
int Net() const
Definition: pns_item.h:150
bool SplitAdjacentSegments(NODE *aNode, ITEM *aSeg, const VECTOR2I &aP)
Check if point aP lies on segment aSeg.
virtual int HoleClearance(const ITEM *aA, const ITEM *aB)=0
void SetMaximum()
Definition: box2.h:57
bool FixRoute(const VECTOR2I &aP, ITEM *aItem, bool aForceFinish=false)
Definition: pns_router.cpp:659
void SetFailureReason(const wxString &aReason)
Definition: pns_router.h:202
void SetShape(SHAPE *shape)
Definition: pns_solid.h:89
RouterState m_state
Definition: pns_router.h:225
#define _(s)
virtual SHAPE * Clone() const
Return a dynamically allocated copy of the shape.
Definition: shape.h:139
ROUTER_IFACE * m_iface
Definition: pns_router.h:234
Handle a list of polygons defining a copper zone.
Definition: zone.h:57
class ZONE, a copper pour area
Definition: typeinfo.h:105
void movePlacing(const VECTOR2I &aP, ITEM *aItem)
Definition: pns_router.cpp:566
const SHAPE * Hole() const override
Definition: pns_solid.h:81
void Move(const VECTOR2I &aP, ITEM *aItem)
Definition: pns_router.cpp:427
bool StartRouting(const VECTOR2I &aP, ITEM *aItem, int aLayer)
Definition: pns_router.cpp:370
void Clear()
Definition: pns_logger.cpp:40
void SetInterface(ROUTER_IFACE *aIface)
Definition: pns_router.cpp:834
int QueryColliding(const ITEM *aItem, OBSTACLES &aObstacles, int aKindMask=ITEM::ANY_T, int aLimitCount=-1, bool aDifferentNetsOnly=true)
Find items colliding (closer than clearance) with the item aItem.
Definition: pns_node.cpp:266
virtual void UpdateItem(ITEM *aItem)=0
void StopRouting()
Definition: pns_router.cpp:702
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
virtual VECTOR2I Anchor(int n) const
Definition: pns_item.h:215
virtual void EraseView()=0
Definition: seg.h:40
LOGGER * m_logger
Definition: pns_router.h:242
static ROUTER * theRouter
Definition: pns_router.cpp:58
virtual DEBUG_DECORATOR * GetDebugDecorator()=0
ROUTER_MODE
Definition: pns_router.h:62
virtual bool IsFlashedOnLayer(const PNS::ITEM *aItem, int aLayer) const =0
void UpdateSizes(const SIZES_SETTINGS &aSizes)
Applies stored settings.
Definition: pns_router.cpp:554
Ignore collisions, mark obstacles.
void SetMode(ROUTER_MODE aMode)
Definition: pns_router.cpp:828
CORNER_MODE GetCornerMode() const
Store starting/ending primitives (pads, vias or segments) for a differential pair.
Represent a polyline (an zero-thickness chain of connected line segments).
LOGGER * Logger()
Definition: pns_router.cpp:786
bool StartDragging(const VECTOR2I &aP, ITEM *aItem, int aDragMode=DM_ANY)
Definition: pns_router.cpp:149
class ZONE, managed by a footprint
Definition: typeinfo.h:94
bool OfKind(int aKindMask) const
Return true if the item's type matches the mask aKindMask.
Definition: pns_item.h:136
bool SwitchLayer(int layer)
Definition: pns_router.cpp:745
static bool FindDpPrimitivePair(NODE *aWorld, const VECTOR2I &aP, ITEM *aItem, DP_PRIMITIVE_PAIR &aPair, wxString *aErrorMsg=nullptr)
SIZES_SETTINGS m_sizes
Definition: pns_router.h:240
virtual void Commit()=0
const ENTRIES & CItems() const
Definition: pns_itemset.h:136
void GetUpdatedItems(ITEM_VECTOR &aRemoved, ITEM_VECTOR &aAdded)
Return the list of items removed and added in this branch with respect to the root branch.
Definition: pns_node.cpp:1332
ITEM * GetBlockingObstacle() const
Definition: pns_line.h:206
virtual void RemoveItem(ITEM *aItem)=0
ROUTER_MODE m_mode
Definition: pns_router.h:241
void FlipPosture()
Definition: pns_router.cpp:736
bool RoutingInProgress() const
Definition: pns_router.cpp:114
H/V/45 with mitered corners (default)
const VIA & Via() const
Definition: pns_line.h:196
Definition: pad.h:57
std::vector< OBSTACLE > OBSTACLES
Definition: pns_node.h:149
wxString GetZoneName() const
Definition: zone.h:129
ROUTER_MODE Mode() const
Definition: pns_router.h:131
Push and Shove diff pair dimensions (gap) settings dialog.
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:90
void Log(EVENT_TYPE evt, VECTOR2I pos, const ITEM *item=nullptr)
Definition: pns_logger.cpp:64
ROUTING_SETTINGS & Settings()
Definition: pns_router.h:181
static ROUTER * GetInstance()
Definition: pns_router.cpp:78
const LAYER_RANGE & Layers() const
Definition: pns_item.h:152
bool m_forceMarkObstaclesMode
Definition: pns_router.h:237
std::vector< ITEM * > ITEM_VECTOR
Definition: pns_node.h:148
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:113
void markViolations(NODE *aNode, ITEM_SET &aCurrent, NODE::ITEM_VECTOR &aRemoved)
Definition: pns_router.cpp:459
Hold an object colliding with another object, along with some useful data about the collision.
Definition: pns_node.h:102
int GetCurrentLayer() const
Definition: pns_router.cpp:775