25#include <wx/stdpaths.h>
26#include <wx/process.h>
28#include <wx/filedlg.h>
115 { wxID_CANCEL,
_(
"Close" ) } } );
121 SetTitle(
m_job->GetSettingsDialogTitle() );
144 size_t bad_count = 0;
150 if(
model.m_Scale.x != 1.0 ||
model.m_Scale.y != 1.0 ||
model.m_Scale.z != 1.0 )
152 bad_scales.Append( wxS(
"\n") );
153 bad_scales.Append(
model.m_Filename );
162 if( !bad_scales.empty() && !
Pgm().GetCommonSettings()->m_DoNotShowAgain.scaled_3d_models_warning )
164 wxString extendedMsg =
_(
"Non-unity scaled models:" ) + wxT(
"\n" ) + bad_scales;
167 "mechanical export." ),
168 _(
"Model Scale Warning" ), wxOK | wxICON_WARNING );
169 msgDlg.SetExtendedMessage( extendedMsg );
191 if( lastPath.IsEmpty() )
193 wxFileName brdFile(
m_editFrame->GetBoard()->GetFileName() );
194 brdFile.SetExt( wxT(
"step" ) );
195 lastPath = brdFile.GetFullPath();
200 wxString currentVariant =
m_editFrame->GetBoard()->GetCurrentVariant();
202 if( !currentVariant.IsEmpty() )
206 if( idx != wxNOT_FOUND )
219 if(
m_job->m_3dparams.m_UseDrillOrigin )
221 else if(
m_job->m_3dparams.m_UseGridOrigin )
223 else if(
m_job->m_3dparams.m_UseDefinedOrigin )
225 else if(
m_job->m_3dparams.m_UsePcbCenterOrigin )
249 if(
m_job->m_3dparams.m_BoardOutlinesChainingEpsilon > 0.05 )
251 else if(
m_job->m_3dparams.m_BoardOutlinesChainingEpsilon < 0.005 )
257 if(
m_job->m_3dparams.m_ComponentFilter.IsEmpty() )
265 if( !
m_job->m_variant.IsEmpty() )
269 if( idx != wxNOT_FOUND )
276 if( formats.second ==
m_job->m_3dparams.m_Format )
285 wxCommandEvent
dummy;
297 if( ( selection != 0 ) && ( selection != wxNOT_FOUND ) )
308 wxArrayString components;
314 components.push_back(
static_cast<FOOTPRINT*
>( item )->GetReference() );
317 return wxJoin( components,
',' );
323 return wxEmptyString;
330 wxFileName brdFile =
board->GetFileName();
354 wxString
filter =
_(
"STEP files" )
356 +
_(
"Binary glTF files" )
360 +
_(
"BREP (OCCT) files" )
366 +
_(
"Universal 3D files" )
374 wxFileName fn(
Prj().AbsolutePath(
path ) );
376 wxFileDialog dlg(
this,
_(
"3D Model Output File" ), fn.GetPath(), fn.GetFullName(),
filter, wxFD_SAVE );
380 if( dlg.ShowModal() == wxID_CANCEL )
383 path = dlg.GetPath();
386 fn = wxFileName(
path );
406 if( choices.second == idx )
408 newExt = choices.first;
415 int sepIdx = std::max(
path.Find(
'/',
true ),
path.Find(
'\\',
true ) );
416 int dotIdx =
path.Find(
'.',
true );
418 if( dotIdx == -1 || dotIdx < sepIdx )
419 path <<
'.' << newExt;
421 path =
path.Mid( 0, dotIdx ) <<
'.' << newExt;
445 wxString& aInputPath, std::vector<wxString>& aTempFiles,
446 wxString& aErrorDetail )
448 aErrorDetail = wxEmptyString;
450 if( aBoardPath.IsEmpty() )
451 return _(
"Please save the board before exporting STEP." );
454 if( !aContentModified )
456 if( !wxFileExists( aBoardPath ) )
458 return _(
"Board file not found on disk.\n"
459 "Save the board before exporting STEP." );
462 aInputPath = aBoardPath;
463 return wxEmptyString;
466 wxFileName boardFn( aBoardPath );
468 if( !boardFn.DirExists() )
470 return _(
"The board directory no longer exists.\n"
471 "Save the board to a valid location before exporting STEP." );
476 wxString stemPrefix = boardFn.GetName() + wxS(
"-unsaved-export-" );
477 wxString reserved = wxFileName::CreateTempFileName( boardFn.GetPathWithSep() + stemPrefix );
479 if( reserved.IsEmpty() )
480 return _(
"Failed to reserve a temporary filename for STEP export." );
482 wxFileName stemFn( reserved );
488 aTempFiles.push_back( reserved );
489 wxRemoveFile( reserved );
494 pi->SaveBoard( tempBoardFn.GetFullPath(), *aBoard,
nullptr );
498 aErrorDetail = ioe.
What();
499 return _(
"Failed to save the current board state for export." );
502 aTempFiles.push_back( tempBoardFn.GetFullPath() );
504 wxFileName srcProjectFn = boardFn;
507 if( srcProjectFn.FileExists() )
509 if( !wxCopyFile( srcProjectFn.GetFullPath(), tempProjectFn.GetFullPath(),
true ) )
511 wxRemoveFile( tempBoardFn.GetFullPath() );
512 return _(
"Failed to stage the project file for STEP export." );
515 aTempFiles.push_back( tempProjectFn.GetFullPath() );
518 aInputPath = tempBoardFn.GetFullPath();
519 return wxEmptyString;
530 case 0: tolerance = 0.001;
break;
532 case 1: tolerance = 0.01;
break;
533 case 2: tolerance = 0.1;
break;
539 std::function<bool( wxString* )> textResolver =
540 [&]( wxString* token ) ->
bool
542 return m_editFrame->GetBoard()->ResolveTextVar( token, 0 );
560 int chainingEpsilon =
pcbIUScale.mmToIU( tolerance );
568 "%.3f mm tolerance.\n"
569 "Run DRC for a full analysis." ),
574 wxFileName fn(
Prj().AbsolutePath(
path ) );
578 msg.Printf(
_(
"File '%s' already exists. Do you want overwrite this file?" ), fn.GetFullPath() );
580 if( wxMessageBox( msg,
_(
"STEP/GLTF Export" ), wxYES_NO | wxICON_QUESTION,
this ) == wxNO )
586 wxFileName appK2S( wxStandardPaths::Get().GetExecutablePath() );
589 if( appK2S.GetPath().Find(
"/Contents/Applications/pcbnew.app/Contents/MacOS" ) != wxNOT_FOUND )
591 appK2S.AppendDir( wxT(
".." ) );
592 appK2S.AppendDir( wxT(
".." ) );
593 appK2S.AppendDir( wxT(
".." ) );
594 appK2S.AppendDir( wxT(
".." ) );
595 appK2S.AppendDir( wxT(
"MacOS" ) );
598 if( wxGetEnv( wxT(
"KICAD_RUN_FROM_BUILD_DIR" ),
nullptr ) )
600 appK2S.RemoveLastDir();
601 appK2S.AppendDir(
"kicad" );
605 appK2S.SetName( wxT(
"kicad-cli" ) );
608 wxString cmdK2S = wxT(
"\"" );
609 cmdK2S.Append( appK2S.GetFullPath() );
610 cmdK2S.Append( wxT(
"\"" ) );
612 cmdK2S.Append( wxT(
" pcb" ) );
613 cmdK2S.Append( wxT(
" export" ) );
615 cmdK2S.Append( wxT(
" " ) );
619 cmdK2S.Append( wxT(
" --no-unspecified" ) );
622 cmdK2S.Append( wxT(
" --no-dnp" ) );
625 cmdK2S.Append( wxT(
" --subst-models" ) );
628 cmdK2S.Append( wxT(
" --no-optimize-step" ) );
631 cmdK2S.Append( wxT(
" --no-board-body" ) );
634 cmdK2S.Append( wxT(
" --no-components" ) );
637 cmdK2S.Append( wxT(
" --include-tracks" ) );
640 cmdK2S.Append( wxT(
" --include-pads" ) );
643 cmdK2S.Append( wxT(
" --include-zones" ) );
646 cmdK2S.Append( wxT(
" --include-inner-copper" ) );
649 cmdK2S.Append( wxT(
" --include-silkscreen" ) );
652 cmdK2S.Append( wxT(
" --include-soldermask" ) );
655 cmdK2S.Append( wxT(
" --fuse-shapes" ) );
658 cmdK2S.Append( wxT(
" --cut-vias-in-body" ) );
661 cmdK2S.Append( wxT(
" --fill-all-vias" ) );
670 if( !selectedVariant.IsEmpty() )
672 cmdK2S.Append( wxString::Format( wxT(
" --variant %c%s%c" ),
673 dblquote, selectedVariant, dblquote ) );
678 cmdK2S.Append( wxString::Format( wxT(
" --net-filter %c%s%c" ),
684 cmdK2S.Append( wxString::Format( wxT(
" --component-filter %c%s%c" ),
690 cmdK2S.Append( wxT(
" --drill-origin" ) );
694 cmdK2S.Append( wxT(
" --grid-origin" ) );
702 cmdK2S.Append( wxString::Format( wxT(
" --user-origin=%c%.6fx%.6fmm%c" ),
703 quote, xOrg, yOrg, quote ) );
712 cmdK2S.Append( wxString::Format( wxT(
" --user-origin=%c%.6fx%.6fmm%c" ),
713 quote, xOrg, yOrg, quote ) );
717 wxFAIL_MSG( wxT(
"Unsupported origin option: how did we get here?" ) );
722 cmdK2S.Append( wxString::Format( wxT(
" --min-distance=%c%.3fmm%c" ),
723 quote, tolerance, quote ) );
727 cmdK2S.Append( wxString::Format( wxT(
" -f -o %c%s%c" ),
728 dblquote, fn.GetFullPath(), dblquote ) );
734 std::vector<wxString> tempFiles;
735 wxString errorDetail;
737 inputPath, tempFiles, errorDetail );
739 if( !error.IsEmpty() )
746 cmdK2S.Append( wxString::Format( wxT(
" %c%s%c" ), dblquote, inputPath, dblquote ) );
748 wxLogTrace(
traceKiCad2Step, wxT(
"export step command: %s" ), cmdK2S );
776 m_job->m_3dparams.m_BoardOutlinesChainingEpsilon = tolerance;
780 m_job->SetStepFormat( *formatChoice );
784 wxASSERT_MSG(
false, wxString::Format(
"Unknown format value %d",
m_choiceFormat->GetSelection() ) );
789 switch(
m_job->m_3dparams.m_Format )
802 m_job->m_3dparams.m_UseDrillOrigin =
false;
803 m_job->m_3dparams.m_UseGridOrigin =
false;
804 m_job->m_3dparams.m_UseDefinedOrigin =
false;
805 m_job->m_3dparams.m_UsePcbCenterOrigin =
false;
813 m_job->m_3dparams.m_UseDrillOrigin =
true;
817 m_job->m_3dparams.m_UseGridOrigin =
true;
821 m_job->m_3dparams.m_UseDefinedOrigin =
true;
828 m_job->m_3dparams.m_UsePcbCenterOrigin =
true;
constexpr EDA_IU_SCALE pcbIUScale
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
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
wxString getComponentFilter() const
Return the component filter implied by the component mode radio buttons.
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, RESOLUTION_CONTEXT aContext)
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.
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
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().