Script plotting patch

This commit is contained in:
Lorenzo Marcantonio
2012-08-29 18:59:50 +02:00
parent 79d55c0460
commit fef8347176
68 changed files with 1535 additions and 1404 deletions
+337 -259
View File
@@ -46,6 +46,9 @@
#include <protos.h>
#include <dialog_plot_base.h>
#include <pcb_plot_params.h>
#include <pcb_plot_params_lexer.h>
#include <plotcontroller.h>
#include <wx/ffile.h>
/* Keywords to r/w options in m_config */
#define CONFIG_XFINESCALE_ADJ wxT( "PlotXFineScaleAdj" )
@@ -56,7 +59,6 @@
#define MIN_SCALE 0.01
#define MAX_SCALE 100.0
static bool setDouble( double* aDouble, double aValue, double aMin, double aMax )
{
if( aValue < aMin )
@@ -74,7 +76,135 @@ static bool setDouble( double* aDouble, double aValue, double aMin, double aMax
return true;
}
/** Get the 'traditional' gerber extension depending on the layer */
static wxString GetGerberExtension( int layer )/*{{{*/
{
switch( layer )
{
case LAYER_N_FRONT:
return wxString( wxT( "gtl" ) );
case LAYER_N_2:
case LAYER_N_3:
case LAYER_N_4:
case LAYER_N_5:
case LAYER_N_6:
case LAYER_N_7:
case LAYER_N_8:
case LAYER_N_9:
case LAYER_N_10:
case LAYER_N_11:
case LAYER_N_12:
case LAYER_N_13:
case LAYER_N_14:
case LAYER_N_15:
// TODO: see if we use .gbr or a layer identifier (gb1 .. gbnn ?)
// according to the new internal layers designation
// (1 is the first internal layer from the front layer)
return wxString( wxT( "gbr" ) );
case LAYER_N_BACK:
return wxString( wxT( "gbl" ) );
case ADHESIVE_N_BACK:
return wxString( wxT( "gba" ) );
case ADHESIVE_N_FRONT:
return wxString( wxT( "gta" ) );
case SOLDERPASTE_N_BACK:
return wxString( wxT( "gbp" ) );
case SOLDERPASTE_N_FRONT:
return wxString( wxT( "gtp" ) );
case SILKSCREEN_N_BACK:
return wxString( wxT( "gbo" ) );
case SILKSCREEN_N_FRONT:
return wxString( wxT( "gto" ) );
case SOLDERMASK_N_BACK:
return wxString( wxT( "gbs" ) );
case SOLDERMASK_N_FRONT:
return wxString( wxT( "gts" ) );
case DRAW_N:
case COMMENT_N:
case ECO1_N:
case ECO2_N:
case EDGE_N:
default:
return wxString( wxT( "gbr" ) );
}
}/*}}}*/
/** Complete a plot filename: forces the output directory, add a suffix to the name
and sets the extension if specified */
static void BuildPlotFileName( wxFileName *aFilename, /*{{{*/
const wxString& aOutputDir,
wxString aSuffix,
const wxString& aExtension )
{
aFilename->SetPath( aOutputDir );
// Set the file extension
aFilename->SetExt( aExtension );
/* remove leading and trailing spaces if any from the suffix, if
something survives add it to the name; also the suffix can contain
an extension: if that's the case, apply it */
aSuffix.Trim( true ); aSuffix.Trim( false );
wxFileName suffix_fn( aSuffix );
if( suffix_fn.HasName() )
aFilename->SetName( aFilename->GetName() + wxT( "-" ) + suffix_fn.GetName() );
if( suffix_fn.HasExt() )
aFilename->SetExt( suffix_fn.GetExt() );
}/*}}}*/
/** Fix the output directory pathname to absolute and ensure it exists */
static bool EnsureOutputDirectory( wxFileName *aOutputDir, /*{{{*/
const wxString& aBoardFilename,
wxTextCtrl* aMessageBox )
{
wxString boardFilePath = wxFileName( aBoardFilename ).GetPath();
if( !aOutputDir->MakeAbsolute( boardFilePath ) )
{
wxString msg;
msg.Printf( _( "Cannot make %s absolute with respect to %s!" ),
GetChars( aOutputDir->GetPath() ),
GetChars( boardFilePath ) );
wxMessageBox( msg, _( "Plot" ), wxOK | wxICON_ERROR );
return false;
}
wxString outputPath( aOutputDir->GetPath() );
if( !wxFileName::DirExists( outputPath ) )
{
if( wxMkdir( outputPath ) )
{
if( aMessageBox )
{
wxString msg;
msg.Printf( _( "Directory %s created.\n" ), GetChars( outputPath ) );
aMessageBox->AppendText( msg );
return true;
}
}
else
{
wxMessageBox( _( "Cannot create output directory!" ),
_( "Plot" ), wxOK | wxICON_ERROR );
return false;
}
}
return true;
}/*}}}*/
/**
* Class DIALOG_PLOT
@@ -111,8 +241,6 @@ private:
};
//const int UNITS_MILS = 1000;
DIALOG_PLOT::DIALOG_PLOT( PCB_EDIT_FRAME* aParent ) :
DIALOG_PLOT_BASE( aParent ),
m_parent( aParent ),
@@ -142,26 +270,26 @@ void DIALOG_PLOT::Init_Dialog()
m_WidthAdjustMinValue = -(m_board->GetDesignSettings().m_TrackMinWidth - 1);
m_WidthAdjustMaxValue = m_board->GetSmallestClearanceValue() - 1;
m_plotFormatOpt->SetSelection( m_plotOpts.GetPlotFormat() );
m_plotFormatOpt->SetSelection( m_plotOpts.GetFormat() );
// Set units and value for HPGL pen size (this param in in mils).
AddUnitSymbol( *m_textPenSize, g_UserUnit );
msg = ReturnStringFromValue( g_UserUnit,
m_plotOpts.GetHpglPenDiameter() * IU_PER_MILS );
m_plotOpts.GetHPGLPenDiameter() * IU_PER_MILS );
m_HPGLPenSizeOpt->AppendText( msg );
// Units are *always* cm/s for HPGL pen speed, from 1 to 99.
msg = ReturnStringFromValue( UNSCALED_UNITS, m_plotOpts.GetHpglPenSpeed() );
msg = ReturnStringFromValue( UNSCALED_UNITS, m_plotOpts.GetHPGLPenSpeed() );
m_HPGLPenSpeedOpt->AppendText( msg );
// Set units and value for HPGL pen overlay (this param in in mils).
AddUnitSymbol( *m_textPenOvr, g_UserUnit );
msg = ReturnStringFromValue( g_UserUnit,
m_plotOpts.GetHpglPenOverlay() * IU_PER_MILS );
m_plotOpts.GetHPGLPenOverlay() * IU_PER_MILS );
m_HPGLPenOverlayOpt->AppendText( msg );
AddUnitSymbol( *m_textDefaultPenSize, g_UserUnit );
msg = ReturnStringFromValue( g_UserUnit, m_plotOpts.GetPlotLineWidth() );
msg = ReturnStringFromValue( g_UserUnit, m_plotOpts.GetLineWidth() );
m_linesWidth->AppendText( msg );
// Set units for PS global width correction.
@@ -187,8 +315,8 @@ void DIALOG_PLOT::Init_Dialog()
msg.Printf( wxT( "%f" ), To_User_Unit( g_UserUnit, m_PSWidthAdjust ) );
m_PSFineAdjustWidthOpt->AppendText( msg );
m_plotPSNegativeOpt->SetValue( m_plotOpts.m_PlotPSNegative );
m_forcePSA4OutputOpt->SetValue( m_plotOpts.GetPsA4Output() );
m_plotPSNegativeOpt->SetValue( m_plotOpts.GetNegative() );
m_forcePSA4OutputOpt->SetValue( m_plotOpts.GetA4Output() );
// List layers in same order than in setup layers dialog
// (Front or Top to Back or Bottom)
@@ -215,44 +343,36 @@ void DIALOG_PLOT::Init_Dialog()
m_useGerberExtensions->SetValue( m_plotOpts.GetUseGerberExtensions() );
// Option for excluding contents of "Edges Pcb" layer
m_excludeEdgeLayerOpt->SetValue( m_plotOpts.m_ExcludeEdgeLayer );
m_excludeEdgeLayerOpt->SetValue( m_plotOpts.GetExcludeEdgeLayer() );
m_subtractMaskFromSilk->SetValue( m_plotOpts.GetSubtractMaskFromSilk() );
// Option to plot page references:
if( m_parent->GetPrintBorderAndTitleBlock() )
{
m_plotSheetRef->SetValue( m_plotOpts.m_PlotFrameRef );
}
else
{
m_plotSheetRef->Enable( false );
m_plotSheetRef->SetValue( false );
}
m_plotSheetRef->SetValue( m_plotOpts.GetPlotFrameRef() );
// Option to plot pads on silkscreen layers or all layers
m_plotPads_on_Silkscreen->SetValue( m_plotOpts.m_PlotPadsOnSilkLayer );
// Option to allow pads on silkscreen layers
m_plotPads_on_Silkscreen->SetValue( m_plotOpts.GetPlotPadsOnSilkLayer() );
// Options to plot texts on footprints
m_plotModuleValueOpt->SetValue( m_plotOpts.m_PlotValue );
m_plotModuleRefOpt->SetValue( m_plotOpts.m_PlotReference );
m_plotTextOther->SetValue( m_plotOpts.m_PlotTextOther );
m_plotInvisibleText->SetValue( m_plotOpts.m_PlotInvisibleTexts );
m_plotModuleValueOpt->SetValue( m_plotOpts.GetPlotValue() );
m_plotModuleRefOpt->SetValue( m_plotOpts.GetPlotReference() );
m_plotTextOther->SetValue( m_plotOpts.GetPlotOtherText() );
m_plotInvisibleText->SetValue( m_plotOpts.GetPlotInvisibleText() );
// Options to plot pads and vias holes
m_drillShapeOpt->SetSelection( m_plotOpts.m_DrillShapeOpt );
m_drillShapeOpt->SetSelection( m_plotOpts.GetDrillMarksType() );
// Scale option
m_scaleOpt->SetSelection( m_plotOpts.GetScaleSelection() );
// Plot mode
m_plotModeOpt->SetSelection( m_plotOpts.m_PlotMode );
m_plotModeOpt->SetSelection( m_plotOpts.GetMode() );
// Plot mirror option
m_plotMirrorOpt->SetValue( m_plotOpts.m_PlotMirror );
m_plotMirrorOpt->SetValue( m_plotOpts.GetMirror() );
// Put vias on mask layer
m_plotNoViaOnMaskOpt->SetValue( m_plotOpts.m_PlotViaOnMaskLayer );
m_plotNoViaOnMaskOpt->SetValue( m_plotOpts.GetPlotViaOnMaskLayer() );
// Output directory
m_outputDirectoryName->SetValue( m_plotOpts.GetOutputDirectory() );
@@ -319,7 +439,7 @@ void DIALOG_PLOT::OnOutputDirectoryBrowseClicked( wxCommandEvent& event )
wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT );
if( dialog.ShowModal() == wxID_YES ) {
wxString boardFilePath = ( (wxFileName) m_parent->GetScreen()->GetFileName()).GetPath();
wxString boardFilePath = ( (wxFileName) m_parent->GetBoard()->GetFileName()).GetPath();
if( !dirName.MakeRelativeTo( boardFilePath ) )
wxMessageBox( _( "Cannot make path relative (target volume different from board file volume)!" ),
@@ -335,37 +455,39 @@ void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event )
switch( m_plotFormatOpt->GetSelection() )
{
case PLOT_FORMAT_POST:
default:
m_drillShapeOpt->Enable( true );
m_plotModeOpt->Enable( true );
m_plotMirrorOpt->Enable( true );
m_useAuxOriginCheckBox->Enable( false );
m_useAuxOriginCheckBox->SetValue( false );
m_linesWidth->Enable( true );
m_HPGLPenSizeOpt->Enable( false );
m_HPGLPenSpeedOpt->Enable( false );
m_HPGLPenOverlayOpt->Enable( false );
m_excludeEdgeLayerOpt->SetValue( false );
m_excludeEdgeLayerOpt->Enable( false );
m_excludeEdgeLayerOpt->Enable( true );
m_subtractMaskFromSilk->Enable( false );
m_subtractMaskFromSilk->SetValue( false );
m_useGerberExtensions->Enable( false );
m_useGerberExtensions->SetValue( false );
m_scaleOpt->Enable( true );
m_fineAdjustXscaleOpt->Enable( true );
m_fineAdjustYscaleOpt->Enable( true );
m_PSFineAdjustWidthOpt->Enable( true );
m_plotPSNegativeOpt->Enable( true );
m_forcePSA4OutputOpt->Enable( true );
m_PlotOptionsSizer->Hide( m_GerberOptionsSizer );
m_PlotOptionsSizer->Hide( m_HPGLOptionsSizer );
m_PlotOptionsSizer->Show( m_PSOptionsSizer );
Layout();
m_MainSizer->SetSizeHints( this );
break;
case PLOT_FORMAT_GERBER:
m_drillShapeOpt->Enable( false );
m_plotModeOpt->SetSelection( 1 );
m_drillShapeOpt->SetSelection( 0 );
m_plotModeOpt->Enable( false );
m_plotMirrorOpt->SetValue( false );
m_plotModeOpt->SetSelection( 1 );
m_plotMirrorOpt->Enable( false );
m_plotMirrorOpt->SetValue( false );
m_useAuxOriginCheckBox->Enable( true );
m_linesWidth->Enable( true );
m_HPGLPenSizeOpt->Enable( false );
@@ -374,74 +496,89 @@ void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event )
m_excludeEdgeLayerOpt->Enable( true );
m_subtractMaskFromSilk->Enable( true );
m_useGerberExtensions->Enable( true );
m_scaleOpt->SetSelection( 1 );
m_scaleOpt->Enable( false );
m_scaleOpt->SetSelection( 1 );
m_fineAdjustXscaleOpt->Enable( false );
m_fineAdjustYscaleOpt->Enable( false );
m_PSFineAdjustWidthOpt->Enable( false );
m_plotPSNegativeOpt->SetValue( false );
m_plotPSNegativeOpt->Enable( false );
m_plotPSNegativeOpt->SetValue( false );
m_forcePSA4OutputOpt->Enable( false );
m_forcePSA4OutputOpt->SetValue( false );
m_PlotOptionsSizer->Show( m_GerberOptionsSizer );
m_PlotOptionsSizer->Hide( m_HPGLOptionsSizer );
m_PlotOptionsSizer->Hide( m_PSOptionsSizer );
Layout();
m_MainSizer->SetSizeHints( this );
break;
case PLOT_FORMAT_HPGL:
m_plotMirrorOpt->Enable( true );
m_drillShapeOpt->Enable( false );
m_drillShapeOpt->Enable( true );
m_plotModeOpt->Enable( true );
m_plotMirrorOpt->Enable( true );
m_useAuxOriginCheckBox->Enable( false );
m_useAuxOriginCheckBox->SetValue( false );
m_linesWidth->Enable( false );
m_HPGLPenSizeOpt->Enable( true );
m_HPGLPenSpeedOpt->Enable( true );
m_HPGLPenOverlayOpt->Enable( true );
m_excludeEdgeLayerOpt->SetValue( false );
m_excludeEdgeLayerOpt->Enable( false );
m_excludeEdgeLayerOpt->Enable( true );
m_subtractMaskFromSilk->Enable( false );
m_subtractMaskFromSilk->SetValue( false );
m_useGerberExtensions->Enable( false );
m_useGerberExtensions->SetValue( false );
m_scaleOpt->Enable( true );
m_fineAdjustXscaleOpt->Enable( false );
m_fineAdjustYscaleOpt->Enable( false );
m_PSFineAdjustWidthOpt->Enable( false );
m_plotPSNegativeOpt->SetValue( false );
m_plotPSNegativeOpt->Enable( false );
m_forcePSA4OutputOpt->Enable( true );
m_PlotOptionsSizer->Hide( m_GerberOptionsSizer );
m_PlotOptionsSizer->Show( m_HPGLOptionsSizer );
m_PlotOptionsSizer->Hide( m_PSOptionsSizer );
Layout();
m_MainSizer->SetSizeHints( this );
break;
case PLOT_FORMAT_DXF:
m_drillShapeOpt->Enable( true );
m_plotModeOpt->Enable( true );
m_plotMirrorOpt->Enable( false );
m_plotMirrorOpt->SetValue( false );
m_drillShapeOpt->Enable( false );
m_plotModeOpt->Enable( true );
m_useAuxOriginCheckBox->Enable( false );
m_useAuxOriginCheckBox->Enable( true );
m_linesWidth->Enable( false );
m_HPGLPenSizeOpt->Enable( false );
m_HPGLPenSpeedOpt->Enable( false );
m_HPGLPenOverlayOpt->Enable( false );
m_excludeEdgeLayerOpt->SetValue( false );
m_excludeEdgeLayerOpt->Enable( false );
m_excludeEdgeLayerOpt->Enable( true );
m_subtractMaskFromSilk->Enable( false );
m_subtractMaskFromSilk->SetValue( false );
m_useGerberExtensions->Enable( false );
m_useGerberExtensions->SetValue( false );
m_scaleOpt->Enable( false );
m_scaleOpt->SetSelection( 1 );
m_fineAdjustXscaleOpt->Enable( false );
m_fineAdjustYscaleOpt->Enable( false );
m_PSFineAdjustWidthOpt->Enable( false );
m_plotPSNegativeOpt->SetValue( false );
m_plotPSNegativeOpt->Enable( false );
m_PlotOptionsSizer->Hide( m_GerberOptionsSizer );
m_plotPSNegativeOpt->SetValue( false );
m_forcePSA4OutputOpt->Enable( false );
m_forcePSA4OutputOpt->SetValue( false );
m_PlotOptionsSizer->Show( m_GerberOptionsSizer );
m_PlotOptionsSizer->Hide( m_HPGLOptionsSizer );
m_PlotOptionsSizer->Hide( m_PSOptionsSizer );
Layout();
m_MainSizer->SetSizeHints( this );
break;
default:
wxASSERT( false );
}
/* Update the interlock between scale and frame reference
* (scaling would mess up the frame border...) */
OnSetScaleOpt( event );
Layout();
m_MainSizer->SetSizeHints( this );
}
@@ -449,29 +586,28 @@ void DIALOG_PLOT::applyPlotSettings()
{
PCB_PLOT_PARAMS tempOptions;
tempOptions.m_ExcludeEdgeLayer = m_excludeEdgeLayerOpt->GetValue();
tempOptions.SetExcludeEdgeLayer( m_excludeEdgeLayerOpt->GetValue() );
tempOptions.SetSubtractMaskFromSilk( m_subtractMaskFromSilk->GetValue() );
if( m_plotSheetRef )
tempOptions.m_PlotFrameRef = m_plotSheetRef->GetValue();
tempOptions.SetPlotFrameRef( m_plotSheetRef->GetValue() );
tempOptions.m_PlotPadsOnSilkLayer = m_plotPads_on_Silkscreen->GetValue();
tempOptions.SetPlotPadsOnSilkLayer( m_plotPads_on_Silkscreen->GetValue() );
tempOptions.SetUseAuxOrigin( m_useAuxOriginCheckBox->GetValue() );
tempOptions.m_PlotValue = m_plotModuleValueOpt->GetValue();
tempOptions.m_PlotReference = m_plotModuleRefOpt->GetValue();
tempOptions.m_PlotTextOther = m_plotTextOther->GetValue();
tempOptions.m_PlotInvisibleTexts = m_plotInvisibleText->GetValue();
tempOptions.SetPlotValue( m_plotModuleValueOpt->GetValue() );
tempOptions.SetPlotReference( m_plotModuleRefOpt->GetValue() );
tempOptions.SetPlotOtherText( m_plotTextOther->GetValue() );
tempOptions.SetPlotInvisibleText( m_plotInvisibleText->GetValue() );
tempOptions.SetScaleSelection( m_scaleOpt->GetSelection() );
tempOptions.m_DrillShapeOpt =
(PCB_PLOT_PARAMS::DrillShapeOptT) m_drillShapeOpt->GetSelection();
tempOptions.m_PlotMirror = m_plotMirrorOpt->GetValue();
tempOptions.m_PlotMode = (EDA_DRAW_MODE_T) m_plotModeOpt->GetSelection();
tempOptions.m_PlotViaOnMaskLayer = m_plotNoViaOnMaskOpt->GetValue();
tempOptions.SetDrillMarksType( static_cast<PCB_PLOT_PARAMS::DrillMarksType>
( m_drillShapeOpt->GetSelection() ) );
tempOptions.SetMirror( m_plotMirrorOpt->GetValue() );
tempOptions.SetMode( static_cast<EDA_DRAW_MODE_T>( m_plotModeOpt->GetSelection() ) );
tempOptions.SetPlotViaOnMaskLayer( m_plotNoViaOnMaskOpt->GetValue() );
// Update settings from text fields. Rewrite values back to the fields,
// since the values may have been constrained by the setters.
@@ -480,9 +616,9 @@ void DIALOG_PLOT::applyPlotSettings()
wxString msg = m_HPGLPenSizeOpt->GetValue();
int tmp = ReturnValueFromString( g_UserUnit, msg ) / IU_PER_MILS;
if( !tempOptions.SetHpglPenDiameter( tmp ) )
if( !tempOptions.SetHPGLPenDiameter( tmp ) )
{
msg = ReturnStringFromValue( g_UserUnit, tempOptions.GetHpglPenDiameter() * IU_PER_MILS );
msg = ReturnStringFromValue( g_UserUnit, tempOptions.GetHPGLPenDiameter() * IU_PER_MILS );
m_HPGLPenSizeOpt->SetValue( msg );
msg.Printf( _( "HPGL pen size constrained!\n" ) );
m_messagesBox->AppendText( msg );
@@ -492,9 +628,9 @@ void DIALOG_PLOT::applyPlotSettings()
msg = m_HPGLPenSpeedOpt->GetValue();
tmp = ReturnValueFromString( UNSCALED_UNITS, msg );
if( !tempOptions.SetHpglPenSpeed( tmp ) )
if( !tempOptions.SetHPGLPenSpeed( tmp ) )
{
msg = ReturnStringFromValue( UNSCALED_UNITS, tempOptions.GetHpglPenSpeed() );
msg = ReturnStringFromValue( UNSCALED_UNITS, tempOptions.GetHPGLPenSpeed() );
m_HPGLPenSpeedOpt->SetValue( msg );
msg.Printf( _( "HPGL pen speed constrained!\n" ) );
m_messagesBox->AppendText( msg );
@@ -504,10 +640,10 @@ void DIALOG_PLOT::applyPlotSettings()
msg = m_HPGLPenOverlayOpt->GetValue();
tmp = ReturnValueFromString( g_UserUnit, msg ) / IU_PER_MILS;
if( !tempOptions.SetHpglPenOverlay( tmp ) )
if( !tempOptions.SetHPGLPenOverlay( tmp ) )
{
msg = ReturnStringFromValue( g_UserUnit,
tempOptions.GetHpglPenOverlay() * IU_PER_MILS );
tempOptions.GetHPGLPenOverlay() * IU_PER_MILS );
m_HPGLPenOverlayOpt->SetValue( msg );
msg.Printf( _( "HPGL pen overlay constrained!\n" ) );
m_messagesBox->AppendText( msg );
@@ -517,9 +653,9 @@ void DIALOG_PLOT::applyPlotSettings()
msg = m_linesWidth->GetValue();
tmp = ReturnValueFromString( g_UserUnit, msg );
if( !tempOptions.SetPlotLineWidth( tmp ) )
if( !tempOptions.SetLineWidth( tmp ) )
{
msg = ReturnStringFromValue( g_UserUnit, tempOptions.GetPlotLineWidth() );
msg = ReturnStringFromValue( g_UserUnit, tempOptions.GetLineWidth() );
m_linesWidth->SetValue( msg );
msg.Printf( _( "Default linewidth constrained!\n" ) );
m_messagesBox->AppendText( msg );
@@ -575,7 +711,7 @@ void DIALOG_PLOT::applyPlotSettings()
tempOptions.SetUseGerberExtensions( m_useGerberExtensions->GetValue() );
tempOptions.SetPlotFormat( m_plotFormatOpt->GetSelection() );
tempOptions.SetFormat( static_cast<PlotFormat>( m_plotFormatOpt->GetSelection() ) );
long selectedLayers = 0;
unsigned int i;
@@ -587,8 +723,8 @@ void DIALOG_PLOT::applyPlotSettings()
}
tempOptions.SetLayerSelection( selectedLayers );
tempOptions.m_PlotPSNegative = m_plotPSNegativeOpt->GetValue();
tempOptions.SetPsA4Output( m_forcePSA4OutputOpt->GetValue() );
tempOptions.SetNegative( m_plotPSNegativeOpt->GetValue() );
tempOptions.SetA4Output( m_forcePSA4OutputOpt->GetValue() );
// Set output directory and replace backslashes with forward ones
wxString dirStr;
@@ -608,63 +744,37 @@ void DIALOG_PLOT::applyPlotSettings()
void DIALOG_PLOT::Plot( wxCommandEvent& event )
{
int layer;
wxFileName fn;
wxString ext;
applyPlotSettings();
// Create output directory if it does not exist
// Create output directory if it does not exist (also transform it in
// absolute form). Bail if it fails
wxFileName outputDir = wxFileName::DirName( m_plotOpts.GetOutputDirectory() );
wxString boardFilePath = ( (wxFileName) m_parent->GetScreen()->GetFileName()).GetPath();
if( !outputDir.MakeAbsolute( boardFilePath ) )
{
wxString msg;
msg.Printf( _( " Cannot make %s absolute with respect to %s!" ),
GetChars( outputDir.GetPath() ),
GetChars( boardFilePath ) );
wxMessageBox( msg, _( "Plot" ), wxOK | wxICON_ERROR );
wxString boardFilename = m_parent->GetBoard()->GetFileName();
if( !EnsureOutputDirectory( &outputDir, boardFilename, m_messagesBox ) )
return;
}
if( !wxFileName::DirExists( outputDir.GetPath() ) )
{
if( wxMkdir( outputDir.GetPath() ) )
{
wxString msg;
msg.Printf( _( "Directory %s created.\n" ), GetChars( outputDir.GetPath() ) );
m_messagesBox->AppendText( msg );
}
else
{
wxMessageBox( _( "Cannot create output directory!" ),
_( "Plot" ), wxOK | wxICON_ERROR );
return;
}
}
m_plotOpts.m_AutoScale = false;
m_plotOpts.m_PlotScale = 1;
m_plotOpts.SetAutoScale( false );
m_plotOpts.SetScale( 1 );
switch( m_plotOpts.GetScaleSelection() )
{
default:
break;
case 0:
m_plotOpts.m_AutoScale = true;
case 0: // Autoscale option
m_plotOpts.SetAutoScale( true );
break;
case 2:
m_plotOpts.m_PlotScale = 1.5;
case 2: // 3:2 option
m_plotOpts.SetScale( 1.5 );
break;
case 3:
m_plotOpts.m_PlotScale = 2;
case 3: // 2:1 option
m_plotOpts.SetScale( 2 );
break;
case 4:
m_plotOpts.m_PlotScale = 3;
case 4: // 3:1 option
m_plotOpts.SetScale( 3 );
break;
}
@@ -674,176 +784,66 @@ void DIALOG_PLOT::Plot( wxCommandEvent& event )
* settings resulting in a divide by zero fault.
*/
if( m_fineAdjustXscaleOpt->IsEnabled() && m_XScaleAdjust != 0.0 )
m_plotOpts.m_FineScaleAdjustX = m_XScaleAdjust;
m_plotOpts.SetFineScaleAdjustX( m_XScaleAdjust );
if( m_fineAdjustYscaleOpt->IsEnabled() && m_YScaleAdjust != 0.0 )
m_plotOpts.m_FineScaleAdjustY = m_YScaleAdjust;
m_plotOpts.SetFineScaleAdjustY( m_YScaleAdjust );
if( m_PSFineAdjustWidthOpt->IsEnabled() )
m_plotOpts.m_FineWidthAdjust = m_PSWidthAdjust;
m_plotOpts.SetWidthAdjust( m_PSWidthAdjust );
switch( m_plotOpts.GetPlotFormat() )
{
case PLOT_FORMAT_POST:
ext = wxT( "ps" );
break;
case PLOT_FORMAT_GERBER:
m_plotOpts.m_PlotScale = 1.0; // No scale option allowed in gerber format
ext = wxT( "pho" );
break;
case PLOT_FORMAT_HPGL:
ext = wxT( "plt" );
break;
case PLOT_FORMAT_DXF:
m_plotOpts.m_PlotScale = 1.0;
ext = wxT( "dxf" );
break;
}
wxString file_ext( GetDefaultPlotExtension( m_plotOpts.GetFormat() ) );
// Test for a reasonable scale value
if( m_plotOpts.m_PlotScale < MIN_SCALE )
// XXX could this actually happen? isn't it constrained in the apply
// function?
if( m_plotOpts.GetScale() < MIN_SCALE )
DisplayInfoMessage( this,
_( "Warning: Scale option set to a very small value" ) );
if( m_plotOpts.m_PlotScale > MAX_SCALE )
if( m_plotOpts.GetScale() > MAX_SCALE )
DisplayInfoMessage( this,
_( "Warning: Scale option set to a very large value" ) );
// Save the current plot options in the board
m_parent->SetPlotSettings( m_plotOpts );
long layerMask = 1;
for( layer = 0; layer < NB_LAYERS; layer++, layerMask <<= 1 )
{
bool success = false;
if( m_plotOpts.GetLayerSelection() & layerMask )
{
fn = m_parent->GetScreen()->GetFileName();
fn.SetPath( outputDir.GetPath() );
// Create file name (from the English layer name for non copper layers).
wxString layername = m_board->GetLayerName( layer, false );
// remove leading and trailing spaces if any
layername.Trim( true ); layername.Trim( false );
fn.SetName( fn.GetName() + wxT( "-" ) + layername );
// Pick the basename from the board file
wxFileName fn( boardFilename );
// Use Gerber Extensions based on layer number
// (See http://en.wikipedia.org/wiki/Gerber_File)
if( ( m_plotOpts.GetPlotFormat() == PLOT_FORMAT_GERBER )
if( ( m_plotOpts.GetFormat() == PLOT_FORMAT_GERBER )
&& m_useGerberExtensions->GetValue() )
{
switch( layer )
{
case LAYER_N_FRONT:
fn.SetExt( wxT( "gtl" ) );
break;
file_ext = GetGerberExtension( layer );
case LAYER_N_2:
case LAYER_N_3:
case LAYER_N_4:
case LAYER_N_5:
case LAYER_N_6:
case LAYER_N_7:
case LAYER_N_8:
case LAYER_N_9:
case LAYER_N_10:
case LAYER_N_11:
case LAYER_N_12:
case LAYER_N_13:
case LAYER_N_14:
case LAYER_N_15:
// Create file name (from the English layer name for non copper layers).
BuildPlotFileName( &fn, outputDir.GetPath(),
m_board->GetLayerName( layer, false ),
file_ext );
// TODO: see if we use .gbr or a layer identifier (gb1 .. gbnn ?)
// according to the new internal layers designation
// (1 is the first internal layer from the front layer)
fn.SetExt( wxT( "gbr" ) );
break;
case LAYER_N_BACK:
fn.SetExt( wxT( "gbl" ) );
break;
case ADHESIVE_N_BACK:
fn.SetExt( wxT( "gba" ) );
break;
case ADHESIVE_N_FRONT:
fn.SetExt( wxT( "gta" ) );
break;
case SOLDERPASTE_N_BACK:
fn.SetExt( wxT( "gbp" ) );
break;
case SOLDERPASTE_N_FRONT:
fn.SetExt( wxT( "gtp" ) );
break;
case SILKSCREEN_N_BACK:
fn.SetExt( wxT( "gbo" ) );
break;
case SILKSCREEN_N_FRONT:
fn.SetExt( wxT( "gto" ) );
break;
case SOLDERMASK_N_BACK:
fn.SetExt( wxT( "gbs" ) );
break;
case SOLDERMASK_N_FRONT:
fn.SetExt( wxT( "gts" ) );
break;
case DRAW_N:
case COMMENT_N:
case ECO1_N:
case ECO2_N:
case EDGE_N:
default:
fn.SetExt( wxT( "gbr" ) );
break;
}
}
else
{
fn.SetExt( ext );
}
switch( m_plotOpts.GetPlotFormat() )
{
case PLOT_FORMAT_POST:
success = m_parent->ExportToPostScriptFile( fn.GetFullPath(), layer,
m_plotOpts.GetPsA4Output(),
m_plotOpts.m_PlotMode );
break;
case PLOT_FORMAT_GERBER:
success = m_parent->ExportToGerberFile( fn.GetFullPath(), layer,
m_plotOpts.GetUseAuxOrigin(),
m_plotOpts.m_PlotMode );
break;
case PLOT_FORMAT_HPGL:
success = m_parent->ExportToHpglFile( fn.GetFullPath(), layer,
m_plotOpts.m_PlotMode );
break;
case PLOT_FORMAT_DXF:
success = m_parent->ExportToDxfFile( fn.GetFullPath(), layer,
m_plotOpts.m_PlotMode );
break;
}
LOCALE_IO toggle;
BOARD *board = m_parent->GetBoard();
PLOTTER *plotter = StartPlotBoard(board, &m_plotOpts,
fn.GetFullPath(),
wxEmptyString );
// Print diags in messages box:
wxString msg;
if( plotter )
{
PlotBoardLayer( board, plotter, layer, m_plotOpts );
plotter->EndPlot();
delete plotter;
if( success )
msg.Printf( _( "Plot file <%s> created" ), GetChars( fn.GetFullPath() ) );
}
else
msg.Printf( _( "Unable to create <%s>" ), GetChars( fn.GetFullPath() ) );
@@ -864,3 +864,81 @@ void PCB_EDIT_FRAME::ToPlotter( wxCommandEvent& event )
DIALOG_PLOT dlg( this );
dlg.ShowModal();
}
/** Batch plotter constructor, nothing interesting here */
PLOT_CONTROLLER::PLOT_CONTROLLER( BOARD *aBoard )
: m_plotter( NULL ), m_board( aBoard )
{
}
/** Batch plotter destructor, ensures that the last plot is closed */
PLOT_CONTROLLER::~PLOT_CONTROLLER()
{
ClosePlot();
}
/* IMPORTANT THING TO KNOW: the locale during plots *MUST* be kept as
* C/POSIX using a LOCALE_IO object on the stack. This even when
* opening/closing the plotfile, since some drivers do I/O even then */
/** Close the current plot, nothing happens if it isn't open */
void PLOT_CONTROLLER::ClosePlot()
{
LOCALE_IO toggle;
if( m_plotter )
{
m_plotter->EndPlot();
delete m_plotter;
m_plotter = NULL;
}
}
/** Open a new plotfile; works as a factory for plotter objects
*/
bool PLOT_CONTROLLER::OpenPlotfile( const wxString &aSuffix, /*{{{*/
PlotFormat aFormat,
const wxString &aSheetDesc )
{
LOCALE_IO toggle;
/* Save the current format: sadly some plot routines depends on this
but the main reason is that the StartPlot method uses it to
dispatch the plotter creation */
m_plotOpts.SetFormat( aFormat );
// Ensure that the previous plot is closed
ClosePlot();
// Now compute the full filename for the output and start the plot
// (after ensuring the output directory is OK)
wxString outputDirName = m_plotOpts.GetOutputDirectory() ;
wxFileName outputDir = wxFileName::DirName( outputDirName );
wxString boardFilename = m_board->GetFileName();
if( EnsureOutputDirectory( &outputDir, boardFilename, NULL ) )
{
wxFileName fn( boardFilename );
BuildPlotFileName( &fn, outputDirName,
aSuffix, GetDefaultPlotExtension( aFormat ) );
m_plotter = StartPlotBoard( m_board, &m_plotOpts, fn.GetFullPath(),
aSheetDesc );
}
return( m_plotter != NULL );
}/*}}}*/
/** Plot a single layer on the current plotfile */
bool PLOT_CONTROLLER::PlotLayer( int aLayer )/*{{{*/
{
LOCALE_IO toggle;
// No plot open, nothing to do...
if( !m_plotter )
return false;
// Fully delegated to the parent
PlotBoardLayer( m_board, m_plotter, aLayer, m_plotOpts );
return true;
}/*}}}*/