KiCad PCB EDA Suite
editrack-part2.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2015 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
5  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
7  * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, you may find one here:
21  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22  * or you may search the http://www.gnu.org website for the version 2 license,
23  * or you may write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26 
32 #include <fctsys.h>
33 #include <gr_basic.h>
34 #include <class_drawpanel.h>
35 #include <confirm.h>
36 #include <wxPcbStruct.h>
37 
38 #include <class_board.h>
39 #include <class_module.h>
40 #include <class_track.h>
41 #include <class_marker_pcb.h>
42 
43 #include <pcbnew.h>
44 #include <drc_stuff.h>
45 
46 
47 bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC )
48 {
49  unsigned itmp;
50 
51  if( aTrack == NULL )
52  {
53  if( GetActiveLayer() != GetScreen()->m_Route_Layer_TOP )
54  SetActiveLayer( GetScreen()->m_Route_Layer_TOP );
55  else
56  SetActiveLayer( GetScreen()->m_Route_Layer_BOTTOM );
57 
59  return true;
60  }
61 
62  // Avoid more than one via on the current location:
63  if( GetBoard()->GetViaByPosition( g_CurrentTrackSegment->GetEnd(),
64  g_CurrentTrackSegment->GetLayer() ) )
65  return false;
66 
67  for( TRACK* segm = g_FirstTrackSegment; segm; segm = segm->Next() )
68  {
69  if( segm->Type() == PCB_VIA_T && g_CurrentTrackSegment->GetEnd() == segm->GetStart() )
70  return false;
71  }
72 
73  // Is the current segment Ok (no DRC error) ?
74  if( g_Drc_On )
75  {
76  if( BAD_DRC==m_drc->Drc( g_CurrentTrackSegment, GetBoard()->m_Track ) )
77  // DRC error, the change layer is not made
78  return false;
79 
80  // Handle 2 segments.
82  {
83  if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment->Back(), GetBoard()->m_Track ) )
84  return false;
85  }
86  }
87 
88  /* Save current state before placing a via.
89  * If the via cannot be placed this current state will be reused
90  */
93 
94  m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
95 
96  // create the via
97  VIA* via = new VIA( GetBoard() );
98  via->SetFlags( IS_NEW );
99  via->SetViaType( GetDesignSettings().m_CurrentViaType );
100  via->SetNetCode( GetBoard()->GetHighLightNetCode() );
101  via->SetPosition( g_CurrentTrackSegment->GetEnd() );
102 
103  // for microvias, the size and hole will be changed later.
104  via->SetWidth( GetDesignSettings().GetCurrentViaSize());
105  via->SetDrill( GetDesignSettings().GetCurrentViaDrill() );
106 
107  // Usual via is from copper to component.
108  // layer pair is B_Cu and F_Cu.
109  via->SetLayerPair( B_Cu, F_Cu );
110 
111  PCB_LAYER_ID first_layer = GetActiveLayer();
112  PCB_LAYER_ID last_layer;
113 
114  // prepare switch to new active layer:
115  if( first_layer != GetScreen()->m_Route_Layer_TOP )
116  last_layer = GetScreen()->m_Route_Layer_TOP;
117  else
118  last_layer = GetScreen()->m_Route_Layer_BOTTOM;
119 
120  // Adjust the actual via layer pair
121  switch( via->GetViaType() )
122  {
123  case VIA_BLIND_BURIED:
124  via->SetLayerPair( first_layer, last_layer );
125  break;
126 
127  case VIA_MICROVIA: // from external to the near neighbor inner layer
128  {
129  PCB_LAYER_ID last_inner_layer = ToLAYER_ID( ( GetBoard()->GetCopperLayerCount() - 2 ) );
130 
131  if( first_layer == B_Cu )
132  last_layer = last_inner_layer;
133  else if( first_layer == F_Cu )
134  last_layer = In1_Cu;
135  else if( first_layer == last_inner_layer )
136  last_layer = B_Cu;
137  else if( first_layer == In1_Cu )
138  last_layer = F_Cu;
139  // else error: will be removed later
140  via->SetLayerPair( first_layer, last_layer );
141 
142  // Update diameter and hole size, which where set previously
143  // for normal vias
144  NETINFO_ITEM* net = via->GetNet();
145  via->SetWidth( net->GetMicroViaSize() );
146  via->SetDrill( net->GetMicroViaDrillSize() );
147  }
148  break;
149 
150  default:
151  break;
152  }
153 
154  if( g_Drc_On && BAD_DRC == m_drc->Drc( via, GetBoard()->m_Track ) )
155  {
156  // DRC fault: the Via cannot be placed here ...
157  delete via;
158 
159  m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
160 
161  // delete the track(s) added in Begin_Route()
162  while( g_CurrentTrackList.GetCount() > itmp )
163  {
165  }
166 
168 
169  // Refresh DRC diag, erased by previous calls
170  if( m_drc->GetCurrentMarker() )
172 
173  return false;
174  }
175 
176  SetActiveLayer( last_layer );
177 
178  TRACK* lastNonVia = g_CurrentTrackSegment;
179 
180  /* A new via was created. It was Ok.
181  */
183 
184  /* The via is now in linked list and we need a new track segment
185  * after the via, starting at via location.
186  * it will become the new current segment (from via to the mouse cursor)
187  */
188 
189  TRACK* track = (TRACK*)lastNonVia->Clone();
190 
191  /* the above creates a new segment from the last entered segment, with the
192  * current width, flags, netcode, etc... values.
193  * layer, start and end point are not correct,
194  * and will be modified next
195  */
196 
197  // set the layer to the new value
198  track->SetLayer( GetActiveLayer() );
199 
200  /* the start point is the via position and the end point is the cursor
201  * which also is on the via (will change when moving mouse)
202  */
203  track->SetEnd( via->GetStart() );
204  track->SetStart( via->GetStart() );
205 
206  g_CurrentTrackList.PushBack( track );
207 
209  {
210  // Create a second segment (we must have 2 track segments to adjust)
212  }
213 
214  m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
215  SetMsgPanel( via );
216  UpdateStatusBar();
217 
218  return true;
219 }
220 
221 
223 {
224  D_PAD* pt_pad = NULL;
225  MODULE* Module = NULL;
226 
228  return;
229 
230  if( ( GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK ) == 0 )
231  Compile_Ratsnest( DC, true );
232 
233  if( item )
234  {
235  if( item->Type() == PCB_PAD_T )
236  {
237  pt_pad = (D_PAD*) item;
238  Module = pt_pad->GetParent();
239  }
240 
241  if( pt_pad ) // Displaying the ratsnest of the corresponding net.
242  {
243  SetMsgPanel( pt_pad );
244 
245  for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
246  {
247  RATSNEST_ITEM* net = &GetBoard()->m_FullRatsnest[ii];
248 
249  if( net->GetNet() == pt_pad->GetNetCode() )
250  {
251  if( ( net->m_Status & CH_VISIBLE ) != 0 )
252  continue;
253 
254  net->m_Status |= CH_VISIBLE;
255 
256  if( ( net->m_Status & CH_ACTIF ) == 0 )
257  continue;
258 
259  net->Draw( m_canvas, DC, GR_XOR, wxPoint( 0, 0 ) );
260  }
261  }
262  }
263  else
264  {
265  if( item->Type() == PCB_MODULE_TEXT_T )
266  {
267  if( item->GetParent() && ( item->GetParent()->Type() == PCB_MODULE_T ) )
268  Module = static_cast<MODULE*>( item->GetParent() );
269  }
270  else if( item->Type() == PCB_MODULE_T )
271  {
272  Module = static_cast<MODULE*>( item );
273  }
274 
275  if( Module )
276  {
277  SetMsgPanel( Module );
278  pt_pad = Module->Pads();
279 
280  for( ; pt_pad != NULL; pt_pad = pt_pad->Next() )
281  {
282  for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
283  {
284  RATSNEST_ITEM* net = &GetBoard()->m_FullRatsnest[ii];
285 
286  if( ( net->m_PadStart == pt_pad ) || ( net->m_PadEnd == pt_pad ) )
287  {
288  if( net->m_Status & CH_VISIBLE )
289  continue;
290 
291  net->m_Status |= CH_VISIBLE;
292 
293  if( (net->m_Status & CH_ACTIF) == 0 )
294  continue;
295 
296  net->Draw( m_canvas, DC, GR_XOR, wxPoint( 0, 0 ) );
297  }
298  }
299  }
300 
301  pt_pad = NULL;
302  }
303  }
304  }
305 
306  // Erase if no pad or module has been selected.
307  if( ( pt_pad == NULL ) && ( Module == NULL ) )
308  {
309  DrawGeneralRatsnest( DC );
310 
311  for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
312  GetBoard()->m_FullRatsnest[ii].m_Status &= ~CH_VISIBLE;
313  }
314 }
#define g_FirstTrackSegment
first segment created
Definition: pcbnew.h:102
#define g_CurrentTrackSegment
most recently created segment
Definition: pcbnew.h:101
KICAD_T Type() const
Function Type()
Definition: base_struct.h:198
bool Other_Layer_Route(TRACK *track, wxDC *DC)
Function Other_Layer_Route operates in one of two ways.
bool g_Drc_On
Definition: pcbnew.cpp:70
TRACK * Delete_Segment(wxDC *DC, TRACK *Track)
Function Delete_Segment removes a track segment.
Definition: deltrack.cpp:45
void SetViaType(VIATYPE_T aViaType)
Definition: class_track.h:447
void SetPosition(const wxPoint &aPoint) override
Definition: class_track.h:417
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
This file is part of the common library.
void SetEnd(const wxPoint &aEnd)
Definition: class_track.h:117
DLIST< TRACK > g_CurrentTrackList
Definition: pcbnew.cpp:98
Class BOARD to handle a board.
MODULE * GetParent() const
Definition: class_pad.h:108
void SetCurItem(BOARD_ITEM *aItem, bool aDisplayInfo=true)
Function SetCurItem sets the currently selected item and displays it in the MsgPanel.
EDA_ITEM * GetParent() const
Definition: base_struct.h:208
virtual EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
BOARD * GetBoard() const
class D_PAD, a pad in a footprint
Definition: typeinfo.h:102
DRC * m_drc
the DRC controller, see drc.cpp
Definition: wxPcbStruct.h:96
TRACK * Begin_Route(TRACK *aTrack, wxDC *aDC)
Function Begin_Route Starts a new track and/or establish of a new track point.
Definition: editrack.cpp:98
Functions relatives to tracks, vias and segments used to fill zones.
void SetWidth(int aWidth)
Definition: class_track.h:114
#define BAD_DRC
Definition: drc_stuff.h:36
void PushBack(T *aNewElement)
Function PushBack puts aNewElement at the end of the list sequence.
Definition: dlist.h:250
#define IS_NEW
New item, just created.
Definition: base_struct.h:113
#define CH_ACTIF
Definition: class_netinfo.h:60
std::vector< RATSNEST_ITEM > m_FullRatsnest
Ratsnest list for the BOARD.
Definition: class_board.h:248
D_PAD * m_PadEnd
Definition: class_netinfo.h:76
class MODULE, a footprint
Definition: typeinfo.h:101
Markers used to show a drc problem on boards.
bool IsElementVisible(GAL_LAYER_ID aElement) const
Function IsElementVisible tests whether a given element category is visible.
Definition: pcbframe.cpp:930
PCB_LAYER_ID
A quick note on layer IDs:
unsigned GetRatsnestsCount() const
Function GetNumRatsnests.
Definition: class_board.h:704
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:253
void Show_1_Ratsnest(EDA_ITEM *item, wxDC *DC)
Function Show_1_Ratsnest draw ratsnest.
VIATYPE_T GetViaType() const
Definition: class_track.h:446
void Draw(EDA_DRAW_PANEL *panel, wxDC *DC, GR_DRAWMODE aDrawMode, const wxPoint &offset)
Function Draw.
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Function SetMsgPanel clears the message panel and populates it with the contents of aList...
Definition: draw_frame.cpp:754
const wxPoint & GetStart() const
Definition: class_track.h:121
void DrawGeneralRatsnest(wxDC *aDC, int aNetcode=0)
function Displays the general ratsnest Only ratsnest with the status bit CH_VISIBLE is set are displa...
Definition: ratsnest.cpp:300
void CallMouseCapture(wxDC *aDC, const wxPoint &aPosition, bool aErase)
Function CallMouseCapture calls the mouse capture callback.
D_PAD * Next() const
Definition: class_pad.h:106
MARKER_PCB * GetCurrentMarker()
Definition: drc_stuff.h:534
#define CH_VISIBLE
Definition: class_netinfo.h:57
PCB_LAYER_ID m_Route_Layer_BOTTOM
bool SetNetCode(int aNetCode, bool aNoAssert=false)
Function SetNetCode sets net using a net code.
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings returns the BOARD_DESIGN_SETTINGS for the BOARD owned by this frame...
void SetLayerPair(PCB_LAYER_ID aTopLayer, PCB_LAYER_ID aBottomLayer)
Function SetLayerPair For a via m_Layer contains the top layer, the other layer is in m_BottomLayer...
int GetNet() const
Function GetNet.
Definition: class_netinfo.h:85
void Compile_Ratsnest(wxDC *aDC, bool aDisplayStatus)
Function Compile_Ratsnest Create the entire board ratsnest.
Definition: ratsnest.cpp:165
D_PAD * m_PadStart
Definition: class_netinfo.h:75
int GetNetCode() const
Function GetNetCode.
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:105
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:92
Class NETINFO_ITEM handles the data for a net.
virtual void UpdateStatusBar() override
Function UpdateStatusBar updates the status bar information.
void SetDrill(int aDrill)
Function SetDrill sets the drill value for vias.
Definition: class_track.h:454
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:151
PCB_SCREEN * GetScreen() const override
Function GetScreen returns a pointer to a BASE_SCREEN or one of its derivatives.
int GetMicroViaDrillSize()
Function GetViaDrillSize returns the size of via drills used to route this net.
unsigned GetCount() const
Function GetCount returns the number of elements in the list.
Definition: dlist.h:126
void SetStart(const wxPoint &aStart)
Definition: class_track.h:120
int Drc(TRACK *aRefSeg, TRACK *aList)
Function Drc tests the current segment and returns the result and displays the error in the status pa...
Definition: drc.cpp:153
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:108
DLIST< D_PAD > & Pads()
Definition: class_module.h:134
Class RATSNEST_ITEM describes a ratsnest line: a straight line connecting 2 pads. ...
Definition: class_netinfo.h:68
DLIST< TRACK > m_Track
Definition: class_board.h:244
Module description (excepted pads)
int GetMicroViaSize()
Function GetMicroViaSize returns the size of vias used to route this net.
virtual void SetActiveLayer(PCB_LAYER_ID aLayer) override
Function SetActiveLayer will change the currently active layer to aLayer and also update the PCB_LAYE...
Definition: pcbframe.cpp:885
virtual PCB_LAYER_ID GetActiveLayer() const
Function GetActiveLayer returns the active layer.
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:767
bool g_TwoSegmentTrackBuild
Definition: pcbnew.cpp:76
NETINFO_ITEM * GetNet() const
Function GetNet Returns NET_INFO object for a given item.
PCB_LAYER_ID m_Route_Layer_TOP