1
1
import os
2
2
import sys
3
3
from argparse import ArgumentParser
4
- import pcbnew
5
4
import logging
6
5
from datetime import datetime
7
6
import wx
7
+ import zipfile
8
+
9
+ from pcbnew import *
8
10
9
11
class CAMmer ():
10
12
def __init__ (self ):
@@ -42,14 +44,14 @@ def startCAMmer(self, args, board=None, logger=None):
42
44
43
45
if logger is None :
44
46
logger = logging .getLogger ()
45
- logger .setLevel ([ logging .WARNING , logging . DEBUG ][ args . verbose ] )
47
+ logger .setLevel (logging .DEBUG )
46
48
47
49
logger .info ('CAMMER START: ' + datetime .now ().isoformat ())
48
50
49
51
# Read the args
50
52
sourceBoardFile = args .path
51
53
layers = args .layers
52
- edges = args .edge
54
+ edges = args .edges
53
55
54
56
# Check if this is running in a plugin
55
57
if board is None :
@@ -66,14 +68,14 @@ def startCAMmer(self, args, board=None, logger=None):
66
68
return sysExit , report
67
69
68
70
# Load source board from file
69
- board = pcbnew . LoadBoard (sourceBoardFile )
71
+ board = LoadBoard (sourceBoardFile )
70
72
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" )
73
75
else : # Running in a plugin
74
76
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" )
77
79
78
80
if board is None :
79
81
report += "Could not load board. Quitting.\n "
@@ -86,7 +88,7 @@ def startCAMmer(self, args, board=None, logger=None):
86
88
return sysExit , report
87
89
88
90
# Check if about to overwrite a zip file
89
- if os .path .isfile (zipFile ):
91
+ if os .path .isfile (zipFilename ):
90
92
if wx .GetApp () is not None :
91
93
resp = wx .MessageBox ("You are about to overwrite existing files.\n Are you sure?" ,
92
94
'Warning' , wx .OK | wx .CANCEL | wx .ICON_WARNING )
@@ -96,8 +98,109 @@ def startCAMmer(self, args, board=None, logger=None):
96
98
return sysExit , report
97
99
98
100
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 ]
100
161
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 ()
101
204
102
205
if sysExit < 0 :
103
206
sysExit = 0
0 commit comments