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 |