KiCad PCB EDA Suite
Loading...
Searching...
No Matches
headless_pcb_context.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
22#include <board.h>
23#include <board_loader.h>
25#include <drc/drc_engine.h>
26#include <footprint.h>
28#include <netlist_reader/netlist_reader.h>
30#include <project.h>
31#include <reporter.h>
33#include <spread_footprints.h>
34#include <tool/tool_manager.h>
35#include <tools/drc_tool.h>
36#include <wx/debug.h>
37
38
39HEADLESS_PCB_CONTEXT::HEADLESS_PCB_CONTEXT( std::unique_ptr<BOARD> aBoard, PROJECT* aProject,
40 APP_SETTINGS_BASE* aSettings,
41 KIWAY* aKiway ) :
42 m_board( std::move( aBoard ) ),
43 m_project( aProject ),
44 m_kiway( aKiway ),
45 m_toolManager( std::make_unique<TOOL_MANAGER>() )
46{
47 wxCHECK( m_board, /* void */ );
48 wxCHECK( m_project, /* void */ );
49
50 m_board->SetProject( m_project );
51 m_toolManager->SetEnvironment( m_board.get(), nullptr, nullptr, aSettings, nullptr );
52}
53
54
56{
57 // Sever the board↔project linkage before destruction. The PROJECT holds a raw pointer
58 // (m_BoardSettings) to the board's design settings. If the board is destroyed while the
59 // project still exists, that pointer becomes dangling.
60 if( m_board )
61 m_board->ClearProject();
62}
63
64
66{
67 return m_board.get();
68}
69
70
72{
73 // Shouldn't be able to construct this without a project
74 wxASSERT( m_project );
75 return *m_project;
76}
77
78
83
84
86{
87 if( !m_board )
88 return wxEmptyString;
89
90 return m_board->GetFileName();
91}
92
93
95{
96 if( !m_board )
97 return false;
98
99 wxString fileName = m_board->GetFileName();
100
101 if( fileName.IsEmpty() )
102 return false;
103
104 bool success = BOARD_LOADER::SaveBoard( fileName, m_board.get() );
105
106 if( success )
107 {
108 wxFileName pro = fileName;
109 pro.SetExt( FILEEXT::ProjectFileExtension );
110 pro.MakeAbsolute();
111
112 Pgm().GetSettingsManager().SaveProjectAs( pro.GetFullPath(), m_board->GetProject() );
113 }
114
115 return success;
116}
117
118
119bool HEADLESS_PCB_CONTEXT::SavePcbCopy( const wxString& aFileName, bool aCreateProject, bool aHeadless )
120{
121 if( !m_board || aFileName.IsEmpty() )
122 return false;
123
124 wxString outPath = aFileName;
125
126 bool success = BOARD_LOADER::SaveBoard( outPath, m_board.get() );
127
128 if( success && aCreateProject )
129 {
130 wxFileName pro = aFileName;
131 pro.SetExt( FILEEXT::ProjectFileExtension );
132 pro.MakeAbsolute();
133
134 Pgm().GetSettingsManager().SaveProjectAs( pro.GetFullPath(), m_board->GetProject() );
135 }
136
137 return success;
138}
139
140
141bool HEADLESS_PCB_CONTEXT::ReadNetlistFromFile( const wxString& aFilename, NETLIST& aNetlist, REPORTER& aReporter )
142{
143 wxString msg;
144
145 try
146 {
147 std::unique_ptr<NETLIST_READER> netlistReader(
148 NETLIST_READER::GetNetlistReader( &aNetlist, aFilename, wxEmptyString ) );
149
150 if( !netlistReader.get() )
151 {
152 msg.Printf( _( "Cannot open netlist file '%s'." ), aFilename );
153 aReporter.Report( msg, RPT_SEVERITY_ERROR );
154 return false;
155 }
156
157 netlistReader->LoadNetlist();
158 LoadNetlistFootprints( GetBoard(), aNetlist, aReporter );
159 }
160 catch( const IO_ERROR& ioe )
161 {
162 msg.Printf( _( "Error loading netlist.\n%s" ), ioe.What().GetData() );
163 aReporter.Report( msg, RPT_SEVERITY_ERROR );
164 return false;
165 }
166
167 return true;
168}
169
170
171std::unique_ptr<BOARD_NETLIST_UPDATER> HEADLESS_PCB_CONTEXT::MakeNetlistUpdater()
172{
173 return std::make_unique<BOARD_NETLIST_UPDATER>( GetToolManager(), GetBoard() );
174}
175
176
178{
179 BOARD* board = GetBoard();
180
181 // Re-sync nets and netclasses
182 board->SynchronizeNetsAndNetClasses( false );
183
184 // Recompute component classes
187
188 // Resync DRC rules to account for new aggregate netclass / component class rules
189 if( DRC_TOOL* drcTool = m_toolManager->GetTool<DRC_TOOL>() )
190 {
191 if( drcTool->GetDRCEngine() )
192 {
193 try
194 {
195 drcTool->GetDRCEngine()->InitEngine( board->GetDesignRulesPath() );
196 }
197 catch( PARSE_ERROR& )
198 {
199 }
200 }
201 }
202
203 std::vector<FOOTPRINT*> newFootprints = aUpdater.GetAddedFootprints();
204 SpreadFootprints( &newFootprints, { 0, 0 }, true );
205
206 board->CompileRatsnest();
207}
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
static bool SaveBoard(wxString &aFileName, BOARD *aBoard, PCB_IO_MGR::PCB_FILE_T aFormat)
Update the BOARD with a new netlist.
std::vector< FOOTPRINT * > GetAddedFootprints() const
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:372
void CompileRatsnest()
Rebuild the entire board ratsnest.
Definition board.cpp:3595
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition board.cpp:3004
wxString GetDesignRulesPath() const
Return the absolute path to the design rules file for this board.
Definition board.cpp:272
COMPONENT_CLASS_MANAGER & GetComponentClassManager()
Gets the component class manager.
Definition board.h:1521
void InvalidateComponentClasses()
Invalidates any caches component classes and recomputes caches if required.
void RebuildRequiredCaches(FOOTPRINT *aFootprint=nullptr) const
Rebuilds any caches that may be required by custom assignment rules.
BOARD * GetBoard() const override
bool SavePcbCopy(const wxString &aFileName, bool aCreateProject, bool aHeadless) override
void OnNetlistChanged(BOARD_NETLIST_UPDATER &aUpdater) override
Post-import board sync (nets, classes, DRC, ratsnest, new footprint placement).
PROJECT & Prj() const override
TOOL_MANAGER * GetToolManager() const override
std::unique_ptr< TOOL_MANAGER > m_toolManager
HEADLESS_PCB_CONTEXT(std::unique_ptr< BOARD > aBoard, PROJECT *aProject, APP_SETTINGS_BASE *aSettings, KIWAY *aKiway=nullptr)
std::unique_ptr< BOARD > m_board
std::unique_ptr< BOARD_NETLIST_UPDATER > MakeNetlistUpdater() override
Create a netlist updater bound to this context's board.
bool ReadNetlistFromFile(const wxString &aFilename, NETLIST &aNetlist, REPORTER &aReporter) override
Read a netlist file and preload component footprints.
wxString GetCurrentFileName() const override
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()
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:311
static NETLIST_READER * GetNetlistReader(NETLIST *aNetlist, const wxString &aNetlistFileName, const wxString &aCompFootprintFileName=wxEmptyString)
Attempt to determine the net list file type of aNetlistFileName and return the appropriate NETLIST_RE...
Store information read from a netlist along with the flags used to update the NETLIST in the BOARD.
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition pgm_base.h:124
Container for project specific data.
Definition project.h:62
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
void SaveProjectAs(const wxString &aFullPath, PROJECT *aProject=nullptr)
Set the currently loaded project path and saves it (pointers remain valid).
Master controller class:
#define _(s)
static const std::string ProjectFileExtension
STL namespace.
void LoadNetlistFootprints(BOARD *aBoard, NETLIST &aNetlist, REPORTER &aReporter)
Load the footprints for each #SCH_COMPONENT in aNetlist from the list of libraries.
PGM_BASE & Pgm()
The global program "get" accessor.
@ RPT_SEVERITY_ERROR
void SpreadFootprints(std::vector< FOOTPRINT * > *aFootprints, VECTOR2I aTargetBoxPosition, bool aGroupBySheet, int aComponentGap, int aGroupGap)
Footprints (after loaded by reading a netlist for instance) are moved to be in a small free area (out...
A filename or source description, a problem input line, a line number, a byte offset,...