Skip to content

Commit 8abf114

Browse files
committed
Add plot layers and zip
1 parent 6ed63db commit 8abf114

File tree

2 files changed

+119
-16
lines changed

2 files changed

+119
-16
lines changed

SparkFunKiCadCAMmer/cammer/cammer.py

Lines changed: 113 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import os
22
import sys
33
from argparse import ArgumentParser
4-
import pcbnew
54
import logging
65
from datetime import datetime
76
import wx
7+
import zipfile
8+
9+
from pcbnew import *
810

911
class CAMmer():
1012
def __init__(self):
@@ -42,14 +44,14 @@ def startCAMmer(self, args, board=None, logger=None):
4244

4345
if logger is None:
4446
logger = logging.getLogger()
45-
logger.setLevel([ logging.WARNING, logging.DEBUG ][args.verbose])
47+
logger.setLevel(logging.DEBUG)
4648

4749
logger.info('CAMMER START: ' + datetime.now().isoformat())
4850

4951
# Read the args
5052
sourceBoardFile = args.path
5153
layers = args.layers
52-
edges = args.edge
54+
edges = args.edges
5355

5456
# Check if this is running in a plugin
5557
if board is None:
@@ -66,14 +68,14 @@ def startCAMmer(self, args, board=None, logger=None):
6668
return sysExit, report
6769

6870
# Load source board from file
69-
board = pcbnew.LoadBoard(sourceBoardFile)
71+
board = LoadBoard(sourceBoardFile)
7072
outputPath = os.path.split(sourceBoardFile)[0] # Get the file path head
71-
zipFile = os.path.split(sourceBoardFile)[1] # Get the file path tail
72-
zipFile = os.path.join(outputPath, os.path.splitext(zipFile)[0] + ".zip")
73+
zipFilename = os.path.split(sourceBoardFile)[1] # Get the file path tail
74+
zipFilename = os.path.join(outputPath, os.path.splitext(zipFilename)[0] + ".zip")
7375
else: # Running in a plugin
7476
outputPath = os.path.split(board.GetFileName())[0] # Get the file path head
75-
zipFile = os.path.split(board.GetFileName())[1] # Get the file path tail
76-
zipFile = os.path.join(outputPath, os.path.splitext(zipFile)[0] + ".zip")
77+
zipFilename = os.path.split(board.GetFileName())[1] # Get the file path tail
78+
zipFilename = os.path.join(outputPath, os.path.splitext(zipFilename)[0] + ".zip")
7779

7880
if board is None:
7981
report += "Could not load board. Quitting.\n"
@@ -86,7 +88,7 @@ def startCAMmer(self, args, board=None, logger=None):
8688
return sysExit, report
8789

8890
# Check if about to overwrite a zip file
89-
if os.path.isfile(zipFile):
91+
if os.path.isfile(zipFilename):
9092
if wx.GetApp() is not None:
9193
resp = wx.MessageBox("You are about to overwrite existing files.\nAre you sure?",
9294
'Warning', wx.OK | wx.CANCEL | wx.ICON_WARNING)
@@ -96,8 +98,109 @@ def startCAMmer(self, args, board=None, logger=None):
9698
return sysExit, report
9799

98100

