Gerber output: Some changes after evaluation of Gerber files by Ucamco (the manager of GERBER format):

* default file ext is now .gbr (the "official extension")
* some outdated commands remoded.
* mainly use mm and 4.5 format instead of inches and 3.4 format. this is mandatory,
  because the 3.4 format (comming from old pcbned internal units) creates truncations in coordinates.
  (with serious issues in polygons which can appear self-intersecting afer truncation)
This commit is contained in:
jean-pierre charras 2014-06-30 12:00:21 +02:00
parent d6d786eed8
commit b50872edca
7 changed files with 79 additions and 32 deletions

View File

@ -12,14 +12,21 @@
* in Eeschema, Pcbnew and GerbView
*/
/* Initial colors values: optimized for Pcbnew, but are also Ok for Eeschema
/* Initial colors values: optimized for Pcbnew 64 layers.
* The table is not actually used by Eeschema.
* these values are superseded by config reading
*/
static const EDA_COLOR_T default_layer_color[] = {
GREEN, BLUE, LIGHTGRAY, BROWN,
RED, MAGENTA, LIGHTGRAY, MAGENTA,
DARKGRAY, BLUE, GREEN, CYAN,
LIGHTRED, LIGHTMAGENTA, YELLOW, RED,
RED, YELLOW, LIGHTMAGENTA, LIGHTRED,
CYAN, GREEN, BLUE, DARKGRAY,
MAGENTA, LIGHTGRAY, MAGENTA, RED,
BROWN, LIGHTGRAY, BLUE, GREEN,
RED, YELLOW, LIGHTMAGENTA, LIGHTRED,
CYAN, GREEN, BLUE, DARKGRAY,
MAGENTA, LIGHTGRAY, MAGENTA, RED,
BROWN, LIGHTGRAY, BLUE, GREEN,
BLUE, MAGENTA,
LIGHTCYAN, RED,
MAGENTA, CYAN,

View File

@ -23,10 +23,23 @@ void GERBER_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
wxASSERT( aMirror == false );
m_plotMirror = false;
plotOffset = aOffset;
wxASSERT( aScale == 1 );
plotScale = 1;
wxASSERT( aScale == 1 ); // aScale parameter is not used in Gerber
plotScale = 1; // Plot scale is *always* 1.0
m_gerberUnitInch = false; // Currently fixed, but could be an option
// number of digits after the point (number of digits of the mantissa
// Be carefull: the coordinates are stored in an integer
// so 6 digits (inches) or 5 digits (mm) is the best value
// to avoid truncations and overflow
m_gerberUnitFmt = m_gerberUnitInch ? 6 : 5;
m_IUsPerDecimil = aIusPerDecimil;
iuPerDeviceUnit = 1.0 / aIusPerDecimil;
iuPerDeviceUnit = pow( 10.0, m_gerberUnitFmt ) / ( aIusPerDecimil * 10000.0 );
if( ! m_gerberUnitInch )
iuPerDeviceUnit *= 25.4; // gerber output in mm
/* We don't handle the filmbox, and it's more useful to keep the
* origin at the origin */
paperSize.x = 0;
@ -67,25 +80,38 @@ bool GERBER_PLOTTER::StartPlot()
if( outputFile == NULL )
return false;
if( !attribFunction.IsEmpty() )
if( ! m_attribFunction.IsEmpty() )
{
fputs( "%TF.GerberVersion,J1*%\n", outputFile );
fprintf( outputFile, "%%TF.FileFunction,%s*%%\n", TO_UTF8( attribFunction ) );
fprintf( outputFile, "%%TF.FileFunction,%s*%%\n",
TO_UTF8( m_attribFunction ) );
}
/* Set coordinate format to 3.4 absolute, leading zero omitted */
fputs( "%FSLAX34Y34*%\n", outputFile );
fputs( "G04 Gerber Fmt 3.4, Leading zero omitted, Abs format*\n", outputFile );
// Set coordinate format to 3.6 or 4.5 absolute, leading zero omitted
// the number of digits for the integer part of coordintes is needed
// in gerber format, but is not very important when omitting leading zeros
// It is fixed here to 3 (inch) or 4 (mm), but is not actually used
int leadingDigitCount = m_gerberUnitInch ? 3 : 4;
fprintf( outputFile, "%%FSLAX%d%dY%d%d*%%\n",
leadingDigitCount, m_gerberUnitFmt,
leadingDigitCount, m_gerberUnitFmt );
fprintf( outputFile,
"G04 Gerber Fmt %d.%d, Leading zero omitted, Abs format (unit %s)*\n",
leadingDigitCount, m_gerberUnitFmt,
m_gerberUnitInch ? "inch" : "mm" );
wxString Title = creator + wxT( " " ) + GetBuildVersion();
fprintf( outputFile, "G04 (created by %s) date %s*\n",
TO_UTF8( Title ), TO_UTF8( DateAndTime() ) );
/* Mass parameter: unit = INCHES */
fputs( "%MOIN*%\n", outputFile );
/* Mass parameter: unit = INCHES/MM */
if( m_gerberUnitInch )
fputs( "%MOIN*%\n", outputFile );
else
fputs( "%MOMM*%\n", outputFile );
/* Specify linear interpol (G01), unit = INCH (G70), abs format (G90) */
fputs( "G01*\nG70*\nG90*\n", outputFile );
/* Specify linear interpol (G01) */
fputs( "G01*\n", outputFile );
fputs( "G04 APERTURE LIST*\n", outputFile );
/* Select the default aperture */
SetCurrentLineWidth( -1 );
@ -191,7 +217,7 @@ void GERBER_PLOTTER::selectAperture( const wxSize& size,
{
// Pick an existing aperture or create a new one
currentAperture = getAperture( size, type );
fprintf( outputFile, "G54D%d*\n", currentAperture->DCode );
fprintf( outputFile, "D%d*\n", currentAperture->DCode );
}
}
@ -208,8 +234,13 @@ void GERBER_PLOTTER::writeApertureList()
for( std::vector<APERTURE>::iterator tool = apertures.begin();
tool != apertures.end(); tool++ )
{
const double fscale = 0.0001f * plotScale
* iuPerDeviceUnit ;
// apertude sizes are in inch or mm, regardless the
// coordinates format
double fscale = 0.0001 * plotScale / m_IUsPerDecimil; // inches
if(! m_gerberUnitInch )
fscale *= 25.4; // size in mm
char* text = cbuf + sprintf( cbuf, "%%ADD%d", tool->DCode );
/* Please note: the Gerber specs for mass parameters say that

View File

@ -109,15 +109,17 @@ bool GERBVIEW_FRAME::LoadGerberFiles( const wxString& aFullFileName )
{
/* Standard gerber filetypes
* (See http://en.wikipedia.org/wiki/Gerber_File)
* the .pho extension is the default used in Pcbnew
* the .gbr (.pho in legacy files) extension is the default used in Pcbnew
* However there are a lot of other extensions used for gerber files
* Because the first letter is usually g, we accept g* as extension
* (Mainly internal copper layers do not have specific extention,
* and filenames are like *.g1, *.g2 *.gb1 ...).
* Now (2014) Ucamco (the company which manager the Gerber format) encourage
* use of .gbr only and the Gerber X2 file format.
*/
filetypes = _( "Gerber files (.g* .lgr .pho)" );
filetypes << wxT("|");
filetypes += wxT("*.g*;*.G*;*.lgr;*.LGR;*.pho;*.PHO" );
filetypes += wxT("*.g*;*.G*;*.pho;*.PHO" );
filetypes << wxT("|");
/* Special gerber filetypes */

View File

@ -314,13 +314,13 @@ protected:
/// Plot scale - chosen by the user (even implicitly with 'fit in a4')
double plotScale;
/* Device scale (how many IUs in a decimil - always); it's a double
/* Caller scale (how many IUs in a decimil - always); it's a double
* because in eeschema there are 0.1 IUs in a decimil (eeschema
* always works in mils internally) while pcbnew can work in decimil
* or nanometers, so this value would be >= 1 */
double m_IUsPerDecimil;
/// Device scale (from IUs to device units - usually decimils)
/// Device scale (from IUs to plotter device units - usually decimils)
double iuPerDeviceUnit;
/// Plot offset (in IUs)
@ -774,7 +774,6 @@ public:
workFile = 0;
finalFile = 0;
currentAperture = apertures.end();
attribFunction = wxEmptyString;
}
virtual PlotFormat GetPlotterType() const
@ -784,7 +783,7 @@ public:
static wxString GetDefaultFileExtension()
{
return wxString( wxT( "pho" ) );
return wxString( wxT( "gbr" ) );
}
virtual bool StartPlot();
@ -821,7 +820,7 @@ public:
virtual void SetLayerAttribFunction( const wxString& function )
{
attribFunction = function;
m_attribFunction = function;
}
protected:
@ -840,7 +839,11 @@ protected:
std::vector<APERTURE> apertures;
std::vector<APERTURE>::iterator currentAperture;
wxString attribFunction; /* the layer "function", it is linked with the layer id */
wxString m_attribFunction; // the layer "function", in GERBER X2 extention
// it is linked with the layer id
bool m_gerberUnitInch; // true if the gerber units are inches, false for mm
int m_gerberUnitFmt; // number of digits in mantissa.
// usually 6 in Inches and 5 or 6 in mm
};

