KiCad PCB EDA Suite
Loading...
Searching...
No Matches
board_loader.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 * @author Jon Evans <[email protected]>
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21#include <board_loader.h>
22
23#include <base_screen.h>
24#include <board.h>
27#include <drc/drc_engine.h>
28#include <filename_resolver.h>
29#include <ki_exception.h>
30#include <pcb_marker.h>
31#include <pgm_base.h>
32#include <project.h>
34#include <properties/property.h>
35#include <reporter.h>
37#include <unordered_set>
38#include <wx/image.h>
39#include <wx/log.h>
40
41
42std::unique_ptr<BOARD> BOARD_LOADER::Load( const wxString& aFileName,
44 PROJECT* aProject,
45 const OPTIONS& aOptions )
46{
47 if( !aProject || aFormat == PCB_IO_MGR::FILE_TYPE_NONE )
48 return nullptr;
49
50 // TODO(JE) need to factor out for MDI
52
53 BOARD* loaded = nullptr;
54
55 if( aOptions.plugin_configurator || aOptions.reporter || aOptions.post_load_hook )
56 {
58
59 if( !pi )
60 return nullptr;
61
62 if( aOptions.plugin_configurator )
63 aOptions.plugin_configurator( *pi );
64
65 if( aOptions.reporter )
66 pi->SetReporter( aOptions.reporter );
67
68 pi->SetProgressReporter( aOptions.progress_reporter );
69
70 // own the board first so a throwing hook can't leak it
71 std::unique_ptr<BOARD> boardOwner(
72 pi->LoadBoard( aFileName, nullptr, aOptions.properties, aProject ) );
73
74 // grab cached lib footprints while the plugin is alive
75 if( boardOwner && aOptions.post_load_hook )
76 aOptions.post_load_hook( *pi );
77
78 loaded = boardOwner.release();
79 }
80 else
81 {
82 loaded = PCB_IO_MGR::Load( aFormat, aFileName, nullptr, aOptions.properties,
83 aProject, aOptions.progress_reporter );
84 }
85
86 std::unique_ptr<BOARD> board( loaded );
87
88 if( !board )
89 return nullptr;
90
91 if( aOptions.initialize_after_load )
92 initializeLoadedBoard( board.get(), aFileName, aProject, aOptions );
93
94 return board;
95}
96
97
98std::unique_ptr<BOARD> BOARD_LOADER::Load( const wxString& aFileName,
100 PROJECT* aProject )
101{
102 return Load( aFileName, aFormat, aProject, OPTIONS{} );
103}
104
105
106void BOARD_LOADER::initializeLoadedBoard( BOARD* aBoard, const wxString& aFileName,
107 PROJECT* aProject, const OPTIONS& aOptions )
108{
109 if( !aBoard || !aProject )
110 return;
111
113 resolver.SetProject( aProject );
114 resolver.SetProgramBase( PgmOrNull() );
115
116 wxString filename = resolver.ResolvePath( BASE_SCREEN::m_DrawingSheetFileName,
117 aProject->GetProjectPath(),
118 { aBoard->GetEmbeddedFiles() } );
119
120 wxString msg;
121
122 if( !DS_DATA_MODEL::GetTheInstance().LoadDrawingSheet( filename, &msg ) )
123 {
124 if( aOptions.drawing_sheet_error_callback )
126 }
127
129
130 layerEnum.Choices().Clear();
131 layerEnum.Undefined( UNDEFINED_LAYER );
132
133 for( PCB_LAYER_ID layer : LSET::AllLayersMask() )
134 {
135 layerEnum.Map( layer, LSET::Name( layer ) );
136 layerEnum.Map( layer, aBoard->GetLayerName( layer ) );
137 }
138
139 aBoard->SetProject( aProject );
140
142 bds.m_DRCEngine = std::make_shared<DRC_ENGINE>( aBoard, &bds );
143
144 try
145 {
146 wxFileName rules = aFileName;
147 rules.SetExt( FILEEXT::DesignRulesFileExtension );
148 bds.m_DRCEngine->InitEngine( rules );
149 }
150 catch( ... )
151 {
152 // Only matters if user tries to run DRC later; will be reported at that time
153 }
154
155 for( PCB_MARKER* marker : aBoard->ResolveDRCExclusions( true ) )
156 aBoard->Add( marker );
157
158 aBoard->BuildConnectivity();
159 aBoard->BuildListOfNets();
160 aBoard->SynchronizeNetsAndNetClasses( true );
161
162 // Apply component class assignment rules from the project. Without this, conditions like
163 // A.hasComponentClass('Inductor') in custom DRC rules never match because no footprints
164 // have any dynamic component class assigned. The interactive load path does this in
165 // PCB_EDIT_FRAME::OpenProjectFiles; CLI and API consumers go through here.
166 if( !aBoard->SynchronizeComponentClasses( std::unordered_set<wxString>() )
167 && aOptions.reporter )
168 {
169 aOptions.reporter->Report( _( "Could not load component class assignment rules" ),
171 }
172
174
175 aBoard->UpdateUserUnits( aBoard, nullptr );
176}
177
178
179std::unique_ptr<BOARD> BOARD_LOADER::CreateEmptyBoard( PROJECT* aProject )
180{
181 std::unique_ptr<BOARD> brd = std::make_unique<BOARD>();
182 brd->SetProject( aProject );
183 return brd;
184}
185
186
187bool BOARD_LOADER::SaveBoard( wxString& aFileName, BOARD* aBoard, PCB_IO_MGR::PCB_FILE_T aFormat )
188{
189 aBoard->BuildConnectivity();
190 aBoard->SynchronizeNetsAndNetClasses( false );
191
192 try
193 {
194 PCB_IO_MGR::Save( aFormat, aFileName, aBoard, nullptr );
195 }
196 catch( const IO_ERROR& ioe )
197 {
198 wxLogError( _( "Cannot save board '%s': %s" ), aFileName, ioe.What() );
199 return false;
200 }
201 catch( const std::exception& e )
202 {
203 // Rethrow so std::bad_alloc and similar aren't silently turned into a false return.
204 wxLogError( _( "Unexpected error saving board '%s': %s" ), aFileName,
205 wxString::FromUTF8( e.what() ) );
206 throw;
207 }
208
209 return true;
210}
211
212
213bool BOARD_LOADER::SaveBoard( wxString& aFileName, BOARD* aBoard )
214{
215 return SaveBoard( aFileName, aBoard, PCB_IO_MGR::KICAD_SEXP );
216}
BASE_SCREEN class implementation.
static wxString m_DrawingSheetFileName
the name of the drawing sheet file, or empty to use the default drawing sheet
Definition base_screen.h:81
Container for design settings for a BOARD object.
std::shared_ptr< DRC_ENGINE > m_DRCEngine
static std::unique_ptr< BOARD > CreateEmptyBoard(PROJECT *aProject)
static std::unique_ptr< BOARD > Load(const wxString &aFileName, PCB_IO_MGR::PCB_FILE_T aFormat, PROJECT *aProject, const OPTIONS &aOptions)
static void initializeLoadedBoard(BOARD *aBoard, const wxString &aFileName, PROJECT *aProject, const OPTIONS &aOptions)
static bool SaveBoard(wxString &aFileName, BOARD *aBoard, PCB_IO_MGR::PCB_FILE_T aFormat)
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:373
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1355
void BuildListOfNets()
Definition board.h:1061
void UpdateUserUnits(BOARD_ITEM *aItem, KIGFX::VIEW *aView)
Update any references within aItem (or its descendants) to the user units.
Definition board.cpp:1830
bool BuildConnectivity(PROGRESS_REPORTER *aReporter=nullptr)
Build or rebuild the board connectivity database for the board, especially the list of connected item...
Definition board.cpp:202
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition board.cpp:3164
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition board.cpp:212
std::vector< PCB_MARKER * > ResolveDRCExclusions(bool aCreateMarkers)
Rebuild DRC markers from the serialized data in BOARD_DESIGN_SETTINGS.
Definition board.cpp:454
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition board.cpp:802
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition board.cpp:1158
bool SynchronizeComponentClasses(const std::unordered_set< wxString > &aNewSheetPaths) const
Copy component class / component class generator information from the project settings.
Definition board.cpp:3196
void SynchronizeTuningProfileProperties()
Ensure that all time domain properties providers are in sync with current settings.
Definition board.cpp:3118
void InitEngine(const wxFileName &aRulePath)
Initialize the DRC engine.
static DS_DATA_MODEL & GetTheInstance()
Return the instance of DS_DATA_MODEL used in the application.
ENUM_MAP & Map(T aValue, const wxString &aName)
Definition property.h:727
static ENUM_MAP< T > & Instance()
Definition property.h:721
ENUM_MAP & Undefined(T aValue)
Definition property.h:734
wxPGChoices & Choices()
Definition property.h:772
Provide an extensible class to resolve 3D model paths.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
static const LSET & AllLayersMask()
Definition lset.cpp:637
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition lset.cpp:184
static BOARD * Load(PCB_FILE_T aFileType, const wxString &aFileName, BOARD *aAppendToMe=nullptr, const std::map< std::string, UTF8 > *aProperties=nullptr, PROJECT *aProject=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
Find the requested #PLUGIN and if found, calls the #PLUGIN::LoadBoard() function on it using the argu...
PCB_FILE_T
The set of file types that the PCB_IO_MGR knows about, and for which there has been a plugin written,...
Definition pcb_io_mgr.h:52
@ KICAD_SEXP
S-expression Pcbnew file format.
Definition pcb_io_mgr.h:54
static PCB_IO * FindPlugin(PCB_FILE_T aFileType)
Return a #PLUGIN which the caller can use to import, export, save, or load design documents.
static void Save(PCB_FILE_T aFileType, const wxString &aFileName, BOARD *aBoard, const std::map< std::string, UTF8 > *aProperties=nullptr)
Write either a full aBoard to a storage file in a format that this implementation knows about,...
wxString m_BoardDrawingSheetFile
PcbNew params.
Container for project specific data.
Definition project.h:63
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition project.cpp:183
virtual PROJECT_FILE & GetProjectFile() const
Definition project.h:201
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
Definition reporter.h:101
#define _(s)
static FILENAME_RESOLVER * resolver
static const std::string DesignRulesFileExtension
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
Definition io_mgr.h:33
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
@ UNDEFINED_LAYER
Definition layer_ids.h:57
PGM_BASE * PgmOrNull()
Return a reference that can be nullptr when running a shared lib from a script, not from a kicad app.
see class PGM_BASE
@ RPT_SEVERITY_WARNING
std::function< void(const wxString &, const wxString &)> drawing_sheet_error_callback
std::function< void(PCB_IO &)> plugin_configurator
std::function< void(PCB_IO &)> post_load_hook
const std::map< std::string, UTF8 > * properties
PROGRESS_REPORTER * progress_reporter
Definition of file extensions used in Kicad.