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 }
#define g_FirstTrackSegment
first segment created
Definition: pcbnew.h:101
#define g_CurrentTrackSegment
most recently created segment
Definition: pcbnew.h:100
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:440
void SetPosition(const wxPoint &aPoint) override
Definition: class_track.h:412
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.
void SetCurItem(BOARD_ITEM *aItem, bool aDisplayInfo=true)
Function SetCurItem sets the currently selected item and displays it in the MsgPanel.
virtual EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
BOARD * GetBoard() const
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:99
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
Markers used to show a drc problem on boards.
PCB_LAYER_ID
A quick note on layer IDs:
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:253
VIATYPE_T GetViaType() const
Definition: class_track.h:439
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:773
const wxPoint & GetStart() const
Definition: class_track.h:121
void CallMouseCapture(wxDC *aDC, const wxPoint &aPosition, bool aErase)
Function CallMouseCapture calls the mouse capture callback.
MARKER_PCB * GetCurrentMarker()
Definition: drc_stuff.h:534
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...
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:92
Class NETINFO_ITEM handles the data for a net.
Definition: class_netinfo.h:69
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:447
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:155
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:108
DLIST< TRACK > m_Track
Definition: class_board.h:246
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:882
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