Jelajahi Sumber

Minimal Excellon class and test script

Juan Pablo Caram 12 tahun lalu
induk
melakukan
0bd00464de
3 mengubah file dengan 165 tambahan dan 3 penghapusan
  1. 120 3
      camlib.py
  2. TEMPAT SAMPAH
      camlib.pyc
  3. 45 0
      test_excellon_1.py

+ 120 - 3
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):
     '''

TEMPAT SAMPAH
camlib.pyc


+ 45 - 0
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()