comandline parser

This commit is contained in:
Hendrik Schutter 2022-06-13 22:48:51 +02:00
parent ff49e082e8
commit f459e7abcc
8 changed files with 397 additions and 32 deletions

View File

@ -4,14 +4,14 @@ from __future__ import absolute_import
from __future__ import print_function from __future__ import print_function
import sys import sys
import os import os
import getopt import argparse
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
import shapes as shapes_pkg import shapes as shapes_pkg
from shapes import point_generator from shapes import point_generator
from config import * from config import *
debug = True debug = True
example_usage = "-i test_data/Test_H.svg -o test_data/test.gcode" example_usage = "-i test_data/Test_H.svg -o test_data/test.gcode -fr 300 -mr 1200 -p 1 -lp 20%"
svg_shapes = set(['rect', 'circle', 'ellipse', 'line', 'polyline', 'polygon', 'path']) svg_shapes = set(['rect', 'circle', 'ellipse', 'line', 'polyline', 'polygon', 'path'])
gcode_file_path = " " gcode_file_path = " "
@ -26,24 +26,25 @@ def close_on_failure():
os.remove(gcode_file_path) os.remove(gcode_file_path)
sys.exit(1) sys.exit(1)
def print_help(): def parse_arguments():
print("Usage:") parser = argparse.ArgumentParser(description='Generate gcode from vector graphics.')
print(os.path.basename(__file__) + " -i <svg file> -o <gcode file>")
print("Example:")
print(os.path.basename(__file__) + " " + example_usage)
sys.exit(1)
def parse_arguments(argv): parser.add_argument("-i", "--input", dest='inputfile', metavar='image.svg', help="path to vector graphic file", required=True)
try: parser.add_argument("-o", "--output", dest='outputfile', metavar='data.gcode', help="path to file for generated gcode", required=True)
opts, args = getopt.getopt(argv,"hi:o:",["ifile=","ofile="])
except getopt.GetoptError: parser.add_argument("-fr", "--feedrate", dest='feedrate', metavar=300, default=300, help="rate while laser is on", required=False)
print_help() parser.add_argument("-mr", "--moverate", dest='moverate', metavar=1200, default=1200, help="rate while laser is off", required=False)
for opt, arg in opts:
if opt in ("-i", "--ifile"): parser.add_argument("-p", "--passes", dest='passes', metavar=1, default=1, help="number of passes (for deeper cutting)", required=False)
inputfile = arg parser.add_argument("-lp", "--laserpower", dest='laserpower', metavar="0%", default="0%", help="laser power in %%", required=False)
elif opt in ("-o", "--ofile"):
outputfile = arg parser.add_argument("-bx", "--bedsizex", dest='bedsizex', default="376", help="x size of bed in mm", required=False)
return (inputfile, outputfile) parser.add_argument("-by", "--bedsizey", dest='bedsizey', default="315", help="y size of bed in mm", required=False)
parser.add_argument("-s", "--smoothness", dest='smoothness', metavar=0.2, default=0.2, help="Used to control the smoothness/sharpness of the curves.\nSmaller the value greater the sharpness.\nMake sure the value is greater than 0.1", required=False)
args = parser.parse_args()
return [args.inputfile, args.outputfile, int(args.feedrate), int(args.moverate), int(args.passes), ((float(args.laserpower.split("%")[0])/100.0)), int(args.bedsizex), int(args.bedsizey), float(args.smoothness) ]
def read_input_file(svg_file_path): def read_input_file(svg_file_path):
try: try:
@ -94,7 +95,7 @@ def generate_gcode(svg_file_root_tree, gcode_file):
gcode_write(gcode_file, "G1 X%0.001f Y%0.001f\n" % (x, y)) gcode_write(gcode_file, "G1 X%0.001f Y%0.001f\n" % (x, y))
num_points += 1 num_points += 1
if (num_points == 1): if (num_points == 1):
gcode_write(gcode_file, "M3 I S150 ;start laser\n") gcode_write(gcode_file, "M3 I S15 ;start laser\n")
elif (debug): elif (debug):
print("\n; Coordinates out of range:", "G1 X%0.01f Y%0.01f" % (x, y)) print("\n; Coordinates out of range:", "G1 X%0.01f Y%0.01f" % (x, y))
print("; Raw:", str(x), str(y), "\nScaled:", str(x), str(y), "\n") print("; Raw:", str(x), str(y), "\nScaled:", str(x), str(y), "\n")
@ -108,9 +109,19 @@ def generate_gcode(svg_file_root_tree, gcode_file):
if __name__ == "__main__": if __name__ == "__main__":
sys.setrecursionlimit(20000) #needed for svg's with more indepented paths sys.setrecursionlimit(20000) #needed for svg's with more indepented paths
if(len(sys.argv) != (len(example_usage.split())+1)):
print_help() svg_file_path, gcode_file_path, feedrate, moverate, passes, laserpower, bedsizex, bedsizey, smoothness = parse_arguments()
svg_file_path, gcode_file_path = parse_arguments(sys.argv[1:])
print("inputfile: " + str(svg_file_path))
print("outputfile: " + str(gcode_file_path))
print("feedrate: " + str(feedrate))
print("moverate: " + str(moverate))
print("passes: " + str(passes))
print("laserpower: " + str(laserpower))
print("bedsizex: " + str(bedsizex))
print("bedsizey: " + str(bedsizey))
print("smoothness: " + str(smoothness))
try: try:
with open(gcode_file_path, 'w') as gcode_file: with open(gcode_file_path, 'w') as gcode_file:
generate_gcode(read_input_file(svg_file_path),gcode_file) generate_gcode(read_input_file(svg_file_path),gcode_file)