View File

@ -133,7 +133,7 @@ void KICAD_MANAGER_FRAME::OnArchiveFiles( wxCommandEvent& event )
/* List of file extensions to save. */
static const wxChar* extentionList[] = {
wxT( "*.sch" ), wxT( "*.lib" ), wxT( "*.mod" ), wxT( "*.cmp" ),
wxT( "*.brd" ), wxT( "*.kicad_pcb" ),
wxT( "*.brd" ), wxT( "*.kicad_pcb" ), wxT( "*.gbr" ),
wxT( "*.net" ), wxT( "*.pro" ), wxT( "*.pho" ), wxT( "*.py" ),
wxT( "*.pdf" ), wxT( "*.txt" ), wxT( "*.dcm" ), wxT( "*.kicad_wks" ),
NULL

View File

@ -69,7 +69,7 @@ static const wxChar* s_allowedExtensionsToList[] =
wxT( "^[^$].*\\.kicad_wks$" ), // S format kicad page layout descr files
wxT( "^.*\\.net$" ),
wxT( "^.*\\.txt$" ),
wxT( "^.*\\.pho$" ), // Gerber file (Kicad extension)
wxT( "^.*\\.pho$" ), // Gerber file (Old Kicad extension)
wxT( "^.*\\.gbr$" ), // Gerber file
wxT( "^.*\\.gb[alops]$" ), // Gerber back (or bottom) layer file
wxT( "^.*\\.gt[alops]$" ), // Gerber front (or top) layer file

View File

@ -1220,7 +1220,11 @@ public:
* @param aLayerMask A layer or layers to mask the hit test.
* @return A pointer to a D_PAD object if found or NULL if not found.
*/
D_PAD* GetPad( const wxPoint& aPosition, LSET aLayerMask = LSET().set() );
D_PAD* GetPad( const wxPoint& aPosition, LSET aLayerMask );
D_PAD* GetPad( const wxPoint& aPosition )
{
return GetPad( aPosition, LSET().set() );
}
/**
* Function GetPad