11import os
22import sys
33from argparse import ArgumentParser
4- import pcbnew
54import logging
65from datetime import datetime
76import wx
7+ import zipfile
8+
9+ from pcbnew import *
810
911class 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.\n Are 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
0 commit comments