25#include <wx/stdpaths.h>
26#include <wx/process.h>
28#include <wx/filedlg.h>
115 { wxID_CANCEL,
_(
"Close" ) } } );
121 SetTitle(
m_job->GetSettingsDialogTitle() );
140 size_t bad_count = 0;
146 if(
model.m_Scale.x != 1.0 ||
model.m_Scale.y != 1.0 ||
model.m_Scale.z != 1.0 )
148 bad_scales.Append( wxS(
"\n") );
149 bad_scales.Append(
model.m_Filename );
158 if( !bad_scales.empty() && !
Pgm().GetCommonSettings()->m_DoNotShowAgain.scaled_3d_models_warning )
160 wxString extendedMsg =
_(
"Non-unity scaled models:" ) + wxT(
"\n" ) + bad_scales;
163 "mechanical export." ),
164 _(
"Model Scale Warning" ), wxOK | wxICON_WARNING );
165 msgDlg.SetExtendedMessage( extendedMsg );
187 if( lastPath.IsEmpty() )
189 wxFileName brdFile(
m_editFrame->GetBoard()->GetFileName() );
190 brdFile.SetExt( wxT(
"step" ) );
191 lastPath = brdFile.GetFullPath();
196 wxString currentVariant =
m_editFrame->GetBoard()->GetCurrentVariant();
198 if( !currentVariant.IsEmpty() )
202 if( idx != wxNOT_FOUND )
215 if(
m_job->m_3dparams.m_UseDrillOrigin )
217 else if(
m_job->m_3dparams.m_UseGridOrigin )
219 else if(
m_job->m_3dparams.m_UseDefinedOrigin )
221 else if(
m_job->m_3dparams.m_UsePcbCenterOrigin )
245 if(
m_job->m_3dparams.m_BoardOutlinesChainingEpsilon > 0.05 )
247 else if(
m_job->m_3dparams.m_BoardOutlinesChainingEpsilon < 0.005 )
255 if( !
m_job->m_variant.IsEmpty() )
259 if( idx != wxNOT_FOUND )
266 if( formats.second ==
m_job->m_3dparams.m_Format )
275 wxCommandEvent
dummy;
287 if( ( selection != 0 ) && ( selection != wxNOT_FOUND ) )
297 wxFileName brdFile =
board->GetFileName();
321 wxString
filter =
_(
"STEP files" )
323 +
_(
"Binary glTF files" )
327 +
_(
"BREP (OCCT) files" )
333 +
_(
"Universal 3D files" )
341 wxFileName fn(
Prj().AbsolutePath(
path ) );
343 wxFileDialog dlg(
this,
_(
"3D Model Output File" ), fn.GetPath(), fn.GetFullName(),
filter, wxFD_SAVE );
347 if( dlg.ShowModal() == wxID_CANCEL )
350 path = dlg.GetPath();
353 fn = wxFileName(
path );
373 if( choices.second == idx )
375 newExt = choices.first;
382 int sepIdx = std::max(
path.Find(
'/',
true ),
path.Find(
'\\',
true ) );
383 int dotIdx =
path.Find(
'.',
true );
385 if( dotIdx == -1 || dotIdx < sepIdx )
386 path <<
'.' << newExt;
388 path =
path.Mid( 0, dotIdx ) <<
'.' << newExt;
412 wxString& aInputPath, std::vector<wxString>& aTempFiles,
413 wxString& aErrorDetail )
415 aErrorDetail = wxEmptyString;
417 if( aBoardPath.IsEmpty() )
418 return _(
"Please save the board before exporting STEP." );
421 if( !aContentModified )
423 if( !wxFileExists( aBoardPath ) )
425 return _(
"Board file not found on disk.\n"
426 "Save the board before exporting STEP." );
429 aInputPath = aBoardPath;
430 return wxEmptyString;
433 wxFileName boardFn( aBoardPath );
435 if( !boardFn.DirExists() )
437 return _(
"The board directory no longer exists.\n"
438 "Save the board to a valid location before exporting STEP." );
443 wxString stemPrefix = boardFn.GetName() + wxS(
"-unsaved-export-" );
444 wxString reserved = wxFileName::CreateTempFileName( boardFn.GetPathWithSep() + stemPrefix );
446 if( reserved.IsEmpty() )
447 return _(
"Failed to reserve a temporary filename for STEP export." );
449 wxFileName stemFn( reserved );
455 aTempFiles.push_back( reserved );
456 wxRemoveFile( reserved );
461 pi->SaveBoard( tempBoardFn.GetFullPath(), aBoard,
nullptr );
465 aErrorDetail = ioe.
What();
466 return _(
"Failed to save the current board state for export." );
469 aTempFiles.push_back( tempBoardFn.GetFullPath() );
471 wxFileName srcProjectFn = boardFn;
474 if( srcProjectFn.FileExists() )
476 if( !wxCopyFile( srcProjectFn.GetFullPath(), tempProjectFn.GetFullPath(),
true ) )
478 wxRemoveFile( tempBoardFn.GetFullPath() );
479 return _(
"Failed to stage the project file for STEP export." );
482 aTempFiles.push_back( tempProjectFn.GetFullPath() );
485 aInputPath = tempBoardFn.GetFullPath();
486 return wxEmptyString;
497 case 0: tolerance = 0.001;
break;
499 case 1: tolerance = 0.01;
break;
500 case 2: tolerance = 0.1;
break;
506 std::function<bool( wxString* )> textResolver =
507 [&]( wxString* token ) ->
bool
509 return m_editFrame->GetBoard()->ResolveTextVar( token, 0 );
527 int chainingEpsilon =
pcbIUScale.mmToIU( tolerance );
535 "%.3f mm tolerance.\n"
536 "Run DRC for a full analysis." ),
541 wxFileName fn(
Prj().AbsolutePath(
path ) );
545 msg.Printf(
_(
"File '%s' already exists. Do you want overwrite this file?" ), fn.GetFullPath() );
547 if( wxMessageBox( msg,
_(
"STEP/GLTF Export" ), wxYES_NO | wxICON_QUESTION,
this ) == wxNO )
553 wxFileName appK2S( wxStandardPaths::Get().GetExecutablePath() );
556 if( appK2S.GetPath().Find(
"/Contents/Applications/pcbnew.app/Contents/MacOS" ) != wxNOT_FOUND )
558 appK2S.AppendDir( wxT(
".." ) );
559 appK2S.AppendDir( wxT(
".." ) );
560 appK2S.AppendDir( wxT(
".." ) );
561 appK2S.AppendDir( wxT(
".." ) );
562 appK2S.AppendDir( wxT(
"MacOS" ) );
565 if( wxGetEnv( wxT(
"KICAD_RUN_FROM_BUILD_DIR" ),
nullptr ) )
567 appK2S.RemoveLastDir();
568 appK2S.AppendDir(
"kicad" );
572 appK2S.SetName( wxT(
"kicad-cli" ) );
575 wxString cmdK2S = wxT(
"\"" );
576 cmdK2S.Append( appK2S.GetFullPath() );
577 cmdK2S.Append( wxT(
"\"" ) );
579 cmdK2S.Append( wxT(
" pcb" ) );
580 cmdK2S.Append( wxT(
" export" ) );
582 cmdK2S.Append( wxT(
" " ) );
586 cmdK2S.Append( wxT(
" --no-unspecified" ) );
589 cmdK2S.Append( wxT(
" --no-dnp" ) );
592 cmdK2S.Append( wxT(
" --subst-models" ) );
595 cmdK2S.Append( wxT(
" --no-optimize-step" ) );
598 cmdK2S.Append( wxT(
" --no-board-body" ) );
601 cmdK2S.Append( wxT(
" --no-components" ) );
604 cmdK2S.Append( wxT(
" --include-tracks" ) );
607 cmdK2S.Append( wxT(
" --include-pads" ) );
610 cmdK2S.Append( wxT(
" --include-zones" ) );
613 cmdK2S.Append( wxT(
" --include-inner-copper" ) );
616 cmdK2S.Append( wxT(
" --include-silkscreen" ) );
619 cmdK2S.Append( wxT(
" --include-soldermask" ) );
622 cmdK2S.Append( wxT(
" --fuse-shapes" ) );
625 cmdK2S.Append( wxT(
" --cut-vias-in-body" ) );
628 cmdK2S.Append( wxT(
" --fill-all-vias" ) );
637 if( !selectedVariant.IsEmpty() )
639 cmdK2S.Append( wxString::Format( wxT(
" --variant %c%s%c" ),
640 dblquote, selectedVariant, dblquote ) );
645 cmdK2S.Append( wxString::Format( wxT(
" --net-filter %c%s%c" ),
651 wxArrayString components;
654 std::for_each( selection.
begin(), selection.
end(),
657 if( item->Type() == PCB_FOOTPRINT_T )
658 components.push_back( static_cast<FOOTPRINT*>( item )->GetReference() );
661 cmdK2S.Append( wxString::Format( wxT(
" --component-filter %c%s%c" ),
662 dblquote, wxJoin( components,
',' ), dblquote ) );
666 cmdK2S.Append( wxString::Format( wxT(
" --component-filter %c%s%c" ),
672 cmdK2S.Append( wxT(
" --drill-origin" ) );
676 cmdK2S.Append( wxT(
" --grid-origin" ) );
684 cmdK2S.Append( wxString::Format( wxT(
" --user-origin=%c%.6fx%.6fmm%c" ),
685 quote, xOrg, yOrg, quote ) );
694 cmdK2S.Append( wxString::Format( wxT(
" --user-origin=%c%.6fx%.6fmm%c" ),
695 quote, xOrg, yOrg, quote ) );
699 wxFAIL_MSG( wxT(
"Unsupported origin option: how did we get here?" ) );
704 cmdK2S.Append( wxString::Format( wxT(
" --min-distance=%c%.3fmm%c" ),
705 quote, tolerance, quote ) );
709 cmdK2S.Append( wxString::Format( wxT(
" -f -o %c%s%c" ),
710 dblquote, fn.GetFullPath(), dblquote ) );
716 std::vector<wxString> tempFiles;
717 wxString errorDetail;
719 inputPath, tempFiles, errorDetail );
721 if( !error.IsEmpty() )
728 cmdK2S.Append( wxString::Format( wxT(
" %c%s%c" ), dblquote, inputPath, dblquote ) );
730 wxLogTrace(
traceKiCad2Step, wxT(
"export step command: %s" ), cmdK2S );
758 m_job->m_3dparams.m_BoardOutlinesChainingEpsilon = tolerance;
762 m_job->SetStepFormat( *formatChoice );
766 wxASSERT_MSG(
false, wxString::Format(
"Unknown format value %d",
m_choiceFormat->GetSelection() ) );
771 switch(
m_job->m_3dparams.m_Format )
784 m_job->m_3dparams.m_UseDrillOrigin =
false;
785 m_job->m_3dparams.m_UseGridOrigin =
false;
786 m_job->m_3dparams.m_UseDefinedOrigin =
false;
787 m_job->m_3dparams.m_UsePcbCenterOrigin =
false;
791 m_job->m_3dparams.m_UseDrillOrigin =
true;
795 m_job->m_3dparams.m_UseGridOrigin =
true;
802 m_job->m_3dparams.m_UseDefinedOrigin =
true;
812 m_job->m_3dparams.m_UsePcbCenterOrigin =
true;
constexpr EDA_IU_SCALE pcbIUScale
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
int ExportSTEP(const TOOL_EVENT &aEvent)
Information pertinent to a Pcbnew printed circuit board.
constexpr const Vec GetCenter() const
DO_NOT_SHOW_AGAIN m_DoNotShowAgain
wxCheckBox * m_cbExportTracks
wxChoice * m_choiceVariant
wxCheckBox * m_cbSubstModels
wxRadioButton * m_rbOnlySelected
wxRadioButton * m_rbGridOrigin
TEXT_CTRL_EVAL * m_originXCtrl
wxStaticText * m_originXUnits
wxStaticText * m_originYUnits
wxCheckBox * m_cbExportBody
wxCheckBox * m_cbRemoveUnspecified
wxCheckBox * m_cbOverwriteFile
wxStaticText * m_originXLabel
wxCheckBox * m_cbRemoveDNP
wxBoxSizer * bSizerSTEPFile
wxCheckBox * m_cbExportComponents
wxCheckBox * m_cbOptimizeStep
wxCheckBox * m_cbFuseShapes
wxRadioButton * m_rbBoardCenterOrigin
wxTextCtrl * m_outputFileName
wxCheckBox * m_cbExportInnerCopper
wxChoice * m_choiceTolerance
wxStaticText * m_originYLabel
wxTextCtrl * m_txtNetFilter
wxCheckBox * m_cbExportSoldermask
wxCheckBox * m_cbExportPads
wxChoice * m_choiceFormat
wxCheckBox * m_cbExportZones
DIALOG_EXPORT_STEP_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Export 3D Model"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
wxRadioButton * m_rbAllComponents
wxRadioButton * m_rbUserDefinedOrigin
wxCheckBox * m_cbExportSilkscreen
wxRadioButton * m_rbFilteredComponents
TEXT_CTRL_EVAL * m_originYCtrl
wxCheckBox * m_cbCutViasInBody
wxRadioButton * m_rbDrillAndPlotOrigin
wxTextCtrl * m_txtComponentFilter
STD_BITMAP_BUTTON * m_browseButton
wxCheckBox * m_cbFillAllVias
void SetTempFilesToCleanup(std::vector< wxString > aPaths)
Register files that should be removed once the subprocess is known to have terminated (or been repare...
void onFormatChoice(wxCommandEvent &event) override
void OnFmtChoiceOptionChanged()
void onCbExportComponents(wxCommandEvent &event) override
PCB_EDIT_FRAME * m_editFrame
void OnComponentModeChange(wxCommandEvent &event) override
DIALOG_EXPORT_STEP(PCB_EDIT_FRAME *aEditFrame, const wxString &aBoardPath)
wxString getSelectedVariant() const
void onUpdateXPos(wxUpdateUIEvent &aEvent) override
JOB_EXPORT_PCB_3D * m_job
static wxString StageBoardForExport(const wxString &aBoardPath, bool aContentModified, BOARD *aBoard, wxString &aInputPath, std::vector< wxString > &aTempFiles, wxString &aErrorDetail)
Resolve the board file to hand to the external 3D/STEP exporter.
bool TransferDataToWindow() override
void onExportButton(wxCommandEvent &aEvent) override
void onUpdateYPos(wxUpdateUIEvent &aEvent) override
void onBrowseClicked(wxCommandEvent &aEvent) override
void OptOut(wxWindow *aWindow)
Opt out of control state saving.
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
A base class for most all the KiCad significant classes used in schematics and boards.
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()
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
bool DoNotShowAgain() const
Checks the 'do not show again' setting for the dialog.
void DoNotShowCheckbox(wxString file, int line)
Shows the 'do not show again' checkbox.
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
The main frame for Pcbnew.
@ KICAD_SEXP
S-expression Pcbnew file format.
static PCB_IO * FindPlugin(PCB_FILE_T aFileType)
Return a #PLUGIN which the caller can use to import, export, save, or load design documents.
virtual COMMON_SETTINGS * GetCommonSettings() const
virtual const wxString AbsolutePath(const wxString &aFileName) const
Fix up aFileName if it is relative to the project's directory to be an absolute path and filename.
Represent a set of closed polygons.
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject, int aFlags)
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
bool BuildBoardPolygonOutlines(BOARD *aBoard, SHAPE_POLY_SET &aOutlines, int aErrorMax, int aChainingEpsilon, bool aInferOutlineIfNecessary, OUTLINE_ERROR_HANDLER *aErrorHandler, bool aAllowUseArcsInPolygons)
Extract the board outlines and build a closed polygon from lines, arcs and circle items on edge cut l...
static const std::map< wxString, int > c_formatExtToChoice
static const std::vector< wxString > c_formatCommand
static const std::map< int, EXPORTER_STEP_PARAMS::FORMAT > c_formatJobCommand
static const std::string BrepFileExtension
static const std::string StepFileAbrvExtension
static const std::string XaoFileExtension
static const std::string GltfBinaryFileExtension
static const std::string ProjectFileExtension
static const std::string U3DFileExtension
static const std::string PdfFileExtension
static const std::string StlFileExtension
static const std::string PlyFileExtension
static const std::string StepFileExtension
static const std::string StepZFileAbrvExtension
static const std::string KiCadPcbFileExtension
const wxChar *const traceKiCad2Step
Flag to enable KiCad2Step debug tracing.
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
std::optional< V > get_opt(const std::map< wxString, V > &aMap, const wxString &aKey)
PGM_BASE & Pgm()
The global program "get" accessor.
std::vector< FAB_LAYER_COLOR > dummy
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
bool scaled_3d_models_warning
wxLogTrace helper definitions.
VECTOR2< double > VECTOR2D
wxString AddFileExtListToFilter(const std::vector< std::string > &aExts)
Build the wildcard extension file dialog wildcard filter to add to the base message dialog.
Definition of file extensions used in Kicad.
#define FN_NORMALIZE_FLAGS
Default flags to pass to wxFileName::Normalize().