View File

@ -0,0 +1,45 @@
G90 ;Absolute programming
G21 ;Programming in millimeters (mm)
M5 ;Disable laser
; == Start of circle ==
G00 X5 Y5
M3 I S150 ;start laser
G02 X5 Y5 I5 J0
M5 ;stop laser
; == End of circle ==
G1 X0.0 Y0.0; Display printbed
; == Start of circle ==
G1 X0.4 Y5.0
M3 I S150 ;start laser
G1 X0.4 Y5.4
G1 X0.7 Y6.6
G1 X1.2 Y7.6
G1 X2.0 Y8.5
G1 X3.1 Y9.2
G1 X4.2 Y9.5
G1 X5.4 Y9.6
G1 X6.6 Y9.3
G1 X7.6 Y8.8
G1 X8.5 Y8.0
G1 X9.2 Y7.0
G1 X9.5 Y5.8
G1 X9.6 Y4.6
G1 X9.3 Y3.4
G1 X8.8 Y2.4
G1 X8.0 Y1.5
G1 X6.9 Y0.8
G1 X5.8 Y0.5
G1 X4.6 Y0.4
G1 X3.4 Y0.7
G1 X2.4 Y1.2
G1 X1.5 Y2.0
G1 X0.8 Y3.0
G1 X0.5 Y4.2
G1 X0.4 Y5.0
M5 ;stop laser
; == End of circle ==
M02 ;End of program

74
test_data/circle_10mm.svg Normal file
View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="10mm"
height="10mm"
viewBox="0 0 10 10"
version="1.1"
id="svg5"
inkscape:version="1.2 (dc2aedaf03, 2022-05-15)"
sodipodi:docname="circle_10mm.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="true"
inkscape:zoom="14.561186"
inkscape:cx="19.12619"
inkscape:cy="21.358151"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="1680"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1">
<inkscape:grid
type="xygrid"
id="grid168" />
</sodipodi:namedview>
<defs
id="defs2">
<linearGradient
id="linearGradient964"
inkscape:swatch="solid">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop962" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient964"
id="linearGradient966"
x1="6.1921271"
y1="4.5499105"
x2="7.5929643"
y2="4.5499105"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(6.5488501,0,0,10.421456,-40.138249,-42.416693)" />
</defs>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<circle
style="fill:none;stroke:url(#linearGradient966);stroke-width:0.826127;stroke-dasharray:none"
id="path166"
cx="5"
cy="5"
inkscape:highlight-color="#b7ee3b"
r="4.5869365" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,36 @@
G90 ;Absolute programming
G21 ;Programming in millimeters (mm)
M5 ;Disable laser
G01 F200.0
; == Start of circle ==
G1 X0.4 Y5.0
M3 I S150 ;start laser
G1 X0.4 Y5.4
G1 X0.7 Y6.6
G1 X1.2 Y7.6
G1 X2.0 Y8.5
G1 X3.1 Y9.2
G1 X4.2 Y9.5
G1 X5.4 Y9.6
G1 X6.6 Y9.3
G1 X7.6 Y8.8
G1 X8.5 Y8.0
G1 X9.2 Y7.0
G1 X9.5 Y5.8
G1 X9.6 Y4.6
G1 X9.3 Y3.4
G1 X8.8 Y2.4
G1 X8.0 Y1.5
G1 X6.9 Y0.8
G1 X5.8 Y0.5
G1 X4.6 Y0.4
G1 X3.4 Y0.7
G1 X2.4 Y1.2
G1 X1.5 Y2.0
G1 X0.8 Y3.0
G1 X0.5 Y4.2
G1 X0.4 Y5.0
M5 ;stop laser
; == End of circle ==
G1 X0.0 Y0.0; Display printbed
M02 ;End of program

View File

