← Back to team overview

kicad-developers team mailing list archive

Option for gerber metric numeric formats

 

I had to done this for some *idiotic* people which needs gerbers in
millimeters. Could help in some extreme DRC situation on the fabrication
side, I don't know... or maybe to raise precision (even if I don't think
current technology can achieve over than one decimil there are 12000 dpi
photoplotter out there... what are they used for?)

In practice: 
- Call the 'SetFormat' of the gerber plotter. You can ask for
  metric/imperial and select the number of digits. See example in the
  last hunk of the patch
- Enjoy. No really, there's nothing else. Also the default is the same
  imperial 3.4 we are already using.

If someone in his spare time wants to add the controls in the
UI/scripting layer maybe it can be useful; I'll just put it here if
someone want or need it.

-- 
Lorenzo Marcantonio
Logos Srl
=== modified file 'common/common_plotGERBER_functions.cpp'
--- common/common_plotGERBER_functions.cpp	2013-05-06 18:34:14 +0000
+++ common/common_plotGERBER_functions.cpp	2013-05-07 12:34:25 +0000
@@ -26,7 +26,14 @@
     wxASSERT( aScale == 1 );
     plotScale = 1;
     m_IUsPerDecimil = aIusPerDecimil;
-    iuPerDeviceUnit = 1.0 / aIusPerDecimil;
+
+    /* The pow add or removes decimal digits as required (decimils
+     * are the same as 4 imperial decimal figures) */
+    if( m_metric )
+        iuPerDeviceUnit = 25.4 / (aIusPerDecimil * pow( 10, 4-m_decimalFigures ) );
+    else
+        iuPerDeviceUnit = 1.0 / (aIusPerDecimil * pow( 10, 4-m_decimalFigures ) );
+
     /* We don't handle the filmbox, and it's more useful to keep the
      * origin at the origin */
     paperSize.x = 0;
@@ -41,9 +48,8 @@
  */
 void GERBER_PLOTTER::emitDcode( const DPOINT& pt, int dcode )
 {
-
     fprintf( outputFile, "X%dY%dD%02d*\n",
-	    int( pt.x ), int( pt.y ), dcode );
+	    KiROUND( pt.x ), KiROUND( pt.y ), dcode );
 }
 
 /**
@@ -71,17 +77,26 @@
     fprintf( outputFile, "G04 (created by %s) date %s*\n",
              TO_UTF8( Title ), TO_UTF8( DateAndTime() ) );
 
-    /* Mass parameter: unit = INCHES */
-    fputs( "%MOIN*%\n", outputFile );
-
-    /* Set coordinate format to 3.4 absolute, leading zero omitted */
-    fputs( "G04 Gerber Fmt 3.4, Leading zero omitted, Abs format*\n%FSLAX34Y34*%\n",
-           outputFile );
-
-    /* Specify linear interpol (G01), unit = INCH (G70), abs format (G90) */
-    fputs( "G01*\nG70*\nG90*\n", outputFile );
+    // Unit mode, coordinate format, absolute mode, leading zero omitted
+    fprintf( outputFile, 
+            "%%MO%s*%%\n"
+            "G04 %s Gerber Fmt %d.%d, Leading zero omitted, Abs format*\n"
+            "%%FSLAX%d%dY%d%d*%%\n",
+            m_metric ? "Metric" : "Imperial",
+            m_metric ? "MM" : "IN",
+            m_integerFigures, m_decimalFigures,
+            m_integerFigures, m_decimalFigures,
+            m_integerFigures, m_decimalFigures );
+
+    /* Specify linear interpol (G01), unit = INCH (G70) or MM (G71), abs format (G90)
+       single quadrant mode (G74) (strongly recommended by the specs) */
+    fprintf( outputFile, "G01*\nG%d*\nG90*\nG74*\n", m_metric ? 71 : 70 );
+
+    /* This is the marker for the insertion of the list during the
+       second pass */
     fputs( "G04 APERTURE LIST*\n", outputFile );
-    /* Select the default aperture */
+
+    // Select the default aperture
     SetCurrentLineWidth( -1 );
 
     return true;
@@ -202,8 +217,7 @@
     for( std::vector<APERTURE>::iterator tool = apertures.begin();
          tool != apertures.end(); tool++ )
     {
-        const double fscale = 0.0001f * plotScale
-				* iuPerDeviceUnit ;
+        const double fscale = userToDeviceSize( 1 ) * pow( 10, -m_decimalFigures );
         char* text = cbuf + sprintf( cbuf, "%%ADD%d", tool->DCode );
 
         /* Please note: the Gerber specs for mass parameters say that
@@ -309,7 +323,7 @@
         fprintf( outputFile, "G03" );
     else
         fprintf( outputFile, "G02" );
-    fprintf( outputFile, "X%dY%dI%dJ%dD01*\n", int( devEnd.x ), int( devEnd.y ),
+    fprintf( outputFile, "X%dY%dI%dJ%dD01*\n", KiROUND( devEnd.x ), KiROUND( devEnd.y ),
              int( devCenter.x ), int( devCenter.y ) );
     fprintf( outputFile, "G74*\nG01*\n" ); // Back to single quadrant and linear interp.
 }

=== modified file 'include/plot_common.h'
--- include/plot_common.h	2013-05-05 10:01:44 +0000
+++ include/plot_common.h	2013-05-07 07:21:52 +0000
@@ -760,6 +760,24 @@
         workFile  = 0;
         finalFile = 0;
         currentAperture = apertures.end();
+
+        // Default format: imperial, 3.4 format
+        m_metric = false;
+        m_integerFigures = 3;
+        m_decimalFigures = 4;
+    }
+
+    /**
+     * Gerber specific: set the output format in metric mode (default is
+     * imperial i.e. inches).
+     * Call this *before* setting the viewport! 
+     * Note that the conversion is done thru an int, so ifig+dfig digits have
+     * to fit in the dynamic range of 2^32 */
+    void SetFormat( bool metric, int ifig, int dfig )
+    {
+        m_metric = metric;
+        m_integerFigures = ifig;
+        m_decimalFigures = dfig;
     }
 
     virtual PlotFormat GetPlotterType() const
@@ -819,6 +837,9 @@
 
     std::vector<APERTURE>           apertures;
     std::vector<APERTURE>::iterator currentAperture;
+    bool m_metric;        /// Give a gerber with metric coordinates (do it before starting)
+    int m_decimalFigures; /// Number of decimal figures: usually 4 for inches, 3 for metric
+    int m_integerFigures; /// Number of integer figures: usually 3 for inches, 4 for metric
 };
 
 

=== modified file 'pcbnew/plot_board_layers.cpp'
--- pcbnew/plot_board_layers.cpp	2013-05-05 10:01:44 +0000
+++ pcbnew/plot_board_layers.cpp	2013-05-07 12:01:24 +0000
@@ -785,6 +785,7 @@
 
     case PLOT_FORMAT_GERBER:
         plotter = new GERBER_PLOTTER();
+        ((GERBER_PLOTTER*)plotter)->SetFormat( false, 3, 4 ); // EXAMPLE DEFAULT
         break;
 
     case PLOT_FORMAT_SVG:

Attachment: smime.p7s
Description: S/MIME cryptographic signature