99-
# ADD MUCH STUFF HERE
101+
# Build layer table
102+
layertable = {}
103+
numlayers = PCB_LAYER_ID_COUNT
104+
for i in range(numlayers):
105+
layertable[board.GetLayerName(i)] = i
106+
107+
# Protel file extensions
108+
file_ext = {
109+
"F.Cu": "GTL",
110+
"In1.Cu": "GL1",
111+
"In2.Cu": "GL2",
112+
"In3.Cu": "GL3",
113+
"In4.Cu": "GL4",
114+
"B.Cu": "GBL",
115+
"F.Mask": "GTS",
116+
"B.Mask": "GBS",
117+
"F.Paste": "GTP",
118+
"B.Paste": "GBP",
119+
"F.Silkscreen": "GTO",
120+
"B.Silkscreen": "GBO",
121+
"Edge.Cuts": "GKO"
122+
}
123+
124+
# Start plotting: https://gitlab.com/kicad/code/kicad/-/blob/master/demos/python_scripts_examples/plot_board.py
125+
126+
pctl = PLOT_CONTROLLER(board)
127+
128+
popt = pctl.GetPlotOptions()
129+
130+
# Set some important plot options:
131+
# One cannot plot the frame references, because the board does not know
132+
# the frame references.
133+
popt.SetPlotFrameRef(False)
134+
popt.SetSketchPadLineWidth(FromMM(0.1))
135+
136+
popt.SetAutoScale(False)
137+
popt.SetScale(1)
138+
popt.SetMirror(False)
139+
popt.SetUseGerberAttributes(True)
140+
popt.SetScale(1)
141+
popt.SetUseAuxOrigin(True)
142+
143+
# This by gerbers only (also the name is truly horrid!)
144+
popt.SetSubtractMaskFromSilk(False) #remove solder mask from silk to be sure there is no silk on pads
145+
146+
filesToZip = []
147+
148+
for layer in layers.split(","):
149+
if layer not in file_ext.keys():
150+
report += "Unknown layer " + layer + "!\n"
151+
sysExit= 2
152+
else:
153+
layername = layer.replace(".", "_")
154+
pctl.SetLayer(layertable[layer])
155+
pctl.OpenPlotfile(layername, PLOT_FORMAT_GERBER)
156+
pctl.PlotLayer()
157+
pctl.ClosePlot() # Release the file - or we can't rename it
158+
159+
plotfile = os.path.splitext(sourceBoardFile)[0] + "-" + layername + ".gbr"
160+
newname = os.path.splitext(sourceBoardFile)[0] + "." + file_ext[layer]
100161

162+
if not os.path.isfile(plotfile):
163+
report += "Could not plot " + plotfile + "\n"
164+
sysExit = 2
165+
else:
166+
if os.path.isfile(newname):
167+
report += "Deleting existing " + newname + "\n"
168+
os.remove(newname)
169+
report += "Renaming " + plotfile + " to " + newname + "\n"
170+
os.rename(plotfile, newname)
171+
if not os.path.isfile(newname):
172+
report += "Could not rename " + newname + "\n"
173+
sysExit = 2
174+
else:
175+
filesToZip.append(newname)
176+
177+
edge = []
178+
edge_ext = ""
179+
for e in edges.split(","):
180+
if e in file_ext.keys():
181+
edge_ext = file_ext[e]
182+
layername = e.replace(".", "_")
183+
edge.append(layertable[e])
184+
185+
if edge_ext == "":
186+
report += "Unknown edge(s) " + str(edges) + "\n"
187+
sysExit= 2
188+
else:
189+
# TODO: add edge layer merge-and-plot here. Try SetLayerSelection and SetPlotOnAllLayersSelection
190+
pass
191+
192+
# TODO: add Excellon drill file export here
193+
# https://gitlab.com/kicad/code/kicad/-/blob/master/demos/python_scripts_examples/gen_gerber_and_drill_files_board.py
194+
195+
# Zip the files
196+
zf = zipfile.ZipFile(zipFilename, "w")
197+
for filename in filesToZip:
198+
zf.write(filename, os.path.basename(filename), compress_type=zipfile.ZIP_DEFLATED)
199+
# Include the ordering_instructions - if present
200+
oi = os.path.join(outputPath, "ordering_instructions.txt")
201+
if os.path.isfile(oi):
202+
zf.write(oi, os.path.basename(oi), compress_type=zipfile.ZIP_DEFLATED)
203+
zf.close()
101204

102205
if sysExit < 0:
103206
sysExit = 0

SparkFunKiCadCAMmer/plugin.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,23 +81,23 @@ def run_cammer(dlg, p_cammer):
8181
layers = dlg.CurrentSettings()["Layers"]
8282
layersCommand = ""
8383
for layer,include in layers.items():
84-
if include:
84+
if include == 'true': # JSON format
8585
if layersCommand == "":
86-
layersCommand = str(layer)
86+
layersCommand = layer
8787
else:
88-
layersCommand = layersCommand + "," + str(layer)
88+
layersCommand = layersCommand + "," + layer
8989

9090
if layersCommand != "":
9191
command.extend(['-l', layersCommand])
9292

9393
edges = dlg.CurrentSettings()["Edges"]
9494
edgesCommand = ""
9595
for edge,include in edges.items():
96-
if include:
96+
if include == 'true': # JSON format
9797
if edgesCommand == "":
98-
edgesCommand = str(edge)
98+
edgesCommand = edge
9999
else:
100-
edgesCommand = edgesCommand + "," + str(edge)
100+
edgesCommand = edgesCommand + "," + edge
101101

102102
if edgesCommand != "":
103103
command.extend(['-e', edgesCommand])

0 commit comments

Comments
 (0)