printrun-src/printrun/laser.py

changeset 23
e18b2a4ef561
parent 22
4c9bb8f93ae8
child 25
0e3e7fbf0bc6
equal deleted inserted replaced
22:4c9bb8f93ae8 23:e18b2a4ef561
44 """ 44 """
45 Default settings object 45 Default settings object
46 """ 46 """
47 def __init__(self): 47 def __init__(self):
48 self.lc_engrave_speed = 10 48 self.lc_engrave_speed = 10
49 # 30mm/min works for wood (regulate the output power to something between 10-30%) 49 # 30mm/sec works for wood (regulate the output power to something between 10-30%)
50 # 30mm/min for black anodized aluminum to get a light engraving @ 100% power 50 # 30mm/sec for black anodized aluminum to get a light engraving @ 100% power
51 # 10mm/min for black anodized aluminum to get more "silver" @ 100% power 51 # 10mm/sec for black anodized aluminum to get maximum possible engraving! @ 100% power
52 self.lc_travel_speed = 120 52 self.lc_travel_speed = 120
53 53
54 # BITMAP: 54 # BITMAP:
55 self.lc_bitmap_speed_factor = 1.0 55 self.lc_bitmap_speed_factor = 1.0
56 self.lc_dpi = 300 56 self.lc_dpi = 300
84 # STATIC DEFINITIONS, DO NOT CHANGE WORLD's RULES! 84 # STATIC DEFINITIONS, DO NOT CHANGE WORLD's RULES!
85 self.INCH = 25.4 # mm 85 self.INCH = 25.4 # mm
86 self.MM_PIXEL = round(self.INCH / self.settings.lc_dpi, 4) 86 self.MM_PIXEL = round(self.INCH / self.settings.lc_dpi, 4)
87 self.STEPS_PIXEL = self.MM_PIXEL * 80 # mine is 80 steps/mm on XY 87 self.STEPS_PIXEL = self.MM_PIXEL * 80 # mine is 80 steps/mm on XY
88 88
89 self.log("Lasercutter library initialized\n%d DPI (%f mm/pixel)" % (self.settings.lc_dpi, self.MM_PIXEL)) 89 self.log("Lasercutter library initialized\n%d DPI (%f mm/pixel)" % (
90 self.settings.lc_dpi, self.MM_PIXEL))
90 if self.STEPS_PIXEL <= 5: 91 if self.STEPS_PIXEL <= 5:
91 self.log("WARNING: STEPS PER PIXEL NEEDS TO BE > 5 (otherwise marlin joins lines): %f" % self.STEPS_PIXEL) 92 self.log("WARNING: STEPS PER PIXEL NEEDS TO BE > 5 (otherwise marlin joins lines): %f" % (
93 self.STEPS_PIXEL))
92 self.log("Travel/Engrave speed: %d mm/sec, %d mm/sec" % ( 94 self.log("Travel/Engrave speed: %d mm/sec, %d mm/sec" % (
93 self.settings.lc_travel_speed, self.settings.lc_engrave_speed) ) 95 self.settings.lc_travel_speed, self.settings.lc_engrave_speed) )
94 self.log("") 96 self.log("")
95 97
96 def log_print(self, msg): 98 def log_print(self, msg):
140 142
141 fo = open(filename + ".g", "w") 143 fo = open(filename + ".g", "w")
142 fo.write("; Filename: %s\n%s" % (filename, GCODE_HEAD)) 144 fo.write("; Filename: %s\n%s" % (filename, GCODE_HEAD))
143 145
144 fo.write(";Start engraving the raster image: %dx%d points @ %d DPI = %.0fx%.0f mm\n\n" % ( 146 fo.write(";Start engraving the raster image: %dx%d points @ %d DPI = %.0fx%.0f mm\n\n" % (
145 im.size[0], im.size[1], self.settings.lc_dpi, im.size[0] * self.MM_PIXEL, im.size[1] * self.MM_PIXEL) ) 147 im.size[0], im.size[1], self.settings.lc_dpi,
148 im.size[0] * self.MM_PIXEL, im.size[1] * self.MM_PIXEL) )
146 149
147 INVERT_Y = self.MM_PIXEL * (im.size[1] -1) * (-1) 150 INVERT_Y = self.MM_PIXEL * (im.size[1] -1) * (-1)
148 DIR = 1 151 DIR = 1
149 travel_speed = self.settings.lc_travel_speed * 60 152 travel_speed = self.settings.lc_travel_speed * 60
150 engrave_speed = self.settings.lc_engrave_speed * 60 * self.settings.lc_bitmap_speed_factor 153 engrave_speed = self.settings.lc_engrave_speed * 60 * self.settings.lc_bitmap_speed_factor
151 for X in range(im.size[0]): 154 for X in range(im.size[0]):
152 # TODO: Skip empty rows!!! 155 gcode_col = ""
153 fo.write("M400 ; X=%d printing row: direction %i\n" % (X, DIR))
154 fo.write("G92 E0\n")
155 E = 0 156 E = 0
156 last_bit = 1 # we engrave on black pixel = 0 157 last_bit = 1 # we engrave on black pixel = 0
157 START_Y = 0 158 START_Y = 0
158 if DIR > 0: 159 if DIR > 0:
159 range_start = 0 160 range_start = 0
183 # draw line 184 # draw line
184 if DIR > 0: 185 if DIR > 0:
185 E = E + self.MM_PIXEL * (Y - START_Y) 186 E = E + self.MM_PIXEL * (Y - START_Y)
186 else: 187 else:
187 E = E + self.MM_PIXEL * (START_Y - Y) 188 E = E + self.MM_PIXEL * (START_Y - Y)
188 fo.write("G1 X%.4f Y%.4f E%.4f F%.4f\n" % (XMM, YMM, E * E_FACTOR, engrave_speed)) 189 gcode_col += "G1 X%.4f Y%.4f E%.4f F%.4f\n" % (
190 XMM, YMM, E * E_FACTOR, engrave_speed)
189 else: 191 else:
190 # bit value has changed! 192 # bit value has changed!
191 if bit == 0: 193 if bit == 0:
192 # jump to start of line to write 194 # jump to start of line to write
193 START_Y = Y 195 START_Y = Y
194 fo.write("G0 X%.4f Y%.4f F%.4f\n" % (XMM, YMM, travel_speed)) 196 gcode_col += "G0 X%.4f Y%.4f F%.4f\n" % (
197 XMM, YMM, travel_speed)
195 else: 198 else:
196 # end of line to write 199 # end of line to write
197 if DIR > 0: 200 if DIR > 0:
198 E = E + (self.MM_PIXEL * (Y - START_Y)) 201 E = E + (self.MM_PIXEL * (Y - START_Y))
199 else: 202 else:
200 E = E + (self.MM_PIXEL * (START_Y - Y)) 203 E = E + (self.MM_PIXEL * (START_Y - Y))
201 fo.write("G1 X%.4f Y%.4f E%.4f F%.4f\n" % (XMM, YMM, E * E_FACTOR, engrave_speed)) 204 gcode_col += "G1 X%.4f Y%.4f E%.4f F%.4f\n" % (
205 XMM, YMM, E * E_FACTOR, engrave_speed)
202 last_bit = bit 206 last_bit = bit
207 if gcode_col <> "":
208 # we skip empty columns
209 fo.write("M400 ; X=%d printing row: direction %i\nG92 E0\n%s" % (
210 X, DIR, gcode_col))
203 if self.settings.lc_change_dir: 211 if self.settings.lc_change_dir:
204 DIR = DIR * (-1) # change y direction on every X 212 DIR = DIR * (-1) # change y direction on every X
205 213
206 fo.write(GCODE_FOOT) 214 fo.write(GCODE_FOOT)
207 fo.close() 215 fo.close()
242 elif cmd == "PU": 250 elif cmd == "PU":
243 LASER_STATE = 0 251 LASER_STATE = 0
244 if last_cmd == "PD": 252 if last_cmd == "PD":
245 OFFSET_X = coord[0] * -1 253 OFFSET_X = coord[0] * -1
246 OFFSET_Y = coord[1] * -1 254 OFFSET_Y = coord[1] * -1
247 fo.write("; PD PU detected, set coord offset %.4f x %.4f mm\n" % (OFFSET_X, OFFSET_Y)) 255 fo.write("; PD PU detected, set coord offset %.4f x %.4f mm\n" % (
256 OFFSET_X, OFFSET_Y))
248 elif cmd == "PA" or cmd == "PR": 257 elif cmd == "PA" or cmd == "PR":
249 # TODO: convert relative coordinates to absolute here! 258 # TODO: convert relative coordinates to absolute here!
250 coord = action[2:].split(",") 259 coord = action[2:].split(",")
251 coord[0] = (float(coord[0]) + OFFSET_X) * SCALE_FACTOR 260 coord[0] = (float(coord[0]) + OFFSET_X) * SCALE_FACTOR
252 coord[1] = (float(coord[1]) + OFFSET_Y) * SCALE_FACTOR 261 coord[1] = (float(coord[1]) + OFFSET_Y) * SCALE_FACTOR
340 if xo == xs and yo == ys: continue 349 if xo == xs and yo == ys: continue
341 350
342 if not pen: start = True 351 if not pen: start = True
343 if xs >= 0 and xs <= bed_max_x and ys >= 0 and ys <= bed_max_y: 352 if xs >= 0 and xs <= bed_max_x and ys >= 0 and ys <= bed_max_y:
344 if start: 353 if start:
345 fo.write("G0 X%0.2f Y%0.2f F%.4f ; Move to start of shape\n" % (xs, ys, travel_speed)) 354 fo.write("G0 X%0.2f Y%0.2f F%.4f ; Move to start of shape\n" % (
355 xs, ys, travel_speed))
346 start = False 356 start = False
347 xo = xs 357 xo = xs
348 yo = ys 358 yo = ys
349 object_xs = xs 359 object_xs = xs
350 object_ys = ys 360 object_ys = ys
351 else: 361 else:
352 e_distance = math.hypot(xs - xo, ys - yo) 362 e_distance = math.hypot(xs - xo, ys - yo)
353 xo = xs 363 xo = xs
354 yo = ys 364 yo = ys
355 E = E + (e_distance) 365 E = E + (e_distance)
356 fo.write("G1 X%0.2f Y%0.2f E%.4f F%.4f\n" % (xs, ys, E * E_FACTOR, engrave_speed)) 366 fo.write("G1 X%0.2f Y%0.2f E%.4f F%.4f\n" % (
367 xs, ys, E * E_FACTOR, engrave_speed))
357 else: 368 else:
358 self.log("Position outside print dimension: %d, %d" % (xs, ys)) 369 self.log("Position outside print dimension: %d, %d" % (xs, ys))
359 if shape_obj.xml_node.get('fill'): 370 if shape_obj.xml_node.get('fill'):
360 # Close the polygon 371 # Close the polygon
361 e_distance = math.hypot(object_xs - xo, object_ys - yo) 372 e_distance = math.hypot(object_xs - xo, object_ys - yo)
362 E = E + (e_distance) 373 E = E + (e_distance)
363 fo.write("G1 X%0.2f Y%0.2f E%.4f F%.4f ; Close the object polygon\n" % (object_xs, object_ys, E * E_FACTOR, engrave_speed)) 374 fo.write("G1 X%0.2f Y%0.2f E%.4f F%.4f ; Close the object polygon\n" % (
375 object_xs, object_ys, E * E_FACTOR, engrave_speed))
364 print "connecting filled path end to start" 376 print "connecting filled path end to start"
365 377
366 fo.write(GCODE_FOOT) 378 fo.write(GCODE_FOOT)
367 fo.close() 379 fo.close()
368 380

mercurial