Commit 699c76cc authored by jean-pierre charras's avatar jean-pierre charras

Rework on EXCELLON_WRITER class, to allow gerber and drill files creation from a python script.

added the example gen_gerber_and_drill_files_board.py in demos, which shows how to do that.
Fix a Printf format issue (shown in Debug mode) in Libedit (%d used for a size_t, changed in %zu)
parent 569c2be3
'''
A python script example to create plot files to build a board:
Gerber files
Drill files
Map dril files
Important note:
this python script does not plot frame references (page layout).
the reason is it is not yet possible from a python script because plotting
plot frame references needs loading the corresponding page layout file
(.wks file) or the default template.
This info (the page layout template) is not stored in the board, and therefore
not available.
Do not try to change SetPlotFrameRef(False) to SetPlotFrameRef(true)
the result is the pcbnew lib will crash if you try to plot
the unknown frame references template.
Anyway, in gerber and drill files the page layout is not plot
'''
import sys
from pcbnew import *
filename=sys.argv[1]
board = LoadBoard(filename)
plotDir = "plot/"
pctl = PLOT_CONTROLLER(board)
popt = pctl.GetPlotOptions()
popt.SetOutputDirectory(plotDir)
# Set some important plot options:
popt.SetPlotFrameRef(False)
popt.SetLineWidth(FromMM(0.35))
popt.SetAutoScale(False)
popt.SetScale(1)
popt.SetMirror(False)
popt.SetUseGerberAttributes(True)
popt.SetExcludeEdgeLayer(False);
popt.SetScale(1)
popt.SetUseAuxOrigin(True)
# This by gerbers only (also the name is truly horrid!)
popt.SetSubtractMaskFromSilk(False)
# Once the defaults are set it become pretty easy...
# I have a Turing-complete programming language here: I'll use it...
# param 0 is a string added to the file base name to identify the drawing
# param 1 is the layer ID
# param 2 is a comment
plot_plan = [
( "CuTop", F_Cu, "Top layer" ),
( "CuBottom", B_Cu, "Bottom layer" ),
( "PasteBottom", B_Paste, "Paste Bottom" ),
( "PasteTop", F_Paste, "Paste top" ),
( "SilkTop", F_SilkS, "Silk top" ),
( "SilkBottom", B_SilkS, "Silk top" ),
( "MaskBottom", B_Mask, "Mask bottom" ),
( "MaskTop", F_Mask, "Mask top" ),
( "EdgeCuts", Edge_Cuts, "Edges" ),
]
for layer_info in plot_plan:
pctl.SetLayer(layer_info[1])
pctl.OpenPlotfile(layer_info[0], PLOT_FORMAT_GERBER, layer_info[2])
pctl.PlotLayer()
#generate internal copper layers, if any
lyrcnt = board.GetCopperLayerCount();
for innerlyr in range ( 1, lyrcnt-1 ):
pctl.SetLayer(innerlyr)
lyrname = 'inner%s' % innerlyr
pctl.OpenPlotfile(lyrname, PLOT_FORMAT_GERBER, "inner")
pctl.PlotLayer()
# At the end you have to close the last plot, otherwise you don't know when
# the object will be recycled!
pctl.ClosePlot()
# Fabricators need drill files.
# sometimes a drill map file is asked (for verification purpose)
drlwriter = EXCELLON_WRITER( board )
drlwriter.SetMapFileFormat( PLOT_FORMAT_PDF )
mirror = False
minimalHeader = False
offset = wxPoint(0,0)
mergeNPTH = False
drlwriter.SetOptions( mirror, minimalHeader, offset, mergeNPTH )
metricFmt = True
drlwriter.SetFormat( metricFmt )
genDrl = True
genMap = True
drlwriter.CreateDrillandMapFilesSet( plotDir, genDrl, genMap );
# One can create a text file to report drill statistics
rptfn = plotDir + '/drill_report.txt'
drlwriter.GenDrillReportFile( rptfn );
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2008-2013 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 2004-2013 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -548,7 +548,7 @@ void LIB_EDIT_FRAME::DeleteOnePart( wxCommandEvent& event )
return;
}
msg.Printf( _( "Select 1 of %d components to delete\nfrom library '%s'." ),
msg.Printf( _( "Select one of %zu components to delete\nfrom library '%s'." ),
nameList.GetCount(),
GetChars( lib->GetName() ) );
......
......@@ -353,6 +353,7 @@ if( KICAD_SCRIPTING )
DEPENDS pcbcommon
DEPENDS plotcontroller.h
DEPENDS exporters/gendrill_Excellon_writer.h
DEPENDS scripting/pcbnew.i
DEPENDS scripting/board.i
DEPENDS scripting/board_item.i
......
......@@ -27,7 +27,6 @@
*/
#include <fctsys.h>
//#include <pgm_base.h>
#include <kiface_i.h>
#include <pcbnew.h>
#include <wxPcbStruct.h>
......@@ -41,6 +40,7 @@
#include <dialog_gendrill.h>
#include <wildcards_and_files_ext.h>
#include <reporter.h>
// Keywords for read and write config
......@@ -351,139 +351,31 @@ void DIALOG_GENDRILL::SetParams()
void DIALOG_GENDRILL::GenDrillAndMapFiles(bool aGenDrill, bool aGenMap)
{
wxString layername_extend; /* added to the Board FileName to
* create FullFileName (= Board
* FileName + layer pair names)
*/
wxString msg;
bool hasBuriedVias = false; /* If true, drill files are created
* layer pair by layer pair for
* buried vias
*/
UpdateConfig(); // set params and Save drill options
m_parent->ClearMsgPanel();
wxString defaultPath = Prj().AbsolutePath( m_plotOpts.GetOutputDirectory() );
WX_TEXT_CTRL_REPORTER reporter( m_messagesBox );
const PlotFormat filefmt[6] =
{ // Keep these format ids in the same order than m_Choice_Drill_Map choices
PLOT_FORMAT_HPGL, PLOT_FORMAT_POST, PLOT_FORMAT_GERBER,
PLOT_FORMAT_DXF, PLOT_FORMAT_SVG, PLOT_FORMAT_PDF
};
unsigned choice = (unsigned) m_Choice_Drill_Map->GetSelection();
if( m_microViasCount || m_blindOrBuriedViasCount )
hasBuriedVias = true;
if( choice >= DIM( filefmt ) )
choice = 1;
EXCELLON_WRITER excellonWriter( m_parent->GetBoard() );
excellonWriter.SetFormat( !m_UnitDrillIsInch,
(EXCELLON_WRITER::zeros_fmt) m_ZerosFormat,
(EXCELLON_WRITER::ZEROS_FMT) m_ZerosFormat,
m_Precision.m_lhs, m_Precision.m_rhs );
excellonWriter.SetOptions( m_Mirror, m_MinimalHeader, m_FileDrillOffset, m_Merge_PTH_NPTH );
excellonWriter.SetMapFileFormat( filefmt[choice] );
wxFileName fn;
int layer1 = F_Cu;
int layer2 = B_Cu;
bool gen_through_holes = true;
bool gen_NPTH_holes = false;
for( ; ; )
{
excellonWriter.BuildHolesList( layer1, layer2, gen_through_holes ? false : true,
gen_NPTH_holes, m_Merge_PTH_NPTH );
if( excellonWriter.GetHolesCount() > 0 ) // has holes?
{
fn = m_parent->GetBoard()->GetFileName();
layername_extend.Empty();
if( gen_NPTH_holes )
{
layername_extend << wxT( "-NPTH" );
}
else if( !gen_through_holes )
{
if( layer1 == F_Cu )
layername_extend << wxT( "-front" );
else
layername_extend << wxT( "-inner" ) << layer1;
if( layer2 == B_Cu )
layername_extend << wxT( "-back" );
else
layername_extend << wxT( "-inner" ) << layer2;
}
fn.SetName( fn.GetName() + layername_extend );
wxString defaultPath = Prj().AbsolutePath( m_plotOpts.GetOutputDirectory() );
fn.SetPath( defaultPath );
if( aGenDrill )
{
fn.SetExt( DrillFileExtension );
wxString fullFilename = fn.GetFullPath();
FILE* file = wxFopen( fullFilename, wxT( "w" ) );
if( file == 0 )
{
msg.Printf( _( "** Unable to create %s **\n" ),
GetChars( fullFilename ) );
m_messagesBox->AppendText( msg );
break;
}
else
{
msg.Printf( _( "Plot: %s OK\n" ), GetChars( fullFilename ) );
m_messagesBox->AppendText( msg );
}
excellonWriter.CreateDrillFile( file );
}
if( aGenMap )
{
const PlotFormat filefmt[6] =
{ // Keep these format ids in the same order than m_Choice_Drill_Map choices
PLOT_FORMAT_HPGL, PLOT_FORMAT_POST, PLOT_FORMAT_GERBER,
PLOT_FORMAT_DXF, PLOT_FORMAT_SVG, PLOT_FORMAT_PDF
};
unsigned choice = (unsigned) m_Choice_Drill_Map->GetSelection();
if( choice >= m_Choice_Drill_Map->GetCount() )
choice = 1;
fn.SetExt( wxEmptyString ); // Will be added by GenDrillMap
wxString fullfilename = fn.GetFullPath() + wxT( "-drl_map" );
GenDrillMap( fullfilename, excellonWriter, filefmt[choice] );
}
}
if( gen_NPTH_holes ) // The last drill file was created
break;
if( !hasBuriedVias )
gen_NPTH_holes = true;
else
{
if( gen_through_holes )
layer2 = layer1 + 1; // done with through-board holes, prepare generation of first layer pair
else
{
if( layer2 >= B_Cu ) // no more layer pair to consider
{
layer1 = F_Cu;
layer2 = B_Cu;
gen_NPTH_holes = true;
continue;
}
layer1++;
layer2++; // use next layer pair
if( layer2 == m_parent->GetBoard()->GetCopperLayerCount() - 1 )
layer2 = B_Cu; // the last layer is always the back layer
}
gen_through_holes = false;
}
}
excellonWriter.CreateDrillandMapFilesSet( defaultPath, aGenDrill, aGenMap,
&reporter);
}
......@@ -510,7 +402,7 @@ void DIALOG_GENDRILL::OnGenReportFile( wxCommandEvent& event )
EXCELLON_WRITER excellonWriter( m_parent->GetBoard() );
excellonWriter.SetFormat( !m_UnitDrillIsInch,
(EXCELLON_WRITER::zeros_fmt) m_ZerosFormat,
(EXCELLON_WRITER::ZEROS_FMT) m_ZerosFormat,
m_Precision.m_lhs, m_Precision.m_rhs );
excellonWriter.SetOptions( m_Mirror, m_MinimalHeader, m_FileDrillOffset, m_Merge_PTH_NPTH );
......@@ -529,72 +421,3 @@ void DIALOG_GENDRILL::OnGenReportFile( wxCommandEvent& event )
m_messagesBox->AppendText( msg );
}
}
// Generate the drill map of the board
void DIALOG_GENDRILL::GenDrillMap( const wxString aFullFileNameWithoutExt,
EXCELLON_WRITER& aExcellonWriter,
PlotFormat format )
{
wxString ext, wildcard;
/* Init extension */
switch( format )
{
case PLOT_FORMAT_HPGL:
ext = HPGL_PLOTTER::GetDefaultFileExtension();
wildcard = _( "HPGL plot files (.plt)|*.plt" );
break;
case PLOT_FORMAT_POST:
ext = PS_PLOTTER::GetDefaultFileExtension();
wildcard = PSFileWildcard;
break;
case PLOT_FORMAT_GERBER:
ext = GERBER_PLOTTER::GetDefaultFileExtension();
wildcard = _( "Gerber files (.pho)|*.pho" );
break;
case PLOT_FORMAT_DXF:
ext = DXF_PLOTTER::GetDefaultFileExtension();
wildcard = _( "DXF files (.dxf)|*.dxf" );
break;
case PLOT_FORMAT_SVG:
ext = SVG_PLOTTER::GetDefaultFileExtension();
wildcard = SVGFileWildcard;
break;
case PLOT_FORMAT_PDF:
ext = PDF_PLOTTER::GetDefaultFileExtension();
wildcard = PdfFileWildcard;
break;
default:
wxLogMessage( wxT( "DIALOG_GENDRILL::GenDrillMap() error, fmt % unknown" ), format );
return;
}
// Add file name extension
wxString fullFilename = aFullFileNameWithoutExt;
fullFilename << wxT(".") << ext;
bool success = aExcellonWriter.GenDrillMapFile( fullFilename,
m_parent->GetPageSettings(),
format );
wxString msg;
if( ! success )
{
msg.Printf( _( "** Unable to create %s **\n" ), GetChars( fullFilename ) );
m_messagesBox->AppendText( msg );
return;
}
else
{
msg.Printf( _( "Plot: %s OK\n" ), GetChars( fullFilename ) );
m_messagesBox->AppendText( msg );
}
}
......@@ -98,14 +98,9 @@ private:
*/
void GenDrillAndMapFiles( bool aGenDrill, bool aGenMap );
void GenDrillMap( const wxString aFileName,
EXCELLON_WRITER& aExcellonWriter,
PlotFormat format );
void UpdatePrecisionOptions();
void UpdateConfig();
int Create_Drill_File_EXCELLON( FILE* aFile,
wxPoint aOffset );
int Create_Drill_File_EXCELLON( FILE* aFile, wxPoint aOffset );
int Gen_Liste_Tools( std::vector<DRILL_TOOL>& buffer,
bool print_header );
......
......@@ -56,17 +56,19 @@ inline double diameter_in_mm( double ius )
bool EXCELLON_WRITER::GenDrillMapFile( const wxString& aFullFileName,
const PAGE_INFO& aSheet,
PlotFormat aFormat )
{
double scale = 1.0;
wxPoint offset;
PLOTTER* plotter = NULL;
PAGE_INFO dummy( PAGE_INFO::A4, false );
PCB_PLOT_PARAMS plot_opts; // starts plotting with default options
LOCALE_IO toggle; // use standard C notation for float numbers
const PAGE_INFO& page_info = m_pageInfo ? *m_pageInfo : dummy;
// Calculate dimensions and center of PCB
EDA_RECT bbbox = m_pcb->ComputeBoundingBox( true );
......@@ -88,7 +90,7 @@ bool EXCELLON_WRITER::GenDrillMapFile( const wxString& aFullFileName,
hpgl_plotter->SetPenNumber( plot_opts.GetHPGLPenNum() );
hpgl_plotter->SetPenSpeed( plot_opts.GetHPGLPenSpeed() );
hpgl_plotter->SetPenOverlap( 0 );
plotter->SetPageSettings( aSheet );
plotter->SetPageSettings( page_info );
plotter->SetViewport( offset, IU_PER_DECIMILS, scale, false );
}
break;
......@@ -140,7 +142,7 @@ bool EXCELLON_WRITER::GenDrillMapFile( const wxString& aFullFileName,
{
DXF_PLOTTER* dxf_plotter = new DXF_PLOTTER;
plotter = dxf_plotter;
plotter->SetPageSettings( aSheet );
plotter->SetPageSettings( page_info );
plotter->SetViewport( offset, IU_PER_DECIMILS, scale, false );
}
break;
......@@ -149,7 +151,7 @@ bool EXCELLON_WRITER::GenDrillMapFile( const wxString& aFullFileName,
{
SVG_PLOTTER* svg_plotter = new SVG_PLOTTER;
plotter = svg_plotter;
plotter->SetPageSettings( aSheet );
plotter->SetPageSettings( page_info );
plotter->SetViewport( offset, IU_PER_DECIMILS, scale, false );
}
break;
......@@ -289,14 +291,14 @@ bool EXCELLON_WRITER::GenDrillReportFile( const wxString& aFullFileName )
unsigned totalHoleCount;
char line[1024];
LAYER_NUM layer1 = F_Cu; // First layer of the stack layer
LAYER_NUM layer2 = B_Cu; // Last layer of the stack layer
LAYER_NUM layer1 = F_Cu; // First layer of the layer stack
LAYER_NUM layer2 = B_Cu; // Last layer of the layer stack
bool gen_through_holes = true;
bool gen_NPTH_holes = false;
wxString brdFilename = m_pcb->GetFileName();
fprintf( m_file, "Drill report for %s\n", TO_UTF8( brdFilename ) );
fprintf( m_file, "Created on %s\n", TO_UTF8( DateAndTime() ) );
fprintf( m_file, "Created on %s\n\n", TO_UTF8( DateAndTime() ) );
/* build hole lists:
* 1 - through holes
......@@ -321,7 +323,7 @@ bool EXCELLON_WRITER::GenDrillReportFile( const wxString& aFullFileName )
if( layer1 == F_Cu )
fputs( "Drill report for buried and blind vias :\n\n", m_file );
sprintf( line, "Drill report for holes from layer %s to layer %s :\n",
sprintf( line, "Holes from layer %s to layer %s :\n",
TO_UTF8( m_pcb->GetLayerName( ToLAYER_ID( layer1 ) ) ),
TO_UTF8( m_pcb->GetLayerName( ToLAYER_ID( layer2 ) ) ) );
}
......@@ -332,7 +334,7 @@ bool EXCELLON_WRITER::GenDrillReportFile( const wxString& aFullFileName )
{
// List the tool number assigned to each drill,
// in mm then in inches.
sprintf( line, "T%d %2.2fmm %2.3f\" ",
sprintf( line, " T%d %2.2fmm %2.3f\" ",
ii + 1,
diameter_in_mm( m_toolListBuffer[ii].m_Diameter ),
diameter_in_inches( m_toolListBuffer[ii].m_Diameter ) );
......
......@@ -53,8 +53,180 @@
#include <pcbnew.h>
#include <gendrill_Excellon_writer.h>
#include <wildcards_and_files_ext.h>
#include <reporter.h>
#include <dialog_gendrill.h> // Dialog box for drill file generation
//#include <dialog_gendrill.h> // Dialog box for drill file generation
EXCELLON_WRITER::EXCELLON_WRITER( BOARD* aPcb )
{
m_file = NULL;
m_pcb = aPcb;
m_zeroFormat = DECIMAL_FORMAT;
m_conversionUnits = 0.0001;
m_unitsDecimal = true;
m_mirror = false;
m_merge_PTH_NPTH = false;
m_minimalHeader = false;
m_ShortHeader = false;
m_mapFileFmt = PLOT_FORMAT_PDF;
m_pageInfo = NULL;
}
void EXCELLON_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory,
bool aGenDrill, bool aGenMap,
REPORTER * aReporter )
{
wxFileName fn;
wxString msg;
wxString layername_extend; // added to the board filefame to create a full filename
//(board fileName + layer pair names)
// If some buried/blind vias are found, drill files are created
// layer pair by layer pair for buried vias
bool hasBuriedVias = false;
for( TRACK* track = m_pcb->m_Track; track != NULL; track = track->Next() )
{
if( track->Type() == PCB_VIA_T )
{
const VIA *via = static_cast<const VIA*>( track );
if( via->GetViaType() == VIA_MICROVIA ||
via->GetViaType() == VIA_BLIND_BURIED )
{
hasBuriedVias = true;
break;
}
}
}
int layer1 = F_Cu;
int layer2 = B_Cu;
bool gen_through_holes = true;
bool gen_NPTH_holes = false;
for( ; ; )
{
BuildHolesList( layer1, layer2, gen_through_holes ? false : true,
gen_NPTH_holes, m_merge_PTH_NPTH );
if( GetHolesCount() > 0 ) // has holes?
{
fn = m_pcb->GetFileName();
layername_extend.Empty();
if( gen_NPTH_holes )
{
layername_extend << wxT( "-NPTH" );
}
else if( !gen_through_holes )
{
if( layer1 == F_Cu )
layername_extend << wxT( "-front" );
else
layername_extend << wxT( "-inner" ) << layer1;
if( layer2 == B_Cu )
layername_extend << wxT( "-back" );
else
layername_extend << wxT( "-inner" ) << layer2;
}
fn.SetName( fn.GetName() + layername_extend );
fn.SetPath( aPlotDirectory );
if( aGenDrill )
{
fn.SetExt( DrillFileExtension );
wxString fullFilename = fn.GetFullPath();
FILE* file = wxFopen( fullFilename, wxT( "w" ) );
if( file == NULL )
{
if( aReporter )
{
msg.Printf( _( "** Unable to create %s **\n" ),
GetChars( fullFilename ) );
aReporter->Report( msg );
}
break;
}
else
{
if( aReporter )
{
msg.Printf( _( "Create file %s\n" ), GetChars( fullFilename ) );
aReporter->Report( msg );
}
}
CreateDrillFile( file );
}
if( aGenMap )
{
fn.SetExt( wxEmptyString ); // Will be added by GenDrillMap
wxString fullfilename = fn.GetFullPath() + wxT( "-drl_map" );
fullfilename << wxT(".") << GetDefaultPlotExtension( m_mapFileFmt );
bool success = GenDrillMapFile( fullfilename, m_mapFileFmt );
if( ! success )
{
if( aReporter )
{
msg.Printf( _( "** Unable to create %s **\n" ), GetChars( fullfilename ) );
aReporter->Report( msg );
}
return;
}
else
{
if( aReporter )
{
msg.Printf( _( "Create file %s\n" ), GetChars( fullfilename ) );
aReporter->Report( msg );
}
}
}
}
if( gen_NPTH_holes ) // The last drill file was created
break;
if( !hasBuriedVias )
gen_NPTH_holes = true;
else
{
if( gen_through_holes )
layer2 = layer1 + 1; // done with through-board holes, prepare generation of first layer pair
else
{
if( layer2 >= B_Cu ) // no more layer pair to consider
{
layer1 = F_Cu;
layer2 = B_Cu;
gen_NPTH_holes = true;
continue;
}
layer1++;
layer2++; // use next layer pair
if( layer2 == m_pcb->GetCopperLayerCount() - 1 )
layer2 = B_Cu; // the last layer is always the back layer
}
gen_through_holes = false;
}
}
}
/*
......@@ -67,8 +239,6 @@
* - Decimal
* - Metric
*/
int EXCELLON_WRITER::CreateDrillFile( FILE* aFile )
{
m_file = aFile;
......@@ -78,7 +248,7 @@ int EXCELLON_WRITER::CreateDrillFile( FILE* aFile )
double xt, yt;
char line[1024];
SetLocaleTo_C_standard(); // Use the standard notation for double numbers
LOCALE_IO dummy; // Use the standard notation for double numbers
WriteEXCELLONHeader();
......@@ -212,14 +382,12 @@ int EXCELLON_WRITER::CreateDrillFile( FILE* aFile )
WriteEXCELLONEndOfFile();
SetLocaleTo_Default(); // Revert to locale double notation
return holes_count;
}
void EXCELLON_WRITER::SetFormat( bool aMetric,
zeros_fmt aZerosFmt,
ZEROS_FMT aZerosFmt,
int aLeftDigits,
int aRightDigits )
{
......@@ -228,9 +396,17 @@ void EXCELLON_WRITER::SetFormat( bool aMetric,
/* Set conversion scale depending on drill file units */
if( m_unitsDecimal )
m_conversionUnits = 1.0 / IU_PER_MM; // EXCELLON units = mm
m_conversionUnits = 1.0 / IU_PER_MM; // EXCELLON units = mm
else
m_conversionUnits = 0.001 / IU_PER_MILS; // EXCELLON units = INCHES
m_conversionUnits = 0.001 / IU_PER_MILS; // EXCELLON units = INCHES
// Set the zero counts. if aZerosFmt == DECIMAL_FORMAT, these values
// will be set, but not used.
if( aLeftDigits <= 0 )
aLeftDigits = m_unitsDecimal ? 3 : 2;
if( aRightDigits <= 0 )
aRightDigits = m_unitsDecimal ? 3 : 4;
m_precision.m_lhs = aLeftDigits;
m_precision.m_rhs = aRightDigits;
......@@ -344,7 +520,8 @@ void EXCELLON_WRITER::WriteEXCELLONHeader()
if( !m_minimalHeader )
{
// The next 2 lines in EXCELLON files are comments:
wxString msg = Pgm().App().GetAppName() + wxT( " " ) + GetBuildVersion();
wxString msg;
msg << wxT("KiCad") << wxT( " " ) << GetBuildVersion();
fprintf( m_file, ";DRILL file {%s} date %s\n", TO_UTF8( msg ),
TO_UTF8( DateAndTime() ) );
......
......@@ -6,8 +6,8 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2012 Jean_Pierre Charras <jp.charras at wanadoo.fr>
* Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 1992-2015 Jean_Pierre Charras <jp.charras at wanadoo.fr>
* Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -120,12 +120,11 @@ public: DRILL_PRECISION( int l = 2, int r = 4 )
class EXCELLON_WRITER
{
public:
enum zeros_fmt {
// Zero format in coordinates
DECIMAL_FORMAT,
SUPPRESS_LEADING,
SUPPRESS_TRAILING,
KEEP_ZEROS
enum ZEROS_FMT { // Zero format in coordinates
DECIMAL_FORMAT, // Floating point coordinates
SUPPRESS_LEADING, // Suppress leading zeros
SUPPRESS_TRAILING, // Suppress trainling zeros
KEEP_ZEROS // keep zeros
};
wxPoint m_Offset; // offset coordinates
......@@ -137,7 +136,7 @@ private:
bool m_minimalHeader; // True to use minimal header
// in excellon file (strip comments)
bool m_unitsDecimal; // true = decimal, false = inches
zeros_fmt m_zeroFormat; // the zero format option for output file
ZEROS_FMT m_zeroFormat; // the zero format option for output file
DRILL_PRECISION m_precision; // The current coordinate precision (not used in decimal format)
double m_conversionUnits; // scaling factor to convert the board unites to Excellon units
// (i.e inches or mm)
......@@ -147,20 +146,13 @@ private:
std::vector<HOLE_INFO> m_holeListBuffer; // Buffer containing holes
std::vector<DRILL_TOOL> m_toolListBuffer; // Buffer containing tools
public:
EXCELLON_WRITER( BOARD* aPcb )
{
m_file = NULL;
m_pcb = aPcb;
m_zeroFormat = DECIMAL_FORMAT;
m_conversionUnits = 0.0001;
m_unitsDecimal = false;
m_mirror = false;
m_merge_PTH_NPTH = false;
m_minimalHeader = false;
m_ShortHeader = false;
}
PlotFormat m_mapFileFmt; // the format of the map drill file,
// if this map is needed
const PAGE_INFO* m_pageInfo; // the page info used to plot drill maps
// If NULL, use a A4 page format
public:
EXCELLON_WRITER( BOARD* aPcb );
~EXCELLON_WRITER()
{
......@@ -178,9 +170,30 @@ public:
* @param aMetric = true for metric coordinates, false for imperial units
* @param aZerosFmt = DECIMAL_FORMAT, SUPPRESS_LEADING, SUPPRESS_TRAILING, KEEP_ZEROS
* @param aLeftDigits = number of digits for integer part of coordinates
* if <= 0 (default), a suitable value will be used, depending on units
* @param aRightDigits = number of digits for mantissa part of coordinates
* if <= 0 (default), a suitable value will be used, depending on units
*/
void SetFormat( bool aMetric, zeros_fmt aZerosFmt, int aLeftDigits, int aRightDigits );
void SetFormat( bool aMetric, ZEROS_FMT aZerosFmt = DECIMAL_FORMAT,
int aLeftDigits = 0, int aRightDigits = 0 );
/**
* Sets the page info used to plot drill maps
* If NULL, a A4 page format will be used
* @param aPageInfo = a reference to the page info, usually used to plot/display the board
*/
void SetPageInfo( const PAGE_INFO* aPageInfo ) { m_pageInfo = aPageInfo; }
/**
* Function SetMapFileFormat
* Initialize the format for the drill map file
* @param SetMapFileFormat = a PlotFormat value (one of
* PLOT_FORMAT_HPGL, PLOT_FORMAT_POST, PLOT_FORMAT_GERBER,
* PLOT_FORMAT_DXF, PLOT_FORMAT_SVG, PLOT_FORMAT_PDF
* the most useful are PLOT_FORMAT_PDF and PLOT_FORMAT_POST
*/
void SetMapFileFormat( PlotFormat aMapFmt ) { m_mapFileFmt = aMapFmt; }
/**
* Function SetOptions
......@@ -219,6 +232,19 @@ public:
int GetHolesCount() const { return m_holeListBuffer.size(); }
/**
* Function CreateDrillandMapFilesSet
* Creates the full set of Excellon drill file for the board
* filenames are computed from the board name, and layers id
* @param aPlotDirectory = the output folder
* @param aGenDrill = true to generate the EXCELLON drill file
* @param aGenMap = true to generate a drill map file
* @param aReporter = a REPORTER to return activity or any message (can be NULL)
*/
void CreateDrillandMapFilesSet( const wxString& aPlotDirectory,
bool aGenDrill, bool aGenMap,
REPORTER * aReporter = NULL );
/**
* Function CreateDrillFile
* Creates an Excellon drill file
......@@ -275,7 +301,7 @@ public:
* Total unplated holes count 1
*
* @param aFullFileName : the name of the file to create
* m_unitsDecimal = false tu use inches, true to use mm in report file
* m_unitsDecimal = false to use inches, true to use mm in report file
*
* @return success if the file is created
*/
......@@ -284,14 +310,14 @@ public:
/**
* Function GenDrillMapFile
* Plot a map of drill marks for holes.
* @param aFullFileNameWithoutExt : the full filename of the file to create,
* without extension (will be added according to the format)
* @param aSheet : the paper sheet to use for plot
* the paper sheet to use to plot the map is set in m_pageInfo
* ( calls SetPageInfo() to set it )
* if NULL, A4 format will be used
* @param aFullFileName : the full filename of the map file to create,
* @param aFormat : one of the supported plot formats (see enum PlotFormat )
*/
bool GenDrillMapFile( const wxString& aFullFileNameWithoutExt,
const PAGE_INFO& aSheet,
PlotFormat aFormat );
bool GenDrillMapFile( const wxString& aFullFileName, PlotFormat aFormat );
private:
/* Print the DRILL file header. The full header is:
* M48
......
......@@ -108,6 +108,7 @@
#include <plotcontroller.h>
#include <pcb_plot_params.h>
#include <exporters/gendrill_Excellon_writer.h>
#include <colors.h>
BOARD *GetBoard(); /* get current editor board */
......@@ -145,6 +146,7 @@
%include <plotcontroller.h>
%include <pcb_plot_params.h>
%include <plot_common.h>
%include <exporters/gendrill_Excellon_writer.h>
%include <colors.h>
%include "board_item.i"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment