aboutsummaryrefslogtreecommitdiff
path: root/py/kicad_gerber.py
diff options
context:
space:
mode:
Diffstat (limited to 'py/kicad_gerber.py')
-rwxr-xr-xpy/kicad_gerber.py145
1 files changed, 145 insertions, 0 deletions
diff --git a/py/kicad_gerber.py b/py/kicad_gerber.py
new file mode 100755
index 0000000..41ae3af
--- /dev/null
+++ b/py/kicad_gerber.py
@@ -0,0 +1,145 @@
+#!/usr/bin/env python
+import sys
+import os
+import argparse
+from pcbnew import *
+
+parser = argparse.ArgumentParser(description='KiCAD PCB to GERBER converter')
+
+parser.add_argument('--pcb',
+ required=True,
+ dest='pcb',
+ action='store',
+ help='A foo.kicad_pcb file')
+
+parser.add_argument('--output-directory',
+ required=True,
+ dest='output_directory',
+ action='store',
+ help='Directory to store output files')
+
+parser.add_argument('--detect-files-only',
+ dest='detect_files_only',
+ action='store_true',
+ help='Don\'t create the GERBER files, just list the files to be created')
+
+parser.add_argument('--create-drill-map-file',
+ dest='create_drill_map_file',
+ action='store_true',
+ help='Create drill map file')
+
+parser.add_argument('--protel-extensions',
+ dest='protel_extensions',
+ action='store_true',
+ help='Use Protel filename extensions')
+
+args = parser.parse_args()
+
+filename = args.pcb
+
+board = LoadBoard(filename)
+
+plot_plan = [
+ ("GTO", board.GetLayerName(F_SilkS), F_SilkS, "Silk front"),
+ ("GTS", board.GetLayerName(F_Mask), F_Mask, "Mask front"),
+ ("GBO", board.GetLayerName(B_SilkS), B_SilkS, "Silk bottom"),
+ ("GBS", board.GetLayerName(B_Mask), B_Mask, "Mask bottom"),
+ ("GBR", board.GetLayerName(Edge_Cuts), Edge_Cuts, "Edges"),
+]
+
+layers = board.GetEnabledLayers()
+for i in layers.CuStack():
+ name = board.GetLayerName(i)
+ plot_plan.append(("", name, i, "Copper Layer " + name))
+
+pctl = PLOT_CONTROLLER(board)
+popt = pctl.GetPlotOptions()
+popt.SetOutputDirectory(args.output_directory)
+
+# A nasty hack to get the base filename
+pctl.SetLayer(F_Cu)
+pctl.OpenPlotfile("", PLOT_FORMAT_GERBER, "")
+filename = pctl.GetPlotFileName()
+try:
+ os.remove(filename)
+except:
+ pass
+pctl.ClosePlot()
+
+basename = filename.replace('.gbr', '')
+drlFile = basename + ".drl"
+drlFileProtel = basename + ".txt"
+
+if args.protel_extensions:
+ popt.SetUseGerberProtelExtensions(True)
+
+if args.detect_files_only:
+ for layer_info in plot_plan:
+ filenamePostfix = layer_info[1]
+ layer_num = layer_info[2]
+ pctl.SetLayer(layer_num)
+
+ pctl.OpenPlotfile(filenamePostfix, PLOT_FORMAT_GERBER, layer_info[3])
+ filename = pctl.GetPlotFileName()
+ print filename
+ try:
+ os.remove(filename)
+ except:
+ pass
+
+ pctl.ClosePlot()
+ if args.protel_extensions:
+ print drlFileProtel
+ else:
+ print drlFile
+ sys.exit(0)
+
+# 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)
+
+for layer_info in plot_plan:
+ filenamePostfix = layer_info[1]
+ layer_num = layer_info[2]
+ pctl.SetLayer(layer_num)
+
+ pctl.OpenPlotfile(filenamePostfix, PLOT_FORMAT_GERBER, layer_info[3])
+ pctl.PlotLayer()
+ pctl.ClosePlot()
+
+popt.SetDrillMarksType(PCB_PLOT_PARAMS.FULL_DRILL_SHAPE)
+
+drlwriter = EXCELLON_WRITER(board)
+# drlwriter.SetMapFileFormat(PLOT_FORMAT_PDF)
+drlwriter.SetMapFileFormat(PLOT_FORMAT_GERBER)
+
+mirror = False
+minimalHeader = False
+offset = wxPoint(0, 0)
+# False to generate 2 separate drill files (one for plated holes, one for non plated holes)
+# True to generate only one drill file
+mergeNPTH = False
+drlwriter.SetOptions(mirror, minimalHeader, offset, mergeNPTH)
+
+metricFmt = True
+drlwriter.SetFormat(metricFmt)
+
+genDrl = True
+genMap = args.create_drill_map_file
+
+drlwriter.CreateDrillandMapFilesSet(pctl.GetPlotDirName(), genDrl, genMap)
+
+if args.protel_extensions:
+ os.rename(drlFile, basename + ".txt")
+ pass