From f1626982a3da4d20cfe5b85095195e8226ed53ef Mon Sep 17 00:00:00 2001 From: Juan Pablo Caram Date: Sat, 4 Jan 2014 00:47:57 -0500 Subject: [PATCH] Created class CNCjob --- camlib.py | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++- camlib.pyc | Bin 45030 -> 45148 bytes 2 files changed, 119 insertions(+), 2 deletions(-) diff --git a/camlib.py b/camlib.py index 3d81060c..fbea85b8 100644 --- a/camlib.py +++ b/camlib.py @@ -106,7 +106,7 @@ class Gerber(): "width":float(gline[indexO+2:indexX]), "height":float(gline[indexX+1:indexstar])} return apid - print "Aperture not implemented:", gline + print "WARNING: Aperture not implemented:", gline return None def parse_file(self, filename): @@ -119,7 +119,6 @@ class Gerber(): ''' Main Gerber parser. ''' - path = [] # Coordinates of the current path last_path_aperture = None current_aperture = None @@ -171,6 +170,8 @@ class Gerber(): indexX = gline.find("X") self.digits = int(gline[indexX + 1]) self.fraction = int(gline[indexX + 2]) + continue + print "WARNING: Line ignored:", gline def create_geometry(self): if len(self.buffered_paths) == 0: @@ -193,12 +194,128 @@ class Gerber(): maxy = loc[1] + height/2 rectangle = shply_box(minx, miny, maxx, maxy) flash_polys.append(rectangle) + continue + print "WARNING: Aperture type %s not implemented"%(aperture['type']) #TODO: Add support for type='O' self.solid_geometry = cascaded_union( self.buffered_paths + [poly['polygon'] for poly in self.regions] + flash_polys) +class CNCjob(): + def __init__(self, units="in", kind="generic", z_move = 0.1, + feedrate = 3.0, z_cut = -0.002): + # Options + self.kind = kind + self.units = units + self.z_cut = z_cut + self.z_move = z_move + self.feedrate = feedrate + + # Constants + self.unitcode = {"in": "G20", "mm": "G21"} + self.pausecode = "G04 P1" + self.feedminutecode = "G94" + self.absolutecode = "G90" + + # Output G-Code + self.gcode = "" + + def generate_from_geometry(self, geometry, append=True): + if append == False: + self.gcode = "" + t = "G0%d X%.4fY%.4f\n" + self.gcode = self.unitcode[self.units] + "\n" + self.gcode += self.absolutecode + "\n" + self.gcode += self.feedminutecode + "\n" + self.gcode += "F%.2f\n"%self.feedrate + 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: + path = list(geo.exterior.coords) # Polygon exterior + self.gcode += t%(0, path[0][0], path[0][1]) # Move to first point + self.gcode += "G01 Z%.4f\n"%self.z_cut # Start cutting + for pt in path[1:]: + self.gcode += t%(1, pt[0], pt[1]) # Linear motion to point + self.gcode += "G00 Z%.4f\n"%self.z_move # Stop cutting + for ints in geo.interiors: # Polygon interiors + path = list(ints.coords) + self.gcode += t%(0, path[0][0], path[0][1]) # Move to first point + self.gcode += "G01 Z%.4f\n"%self.z_cut # Start cutting + for pt in path[1:]: + self.gcode += t%(1, pt[0], pt[1]) # Linear motion to point + self.gcode += "G00 Z%.4f\n"%self.z_move # Stop cutting + continue + + if type(geo) == LineString or type(geo) == LineRing: + path = list(geo.coords) + self.gcode += t%(0, path[0][0], path[0][1]) # Move to first point + self.gcode += "G01 Z%.4f\n"%self.z_cut # Start cutting + for pt in path[1:]: + self.gcode += t%(1, pt[0], pt[1]) # Linear motion to point + self.gcode += "G00 Z%.4f\n"%self.z_move # Stop cutting + continue + + if type(geo) == Point: + path = list(geo.coords) + self.gcode += t%(0, path[0][0], path[0][1]) # Move to first point + self.gcode += "G01 Z%.4f\n"%self.z_cut # Start cutting + self.gcode += "G00 Z%.4f\n"%self.z_move # Stop cutting + continue + + print "WARNING: G-code generation not implemented for %s"%(str(type(geo))) + + self.gcode += "M05\n" # Spindle stop + + def create_gcode_geometry(self): + geometry = [] + + gobjs = gparse1b(self.gcode) + + # Last known instruction + current = {'X': 0.0, 'Y': 0.0, 'Z': 0.0, 'G': 0} + + # Process every instruction + 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 " To:", gobj + current['Z'] = gobj['Z'] + + if 'G' in gobj: + current['G'] = gobj['G'] + + if 'X' in gobj or 'Y' in gobj: + x = 0 + y = 0 + kind = ["C","F"] # T=travel, C=cut, F=fast, S=slow + if 'X' in gobj: + x = gobj['X'] + else: + x = current['X'] + if 'Y' in gobj: + y = gobj['Y'] + else: + y = current['Y'] + if current['Z'] > 0: + kind[0] = 'T' + if current['G'] == 1: + kind[1] = 'S' + geometry.append({'geom':LineString([(current['X'],current['Y']), + (x,y)]), 'kind':kind}) + + # Update current instruction + for code in gobj: + current[code] = gobj[code] + + return geometry + + + def fix_poly(poly): ''' Fixes polygons with internal cutouts by identifying diff --git a/camlib.pyc b/camlib.pyc index db626d70cd5f9911bfa0e3f24dc4352566873742..97bc744846fb452057afcc14d4e9e7194102653c 100644 GIT binary patch delta 557 zcmYk1Ur3W-6vofs7UWfQli7(~1Q7%wgk6MXD3Q@$yb($Wq!_(+5nVh74u|J?e&_3qc=thAwRwAf z?)ccK^>x0zoQRr3yQ15pk)WSv@_%7Pw;*aK>K7DqQ@{3i>U5$>WI*)?qP$?sL9_|E zP`K3{CyFhhNXDQ@Lywo5m1FlBj|>-0EKRxpkKWM{H~k&$@$RG<3re?R+R~)Xq|2X< zogNP?I0Cg6Dp{1mN~zPb#ktw$M26^?u9_{7L(ZdO6Qovr(XrTUqm07S$m@wYz04eW58^uUb70U7AEmf(tD*E5Up@f-C_a;q$x-Vh+D^mV=ciP|4 zmFP6P%y`<2Noz^Y@?a6BS{Aq}4Z8w$${N=d1bNKWr{N`sN^c4L;P+*x04ujHn*uyC z;5&p8zV7SQu!;-HvjUC$Y;~Q1GieBpgnlX>{g)iu8j?3WvA zA7P3=*QN~I;l1I2z${XdrAr*Z37>QQ9QOq-22X4ne6)h^j5o2XKkb03}H+Fr^i~AP2))&#e2YOr|3z z5Ro&Hah&I>yg?0%JRf^1@SB_RhX9?I3%)`TuaDe<#s0!R4M%zS*n5HNe6A>Nz~Q0e zE5N3_Qu+~F96tF0_{l3}8#&nJmlX#F+T@F>ci7;Y)jbBL`AgjyfgRTBn}gWrwr0b^ zXYRbc?!^;6dq1w>4-a(D>IiX3U&f1CUT~&#{NncEU4eXVcsOUEhO;BF956>G9UW1A j^f)Ha!821=HT3gAX4S-VUVgQx<1}a9OaSw;^zEsCOE-&E