KiCad PCB EDA Suite
netinfo_list.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-2021 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 
24 #include <board.h>
25 #include <footprint.h>
26 #include <macros.h>
27 #include <pad.h>
28 #include <pcb_track.h>
29 #include <zone.h>
30 #include <netinfo.h>
31 #include <wx/log.h>
32 
33 
34 // Constructor and destructor
36  m_parent( aParent )
37 {
38  // Make sure that the unconnected net has number 0
39  AppendNet( new NETINFO_ITEM( aParent, wxEmptyString, 0 ) );
40 
41  m_newNetCode = 0;
42 }
43 
44 
46 {
47  clear();
48 }
49 
50 
52 {
53  NETNAMES_MAP::iterator it, itEnd;
54  for( it = m_netNames.begin(), itEnd = m_netNames.end(); it != itEnd; ++it )
55  delete it->second;
56 
57  m_netNames.clear();
58  m_netCodes.clear();
59  m_newNetCode = 0;
60 }
61 
62 
63 NETINFO_ITEM* NETINFO_LIST::GetNetItem( int aNetCode ) const
64 {
65  NETCODES_MAP::const_iterator result = m_netCodes.find( aNetCode );
66 
67  if( result != m_netCodes.end() )
68  return (*result).second;
69 
70  return nullptr;
71 }
72 
73 
74 NETINFO_ITEM* NETINFO_LIST::GetNetItem( const wxString& aNetName ) const
75 {
76  NETNAMES_MAP::const_iterator result = m_netNames.find( aNetName );
77 
78  if( result != m_netNames.end() )
79  return (*result).second;
80 
81  return nullptr;
82 }
83 
84 
86 {
87  bool removed = false;
88 
89  for( NETCODES_MAP::iterator i = m_netCodes.begin(); i != m_netCodes.end(); ++i )
90  {
91  if ( i->second == aNet )
92  {
93  removed = true;
94  m_netCodes.erase(i);
95  break;
96  }
97  }
98 
99  for( NETNAMES_MAP::iterator i = m_netNames.begin(); i != m_netNames.end(); ++i )
100  {
101  if ( i->second == aNet )
102  {
103  wxASSERT_MSG( removed, "NETINFO_LIST::RemoveNet: target net found in m_netNames "
104  "but not m_netCodes!" );
105  m_netNames.erase(i);
106  break;
107  }
108  }
109 
110  if( removed )
111  m_newNetCode = std::min( m_newNetCode, aNet->m_netCode - 1 );
112 }
113 
114 
116 {
117  NETCODES_MAP existingNets = m_netCodes;
118 
119  m_netCodes.clear();
120  m_netNames.clear();
121 
122  for( std::pair<const int, NETINFO_ITEM*> item : existingNets )
123  {
124  if( item.second->IsCurrent() )
125  {
126  m_netNames.insert( std::make_pair( item.second->GetNetname(), item.second ) );
127  m_netCodes.insert( std::make_pair( item.first, item.second ) );
128  }
129  }
130 }
131 
132 
134 {
135  // if there is a net with such name then just assign the correct number
136  NETINFO_ITEM* sameName = GetNetItem( aNewElement->GetNetname() );
137 
138  if( sameName != nullptr )
139  {
140  aNewElement->m_netCode = sameName->GetNetCode();
141 
142  return;
143  }
144  else if( aNewElement->m_netCode != (int) m_netCodes.size() || aNewElement->m_netCode < 0 )
145  {
146  // be sure that net codes are consecutive
147  // negative net code means that it has to be auto assigned
148  aNewElement->m_netCode = getFreeNetCode();
149  }
150 
151  // net names & codes are supposed to be unique
152  assert( GetNetItem( aNewElement->GetNetname() ) == nullptr );
153  assert( GetNetItem( aNewElement->GetNetCode() ) == nullptr );
154 
155  // add an entry for fast look up by a net name using a map
156  m_netNames.insert( std::make_pair( aNewElement->GetNetname(), aNewElement ) );
157  m_netCodes.insert( std::make_pair( aNewElement->GetNetCode(), aNewElement ) );
158 }
159 
160 
162 {
163  // Restore the initial state of NETINFO_ITEMs
164  for( NETINFO_ITEM* net : *this )
165  net->Clear();
166 
169 }
170 
171 
172 #if defined(DEBUG)
173 void NETINFO_LIST::Show() const
174 {
175  int i = 0;
176  NETNAMES_MAP::const_iterator it, itEnd;
177 
178  for( it = m_netNames.begin(), itEnd = m_netNames.end(); it != itEnd; ++it )
179  {
180  wxLogDebug( "[%d]: netcode:%d netname:<%s>\n",
181  i++,
182  it->second->GetNetCode(),
183  TO_UTF8( it->second->GetNetname() ) );
184  }
185 }
186 #endif
187 
188 
190 {
191  do
192  {
193  if( m_newNetCode < 0 )
194  m_newNetCode = 0;
195  } while( m_netCodes.count( ++m_newNetCode ) != 0 );
196 
197  return m_newNetCode;
198 }
199 
200 
201 int NETINFO_MAPPING::Translate( int aNetCode ) const
202 {
203  std::map<int, int>::const_iterator value = m_netMapping.find( aNetCode );
204 
205  if( value != m_netMapping.end() )
206  return value->second;
207 
208  // There was no entry for the given net code
209  return aNetCode;
210 }
211 
212 
214 {
215  // Collect all the used nets
216  std::set<int> nets;
217 
218  // Be sure that the unconnected gets 0 and is mapped as 0
219  nets.insert( 0 );
220 
221  // Zones
222  for( ZONE* zone : m_board->Zones() )
223  nets.insert( zone->GetNetCode() );
224 
225  // Tracks
226  for( PCB_TRACK* track : m_board->Tracks() )
227  nets.insert( track->GetNetCode() );
228 
229  // footprints/pads
230  for( FOOTPRINT* footprint : m_board->Footprints() )
231  {
232  for( PAD* pad : footprint->Pads() )
233  nets.insert( pad->GetNetCode() );
234  }
235 
236  // Prepare the new mapping
237  m_netMapping.clear();
238 
239  // Now the nets variable stores all the used net codes (not only for pads) and we are ready to
240  // assign new consecutive net numbers
241  int newNetCode = 0;
242 
243  for( auto net : nets )
244  m_netMapping[net] = newNetCode++;
245 }
246 
247 
249 {
250  return m_mapping->m_board->FindNet( m_iterator->first );
251 }
252 
253 
255 {
256  return m_mapping->m_board->FindNet( m_iterator->first );
257 }
258 
259 
260 const int NETINFO_LIST::UNCONNECTED = 0;
261 const int NETINFO_LIST::ORPHANED = -1;
262 
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition: board.cpp:1325
ZONES & Zones()
Definition: board.h:239
const BOARD * m_board
Board for which mapping is prepared.
Definition: netinfo.h:293
NETNAMES_MAP m_netNames
map of <wxString, NETINFO_ITEM*>, is NETINFO_ITEM owner
Definition: netinfo.h:472
void RemoveUnusedNets()
int getFreeNetCode()
Return the first available net code that is not used by any other net.
std::map< int, int > m_netMapping
Map that allows saving net codes with consecutive numbers (for compatibility reasons)
Definition: netinfo.h:294
const NETINFO_MAPPING * m_mapping
Definition: netinfo.h:259
This file contains miscellaneous commonly used macros and functions.
BOARD * m_parent
Definition: netinfo.h:470
void AppendNet(NETINFO_ITEM *aNewElement)
Add aNewElement to the end of the net list.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
void SynchronizeNetsAndNetClasses()
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition: board.cpp:1391
void RemoveNet(NETINFO_ITEM *aNet)
Remove a net from the net list.
NETINFO_ITEM * operator->() const
FOOTPRINTS & Footprints()
Definition: board.h:233
int m_netCode
A number equivalent to the net name.
Definition: netinfo.h:167
int m_newNetCode
possible value for new net code assignment
Definition: netinfo.h:475
const wxString & GetNetname() const
Definition: netinfo.h:119
Handle a list of polygons defining a copper zone.
Definition: zone.h:56
int SetAreasNetCodesFromNetNames()
Set the .m_NetCode member of all copper areas, according to the area Net Name The SetNetCodesFromNetN...
Definition: board.cpp:1424
static const int ORPHANED
NETINFO_ITEM meaning that there was no net assigned for an item, as there was no board storing net li...
Definition: netinfo.h:369
Handle the data for a net.
Definition: netinfo.h:64
void Clear()
Set all fields to their default values.
Definition: netinfo.h:154
std::map< int, int >::const_iterator m_iterator
Definition: netinfo.h:258
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
NETINFO_ITEM * operator *() const
void Update()
Prepare a mapping for net codes so they can be saved as consecutive numbers.
void clear()
Delete the list of nets (and free memory).
NETINFO_LIST(BOARD *aParent)
Definition: pad.h:57
NETINFO_ITEM * GetNetItem(int aNetCode) const
static const int UNCONNECTED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
Definition: netinfo.h:365
TRACKS & Tracks()
Definition: board.h:230
void buildListOfNets()
Rebuild the list of NETINFO_ITEMs.
int Translate(int aNetCode) const
Translate net number according to the map prepared by Update() function.
NETCODES_MAP m_netCodes
map of <int, NETINFO_ITEM*> is NOT owner
Definition: netinfo.h:473
int GetNetCode() const
Definition: netinfo.h:113