Просмотр исходного кода

Bug fix: missing path in gerber, feature: Gcode parse/plot

Juan Pablo Caram 12 лет назад
Родитель
Сommit
ff46b2afe9
2 измененных файлов с 71 добавлено и 6 удалено
  1. 71 6
      camlib.py
  2. BIN
      camlib.pyc

+ 71 - 6
camlib.py

@@ -8,6 +8,7 @@ import cairo
 #import sys
 #import sys
 
 
 from numpy import arctan2, Inf, array
 from numpy import arctan2, Inf, array
+from matplotlib.figure import Figure
 
 
 # See: http://toblerity.org/shapely/manual.html
 # See: http://toblerity.org/shapely/manual.html
 from shapely.geometry import Polygon, LineString, Point
 from shapely.geometry import Polygon, LineString, Point
@@ -164,7 +165,7 @@ class Gerber (Geometry):
                                      "aperture":current_aperture})
                                      "aperture":current_aperture})
                 continue
                 continue
             if indexD3 == 0: # Flash?
             if indexD3 == 0: # Flash?
-                print "Warning: Uninplemented flash style:", gline
+                print "WARNING: Uninplemented flash style:", gline
                 continue
                 continue
             
             
             if gline.find("G37*") != -1: # end region
             if gline.find("G37*") != -1: # end region
@@ -192,7 +193,12 @@ class Gerber (Geometry):
                 self.fraction = int(gline[indexX + 2])
                 self.fraction = int(gline[indexX + 2])
                 continue
                 continue
             print "WARNING: Line ignored:", gline
             print "WARNING: Line ignored:", gline
-                
+        
+        if len(path) > 1:
+            # EOF, create shapely LineString if something in path
+            self.paths.append({"linestring":LineString(path), 
+                               "aperture":last_path_aperture})
+        
     def create_geometry(self):
     def create_geometry(self):
         if len(self.buffered_paths) == 0:
         if len(self.buffered_paths) == 0:
             self.buffer_paths()
             self.buffer_paths()
@@ -241,7 +247,26 @@ class CNCjob():
         # Output G-Code
         # Output G-Code
         self.gcode = ""
         self.gcode = ""
         
         
-    def generate_from_geometry(self, geometry, append=True):
+        # Bounds of geometry given to CNCjob.generate_from_geometry()
+        self.input_geometry_bounds = None
+        
+        # Tool diameter given to CNCjob.generate_from_geometry()
+        self.tooldia = 0
+        
+        # Output generated by CNCjob.create_gcode_geometry()
+        self.G_geometry = None
+        
+    def generate_from_geometry(self, geometry, append=True, tooldia=None):
+        '''
+        Generates G-Code for geometry (Shapely collection).
+        '''
+        if tooldia == None:
+            tooldia = self.tooldia
+        else:
+            self.tooldia = tooldia
+            
+        self.input_geometry_bounds = geometry.bounds
+        
         if append == False:
         if append == False:
             self.gcode = ""
             self.gcode = ""
         t = "G0%d X%.4fY%.4f\n"
         t = "G0%d X%.4fY%.4f\n"
@@ -252,6 +277,7 @@ class CNCjob():
         self.gcode += "G00 Z%.4f\n"%self.z_move  # Move to travel height
         self.gcode += "G00 Z%.4f\n"%self.z_move  # Move to travel height
         self.gcode += "M03\n" # Spindle start
         self.gcode += "M03\n" # Spindle start
         self.gcode += self.pausecode + "\n"
         self.gcode += self.pausecode + "\n"
+        
         for geo in geometry:
         for geo in geometry:
             
             
             if type(geo) == Polygon:
             if type(geo) == Polygon:
@@ -291,6 +317,10 @@ class CNCjob():
         self.gcode += "M05\n" # Spindle stop
         self.gcode += "M05\n" # Spindle stop
     
     
     def create_gcode_geometry(self):
     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.
+        '''
         geometry = []        
         geometry = []        
         
         
         gobjs = gparse1b(self.gcode)
         gobjs = gparse1b(self.gcode)
@@ -302,7 +332,7 @@ class CNCjob():
         for gobj in gobjs:
         for gobj in gobjs:
             if 'Z' in gobj:
             if 'Z' in gobj:
                 if ('X' in gobj or 'Y' in gobj) and gobj['Z'] != current['Z']:
                 if ('X' in gobj or 'Y' in gobj) and gobj['Z'] != current['Z']:
-                    print "WARNING: No orthogonal motion: From", current
+                    print "WARNING: Non-orthogonal motion: From", current
                     print "         To:", gobj
                     print "         To:", gobj
                 current['Z'] = gobj['Z']
                 current['Z'] = gobj['Z']
                 
                 
@@ -332,10 +362,45 @@ class CNCjob():
             for code in gobj:
             for code in gobj:
                 current[code] = gobj[code]
                 current[code] = gobj[code]
                 
                 
+        self.G_geometry = geometry
         return geometry
         return geometry
+        
+    def plot(self, tooldia=None, dpi=75, margin=0.1,
+             color={"T":["#F0E24D", "#B5AB3A"], "C":["#5E6CFF", "#4650BD"]},
+             alpha={"T":0.3, "C":1.0}):
+        '''
+        Creates a Matplotlib figure with a plot of the
+        G-code job.
+        '''
+        if tooldia == None:
+            tooldia = self.tooldia
+            
+        fig = Figure(dpi=dpi)
+        ax = fig.add_subplot(111)
+        ax.set_aspect(1)
+        xmin, ymin, xmax, ymax = self.input_geometry_bounds
+        ax.set_xlim(xmin-margin, xmax+margin)
+        ax.set_ylim(ymin-margin, ymax+margin)
+        
+        if tooldia == 0:
+            for geo in self.G_geometry:
+                linespec = '--'
+                linecolor = color[geo['kind'][0]][1]
+                if geo['kind'][0] == 'C':
+                    linespec = 'k-'
+                x, y = geo['geom'].coords.xy
+                ax.plot(x, y, linespec, color=linecolor)
+        else:
+            for geo in self.G_geometry:
+                poly = geo['geom'].buffer(tooldia/2.0)
+                patch = PolygonPatch(poly, facecolor=color[geo['kind'][0]][0],
+                                     edgecolor=color[geo['kind'][0]][1],
+                                     alpha=alpha[geo['kind'][0]], zorder=2)
+                ax.add_patch(patch)
+        
+        return fig
+            
                 
                 
-                
-
 def fix_poly(poly):
 def fix_poly(poly):
     '''
     '''
     Fixes polygons with internal cutouts by identifying
     Fixes polygons with internal cutouts by identifying