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
106 FILENAME_RESOLVER resolver;
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:410
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1524
void BuildListOfNets()
Definition board.h:1178
void UpdateUserUnits(BOARD_ITEM *aItem, KIGFX::VIEW *aView)
Update any references within aItem (or its descendants) to the user units.
Definition board.cpp:2045
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:367
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition board.cpp:3423
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition board.cpp:377
std::vector< PCB_MARKER * > ResolveDRCExclusions(bool aCreateMarkers)
Rebuild DRC markers from the serialized data in BOARD_DESIGN_SETTINGS.
Definition board.cpp:596
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition board.cpp:943
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition board.cpp:1301
void SynchronizeProperties()
Copy the current project's text variables into the boards property cache.
Definition board.cpp:3153
bool SynchronizeComponentClasses(const std::unordered_set< wxString > &aNewSheetPaths) const
Copy component class / component class generator information from the project settings.
Definition board.cpp:3467
void SynchronizeTuningProfileProperties()
Ensure that all time domain properties providers are in sync with current settings.
Definition board.cpp:3377
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:789
static ENUM_MAP< T > & Instance()
Definition property.h:783
ENUM_MAP & Undefined(T aValue)
Definition property.h:796
wxPGChoices & Choices()
Definition property.h:834
Provide an extensible class to resolve 3D model paths.
wxString ResolvePath(const wxString &aFileName, const wxString &aWorkingPath, std::vector< const EMBEDDED_FILES * > aEmbeddedFilesStack)
Determine the full path of the given file name.
void SetProgramBase(PGM_BASE *aBase)
Set a pointer to the application's PGM_BASE instance used to extract the local env vars.
bool SetProject(const PROJECT *aProject, bool *flgChanged=nullptr)
Set the current KiCad project directory as the first entry in the model path list.
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 PCB_IO 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 PCB_IO and if found, calls the PCB_IO::LoadBoard() function on it using the argume...
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 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.