@ -0,0 +1,35 @@
G90 ;Absolute programming
G21 ;Programming in millimeters (mm)
M5 ;Disable laser
; == Start of circle ==
G1 X0.4 Y5.0
M3 I S150 ;start laser
G1 X0.4 Y5.4
G1 X0.7 Y6.6
G1 X1.2 Y7.6
G1 X2.0 Y8.5
G1 X3.1 Y9.2
G1 X4.2 Y9.5
G1 X5.4 Y9.6
G1 X6.6 Y9.3
G1 X7.6 Y8.8
G1 X8.5 Y8.0
G1 X9.2 Y7.0
G1 X9.5 Y5.8
G1 X9.6 Y4.6
G1 X9.3 Y3.4
G1 X8.8 Y2.4
G1 X8.0 Y1.5
G1 X6.9 Y0.8
G1 X5.8 Y0.5
G1 X4.6 Y0.4
G1 X3.4 Y0.7
G1 X2.4 Y1.2
G1 X1.5 Y2.0
G1 X0.8 Y3.0
G1 X0.5 Y4.2
G1 X0.4 Y5.0
M5 ;stop laser
; == End of circle ==
G1 X0.0 Y0.0; Display printbed
M02 ;End of program

103
test_data/circle_rect.svg Normal file
View File

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg5"
inkscape:version="1.2 (dc2aedaf03, 2022-05-15)"
sodipodi:docname="circle_rect.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="2.4109002"
inkscape:cx="67.609602"
inkscape:cy="119.87224"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="1680"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2">
<linearGradient
id="linearGradient1693"
inkscape:swatch="solid">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop1691" />
</linearGradient>
<linearGradient
id="linearGradient1687"
inkscape:swatch="solid">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop1685" />
</linearGradient>
<linearGradient
id="linearGradient1681"
inkscape:swatch="solid">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop1679" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient1681"
id="linearGradient1683"
x1="19.42469"
y1="13.817454"
x2="33.230409"
y2="13.817454"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.71925141,0,0,0.68550157,16.06387,25.528111)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient1693"
id="linearGradient1695"
x1="15.992893"
y1="32.574879"
x2="29.680855"
y2="32.574879"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.72529736,0,0,0.71786491,-6.5635245,-13.384362)" />
</defs>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<ellipse
style="fill:none;fill-opacity:1;stroke:url(#linearGradient1695);stroke-width:0.0721572;stroke-opacity:1"
id="path1465"
cx="10"
cy="10"
rx="4.9639211"
ry="4.9639215" />
<rect
style="fill:none;fill-opacity:1;stroke:url(#linearGradient1683);stroke-width:0.0702174"
id="rect1519"
width="9.9297819"
height="9.9297829"
x="30.035109"
y="30.035109" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

47
test_data/path.svg Normal file
View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg3908"
inkscape:version="1.2 (dc2aedaf03, 2022-05-15)"
sodipodi:docname="polygon.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview3910"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="3.0896281"
inkscape:cx="20.06714"
inkscape:cy="113.92957"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="1680"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs3905" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;stroke:#000000;stroke-width:0.3614px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 8.567566,11.725796 29.426043,9.6990304 41.526735,22.101801 35.291377,35.332061 c 0,0 -1.200062,11.342766 -14.752929,2.011317 C 6.9855816,28.011925 9.5682504,22.977429 9.5682504,22.977429 Z"
id="path7034" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -1,15 +1,29 @@
G90 ;Absolute programming G90 ;Absolute programming
G21 ;Programming in millimeters (mm) G21 ;Programming in millimeters (mm)
M5 ;Disable laser M5 ;Disable laser
; == Start of rect == ; == Start of path ==
G1 X0.1 Y0.1 G1 X8.6 Y11.7
M3 I S150 ;start laser M3 I S15 ;start laser
G1 X0.1 Y0.1 G1 X8.6 Y11.7
G1 X9.9 Y0.1 G1 X29.4 Y9.7
G1 X9.9 Y9.9 G1 X41.5 Y22.1
G1 X0.1 Y9.9 G1 X35.3 Y35.3
G1 X0.1 Y0.1 G1 X34.7 Y37.4
G1 X33.9 Y38.9
G1 X32.5 Y40.3
G1 X30.4 Y41.0
G1 X27.6 Y40.8
G1 X23.7 Y39.4
G1 X18.8 Y36.2
G1 X14.9 Y33.0
G1 X12.3 Y30.3
G1 X10.6 Y27.9
G1 X9.7 Y26.1
G1 X9.4 Y24.6
G1 X9.4 Y23.3
G1 X9.6 Y23.0
G1 X8.6 Y11.7
M5 ;stop laser M5 ;stop laser
; == End of rect == ; == End of path ==
G1 X0.0 Y0.0; Display printbed G1 X0.0 Y0.0; Display printbed
M02 ;End of program M02 ;End of program