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 along
18 * with this program. If not, see <http://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 )
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 loaded = pi->LoadBoard( aFileName, nullptr, aOptions.properties, aProject );
70 }
71 else
72 {
73 loaded = PCB_IO_MGR::Load( aFormat, aFileName, nullptr, aOptions.properties,
74 aProject, aOptions.progress_reporter );
75 }
76
77 std::unique_ptr<BOARD> board( loaded );
78
79 if( !board )
80 return nullptr;
81
82 if( aOptions.initialize_after_load )
83 initializeLoadedBoard( board.get(), aFileName, aProject, aOptions );
84
85 return board;
86}
87
88
89std::unique_ptr<BOARD> BOARD_LOADER::Load( const wxString& aFileName,
91 PROJECT* aProject )
92{
93 return Load( aFileName, aFormat, aProject, OPTIONS{} );
94}
95
96
97void BOARD_LOADER::initializeLoadedBoard( BOARD* aBoard, const wxString& aFileName,
98 PROJECT* aProject, const OPTIONS& aOptions )
99{
100 if( !aBoard || !aProject )
101 return;
102
104 resolver.SetProject( aProject );
105 resolver.SetProgramBase( PgmOrNull() );
106
107 wxString filename = resolver.ResolvePath( BASE_SCREEN::m_DrawingSheetFileName,
108 aProject->GetProjectPath(),
109 { aBoard->GetEmbeddedFiles() } );
110
111 wxString msg;
112
113 if( !DS_DATA_MODEL::GetTheInstance().LoadDrawingSheet( filename, &msg ) )
114 {
115 if( aOptions.drawing_sheet_error_callback )
117 }
118
120
121 layerEnum.Choices().Clear();
122 layerEnum.Undefined( UNDEFINED_LAYER );
123
124 for( PCB_LAYER_ID layer : LSET::AllLayersMask() )
125 {
126 layerEnum.Map( layer, LSET::Name( layer ) );
127 layerEnum.Map( layer, aBoard->GetLayerName( layer ) );
128 }
129
130 aBoard->SetProject( aProject );
131
133 bds.m_DRCEngine = std::make_shared<DRC_ENGINE>( aBoard, &bds );
134
135 try
136 {
137 wxFileName rules = aFileName;
138 rules.SetExt( FILEEXT::DesignRulesFileExtension );
139 bds.m_DRCEngine->InitEngine( rules );
140 }
141 catch( ... )
142 {
143 // Only matters if user tries to run DRC later; will be reported at that time
144 }
145
146 for( PCB_MARKER* marker : aBoard->ResolveDRCExclusions( true ) )
147 aBoard->Add( marker );
148
149 aBoard->BuildConnectivity();
150 aBoard->BuildListOfNets();
151 aBoard->SynchronizeNetsAndNetClasses( true );
152
153 // Apply component class assignment rules from the project. Without this, conditions like
154 // A.hasComponentClass('Inductor') in custom DRC rules never match because no footprints
155 // have any dynamic component class assigned. The interactive load path does this in
156 // PCB_EDIT_FRAME::OpenProjectFiles; CLI and API consumers go through here.
157 if( !aBoard->SynchronizeComponentClasses( std::unordered_set<wxString>() )
158 && aOptions.reporter )
159 {
160 aOptions.reporter->Report( _( "Could not load component class assignment rules" ),
162 }
163
165
166 aBoard->UpdateUserUnits( aBoard, nullptr );
167}
168
169
170std::unique_ptr<BOARD> BOARD_LOADER::CreateEmptyBoard( PROJECT* aProject )
171{
172 std::unique_ptr<BOARD> brd = std::make_unique<BOARD>();
173 brd->SetProject( aProject );
174 return brd;
175}
176
177
178bool BOARD_LOADER::SaveBoard( wxString& aFileName, BOARD* aBoard, PCB_IO_MGR::PCB_FILE_T aFormat )
179{
180 aBoard->BuildConnectivity();
181 aBoard->SynchronizeNetsAndNetClasses( false );
182
183 try
184 {
185 PCB_IO_MGR::Save( aFormat, aFileName, aBoard, nullptr );
186 }
187 catch( const IO_ERROR& ioe )
188 {
189 wxLogError( _( "Cannot save board '%s': %s" ), aFileName, ioe.What() );
190 return false;
191 }
192 catch( const std::exception& e )
193 {
194 // Rethrow so std::bad_alloc and similar aren't silently turned into a false return.
195 wxLogError( _( "Unexpected error saving board '%s': %s" ), aFileName,
196 wxString::FromUTF8( e.what() ) );
197 throw;
198 }
199
200 return true;
201}
202
203
204bool BOARD_LOADER::SaveBoard( wxString& aFileName, BOARD* aBoard )
205{
206 return SaveBoard( aFileName, aBoard, PCB_IO_MGR::KICAD_SEXP );
207}
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:85
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:323
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1247
void BuildListOfNets()
Definition board.h:967
void UpdateUserUnits(BOARD_ITEM *aItem, KIGFX::VIEW *aView)
Update any references within aItem (or its descendants) to the user units.
Definition board.cpp:1715
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:203
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition board.cpp:2956
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition board.cpp:213
std::vector< PCB_MARKER * > ResolveDRCExclusions(bool aCreateMarkers)
Rebuild DRC markers from the serialized data in BOARD_DESIGN_SETTINGS.
Definition board.cpp:403
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition board.cpp:745
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition board.cpp:1101
bool SynchronizeComponentClasses(const std::unordered_set< wxString > &aNewSheetPaths) const
Copy component class / component class generator information from the project settings.
Definition board.cpp:2986
void SynchronizeTuningProfileProperties()
Ensure that all time domain properties providers are in sync with current settings.
Definition board.cpp:2950
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:770
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:641
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition lset.cpp:188
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:56
@ KICAD_SEXP
S-expression Pcbnew file format.
Definition pcb_io_mgr.h:58
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:66
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition project.cpp:187
virtual PROJECT_FILE & GetProjectFile() const
Definition project.h:204
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
Definition reporter.h:104
#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:60
@ UNDEFINED_LAYER
Definition layer_ids.h:61
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
const std::map< std::string, UTF8 > * properties
PROGRESS_REPORTER * progress_reporter
Definition of file extensions used in Kicad.