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-2020 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 #include <functional>
24 using namespace std::placeholders;
25 #include <class_board.h>
26 #include <class_board_item.h>
27 #include <class_module.h>
28 #include <class_edge_mod.h>
29 #include <class_pad.h>
30 #include <pcb_edit_frame.h>
31 #include <pcbnew_id.h>
32 #include <pcb_layer_widget.h>
36 #include <confirm.h>
37 #include <bitmaps.h>
38 #include <tool/action_menu.h>
39 #include <tool/tool_manager.h>
40 #include <tool/grid_menu.h>
41 #include <tool/zoom_menu.h>
42 #include <tools/pcb_actions.h>
43 #include <tools/selection_tool.h>
44 #include <tools/grid_helper.h>
45 
46 #include "router_tool.h"
47 #include "pns_segment.h"
48 #include "pns_router.h"
49 #include "pns_itemset.h"
50 #include "pns_logger.h"
51 
52 #include "pns_kicad_iface.h"
53 
54 #ifdef DEBUG
55 #include <kicad_plugin.h>
56 #endif
57 
58 using namespace KIGFX;
59 
64 {
65  // Via type
66  VIA_MASK = 0x03,
67  VIA = 0x00,
68  BLIND_VIA = 0x01,
69  MICROVIA = 0x02,
70 
71  // Select layer
73 };
74 
75 
76 // Actions, being statically-defined, require specialized I18N handling. We continue to
77 // use the _() macro so that string harvesting by the I18N framework doesn't have to be
78 // specialized, but we don't translate on initialization and instead do it in the getters.
79 
80 #undef _
81 #define _(s) s
82 
83 static const TOOL_ACTION ACT_UndoLastSegment( "pcbnew.InteractiveRouter.UndoLastSegment",
84  AS_CONTEXT,
85  WXK_BACK, "",
86  _( "Undo last segment" ), _( "Stops laying the current track." ),
88 
89 static const TOOL_ACTION ACT_EndTrack( "pcbnew.InteractiveRouter.EndTrack",
90  AS_CONTEXT,
91  WXK_END, "",
92  _( "Finish Track" ), _( "Stops laying the current track." ),
94 
95 static const TOOL_ACTION ACT_AutoEndRoute( "pcbnew.InteractiveRouter.AutoEndRoute",
96  AS_CONTEXT,
97  'F', "",
98  _( "Auto-finish Track" ), _( "Automagically finishes laying the current track." ) );
99 
100 static const TOOL_ACTION ACT_PlaceThroughVia( "pcbnew.InteractiveRouter.PlaceVia",
101  AS_CONTEXT,
102  'V', LEGACY_HK_NAME( "Add Through Via" ),
103  _( "Place Through Via" ),
104  _( "Adds a through-hole via at the end of currently routed track." ),
106 
107 static const TOOL_ACTION ACT_PlaceBlindVia( "pcbnew.InteractiveRouter.PlaceBlindVia",
108  AS_CONTEXT,
109  MD_ALT + MD_SHIFT + 'V', LEGACY_HK_NAME( "Add Blind/Buried Via" ),
110  _( "Place Blind/Buried Via" ),
111  _( "Adds a blind or buried via at the end of currently routed track."),
113 
114 static const TOOL_ACTION ACT_PlaceMicroVia( "pcbnew.InteractiveRouter.PlaceMicroVia",
115  AS_CONTEXT,
116  MD_CTRL + 'V', LEGACY_HK_NAME( "Add MicroVia" ),
117  _( "Place Microvia" ), _( "Adds a microvia at the end of currently routed track." ),
119 
120 static const TOOL_ACTION ACT_SelLayerAndPlaceThroughVia( "pcbnew.InteractiveRouter.SelLayerAndPlaceVia",
121  AS_CONTEXT,
122  '<', LEGACY_HK_NAME( "Select Layer and Add Through Via" ),
123  _( "Select Layer and Place Through Via..." ),
124  _( "Select a layer, then add a through-hole via at the end of currently routed track." ),
127 
128 static const TOOL_ACTION ACT_SelLayerAndPlaceBlindVia( "pcbnew.InteractiveRouter.SelLayerAndPlaceBlindVia",
129  AS_CONTEXT,
130  MD_ALT + '<', LEGACY_HK_NAME( "Select Layer and Add Blind/Buried Via" ),
131  _( "Select Layer and Place Blind/Buried Via..." ),
132  _( "Select a layer, then add a blind or buried via at the end of currently routed track."),
135 
136 static const TOOL_ACTION ACT_CustomTrackWidth( "pcbnew.InteractiveRouter.CustomTrackViaSize",
137  AS_CONTEXT,
138  'Q', LEGACY_HK_NAME( "Custom Track/Via Size" ),
139  _( "Custom Track/Via Size..." ),
140  _( "Shows a dialog for changing the track width and via size." ),
141  width_track_xpm );
142 
143 static const TOOL_ACTION ACT_SwitchPosture( "pcbnew.InteractiveRouter.SwitchPosture",
144  AS_CONTEXT,
145  '/', LEGACY_HK_NAME( "Switch Track Posture" ),
146  _( "Switch Track Posture" ),
147  _( "Switches posture of the currently routed track." ),
149 
150 static const TOOL_ACTION ACT_SwitchRounding( "pcbnew.InteractiveRouter.SwitchRounding",
151  AS_CONTEXT,
152  0, LEGACY_HK_NAME( "Switch Corner Rounding" ),
153  _( "Switch Corner Rounding" ),
154  _( "Switches the corner type of the currently routed track." ),
156 
157 #undef _
158 #define _(s) wxGetTranslation((s))
159 
160 
162  TOOL_BASE( "pcbnew.InteractiveRouter" )
163 {
164 }
165 
166 
168 {
169 public:
171  ACTION_MENU( true ),
172  m_frame( aFrame )
173  {
175  SetTitle( _( "Select Track/Via Width" ) );
176  }
177 
178 protected:
179  ACTION_MENU* create() const override
180  {
181  return new TRACK_WIDTH_MENU( m_frame );
182  }
183 
184  void update() override
185  {
186  EDA_UNITS units = m_frame.GetUserUnits();
188  bool useIndex = !bds.m_UseConnectedTrackWidth &&
189  !bds.UseCustomTrackViaSize();
190  wxString msg;
191 
192  Clear();
193 
194  Append( ID_POPUP_PCB_SELECT_AUTO_WIDTH, _( "Use Starting Track Width" ),
195  _( "Route using the width of the starting track." ), wxITEM_CHECK );
198 
199  Append( ID_POPUP_PCB_SELECT_USE_NETCLASS_VALUES, _( "Use Net Class Values" ),
200  _( "Use track and via sizes from the net class" ), wxITEM_CHECK );
202  useIndex && bds.GetTrackWidthIndex() == 0 && bds.GetViaSizeIndex() == 0 );
203 
204  Append( ID_POPUP_PCB_SELECT_CUSTOM_WIDTH, _( "Use Custom Values..." ),
205  _( "Specify custom track and via sizes" ), wxITEM_CHECK );
207 
208  AppendSeparator();
209 
210  // Append the list of tracks & via sizes
211  for( unsigned i = 0; i < bds.m_TrackWidthList.size(); i++ )
212  {
213  int width = bds.m_TrackWidthList[i];
214 
215  if( i == 0 )
216  msg = _( "Track netclass width" );
217  else
218  msg.Printf( _( "Track %s" ), MessageTextFromValue( units, width, true ) );
219 
220  int menuIdx = ID_POPUP_PCB_SELECT_WIDTH1 + i;
221  Append( menuIdx, msg, wxEmptyString, wxITEM_CHECK );
222  Check( menuIdx, useIndex && bds.GetTrackWidthIndex() == i );
223  }
224 
225  AppendSeparator();
226 
227  for( unsigned i = 0; i < bds.m_ViasDimensionsList.size(); i++ )
228  {
229  VIA_DIMENSION via = bds.m_ViasDimensionsList[i];
230 
231  if( i == 0 )
232  msg = _( "Via netclass values" );
233  else
234  {
235  if( via.m_Drill > 0 )
236  msg.Printf( _("Via %s, drill %s" ),
237  MessageTextFromValue( units, via.m_Diameter, true ),
238  MessageTextFromValue( units, via.m_Drill, true ) );
239  else
240  msg.Printf( _( "Via %s" ), MessageTextFromValue( units, via.m_Diameter, true ) );
241  }
242 
243  int menuIdx = ID_POPUP_PCB_SELECT_VIASIZE1 + i;
244  Append( menuIdx, msg, wxEmptyString, wxITEM_CHECK );
245  Check( menuIdx, useIndex && bds.GetViaSizeIndex() == i );
246  }
247  }
248 
249  OPT_TOOL_EVENT eventHandler( const wxMenuEvent& aEvent ) override
250  {
252  int id = aEvent.GetId();
253 
254  // On Windows, this handler can be called with an event ID not existing in any
255  // menuitem, so only set flags when we have an ID match.
256 
258  {
259  bds.UseCustomTrackViaSize( true );
260  bds.m_UseConnectedTrackWidth = false;
262  }
263  else if( id == ID_POPUP_PCB_SELECT_AUTO_WIDTH )
264  {
265  bds.UseCustomTrackViaSize( false );
266  bds.m_UseConnectedTrackWidth = true;
267  }
269  {
270  bds.UseCustomTrackViaSize( false );
271  bds.m_UseConnectedTrackWidth = false;
272  bds.SetViaSizeIndex( 0 );
273  bds.SetTrackWidthIndex( 0 );
274  }
276  {
277  bds.UseCustomTrackViaSize( false );
278  bds.m_UseConnectedTrackWidth = false;
280  }
282  {
283  bds.UseCustomTrackViaSize( false );
284  bds.m_UseConnectedTrackWidth = false;
286  }
287 
288  return OPT_TOOL_EVENT( PCB_ACTIONS::trackViaSizeChanged.MakeEvent() );
289  }
290 
291 private:
293 };
294 
295 
297 {
298 public:
300  ACTION_MENU( true ),
301  m_frame( aFrame )
302  {
304  SetTitle( _( "Select Differential Pair Dimensions" ) );
305  }
306 
307 protected:
308  ACTION_MENU* create() const override
309  {
310  return new DIFF_PAIR_MENU( m_frame );
311  }
312 
313  void update() override
314  {
315  EDA_UNITS units = m_frame.GetUserUnits();
317 
318  Clear();
319 
320  Append( ID_POPUP_PCB_SELECT_USE_NETCLASS_DIFFPAIR, _( "Use Net Class Values" ),
321  _( "Use differential pair dimensions from the net class" ), wxITEM_CHECK );
323  !bds.UseCustomDiffPairDimensions() && bds.GetDiffPairIndex() == 0 );
324 
325  Append( ID_POPUP_PCB_SELECT_CUSTOM_DIFFPAIR, _( "Use Custom Values..." ),
326  _( "Specify custom differential pair dimensions" ), wxITEM_CHECK );
328 
329  AppendSeparator();
330 
331  // Append the list of differential pair dimensions
332 
333  // Drop index 0 which is the current netclass dimensions (which are handled above)
334  for( unsigned i = 1; i < bds.m_DiffPairDimensionsList.size(); ++i )
335  {
337  wxString msg;
338 
339  msg << _( "Width " ) << MessageTextFromValue( units, diffPair.m_Width, true );
340 
341  if( diffPair.m_Gap > 0 )
342  msg << _( ", gap " ) << MessageTextFromValue( units, diffPair.m_Gap, true );
343 
344  if( diffPair.m_ViaGap > 0 )
345  msg << _( ", via gap " ) << MessageTextFromValue( units, diffPair.m_ViaGap, true );
346 
347  int menuIdx = ID_POPUP_PCB_SELECT_DIFFPAIR1 + i - 1;
348  Append( menuIdx, msg, wxEmptyString, wxITEM_CHECK );
349  Check( menuIdx, !bds.UseCustomDiffPairDimensions() && bds.GetDiffPairIndex() == i );
350  }
351  }
352 
353  OPT_TOOL_EVENT eventHandler( const wxMenuEvent& aEvent ) override
354  {
356  int id = aEvent.GetId();
357 
358  // On Windows, this handler can be called with an event ID not existing in any
359  // menuitem, so only set flags when we have an ID match.
360 
362  {
363  bds.UseCustomDiffPairDimensions( true );
364  TOOL_MANAGER* toolManager = m_frame.GetToolManager();
365  toolManager->RunAction( PCB_ACTIONS::routerDiffPairDialog, true );
366  }
368  {
369  bds.UseCustomDiffPairDimensions( false );
370  bds.SetDiffPairIndex( 0 );
371  }
373  {
374  bds.UseCustomDiffPairDimensions( false );
375  // remember that the menu doesn't contain index 0 (which is the netclass values)
377  }
378 
379  return OPT_TOOL_EVENT( PCB_ACTIONS::trackViaSizeChanged.MakeEvent() );
380  }
381 
382 private:
384 };
385 
386 
388 {
389 public:
391  ACTION_MENU( true ),
392  m_frame( aFrame ), m_mode( aMode ), m_trackViaMenu( aFrame ), m_diffPairMenu( aFrame ),
393  m_zoomMenu( &aFrame ), m_gridMenu( &aFrame )
394  {
395  SetTitle( _( "Interactive Router" ) );
396 
398 
399  AppendSeparator();
400 
403  Add( ACT_EndTrack );
406 
409 
410 // Add( ACT_AutoEndRoute ); // fixme: not implemented yet. Sorry.
418 
419  AppendSeparator();
420 
421  Add( &m_trackViaMenu );
422 
424  Add( &m_diffPairMenu );
425 
427 
428  AppendSeparator();
429 
430  Add( &m_zoomMenu );
431  Add( &m_gridMenu );
432  }
433 
434 private:
435  ACTION_MENU* create() const override
436  {
437  return new ROUTER_TOOL_MENU( m_frame, m_mode );
438  }
439 
446 };
447 
448 
450 {
451 }
452 
453 
455 {
456  return true;
457 }
458 
459 
461 {
462  if( aReason == RUN )
463  TOOL_BASE::Reset( aReason );
464 }
465 
466 
468 {
469 #ifdef DEBUG
470  if( aEvent.IsKeyPressed() )
471  {
472  switch( aEvent.KeyCode() )
473  {
474  case '0':
475  {
476  auto logger = m_router->Logger();
477  if( ! logger )
478  return;
479 
480  FILE *f = fopen("/tmp/pns.log", "wb");
481  wxLogTrace( "PNS", "saving drag/route log...\n" );
482 
483  const auto& events = logger->GetEvents();
484 
485  for( auto evt : events)
486  {
487  wxString id = "null";
488  if( evt.item && evt.item->Parent() )
489  id = evt.item->Parent()->m_Uuid.AsString();
490 
491  fprintf(f, "event %d %d %d %s\n", evt.p.x, evt.p.y, evt.type, (const char*) id.c_str() );
492  }
493 
494  fclose(f);
495 
496  // Export as *.kicad_pcb format, using a strategy which is specifically chosen
497  // as an example on how it could also be used to send it to the system clipboard.
498 
499  PCB_IO pcb_io;
500 
501  pcb_io.Save("/tmp/pns.dump", m_iface->GetBoard(), nullptr );
502 
503  break;
504  }
505  }
506  }
507 #endif
508 }
509 
510 
512 {
513  int tl = getView()->GetTopLayer();
514 
515  if( m_startItem )
516  {
517  const LAYER_RANGE& ls = m_startItem->Layers();
518 
519  if( ls.Overlaps( tl ) )
520  return tl;
521  else
522  return ls.Start();
523  }
524 
525  return tl;
526 }
527 
528 
530 {
531  int al = frame()->GetActiveLayer();
532  int cl = m_router->GetCurrentLayer();
533 
534  if( cl != al )
535  {
536  m_router->SwitchLayer( al );
537  }
538 
539  OPT<int> newLayer = m_router->Sizes().PairedLayer( cl );
540 
541  if( !newLayer )
542  newLayer = m_router->Sizes().GetLayerTop();
543 
544  m_router->SwitchLayer( *newLayer );
545  frame()->SetActiveLayer( ToLAYER_ID( *newLayer ) );
546 }
547 
548 
549 static VIATYPE getViaTypeFromFlags( int aFlags )
550 {
551  switch( aFlags & VIA_ACTION_FLAGS::VIA_MASK )
552  {
554  return VIATYPE::THROUGH;
556  return VIATYPE::BLIND_BURIED;
558  return VIATYPE::MICROVIA;
559  default:
560  wxASSERT_MSG( false, "Unhandled via type" );
561  return VIATYPE::THROUGH;
562  }
563 }
564 
565 
567 {
568  if( aEvent.IsAction( &PCB_ACTIONS::layerTop ) )
569  return F_Cu;
570  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner1 ) )
571  return In1_Cu;
572  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner2 ) )
573  return In2_Cu;
574  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner3 ) )
575  return In3_Cu;
576  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner4 ) )
577  return In4_Cu;
578  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner5 ) )
579  return In5_Cu;
580  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner6 ) )
581  return In6_Cu;
582  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner7 ) )
583  return In7_Cu;
584  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner8 ) )
585  return In8_Cu;
586  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner9 ) )
587  return In9_Cu;
588  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner10 ) )
589  return In10_Cu;
590  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner11 ) )
591  return In11_Cu;
592  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner12 ) )
593  return In12_Cu;
594  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner13 ) )
595  return In13_Cu;
596  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner14 ) )
597  return In14_Cu;
598  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner15 ) )
599  return In15_Cu;
600  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner16 ) )
601  return In16_Cu;
602  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner17 ) )
603  return In17_Cu;
604  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner18 ) )
605  return In18_Cu;
606  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner19 ) )
607  return In19_Cu;
608  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner20 ) )
609  return In20_Cu;
610  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner21 ) )
611  return In21_Cu;
612  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner22 ) )
613  return In22_Cu;
614  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner23 ) )
615  return In23_Cu;
616  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner24 ) )
617  return In24_Cu;
618  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner25 ) )
619  return In25_Cu;
620  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner26 ) )
621  return In26_Cu;
622  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner27 ) )
623  return In27_Cu;
624  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner28 ) )
625  return In28_Cu;
626  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner29 ) )
627  return In29_Cu;
628  else if( aEvent.IsAction( &PCB_ACTIONS::layerInner30 ) )
629  return In30_Cu;
630  else if( aEvent.IsAction( &PCB_ACTIONS::layerBottom ) )
631  return B_Cu;
632  else
633  return UNDEFINED_LAYER;
634 }
635 
636 
638 {
639  if( !IsToolActive() )
640  return 0;
641 
642  // First see if this is one of the switch layer commands
643  LSEQ layers = LSET( board()->GetEnabledLayers() & LSET::AllCuMask() ).Seq();
644  int currentLayer = m_router->GetCurrentLayer();
645 
646  PCB_LAYER_ID targetLayer = UNDEFINED_LAYER;
647 
648  if( aEvent.IsAction( &PCB_ACTIONS::layerNext ) )
649  {
650  size_t idx = 0;
651 
652  for( size_t i = 0; i < layers.size(); i++ )
653  {
654  if( layers[i] == currentLayer )
655  {
656  idx = i;
657  break;
658  }
659  }
660 
661  idx = ( idx + 1 ) % layers.size();
662  targetLayer = layers[idx];
663  }
664  else if( aEvent.IsAction( &PCB_ACTIONS::layerPrev ) )
665  {
666  size_t idx = 0;
667 
668  for( size_t i = 0; i < layers.size(); i++ )
669  {
670  if( layers[i] == currentLayer )
671  {
672  idx = i;
673  break;
674  }
675  }
676 
677  idx = ( idx > 0 ) ? ( idx - 1 ) : ( layers.size() - 1 );
678  targetLayer = layers[idx];
679  }
680  else
681  {
682  targetLayer = getTargetLayerFromEvent( aEvent );
683 
684  if( targetLayer != UNDEFINED_LAYER )
685  {
686  if( targetLayer == currentLayer )
687  return 0;
688  }
689  }
690 
692  const int layerCount = bds.GetCopperLayerCount();
693 
696 
698 
699  VIATYPE viaType = VIATYPE::THROUGH;
700  bool selectLayer = false;
701 
702  // Otherwise it is one of the router-specific via commands
703  if( targetLayer == UNDEFINED_LAYER )
704  {
705  const int actViaFlags = aEvent.Parameter<intptr_t>();
706  selectLayer = actViaFlags & VIA_ACTION_FLAGS::SELECT_LAYER;
707 
708  viaType = getViaTypeFromFlags( actViaFlags );
709 
710  // ask the user for a target layer
711  if( selectLayer )
712  {
713  wxPoint dlgPosition = wxGetMousePosition();
714 
715  targetLayer = frame()->SelectLayer(
716  static_cast<PCB_LAYER_ID>( currentLayer ), LSET::AllNonCuMask(), dlgPosition );
717 
718  // Reset the cursor to the position where the event occured
719  controls()->SetCursorPosition( aEvent.HasPosition() ? aEvent.Position() : dlgPosition );
720  }
721  }
722 
723  // fixme: P&S supports more than one fixed layer pair. Update the dialog?
724  sizes.ClearLayerPairs();
725 
726  if( !m_router->IsPlacingVia() )
727  {
728  // Cannot place microvias or blind vias if not allowed (obvious)
729  if( ( viaType == VIATYPE::BLIND_BURIED ) && ( !bds.m_BlindBuriedViaAllowed ) )
730  {
731  frame()->ShowInfoBarError( _( "Blind/buried vias have to be enabled in "
732  "Board Setup > Design Rules > Constraints." ) );
733  return false;
734  }
735 
736  if( ( viaType == VIATYPE::MICROVIA ) && ( !bds.m_MicroViasAllowed ) )
737  {
738  frame()->ShowInfoBarError( _( "Microvias have to be enabled in "
739  "Board Setup > Design Rules > Constraints." ) );
740  return false;
741  }
742 
743  // Can only place through vias on 2-layer boards
744  if( ( viaType != VIATYPE::THROUGH ) && ( layerCount <= 2 ) )
745  {
746  frame()->ShowInfoBarError( _( "Only through vias are allowed on 2 layer boards." ) );
747  return false;
748  }
749 
750  // Can only place microvias if we're on an outer layer, or directly adjacent to one
751  if( ( viaType == VIATYPE::MICROVIA ) && ( currentLayer > In1_Cu )
752  && ( currentLayer < layerCount - 2 ) )
753  {
754  frame()->ShowInfoBarError( _( "Microvias can only be placed between the outer layers "
755  "(F.Cu/B.Cu) and the ones directly adjacent to them." ) );
756  return false;
757  }
758  }
759 
760  // Convert blind/buried via to a through hole one, if it goes through all layers
761  if( viaType == VIATYPE::BLIND_BURIED
762  && ( ( targetLayer == B_Cu && currentLayer == F_Cu )
763  || ( targetLayer == F_Cu && currentLayer == B_Cu ) ) )
764  {
765  viaType = VIATYPE::THROUGH;
766  }
767 
768  switch( viaType )
769  {
770  case VIATYPE::THROUGH:
771  sizes.SetViaDiameter( bds.GetCurrentViaSize() );
772  sizes.SetViaDrill( bds.GetCurrentViaDrill() );
773 
774  if( targetLayer != UNDEFINED_LAYER )
775  {
776  // go from the current layer to the chosen layer
777  sizes.AddLayerPair( currentLayer, targetLayer );
778  }
779  else
780  {
781  // use the default layer pair
782  sizes.AddLayerPair( pairTop, pairBottom );
783  }
784  break;
785 
786  case VIATYPE::MICROVIA:
787  sizes.SetViaDiameter( bds.GetCurrentMicroViaSize() );
788  sizes.SetViaDrill( bds.GetCurrentMicroViaDrill() );
789 
790  wxASSERT_MSG( !selectLayer,
791  "Unexpected select layer for microvia (microvia layers are implicit)" );
792 
793  if( currentLayer == F_Cu || currentLayer == In1_Cu )
794  {
795  // front-side microvia
796  sizes.AddLayerPair( F_Cu, In1_Cu );
797  }
798  else if( currentLayer == B_Cu || currentLayer == layerCount - 2 )
799  {
800  // back-side microvia
801  sizes.AddLayerPair( B_Cu, layerCount - 2 );
802  }
803  else
804  {
805  wxASSERT_MSG( false,
806  "Invalid layer pair for microvia (must be on or adjacent to an outer layer)" );
807  }
808  break;
809 
811  sizes.SetViaDiameter( bds.GetCurrentViaSize() );
812  sizes.SetViaDrill( bds.GetCurrentViaDrill() );
813 
814  if( targetLayer != UNDEFINED_LAYER )
815  {
816  // go directly to the user specified layer
817  sizes.AddLayerPair( currentLayer, targetLayer );
818  }
819  else
820  {
821  if( currentLayer == pairTop || currentLayer == pairBottom )
822  {
823  // the current layer is on the defined layer pair,
824  // swap to the other side
825  sizes.AddLayerPair( pairTop, pairBottom );
826  }
827  else
828  {
829  // the current layer is not part of the current layer pair,
830  // so fallback and swap to the top layer of the pair by default
831  sizes.AddLayerPair( pairTop, currentLayer );
832  }
833  }
834  break;
835 
836  default:
837  wxASSERT( false );
838  break;
839  }
840 
841  sizes.SetViaType( viaType );
842 
843  m_router->UpdateSizes( sizes );
845 
846  if( m_router->RoutingInProgress() )
847  updateEndItem( aEvent );
848  else
849  updateStartItem( aEvent );
850 
851  m_router->Move( m_endSnapPoint, m_endItem ); // refresh
852 
853  return 0;
854 }
855 
856 
858 {
859  int routingLayer = getStartLayer( m_startItem );
860 
861  if( !IsCopperLayer( routingLayer ) )
862  {
863  frame()->ShowInfoBarError( _( "Tracks on Copper layers only" ) );
864  return false;
865  }
866 
867  PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
868 
869  editFrame->SetActiveLayer( ToLAYER_ID( routingLayer ) );
870 
871  // for some reason I don't understand, GetNetclass() may return null sometimes...
872  if( m_startItem && m_startItem->Net() >= 0 &&
874  {
875  highlightNet( true, m_startItem->Net() );
876  // Update track width and via size shown in main toolbar comboboxes
878  }
879  else
881 
882  controls()->ForceCursorPosition( false );
883  controls()->SetAutoPan( true );
884 
885  PNS::SIZES_SETTINGS sizes( m_router->Sizes() );
886 
887  sizes.Init( board(), m_startItem );
888  sizes.AddLayerPair( frame()->GetScreen()->m_Route_Layer_TOP,
889  frame()->GetScreen()->m_Route_Layer_BOTTOM );
890  m_router->UpdateSizes( sizes );
891 
892  if( !m_router->StartRouting( m_startSnapPoint, m_startItem, routingLayer ) )
893  {
895  highlightNet( false );
896  controls()->SetAutoPan( false );
897  return false;
898  }
899 
900  m_endItem = nullptr;
902 
903  frame()->UndoRedoBlock( true );
904 
905  return true;
906 }
907 
908 
910 {
912 
913  controls()->SetAutoPan( false );
914  controls()->ForceCursorPosition( false );
915  frame()->UndoRedoBlock( false );
916  highlightNet( false );
917 
918  return true;
919 }
920 
921 
923 {
924  if( !prepareInteractive() )
925  return;
926 
927  while( TOOL_EVENT* evt = Wait() )
928  {
929  frame()->GetCanvas()->SetCurrentCursor( wxCURSOR_PENCIL );
930 
931  // Don't crash if we missed an operation that cancelled routing.
932  if( !m_router->RoutingInProgress() )
933  {
934  if( evt->IsCancelInteractive() )
935  m_cancelled = true;
936 
937  break;
938  }
939 
940  handleCommonEvents( *evt );
941 
942  if( evt->IsMotion() )
943  {
944  m_router->SetOrthoMode( evt->Modifier( MD_CTRL ) );
945  updateEndItem( *evt );
947  }
948  else if( evt->IsAction( &ACT_UndoLastSegment ) )
949  {
951  updateEndItem( *evt );
953  }
954  else if( evt->IsClick( BUT_LEFT ) || evt->IsAction( &PCB_ACTIONS::routeSingleTrack ) )
955  {
956  updateEndItem( *evt );
957  bool needLayerSwitch = m_router->IsPlacingVia();
958  bool forceFinish = evt->Modifier( MD_SHIFT );
959 
960  if( m_router->FixRoute( m_endSnapPoint, m_endItem, forceFinish ) )
961  {
962  break;
963  }
964 
965  if( needLayerSwitch )
967 
968  // Synchronize the indicated layer
970  updateEndItem( *evt );
972  m_startItem = nullptr;
973  }
974  else if( evt->IsAction( &ACT_SwitchRounding ) )
975  {
977  updateEndItem( *evt );
978  m_router->Move( m_endSnapPoint, m_endItem ); // refresh
979  }
980  else if( evt->IsAction( &ACT_SwitchPosture ) )
981  {
983  updateEndItem( *evt );
984  m_router->Move( m_endSnapPoint, m_endItem ); // refresh
985  }
986  else if( evt->IsAction( &PCB_ACTIONS::layerChanged ) )
987  {
988  m_router->SwitchLayer( frame()->GetActiveLayer() );
989  updateEndItem( *evt );
990  m_router->Move( m_endSnapPoint, m_endItem ); // refresh
991  }
992  else if( evt->IsAction( &ACT_EndTrack ) || evt->IsDblClick( BUT_LEFT ) )
993  {
994  // Stop current routing:
996  break;
997  }
998  else if( evt->IsCancelInteractive() || evt->IsActivate()
999  || evt->IsUndoRedo()
1000  || evt->IsAction( &PCB_ACTIONS::routerInlineDrag ) )
1001  {
1002  if( evt->IsCancelInteractive() && !m_router->RoutingInProgress() )
1003  m_cancelled = true;
1004 
1005  if( evt->IsActivate() && !evt->IsMoveTool() )
1006  m_cancelled = true;
1007 
1008  break;
1009  }
1010  else
1011  {
1012  evt->SetPassEvent();
1013  }
1014  }
1015 
1017  m_router->StopRouting();
1018 
1020 }
1021 
1022 
1024 {
1025  PNS::SIZES_SETTINGS sizes = m_router->Sizes();
1026  DIALOG_PNS_DIFF_PAIR_DIMENSIONS settingsDlg( frame(), sizes );
1027 
1028  if( settingsDlg.ShowModal() == wxID_OK )
1029  {
1030  m_router->UpdateSizes( sizes );
1031  m_savedSizes = sizes;
1032 
1034  bds.SetCustomDiffPairWidth( sizes.DiffPairWidth() );
1035  bds.SetCustomDiffPairGap( sizes.DiffPairGap() );
1036  bds.SetCustomDiffPairViaGap( sizes.DiffPairViaGap() );
1037  }
1038 
1039  return 0;
1040 }
1041 
1042 
1044 {
1045  DIALOG_PNS_SETTINGS settingsDlg( frame(), m_router->Settings() );
1046 
1047  settingsDlg.ShowModal();
1048 
1049  return 0;
1050 }
1051 
1052 
1054 {
1055  PNS::PNS_MODE mode = aEvent.Parameter<PNS::PNS_MODE>();
1056  PNS::ROUTING_SETTINGS& settings = m_router->Settings();
1057 
1058  settings.SetMode( mode );
1059 
1060  return 0;
1061 }
1062 
1063 
1065 {
1066  return m_router->Settings().Mode();
1067 }
1068 
1069 
1071 {
1074 }
1075 
1076 
1077 int ROUTER_TOOL::MainLoop( const TOOL_EVENT& aEvent )
1078 {
1079  PNS::ROUTER_MODE mode = aEvent.Parameter<PNS::ROUTER_MODE>();
1080  PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
1081 
1082  // Deselect all items
1084 
1085  std::string tool = aEvent.GetCommandStr().get();
1086  frame->PushTool( tool );
1087  Activate();
1088 
1089  m_router->SetMode( mode );
1090 
1091  VIEW_CONTROLS* ctls = getViewControls();
1092  ctls->ShowCursor( true );
1093  ctls->ForceCursorPosition( false );
1094  m_cancelled = false;
1096 
1097  std::unique_ptr<ROUTER_TOOL_MENU> ctxMenu( new ROUTER_TOOL_MENU( *frame, mode ) );
1098  SetContextMenu( ctxMenu.get() );
1099 
1100  // Prime the pump
1101  if( aEvent.HasPosition() )
1103 
1104  // Main loop: keep receiving events
1105  while( TOOL_EVENT* evt = Wait() )
1106  {
1107  frame->GetCanvas()->SetCurrentCursor( wxCURSOR_PENCIL );
1108 
1109  if( evt->IsCancelInteractive() )
1110  {
1111  frame->PopTool( tool );
1112  break;
1113  }
1114  else if( evt->IsActivate() )
1115  {
1116  if( evt->IsMoveTool() )
1117  {
1118  // leave ourselves on the stack so we come back after the move
1119  break;
1120  }
1121  else
1122  {
1123  frame->PopTool( tool );
1124  break;
1125  }
1126  }
1127  else if( evt->Action() == TA_UNDO_REDO_PRE )
1128  {
1129  m_router->ClearWorld();
1130  }
1131  else if( evt->Action() == TA_UNDO_REDO_POST || evt->Action() == TA_MODEL_CHANGE )
1132  {
1133  m_router->SyncWorld();
1134  }
1135  else if( evt->IsMotion() )
1136  {
1137  updateStartItem( *evt );
1138  }
1139  else if( evt->IsAction( &PCB_ACTIONS::dragFreeAngle ) )
1140  {
1141  updateStartItem( *evt, true );
1143  }
1144  else if( evt->IsAction( &PCB_ACTIONS::drag45Degree ) )
1145  {
1146  updateStartItem( *evt, true );
1148  }
1149  else if( evt->IsAction( &PCB_ACTIONS::breakTrack ) )
1150  {
1151  updateStartItem( *evt, true );
1152  breakTrack( );
1153  }
1154  else if( evt->IsClick( BUT_LEFT )
1155  || evt->IsAction( &PCB_ACTIONS::routeSingleTrack )
1156  || evt->IsAction( &PCB_ACTIONS::routeDiffPair ) )
1157  {
1158  if( evt->IsAction( &PCB_ACTIONS::routeSingleTrack )
1159  || evt->IsAction( &PCB_ACTIONS::routeDiffPair ) )
1160  {
1161  mode = evt->Parameter<PNS::ROUTER_MODE>();
1162  }
1163 
1164  updateStartItem( *evt );
1165 
1166  if( evt->HasPosition() )
1167  {
1168  if( evt->Modifier( MD_CTRL ) )
1170  else
1171  performRouting();
1172  }
1173  }
1174  else if( evt->IsAction( &ACT_PlaceThroughVia ) )
1175  {
1177  }
1178  else if( evt->IsAction( &PCB_ACTIONS::layerChanged ) )
1179  {
1181  updateStartItem( *evt );
1182  }
1183  else if( evt->IsKeyPressed() )
1184  {
1185  // wxWidgets fails to correctly translate shifted keycodes on the wxEVT_CHAR_HOOK
1186  // event so we need to process the wxEVT_CHAR event that will follow as long as we
1187  // pass the event.
1188  evt->SetPassEvent();
1189  }
1190 
1191  if( m_cancelled )
1192  {
1193  frame->PopTool( tool );
1194  break;
1195  }
1196  }
1197 
1198  SetContextMenu( nullptr );
1199 
1200  // Store routing settings till the next invocation
1202 
1203  return 0;
1204 }
1205 
1206 
1208 {
1209  VIEW_CONTROLS* ctls = getViewControls();
1210 
1211  if( m_startItem && m_startItem->IsLocked() )
1212  {
1213  KIDIALOG dlg( frame(), _( "The selected item is locked." ), _( "Confirmation" ),
1214  wxOK | wxCANCEL | wxICON_WARNING );
1215  dlg.SetOKLabel( _( "Drag Anyway" ) );
1216  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
1217 
1218  if( dlg.ShowModal() == wxID_CANCEL )
1219  return;
1220  }
1221 
1222  bool dragStarted = m_router->StartDragging( m_startSnapPoint, m_startItem, aMode );
1223 
1224  if( !dragStarted )
1225  return;
1226 
1227  if( m_startItem && m_startItem->Net() >= 0 )
1228  highlightNet( true, m_startItem->Net() );
1229 
1230  ctls->SetAutoPan( true );
1232  frame()->UndoRedoBlock( true );
1233 
1234  while( TOOL_EVENT* evt = Wait() )
1235  {
1236  ctls->ForceCursorPosition( false );
1237 
1238  if( evt->IsMotion() )
1239  {
1240  updateEndItem( *evt );
1242  }
1243  else if( evt->IsClick( BUT_LEFT ) )
1244  {
1246  break;
1247  }
1248  else if( evt->IsCancelInteractive() || evt->IsActivate() || evt->IsUndoRedo() )
1249  {
1250  if( evt->IsCancelInteractive() && !m_startItem )
1251  m_cancelled = true;
1252 
1253  if( evt->IsActivate() && !evt->IsMoveTool() )
1254  m_cancelled = true;
1255 
1256  break;
1257  }
1258 
1259  handleCommonEvents( *evt );
1260  }
1261 
1262  if( m_router->RoutingInProgress() )
1263  m_router->StopRouting();
1264 
1265  m_startItem = nullptr;
1266 
1267  m_gridHelper->SetAuxAxes( false );
1268  frame()->UndoRedoBlock( false );
1269  ctls->SetAutoPan( false );
1270  ctls->ForceCursorPosition( false );
1271  highlightNet( false );
1272 }
1273 
1274 
1276 {
1277  /*
1278  * If the collection contains a trivial line corner (two connected segments)
1279  * or a non-fanout-via (a via with no more than two connected segments), then
1280  * trim the collection down to a single item (which one won't matter since
1281  * they're all connected).
1282  */
1283 
1284  // First make sure we've got something that *might* match.
1285  int vias = aCollector.CountType( PCB_VIA_T );
1286  int traces = aCollector.CountType( PCB_TRACE_T );
1287  int arcs = aCollector.CountType( PCB_ARC_T );
1288 
1289  if( arcs > 0 || vias > 1 || traces > 2 || vias + traces < 1 )
1290  return;
1291 
1292  // Fetch first TRACK (via or trace) as our reference
1293  TRACK* reference = nullptr;
1294 
1295  for( int i = 0; !reference && i < aCollector.GetCount(); i++ )
1296  reference = dynamic_cast<TRACK*>( aCollector[i] );
1297 
1298  int refNet = reference->GetNetCode();
1299 
1300  wxPoint refPoint( aPt.x, aPt.y );
1301  STATUS_FLAGS flags = reference->IsPointOnEnds( refPoint, -1 );
1302 
1303  if( flags & STARTPOINT )
1304  refPoint = reference->GetStart();
1305  else if( flags & ENDPOINT )
1306  refPoint = reference->GetEnd();
1307 
1308  // Check all items to ensure that any TRACKs are co-terminus with the reference and on
1309  // the same net.
1310  for( int i = 0; i < aCollector.GetCount(); i++ )
1311  {
1312  TRACK* neighbor = dynamic_cast<TRACK*>( aCollector[i] );
1313 
1314  if( neighbor && neighbor != reference )
1315  {
1316  if( neighbor->GetNetCode() != refNet )
1317  return;
1318 
1319  if( neighbor->GetStart() != refPoint && neighbor->GetEnd() != refPoint )
1320  return;
1321  }
1322  }
1323 
1324  // Selection meets criteria; trim it to the reference item.
1325  aCollector.Empty();
1326  aCollector.Append( reference );
1327 }
1328 
1329 
1331 {
1333  const auto& selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection();
1334 
1335  if( selection.Size() == 1 )
1336  {
1337  const BOARD_ITEM* item = static_cast<const BOARD_ITEM*>( selection.Front() );
1338 
1339  if( item->Type() == PCB_TRACE_T || item->Type() == PCB_VIA_T || item->Type() == PCB_MODULE_T )
1340  return true;
1341  }
1342 
1343  return false;
1344 }
1345 
1346 
1348 {
1349  const auto& selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection();
1350 
1351  if( selection.Empty() )
1353 
1354  if( selection.Size() != 1 )
1355  return 0;
1356 
1357  const BOARD_ITEM* item = static_cast<const BOARD_ITEM*>( selection.Front() );
1358 
1359  if( item->Type() != PCB_TRACE_T && item->Type() != PCB_VIA_T && item->Type() != PCB_MODULE_T )
1360  return 0;
1361 
1362  Activate();
1363 
1365  m_router->SyncWorld();
1366  m_startItem = nullptr;
1367 
1368  PNS::ITEM* startItem = nullptr;
1369  PNS::ITEM_SET itemsToDrag;
1370  const MODULE* module = nullptr;
1371 
1372  if( item->Type() == PCB_MODULE_T )
1373  {
1374  module = static_cast<const MODULE*>(item);
1375 
1376  for( const D_PAD* pad : module->Pads() )
1377  {
1378  PNS::ITEM* solid = m_router->GetWorld()->FindItemByParent( pad );
1379 
1380  if( solid )
1381  itemsToDrag.Add( solid );
1382  }
1383  }
1384  else
1385  {
1386  startItem = m_router->GetWorld()->FindItemByParent( static_cast<const BOARD_CONNECTED_ITEM*>( item ) );
1387 
1388  if( startItem)
1389  itemsToDrag.Add( startItem );
1390  }
1391 
1392  if( startItem && startItem->IsLocked() )
1393  {
1394  KIDIALOG dlg( frame(), _( "The selected item is locked." ), _( "Confirmation" ),
1395  wxOK | wxCANCEL | wxICON_WARNING );
1396  dlg.SetOKLabel( _( "Drag Anyway" ) );
1397  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
1398 
1399  if( dlg.ShowModal() == wxID_CANCEL )
1400  return 0;
1401  }
1402 
1403  VECTOR2I p0 = controls()->GetCursorPosition( false );
1404  VECTOR2I p = p0;
1405 
1406  if( startItem )
1407  p = snapToItem( true, startItem, p0 );
1408 
1409  int dragMode = aEvent.Parameter<int64_t> ();
1410 
1411  bool dragStarted = m_router->StartDragging( p, itemsToDrag, dragMode );
1412 
1413  if( !dragStarted )
1414  return 0;
1415 
1416  m_gridHelper->SetAuxAxes( true, p );
1417  controls()->ShowCursor( true );
1418  controls()->ForceCursorPosition( false );
1419  controls()->SetAutoPan( true );
1420  frame()->UndoRedoBlock( true );
1421 
1422  view()->ClearPreview();
1423  view()->InitPreview();
1424 
1425  while( TOOL_EVENT* evt = Wait() )
1426  {
1427  frame()->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
1428 
1429  if( evt->IsCancelInteractive() )
1430  {
1431  break;
1432  }
1433  else if( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) )
1434  {
1435  updateEndItem( *evt );
1437 
1438  if( module )
1439  {
1440  VECTOR2I offset = m_endSnapPoint - p;
1441  BOARD_ITEM* previewItem;
1442 
1443  view()->ClearPreview();
1444 
1445  for( BOARD_ITEM* drawing : module->GraphicalItems() )
1446  {
1447  previewItem = static_cast<BOARD_ITEM*>( drawing->Clone() );
1448 
1449  if( drawing->Type() == PCB_MODULE_EDGE_T )
1450  {
1451  EDGE_MODULE* edge = static_cast<EDGE_MODULE*>( previewItem );
1452  edge->DRAWSEGMENT::Move( (wxPoint) offset );
1453  }
1454  else
1455  {
1456  previewItem->Move( offset );
1457  }
1458 
1459  view()->AddToPreview( previewItem );
1460  view()->Hide( drawing, true );
1461  }
1462 
1463  previewItem = static_cast<BOARD_ITEM*>( module->Reference().Clone() );
1464  previewItem->Move( offset );
1465  view()->AddToPreview( previewItem );
1466  view()->Hide( &module->Reference() );
1467 
1468  previewItem = static_cast<BOARD_ITEM*>( module->Value().Clone() );
1469  previewItem->Move( offset );
1470  view()->AddToPreview( previewItem );
1471  view()->Hide( &module->Value() );
1472 
1473  for( ZONE_CONTAINER* zone : module->Zones() )
1474  {
1475  previewItem = static_cast<BOARD_ITEM*>( zone->Clone() );
1476  previewItem->Move( offset );
1477  view()->AddToPreview( previewItem );
1478  view()->Hide( zone, true );
1479  }
1480  }
1481  }
1482  else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
1483  {
1484  updateEndItem( *evt );
1486  break;
1487  }
1488  else if( evt->Category() == TC_COMMAND )
1489  {
1490  // disallow editing commands
1491  if( evt->IsAction( &ACTIONS::cut )
1492  || evt->IsAction( &ACTIONS::copy )
1493  || evt->IsAction( &ACTIONS::paste )
1494  || evt->IsAction( &ACTIONS::pasteSpecial ) )
1495  {
1496  wxBell();
1497  }
1498  }
1499  }
1500 
1501  if( module )
1502  {
1503  for( BOARD_ITEM* drawing : module->GraphicalItems() )
1504  view()->Hide( drawing, false );
1505 
1506  view()->Hide( &module->Reference(), false );
1507  view()->Hide( &module->Value(), false );
1508 
1509  for( ZONE_CONTAINER* zone : module->Zones() )
1510  view()->Hide( zone, false );
1511 
1512  view()->ClearPreview();
1513  view()->ShowPreview( false );
1514  }
1515 
1516  if( m_router->RoutingInProgress() )
1517  m_router->StopRouting();
1518 
1519  m_gridHelper->SetAuxAxes( false );
1520  controls()->SetAutoPan( false );
1521  controls()->ForceCursorPosition( false );
1522  frame()->UndoRedoBlock( false );
1523 
1524  return 0;
1525 }
1526 
1527 
1529 {
1530  const auto& selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection();
1531 
1532  if( selection.Size() != 1 )
1533  return 0;
1534 
1535  const BOARD_CONNECTED_ITEM* item = static_cast<const BOARD_CONNECTED_ITEM*>( selection.Front() );
1536 
1537  if( item->Type() != PCB_TRACE_T )
1538  return 0;
1539 
1540  Activate();
1541 
1543  m_router->SyncWorld();
1545  m_startSnapPoint = snapToItem( true, m_startItem, controls()->GetCursorPosition() );
1546 
1547 
1548  if( m_startItem && m_startItem->IsLocked() )
1549  {
1550  KIDIALOG dlg( frame(), _( "The selected item is locked." ), _( "Confirmation" ),
1551  wxOK | wxCANCEL | wxICON_WARNING );
1552  dlg.SetOKLabel( _( "Break Track" ) );
1553  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
1554 
1555  if( dlg.ShowModal() == wxID_CANCEL )
1556  return 0;
1557  }
1558 
1559  frame()->UndoRedoBlock( true );
1560  breakTrack();
1561 
1562  if( m_router->RoutingInProgress() )
1563  m_router->StopRouting();
1564 
1565  frame()->UndoRedoBlock( false );
1566 
1567  return 0;
1568 }
1569 
1570 
1572 {
1574  DIALOG_TRACK_VIA_SIZE sizeDlg( frame(), bds );
1575 
1576  if( sizeDlg.ShowModal() )
1577  {
1578  bds.UseCustomTrackViaSize( true );
1579 
1580  TOOL_EVENT dummy;
1582  }
1583 
1584  return 0;
1585 }
1586 
1587 
1589 {
1590  PNS::SIZES_SETTINGS sizes( m_router->Sizes() );
1591  sizes.ImportCurrent( board()->GetDesignSettings() );
1592  m_router->UpdateSizes( sizes );
1593 
1594  // Changing the track width can affect the placement, so call the
1595  // move routine without changing the destination
1597 
1598  return 0;
1599 }
1600 
1601 
1603 {
1605 
1615 
1621 
1656 
1659 }
void Empty()
Function Empty sets the list to empty.
Definition: collector.h:110
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:62
const wxString & FailureReason() const
Definition: pns_router.h:230
int GetCurrentMicroViaSize()
Function GetCurrentMicroViaSize.
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:719
virtual void ShowCursor(bool aEnabled)
Function ShowCursor() Enables or disables display of cursor.
EDA_UNITS
Definition: common.h:198
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:239
static TOOL_ACTION layerBottom
Definition: pcb_actions.h:270
void Hide(VIEW_ITEM *aItem, bool aHide=true)
Temporarily hides the item in the view (e.g.
Definition: view.cpp:1498
ITEM.
Definition: pns_item.h:53
static TOOL_ACTION layerInner26
Definition: pcb_actions.h:265
Struct VIA_DIMENSION is a small helper container to handle a stock of specific vias each with unique ...
BOARD * GetBoard() const
ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:61
wxMenuItem * Add(const wxString &aLabel, int aId, const BITMAP_OPAQUE *aIcon)
Adds a wxWidgets-style entry to the menu.
OPT_TOOL_EVENT eventHandler(const wxMenuEvent &aEvent) override
Event handler stub.
void SetMode(PNS_MODE aMode)
Sets the routing mode.
BOARD_CONNECTED_ITEM * Parent() const
Definition: pns_item.h:146
TEXTE_MODULE & Reference()
Definition: class_module.h:492
void DoNotShowCheckbox(wxString file, int line)
Shows the 'do not show again' checkbox
Definition: confirm.cpp:53
void SetTrackWidthIndex(unsigned aIndex)
Function SetTrackWidthIndex sets the current track width list index to aIndex.
int GetNetCode() const
Function GetNetCode.
static TOOL_ACTION layerNext
Definition: pcb_actions.h:271
PNS::PNS_MODE GetRouterMode()
static TOOL_ACTION layerInner2
Definition: pcb_actions.h:241
int MainLoop(const TOOL_EVENT &aEvent)
static TOOL_ACTION selectLayerPair
Definition: pcb_actions.h:126
PCB_IO is a PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
static const TOOL_ACTION ACT_PlaceMicroVia("pcbnew.InteractiveRouter.PlaceMicroVia", AS_CONTEXT, MD_CTRL+ 'V', LEGACY_HK_NAME("Add MicroVia"), _("Place Microvia"), _("Adds a microvia at the end of currently routed track."), via_microvia_xpm, AF_NONE,(void *) VIA_ACTION_FLAGS::MICROVIA)
PCB_EDIT_FRAME & m_frame
GRID_HELPER * m_gridHelper
Definition: pns_tool_base.h:75
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
BOARD * board() const
int GetCurrentViaDrill() const
Function GetCurrentViaDrill.
#define LEGACY_HK_NAME(x)
Definition: actions.h:35
int DpDimensionsDialog(const TOOL_EVENT &aEvent)
Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:175
PNS_MODE
Routing modes
static TOOL_ACTION layerInner5
Definition: pcb_actions.h:244
Normal via
Definition: router_tool.cpp:68
Helper class to create more flexible dialogs, including 'do not show again' 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:69
Defines the structure of a menu based on ACTIONs.
Definition: action_menu.h:43
This file is part of the common library.
static TOOL_ACTION layerInner6
Definition: pcb_actions.h:245
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
static TOOL_ACTION routerDiffPairDialog
Definition: pcb_actions.h:191
std::vector< int > m_TrackWidthList
static TOOL_ACTION layerInner7
Definition: pcb_actions.h:246
static TOOL_ACTION layerInner8
Definition: pcb_actions.h:247
void SetCurrentCursor(wxStockCursor aStockCursorID)
Function SetCurrentCursor Set the current cursor shape for this panel.
void AddToPreview(EDA_ITEM *aItem, bool aTakeOwnership=true)
Definition: view.cpp:1572
const wxPoint & GetStart() const
Definition: class_track.h:116
const wxString & GetName() const
Definition: netclass.h:96
int GetCurrentMicroViaDrill()
Function GetCurrentMicroViaDrill.
static TOOL_ACTION layerInner21
Definition: pcb_actions.h:260
std::vector< DIFF_PAIR_DIMENSION > m_DiffPairDimensionsList
VECTOR2I m_startSnapPoint
Definition: pns_tool_base.h:69
Classes BOARD_ITEM and BOARD_CONNECTED_ITEM.
int InlineDrag(const TOOL_EVENT &aEvent)
void CommitRouting()
Definition: pns_router.cpp:443
SELECTION_TOOL.
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
NETCLASS * GetNetClass() const
Function GetNetClassPtr returns the NETCLASS for this item.
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
static TOOL_ACTION dragFreeAngle
Definition: pcb_actions.h:135
Tool is invoked after being inactive.
Definition: tool_base.h:81
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219
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:742
static TOOL_ACTION cancelInteractive
Definition: actions.h:65
virtual void PushTool(const std::string &actionName)
NB: the definition of "tool" is different at the user level.
SIZES_SETTINGS m_savedSizes
Stores sizes settings between router invocations.
Definition: pns_tool_base.h:66
void SyncWorld()
Definition: pns_router.cpp:99
PADS & Pads()
Definition: class_module.h:181
bool IsPlacingVia() const
Definition: pns_router.cpp:535
void InitPreview()
Definition: view.cpp:1565
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
void ToggleRounded()
Definition: pns_router.cpp:544
Microvia
Definition: router_tool.cpp:72
bool IsKeyPressed() const
Definition: tool_event.h:352
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:140
class ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
bool Overlaps(const LAYER_RANGE &aOther) const
Definition: pns_layerset.h:68
static TOOL_ACTION routerHighlightMode
Actions to enable switching modes via hotkey assignments.
Definition: pcb_actions.h:194
void PrimeTool(const VECTOR2D &aPosition)
Function PrimeTool() "Primes" a tool by sending a cursor left-click event with the mouse position set...
static TOOL_ACTION trackViaSizeChanged
Definition: pcb_actions.h:287
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:537
static TOOL_ACTION drag45Degree
Definition: pcb_actions.h:134
static const TOOL_ACTION ACT_SwitchPosture("pcbnew.InteractiveRouter.SwitchPosture", AS_CONTEXT, '/', LEGACY_HK_NAME("Switch Track Posture"), _("Switch Track Posture"), _("Switches posture of the currently routed track."), change_entry_orient_xpm)
virtual void SetCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true, bool aTriggeredByArrows=false, long aArrowCommand=0)=0
Moves cursor to the requested position expressed in world coordinates.
TRACK_WIDTH_MENU(PCB_EDIT_FRAME &aFrame)
static const TOOL_ACTION ACT_SwitchRounding("pcbnew.InteractiveRouter.SwitchRounding", AS_CONTEXT, 0, LEGACY_HK_NAME("Switch Corner Rounding"), _("Switch Corner Rounding"), _("Switches the corner type of the currently routed track."), switch_corner_rounding_shape_xpm)
void UndoRedoBlock(bool aBlock=true)
Function UndoRedoBlock Enables/disable undo and redo operations.
void SetViaDrill(int aDrill)
DRAWINGS & GraphicalItems()
Definition: class_module.h:191
void SetContextMenu(ACTION_MENU *aMenu, CONTEXT_MENU_TRIGGER aTrigger=CMENU_BUTTON)
Function SetContextMenu()
SIZES_SETTINGS & Sizes()
Definition: pns_router.h:222
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:489
int CountType(KICAD_T aType)
Function CountType counts the number of items matching aType.
Definition: collector.h:262
void breakTrack()
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Function Seq returns an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:380
static TOOL_ACTION layerInner3
Definition: pcb_actions.h:242
BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected and have...
void Add(const LINE &aLine)
Definition: pns_itemset.cpp:32
ROUTER_TOOL_MENU(PCB_EDIT_FRAME &aFrame, PNS::ROUTER_MODE aMode)
static TOOL_ACTION layerInner24
Definition: pcb_actions.h:263
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:94
int ChangeRouterMode(const TOOL_EVENT &aEvent)
void SetOrthoMode(bool aEnable)
Definition: pns_router.cpp:550
Struct DIFF_PAIR_DIMENSION is a small helper container to handle a stock of specific differential pai...
static TOOL_ACTION layerInner11
Definition: pcb_actions.h:250
const VECTOR2I snapToItem(bool aEnabled, ITEM *aItem, VECTOR2I aP)
static const TOOL_ACTION ACT_EndTrack("pcbnew.InteractiveRouter.EndTrack", AS_CONTEXT, WXK_END, "", _("Finish Track"), _("Stops laying the current track."), checked_ok_xpm)
void ToggleViaPlacement()
Definition: pns_router.cpp:502
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:96
void handleCommonEvents(const TOOL_EVENT &evt)
const BITMAP_OPAQUE via_microvia_xpm[1]
GRID_MENU m_gridMenu
bool IsAction(const TOOL_ACTION *aAction) const
Function IsAction() Tests if the event contains an action issued upon activation of the given TOOL_AC...
Definition: tool_event.cpp:67
void ClearWorld()
Definition: pns_router.cpp:108
static TOOL_ACTION layerTop
Definition: pcb_actions.h:239
int Start() const
Definition: pns_layerset.h:83
void ShowPreview(bool aShow=true)
Definition: view.cpp:1586
void Append(EDA_ITEM *item)
Function Append adds an item to the end of the list.
Definition: collector.h:120
PCB_BASE_EDIT_FRAME * frame() const
void UndoLastSegment()
Definition: pns_router.cpp:434
virtual PCB_LAYER_ID GetActiveLayer() const
virtual void updateStartItem(const TOOL_EVENT &aEvent, bool aIgnorePads=false)
static TOOL_ACTION layerInner23
Definition: pcb_actions.h:262
void SetViaSizeIndex(unsigned aIndex)
Function SetViaSizeIndex sets the current via size list index to aIndex.
int onViaCommand(const TOOL_EVENT &aEvent)
static VIATYPE getViaTypeFromFlags(int aFlags)
TOOL_MANAGER.
Definition: tool_manager.h:51
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:101
virtual void Reset(RESET_REASON aReason)=0
Function Reset() Brings the tool to a known, initial state.
class MODULE, a footprint
Definition: typeinfo.h:89
static TOOL_ACTION copy
Definition: actions.h:70
ACTION_MENU * create() const override
Returns an instance of this class. It has to be overridden in inheriting classes.
virtual void updateEndItem(const TOOL_EVENT &aEvent)
bool prepareInteractive()
void SetAuxAxes(bool aEnable, const VECTOR2I &aOrigin=VECTOR2I(0, 0))
PCB_LAYER_ID
A quick note on layer IDs:
static TOOL_ACTION routerSettingsDialog
Activation of the Push and Shove settings dialogs.
Definition: pcb_actions.h:190
#define _(s)
LSET is a set of PCB_LAYER_IDs.
static TOOL_ACTION layerInner13
Definition: pcb_actions.h:252
const PCBNEW_SELECTION & selection() const
void performRouting()
void BreakSegment(ITEM *aItem, const VECTOR2I &aP)
Definition: pns_router.cpp:570
static TOOL_ACTION layerPrev
Definition: pcb_actions.h:272
static const TOOL_ACTION ACT_AutoEndRoute("pcbnew.InteractiveRouter.AutoEndRoute", AS_CONTEXT, 'F', "", _("Auto-finish Track"), _("Automagically finishes laying the current track."))
const BITMAP_OPAQUE select_w_layer_xpm[1]
static const TOOL_ACTION ACT_UndoLastSegment("pcbnew.InteractiveRouter.UndoLastSegment", AS_CONTEXT, WXK_BACK, "", _("Undo last segment"), _("Stops laying the current track."), checked_ok_xpm)
static const char Default[]
the name of the default NETCLASS
Definition: netclass.h:80
static PCB_LAYER_ID getTargetLayerFromEvent(const TOOL_EVENT &aEvent)
void update() override
Update menu state stub.
virtual void Move(const wxPoint &aMoveVector)
Function Move move this object.
unsigned GetViaSizeIndex() const
Function GetViaSizeIndex.
virtual void PopTool(const std::string &actionName)
TEXTE_MODULE & Value()
read/write accessors:
Definition: class_module.h:491
static TOOL_ACTION layerInner25
Definition: pcb_actions.h:264
int Net() const
Definition: pns_item.h:149
static const TOOL_ACTION ACT_CustomTrackWidth("pcbnew.InteractiveRouter.CustomTrackViaSize", AS_CONTEXT, 'Q', LEGACY_HK_NAME("Custom Track/Via Size"), _("Custom Track/Via Size..."), _("Shows a dialog for changing the track width and via size."), width_track_xpm)
static TOOL_ACTION layerInner18
Definition: pcb_actions.h:257
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:435
virtual int GetTopLayer() const
Definition: view.cpp:847
void SetCustomDiffPairWidth(int aWidth)
Function SetCustomDiffPairWidth Sets custom track width for differential pairs (i....
void SetIcon(const BITMAP_OPAQUE *aIcon)
Assigns an icon for the entry.
Definition: action_menu.cpp:71
TOOL_EVENT.
Definition: tool_event.h:171
VIATYPE
Definition: class_track.h:68
PNS::ROUTER_MODE m_mode
ITEM * m_startItem
Definition: pns_tool_base.h:67
bool FixRoute(const VECTOR2I &aP, ITEM *aItem, bool aForceFinish=false)
Definition: pns_router.cpp:407
OPT_TOOL_EVENT eventHandler(const wxMenuEvent &aEvent) override
Event handler stub.
unsigned GetTrackWidthIndex() const
Function GetTrackWidthIndex.
DIFF_PAIR_MENU(PCB_EDIT_FRAME &aFrame)
static TOOL_ACTION layerInner30
Definition: pcb_actions.h:269
void ClearPreview()
Definition: view.cpp:1553
static TOOL_ACTION cut
Definition: actions.h:69
KIGFX::PCB_VIEW * view() const
ZOOM_MENU m_zoomMenu
static TOOL_ACTION layerInner29
Definition: pcb_actions.h:268
void Init(BOARD *aBoard, ITEM *aStartItem=NULL, int aNet=-1)
unsigned STATUS_FLAGS
Definition: base_struct.h:152
ROUTER * m_router
Definition: pns_tool_base.h:77
bool CanInlineDrag()
PNS_MODE Mode() const
Returns the routing mode.
VIEW_CONTROLS is an interface for classes handling user events controlling the view behaviour (such a...
PCB_LAYER_ID m_Route_Layer_BOTTOM
Definition: pcb_screen.h:39
void switchLayerOnViaPlacement()
PCB_EDIT_FRAME & m_frame
static TOOL_ACTION layerInner10
Definition: pcb_actions.h:249
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Function ForceCursorPosition() Places the cursor immediately at a given point.
bool m_BlindBuriedViaAllowed
true to allow blind/buried vias
int SettingsDialog(const TOOL_EVENT &aEvent)
void SetDiffPairIndex(unsigned aIndex)
Function SetDiffPairIndex.
static const TOOL_ACTION ACT_SelLayerAndPlaceThroughVia("pcbnew.InteractiveRouter.SelLayerAndPlaceVia", AS_CONTEXT, '<', LEGACY_HK_NAME("Select 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))
int CustomTrackWidthDialog(const TOOL_EVENT &aEvent)
virtual void SetActiveLayer(PCB_LAYER_ID aLayer)
void SetCustomDiffPairGap(int aGap)
Function SetCustomDiffPairGap Sets custom gap for differential pairs (i.e.
void ImportCurrent(BOARD_DESIGN_SETTINGS &aSettings)
const BITMAP_OPAQUE via_buried_xpm[1]
Definition: via_buried.cpp:55
void ShowInfoBarError(const wxString &aErrorMsg)
const BITMAP_OPAQUE switch_corner_rounding_shape_xpm[1]
static TOOL_ACTION routerWalkaroundMode
Definition: pcb_actions.h:196
void Move(const VECTOR2I &aP, ITEM *aItem)
Definition: pns_router.cpp:257
static TOOL_ACTION layerInner15
Definition: pcb_actions.h:254
const BITMAP_OPAQUE width_track_via_xpm[1]
int onTrackViaSizeChanged(const TOOL_EVENT &aEvent)
static TOOL_ACTION routerInlineDrag
Activation of the Push and Shove router (inline dragging mode)
Definition: pcb_actions.h:199
bool StartRouting(const VECTOR2I &aP, ITEM *aItem, int aLayer)
Definition: pns_router.cpp:195
static TOOL_ACTION layerInner28
Definition: pcb_actions.h:267
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:36
virtual void SetAutoPan(bool aEnabled)
Function SetAutoPan Turns on/off auto panning (this feature is used when there is a tool active (eg.
static TOOL_ACTION layerInner27
Definition: pcb_actions.h:266
void SetViaType(VIATYPE aViaType)
Pad object description.
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:121
static TOOL_ACTION inlineBreakTrack
Breaks track when router is not activated.
Definition: pcb_actions.h:132
ACTION_MENU * create() const override
Returns an instance of this class. It has to be overridden in inheriting classes.
static TOOL_ACTION layerInner17
Definition: pcb_actions.h:256
static TOOL_ACTION breakTrack
Break a single track into two segments at the cursor.
Definition: pcb_actions.h:129
static TOOL_ACTION layerInner20
Definition: pcb_actions.h:259
static TOOL_ACTION pasteSpecial
Definition: actions.h:72
void StopRouting()
Definition: pns_router.cpp:452
virtual void highlightNet(bool aEnabled, int aNetcode=-1)
static const TOOL_ACTION ACT_PlaceThroughVia("pcbnew.InteractiveRouter.PlaceVia", AS_CONTEXT, 'V', LEGACY_HK_NAME("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)
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aUseMils, EDA_DATA_TYPE aType)
Definition: base_units.cpp:124
ACTION_MENU * create() const override
Returns an instance of this class. It has to be overridden in inheriting classes.
OPT< std::string > GetCommandStr() const
Definition: tool_event.h:463
ROUTER_MODE
Definition: pns_router.h:68
PCB_EDIT_FRAME & m_frame
static TOOL_ACTION layerInner22
Definition: pcb_actions.h:261
int GetCurrentViaSize() const
Function GetCurrentViaSize.
static TOOL_ACTION layerChanged
Definition: pcb_actions.h:277
void UpdateSizes(const SIZES_SETTINGS &aSizes)
Applies stored settings.
Definition: pns_router.cpp:348
void SetTitle(const wxString &aTitle) override
Sets title for the menu.
Definition: action_menu.cpp:89
KIGFX::VIEW_CONTROLS * controls() const
void SetMode(ROUTER_MODE aMode)
Definition: pns_router.cpp:559
void update() override
Update menu state stub.
STATUS_FLAGS IsPointOnEnds(const wxPoint &point, int min_dist=0) const
Function IsPointOnEnds returns STARTPOINT if point if near (dist = min_dist) start point,...
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
MODULE * module() const
static TOOL_ACTION routeSingleTrack
Activation of the Push and Shove router.
Definition: pcb_actions.h:173
VECTOR2I m_endSnapPoint
Definition: pns_tool_base.h:73
LOGGER * Logger()
Definition: pns_router.cpp:529
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:240
TOOL_BASE.
Definition: tool_base.h:67
bool IsToolActive() const
Definition: tool_base.cpp:31
static TOOL_ACTION layerInner14
Definition: pcb_actions.h:253
Represents a single user action.
Definition: tool_action.h:44
static TOOL_ACTION layerInner9
Definition: pcb_actions.h:248
bool StartDragging(const VECTOR2I &aP, ITEM *aItem, int aDragMode=DM_ANY)
Definition: pns_router.cpp:134
#define ENDPOINT
ends. (Used to support dragging.)
Definition: base_struct.h:123
static void NeighboringSegmentFilter(const VECTOR2I &aPt, GENERAL_COLLECTOR &aCollector)
void performDragging(int aMode=PNS::DM_ANY)
bool OfKind(int aKindMask) const
Function OfKind()
Definition: pns_item.h:133
PCB_EDIT_FRAME is the main frame for Pcbnew.
void Clear()
Removes all the entries from the menu (as well as its title).
TOOL_EVENT MakeEvent() const
Returns the event associated with the action (i.e.
Definition: tool_action.h:113
int Size() const
Returns the number of selected parts.
Definition: selection.h:127
bool IsLocked() const
Definition: pns_item.h:241
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:1448
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:79
static TOOL_ACTION layerInner16
Definition: pcb_actions.h:255
const wxPoint & GetEnd() const
Definition: class_track.h:113
std::vector< VIA_DIMENSION > m_ViasDimensionsList
boost::optional< T > OPT
Definition: optional.h:7
int ShowModal() override
Definition: confirm.cpp:95
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
void Activate()
Function Activate() Runs the tool.
MODULE_ZONE_CONTAINERS & Zones()
Definition: class_module.h:201
Implementing DIALOG_TRACK_VIA_SIZE_BASE.
int SelectCopperLayerPair(const TOOL_EVENT &aEvent)
Definition: sel_layer.cpp:261
static TOOL_ACTION layerInner4
Definition: pcb_actions.h:243
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
unsigned GetDiffPairIndex() const
Function GetDiffPairIndex.
static const TOOL_ACTION ACT_PlaceBlindVia("pcbnew.InteractiveRouter.PlaceBlindVia", AS_CONTEXT, MD_ALT+MD_SHIFT+ 'V', LEGACY_HK_NAME("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)
bool HasPosition() const
Returns if it this event has a valid position (true for mouse events and context-menu or hotkey-based...
Definition: tool_event.h:260
void AddLayerPair(int aL1, int aL2)
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:78
bool m_MicroViasAllowed
true to allow micro vias
BOARD * GetBoard() const
KIGFX::VIEW_CONTROLS * getViewControls() const
Function getViewControls()
Definition: tool_base.cpp:42
void FlipPosture()
Definition: pns_router.cpp:480
DIFF_PAIR_MENU m_diffPairMenu
const BITMAP_OPAQUE change_entry_orient_xpm[1]
bool RoutingInProgress() const
Definition: pns_router.cpp:120
int KeyCode() const
Definition: tool_event.h:347
static TOOL_ACTION layerInner19
Definition: pcb_actions.h:258
void SetViaDiameter(int aDiameter)
EDGE_MODULE class definition.
int getStartLayer(const PNS::ITEM *aItem)
TRACK_WIDTH_MENU m_trackViaMenu
static TOOL_ACTION layerInner1
Definition: pcb_actions.h:240
static TOOL_ACTION routerShoveMode
Definition: pcb_actions.h:195
NODE * GetWorld() const
Definition: pns_router.h:155
int GetCopperLayerCount() const
Function GetCopperLayerCount.
OPT< int > PairedLayer(int aLayerId)
const BITMAP_OPAQUE width_track_xpm[1]
Definition: width_track.cpp:39
PNS_KICAD_IFACE * m_iface
Definition: pns_tool_base.h:76
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:206
const BITMAP_OPAQUE via_xpm[1]
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:203
const BITMAP_OPAQUE checked_ok_xpm[1]
Definition: checked_ok.cpp:51
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:856
static TOOL_ACTION paste
Definition: actions.h:71
VIA_ACTION_FLAGS
Flags used by via tool actions.
Definition: router_tool.cpp:63
const VECTOR2D Position() const
Returns mouse cursor position in world coordinates.
Definition: tool_event.h:274
static TOOL_ACTION selectionCursor
Select a single item under the cursor position.
Definition: pcb_actions.h:59
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
LAYER_RANGE.
Definition: pns_layerset.h:32
const LAYER_RANGE & Layers() const
Definition: pns_item.h:151
PCB_LAYER_ID m_Route_Layer_TOP
Definition: pcb_screen.h:38
void UseCustomTrackViaSize(bool aEnabled)
Function UseCustomTrackViaSize Enables/disables custom track/via size settings.
virtual void Save(const wxString &aFileName, BOARD *aBoard, const PROPERTIES *aProperties=NULL) override
Function Save will write aBoard to a storage file in a format that this PLUGIN implementation knows a...
VECTOR2D GetCursorPosition() const
Returns the current cursor position in world coordinates.
EDA_ITEM * Front() const
Definition: selection.h:184
static TOOL_ACTION layerInner12
Definition: pcb_actions.h:251
static const TOOL_ACTION ACT_SelLayerAndPlaceBlindVia("pcbnew.InteractiveRouter.SelLayerAndPlaceBlindVia", AS_CONTEXT, MD_ALT+'<', LEGACY_HK_NAME("Select 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))
OPT< TOOL_EVENT > OPT_TOOL_EVENT
Definition: tool_event.h:556
KICAD_T Type() const
Function Type()
Definition: base_struct.h:193
BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.
#define STARTPOINT
When a line is selected, these flags indicate which.
Definition: base_struct.h:122
static TOOL_ACTION layerToggle
Definition: pcb_actions.h:275
int GetCurrentLayer() const
Definition: pns_router.cpp:521
static TOOL_ACTION routeDiffPair
Activation of the Push and Shove router (differential pair mode)
Definition: pcb_actions.h:176