KiCad PCB EDA Suite
pns_tool_base.cpp
Go to the documentation of this file.
1 /*
2  * KiRouter - a push-and-(sometimes-)shove PCB router
3  *
4  * Copyright (C) 2013 CERN
5  * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
6  * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
7  *
8  * This program is free software: you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation, either version 3 of the License, or (at your
11  * option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <wx/numdlg.h>
23 
24 #include <functional>
25 using namespace std::placeholders;
26 
27 #include "class_draw_panel_gal.h"
28 #include "class_board.h"
29 
30 #include <wxPcbStruct.h>
31 #include <id.h>
32 #include <macros.h>
33 #include <pcbnew_id.h>
34 #include <view/view_controls.h>
35 #include <pcb_painter.h>
40 #include <base_units.h>
41 #include <bitmaps.h>
42 
43 #include <tool/context_menu.h>
44 #include <tools/pcb_actions.h>
45 #include <tools/grid_helper.h>
46 
47 #include <ratsnest_data.h>
48 
49 #include "pns_kicad_iface.h"
50 #include "pns_tool_base.h"
51 #include "pns_segment.h"
52 #include "pns_solid.h"
53 #include "pns_via.h"
54 #include "pns_router.h"
55 #include "pns_meander_placer.h" // fixme: move settings to separate header
56 #include "pns_tune_status_popup.h"
57 #include "pns_topology.h"
58 
59 #include <view/view.h>
60 
61 using namespace KIGFX;
62 
63 namespace PNS {
64 
65 TOOL_ACTION TOOL_BASE::ACT_RouterOptions( "pcbnew.InteractiveRouter.RouterOptions",
66  AS_CONTEXT, 'E',
67  _( "Routing Options..." ),
68  _( "Shows a dialog containing router options." ), tools_xpm );
69 
70 
71 TOOL_BASE::TOOL_BASE( const std::string& aToolName ) :
72  TOOL_INTERACTIVE( aToolName )
73 {
74  m_gridHelper = nullptr;
75  m_iface = nullptr;
76  m_router = nullptr;
77 
78  m_startItem = nullptr;
79  m_startLayer = 0;
80 
81  m_endItem = nullptr;
82 
83  m_frame = nullptr;
84  m_ctls = nullptr;
85  m_board = nullptr;
86  m_gridHelper = nullptr;
87 }
88 
89 
91 {
92  delete m_gridHelper;
93  delete m_iface;
94  delete m_router;
95 }
96 
97 
98 
100 {
101  delete m_gridHelper;
102  delete m_iface;
103  delete m_router;
104 
105  m_frame = getEditFrame<PCB_EDIT_FRAME>();
107  m_board = getModel<BOARD>();
108 
109  m_iface = new PNS_KICAD_IFACE;
110  m_iface->SetBoard( m_board );
111  m_iface->SetView( getView() );
112  m_iface->SetHostFrame( m_frame );
113 
114  m_router = new ROUTER;
115  m_router->SetInterface(m_iface);
116  m_router->ClearWorld();
117  m_router->SyncWorld();
120 
122 }
123 
124 
125 ITEM* TOOL_BASE::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLayer )
126 {
127  int tl = getView()->GetTopLayer();
128 
129  if( aLayer > 0 )
130  tl = aLayer;
131 
132  ITEM* prioritized[4];
133 
134  for( int i = 0; i < 4; i++ )
135  prioritized[i] = 0;
136 
137  ITEM_SET candidates = m_router->QueryHoverItems( aWhere );
138 
139  for( ITEM* item : candidates.Items() )
140  {
141  if( !IsCopperLayer( item->Layers().Start() ) )
142  continue;
143 
144  // fixme: this causes flicker with live loop removal...
145  //if( item->Parent() && !item->Parent()->ViewIsVisible() )
146  // continue;
147 
148  if( aNet < 0 || item->Net() == aNet )
149  {
150  if( item->OfKind( ITEM::VIA_T | ITEM::SOLID_T ) )
151  {
152  if( !prioritized[2] )
153  prioritized[2] = item;
154  if( item->Layers().Overlaps( tl ) )
155  prioritized[0] = item;
156  }
157  else
158  {
159  if( !prioritized[3] )
160  prioritized[3] = item;
161  if( item->Layers().Overlaps( tl ) )
162  prioritized[1] = item;
163  }
164  }
165  }
166 
167  ITEM* rv = NULL;
168  PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
169  DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)frame->GetDisplayOptions();
170 
171  for( int i = 0; i < 4; i++ )
172  {
173  ITEM* item = prioritized[i];
174 
175  if( displ_opts->m_ContrastModeDisplay )
176  if( item && !item->Layers().Overlaps( tl ) )
177  item = NULL;
178 
179  if( item )
180  {
181  rv = item;
182  break;
183  }
184  }
185 
186  if( rv && aLayer >= 0 && !rv->Layers().Overlaps( aLayer ) )
187  rv = NULL;
188 
189  if( rv )
190  {
191  wxLogTrace( "PNS", "%s, layer : %d, tl: %d", rv->KindStr().c_str(), rv->Layers().Start(), tl );
192  }
193 
194  return rv;
195 }
196 
197 
198 void TOOL_BASE::highlightNet( bool aEnabled, int aNetcode )
199 {
201 
202  if( aNetcode >= 0 && aEnabled )
203  rs->SetHighlight( true, aNetcode );
204  else
205  rs->SetHighlight( false );
206 
208 }
209 
210 
212 {
213  int tl = getView()->GetTopLayer();
215  VECTOR2I p;
216 
217  bool snapEnabled = true;
218 
219  if( aEvent.IsMotion() || aEvent.IsClick() )
220  {
221  snapEnabled = !aEvent.Modifier( MD_SHIFT );
222  p = aEvent.Position();
223  }
224  else
225  {
226  p = cp;
227  }
228 
230 
231  if( !snapEnabled && m_startItem && !m_startItem->Layers().Overlaps( tl ) )
232  m_startItem = nullptr;
233 
234  m_startSnapPoint = snapToItem( snapEnabled, m_startItem, p );
236 }
237 
238 
240 {
242  VECTOR2I p = getView()->ToWorld( mp );
243  int layer;
244  bool snapEnabled = !aEvent.Modifier( MD_SHIFT );
245 
246  if( m_router->GetCurrentNets().empty() || m_router->GetCurrentNets().front() < 0 )
247  {
248  m_endSnapPoint = snapToItem( snapEnabled, nullptr, p );
250  m_endItem = nullptr;
251 
252  return;
253  }
254 
255  if( m_router->IsPlacingVia() )
256  layer = -1;
257  else
258  layer = m_router->GetCurrentLayer();
259 
260  ITEM* endItem = nullptr;
261 
262  std::vector<int> nets = m_router->GetCurrentNets();
263 
264  for( int net : nets )
265  {
266  endItem = pickSingleItem( p, net, layer );
267 
268  if( endItem )
269  break;
270  }
271 
272  VECTOR2I cursorPos = snapToItem( snapEnabled, endItem, p );
273  m_ctls->ForceCursorPosition( true, cursorPos );
274  m_endItem = endItem;
275  m_endSnapPoint = cursorPos;
276 
277  if( m_endItem )
278  {
279  wxLogTrace( "PNS", "%s, layer : %d", m_endItem->KindStr().c_str(), m_endItem->Layers().Start() );
280  }
281 }
282 
283 
284 void TOOL_BASE::deleteTraces( ITEM* aStartItem, bool aWholeTrack )
285 {
286  NODE *node = m_router->GetWorld()->Branch();
287 
288  if( !aStartItem )
289  return;
290 
291  if( !aWholeTrack )
292  {
293  node->Remove( aStartItem );
294  }
295  else
296  {
297  TOPOLOGY topo( node );
298  ITEM_SET path = topo.AssembleTrivialPath( aStartItem );
299 
300  for( auto ent : path.Items() )
301  node->Remove( ent.item );
302  }
303 
304  m_router->CommitRouting( node );
305 }
306 
307 
309 {
310  return m_router;
311 }
312 
313 
314 const VECTOR2I TOOL_BASE::snapToItem( bool aEnabled, ITEM* aItem, VECTOR2I aP)
315 {
316  VECTOR2I anchor;
317 
318  if( !aItem || !aEnabled )
319  {
320  return m_gridHelper->Align( aP );
321  }
322 
323  switch( aItem->Kind() )
324  {
325  case ITEM::SOLID_T:
326  anchor = static_cast<SOLID*>( aItem )->Pos();
327  break;
328 
329  case ITEM::VIA_T:
330  anchor = static_cast<VIA*>( aItem )->Pos();
331  break;
332 
333  case ITEM::SEGMENT_T:
334  {
335  SEGMENT* seg = static_cast<SEGMENT*>( aItem );
336  const SEG& s = seg->Seg();
337  int w = seg->Width();
338 
339 
340  if( ( aP - s.A ).EuclideanNorm() < w / 2 )
341  anchor = s.A;
342  else if( ( aP - s.B ).EuclideanNorm() < w / 2 )
343  anchor = s.B;
344  else
345  anchor = m_gridHelper->AlignToSegment( aP, s );
346 
347  break;
348  }
349 
350  default:
351  break;
352  }
353 
354  return anchor;
355 }
356 
357 }
Class ITEM.
Definition: pns_item.h:53
int GetTopLayer() const
Definition: view.cpp:739
Class NODE.
Definition: pns_node.h:137
GRID_HELPER * m_gridHelper
Definition: pns_tool_base.h:83
Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
Definition: class_module.h:56
const LAYER_RANGE & Layers() const
Function Layers()
Definition: pns_item.h:207
void LoadSettings(const ROUTING_SETTINGS &aSettings)
Changes routing settings to ones passed in the parameter.
Definition: pns_router.h:192
Class RENDER_SETTINGS Contains all the knowledge about how graphical objects are drawn on any output ...
Definition: painter.h:56
Implementation of conversion functions that require both schematic and board internal units...
bool IsMotion() const
Definition: tool_event.h:290
VECTOR2I Align(const VECTOR2I &aPoint) const
Definition: grid_helper.cpp:95
VIEW_CONTROLS class definition.
VECTOR2I m_startSnapPoint
Definition: pns_tool_base.h:75
const ITEM_SET QueryHoverItems(const VECTOR2I &aP)
Definition: pns_router.cpp:125
Class BOARD to handle a board.
Class that computes missing connections on a PCB.
ENTRIES & Items()
Definition: pns_itemset.h:137
VECTOR2D ToWorld(const VECTOR2D &aCoord, bool aAbsolute=true) const
Function ToWorld() Converts a screen space point/vector to a point/vector in world space coordinates...
Definition: view.cpp:440
SIZES_SETTINGS m_savedSizes
Stores sizes settings between router invocations.
Definition: pns_tool_base.h:72
void SyncWorld()
Definition: pns_router.cpp:98
VECTOR2I AlignToSegment(const VECTOR2I &aPoint, const SEG &aSeg)
int Modifier(int aMask=MD_MODIFIER_MASK) const
Returns information about key modifiers state (Ctrl, Alt, etc.)
Definition: tool_event.h:311
const VECTOR2D & Position() const
Returns mouse cursor position in world coordinates.
Definition: tool_event.h:248
bool IsPlacingVia() const
Definition: pns_router.cpp:466
const std::vector< int > GetCurrentNets() const
Definition: pns_router.cpp:426
NODE * Branch()
Function Branch()
Definition: pns_node.cpp:109
const VECTOR2I snapToItem(bool aEnabled, ITEM *aItem, VECTOR2I aP)
NODE * GetWorld() const
Definition: pns_router.h:134
void * GetDisplayOptions() override
Function GetDisplayOptions returns the display options current in use Display options are relative to...
This file contains miscellaneous commonly used macros and functions.
void ClearWorld()
Definition: pns_router.cpp:107
KIGFX::VIEW_CONTROLS * m_ctls
Definition: pns_tool_base.h:81
virtual void updateEndItem(const TOOL_EVENT &aEvent)
virtual void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
const ITEM_SET AssembleTrivialPath(ITEM *aStart)
virtual ~TOOL_BASE()
virtual VECTOR2D GetCursorPosition() const =0
Function GetCursorPosition() Returns the current cursor position in world coordinates.
Class TOOL_EVENT.
Definition: tool_event.h:162
ITEM * m_startItem
Definition: pns_tool_base.h:73
ROUTER * m_router
Definition: pns_tool_base.h:85
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Function ForceCursorPosition() Places the cursor immediately at a given point.
ROUTING_SETTINGS m_savedSettings
Stores routing settings between router invocations.
Definition: pns_tool_base.h:71
int Width() const
Definition: pns_segment.h:88
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:196
int Start() const
Definition: pns_layerset.h:83
bool Overlaps(const LAYER_RANGE &aOther) const
Definition: pns_layerset.h:68
void SetInterface(ROUTER_IFACE *aIface)
Definition: pns_router.cpp:490
KIGFX::VIEW_CONTROLS * getViewControls() const
Function getViewControls()
Definition: tool_base.cpp:36
void Remove(SOLID *aSolid)
Function Remove()
Definition: pns_node.cpp:729
Class DISPLAY_OPTIONS handles display options like enable/disable some optional drawings.
Definition: pcbstruct.h:62
PnsKind Kind() const
Function Kind()
Definition: pns_item.h:120
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:30
virtual void highlightNet(bool aEnabled, int aNetcode=-1)
Definition: seg.h:37
virtual RENDER_SETTINGS * GetSettings()=0
Function GetSettings Returns pointer to current settings that are going to be used when drawing items...
void UpdateSizes(const SIZES_SETTINGS &aSizes)
Applies stored settings.
Definition: pns_router.cpp:285
void CommitRouting(NODE *aNode)
Definition: pns_router.cpp:324
VECTOR2I m_endSnapPoint
Definition: pns_tool_base.h:78
void deleteTraces(ITEM *aStartItem, bool aWholeTrack)
Class TOOL_ACTION.
Definition: tool_action.h:46
VECTOR2I A
Definition: seg.h:47
PCB_EDIT_FRAME * m_frame
Definition: pns_tool_base.h:80
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:80
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
const SEG & Seg() const
Definition: pns_segment.h:93
virtual ITEM * pickSingleItem(const VECTOR2I &aWhere, int aNet=-1, int aLayer=-1)
int GetCurrentLayer() const
Definition: pns_router.cpp:435
void UpdateAllLayersColor()
Function UpdateAllLayersColor() Applies the new coloring scheme to all layers.
Definition: view.cpp:674
ROUTER * Router() const
bool IsClick(int aButtonMask=BUT_ANY) const
Definition: tool_event.h:268
Push and Shove diff pair dimensions (gap) settings dialog.
void SetHighlight(bool aEnabled, int aNetcode=-1)
Function SetHighlight Turns on/off highlighting - it may be done for the active layer or the specifie...
Definition: painter.h:139
void SetBoard(BOARD *aBoard)
PNS_KICAD_IFACE * m_iface
Definition: pns_tool_base.h:84
const std::string KindStr() const
Function KindStr()
Definition: pns_item.cpp:63
TOOL_BASE(TOOL_TYPE aType, TOOL_ID aId, const std::string &aName=std::string(""))
Definition: tool_base.h:71
virtual VECTOR2I GetMousePosition() const =0
Function GetMousePosition() Returns the current mouse pointer position in screen coordinates.
virtual void updateStartItem(TOOL_EVENT &aEvent)
VECTOR2I B
Definition: seg.h:48