KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 The 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 "netinfo.h"
25
26#include <wx/log.h>
27
28#include <board.h>
29#include <board_commit.h>
30#include <footprint.h>
31#include <macros.h>
32#include <pad.h>
33#include <pcb_shape.h>
34#include <pcb_track.h>
35#include <string_utils.h>
36#include <zone.h>
37
38
39// Constructor and destructor
41 m_parent( aParent ),
42 m_newNetCode( 0 )
43{
44 // Make sure that the unconnected net has number 0
45 AppendNet( new NETINFO_ITEM( aParent, wxEmptyString, 0 ) );
46}
47
48
53
54
56{
57 NETNAMES_MAP::iterator it, itEnd;
58
59 for( it = m_netNames.begin(), itEnd = m_netNames.end(); it != itEnd; ++it )
60 delete it->second;
61
62 m_netNames.clear();
63 m_netCodes.clear();
64 m_newNetCode = 0;
65}
66
67
69{
70 NETCODES_MAP::const_iterator result = m_netCodes.find( aNetCode );
71
72 if( result != m_netCodes.end() )
73 return (*result).second;
74
75 return nullptr;
76}
77
78
79NETINFO_ITEM* NETINFO_LIST::GetNetItem( const wxString& aNetName ) const
80{
81 NETNAMES_MAP::const_iterator result = m_netNames.find( aNetName );
82
83 if( result != m_netNames.end() )
84 return (*result).second;
85
86 return nullptr;
87}
88
89
91{
92 bool removed = false;
93
94 for( NETCODES_MAP::iterator i = m_netCodes.begin(); i != m_netCodes.end(); ++i )
95 {
96 if ( i->second == aNet )
97 {
98 removed = true;
99 m_netCodes.erase(i);
100 break;
101 }
102 }
103
104 for( NETNAMES_MAP::iterator i = m_netNames.begin(); i != m_netNames.end(); ++i )
105 {
106 if ( i->second == aNet )
107 {
108 wxASSERT_MSG( removed, wxT( "NETINFO_LIST::RemoveNet: target net found in m_netNames "
109 "but not m_netCodes!" ) );
110 m_netNames.erase(i);
111 break;
112 }
113 }
114
115 if( removed )
116 {
117 m_newNetCode = std::min( m_newNetCode, aNet->m_netCode - 1 );
119 }
120}
121
122
124{
125 NETCODES_MAP existingNets = m_netCodes;
126 std::vector<NETINFO_ITEM*> unusedNets;
127
128 m_netCodes.clear();
129 m_netNames.clear();
130
131 for( const auto& [ netCode, netInfo ] : existingNets )
132 {
133 if( netInfo->IsCurrent() )
134 {
135 m_netNames.insert( std::make_pair( netInfo->GetNetname(), netInfo ) );
136 m_netCodes.insert( std::make_pair( netCode, netInfo ) );
137 }
138 else
139 {
141
142 if( aCommit )
143 aCommit->Removed( netInfo );
144 }
145 }
146}
147
148
150{
151 // if there is a net with such name then just assign the correct number
152 NETINFO_ITEM* sameName = GetNetItem( aNewElement->GetNetname() );
153
154 if( sameName != nullptr )
155 {
156 aNewElement->m_netCode = sameName->GetNetCode();
157
158 return;
159 }
160 else if( aNewElement->m_netCode != (int) m_netCodes.size() || aNewElement->m_netCode < 0 )
161 {
162 // be sure that net codes are consecutive
163 // negative net code means that it has to be auto assigned
164 aNewElement->m_netCode = getFreeNetCode();
165 }
166
167 // net names & codes are supposed to be unique
168 assert( GetNetItem( aNewElement->GetNetname() ) == nullptr );
169 assert( GetNetItem( aNewElement->GetNetCode() ) == nullptr );
170
171 // add an entry for fast look up by a net name using a map
172 m_netNames.insert( std::make_pair( aNewElement->GetNetname(), aNewElement ) );
173 m_netCodes.insert( std::make_pair( aNewElement->GetNetCode(), aNewElement ) );
174
176}
177
178
180{
181 // Restore the initial state of NETINFO_ITEMs
182 for( NETINFO_ITEM* net : *this )
183 net->Clear();
184
185 m_parent->SynchronizeNetsAndNetClasses( false );
186 m_parent->SetAreasNetCodesFromNetNames();
187}
188
189
191{
192 std::map<wxString, std::vector<wxString>> shortNameMap;
193
194 for( NETINFO_ITEM* net : *this )
195 shortNameMap[net->m_shortNetname].push_back( net->m_netname );
196
197 for( NETINFO_ITEM* net : *this )
198 {
199 if( shortNameMap[net->m_shortNetname].size() == 1 )
200 {
202 }
203 else
204 {
205 wxArrayString parts = wxSplit( net->m_netname, '/' );
206 std::vector<wxArrayString> aggregateParts;
207 std::optional<size_t> firstNonCommon;
208
209 for( const wxString& longName : shortNameMap[net->m_shortNetname] )
210 aggregateParts.push_back( wxSplit( longName, '/' ) );
211
212 for( size_t ii = 0; ii < parts.size() && !firstNonCommon; ++ii )
213 {
214 for( const wxArrayString& otherParts : aggregateParts )
215 {
216 if( ii < otherParts.size() && otherParts[ii] == parts[ii] )
217 continue;
218
219 firstNonCommon = ii;
220 break;
221 }
222 }
223
224 if( firstNonCommon.value_or( 0 ) > 0 && firstNonCommon.value() < parts.size() )
225 {
226 wxString disambiguatedName;
227
228 for( size_t ii = firstNonCommon.value(); ii < parts.size(); ++ii )
229 {
230 if( !disambiguatedName.IsEmpty() )
231 disambiguatedName += wxS( "/" );
232
233 disambiguatedName += parts[ii];
234 }
235
236 net->m_displayNetname = UnescapeString( disambiguatedName );
237 }
238 else
239 {
241 }
242 }
243 }
244
246}
247
248
249#if defined(DEBUG)
250void NETINFO_LIST::Show() const
251{
252 int i = 0;
253 NETNAMES_MAP::const_iterator it, itEnd;
254
255 for( it = m_netNames.begin(), itEnd = m_netNames.end(); it != itEnd; ++it )
256 {
257 wxLogDebug( wxT( "[%d]: netcode:%d netname:<%s>\n" ),
258 i++,
259 it->second->GetNetCode(),
260 TO_UTF8( it->second->GetNetname() ) );
261 }
262}
263#endif
264
265
267{
268 do
269 {
270 if( m_newNetCode < 0 )
271 m_newNetCode = 0;
272 } while( m_netCodes.count( ++m_newNetCode ) != 0 );
273
274 return m_newNetCode;
275}
276
277
278int NETINFO_MAPPING::Translate( int aNetCode ) const
279{
280 std::map<int, int>::const_iterator value = m_netMapping.find( aNetCode );
281
282 if( value != m_netMapping.end() )
283 return value->second;
284
285 // There was no entry for the given net code
286 return aNetCode;
287}
288
289
291{
292 // Collect all the used nets
293 std::set<int> nets;
294
295 // Be sure that the unconnected gets 0 and is mapped as 0
296 nets.insert( 0 );
297
298 // Zones
299 for( ZONE* zone : m_board->Zones() )
300 nets.insert( zone->GetNetCode() );
301
302 // Tracks
303 for( PCB_TRACK* track : m_board->Tracks() )
304 nets.insert( track->GetNetCode() );
305
306 for( BOARD_ITEM* item : m_board->Drawings() )
307 {
308 if( item->Type() != PCB_SHAPE_T )
309 continue;
310
311 PCB_SHAPE* shape = static_cast<PCB_SHAPE*>( item );
312
313 if( shape->GetNetCode() > 0 )
314 nets.insert( shape->GetNetCode() );
315 }
316
317 // footprints/pads
318 for( FOOTPRINT* footprint : m_board->Footprints() )
319 {
320 for( PAD* pad : footprint->Pads() )
321 nets.insert( pad->GetNetCode() );
322 }
323
324 // Prepare the new mapping
325 m_netMapping.clear();
326
327 // Now the nets variable stores all the used net codes (not only for pads) and we are ready to
328 // assign new consecutive net numbers
329 int newNetCode = 0;
330
331 for( auto net : nets )
332 m_netMapping[net] = newNetCode++;
333}
334
335
337{
338 return m_mapping->m_board->FindNet( m_iterator->first );
339}
340
341
343{
344 return m_mapping->m_board->FindNet( m_iterator->first );
345}
346
347
348const int NETINFO_LIST::UNCONNECTED = 0;
349const int NETINFO_LIST::ORPHANED = -1;
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:79
COMMIT & Removed(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Definition commit.h:96
Handle the data for a net.
Definition netinfo.h:54
wxString m_shortNetname
Short net name, like vout from /sheet/subsheet/vout.
Definition netinfo.h:178
wxString m_displayNetname
Unescaped netname for display.
Definition netinfo.h:180
const wxString & GetNetname() const
Definition netinfo.h:112
void Clear()
Set all fields to their default values.
int GetNetCode() const
Definition netinfo.h:106
int m_netCode
A number equivalent to the net name.
Definition netinfo.h:176
wxString m_netname
Full net name like /sheet/subsheet/vout used by Eeschema.
Definition netinfo.h:177
int getFreeNetCode()
Return the first available net code that is not used by any other net.
void RemoveUnusedNets(BOARD_COMMIT *aCommit)
friend class BOARD
Definition netinfo.h:331
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition netinfo.h:365
NETCODES_MAP m_netCodes
map of <int, NETINFO_ITEM*> is NOT owner
Definition netinfo.h:490
static const int ORPHANED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
Definition netinfo.h:369
int m_newNetCode
possible value for new net code assignment
Definition netinfo.h:492
void RemoveNet(NETINFO_ITEM *aNet)
Remove a net from the net list.
BOARD * m_parent
Definition netinfo.h:487
NETINFO_ITEM * GetNetItem(int aNetCode) const
NETINFO_LIST(BOARD *aParent)
void clear()
Delete the list of nets (and free memory).
NETNAMES_MAP m_netNames
map of <wxString, NETINFO_ITEM*>, is NETINFO_ITEM owner
Definition netinfo.h:489
void AppendNet(NETINFO_ITEM *aNewElement)
Add aNewElement to the end of the net list.
bool m_DisplayNetnamesDirty
Definition netinfo.h:484
void RebuildDisplayNetnames() const
void buildListOfNets()
Rebuild the list of NETINFO_ITEMs.
NETINFO_ITEM * operator->() const
const NETINFO_MAPPING * m_mapping
Definition netinfo.h:273
std::map< int, int >::const_iterator m_iterator
Definition netinfo.h:272
NETINFO_ITEM * operator*() const
int Translate(int aNetCode) const
Translate net number according to the map prepared by Update() function.
void Update()
Prepare a mapping for net codes so they can be saved as consecutive numbers.
const BOARD * m_board
Board for which mapping is prepared.
Definition netinfo.h:307
std::map< int, int > m_netMapping
Map that allows saving net codes with consecutive numbers (for compatibility reasons)
Definition netinfo.h:308
Definition pad.h:54
Handle a list of polygons defining a copper zone.
Definition zone.h:74
This file contains miscellaneous commonly used macros and functions.
wxString UnescapeString(const wxString &aSource)
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
wxString result
Test unit parsing edge cases and error handling.
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition typeinfo.h:88