28 M201 X1000 Y1000 E1000 ; Set acceleration |
28 M201 X1000 Y1000 E1000 ; Set acceleration |
29 M203 X1000 Y1000 Z4 E1000 ; Set max feedrate |
29 M203 X1000 Y1000 Z4 E1000 ; Set max feedrate |
30 M209 S0 ; disable firmware retraction, we dont want to burn holes... |
30 M209 S0 ; disable firmware retraction, we dont want to burn holes... |
31 M302 ; Allow cold extrudes - doesnt matter because we hack the extruder physically off with the M571 E mod |
31 M302 ; Allow cold extrudes - doesnt matter because we hack the extruder physically off with the M571 E mod |
32 M571 S1 E1 ; Activate Laser output on extrusion, but block real motor movement! |
32 M571 S1 E1 ; Activate Laser output on extrusion, but block real motor movement! |
|
33 M85 S0 ; Disable idle hold timeout |
|
34 M84 ; enable motors |
|
35 |
33 """ |
36 """ |
34 |
37 |
35 GCODE_FOOT = """G0 X0 Y0 F%.4f |
38 GCODE_FOOT = """ |
|
39 M42 P28 S0 ; Force laser off! |
|
40 M85 S30 ; re-enable idle hold timeout |
|
41 G0 X0 Y0 F%.4f ; Move back to origin |
36 M400 ; Wait for all moves to finish |
42 M400 ; Wait for all moves to finish |
37 M571 S0 E0 |
43 M571 S0 E0 ; disable extruder firmware hack |
38 M42 P28 S0 ; Force laser off! |
|
39 M501 ; undo all settings made |
44 M501 ; undo all settings made |
40 """ % (100*60) |
45 """ % (100*60) |
41 |
46 |
42 |
47 |
43 class LasercutterSettings: |
48 class LasercutterSettings: |
293 def svg2gcode(self, filename): |
298 def svg2gcode(self, filename): |
294 # Imports for SVG |
299 # Imports for SVG |
295 import xml.etree.ElementTree as ET |
300 import xml.etree.ElementTree as ET |
296 from svg2gcode import shapes as shapes_pkg |
301 from svg2gcode import shapes as shapes_pkg |
297 from svg2gcode.shapes import point_generator |
302 from svg2gcode.shapes import point_generator |
|
303 from svg2gcode import simplepath, cspsubdiv, cubicsuperpath |
298 |
304 |
299 self.log("Generating paths from SVG (outlines only)...") |
305 self.log("Generating paths from SVG (outlines only)...") |
300 svg_shapes = set(['rect', 'circle', 'ellipse', 'line', 'polyline', 'polygon', 'path']) |
306 svg_shapes = set(['rect', 'circle', 'ellipse', 'line', 'polyline', 'polygon', 'path']) |
301 tree = ET.parse(filename) |
307 tree = ET.parse(filename) |
302 root = tree.getroot() |
308 root = tree.getroot() |
389 if tag_suffix in svg_shapes: |
396 if tag_suffix in svg_shapes: |
390 self.log("Parsing shape: %s" % tag_suffix) |
397 self.log("Parsing shape: %s" % tag_suffix) |
391 shape_class = getattr(shapes_pkg, tag_suffix) |
398 shape_class = getattr(shapes_pkg, tag_suffix) |
392 shape_obj = shape_class(elem) |
399 shape_obj = shape_class(elem) |
393 d = shape_obj.d_path() |
400 d = shape_obj.d_path() |
394 m = shape_obj.transformation_matrix() |
401 mat = shape_obj.transformation_matrix() |
395 |
402 |
396 if d: |
403 if d: |
397 fo.write("M400 ; start %s\n" % (tag_suffix)) |
404 fo.write("M400 ; start %s\n" % (tag_suffix)) |
398 fo.write("G92 E0\n") |
405 fo.write("G92 E0\n") |
399 E = 0 |
406 E = 0 |
400 xo = 0 |
407 xo = 0 |
401 yo = 0 |
408 yo = 0 |
402 p = point_generator(d, m, smoothness) |
409 idxo = None |
403 start = True |
410 #p = point_generator(d, mat, smoothness) |
404 for x,y,pen in p: |
411 |
405 x += ofs_x |
412 simple_path = simplepath.parsePath(d) |
406 y += ofs_y |
413 if len(simple_path) == 0: |
407 y = height - y # invert the bed |
414 self.log("Path length zero!") |
408 xs = scale_x * x |
415 continue |
409 ys = scale_y * y |
416 |
410 if xo == xs and yo == ys: continue |
417 p = cubicsuperpath.parsePath(d) |
411 |
418 |
412 if not pen: start = True |
419 if mat: |
413 if xs >= 0 and xs <= bed_max_x+0.1 and ys >= 0 and ys <= bed_max_y+0.1: |
420 simpletransform.applyTransformToPath(mat, p) |
414 if start: |
421 |
415 fo.write("G0 X%0.2f Y%0.2f F%.4f ; Move to start of shape\n" % ( |
422 for sp in p: |
416 xs, ys, travel_speed)) |
423 cspsubdiv.subdiv( sp, smoothness) |
417 start = False |
424 self.log("Laser ON at: " + repr(sp[0][0])) |
418 xo = xs |
425 x = sp[0][0][0] + ofs_x |
419 yo = ys |
426 y = sp[0][0][1] + ofs_y |
420 object_xs = xs |
427 y = height - y # invert the bed |
421 object_ys = ys |
428 xs = scale_x * x |
422 else: |
429 ys = scale_y * y |
423 e_distance = math.hypot(xs - xo, ys - yo) |
430 fo.write("M400 ; Wait for all moves to finish\n") |
424 xo = xs |
431 fo.write("M42 P28 S0 ; Turn off laser\n") |
425 yo = ys |
432 fo.write("G0 X%0.4f Y%0.4f F%.4f ; Move to start of shape\n" % ( |
426 E = E + (e_distance) |
433 xs, ys, travel_speed)) |
427 fo.write("G1 X%0.2f Y%0.2f E%.4f F%.4f\n" % ( |
434 fo.write("M400 ; Wait for all moves to finish\n") |
428 xs, ys, E * E_FACTOR, engrave_speed)) |
435 fo.write("M42 P28 S255 ; Turn on laser\n") |
429 else: |
436 |
430 self.log("Position outside print dimension: %d, %d" % (xs, ys)) |
437 xo = xs |
|
438 yo = ys |
|
439 object_xs = xs |
|
440 object_ys = ys |
|
441 |
|
442 for csp in sp: |
|
443 ctrl_pt1 = csp[0] |
|
444 ctrl_pt2 = csp[1] |
|
445 end_pt = csp[2] |
|
446 |
|
447 x = end_pt[0] + ofs_x |
|
448 y = end_pt[1] + ofs_y |
|
449 |
|
450 y = height - y # invert the bed |
|
451 xs = round(scale_x * x, 4) |
|
452 ys = round(scale_y * y, 4) |
|
453 if xo == xs and yo == ys: continue |
|
454 |
|
455 #self.log(" Point " + repr(end_pt)) |
|
456 |
|
457 if xs >= 0 and xs <= bed_max_x+0.1 and ys >= 0 and ys <= bed_max_y+0.1: |
|
458 e_distance = math.hypot(xs - xo, ys - yo) |
|
459 xo = xs |
|
460 yo = ys |
|
461 E = E + (e_distance) |
|
462 fo.write("G1 X%0.4f Y%0.4f E%.4f F%.4f\n" % ( |
|
463 xs, ys, E * E_FACTOR, engrave_speed)) |
|
464 |
|
465 else: |
|
466 self.log("Position outside print dimension: %d, %d" % (xs, ys)) |
|
467 |
|
468 |
|
469 #print " Point: ", end_pt[0], end_pt[1], pen |
|
470 self.log("Laser OFF at: " + repr(sp[-1][-1])) |
431 |
471 |
432 if shape_obj.xml_node.get('fill'): |
472 if shape_obj.xml_node.get('fill'): |
433 # Close the polygon |
473 # Close the polygon |
434 e_distance = math.hypot(object_xs - xo, object_ys - yo) |
474 e_distance = math.hypot(object_xs - xo, object_ys - yo) |
435 E = E + (e_distance) |
475 E = E + (e_distance) |
436 fo.write("G1 X%0.2f Y%0.2f E%.4f F%.4f ; Close the object polygon\n" % ( |
476 fo.write("G1 X%0.4f Y%0.4f E%.4f F%.4f ; Close the object polygon\n" % ( |
437 object_xs, object_ys, E * E_FACTOR, engrave_speed)) |
477 object_xs, object_ys, E * E_FACTOR, engrave_speed)) |
438 print "connecting filled path end to start" |
478 print "connecting filled path end to start" |
439 |
479 |
440 fo.write(GCODE_FOOT) |
480 fo.write(GCODE_FOOT) |
441 fo.close() |
481 fo.close() |