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