diff --git a/camlib.py b/camlib.py index d7a79df0..c18b4913 100644 --- a/camlib.py +++ b/camlib.py @@ -228,7 +228,7 @@ class Gerber (Geometry): [poly['polygon'] for poly in self.regions] + flash_polys) -class CNCjob(): +class CNCjob: def __init__(self, units="in", kind="generic", z_move = 0.1, feedrate = 3.0, z_cut = -0.002): # Options @@ -256,6 +256,45 @@ class CNCjob(): # Output generated by CNCjob.create_gcode_geometry() self.G_geometry = None + def generate_from_excellon(self, exobj): + ''' + Generates G-code for drilling from excellon text. + self.gcode becomes a list, each element is a + different job for each tool in the excellon code. + ''' + self.kind = "drill" + self.gcode = [] + + t = "G00 X%.4fY%.4f\n" + down = "G01 Z%.4f\n"%self.z_cut + up = "G01 Z%.4f\n"%self.z_move + + for tool in exobj.tools: + + points = [] + gcode = "" + + for drill in exobj.drill: + if drill['tool'] == tool: + points.append(drill['point']) + + gcode = self.unitcode[self.units] + "\n" + gcode += self.absolutecode + "\n" + gcode += self.feedminutecode + "\n" + gcode += "F%.2f\n"%self.feedrate + gcode += "G00 Z%.4f\n"%self.z_move # Move to travel height + gcode += "M03\n" # Spindle start + gcode += self.pausecode + "\n" + + for point in points: + gcode += t%point + gcode += down + up + + gcode += t%(0,0) + gcode += "M05\n" # Spindle stop + + self.gcode.append(gcode) + def generate_from_geometry(self, geometry, append=True, tooldia=None): ''' Generates G-Code for geometry (Shapely collection). @@ -314,15 +353,19 @@ class CNCjob(): print "WARNING: G-code generation not implemented for %s"%(str(type(geo))) + self.gcode += "G00 Z%.4f\n"%self.z_move # Stop cutting + self.gcode += "G00 X0Y0\n" self.gcode += "M05\n" # Spindle stop def create_gcode_geometry(self): ''' - G-Code parser. Generates dictionary with single-segment LineString's - and "kind" indicating cut or travel, fast or feedrate speed. + G-Code parser (from self.gcode). Generates dictionary with + single-segment LineString's and "kind" indicating cut or travel, + fast or feedrate speed. ''' geometry = [] + # TODO: ???? bring this into the class?? gobjs = gparse1b(self.gcode) # Last known instruction @@ -400,6 +443,80 @@ class CNCjob(): return fig + +class Excellon(Geometry): + def __init__(self): + Geometry.__init__(self) + + self.tools = {} + + self.drills = [] + + def parse_file(self, filename): + efile = open(filename, 'r') + estr = efile.readlines() + efile.close() + self.parse_lines(estr) + + def parse_lines(self, elines): + ''' + Main Excellon parser. + ''' + current_tool = "" + + for eline in elines: + + ## Tool definitions ## + # TODO: Verify all this + indexT = eline.find("T") + indexC = eline.find("C") + indexF = eline.find("F") + # Type 1 + if indexT != -1 and indexC > indexT and indexF > indexF: + tool = eline[1:indexC] + spec = eline[indexC+1:indexF] + self.tools[tool] = spec + continue + # Type 2 + # TODO: Is this inches? + #indexsp = eline.find(" ") + #indexin = eline.find("in") + #if indexT != -1 and indexsp > indexT and indexin > indexsp: + # tool = eline[1:indexsp] + # spec = eline[indexsp+1:indexin] + # self.tools[tool] = spec + # continue + # Type 3 + if indexT != -1 and indexC > indexT: + tool = eline[1:indexC] + spec = eline[indexC+1:-1] + self.tools[tool] = spec + continue + + ## Tool change + if indexT == 0: + current_tool = eline[1:-1] + continue + + ## Drill + indexX = eline.find("X") + indexY = eline.find("Y") + if indexX != -1 and indexY != -1: + x = float(int(eline[indexX+1:indexY])/10000.0) + y = float(int(eline[indexY+1:-1])/10000.0) + self.drills.append({'point':Point((x,y)), 'tool':current_tool}) + continue + + print "WARNING: Line ignored:", eline + + def create_geometry(self): + self.solid_geometry = [] + sizes = {} + for tool in self.tools: + sizes[tool] = float(self.tools[tool]) + for drill in self.drills: + poly = Point(drill['point']).buffer(sizes[drill['tool']]/2.0) + self.solid_geometry.append(poly) def fix_poly(poly): ''' diff --git a/camlib.pyc b/camlib.pyc index 05a5333a..3970c11b 100644 Binary files a/camlib.pyc and b/camlib.pyc differ diff --git a/test_excellon_1.py b/test_excellon_1.py new file mode 100644 index 00000000..72656b61 --- /dev/null +++ b/test_excellon_1.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +""" +Created on Sun Jan 05 13:30:47 2014 + +@author: jpcaram +""" + +from camlib import * +#from matplotlib.figure import Figure +from matplotlib import pyplot + +# Gerber. To see if the Excellon is correct +project_dir = "C:/Users/jpcaram/Dropbox/VNA/KiCad_Squarer/" +gerber_filename = project_dir + "KiCad_Squarer-F_Cu.gtl" +g = Gerber() +g.parse_file(gerber_filename) +g.create_geometry() + +excellon_filename = project_dir + "KiCad_Squarer.drl" +ex = Excellon() +ex.parse_file(excellon_filename) +ex.create_geometry() + +#fig = Figure() +fig = pyplot.figure() +ax = fig.add_subplot(111) +ax.set_aspect(1) + +# Plot gerber +for geo in g.solid_geometry: + x, y = geo.exterior.coords.xy + plot(x, y, 'k-') + for ints in geo.interiors: + x, y = ints.coords.xy + ax.plot(x, y, 'k-') + +# Plot excellon +for geo in ex.solid_geometry: + x, y = geo.exterior.coords.xy + plot(x, y, 'r-') + for ints in geo.interiors: + x, y = ints.coords.xy + ax.plot(x, y, 'g-') + +fig.show() \ No newline at end of file