From ff46b2afe93096b8668d5cb4b31f9fb3f79fd181 Mon Sep 17 00:00:00 2001 From: Juan Pablo Caram Date: Sat, 4 Jan 2014 20:54:30 -0500 Subject: [PATCH] Bug fix: missing path in gerber, feature: Gcode parse/plot --- camlib.py | 77 ++++++++++++++++++++++++++++++++++++++++++++++++----- camlib.pyc | Bin 48107 -> 48806 bytes 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/camlib.py b/camlib.py index 893464fa..d7a79df0 100644 --- a/camlib.py +++ b/camlib.py @@ -8,6 +8,7 @@ import cairo #import sys from numpy import arctan2, Inf, array +from matplotlib.figure import Figure # See: http://toblerity.org/shapely/manual.html from shapely.geometry import Polygon, LineString, Point @@ -164,7 +165,7 @@ class Gerber (Geometry): "aperture":current_aperture}) continue if indexD3 == 0: # Flash? - print "Warning: Uninplemented flash style:", gline + print "WARNING: Uninplemented flash style:", gline continue if gline.find("G37*") != -1: # end region @@ -192,7 +193,12 @@ class Gerber (Geometry): self.fraction = int(gline[indexX + 2]) continue 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): if len(self.buffered_paths) == 0: self.buffer_paths() @@ -241,7 +247,26 @@ class CNCjob(): # Output G-Code 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: self.gcode = "" 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 += "M03\n" # Spindle start self.gcode += self.pausecode + "\n" + for geo in geometry: if type(geo) == Polygon: @@ -291,6 +317,10 @@ class CNCjob(): 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. + ''' geometry = [] gobjs = gparse1b(self.gcode) @@ -302,7 +332,7 @@ class CNCjob(): for gobj in gobjs: if 'Z' in gobj: 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 current['Z'] = gobj['Z'] @@ -332,10 +362,45 @@ class CNCjob(): for code in gobj: current[code] = gobj[code] + self.G_geometry = 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): ''' Fixes polygons with internal cutouts by identifying diff --git a/camlib.pyc b/camlib.pyc index 09514b84c73c9c2a3e54e1d1cccc5e36ba0d78f4..05a5333a923e174edd30c4891557761e51ca1e8e 100644 GIT binary patch delta 6793 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 @{9o+|XE| zFW6JKn9plYZ}_3UX_eV)Cr!bnCZbv}4kx9$3euo{cu#Zl#ZZooV|kA|{Wnnu-=~9g zh4<6@t}hx0(YxL_W^cjlto5#VnL7mMq~RYXnJnfBoG1jXMkaJ( z<}3EmeIt&sIP-Ds9M$!hU~&>BxWqFTY=;TC97E!v#RKA0z)mn*Zy%)nfOzzGqIs93 zvdjA%%hjvyM&~{Hl)H|1HG>u_o88_(B21gWv3o~uwvOE=o+Sh zo-`=ngO+m(CxN+44-cBNB7UFTL_^If;2(&3RR?rD$|v3@u0&_p@3p4dNe{K+tDeqB zUM-C64o?nj!~#?A>gI#9TH?#I7&cLRL&MRb;V6Ga6QnIV=nqDX6<#7fxsLM&meZ4H z+Qs2O)Zf#wPrrPy$HkTO72R~`9Jx$iaj0}`HH>csYyn&k;CI~nA#DUa3&2(1ybDSM z){15+B*Qx-zOA7CD^yo5c;?FuR0f4@q>$Z;6B%o)UX-+V)$3AUwA`&%9L~u(gVd&{ U6ekqR0+}VV5^^8b(Zh581C4ybx&QzG