KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_netlist_utils.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
12#include "pcb_netlist_utils.h"
13
14#include <board.h>
16#include <footprint.h>
18#include <lib_id.h>
19#include <netlist_reader/netlist_reader.h>
21#include <project_pcb.h>
22#include <reporter.h>
23
24
25FOOTPRINT* LoadFootprintFromProject( BOARD* aBoard, const LIB_ID& aFootprintId, bool aKeepUuid )
26{
27 FOOTPRINT* footprint = nullptr;
28
29 try
30 {
31 FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( nullptr /* ignored */ );
32 footprint = adapter->LoadFootprintWithOptionalNickname( aFootprintId, aKeepUuid );
33 }
34 catch( const IO_ERROR& )
35 {
36 }
37
38 if( footprint )
39 {
40 // If the footprint is found, clear all net info to be sure there are no broken links to
41 // any netinfo list (should be not needed, but it can be edited from the footprint editor )
42 footprint->ClearAllNets();
43
44 if( aBoard && !aBoard->IsFootprintHolder() )
45 {
47
48 footprint->ApplyDefaultSettings( *aBoard, bds.m_StyleFPFields, bds.m_StyleFPText,
51 }
52 }
53
54 return footprint;
55}
56
57
58void LoadNetlistFootprints( BOARD* aBoard, NETLIST& aNetlist, REPORTER& aReporter )
59{
60 wxString msg;
61 LIB_ID lastFPID;
62 COMPONENT* component;
63 FOOTPRINT* footprint = nullptr;
64 FOOTPRINT* fpOnBoard = nullptr;
65
66 FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( nullptr /* ignored */ );
67
68 if( aNetlist.IsEmpty() || adapter->Rows().empty() )
69 return;
70
71 // Make sure the libraries are loaded before we start loading the footprints.
72 adapter->AsyncLoad();
73 adapter->BlockUntilLoaded();
74
75 aNetlist.SortByFPID();
76
77 for( unsigned ii = 0; ii < aNetlist.GetCount(); ii++ )
78 {
79 component = aNetlist.GetComponent( ii );
80
81 if( !component->GetFPID().GetLibItemName().size() )
82 {
83 msg.Printf( _( "No footprint defined for symbol %s." ), component->GetReference() );
84 aReporter.Report( msg, RPT_SEVERITY_ERROR );
85 continue;
86 }
87
88 if( aNetlist.IsFindByTimeStamp() )
89 {
90 for( const KIID& uuid : component->GetKIIDs() )
91 {
92 KIID_PATH path = component->GetPath();
93 path.push_back( uuid );
94
95 if( ( fpOnBoard = aBoard->FindFootprintByPath( path ) ) != nullptr )
96 break;
97 }
98 }
99 else
100 {
101 fpOnBoard = aBoard->FindFootprintByReference( component->GetReference() );
102 }
103
104 bool footprintMisMatch = false;
105
106 if( fpOnBoard )
107 {
108 if( component->GetFPID().IsLegacy() )
109 {
110 footprintMisMatch = fpOnBoard->GetFPID().GetLibItemName()
111 != component->GetFPID().GetLibItemName();
112 }
113 else
114 {
115 footprintMisMatch = fpOnBoard->GetFPID() != component->GetFPID();
116 }
117 }
118
119 if( footprintMisMatch && !aNetlist.GetReplaceFootprints() )
120 {
121 msg.Printf( _( "Footprint of %s changed: board footprint '%s', netlist footprint '%s'." ),
122 component->GetReference(),
123 fpOnBoard->GetFPID().Format().wx_str(),
124 component->GetFPID().Format().wx_str() );
125 aReporter.Report( msg, RPT_SEVERITY_WARNING );
126 continue;
127 }
128
129 if( !aNetlist.GetReplaceFootprints() )
130 footprintMisMatch = false;
131
132 if( fpOnBoard && !footprintMisMatch )
133 continue;
134
135 if( component->GetFPID() != lastFPID )
136 {
137 footprint = nullptr;
138
139 if( !component->GetFPID().GetLibItemName().size() )
140 {
141 msg.Printf( _( "%s footprint ID '%s' is not valid." ),
142 component->GetReference(),
143 component->GetFPID().Format().wx_str() );
144 aReporter.Report( msg, RPT_SEVERITY_ERROR );
145 continue;
146 }
147
148 footprint = LoadFootprintFromProject( aBoard, component->GetFPID() );
149
150 if( footprint )
151 {
152 lastFPID = component->GetFPID();
153 }
154 else
155 {
156 msg.Printf( _( "%s footprint '%s' not found in any libraries in the footprint "
157 "library table." ),
158 component->GetReference(),
159 component->GetFPID().GetLibItemName().wx_str() );
160 aReporter.Report( msg, RPT_SEVERITY_ERROR );
161 continue;
162 }
163 }
164 else
165 {
166 if( !footprint )
167 continue;
168
169 footprint = new FOOTPRINT( *footprint );
170 footprint->ResetUuidDirect();
171 }
172
173 if( footprint )
174 component->SetFootprint( footprint );
175 }
176}
Container for design settings for a BOARD object.
void ResetUuidDirect()
Definition board_item.h:242
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:372
bool IsFootprintHolder() const
Find out if the board is being used to hold a single footprint for editing/viewing.
Definition board.h:402
FOOTPRINT * FindFootprintByPath(const KIID_PATH &aPath) const
Search for a FOOTPRINT within this board with the given path.
Definition board.cpp:2751
FOOTPRINT * FindFootprintByReference(const wxString &aReference) const
Search for a FOOTPRINT within this board with the given reference designator.
Definition board.cpp:2739
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition board.cpp:1149
Store all of the related component information found in a netlist.
const KIID_PATH & GetPath() const
const wxString & GetReference() const
void SetFootprint(FOOTPRINT *aFootprint)
const std::vector< KIID > & GetKIIDs() const
const LIB_ID & GetFPID() const
An interface to the global shared library manager that is schematic-specific and linked to one projec...
FOOTPRINT * LoadFootprintWithOptionalNickname(const LIB_ID &aFootprintId, bool aKeepUUID)
Load a footprint having aFootprintId with possibly an empty nickname.
const LIB_ID & GetFPID() const
Definition footprint.h:441
void ApplyDefaultSettings(const BOARD &board, bool aStyleFields, bool aStyleText, bool aStyleShapes, bool aStyleDimensions, bool aStyleBarcodes)
Apply default board settings to the footprint field text properties.
void ClearAllNets()
Clear (i.e.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition kiid.h:44
std::vector< LIBRARY_TABLE_ROW * > Rows(LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH, bool aIncludeInvalid=false) const
Like LIBRARY_MANAGER::Rows but filtered to the LIBRARY_TABLE_TYPE of this adapter.
void AsyncLoad()
Loads all available libraries for this adapter type in the background.
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
UTF8 Format() const
Definition lib_id.cpp:115
const UTF8 & GetLibItemName() const
Definition lib_id.h:98
bool IsLegacy() const
Definition lib_id.h:176
Store information read from a netlist along with the flags used to update the NETLIST in the BOARD.
bool GetReplaceFootprints() const
unsigned GetCount() const
COMPONENT * GetComponent(unsigned aIndex)
Return the COMPONENT at aIndex.
bool IsFindByTimeStamp() const
static FOOTPRINT_LIBRARY_ADAPTER * FootprintLibAdapter(PROJECT *aProject)
A pure virtual class used to derive REPORTER objects from.
Definition reporter.h:71
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
Definition reporter.h:100
std::string::size_type size() const
Definition utf8.h:112
wxString wx_str() const
Definition utf8.cpp:41
#define _(s)
void LoadNetlistFootprints(BOARD *aBoard, NETLIST &aNetlist, REPORTER &aReporter)
Load the footprints for each #SCH_COMPONENT in aNetlist from the list of libraries.
FOOTPRINT * LoadFootprintFromProject(BOARD *aBoard, const LIB_ID &aFootprintId, bool aKeepUuid)
Load a footprint from the project library table and apply board default settings.
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
std::string path