Initial jobset creation and running within the CLI and GUI.

Incomplete, just pushing this before feature freeze, much fixing left
This commit is contained in:
Marek Roszko
2024-09-30 20:04:53 -04:00
parent 6255586d5b
commit d74caace0a
150 changed files with 9950 additions and 3247 deletions
+387 -303
View File
@@ -49,6 +49,7 @@
#include <filename_resolver.h>
#include <core/map_helpers.h>
#include <settings/settings_manager.h>
#include <jobs/job_export_pcb_3d.h>
// Maps m_choiceFormat selection to extension (and kicad-cli command)
@@ -81,16 +82,33 @@ bool DIALOG_EXPORT_STEP::m_fuseShapes = false;
DIALOG_EXPORT_STEP::COMPONENT_MODE DIALOG_EXPORT_STEP::m_componentMode = COMPONENT_MODE::EXPORT_ALL;
wxString DIALOG_EXPORT_STEP::m_componentFilter;
DIALOG_EXPORT_STEP::DIALOG_EXPORT_STEP( PCB_EDIT_FRAME* aEditFrame, const wxString& aBoardPath ) :
DIALOG_EXPORT_STEP_BASE( aEditFrame )
DIALOG_EXPORT_STEP( aEditFrame, aEditFrame, aBoardPath )
{
m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) );
}
m_editFrame = aEditFrame;
m_boardPath = aBoardPath;
SetupStandardButtons( { { wxID_OK, _( "Export" ) },
{ wxID_CANCEL, _( "Close" ) } } );
DIALOG_EXPORT_STEP::DIALOG_EXPORT_STEP( PCB_EDIT_FRAME* aEditFrame, wxWindow* aParent,
const wxString& aBoardPath,
JOB_EXPORT_PCB_3D* aJob ) :
DIALOG_EXPORT_STEP_BASE( aEditFrame ),
m_editFrame( aEditFrame ),
m_job( aJob ),
m_boardPath( aBoardPath )
{
if( m_job == nullptr )
{
m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) );
SetupStandardButtons( { { wxID_OK, _( "Export" ) },
{ wxID_CANCEL, _( "Close" ) } } );
}
else
{
m_browseButton->Hide();
SetupStandardButtons( { { wxID_OK, _( "Save" ) },
{ wxID_CANCEL, _( "Close" ) } } );
}
// Build default output file name
// (last saved filename in project or built from board filename)
@@ -110,62 +128,65 @@ DIALOG_EXPORT_STEP::DIALOG_EXPORT_STEP( PCB_EDIT_FRAME* aEditFrame, const wxStri
SetFocus();
PCBNEW_SETTINGS* cfg = m_editFrame->GetPcbNewSettings();
m_origin = static_cast<STEP_ORIGIN_OPTION>( cfg->m_ExportStep.origin_mode );
switch( m_origin )
if( !m_job )
{
default:
case STEP_ORIGIN_PLOT_AXIS: m_rbDrillAndPlotOrigin->SetValue( true ); break;
case STEP_ORIGIN_GRID_AXIS: m_rbGridOrigin->SetValue( true ); break;
case STEP_ORIGIN_USER: m_rbUserDefinedOrigin->SetValue( true ); break;
case STEP_ORIGIN_BOARD_CENTER: m_rbBoardCenterOrigin->SetValue( true ); break;
PCBNEW_SETTINGS* cfg = m_editFrame->GetPcbNewSettings();
m_origin = static_cast<STEP_ORIGIN_OPTION>( cfg->m_ExportStep.origin_mode );
switch( m_origin )
{
default:
case STEP_ORIGIN_PLOT_AXIS: m_rbDrillAndPlotOrigin->SetValue( true ); break;
case STEP_ORIGIN_GRID_AXIS: m_rbGridOrigin->SetValue( true ); break;
case STEP_ORIGIN_USER: m_rbUserDefinedOrigin->SetValue( true ); break;
case STEP_ORIGIN_BOARD_CENTER: m_rbBoardCenterOrigin->SetValue( true ); break;
}
m_originUnits = cfg->m_ExportStep.origin_units;
m_userOriginX = cfg->m_ExportStep.origin_x;
m_userOriginY = cfg->m_ExportStep.origin_y;
m_noUnspecified = cfg->m_ExportStep.no_unspecified;
m_noDNP = cfg->m_ExportStep.no_dnp;
m_txtNetFilter->SetValue( m_netFilter );
m_cbOptimizeStep->SetValue( m_optimizeStep );
m_cbExportBody->SetValue( m_exportBoardBody );
m_cbExportComponents->SetValue( m_exportComponents );
m_cbExportTracks->SetValue( m_exportTracks );
m_cbExportPads->SetValue( m_exportPads );
m_cbExportZones->SetValue( m_exportZones );
m_cbExportInnerCopper->SetValue( m_exportInnerCopper );
m_cbExportSilkscreen->SetValue( m_exportSilkscreen );
m_cbExportSoldermask->SetValue( m_exportSoldermask );
m_cbFuseShapes->SetValue( m_fuseShapes );
m_cbRemoveUnspecified->SetValue( m_noUnspecified );
m_cbRemoveDNP->SetValue( m_noDNP );
m_cbSubstModels->SetValue( cfg->m_ExportStep.replace_models );
m_cbOverwriteFile->SetValue( cfg->m_ExportStep.overwrite_file );
m_txtComponentFilter->SetValue( m_componentFilter );
switch( m_componentMode )
{
case COMPONENT_MODE::EXPORT_ALL: m_rbAllComponents->SetValue( true ); break;
case COMPONENT_MODE::EXPORT_SELECTED: m_rbOnlySelected->SetValue( true ); break;
case COMPONENT_MODE::CUSTOM_FILTER: m_rbFilteredComponents->SetValue( true ); break;
}
// Sync the enabled states
wxCommandEvent dummy;
DIALOG_EXPORT_STEP::onCbExportComponents( dummy );
m_STEP_OrgUnitChoice->SetSelection( m_originUnits );
wxString tmpStr;
tmpStr << m_userOriginX;
m_STEP_Xorg->SetValue( tmpStr );
tmpStr = wxEmptyString;
tmpStr << m_userOriginY;
m_STEP_Yorg->SetValue( tmpStr );
}
m_originUnits = cfg->m_ExportStep.origin_units;
m_userOriginX = cfg->m_ExportStep.origin_x;
m_userOriginY = cfg->m_ExportStep.origin_y;
m_noUnspecified = cfg->m_ExportStep.no_unspecified;
m_noDNP = cfg->m_ExportStep.no_dnp;
m_txtNetFilter->SetValue( m_netFilter );
m_cbOptimizeStep->SetValue( m_optimizeStep );
m_cbExportBody->SetValue( m_exportBoardBody );
m_cbExportComponents->SetValue( m_exportComponents );
m_cbExportTracks->SetValue( m_exportTracks );
m_cbExportPads->SetValue( m_exportPads );
m_cbExportZones->SetValue( m_exportZones );
m_cbExportInnerCopper->SetValue( m_exportInnerCopper );
m_cbExportSilkscreen->SetValue( m_exportSilkscreen );
m_cbExportSoldermask->SetValue( m_exportSoldermask );
m_cbFuseShapes->SetValue( m_fuseShapes );
m_cbRemoveUnspecified->SetValue( m_noUnspecified );
m_cbRemoveDNP->SetValue( m_noDNP );
m_cbSubstModels->SetValue( cfg->m_ExportStep.replace_models );
m_cbOverwriteFile->SetValue( cfg->m_ExportStep.overwrite_file );
m_txtComponentFilter->SetValue( m_componentFilter );
switch( m_componentMode )
{
case COMPONENT_MODE::EXPORT_ALL: m_rbAllComponents->SetValue( true ); break;
case COMPONENT_MODE::EXPORT_SELECTED: m_rbOnlySelected->SetValue( true ); break;
case COMPONENT_MODE::CUSTOM_FILTER: m_rbFilteredComponents->SetValue( true ); break;
}
// Sync the enabled states
wxCommandEvent dummy;
DIALOG_EXPORT_STEP::onCbExportComponents( dummy );
m_STEP_OrgUnitChoice->SetSelection( m_originUnits );
wxString tmpStr;
tmpStr << m_userOriginX;
m_STEP_Xorg->SetValue( tmpStr );
tmpStr = wxEmptyString;
tmpStr << m_userOriginY;
m_STEP_Yorg->SetValue( tmpStr );
wxString bad_scales;
size_t bad_count = 0;
@@ -424,261 +445,324 @@ void DIALOG_EXPORT_STEP::OnComponentModeChange( wxCommandEvent& event )
void DIALOG_EXPORT_STEP::onExportButton( wxCommandEvent& aEvent )
{
wxString path = m_outputFileName->GetValue();
m_editFrame->SetLastPath( LAST_PATH_STEP, path );
// Build the absolute path of current output directory to preselect it in the file browser.
std::function<bool( wxString* )> textResolver =
[&]( wxString* token ) -> bool
{
return m_editFrame->GetBoard()->ResolveTextVar( token, 0 );
};
path = ExpandTextVars( path, &textResolver );
path = ExpandEnvVarSubstitutions( path, &Prj() );
path = Prj().AbsolutePath( path );
if( path.IsEmpty() )
if( !m_job )
{
DisplayErrorMessage( this, _( "No filename for output file" ) );
return;
}
wxString path = m_outputFileName->GetValue();
m_editFrame->SetLastPath( LAST_PATH_STEP, path );
m_netFilter = m_txtNetFilter->GetValue();
m_componentFilter = m_txtComponentFilter->GetValue();
// Build the absolute path of current output directory to preselect it in the file browser.
std::function<bool( wxString* )> textResolver =
[&]( wxString* token ) -> bool
{
return m_editFrame->GetBoard()->ResolveTextVar( token, 0 );
};
if( m_rbAllComponents->GetValue() )
m_componentMode = COMPONENT_MODE::EXPORT_ALL;
else if( m_rbOnlySelected->GetValue() )
m_componentMode = COMPONENT_MODE::EXPORT_SELECTED;
else
m_componentMode = COMPONENT_MODE::CUSTOM_FILTER;
path = ExpandTextVars( path, &textResolver );
path = ExpandEnvVarSubstitutions( path, &Prj() );
path = Prj().AbsolutePath( path );
double tolerance; // default value in mm
m_toleranceLastChoice = m_choiceTolerance->GetSelection();
m_formatLastChoice = m_choiceFormat->GetSelection();
m_optimizeStep = m_cbOptimizeStep->GetValue();
m_exportBoardBody = m_cbExportBody->GetValue();
m_exportComponents = m_cbExportComponents->GetValue();
m_exportTracks = m_cbExportTracks->GetValue();
m_exportPads = m_cbExportPads->GetValue();
m_exportZones = m_cbExportZones->GetValue();
m_exportInnerCopper = m_cbExportInnerCopper->GetValue();
m_exportSilkscreen = m_cbExportSilkscreen->GetValue();
m_exportSoldermask = m_cbExportSoldermask->GetValue();
m_fuseShapes = m_cbFuseShapes->GetValue();
switch( m_choiceTolerance->GetSelection() )
{
case 0: tolerance = 0.001; break;
default:
case 1: tolerance = 0.01; break;
case 2: tolerance = 0.1; break;
}
SHAPE_POLY_SET outline;
wxString msg;
// Check if the board outline is continuous
// max dist from one endPt to next startPt to build a closed shape:
int chainingEpsilon = pcbIUScale.mmToIU( tolerance );
// Arc to segment approx error (not critical here: we do not use the outline shape):
int maxError = pcbIUScale.mmToIU( 0.005 );
bool success = BuildBoardPolygonOutlines( m_editFrame->GetBoard(), outline, maxError,
chainingEpsilon, nullptr );
if( !success )
{
DisplayErrorMessage( this, wxString::Format(
_( "Board outline is missing or not closed using %.3f mm tolerance.\n"
"Run DRC for a full analysis." ), tolerance ) );
return;
}
wxFileName fn( Prj().AbsolutePath( path ) );
if( fn.FileExists() && !GetOverwriteFile() )
{
msg.Printf( _( "File '%s' already exists. Do you want overwrite this file?" ),
fn.GetFullPath() );
if( wxMessageBox( msg, _( "STEP/GLTF Export" ), wxYES_NO | wxICON_QUESTION, this ) == wxNO )
return;
}
wxFileName appK2S( wxStandardPaths::Get().GetExecutablePath() );
#ifdef __WXMAC__
// On macOS, we have standalone applications inside the main bundle, so we handle that here:
if( appK2S.GetPath().Find( "/Contents/Applications/pcbnew.app/Contents/MacOS" ) != wxNOT_FOUND )
{
appK2S.AppendDir( wxT( ".." ) );
appK2S.AppendDir( wxT( ".." ) );
appK2S.AppendDir( wxT( ".." ) );
appK2S.AppendDir( wxT( ".." ) );
appK2S.AppendDir( wxT( "MacOS" ) );
}
#else
if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
{
appK2S.RemoveLastDir();
appK2S.AppendDir( "kicad" );
}
#endif
appK2S.SetName( wxT( "kicad-cli" ) );
appK2S.Normalize( FN_NORMALIZE_FLAGS );
wxString cmdK2S = wxT( "\"" );
cmdK2S.Append( appK2S.GetFullPath() );
cmdK2S.Append( wxT( "\"" ) );
cmdK2S.Append( wxT( " pcb" ) );
cmdK2S.Append( wxT( " export" ) );
cmdK2S.Append( wxT( " " ) );
cmdK2S.Append( c_formatCommand[m_choiceFormat->GetSelection()] );
if( GetNoUnspecifiedOption() )
cmdK2S.Append( wxT( " --no-unspecified" ) );
if( GetNoDNPOption() )
cmdK2S.Append( wxT( " --no-dnp" ) );
if( GetSubstOption() )
cmdK2S.Append( wxT( " --subst-models" ) );
if( !m_optimizeStep )
cmdK2S.Append( wxT( " --no-optimize-step" ) );
if( !m_exportBoardBody )
cmdK2S.Append( wxT( " --no-board-body" ) );
if( !m_exportComponents )
cmdK2S.Append( wxT( " --no-components" ) );
if( m_exportTracks )
cmdK2S.Append( wxT( " --include-tracks" ) );
if( m_exportPads )
cmdK2S.Append( wxT( " --include-pads" ) );
if( m_exportZones )
cmdK2S.Append( wxT( " --include-zones" ) );
if( m_exportInnerCopper )
cmdK2S.Append( wxT( " --include-inner-copper" ) );
if( m_exportSilkscreen )
cmdK2S.Append( wxT( " --include-silkscreen" ) );
if( m_exportSoldermask )
cmdK2S.Append( wxT( " --include-soldermask" ) );
if( m_fuseShapes )
cmdK2S.Append( wxT( " --fuse-shapes" ) );
// Note: for some reason, using \" to insert a quote in a format string, under MacOS
// wxString::Format does not work. So use a %c format in string
int quote = '\'';
int dblquote = '"';
if( !m_netFilter.empty() )
{
cmdK2S.Append( wxString::Format( wxT( " --net-filter %c%s%c" ), dblquote, m_netFilter,
dblquote ) );
}
switch( m_componentMode )
{
case COMPONENT_MODE::EXPORT_SELECTED:
{
wxArrayString components;
SELECTION& selection = m_editFrame->GetCurrentSelection();
std::for_each( selection.begin(), selection.end(),
[&components]( EDA_ITEM* item )
{
if( item->Type() == PCB_FOOTPRINT_T )
components.push_back( static_cast<FOOTPRINT*>( item )->GetReference() );
} );
cmdK2S.Append( wxString::Format( wxT( " --component-filter %c%s%c" ), dblquote,
wxJoin( components, ',' ), dblquote ) );
break;
}
case COMPONENT_MODE::CUSTOM_FILTER:
cmdK2S.Append( wxString::Format( wxT( " --component-filter %c%s%c" ), dblquote,
m_componentFilter, dblquote ) );
break;
default:
break;
}
switch( GetOriginOption() )
{
case STEP_ORIGIN_0:
wxFAIL_MSG( wxT( "Unsupported origin option: how did we get here?" ) );
break;
case STEP_ORIGIN_PLOT_AXIS:
cmdK2S.Append( wxT( " --drill-origin" ) );
break;
case STEP_ORIGIN_GRID_AXIS:
cmdK2S.Append( wxT( " --grid-origin" ) );
break;
case STEP_ORIGIN_USER:
{
double xOrg = GetXOrg();
double yOrg = GetYOrg();
if( GetOrgUnitsChoice() == 1 )
if( path.IsEmpty() )
{
// selected reference unit is in inches, and STEP units are mm
xOrg *= 25.4;
yOrg *= 25.4;
DisplayErrorMessage( this, _( "No filename for output file" ) );
return;
}
LOCALE_IO dummy;
cmdK2S.Append( wxString::Format( wxT( " --user-origin=%c%.6fx%.6fmm%c" ),
quote, xOrg, yOrg, quote ) );
break;
}
m_netFilter = m_txtNetFilter->GetValue();
m_componentFilter = m_txtComponentFilter->GetValue();
case STEP_ORIGIN_BOARD_CENTER:
if( m_rbAllComponents->GetValue() )
m_componentMode = COMPONENT_MODE::EXPORT_ALL;
else if( m_rbOnlySelected->GetValue() )
m_componentMode = COMPONENT_MODE::EXPORT_SELECTED;
else
m_componentMode = COMPONENT_MODE::CUSTOM_FILTER;
double tolerance; // default value in mm
m_toleranceLastChoice = m_choiceTolerance->GetSelection();
m_formatLastChoice = m_choiceFormat->GetSelection();
m_optimizeStep = m_cbOptimizeStep->GetValue();
m_exportBoardBody = m_cbExportBody->GetValue();
m_exportComponents = m_cbExportComponents->GetValue();
m_exportTracks = m_cbExportTracks->GetValue();
m_exportPads = m_cbExportPads->GetValue();
m_exportZones = m_cbExportZones->GetValue();
m_exportInnerCopper = m_cbExportInnerCopper->GetValue();
m_exportSilkscreen = m_cbExportSilkscreen->GetValue();
m_exportSoldermask = m_cbExportSoldermask->GetValue();
m_fuseShapes = m_cbFuseShapes->GetValue();
switch( m_choiceTolerance->GetSelection() )
{
case 0: tolerance = 0.001; break;
default:
case 1: tolerance = 0.01; break;
case 2: tolerance = 0.1; break;
}
SHAPE_POLY_SET outline;
wxString msg;
// Check if the board outline is continuous
// max dist from one endPt to next startPt to build a closed shape:
int chainingEpsilon = pcbIUScale.mmToIU( tolerance );
// Arc to segment approx error (not critical here: we do not use the outline shape):
int maxError = pcbIUScale.mmToIU( 0.005 );
bool success = BuildBoardPolygonOutlines( m_editFrame->GetBoard(), outline, maxError,
chainingEpsilon, nullptr );
if( !success )
{
DisplayErrorMessage( this, wxString::Format(
_( "Board outline is missing or not closed using %.3f mm tolerance.\n"
"Run DRC for a full analysis." ), tolerance ) );
return;
}
wxFileName fn( Prj().AbsolutePath( path ) );
if( fn.FileExists() && !GetOverwriteFile() )
{
msg.Printf( _( "File '%s' already exists. Do you want overwrite this file?" ),
fn.GetFullPath() );
if( wxMessageBox( msg, _( "STEP/GLTF Export" ), wxYES_NO | wxICON_QUESTION, this ) == wxNO )
return;
}
wxFileName appK2S( wxStandardPaths::Get().GetExecutablePath() );
#ifdef __WXMAC__
// On macOS, we have standalone applications inside the main bundle, so we handle that here:
if( appK2S.GetPath().Find( "/Contents/Applications/pcbnew.app/Contents/MacOS" ) != wxNOT_FOUND )
{
appK2S.AppendDir( wxT( ".." ) );
appK2S.AppendDir( wxT( ".." ) );
appK2S.AppendDir( wxT( ".." ) );
appK2S.AppendDir( wxT( ".." ) );
appK2S.AppendDir( wxT( "MacOS" ) );
}
#else
if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
{
appK2S.RemoveLastDir();
appK2S.AppendDir( "kicad" );
}
#endif
appK2S.SetName( wxT( "kicad-cli" ) );
appK2S.Normalize( FN_NORMALIZE_FLAGS );
wxString cmdK2S = wxT( "\"" );
cmdK2S.Append( appK2S.GetFullPath() );
cmdK2S.Append( wxT( "\"" ) );
cmdK2S.Append( wxT( " pcb" ) );
cmdK2S.Append( wxT( " export" ) );
cmdK2S.Append( wxT( " " ) );
cmdK2S.Append( c_formatCommand[m_choiceFormat->GetSelection()] );
if( GetNoUnspecifiedOption() )
cmdK2S.Append( wxT( " --no-unspecified" ) );
if( GetNoDNPOption() )
cmdK2S.Append( wxT( " --no-dnp" ) );
if( GetSubstOption() )
cmdK2S.Append( wxT( " --subst-models" ) );
if( !m_optimizeStep )
cmdK2S.Append( wxT( " --no-optimize-step" ) );
if( !m_exportBoardBody )
cmdK2S.Append( wxT( " --no-board-body" ) );
if( !m_exportComponents )
cmdK2S.Append( wxT( " --no-components" ) );
if( m_exportTracks )
cmdK2S.Append( wxT( " --include-tracks" ) );
if( m_exportPads )
cmdK2S.Append( wxT( " --include-pads" ) );
if( m_exportZones )
cmdK2S.Append( wxT( " --include-zones" ) );
if( m_exportInnerCopper )
cmdK2S.Append( wxT( " --include-inner-copper" ) );
if( m_exportSilkscreen )
cmdK2S.Append( wxT( " --include-silkscreen" ) );
if( m_exportSoldermask )
cmdK2S.Append( wxT( " --include-soldermask" ) );
if( m_fuseShapes )
cmdK2S.Append( wxT( " --fuse-shapes" ) );
// Note: for some reason, using \" to insert a quote in a format string, under MacOS
// wxString::Format does not work. So use a %c format in string
int quote = '\'';
int dblquote = '"';
if( !m_netFilter.empty() )
{
cmdK2S.Append( wxString::Format( wxT( " --net-filter %c%s%c" ), dblquote, m_netFilter,
dblquote ) );
}
switch( m_componentMode )
{
case COMPONENT_MODE::EXPORT_SELECTED:
{
wxArrayString components;
SELECTION& selection = m_editFrame->GetCurrentSelection();
std::for_each( selection.begin(), selection.end(),
[&components]( EDA_ITEM* item )
{
if( item->Type() == PCB_FOOTPRINT_T )
components.push_back( static_cast<FOOTPRINT*>( item )->GetReference() );
} );
cmdK2S.Append( wxString::Format( wxT( " --component-filter %c%s%c" ), dblquote,
wxJoin( components, ',' ), dblquote ) );
break;
}
case COMPONENT_MODE::CUSTOM_FILTER:
cmdK2S.Append( wxString::Format( wxT( " --component-filter %c%s%c" ), dblquote,
m_componentFilter, dblquote ) );
break;
default:
break;
}
switch( GetOriginOption() )
{
case STEP_ORIGIN_0:
wxFAIL_MSG( wxT( "Unsupported origin option: how did we get here?" ) );
break;
case STEP_ORIGIN_PLOT_AXIS:
cmdK2S.Append( wxT( " --drill-origin" ) );
break;
case STEP_ORIGIN_GRID_AXIS:
cmdK2S.Append( wxT( " --grid-origin" ) );
break;
case STEP_ORIGIN_USER:
{
double xOrg = GetXOrg();
double yOrg = GetYOrg();
if( GetOrgUnitsChoice() == 1 )
{
// selected reference unit is in inches, and STEP units are mm
xOrg *= 25.4;
yOrg *= 25.4;
}
LOCALE_IO dummy;
cmdK2S.Append( wxString::Format( wxT( " --user-origin=%c%.6fx%.6fmm%c" ),
quote, xOrg, yOrg, quote ) );
break;
}
case STEP_ORIGIN_BOARD_CENTER:
{
BOX2I bbox = m_editFrame->GetBoard()->ComputeBoundingBox( true );
double xOrg = pcbIUScale.IUTomm( bbox.GetCenter().x );
double yOrg = pcbIUScale.IUTomm( bbox.GetCenter().y );
LOCALE_IO dummy;
cmdK2S.Append( wxString::Format( wxT( " --user-origin=%c%.6fx%.6fmm%c" ),
quote, xOrg, yOrg, quote ) );
break;
}
}
{
LOCALE_IO dummy;
cmdK2S.Append( wxString::Format( wxT( " --min-distance=%c%.3fmm%c" ),
quote, tolerance, quote ) );
}
// Output file path.
cmdK2S.Append( wxString::Format( wxT( " -f -o %c%s%c" ),
dblquote, fn.GetFullPath(), dblquote ) );
// Input file path.
cmdK2S.Append( wxString::Format( wxT( " %c%s%c" ), dblquote, m_boardPath, dblquote ) );
wxLogTrace( traceKiCad2Step, wxT( "export step command: %s" ), cmdK2S );
DIALOG_EXPORT_STEP_LOG* log = new DIALOG_EXPORT_STEP_LOG( this, cmdK2S );
log->ShowModal();
}
else
{
BOX2I bbox = m_editFrame->GetBoard()->ComputeBoundingBox( true );
double xOrg = pcbIUScale.IUTomm( bbox.GetCenter().x );
double yOrg = pcbIUScale.IUTomm( bbox.GetCenter().y );
LOCALE_IO dummy;
m_job->SetOutputPath( m_outputFileName->GetValue() );
m_job->m_3dparams.m_NetFilter = m_txtNetFilter->GetValue();
m_job->m_3dparams.m_ComponentFilter = m_txtComponentFilter->GetValue();
m_job->m_3dparams.m_ExportBoardBody = m_cbExportBody->GetValue();
m_job->m_3dparams.m_ExportComponents = m_cbExportComponents->GetValue();
m_job->m_3dparams.m_ExportTracksVias = m_cbExportTracks->GetValue();
m_job->m_3dparams.m_ExportPads = m_cbExportPads->GetValue();
m_job->m_3dparams.m_ExportZones = m_cbExportZones->GetValue();
m_job->m_3dparams.m_ExportInnerCopper = m_cbExportInnerCopper->GetValue();
m_job->m_3dparams.m_ExportSilkscreen = m_cbExportSilkscreen->GetValue();
m_job->m_3dparams.m_ExportSoldermask = m_cbExportSoldermask->GetValue();
m_job->m_3dparams.m_FuseShapes = m_cbFuseShapes->GetValue();
m_job->m_3dparams.m_OptimizeStep = m_cbOptimizeStep->GetValue();
m_job->m_3dparams.m_Format = static_cast<EXPORTER_STEP_PARAMS::FORMAT>( m_choiceFormat->GetSelection() );
m_job->m_3dparams.m_Overwrite = m_cbOverwriteFile->GetValue();
m_job->m_3dparams.m_IncludeUnspecified = !m_cbRemoveUnspecified->GetValue();
m_job->m_3dparams.m_IncludeDNP = !m_cbRemoveDNP->GetValue();
m_job->m_3dparams.m_SubstModels = m_cbSubstModels->GetValue();
switch( GetOriginOption() )
{
case STEP_ORIGIN_0:
break;
case STEP_ORIGIN_PLOT_AXIS:
m_job->m_3dparams.m_UseDrillOrigin = true;
break;
case STEP_ORIGIN_GRID_AXIS:
m_job->m_3dparams.m_UseGridOrigin = true;
break;
case STEP_ORIGIN_USER:
{
double xOrg = GetXOrg();
double yOrg = GetYOrg();
if( GetOrgUnitsChoice() == 1 )
{
// selected reference unit is in inches, and STEP units are mm
xOrg *= 25.4;
yOrg *= 25.4;
}
m_job->m_3dparams.m_Origin = VECTOR2D( xOrg, yOrg );
break;
}
case STEP_ORIGIN_BOARD_CENTER:
{
BOX2I bbox = m_editFrame->GetBoard()->ComputeBoundingBox( true );
double xOrg = pcbIUScale.IUTomm( bbox.GetCenter().x );
double yOrg = pcbIUScale.IUTomm( bbox.GetCenter().y );
LOCALE_IO dummy;
m_job->m_3dparams.m_Origin = VECTOR2D( xOrg, yOrg );
break;
}
}
cmdK2S.Append( wxString::Format( wxT( " --user-origin=%c%.6fx%.6fmm%c" ),
quote, xOrg, yOrg, quote ) );
break;
}
}
{
LOCALE_IO dummy;
cmdK2S.Append( wxString::Format( wxT( " --min-distance=%c%.3fmm%c" ),
quote, tolerance, quote ) );
}
// Output file path.
cmdK2S.Append( wxString::Format( wxT( " -f -o %c%s%c" ),
dblquote, fn.GetFullPath(), dblquote ) );
// Input file path.
cmdK2S.Append( wxString::Format( wxT( " %c%s%c" ), dblquote, m_boardPath, dblquote ) );
wxLogTrace( traceKiCad2Step, wxT( "export step command: %s" ), cmdK2S );
DIALOG_EXPORT_STEP_LOG* log = new DIALOG_EXPORT_STEP_LOG( this, cmdK2S );
log->ShowModal();
}