Skip to content

Instantly share code, notes, and snippets.

@akira345
Created July 3, 2019 08:23
Show Gist options
  • Save akira345/1a1aed1861e509fcff0d4a6efd7ce97a to your computer and use it in GitHub Desktop.
Save akira345/1a1aed1861e509fcff0d4a6efd7ce97a to your computer and use it in GitHub Desktop.
KiCad5でガーバデータ出力するスクリプト。FusionPCB向けに改造。
# file : action_menu_gerber_zip.py
#
# (gerber_zip)
#
# Copyright (C) 2018 g200kg
# Released under MIT License
#
import pcbnew
from pcbnew import *
import wx
import os
import zipfile
#
# Setup params
#
gerber_subdir = "Gerber"
merge_npth = True
use_aux_origin = False
excellon_format = EXCELLON_WRITER.DECIMAL_FORMAT
#excellon_format = EXCELLON_WRITER.SUPPRESS_LEADING
#
#
#
class GerberZip( pcbnew.ActionPlugin ):
'''
Make Gerber Zip-file for Elecrow / FusionPCB
'''
layers = [
[ F_Cu, 'GTL', None ],
[ B_Cu, 'GBL', None ],
[ F_SilkS, 'GTO', None ],
[ B_SilkS, 'GBO', None ],
[ F_Mask, 'GTS', None ],
[ B_Mask, 'GBS', None ],
[ Edge_Cuts,'GML', None ],
# [ In1_Cu, 'GL2', None ],
# [ In2_Cu, 'GL3', None ],
# [ In3_Cu, 'GL4', None ],
# [ In4_Cu, 'GL5', None ],
]
max_layer = 7
def defaults( self ):
self.name = "Make Gerber-Zip (Elecrow/FusionPCB style)"
self.category = "Plot"
self.description = "Make Gerber-Zip-file for Elecrow / FusionPCB"
def forcedel( self, fname ):
if os.path.exists(fname):
os.remove(fname)
def forceren( self, src, dst ):
self.forcedel(dst)
os.rename(src, dst)
def Run( self ):
board = pcbnew.GetBoard()
board_fname = board.GetFileName()
board_dir = os.path.dirname(board_fname)
board_basename = (os.path.splitext(os.path.basename(board_fname)))[0]
gerber_dir = '%s/%s' % (board_dir, gerber_subdir)
drill_fname = '%s/%s.TXT' % (gerber_dir, board_basename)
npth_fname = '%s/%s-NPTH.TXT' % (gerber_dir, board_basename)
zip_fname = '%s/%s.zip' % (gerber_dir, board_basename)
if not os.path.exists(gerber_dir):
os.mkdir(gerber_dir)
max_layer = board.GetCopperLayerCount() + 5
# PLOT
pc = pcbnew.PLOT_CONTROLLER(board)
po = pc.GetPlotOptions()
po.SetFormat(PLOT_FORMAT_GERBER)
po.SetOutputDirectory(gerber_dir)
po.SetPlotValue(True)
po.SetPlotReference(True)
# po.SetExcludeEdgeLayer(False)
po.SetExcludeEdgeLayer(True)
po.SetLineWidth(FromMM(0.1))
# po.SetSubtractMaskFromSilk(True)
po.SetSubtractMaskFromSilk(False)
po.SetUseAuxOrigin(use_aux_origin)
po.SetPlotViaOnMaskLayer(False)
# Options
po.SetUseGerberProtelExtensions(True)
po.SetCreateGerberJobFile(False)
po.SetSubtractMaskFromSilk(False)
po.SetUseGerberX2format(False)
po.SetIncludeGerberNetlistInfo(False)
for layer in self.layers:
targetname = '%s/%s.%s' % (gerber_dir, board_basename, layer[1])
self.forcedel(targetname)
self.forcedel(drill_fname)
self.forcedel(npth_fname)
self.forcedel(zip_fname)
for i in range(max_layer):
layer = self.layers[i]
pc.SetLayer(layer[0])
pc.OpenPlotfile(layer[1],PLOT_FORMAT_GERBER,layer[1])
pc.PlotLayer()
layer[2] = pc.GetPlotFileName()
pc.ClosePlot()
for i in range(max_layer):
layer = self.layers[i]
targetname = '%s/%s.%s' % (gerber_dir, board_basename, layer[1])
self.forceren(layer[2],targetname)
# DRILL
ew = EXCELLON_WRITER(board)
ew.SetFormat(True, excellon_format, 3, 3)
offset = wxPoint(0,0)
if(use_aux_origin):
offset = board.GetAuxOrigin()
ew.SetOptions(False, False, offset, merge_npth)
ew.CreateDrillandMapFilesSet(gerber_dir,True,False)
if merge_npth:
self.forceren('%s/%s.drl' % (gerber_dir, board_basename), drill_fname)
else:
self.forceren('%s/%s-PTH.drl' % (gerber_dir, board_basename), drill_fname)
self.forceren('%s/%s-NPTH.drl' % (gerber_dir, board_basename), npth_fname)
# ZIP
with zipfile.ZipFile(zip_fname,'w') as f:
for i in range(max_layer):
layer = self.layers[i]
targetname = '%s/%s.%s' % (gerber_dir, board_basename, layer[1])
f.write(targetname, os.path.basename(targetname))
f.write(drill_fname, os.path.basename(drill_fname))
if not merge_npth:
f.write(npth_fname, os.path.basename(npth_fname))
wx.MessageBox('GerberZip Complete.\n\n%s' % zip_fname, 'Gerber Zip', wx.OK|wx.ICON_INFORMATION)
GerberZip().register()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment