aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/kicad_gerber.cmake25
-rwxr-xr-xpy/kicad_gerber.py160
2 files changed, 130 insertions, 55 deletions
diff --git a/cmake/kicad_gerber.cmake b/cmake/kicad_gerber.cmake
index 330c5bd..580fa10 100644
--- a/cmake/kicad_gerber.cmake
+++ b/cmake/kicad_gerber.cmake
@@ -1,7 +1,7 @@
function(kicad_gerber)
- set(options ALL)
+ set(options ALL UPPERCASE_EXTENSIONS)
set(one_value_args TARGET PCB_FILE DIR ZIP_FILE NAMING_STYLE)
- set(multi_value_args)
+ set(multi_value_args LAYER_EXTENSION)
cmake_parse_arguments(ARGS "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN})
if (NOT ARGS_PCB_FILE)
@@ -15,7 +15,7 @@ function(kicad_gerber)
if (ARGS_NAMING_STYLE STREQUAL MODERN)
elseif (ARGS_NAMING_STYLE STREQUAL PROTEL)
- set(protel --protel-extension)
+ set(protel --protel-extensions)
else ()
message(SEND_ERROR "Unsupported NAMING_STYLE: ${ARGS_NAMING_STYLE}")
return()
@@ -36,11 +36,19 @@ function(kicad_gerber)
return()
endif ()
+ foreach (le ${ARGS_LAYER_EXTENSION})
+ list(APPEND les --layer-extension ${le})
+ endforeach ()
+
+ if (ARGS_UPPERCASE_EXTENSIONS)
+ set(uppercase_extensions --uppercase-extensions)
+ endif ()
+
set(out_dir "${ARGS_DIR}")
set(prefix "${out_dir}/${basename}")
execute_process(
- COMMAND "${KicadUtilsPyDir}/kicad_gerber.py" --pcb "${pcb_file}" --output-directory "${out_dir}" ${protel} --detect-files-only
+ COMMAND "${KicadUtilsPyDir}/kicad_gerber.py" --pcb "${pcb_file}" --output-directory "${out_dir}" ${protel} ${uppercase_extensions} ${les} --detect-files-only
OUTPUT_FILE ${CMAKE_CURRENT_BINARY_DIR}/${target}-gerber-index.txt
OUTPUT_VARIABLE out
ERROR_VARIABLE err
@@ -53,16 +61,11 @@ function(kicad_gerber)
return()
endif ()
-# foreach (o ${out})
-# list(APPEND outputs ${prefix}${o})
-# endforeach ()
-
- # message("out=${out}")
- message("outputs=${outputs}")
+ message("outputs=${outputs}")
add_custom_command(
OUTPUT ${outputs}
COMMAND cmake -E make_directory "${out_dir}"
- COMMAND "${KicadUtilsPyDir}/kicad_gerber.py" --pcb "${pcb_file}" --output-directory "${out_dir}" ${protel}
+ COMMAND "${KicadUtilsPyDir}/kicad_gerber.py" --pcb "${pcb_file}" --output-directory "${out_dir}" ${protel} ${uppercase_extensions} ${les}
MAIN_DEPENDENCY "${pcb_file}")
if (ARGS_ALL)
diff --git a/py/kicad_gerber.py b/py/kicad_gerber.py
index 45358c0..e963be7 100755
--- a/py/kicad_gerber.py
+++ b/py/kicad_gerber.py
@@ -4,6 +4,13 @@ import os
import argparse
from pcbnew import *
+def layer_name_parser(s):
+ parts = s.split('=')
+ if len(parts) != 2:
+ raise argparse.ArgumentTypeError("Invalid layer renaming: " + s)
+ else:
+ return parts
+
parser = argparse.ArgumentParser(description='KiCAD PCB to GERBER converter')
parser.add_argument('--pcb',
@@ -31,26 +38,60 @@ parser.add_argument('--create-drill-map-file',
parser.add_argument('--protel-extensions',
dest='protel_extensions',
action='store_true',
- help='Use Protel filename extensions')
-
-args = parser.parse_args()
+ help='Use Protel filename extensions instead of .gbr')
-filename = args.pcb
+parser.add_argument('--uppercase-extensions',
+ action='store_true',
+ help='Uppercase all extensions')
-board = LoadBoard(filename)
+parser.add_argument('--layer-extension',
+ dest='layer_extensions',
+ metavar='LAYER_AND_EXTENSION',
+ action='append',
+ type=layer_name_parser,
+ help='Set the file extension of a KiCAD layer. Format: <KiCAD Layer>=<extension>, example: F.SilkS=GSILK')
-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"),
-]
+args = parser.parse_args()
+# print "args: " + str(args)
+# print "args.name_layer: " + str(args.name_layers)
+
+renames = {}
+if args.layer_extensions is not None:
+ for s in args.layer_extensions:
+ renames[s[0]] = s[1]
+# print("renames: " + str(renames))
+
+board = LoadBoard(args.pcb)
+
+class Plan:
+ def __init__(self, layerNum, layerName, description):
+ self.layerNum = layerNum
+ self.layerName = layerName
+ self.description = description
+ self.postfix = ""
+ self.ext = None
+
+ @staticmethod
+ def standard(layerNum, description):
+ layerName = board.GetLayerName(layerNum)
+ return Plan(layerNum, layerName, description)
+
+ @staticmethod
+ def copper(layerNum):
+ layerName = board.GetLayerName(layerNum)
+ description = "Copper Layer " + layerName
+ return Plan(layerNum, layerName, description)
+
+plot_plan = [Plan.standard(layerNum, description) for (layerNum, description) in [
+ (F_SilkS, "Silk front"),
+ (F_Mask, "Mask front"),
+ (B_SilkS, "Silk bottom"),
+ (B_Mask, "Mask bottom"),
+ (Edge_Cuts, "Edges")]]
layers = board.GetEnabledLayers()
-for i in layers.CuStack():
- name = board.GetLayerName(i)
- plot_plan.append(("", name, i, "Copper Layer " + name))
+for layerNum in layers.CuStack():
+ plot_plan.append(Plan.copper(layerNum))
pctl = PLOT_CONTROLLER(board)
popt = pctl.GetPlotOptions()
@@ -66,32 +107,58 @@ except:
pass
pctl.ClosePlot()
-basename = filename.replace('.gbr', '')
-drlFile = basename + ".drl"
-drlFileProtel = basename + ".txt"
-
if args.protel_extensions:
popt.SetUseGerberProtelExtensions(True)
+basename = os.path.splitext(filename)[0]
+
+drlFileOut = drlFile = basename + ".drl"
+
+if args.protel_extensions:
+ n, e = os.path.splitext(drlFileOut)
+ drlFileOut = n + ".txt"
+
+if args.uppercase_extensions:
+ n, e = os.path.splitext(drlFileOut)
+ drlFileOut = n + e.upper()
+
+values = vars(args)
+for plan in plot_plan:
+ pctl.SetLayer(plan.layerNum)
+ pctl.OpenPlotfile("", PLOT_FORMAT_GERBER, plan.description)
+ filename = pctl.GetPlotFileName()
+ pctl.ClosePlot()
+ # By opening and closing the plot we create an empty plot file.
+ try:
+ os.remove(filename)
+ except:
+ pass
+
+ filename, ext = os.path.splitext(filename)
+ if args.uppercase_extensions:
+ ext = ext.upper()
+
+ if plan.layerName in renames:
+ ext = "." + renames[plan.layerName]
+
+ # if plan.arg is not None:
+ # newExt = values[plan.arg]
+ # if newExt is not None:
+ # ext = "." + newExt
+
+ # if not args.protel_extensions:
+ plan.postfix = plan.layerName
+ plan.filename = basename + "-" + plan.postfix + ext
+
+ # print "filename = " + plan.filename + ", postfix=" + plan.postfix
+ # print "filename: " + plan.filename
+
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()
+ for plan in plot_plan:
+ print plan.filename
+
if args.protel_extensions:
- print drlFileProtel
- else:
- print drlFile
+ print drlFileOut
sys.exit(0)
# Set some important plot options:
@@ -108,19 +175,24 @@ 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)
+for plan in plot_plan:
+ pctl.SetLayer(plan.layerNum)
+
+ # print "filename = " + plan.filename + ", postfix=" + plan.postfix
+ pctl.OpenPlotfile(plan.postfix, PLOT_FORMAT_GERBER, plan.description)
+
+ actualFilename = pctl.GetPlotFileName()
+ expectedFilename = plan.filename
+
+ if expectedFilename != actualFilename:
+ os.rename(actualFilename, expectedFilename)
- 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
@@ -139,6 +211,6 @@ genMap = args.create_drill_map_file
drlwriter.CreateDrillandMapFilesSet(pctl.GetPlotDirName(), genDrl, genMap)
-if args.protel_extensions:
- os.rename(drlFile, basename + ".txt")
+if drlFile != drlFileOut:
+ os.rename(drlFile, drlFileOut)
pass