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