Last active
July 29, 2020 18:49
-
-
Save salkinium/0c588d4652c1f33850caa234b04cbe6f to your computer and use it in GitHub Desktop.
Python script to generate Gerber ZIP files from KiCAD files in the right format for JLCPCB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/Applications/Kicad/kicad.app/Contents/Frameworks/Python.framework/Versions/Current/bin/python | |
import sys | |
sys.path.insert(0,"/Applications/Kicad/kicad.app/Contents/Frameworks/python/site-packages/") | |
import os | |
import shutil | |
import zipfile | |
import tempfile | |
import pcbnew | |
output, dependency, = sys.argv[1:] | |
print("Gerberizing '{}'".format(output)) | |
board = pcbnew.LoadBoard(dependency) | |
with_silkscreen = True # Silkscreen makes the boards slightly thicker | |
with_paste = True | |
with_4layers = board.GetDesignSettings().GetCopperLayerCount() == 4 | |
# Configure plotter | |
pctl = pcbnew.PLOT_CONTROLLER(board) | |
popt = pctl.GetPlotOptions() | |
# Set some important plot options | |
popt.SetPlotFrameRef(False) | |
popt.SetLineWidth(pcbnew.FromMM(0.05)) | |
popt.SetAutoScale(False) | |
popt.SetScale(1) | |
popt.SetMirror(False) | |
popt.SetUseGerberAttributes(False) | |
popt.SetUseGerberProtelExtensions(True) | |
popt.SetExcludeEdgeLayer(True) | |
popt.SetUseAuxOrigin(False) | |
popt.SetDrillMarksType(pcbnew.PCB_PLOT_PARAMS.NO_DRILL_SHAPE) | |
popt.SetSkipPlotNPTH_Pads(True) | |
# Render Plot Files | |
tempdir = tempfile.mkdtemp() | |
popt.SetOutputDirectory(tempdir) | |
plot_plan = [ | |
( "F_Cu", pcbnew.F_Cu, "Top layer" ), | |
( "B_Cu", pcbnew.B_Cu, "Bottom layer" ), | |
( "F_Mask", pcbnew.F_Mask, "Mask top" ), | |
( "B_Mask", pcbnew.B_Mask, "Mask bottom" ), | |
( "Edge_Cuts", pcbnew.Edge_Cuts, "Edges" ), | |
] | |
if with_4layers: | |
plot_plan += [ | |
( "In1_Cu", pcbnew.In1_Cu, "Top internal layer" ), | |
( "In2_Cu", pcbnew.In2_Cu, "Bottom internal layer" ), | |
] | |
if with_silkscreen: | |
plot_plan += [ | |
( "F_Silk", pcbnew.F_SilkS, "Silk top" ), | |
( "B_Silk", pcbnew.B_SilkS, "Silk top" ), | |
] | |
if with_paste: | |
plot_plan += [ | |
( "F_Paste", pcbnew.F_Paste, "Paste top" ), | |
( "B_Paste", pcbnew.B_Paste, "Paste Bottom" ), | |
] | |
for layer_info in plot_plan: | |
pctl.SetLayer(layer_info[1]) | |
pctl.OpenPlotfile(layer_info[0], pcbnew.PLOT_FORMAT_GERBER, layer_info[2]) | |
pctl.PlotLayer() | |
# Render Drill Files | |
drlwriter = pcbnew.EXCELLON_WRITER(board) | |
drlwriter.SetMapFileFormat(pcbnew.PLOT_FORMAT_GERBER) | |
drlwriter.SetOptions(aMirror=False, aMinimalHeader=False, | |
aOffset=pcbnew.wxPoint(0, 0), aMerge_PTH_NPTH=False) | |
drlwriter.SetFormat(True, pcbnew.EXCELLON_WRITER.DECIMAL_FORMAT, 3, 3) | |
drlwriter.CreateDrillandMapFilesSet( pctl.GetPlotDirName(), True, False ); | |
pctl.ClosePlot() | |
# Archive files | |
files = os.listdir(tempdir) | |
with zipfile.ZipFile(os.path.join(tempdir, "zip"), 'w', zipfile.ZIP_DEFLATED) as myzip: | |
for file in files: | |
myzip.write(os.path.join(tempdir, file), file) | |
os.rename(os.path.join(tempdir, "zip"), output) | |
# Remove tempdir | |
shutil.rmtree(tempdir) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Raw usage:
Example usage within Makefile: