|
|
@@ -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):
|
|
|
'''
|