KiCad PCB EDA Suite
class_netinfolist.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) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
28 #include <fctsys.h>
29 #include <gr_basic.h>
30 #include <common.h>
31 #include <class_drawpanel.h>
32 #include <macros.h>
33 #include <pcbnew.h>
34 
35 #include <class_board.h>
36 #include <class_module.h>
37 #include <class_pad.h>
38 #include <class_track.h>
39 #include <class_zone.h>
40 #include <class_netinfo.h>
41 
42 
43 // Constructor and destructor
44 NETINFO_LIST::NETINFO_LIST( BOARD* aParent ) : m_Parent( aParent )
45 {
46  // Make sure that the unconnected net has number 0
47  AppendNet( new NETINFO_ITEM( aParent, wxEmptyString, 0 ) );
48 
49  m_newNetCode = 0;
50 }
51 
52 
54 {
55  clear();
56 }
57 
58 
60 {
61  NETNAMES_MAP::iterator it, itEnd;
62  for( it = m_netNames.begin(), itEnd = m_netNames.end(); it != itEnd; ++it )
63  delete it->second;
64 
65  m_PadsFullList.clear();
66  m_netNames.clear();
67  m_netCodes.clear();
68  m_newNetCode = 0;
69 }
70 
71 
72 NETINFO_ITEM* NETINFO_LIST::GetNetItem( int aNetCode ) const
73 {
74  NETCODES_MAP::const_iterator result = m_netCodes.find( aNetCode );
75 
76  if( result != m_netCodes.end() )
77  return (*result).second;
78 
79  return NULL;
80 }
81 
82 
83 NETINFO_ITEM* NETINFO_LIST::GetNetItem( const wxString& aNetName ) const
84 {
85  NETNAMES_MAP::const_iterator result = m_netNames.find( aNetName );
86 
87  if( result != m_netNames.end() )
88  return (*result).second;
89 
90  return NULL;
91 }
92 
93 
95 {
96  for( NETCODES_MAP::iterator i = m_netCodes.begin(); i != m_netCodes.end(); ++i )
97  {
98  if ( i->second == aNet )
99  {
100  m_netCodes.erase(i);
101  break;
102  }
103  }
104 
105  for( NETNAMES_MAP::iterator i = m_netNames.begin(); i != m_netNames.end(); ++i )
106  {
107  if ( i->second == aNet )
108  {
109  m_netNames.erase(i);
110  break;
111  }
112  }
113 
115 }
116 
117 
119 {
120  // if there is a net with such name then just assign the correct number
121  NETINFO_ITEM* sameName = GetNetItem( aNewElement->GetNetname() );
122 
123  if( sameName != NULL )
124  {
125  aNewElement->m_NetCode = sameName->GetNet();
126 
127  return;
128  }
129  // be sure that net codes are consecutive
130  // negative net code means that it has to be auto assigned
131  else if( ( aNewElement->m_NetCode != (int) m_netCodes.size() ) || ( aNewElement->m_NetCode < 0 ) )
132  {
133  aNewElement->m_NetCode = getFreeNetCode();
134  }
135 
136  // net names & codes are supposed to be unique
137  assert( GetNetItem( aNewElement->GetNetname() ) == NULL );
138  assert( GetNetItem( aNewElement->GetNet() ) == NULL );
139 
140  // add an entry for fast look up by a net name using a map
141  m_netNames.insert( std::make_pair( aNewElement->GetNetname(), aNewElement ) );
142  m_netCodes.insert( std::make_pair( aNewElement->GetNet(), aNewElement ) );
143 }
144 
145 
146 D_PAD* NETINFO_LIST::GetPad( unsigned aIdx ) const
147 {
148  if( aIdx < m_PadsFullList.size() )
149  return m_PadsFullList[aIdx];
150  else
151  return NULL;
152 }
153 
154 
156 {
157  std::vector<D_PAD*>::iterator it = m_PadsFullList.begin();
158  std::vector<D_PAD*>::iterator end = m_PadsFullList.end();
159 
160  for( ; it != end; ++it )
161  {
162  if( *it == aPad )
163  {
164  m_PadsFullList.erase( it );
165  return true;
166  }
167  }
168  return false;
169 }
170 
171 
172 /* sort function, to sort pad list by netnames
173  * this is a case sensitive sort.
174  * DO NOT change it because NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname )
175  * when search a net by its net name does a binary search
176  * and expects to have a nets list sorted by an alphabetic case sensitive sort
177  */
178 
179 static bool padlistSortByNetnames( const D_PAD* a, const D_PAD* b )
180 {
181  return ( a->GetNetname().Cmp( b->GetNetname() ) ) < 0;
182 }
183 
184 
198 {
199  D_PAD* pad;
200  int nodes_count = 0;
201 
202  // Build the PAD list, sorted by net
204 
205  // Restore the initial state of NETINFO_ITEMs
206  for( NETINFO_LIST::iterator net( begin() ), netEnd( end() ); net != netEnd; ++net )
207  net->Clear();
208 
209  // Assign pads to appropriate NETINFO_ITEMs
210  for( unsigned ii = 0; ii < m_PadsFullList.size(); ii++ )
211  {
212  pad = m_PadsFullList[ii];
213 
214  if( pad->GetNetCode() == NETINFO_LIST::UNCONNECTED ) // pad not connected
215  continue;
216 
217  if( !( pad->GetLayerSet() & LSET::AllCuMask() ).any() )
218  // pad not a copper layer (happens when building complex shapes)
219  continue;
220 
221  // Add pad to the appropriate list of pads
222  NETINFO_ITEM* net = pad->GetNet();
223 
224  // it should not be possible for BOARD_CONNECTED_ITEM to return NULL as a result of GetNet()
225  wxASSERT( net );
226 
227  if( net )
228  net->m_PadInNetList.push_back( pad );
229 
230  ++nodes_count;
231  }
232 
233  m_Parent->SetNodeCount( nodes_count );
234 
236 
238 
240 }
241 
242 
243 #if defined(DEBUG)
244 void NETINFO_LIST::Show() const
245 {
246  int i = 0;
247  NETNAMES_MAP::const_iterator it, itEnd;
248  for( it = m_netNames.begin(), itEnd = m_netNames.end(); it != itEnd; ++it )
249  {
250  printf( "[%d]: netcode:%d netname:<%s>\n",
251  i++, it->second->GetNet(),
252  TO_UTF8( it->second->GetNetname() ) );
253  }
254 }
255 #endif
256 
257 
259 {
260  /*
261  * initialize:
262  * m_Pads (list of pads)
263  * set m_Status_Pcb = LISTE_PAD_OK;
264  * also clear m_Pcb->m_FullRatsnest that could have bad data
265  * (m_Pcb->m_FullRatsnest uses pointer to pads)
266  * Be aware NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname )
267  * when search a net by its net name does a binary search
268  * and expects to have a nets list sorted by an alphabetic case sensitive sort
269  * So do not change the sort function used here
270  */
271 
273  return;
274 
275  // empty the old list
276  m_PadsFullList.clear();
277  m_Parent->m_FullRatsnest.clear();
278 
279  // Clear variables used in ratsnest computation
280  for( MODULE* module = m_Parent->m_Modules; module; module = module->Next() )
281  {
282  for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
283  {
284  m_PadsFullList.push_back( pad );
285 
286  pad->SetSubRatsnest( 0 );
287  pad->SetParent( module );
288  }
289  }
290 
291  // Sort pad list per net
292  sort( m_PadsFullList.begin(), m_PadsFullList.end(), padlistSortByNetnames );
293 
295 }
296 
297 
299 {
300  do {
301  if( m_newNetCode < 0 )
302  m_newNetCode = 0;
303  } while( m_netCodes.count( ++m_newNetCode ) != 0 );
304 
305  return m_newNetCode;
306 }
307 
308 
309 int NETINFO_MAPPING::Translate( int aNetCode ) const
310 {
311  std::map<int, int>::const_iterator value = m_netMapping.find( aNetCode );
312 
313  if( value != m_netMapping.end() )
314  return value->second;
315 
316  // There was no entry for the given net code
317  return aNetCode;
318 }
319 
320 
322 {
323  // Collect all the used nets
324  std::set<int> nets;
325 
326  // Be sure that the unconnected gets 0 and is mapped as 0
327  nets.insert( 0 );
328 
329  // Zones
330  for( int i = 0; i < m_board->GetAreaCount(); ++i )
331  nets.insert( m_board->GetArea( i )->GetNetCode() );
332 
333  // Tracks
334  for( TRACK* track = m_board->m_Track; track; track = track->Next() )
335  nets.insert( track->GetNetCode() );
336 
337  // Modules/pads
338  for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
339  {
340  for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() )
341  {
342  nets.insert( pad->GetNetCode() );
343  }
344  }
345 
346  // Segzones
347  for( SEGZONE* zone = m_board->m_Zone; zone; zone = zone->Next() )
348  nets.insert( zone->GetNetCode() );
349 
350  // Prepare the new mapping
351  m_netMapping.clear();
352 
353  // Now the nets variable stores all the used net codes (not only for pads) and we are ready to
354  // assign new consecutive net numbers
355  int newNetCode = 0;
356  for( std::set<int>::const_iterator it = nets.begin(), itEnd = nets.end(); it != itEnd; ++it )
357  m_netMapping[*it] = newNetCode++;
358 }
359 
360 
362 {
363  return m_mapping->m_board->FindNet( m_iterator->first );
364 }
365 
366 
368 {
369  return m_mapping->m_board->FindNet( m_iterator->first );
370 }
371 
372 
373 const int NETINFO_LIST::UNCONNECTED = 0;
374 const int NETINFO_LIST::ORPHANED = -1;
375 
376 NETINFO_ITEM NETINFO_LIST::ORPHANED_ITEM = NETINFO_ITEM( NULL, wxEmptyString, NETINFO_LIST::UNCONNECTED );
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu LAYER_IDs.
Definition: lset.cpp:638
Wrapper class, so you can iterate through NETINFO_ITEM*s, not std::pair
static bool padlistSortByNetnames(const D_PAD *a, const D_PAD *b)
BOARD * m_Parent
NETINFO_ITEM * operator->() const
const BOARD * m_board
Board for which mapping is prepared
Class BOARD to handle a board.
MODULE * Next() const
Definition: class_module.h:99
NETINFO_ITEM * GetNetItem(int aNetCode) const
Function GetItem.
Classes to handle copper zones.
void buildPadsFullList()
Function buildPadsFullList creates the pad list, and initializes: m_Pads (list of pads) set m_Status_...
DLIST< SEGZONE > m_Zone
Definition: class_board.h:245
NETNAMES_MAP m_netNames
map of , is NETINFO_ITEM owner
int getFreeNetCode()
Function getFreeNetCode returns the first available net code that is not used by any other net...
D_PADS m_PadInNetList
List of pads connected to this net.
Functions relatives to tracks, vias and segments used to fill zones.
std::map< int, int > m_netMapping
Map that allows saving net codes with consecutive numbers (for compatibility reasons) ...
const NETINFO_MAPPING * m_mapping
This file contains miscellaneous commonly used macros and functions.
SEGZONE * Next() const
Definition: class_track.h:362
void AppendNet(NETINFO_ITEM *aNewElement)
Function AppendNet adds aNewElement to the end of the net list.
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
std::vector< RATSNEST_ITEM > m_FullRatsnest
Ratsnest list for the BOARD.
Definition: class_board.h:248
void SynchronizeNetsAndNetClasses()
Function SynchronizeNetsAndNetClasses copies NETCLASS info to each NET, based on NET membership in a ...
void RemoveNet(NETINFO_ITEM *aNet)
Function RemoveNet Removes a new from the net list.
int Translate(int aNetCode) const
Function Translate Translates net number according to the map prepared by Update() function...
int m_newNetCode
possible value for new net code assignment
D_PAD * GetPad(unsigned aIdx) const
Function GetPad.
LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
Definition: class_pad.h:235
D_PAD * Next() const
Definition: class_pad.h:106
bool DeletePad(D_PAD *aPad)
int m_NetCode
A number equivalent to the net name.
int SetAreasNetCodesFromNetNames(void)
Function SetAreasNetCodesFromNetNames Set the .m_NetCode member of all copper areas, according to the area Net Name The SetNetCodesFromNetNames is an equivalent to net name, for fast comparisons.
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:1051
int GetNet() const
Function GetNet.
Pad object description.
static const int ORPHANED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
int GetNetCode() const
Function GetNetCode.
Class NETINFO_ITEM handles the data for a net.
iterator begin() const
TRACK * Next() const
Definition: class_track.h:97
std::map< int, int >::const_iterator m_iterator
const wxString & GetNetname() const
Function GetNetname.
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:1022
iterator end() const
static NETINFO_ITEM ORPHANED_ITEM
NETINFO_ITEM meaning that there was no net assigned for an item, as there was no board storing net li...
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:166
DLIST< MODULE > m_Modules
Definition: class_board.h:243
NETINFO_ITEM * operator*() const
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
The common library.
void Update()
Function Update Prepares a mapping for net codes so they can be saved as consecutive numbers...
void clear()
Function clear deletes the list of nets (and free memory)
DLIST< TRACK > m_Track
Definition: class_board.h:244
Module description (excepted pads)
const wxString & GetNetname() const
Function GetNetname.
void SetNodeCount(unsigned aCount)
Function SetNodeCount set the number of nodes of the current net to aCount.
Definition: class_board.h:721
NETINFO_LIST(BOARD *aParent)
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
NETINFO_ITEM * GetNet() const
Function GetNet Returns NET_INFO object for a given item.
void buildListOfNets()
Function buildListOfNets builds or rebuilds the list of NETINFO_ITEMs The list is sorted by names...
#define min(a, b)
Definition: auxiliary.h:85
D_PADS m_PadsFullList
contains all pads, sorted by pad's netname.
int m_Status_Pcb
Flags used in ratsnest calculation and update.
Definition: class_board.h:240
NETCODES_MAP m_netCodes
map of is NOT owner