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 std::unique_ptr<BOARD> board;
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 board = pi->LoadBoard( aFileName, aOptions.properties, aProject );
72
73 // grab cached lib footprints while the plugin is alive
74 if( board && aOptions.post_load_hook )
75 aOptions.post_load_hook( *pi );
76 }
77 else
78 {
79 board = PCB_IO_MGR::Load( aFormat, aFileName, aOptions.properties, aProject, aOptions.progress_reporter );
80 }
81
82 if( !board )
83 return nullptr;
84
85 if( aOptions.initialize_after_load )
86 initializeLoadedBoard( board.get(), aFileName, aProject, aOptions );
87
88 return board;
89}
90
91
92std::unique_ptr<BOARD> BOARD_LOADER::Load( const wxString& aFileName,
94 PROJECT* aProject )
95{
96 return Load( aFileName, aFormat, aProject, OPTIONS{} );
97}
98
99
100void BOARD_LOADER::initializeLoadedBoard( BOARD* aBoard, const wxString& aFileName,
101 PROJECT* aProject, const OPTIONS& aOptions )
102{
103 if( !aBoard || !aProject )
104 return;
105
107 resolver.SetProject( aProject );
108 resolver.SetProgramBase( PgmOrNull() );
109
110 wxString filename = resolver.ResolvePath( BASE_SCREEN::m_DrawingSheetFileName,
111 aProject->GetProjectPath(),
112 { aBoard->GetEmbeddedFiles() } );
113
114 wxString msg;
115
116 if( !DS_DATA_MODEL::GetTheInstance().LoadDrawingSheet( filename, &msg ) )
117 {
118 if( aOptions.drawing_sheet_error_callback )
120 }
121
123
124 layerEnum.Choices().Clear();
125 layerEnum.Undefined( UNDEFINED_LAYER );
126
127 for( PCB_LAYER_ID layer : LSET::AllLayersMask() )
128 {
129 layerEnum.Map( layer, LSET::Name( layer ) );
130 layerEnum.Map( layer, aBoard->GetLayerName( layer ) );
131 }
132
133 aBoard->SetProject( aProject );
134
136 bds.m_DRCEngine = std::make_shared<DRC_ENGINE>( aBoard, &bds );
137
138 try
139 {
140 wxFileName rules = aFileName;
141 rules.SetExt( FILEEXT::DesignRulesFileExtension );
142 bds.m_DRCEngine->InitEngine( rules );
143 }
144 catch( ... )
145 {
146 // Only matters if user tries to run DRC later; will be reported at that time
147 }
148
149 for( PCB_MARKER* marker : aBoard->ResolveDRCExclusions( true ) )
150 aBoard->Add( marker );
151
152 aBoard->BuildConnectivity();
153 aBoard->BuildListOfNets();
154 aBoard->SynchronizeNetsAndNetClasses( true );
155
156 // Apply component class assignment rules from the project. Without this, conditions like
157 // A.hasComponentClass('Inductor') in custom DRC rules never match because no footprints
158 // have any dynamic component class assigned. The interactive load path does this in
159 // PCB_EDIT_FRAME::OpenProjectFiles; CLI and API consumers go through here.
160 if( !aBoard->SynchronizeComponentClasses( std::unordered_set<wxString>() )
161 && aOptions.reporter )
162 {
163 aOptions.reporter->Report( _( "Could not load component class assignment rules" ),
165 }
166
168
169 aBoard->UpdateUserUnits( aBoard, nullptr );
170}
171
172
173std::unique_ptr<BOARD> BOARD_LOADER::CreateEmptyBoard( PROJECT* aProject )
174{
175 std::unique_ptr<BOARD> brd = std::make_unique<BOARD>();
176 brd->SetProject( aProject );
177 return brd;
178}
179
180
181bool BOARD_LOADER::SaveBoard( wxString& aFileName, BOARD& aBoard, PCB_IO_MGR::PCB_FILE_T aFormat )
182{
183 aBoard.BuildConnectivity();
184 aBoard.SynchronizeNetsAndNetClasses( false );
185 aBoard.SynchronizeProperties();
186
187 try
188 {
189 PCB_IO_MGR::Save( aFormat, aFileName, aBoard, nullptr );
190 }
191 catch( const IO_ERROR& ioe )
192 {
193 wxLogError( _( "Cannot save board '%s': %s" ), aFileName, ioe.What() );
194 return false;
195 }
196 catch( const std::exception& e )
197 {
198 // Rethrow so std::bad_alloc and similar aren't silently turned into a false return.
199 wxLogError( _( "Unexpected error saving board '%s': %s" ), aFileName,
200 wxString::FromUTF8( e.what() ) );
201 throw;
202 }
203
204 return true;
205}
206
207
208bool BOARD_LOADER::SaveBoard( wxString& aFileName, BOARD& aBoard )
209{
210 return SaveBoard( aFileName, aBoard, PCB_IO_MGR::KICAD_SEXP );
211}
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 bool SaveBoard(wxString &aFileName, BOARD &aBoard, PCB_IO_MGR::PCB_FILE_T aFormat)
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)
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:409
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1497
void BuildListOfNets()
Definition board.h:1170
void UpdateUserUnits(BOARD_ITEM *aItem, KIGFX::VIEW *aView)
Update any references within aItem (or its descendants) to the user units.
Definition board.cpp:2018
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:364
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition board.cpp:3402
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition board.cpp:374
std::vector< PCB_MARKER * > ResolveDRCExclusions(bool aCreateMarkers)
Rebuild DRC markers from the serialized data in BOARD_DESIGN_SETTINGS.
Definition board.cpp:595
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition board.cpp:936
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition board.cpp:1299
void SynchronizeProperties()
Copy the current project's text variables into the boards property cache.
Definition board.cpp:3132
bool SynchronizeComponentClasses(const std::unordered_set< wxString > &aNewSheetPaths) const
Copy component class / component class generator information from the project settings.
Definition board.cpp:3446
void SynchronizeTuningProfileProperties()
Ensure that all time domain properties providers are in sync with current settings.
Definition board.cpp:3356
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:776
static ENUM_MAP< T > & Instance()
Definition property.h:770
ENUM_MAP & Undefined(T aValue)
Definition property.h:783
wxPGChoices & Choices()
Definition property.h:821
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
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 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,...
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 std::unique_ptr< BOARD > Load(PCB_FILE_T aFileType, const wxString &aFileName, 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...
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:102
#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.