KiCad PCB EDA Suite
router_tool.cpp
Go to the documentation of this file.
1 /*
2  * KiRouter - a push-and-(sometimes-)shove PCB router
3  *
4  * Copyright (C) 2013-2017 CERN
5  * Copyright (C) 2017 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 <wx/numdlg.h>
23 
24 #include <core/optional.h>
25 #include <functional>
26 using namespace std::placeholders;
27 
28 #include "class_draw_panel_gal.h"
29 #include "class_board.h"
30 
31 #include <pcb_edit_frame.h>
32 #include <id.h>
33 #include <macros.h>
34 #include <pcbnew_id.h>
35 #include <view/view.h>
36 #include <view/view_controls.h>
37 #include <pcb_layer_widget.h>
38 #include <pcb_painter.h>
42 #include <base_units.h>
43 #include <hotkeys.h>
44 #include <confirm.h>
45 #include <bitmaps.h>
46 #include <collectors.h>
47 
48 #include <tool/context_menu.h>
49 #include <tool/tool_manager.h>
50 #include <tool/tool_settings.h>
51 #include <tool/grid_menu.h>
52 
53 #include <tool/zoom_menu.h>
54 #include <tools/pcb_actions.h>
55 #include <tools/selection_tool.h>
56 #include <tools/edit_tool.h>
57 #include <tools/tool_event_utils.h>
58 
59 #include "router_tool.h"
60 #include "pns_segment.h"
61 #include "pns_router.h"
62 
63 using namespace KIGFX;
64 
69 {
70  // Via type
71  VIA_MASK = 0x03,
72  VIA = 0x00,
73  BLIND_VIA = 0x01,
74  MICROVIA = 0x02,
75 
76  // Select layer
78 };
79 
80 
81 TOOL_ACTION PCB_ACTIONS::routerActivateSingle( "pcbnew.InteractiveRouter.SingleTrack",
83  _( "Interactive Router (Single Tracks)" ),
84  _( "Run push & shove router (single tracks)" ), ps_router_xpm, AF_ACTIVATE );
85 
86 TOOL_ACTION PCB_ACTIONS::routerActivateDiffPair( "pcbnew.InteractiveRouter.DiffPair",
88  _( "Interactive Router (Differential Pairs)" ),
89  _( "Run push & shove router (differential pairs)" ), ps_diff_pair_xpm, AF_ACTIVATE );
90 
91 TOOL_ACTION PCB_ACTIONS::routerActivateSettingsDialog( "pcbnew.InteractiveRouter.SettingsDialog",
93  _( "Interactive Router Settings..." ),
94  _( "Open Interactive Router settings" ), tools_xpm );
95 
96 TOOL_ACTION PCB_ACTIONS::routerActivateDpDimensionsDialog( "pcbnew.InteractiveRouter.DpDimensionsDialog",
97  AS_GLOBAL, 0,
98  _( "Differential Pair Dimension Settings..." ),
99  _( "Open Differential Pair Dimension settings" ),
100  ps_diff_pair_gap_xpm );
101 
102 TOOL_ACTION PCB_ACTIONS::routerActivateTuneSingleTrace( "pcbnew.LengthTuner.TuneSingleTrack",
104  _( "Tune length of a single track" ), "", ps_tune_length_xpm, AF_ACTIVATE );
105 
106 TOOL_ACTION PCB_ACTIONS::routerActivateTuneDiffPair( "pcbnew.LengthTuner.TuneDiffPair",
108  _( "Tune length of a differential pair" ), "", NULL, AF_ACTIVATE );
109 
110 TOOL_ACTION PCB_ACTIONS::routerActivateTuneDiffPairSkew( "pcbnew.LengthTuner.TuneDiffPairSkew",
112  _( "Tune skew of a differential pair" ), "", NULL, AF_ACTIVATE );
113 
114 TOOL_ACTION PCB_ACTIONS::routerInlineDrag( "pcbnew.InteractiveRouter.InlineDrag",
115  AS_CONTEXT, 0,
116  _( "Drag Track/Via" ), _( "Drags tracks and vias without breaking connections" ),
117  drag_xpm );
118 
119 TOOL_ACTION PCB_ACTIONS::inlineBreakTrack( "pcbnew.InteractiveRouter.InlineBreakTrack",
120  AS_GLOBAL, 0,
121  _( "Break Track" ),
122  _( "Splits the track segment into two segments connected at the cursor position." ),
123  break_line_xpm );
124 
125 TOOL_ACTION PCB_ACTIONS::breakTrack( "pcbnew.InteractiveRouter.BreakTrack",
126  AS_GLOBAL, 0,
127  _( "Break Track" ),
128  _( "Splits the track segment into two segments connected at the cursor position." ),
129  break_line_xpm );
130 
131 TOOL_ACTION PCB_ACTIONS::drag45Degree( "pcbnew.InteractiveRouter.Drag45Degree",
133  _( "Drag (45 degree mode)" ),
134  _( "Drags the track segment while keeping connected tracks at 45 degrees." ),
135  drag_segment_withslope_xpm );
136 
137 TOOL_ACTION PCB_ACTIONS::dragFreeAngle( "pcbnew.InteractiveRouter.DragFreeAngle",
139  _( "Drag (free angle)" ),
140  _( "Drags the nearest joint in the track without restricting the track angle." ),
141  move_xpm );
142 
143 static const TOOL_ACTION ACT_NewTrack( "pcbnew.InteractiveRouter.NewTrack", AS_CONTEXT,
145  _( "New Track" ), _( "Starts laying a new track." ), add_tracks_xpm );
146 
147 static const TOOL_ACTION ACT_EndTrack( "pcbnew.InteractiveRouter.EndTrack", AS_CONTEXT, WXK_END,
148  _( "End Track" ), _( "Stops laying the current track." ), checked_ok_xpm );
149 
150 static const TOOL_ACTION ACT_AutoEndRoute( "pcbnew.InteractiveRouter.AutoEndRoute", AS_CONTEXT, 'F',
151  _( "Auto-end Track" ), _( "Automagically finishes currently routed track." ) );
152 
153 static const TOOL_ACTION ACT_PlaceThroughVia( "pcbnew.InteractiveRouter.PlaceVia",
155  _( "Place Through Via" ),
156  _( "Adds a through-hole via at the end of currently routed track." ),
157  via_xpm, AF_NONE,
158  (void*) VIA_ACTION_FLAGS::VIA );
159 
160 static const TOOL_ACTION ACT_PlaceBlindVia( "pcbnew.InteractiveRouter.PlaceBlindVia",
162  _( "Place Blind/Buried Via" ),
163  _( "Adds a blind or buried via at the end of currently routed track."),
164  via_buried_xpm, AF_NONE,
165  (void*) VIA_ACTION_FLAGS::BLIND_VIA );
166 
167 static const TOOL_ACTION ACT_PlaceMicroVia( "pcbnew.InteractiveRouter.PlaceMicroVia",
169  _( "Place Microvia" ), _( "Adds a microvia at the end of currently routed track." ),
170  via_microvia_xpm, AF_NONE,
171  (void*) VIA_ACTION_FLAGS::MICROVIA );
172 
174  "pcbnew.InteractiveRouter.SelLayerAndPlaceVia",
176  _( "Select Layer and Place Through Via..." ),
177  _( "Select a layer, then add a through-hole via at the end of currently routed track." ),
178  select_w_layer_xpm, AF_NONE,
180 
182  "pcbnew.InteractiveRouter.SelLayerAndPlaceBlindVia",
184  _( "Select Layer and Place Blind/Buried Via..." ),
185  _( "Select a layer, then add a blind or buried via at the end of currently routed track."),
186  select_w_layer_xpm, AF_NONE,
188 
189 static const TOOL_ACTION ACT_CustomTrackWidth( "pcbnew.InteractiveRouter.CustomTrackViaSize",
191  _( "Custom Track/Via Size..." ),
192  _( "Shows a dialog for changing the track width and via size." ),
193  width_track_xpm );
194 
195 static const TOOL_ACTION ACT_SwitchPosture( "pcbnew.InteractiveRouter.SwitchPosture", AS_CONTEXT,
197  _( "Switch Track Posture" ),
198  _( "Switches posture of the currently routed track." ),
199  change_entry_orient_xpm );
200 
202  TOOL_BASE( "pcbnew.InteractiveRouter" )
203 {
204 }
205 
206 
208 {
209 public:
211  m_frame( aFrame )
212  {
213  SetIcon( width_track_via_xpm );
214  SetTitle( _( "Select Track/Via Width" ) );
215  }
216 
217 protected:
218  CONTEXT_MENU* create() const override
219  {
220  return new TRACK_WIDTH_MENU( m_frame );
221  }
222 
223  void update() override
224  {
225  EDA_UNITS_T units = m_frame.GetUserUnits();
226  BOARD_DESIGN_SETTINGS& bds = m_frame.GetBoard()->GetDesignSettings();
227  bool useIndex = !bds.m_UseConnectedTrackWidth &&
228  !bds.UseCustomTrackViaSize();
229  wxString msg;
230 
231  Clear();
232 
233  Append( ID_POPUP_PCB_SELECT_AUTO_WIDTH, _( "Use Starting Track Width" ),
234  _( "Route using the width of the starting track." ), wxITEM_CHECK );
237 
238  Append( ID_POPUP_PCB_SELECT_USE_NETCLASS_VALUES, _( "Use Net Class Values" ),
239  _( "Use track and via sizes from the net class" ), wxITEM_CHECK );
241  useIndex && bds.GetTrackWidthIndex() == 0 && bds.GetViaSizeIndex() == 0 );
242 
243  Append( ID_POPUP_PCB_SELECT_CUSTOM_WIDTH, _( "Use Custom Values..." ),
244  _( "Specify custom track and via sizes" ), wxITEM_CHECK );
246 
247  AppendSeparator();
248 
249  // Append the list of tracks & via sizes
250  for( unsigned i = 0; i < bds.m_TrackWidthList.size(); i++ )
251  {
252  int width = bds.m_TrackWidthList[i];
253 
254  if( i == 0 )
255  msg = _( "Track netclass width" );
256  else
257  msg = _( "Track " ) + MessageTextFromValue( units, width, true );
258 
259  int menuIdx = ID_POPUP_PCB_SELECT_WIDTH1 + i;
260  Append( menuIdx, msg, wxEmptyString, wxITEM_CHECK );
261  Check( menuIdx, useIndex && bds.GetTrackWidthIndex() == i );
262  }
263 
264  AppendSeparator();
265 
266  for( unsigned i = 0; i < bds.m_ViasDimensionsList.size(); i++ )
267  {
269 
270  if( i == 0 )
271  msg = _( "Via netclass values" );
272  else
273  {
274  msg = _( "Via " ) + MessageTextFromValue( units, via.m_Diameter, true );
275 
276  if( via.m_Drill > 0 )
277  msg << _(", drill " ) << MessageTextFromValue( units, via.m_Drill, true );
278  }
279 
280  int menuIdx = ID_POPUP_PCB_SELECT_VIASIZE1 + i;
281  Append( menuIdx, msg, wxEmptyString, wxITEM_CHECK );
282  Check( menuIdx, useIndex && bds.GetViaSizeIndex() == i );
283  }
284  }
285 
286  OPT_TOOL_EVENT eventHandler( const wxMenuEvent& aEvent ) override
287  {
288  BOARD_DESIGN_SETTINGS &bds = m_frame.GetBoard()->GetDesignSettings();
289  int id = aEvent.GetId();
290 
291  // On Windows, this handler can be called with an event ID not existing in any
292  // menuitem, so only set flags when we have an ID match.
293 
295  {
296  bds.UseCustomTrackViaSize( true );
297  bds.m_UseConnectedTrackWidth = false;
298  m_frame.GetToolManager()->RunAction( ACT_CustomTrackWidth, true );
299  }
300  else if( id == ID_POPUP_PCB_SELECT_AUTO_WIDTH )
301  {
302  bds.UseCustomTrackViaSize( false );
303  bds.m_UseConnectedTrackWidth = true;
304  }
306  {
307  bds.UseCustomTrackViaSize( false );
308  bds.m_UseConnectedTrackWidth = false;
309  bds.SetViaSizeIndex( 0 );
310  bds.SetTrackWidthIndex( 0 );
311  }
313  {
314  bds.UseCustomTrackViaSize( false );
315  bds.m_UseConnectedTrackWidth = false;
317  }
319  {
320  bds.UseCustomTrackViaSize( false );
321  bds.m_UseConnectedTrackWidth = false;
323  }
324 
325  return OPT_TOOL_EVENT( PCB_ACTIONS::trackViaSizeChanged.MakeEvent() );
326  }
327 
328 private:
330 };
331 
332 
334 {
335 public:
337  m_frame( aFrame )
338  {
339  SetIcon( width_track_via_xpm );
340  SetTitle( _( "Select Differential Pair Dimensions" ) );
341  }
342 
343 protected:
344  CONTEXT_MENU* create() const override
345  {
346  return new DIFF_PAIR_MENU( m_frame );
347  }
348 
349  void update() override
350  {
351  EDA_UNITS_T units = m_frame.GetUserUnits();
352  const BOARD_DESIGN_SETTINGS& bds = m_frame.GetBoard()->GetDesignSettings();
353 
354  Clear();
355 
356  Append( ID_POPUP_PCB_SELECT_USE_NETCLASS_DIFFPAIR, _( "Use Net Class Values" ),
357  _( "Use differential pair dimensions from the net class" ), wxITEM_CHECK );
359  !bds.UseCustomDiffPairDimensions() && bds.GetDiffPairIndex() == 0 );
360 
361  Append( ID_POPUP_PCB_SELECT_CUSTOM_DIFFPAIR, _( "Use Custom Values..." ),
362  _( "Specify custom differential pair dimensions" ), wxITEM_CHECK );
364 
365  AppendSeparator();
366 
367  // Append the list of differential pair dimensions
368 
369  // Drop index 0 which is the current netclass dimensions (which are handled above)
370  for( unsigned i = 1; i < bds.m_DiffPairDimensionsList.size(); ++i )
371  {
373  wxString msg;
374 
375  msg << _( "Width " ) << MessageTextFromValue( units, diffPair.m_Width, true );
376 
377  if( diffPair.m_Gap > 0 )
378  msg << _( ", gap " ) << MessageTextFromValue( units, diffPair.m_Gap, true );
379 
380  if( diffPair.m_ViaGap > 0 )
381  msg << _( ", via gap " ) << MessageTextFromValue( units, diffPair.m_ViaGap, true );
382 
383  int menuIdx = ID_POPUP_PCB_SELECT_DIFFPAIR1 + i - 1;
384  Append( menuIdx, msg, wxEmptyString, wxITEM_CHECK );
385  Check( menuIdx, !bds.UseCustomDiffPairDimensions() && bds.GetDiffPairIndex() == i );
386  }
387  }
388 
389  OPT_TOOL_EVENT eventHandler( const wxMenuEvent& aEvent ) override
390  {
391  BOARD_DESIGN_SETTINGS &bds = m_frame.GetBoard()->GetDesignSettings();
392  int id = aEvent.GetId();
393 
394  // On Windows, this handler can be called with an event ID not existing in any
395  // menuitem, so only set flags when we have an ID match.
396 
398  {
399  bds.UseCustomDiffPairDimensions( true );
400  TOOL_MANAGER* toolManager = m_frame.GetToolManager();
402  }
404  {
405  bds.UseCustomDiffPairDimensions( false );
406  bds.SetDiffPairIndex( 0 );
407  }
409  {
410  bds.UseCustomDiffPairDimensions( false );
411  // remember that the menu doesn't contain index 0 (which is the netclass values)
413  }
414 
415  return OPT_TOOL_EVENT( PCB_ACTIONS::trackViaSizeChanged.MakeEvent() );
416  }
417 
418 private:
420 };
421 
422 
424 {
425 public:
427  m_frame( aFrame ), m_mode( aMode ), m_trackViaMenu( aFrame ), m_diffPairMenu( aFrame ),
428  m_zoomMenu( &aFrame ), m_gridMenu( &aFrame )
429  {
430  SetTitle( _( "Interactive Router" ) );
431 
433 
434  AppendSeparator();
435 
436  Add( ACT_NewTrack );
437  Add( ACT_EndTrack );
439 
442 
443 // Add( ACT_AutoEndRoute ); // fixme: not implemented yet. Sorry.
444  Add( ACT_PlaceThroughVia );
445  Add( ACT_PlaceBlindVia );
446  Add( ACT_PlaceMicroVia );
449  Add( ACT_SwitchPosture );
450 
451  AppendSeparator();
452 
453  Add( &m_trackViaMenu );
454 
455  if( m_mode == PNS::PNS_MODE_ROUTE_DIFF_PAIR )
456  Add( &m_diffPairMenu );
457 
459 
460  AppendSeparator();
461 
462  Add( &m_zoomMenu );
463  Add( &m_gridMenu );
464  }
465 
466 private:
467  CONTEXT_MENU* create() const override
468  {
469  return new ROUTER_TOOL_MENU( m_frame, m_mode );
470  }
471 
478 };
479 
480 
482 {
484 }
485 
486 
488 {
490  return true;
491 }
492 
493 
495 {
496  if( aReason == RUN )
497  TOOL_BASE::Reset( aReason );
498 }
499 
500 
502 {
503 #ifdef DEBUG
504  if( aEvent.IsKeyPressed() )
505  {
506  switch( aEvent.KeyCode() )
507  {
508  case '0':
509  wxLogTrace( "PNS", "saving drag/route log...\n" );
510  m_router->DumpLog();
511  break;
512  }
513  }
514 #endif
515 }
516 
517 
519 {
520  int tl = getView()->GetTopLayer();
521 
522  if( m_startItem )
523  {
524  const LAYER_RANGE& ls = m_startItem->Layers();
525 
526  if( ls.Overlaps( tl ) )
527  return tl;
528  else
529  return ls.Start();
530  }
531 
532  return tl;
533 }
534 
535 
537 {
538  int al = frame()->GetActiveLayer();
539  int cl = m_router->GetCurrentLayer();
540 
541  if( cl != al )
542  {
543  m_router->SwitchLayer( al );
544  }
545 
546  OPT<int> newLayer = m_router->Sizes().PairedLayer( cl );
547 
548  if( !newLayer )
549  newLayer = m_router->Sizes().GetLayerTop();
550 
551  m_router->SwitchLayer( *newLayer );
552  frame()->SetActiveLayer( ToLAYER_ID( *newLayer ) );
553 }
554 
555 
556 static VIATYPE_T getViaTypeFromFlags( int aFlags )
557 {
558  switch( aFlags & VIA_ACTION_FLAGS::VIA_MASK )
559  {
560  case VIA_ACTION_FLAGS::VIA: return VIA_THROUGH;
563  default:
564  wxASSERT_MSG( false, "Unhandled via type" );
565  return VIA_THROUGH;
566  }
567 }
568 
569 
571 {
572  const int actViaFlags = aEvent.Parameter<intptr_t>();
573 
574  VIATYPE_T viaType = getViaTypeFromFlags( actViaFlags );
575  const bool selectLayer = actViaFlags & VIA_ACTION_FLAGS::SELECT_LAYER;
576 
578 
579  const int layerCount = bds.GetCopperLayerCount();
580  int currentLayer = m_router->GetCurrentLayer();
583 
585 
586  // ask the user for a target layer
587  PCB_LAYER_ID targetLayer = UNDEFINED_LAYER;
588 
589  if( selectLayer )
590  {
591  wxPoint dlgPosition = wxGetMousePosition();
592 
593  targetLayer = frame()->SelectLayer( static_cast<PCB_LAYER_ID>( currentLayer ),
594  LSET::AllNonCuMask(), dlgPosition );
595  }
596 
597  // fixme: P&S supports more than one fixed layer pair. Update the dialog?
598  sizes.ClearLayerPairs();
599 
600  if( !m_router->IsPlacingVia() )
601  {
602  // Cannot place microvias or blind vias if not allowed (obvious)
603  if( ( viaType == VIA_BLIND_BURIED ) && ( !bds.m_BlindBuriedViaAllowed ) )
604  {
605  DisplayError( frame(), _( "Blind/buried vias have to be enabled in the design settings." ) );
606  return false;
607  }
608 
609  if( ( viaType == VIA_MICROVIA ) && ( !bds.m_MicroViasAllowed ) )
610  {
611  DisplayError( frame(), _( "Microvias have to be enabled in the design settings." ) );
612  return false;
613  }
614 
615  // Can only place through vias on 2-layer boards
616  if( ( viaType != VIA_THROUGH ) && ( layerCount <= 2 ) )
617  {
618  DisplayError( frame(), _( "Only through vias are allowed on 2 layer boards." ) );
619  return false;
620  }
621 
622  // Can only place microvias if we're on an outer layer, or directly adjacent to one
623  if( ( viaType == VIA_MICROVIA ) && ( currentLayer > In1_Cu ) && ( currentLayer < layerCount - 2 ) )
624  {
625  DisplayError( frame(), _( "Microvias can be placed only between the outer layers " \
626  "(F.Cu/B.Cu) and the ones directly adjacent to them." ) );
627  return false;
628  }
629  }
630 
631  // Convert blind/buried via to a through hole one, if it goes through all layers
632  if( viaType == VIA_BLIND_BURIED && ( ( currentLayer == B_Cu ) || ( currentLayer == F_Cu ) )
633  && ( ( pairTop == B_Cu && pairBottom == F_Cu )
634  || ( pairTop == F_Cu && pairBottom == B_Cu ) ) )
635  {
636  viaType = VIA_THROUGH;
637  }
638 
639  switch( viaType )
640  {
641  case VIA_THROUGH:
642  sizes.SetViaDiameter( bds.GetCurrentViaSize() );
643  sizes.SetViaDrill( bds.GetCurrentViaDrill() );
644 
645  if( targetLayer != UNDEFINED_LAYER )
646  {
647  // go from the current layer to the chosen layer
648  sizes.AddLayerPair( currentLayer, targetLayer );
649  }
650  else
651  {
652  // use the default layer pair
653  sizes.AddLayerPair( pairTop, pairBottom );
654  }
655  break;
656 
657  case VIA_MICROVIA:
658  sizes.SetViaDiameter( bds.GetCurrentMicroViaSize() );
659  sizes.SetViaDrill( bds.GetCurrentMicroViaDrill() );
660 
661  wxASSERT_MSG( !selectLayer, "Unexpected select layer for microvia (microvia layers are implicit)" );
662 
663  if( currentLayer == F_Cu || currentLayer == In1_Cu )
664  {
665  // front-side microvia
666  sizes.AddLayerPair( F_Cu, In1_Cu );
667  }
668  else if( currentLayer == B_Cu || currentLayer == layerCount - 2 )
669  {
670  // back-side microvia
671  sizes.AddLayerPair( B_Cu, layerCount - 2 );
672  }
673  else
674  {
675  wxASSERT_MSG( false, "Invalid layer pair for microvia (must be on or adjacent to an outer layer)" );
676  }
677  break;
678 
679  case VIA_BLIND_BURIED:
680  sizes.SetViaDiameter( bds.GetCurrentViaSize() );
681  sizes.SetViaDrill( bds.GetCurrentViaDrill() );
682 
683  if( targetLayer != UNDEFINED_LAYER )
684  {
685  // go directly to the user specified layer
686  sizes.AddLayerPair( currentLayer, targetLayer );
687  }
688  else
689  {
690  if( currentLayer == pairTop || currentLayer == pairBottom )
691  {
692  // the current layer is on the defined layer pair,
693  // swap to the other side
694  sizes.AddLayerPair( pairTop, pairBottom );
695  }
696  else
697  {
698  // the current layer is not part of the current layer pair,
699  // so fallback and swap to the top layer of the pair by default
700  sizes.AddLayerPair( pairTop, currentLayer );
701  }
702  }
703  break;
704 
705  default:
706  wxASSERT( false );
707  break;
708  }
709 
710  sizes.SetViaType( viaType );
711 
712  m_router->UpdateSizes( sizes );
714 
715  if( m_router->RoutingInProgress() )
716  updateEndItem( aEvent );
717  else
718  updateStartItem( aEvent );
719 
720  m_router->Move( m_endSnapPoint, m_endItem ); // refresh
721 
722  return 0;
723 }
724 
725 
727 {
728  int routingLayer = getStartLayer( m_startItem );
729 
730  if( !IsCopperLayer( routingLayer ) )
731  {
732  DisplayError( frame(), _( "Tracks on Copper layers only" ) );
733  return false;
734  }
735 
736  frame()->SetActiveLayer( ToLAYER_ID( routingLayer ) );
737 
738  // Force layer visible
739  frame()->GetLayerManager()->SetLayerVisible( routingLayer, true );
740 
741  // for some reason I don't understand, GetNetclass() may return null sometimes...
742  if( m_startItem && m_startItem->Net() >= 0 &&
744  {
745  highlightNet( true, m_startItem->Net() );
746  // Update track width and via size shown in main toolbar comboboxes
747  frame()->SetCurrentNetClass( m_startItem->Parent()->GetNetClass()->GetName() );
748  }
749  else
751 
752  controls()->ForceCursorPosition( false );
753  controls()->SetAutoPan( true );
754 
755  PNS::SIZES_SETTINGS sizes( m_router->Sizes() );
756 
757  sizes.Init( board(), m_startItem );
758  sizes.AddLayerPair( frame()->GetScreen()->m_Route_Layer_TOP,
759  frame()->GetScreen()->m_Route_Layer_BOTTOM );
760  m_router->UpdateSizes( sizes );
761 
762  if( !m_router->StartRouting( m_startSnapPoint, m_startItem, routingLayer ) )
763  {
765  highlightNet( false );
766  controls()->SetAutoPan( false );
767  return false;
768  }
769 
770  m_endItem = NULL;
772 
773  frame()->UndoRedoBlock( true );
774 
775  return true;
776 }
777 
778 
780 {
782 
783  controls()->SetAutoPan( false );
784  controls()->ForceCursorPosition( false );
785  frame()->UndoRedoBlock( false );
786  highlightNet( false );
787 
788  return true;
789 }
790 
791 
793 {
794  if( !prepareInteractive() )
795  return;
796 
797  while( OPT_TOOL_EVENT evt = Wait() )
798  {
799  // Don't crash if we missed an operation that cancelled routing.
800  wxCHECK2( m_router->RoutingInProgress(), break );
801 
802  if( evt->IsMotion() )
803  {
804  m_router->SetOrthoMode( evt->Modifier( MD_CTRL ) );
805  updateEndItem( *evt );
807  }
808  else if( evt->IsClick( BUT_LEFT ) || evt->IsAction( &ACT_NewTrack ) )
809  {
810  updateEndItem( *evt );
811  bool needLayerSwitch = m_router->IsPlacingVia();
812  bool forceFinish = evt->Modifier( MD_SHIFT );
813 
814 
815  if( m_router->FixRoute( m_endSnapPoint, m_endItem, forceFinish ) )
816  break;
817 
818  if( needLayerSwitch )
820 
821  // Synchronize the indicated layer
823  updateEndItem( *evt );
825  m_startItem = NULL;
826  }
827  else if( evt->IsAction( &ACT_SwitchPosture ) )
828  {
830  updateEndItem( *evt );
831  m_router->Move( m_endSnapPoint, m_endItem ); // refresh
832  }
833  else if( evt->IsAction( &PCB_ACTIONS::layerChanged ) )
834  {
835  m_router->SwitchLayer( frame()->GetActiveLayer() );
836  updateEndItem( *evt );
837  m_router->Move( m_endSnapPoint, m_endItem ); // refresh
838  }
839  else if( evt->IsAction( &ACT_EndTrack ) )
840  {
841  bool still_routing = true;
842  while( still_routing )
843  still_routing = m_router->FixRoute( m_endSnapPoint, m_endItem );
844  break;
845  }
846  else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt )
847  || evt->IsUndoRedo()
848  || evt->IsAction( &PCB_ACTIONS::routerInlineDrag ) )
849  break;
850  }
851 
853 }
854 
855 
857 {
859  DIALOG_PNS_DIFF_PAIR_DIMENSIONS settingsDlg( frame(), sizes );
860 
861  if( settingsDlg.ShowModal() == wxID_OK )
862  {
863  m_router->UpdateSizes( sizes );
864  m_savedSizes = sizes;
865 
867  bds.SetCustomDiffPairWidth( sizes.DiffPairWidth() );
868  bds.SetCustomDiffPairGap( sizes.DiffPairGap() );
870  }
871 
872  return 0;
873 }
874 
875 
877 {
878  DIALOG_PNS_SETTINGS settingsDlg( frame(), m_router->Settings() );
879 
880  if( settingsDlg.ShowModal() == wxID_OK )
882 
883  return 0;
884 }
885 
886 
888 {
895 
901 
904 }
905 
906 
908 {
909  frame()->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Route Track" ) );
911 }
912 
913 
915 {
916  frame()->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Router Differential Pair" ) );
918 }
919 
920 
922 {
924  {
926  }
927 }
928 
929 
931 {
932  PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
933 
934  // Deselect all items
936 
937  Activate();
938 
939  m_router->SetMode( aMode );
940 
941  VIEW_CONTROLS* ctls = getViewControls();
942  ctls->ShowCursor( true );
943  ctls->ForceCursorPosition( false );
945 
946  std::unique_ptr<ROUTER_TOOL_MENU> ctxMenu( new ROUTER_TOOL_MENU( *frame, aMode ) );
947  SetContextMenu( ctxMenu.get() );
948 
949  // Main loop: keep receiving events
950  while( OPT_TOOL_EVENT evt = Wait() )
951  {
953  {
954  break; // Finish
955  }
956  else if( evt->Action() == TA_UNDO_REDO_PRE )
957  {
958  m_router->ClearWorld();
959  }
960  else if( evt->Action() == TA_UNDO_REDO_POST || evt->Action() == TA_MODEL_CHANGE )
961  {
962  m_router->SyncWorld();
963  }
964  else if( evt->IsMotion() )
965  {
966  updateStartItem( *evt );
967  }
968  else if( evt->IsAction( &PCB_ACTIONS::dragFreeAngle ) )
969  {
970  updateStartItem( *evt, true );
972  }
973  else if( evt->IsAction( &PCB_ACTIONS::drag45Degree ) )
974  {
975  updateStartItem( *evt, true );
977  }
978  else if( evt->IsAction( &PCB_ACTIONS::breakTrack ) )
979  {
980  updateStartItem( *evt, true );
981  breakTrack( );
982  }
983  else if( evt->IsClick( BUT_LEFT ) || evt->IsAction( &ACT_NewTrack ) )
984  {
985  updateStartItem( *evt );
986 
987  if( evt->Modifier( MD_CTRL ) )
989  else
990  performRouting();
991  }
992  else if( evt->IsAction( &ACT_PlaceThroughVia ) )
993  {
995  }
996  }
997 
998  frame->SetNoToolSelected();
999  SetContextMenu( nullptr );
1000 
1001  // Store routing settings till the next invocation
1004 
1005  return 0;
1006 }
1007 
1008 
1010 {
1011  VIEW_CONTROLS* ctls = getViewControls();
1012 
1013  if( m_startItem && m_startItem->IsLocked() )
1014  {
1015  KIDIALOG dlg( frame(), _( "The selected item is locked." ), _( "Confirmation" ),
1016  wxOK | wxCANCEL | wxICON_WARNING );
1017  dlg.SetOKLabel( _( "Drag Anyway" ) );
1018  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
1019 
1020  if( dlg.ShowModal() == wxID_CANCEL )
1021  return;
1022  }
1023 
1024  bool dragStarted = m_router->StartDragging( m_startSnapPoint, m_startItem, aMode );
1025 
1026  if( !dragStarted )
1027  return;
1028 
1029  if( m_startItem && m_startItem->Net() >= 0 )
1030  highlightNet( true, m_startItem->Net() );
1031 
1032  ctls->SetAutoPan( true );
1033 
1034  frame()->UndoRedoBlock( true );
1035 
1036  while( OPT_TOOL_EVENT evt = Wait() )
1037  {
1038  ctls->ForceCursorPosition( false );
1039 
1040  if( evt->IsMotion() )
1041  {
1042  updateEndItem( *evt );
1044  }
1045  else if( evt->IsClick( BUT_LEFT ) )
1046  {
1048  break;
1049  }
1050  else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsUndoRedo() )
1051  {
1052  break;
1053  }
1054 
1055  handleCommonEvents( *evt );
1056  }
1057 
1058  if( m_router->RoutingInProgress() )
1059  m_router->StopRouting();
1060 
1061  m_startItem = nullptr;
1062 
1063  frame()->UndoRedoBlock( false );
1064  ctls->SetAutoPan( false );
1065  ctls->ForceCursorPosition( false );
1066  highlightNet( false );
1067 }
1068 
1069 
1071 {
1072  /*
1073  * If the collection contains a trivial line corner (two connected segments)
1074  * or a non-fanout-via (a via with no more than two connected segments), then
1075  * trim the collection down to a single item (which one won't matter since
1076  * they're all connected).
1077  */
1078 
1079  // First make sure we've got something that *might* match.
1080  int vias = aCollector.CountType( PCB_VIA_T );
1081  int traces = aCollector.CountType( PCB_TRACE_T );
1082 
1083  if( vias > 1 || traces > 2 || vias + traces < 1 )
1084  return;
1085 
1086  // Fetch first TRACK (via or trace) as our reference
1087  TRACK* reference = nullptr;
1088 
1089  for( int i = 0; !reference && i < aCollector.GetCount(); i++ )
1090  reference = dynamic_cast<TRACK*>( aCollector[i] );
1091 
1092  int refNet = reference->GetNetCode();
1093 
1094  wxPoint refPoint( aPt.x, aPt.y );
1095  STATUS_FLAGS flags = reference->IsPointOnEnds( refPoint, -1 );
1096 
1097  if( flags & STARTPOINT )
1098  refPoint = reference->GetStart();
1099  else if( flags & ENDPOINT )
1100  refPoint = reference->GetEnd();
1101 
1102  // Check all items to ensure that any TRACKs are co-terminus with the reference and on
1103  // the same net.
1104  for( int i = 0; i < aCollector.GetCount(); i++ )
1105  {
1106  TRACK* neighbor = dynamic_cast<TRACK*>( aCollector[i] );
1107 
1108  if( neighbor && neighbor != reference )
1109  {
1110  if( neighbor->GetNetCode() != refNet )
1111  return;
1112 
1113  if( neighbor->GetStart() != refPoint && neighbor->GetEnd() != refPoint )
1114  return;
1115  }
1116  }
1117 
1118  // Selection meets criteria; trim it to the reference item.
1119  aCollector.Empty();
1120  aCollector.Append( reference );
1121 }
1122 
1123 
1125 {
1127  const auto& selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection();
1128 
1129  if( selection.Size() == 1 )
1130  {
1131  const BOARD_CONNECTED_ITEM* item = static_cast<const BOARD_CONNECTED_ITEM*>( selection.Front() );
1132 
1133  if( item->Type() == PCB_TRACE_T || item->Type() == PCB_VIA_T )
1134  return true;
1135  }
1136 
1137  return false;
1138 }
1139 
1140 
1142 {
1143  const auto& selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection();
1144 
1145  if( selection.Empty() )
1147 
1148  if( selection.Size() != 1 )
1149  return 0;
1150 
1151  const BOARD_CONNECTED_ITEM* item = static_cast<const BOARD_CONNECTED_ITEM*>( selection.Front() );
1152 
1153  if( item->Type() != PCB_TRACE_T && item->Type() != PCB_VIA_T )
1154  return 0;
1155 
1156  Activate();
1157 
1159  m_router->SyncWorld();
1161 
1162  if( m_startItem && m_startItem->IsLocked() )
1163  {
1164  KIDIALOG dlg( frame(), _( "The selected item is locked." ), _( "Confirmation" ),
1165  wxOK | wxCANCEL | wxICON_WARNING );
1166  dlg.SetOKLabel( _( "Drag Anyway" ) );
1167  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
1168 
1169  if( dlg.ShowModal() == wxID_CANCEL )
1170  return 0;
1171  }
1172 
1174 
1175  int dragMode = aEvent.Parameter<int64_t> ();
1176 
1177  bool dragStarted = m_router->StartDragging( p0, m_startItem, dragMode );
1178 
1179  if( !dragStarted )
1180  return 0;
1181 
1182  controls()->ShowCursor( true );
1183  controls()->ForceCursorPosition( false );
1184  controls()->SetAutoPan( true );
1185  frame()->UndoRedoBlock( true );
1186 
1187  while( OPT_TOOL_EVENT evt = Wait() )
1188  {
1189  if( evt->IsCancel() )
1190  {
1191  break;
1192  }
1193  else if( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) )
1194  {
1195  updateEndItem( *evt );
1197  }
1198  else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
1199  {
1200  updateEndItem( *evt );
1202  break;
1203  }
1204  }
1205 
1206  if( m_router->RoutingInProgress() )
1207  m_router->StopRouting();
1208 
1209  controls()->SetAutoPan( false );
1210  controls()->ForceCursorPosition( false );
1211  frame()->UndoRedoBlock( false );
1212 
1213  return 0;
1214 }
1215 
1216 
1218 {
1219  const auto& selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection();
1220 
1221  if( selection.Size() != 1 )
1222  return 0;
1223 
1224  const BOARD_CONNECTED_ITEM* item = static_cast<const BOARD_CONNECTED_ITEM*>( selection.Front() );
1225 
1226  if( item->Type() != PCB_TRACE_T )
1227  return 0;
1228 
1229  Init();
1230  Activate();
1231 
1233  m_router->SyncWorld();
1235  m_startSnapPoint = snapToItem( true, m_startItem, controls()->GetCursorPosition() );
1236 
1237 
1238  if( m_startItem && m_startItem->IsLocked() )
1239  {
1240  KIDIALOG dlg( frame(), _( "The selected item is locked." ), _( "Confirmation" ),
1241  wxOK | wxCANCEL | wxICON_WARNING );
1242  dlg.SetOKLabel( _( "Break Track" ) );
1243  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
1244 
1245  if( dlg.ShowModal() == wxID_CANCEL )
1246  return 0;
1247  }
1248 
1249  frame()->UndoRedoBlock( true );
1250  breakTrack();
1251 
1252  if( m_router->RoutingInProgress() )
1253  m_router->StopRouting();
1254 
1255  frame()->UndoRedoBlock( false );
1256 
1257  return 0;
1258 }
1259 
1260 
1262 {
1264  DIALOG_TRACK_VIA_SIZE sizeDlg( frame(), bds );
1265 
1266  if( sizeDlg.ShowModal() )
1267  {
1268  bds.UseCustomTrackViaSize( true );
1270  }
1271 
1272  return 0;
1273 }
1274 
1275 
1277 {
1278  PNS::SIZES_SETTINGS sizes( m_router->Sizes() );
1279  sizes.ImportCurrent( board()->GetDesignSettings() );
1280  m_router->UpdateSizes( sizes );
1281 
1282  //Changing the track width can affect the placement, so call the
1283  // move routine without changing the destination
1285 
1286  return 0;
1287 }
void Empty()
Function Empty sets the list to empty.
Definition: collector.h:123
CONTEXT_MENU * create() const override
Returns an instance of this class. It has to be overridden in inheriting classes. ...
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:53
int mainLoop(PNS::ROUTER_MODE aMode)
int GetCurrentMicroViaSize()
Function GetCurrentMicroViaSize.
virtual void ShowCursor(bool aEnabled)
Function ShowCursor() Enables or disables display of cursor.
Class ITEM.
Definition: pns_item.h:53
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:114
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
Struct VIA_DIMENSION is a small helper container to handle a stock of specific vias each with unique ...
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:116
OPT_TOOL_EVENT eventHandler(const wxMenuEvent &aEvent) override
Event handler stub.
virtual int GetTopLayer() const
Definition: view.cpp:849
void DoNotShowCheckbox(wxString file, int line)
Shows the &#39;do not show again&#39; checkbox
Definition: confirm.cpp:60
void SetTrackWidthIndex(unsigned aIndex)
Function SetTrackWidthIndex sets the current track width list index to aIndex.
int GetCurrentViaDrill() const
Function GetCurrentViaDrill.
virtual void SetToolID(int aId, int aCursor, const wxString &aToolMsg) override
Set the tool command ID to aId and sets the cursor to aCursor.
PCB_EDIT_FRAME & m_frame
int DpDimensionsDialog(const TOOL_EVENT &aEvent)
Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
Definition: class_module.h:57
const LAYER_RANGE & Layers() const
Function Layers()
Definition: pns_item.h:209
Normal via
Definition: router_tool.cpp:73
Helper class to create more flexible dialogs, including &#39;do not show again&#39; checkbox handling...
Definition: confirm.h:44
bool finishInteractive()
void SetCustomDiffPairViaGap(int aGap)
Function SetCustomDiffPairViaGap Sets custom via gap for differential pairs (i.e. ...
blind/buried via
Definition: router_tool.cpp:74
Implementation of conversion functions that require both schematic and board internal units...
This file is part of the common library.
const wxString & FailureReason() const
Definition: pns_router.h:214
std::vector< int > m_TrackWidthList
Class CONTEXT_MENU.
Definition: context_menu.h:44
int GetCurrentMicroViaDrill()
Function GetCurrentMicroViaDrill.
VIEW_CONTROLS class definition.
std::vector< DIFF_PAIR_DIMENSION > m_DiffPairDimensionsList
VECTOR2I m_startSnapPoint
Definition: pns_tool_base.h:70
int InlineDrag(const TOOL_EVENT &aEvent)
Class SELECTION_TOOL.
static const TOOL_ACTION ACT_NewTrack("pcbnew.InteractiveRouter.NewTrack", AS_CONTEXT, TOOL_ACTION::LegacyHotKey(HK_ADD_NEW_TRACK), _("New Track"), _("Starts laying a new track."), add_tracks_xpm)
Class BOARD to handle a board.
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
STATUS_FLAGS IsPointOnEnds(const wxPoint &point, int min_dist=0)
Function IsPointOnEnds returns STARTPOINT if point if near (dist = min_dist) start point...
int RouteSingleTrace(const TOOL_EVENT &aEvent)
static TOOL_ACTION dragFreeAngle
Definition: pcb_actions.h:142
Tool is invoked after being inactive.
Definition: tool_base.h:82
EDA_ITEM * Front() const
Definition: selection.h:152
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
void UseCustomDiffPairDimensions(bool aEnabled)
Function UseCustomDiffPairDimensions Enables/disables custom differential pair dimensions.
static LSET AllNonCuMask()
Function AllNonCuMask returns a mask holding all layer minus CU layers.
Definition: lset.cpp:699
static TOOL_ACTION cancelInteractive
Definition: actions.h:45
SIZES_SETTINGS m_savedSizes
Stores sizes settings between router invocations.
Definition: pns_tool_base.h:67
void SyncWorld()
Definition: pns_router.cpp:91
OPT_TOOL_EVENT Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
Microvia
Definition: router_tool.cpp:77
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:125
static int LegacyHotKey(int aHotKey)
Creates a hot key code that refers to a legacy hot key setting, instead of a particular key...
Definition: tool_action.h:174
static const TOOL_ACTION ACT_PlaceBlindVia("pcbnew.InteractiveRouter.PlaceBlindVia", AS_CONTEXT, TOOL_ACTION::LegacyHotKey(HK_ADD_BLIND_BURIED_VIA), _("Place Blind/Buried Via"), _("Adds a blind or buried via at the end of currently routed track."), via_buried_xpm, AF_NONE,(void *) VIA_ACTION_FLAGS::BLIND_VIA)
BOARD * GetBoard() const
static TOOL_ACTION trackViaSizeChanged
Definition: pcb_actions.h:299
static TOOL_ACTION drag45Degree
Definition: pcb_actions.h:141
TRACK_WIDTH_MENU(PCB_EDIT_FRAME &aFrame)
static const TOOL_ACTION ACT_PlaceThroughVia("pcbnew.InteractiveRouter.PlaceVia", AS_CONTEXT, TOOL_ACTION::LegacyHotKey(HK_ADD_THROUGH_VIA), _("Place Through Via"), _("Adds a through-hole via at the end of currently routed track."), via_xpm, AF_NONE,(void *) VIA_ACTION_FLAGS::VIA)
static TOOL_ACTION routerActivateSingle
Activation of the Push and Shove router.
Definition: pcb_actions.h:203
void UndoRedoBlock(bool aBlock=true)
Function UndoRedoBlock Enables/disable undo and redo operations.
void SetViaDrill(int aDrill)
bool IsPlacingVia() const
Definition: pns_router.cpp:492
SIZES_SETTINGS & Sizes()
Definition: pns_router.h:206
VIATYPE_T
Definition: class_track.h:50
bool IsKeyPressed() const
Definition: tool_event.h:335
int KeyCode() const
Definition: tool_event.h:330
bool SetCurrentNetClass(const wxString &aNetClassName)
Function SetCurrentNetClass Must be called after a netclass selection (or after a netclass parameter ...
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
void SwitchLayer(int layer)
Definition: pns_router.cpp:429
int CountType(KICAD_T aType)
Function CountType counts the number of items matching aType.
Definition: collector.h:265
void breakTrack()
int GetCurrentViaSize() const
Function GetCurrentViaSize.
Class BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected an...
ROUTER_TOOL_MENU(PCB_EDIT_FRAME &aFrame, PNS::ROUTER_MODE aMode)
static TOOL_ACTION routerActivateTuneSingleTrace
Activation of the Push and Shove router (tune single line mode)
Definition: pcb_actions.h:209
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
void SetOrthoMode(bool aEnable)
Definition: pns_router.cpp:501
Struct DIFF_PAIR_DIMENSION is a small helper container to handle a stock of specific differential pai...
const wxPoint & GetEnd() const
Definition: class_track.h:123
const VECTOR2I snapToItem(bool aEnabled, ITEM *aItem, VECTOR2I aP)
NODE * GetWorld() const
Definition: pns_router.h:143
void ToggleViaPlacement()
Definition: pns_router.cpp:442
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
void handleCommonEvents(const TOOL_EVENT &evt)
Pcbnew hotkeys.
GRID_MENU m_gridMenu
This file contains miscellaneous commonly used macros and functions.
void ClearWorld()
Definition: pns_router.cpp:100
unsigned GetViaSizeIndex() const
Function GetViaSizeIndex.
void Append(EDA_ITEM *item)
Function Append adds an item to the end of the list.
Definition: collector.h:133
bool RoutingInProgress() const
Definition: pns_router.cpp:112
bool OfKind(int aKindMask) const
Function OfKind()
Definition: pns_item.h:132
wxString MessageTextFromValue(EDA_UNITS_T aUnits, int aValue, bool aUseMils)
Definition: base_units.cpp:125
virtual void updateStartItem(const TOOL_EVENT &aEvent, bool aIgnorePads=false)
void SetViaSizeIndex(unsigned aIndex)
Function SetViaSizeIndex sets the current via size list index to aIndex.
int onViaCommand(const TOOL_EVENT &aEvent)
Class TOOL_MANAGER.
Definition: tool_manager.h:49
KIGFX::VIEW_CONTROLS * controls() const
Definition: pcb_tool.h:138
virtual void Reset(RESET_REASON aReason)=0
Function Reset() Brings the tool to a known, initial state.
int RouteDiffPair(const TOOL_EVENT &aEvent)
virtual void updateEndItem(const TOOL_EVENT &aEvent)
bool prepareInteractive()
PCB_LAYER_ID
A quick note on layer IDs:
bool IsLocked() const
Definition: pns_item.h:338
int GetCopperLayerCount() const
Function GetCopperLayerCount.
void performRouting()
CONTEXT_MENU * create() const override
Returns an instance of this class. It has to be overridden in inheriting classes. ...
void BreakSegment(ITEM *aItem, const VECTOR2I &aP)
Definition: pns_router.cpp:522
static TOOL_ACTION routerActivateTuneDiffPairSkew
Activation of the Push and Shove router (skew tuning mode)
Definition: pcb_actions.h:215
std::shared_ptr< NETCLASS > GetNetClass() const
Function GetNetClass returns the NETCLASS for this item.
static const char Default[]
the name of the default NETCLASS
Definition: netclass.h:80
void update() override
Update menu state stub.
const wxPoint & GetStart() const
Definition: class_track.h:126
CONTEXT_MENU * create() const override
Returns an instance of this class. It has to be overridden in inheriting classes. ...
VECTOR2D GetCursorPosition() const
Returns the current cursor position in world coordinates.
void SetCustomDiffPairWidth(int aWidth)
Function SetCustomDiffPairWidth Sets custom track width for differential pairs (i.e.
PCB_EDIT_FRAME * frame() const
Definition: pcb_tool.h:139
Class TOOL_EVENT.
Definition: tool_event.h:168
PNS::ROUTER_MODE m_mode
ITEM * m_startItem
Definition: pns_tool_base.h:68
bool FixRoute(const VECTOR2I &aP, ITEM *aItem, bool aForceFinish=false)
Definition: pns_router.cpp:367
OPT_TOOL_EVENT eventHandler(const wxMenuEvent &aEvent) override
Event handler stub.
DIFF_PAIR_MENU(PCB_EDIT_FRAME &aFrame)
static const TOOL_ACTION ACT_SwitchPosture("pcbnew.InteractiveRouter.SwitchPosture", AS_CONTEXT, TOOL_ACTION::LegacyHotKey(HK_SWITCH_TRACK_POSTURE), _("Switch Track Posture"), _("Switches posture of the currently routed track."), change_entry_orient_xpm)
ZOOM_MENU m_zoomMenu
void Init(BOARD *aBoard, ITEM *aStartItem=NULL, int aNet=-1)
unsigned STATUS_FLAGS
Definition: base_struct.h:147
ROUTER * m_router
Definition: pns_tool_base.h:78
void SetContextMenu(CONTEXT_MENU *aMenu, CONTEXT_MENU_TRIGGER aTrigger=CMENU_BUTTON)
Function SetContextMenu()
bool CanInlineDrag()
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:539
void Load(const TOOL_SETTINGS &where)
Class VIEW_CONTROLS is an interface for classes handling user events controlling the view behaviour (...
PCB_LAYER_ID m_Route_Layer_BOTTOM
Definition: pcb_screen.h:46
void switchLayerOnViaPlacement()
PCB_EDIT_FRAME & m_frame
int DiffPairViaGap() const
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Function ForceCursorPosition() Places the cursor immediately at a given point.
PCB_LAYER_WIDGET * GetLayerManager()
static TOOL_ACTION routerActivateTuneDiffPair
Activation of the Push and Shove router (diff pair tuning mode)
Definition: pcb_actions.h:212
bool m_BlindBuriedViaAllowed
true to allow blind/buried vias
const SELECTION & selection() const
Definition: pcb_tool.cpp:245
ROUTING_SETTINGS m_savedSettings
Stores routing settings between router invocations.
Definition: pns_tool_base.h:66
int SettingsDialog(const TOOL_EVENT &aEvent)
void SetDiffPairIndex(unsigned aIndex)
Function SetDiffPairIndex.
int CustomTrackWidthDialog(const TOOL_EVENT &aEvent)
void SetCustomDiffPairGap(int aGap)
Function SetCustomDiffPairGap Sets custom gap for differential pairs (i.e.
void ImportCurrent(BOARD_DESIGN_SETTINGS &aSettings)
int Start() const
Definition: pns_layerset.h:83
static const TOOL_ACTION ACT_PlaceMicroVia("pcbnew.InteractiveRouter.PlaceMicroVia", AS_CONTEXT, TOOL_ACTION::LegacyHotKey(HK_ADD_MICROVIA), _("Place Microvia"), _("Adds a microvia at the end of currently routed track."), via_microvia_xpm, AF_NONE,(void *) VIA_ACTION_FLAGS::MICROVIA)
bool IsCancelInteractive(const TOOL_EVENT &aEvt)
Function IsCancelInteractive()
All active tools
Definition: tool_event.h:144
void Move(const VECTOR2I &aP, ITEM *aItem)
Definition: pns_router.cpp:228
TOOL_SETTINGS & GetSettings()
Definition: tool_base.cpp:77
int onTrackViaSizeChanged(const TOOL_EVENT &aEvent)
static TOOL_ACTION routerInlineDrag
Activation of the Push and Shove router (inline dragging mode)
Definition: pcb_actions.h:223
bool StartRouting(const VECTOR2I &aP, ITEM *aItem, int aLayer)
Definition: pns_router.cpp:173
bool Overlaps(const LAYER_RANGE &aOther) const
Definition: pns_layerset.h:68
virtual void SetAutoPan(bool aEnabled)
Function SetAutoPan Turns on/off auto panning (this feature is used when there is a tool active (eg...
KIGFX::VIEW_CONTROLS * getViewControls() const
Function getViewControls()
Definition: tool_base.cpp:41
static TOOL_ACTION inlineBreakTrack
Breaks track when router is not activated.
Definition: pcb_actions.h:139
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:35
static TOOL_ACTION breakTrack
Break a single track into two segments at the cursor.
Definition: pcb_actions.h:136
void StopRouting()
Definition: pns_router.cpp:392
int GetNetCode() const
Function GetNetCode.
virtual void highlightNet(bool aEnabled, int aNetcode=-1)
static const TOOL_ACTION ACT_CustomTrackWidth("pcbnew.InteractiveRouter.CustomTrackViaSize", AS_CONTEXT, TOOL_ACTION::LegacyHotKey(HK_CUSTOM_TRACK_WIDTH), _("Custom Track/Via Size..."), _("Shows a dialog for changing the track width and via size."), width_track_xpm)
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
virtual void SetNoToolSelected()
Select the ID_NO_TOOL_SELECTED id tool (Idle tool)
ROUTER_MODE
Definition: pns_router.h:64
PCB_EDIT_FRAME & m_frame
void SetViaType(VIATYPE_T aViaType)
static TOOL_ACTION layerChanged
Definition: pcb_actions.h:291
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:387
TOOL_EVENT MakeEvent() const
Function HasHotKey() Checks if the action has a hot key assigned.
Definition: tool_action.h:104
void UpdateSizes(const SIZES_SETTINGS &aSizes)
Applies stored settings.
Definition: pns_router.cpp:311
void SetMode(ROUTER_MODE aMode)
Definition: pns_router.cpp:510
void update() override
Update menu state stub.
unsigned GetDiffPairIndex() const
Function GetDiffPairIndex.
static TOOL_ACTION routerActivateSettingsDialog
Activation of the Push and Shove settings dialogs.
Definition: pcb_actions.h:218
static const TOOL_ACTION ACT_SelLayerAndPlaceThroughVia("pcbnew.InteractiveRouter.SelLayerAndPlaceVia", AS_CONTEXT, TOOL_ACTION::LegacyHotKey(HK_SEL_LAYER_AND_ADD_THROUGH_VIA), _("Select Layer and Place Through Via..."), _("Select a layer, then add a through-hole via at the end of currently routed track."), select_w_layer_xpm, AF_NONE,(void *)(VIA_ACTION_FLAGS::VIA|VIA_ACTION_FLAGS::SELECT_LAYER))
VECTOR2I m_endSnapPoint
Definition: pns_tool_base.h:74
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:245
Class TOOL_BASE.
Definition: tool_base.h:68
Class TOOL_ACTION.
Definition: tool_action.h:46
size_t i
Definition: json11.cpp:597
bool StartDragging(const VECTOR2I &aP, ITEM *aItem, int aDragMode=DM_ANY)
Definition: pns_router.cpp:127
#define ENDPOINT
Definition: base_struct.h:120
static void NeighboringSegmentFilter(const VECTOR2I &aPt, GENERAL_COLLECTOR &aCollector)
void performDragging(int aMode=PNS::DM_ANY)
Class PCB_EDIT_FRAME is the main frame for Pcbnew.
int Net() const
Function Net()
Definition: pns_item.h:179
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
int InlineBreakTrack(const TOOL_EVENT &aEvent)
ITEM * FindItemByParent(const BOARD_CONNECTED_ITEM *aParent)
Definition: pns_node.cpp:1329
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:80
std::vector< VIA_DIMENSION > m_ViasDimensionsList
boost::optional< T > OPT
Definition: optional.h:7
unsigned GetTrackWidthIndex() const
Function GetTrackWidthIndex.
int ShowModal() override
Definition: confirm.cpp:102
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
void Activate()
Function Activate() Runs the tool.
Implementing DIALOG_TRACK_VIA_SIZE_BASE.
int GetCurrentLayer() const
Definition: pns_router.cpp:461
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
void AddLayerPair(int aL1, int aL2)
int Size() const
Returns the number of selected parts.
Definition: selection.h:122
static const TOOL_ACTION ACT_EndTrack("pcbnew.InteractiveRouter.EndTrack", AS_CONTEXT, WXK_END, _("End Track"), _("Stops laying the current track."), checked_ok_xpm)
void DumpLog()
Definition: pns_router.cpp:469
static const TOOL_ACTION ACT_SelLayerAndPlaceBlindVia("pcbnew.InteractiveRouter.SelLayerAndPlaceBlindVia", AS_CONTEXT, TOOL_ACTION::LegacyHotKey(HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA), _("Select Layer and Place Blind/Buried Via..."), _("Select a layer, then add a blind or buried via at the end of currently routed track."), select_w_layer_xpm, AF_NONE,(void *)(VIA_ACTION_FLAGS::BLIND_VIA|VIA_ACTION_FLAGS::SELECT_LAYER))
static VIATYPE_T getViaTypeFromFlags(int aFlags)
void Save(TOOL_SETTINGS &where) const
bool m_MicroViasAllowed
true to allow micro vias
void SetLayerVisible(LAYER_NUM aLayer, bool isVisible)
Function SetLayerVisible sets aLayer visible or not.
static const TOOL_ACTION ACT_AutoEndRoute("pcbnew.InteractiveRouter.AutoEndRoute", AS_CONTEXT, 'F', _("Auto-end Track"), _("Automagically finishes currently routed track."))
void FlipPosture()
Definition: pns_router.cpp:420
DIFF_PAIR_MENU m_diffPairMenu
int DiffPairWidth() const
void SetViaDiameter(int aDiameter)
int getStartLayer(const PNS::ITEM *aItem)
TRACK_WIDTH_MENU m_trackViaMenu
static TOOL_ACTION routerActivateDiffPair
Activation of the Push and Shove router (differential pair mode)
Definition: pcb_actions.h:206
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:245
OPT< int > PairedLayer(int aLayerId)
PCB_LAYER_ID SelectLayer(PCB_LAYER_ID aDefaultLayer, LSET aNotAllowedLayersMask=LSET(), wxPoint aDlgPosition=wxDefaultPosition)
Install the dialog box for layer selection.
Definition: sel_layer.cpp:205
virtual void SetActiveLayer(PCB_LAYER_ID aLayer) override
Function SetActiveLayer will change the currently active layer to aLayer and also update the PCB_LAYE...
ROUTING_SETTINGS & Settings()
Definition: pns_router.h:187
virtual PCB_LAYER_ID GetActiveLayer() const
Function GetActiveLayer returns the active layer.
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:813
VIA_ACTION_FLAGS
Flags used by via tool actions.
Definition: router_tool.cpp:68
EDA_UNITS_T
Definition: common.h:160
static TOOL_ACTION selectionCursor
Select a single item under the cursor position.
Definition: pcb_actions.h:50
BOARD_CONNECTED_ITEM * Parent() const
Function Parent()
Definition: pns_item.h:159
Class LAYER_RANGE.
Definition: pns_layerset.h:32
PCB_LAYER_ID m_Route_Layer_TOP
Definition: pcb_screen.h:45
void UseCustomTrackViaSize(bool aEnabled)
Function UseCustomTrackViaSize Enables/disables custom track/via size settings.
OPT< TOOL_EVENT > OPT_TOOL_EVENT
Definition: tool_event.h:495
Class BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.
#define STARTPOINT
Definition: base_struct.h:119
static TOOL_ACTION layerToggle
Definition: pcb_actions.h:289
BOARD * board() const
Definition: pcb_tool.h:140
static TOOL_ACTION routerActivateDpDimensionsDialog
Definition: pcb_actions.h:219