comandline parser
57
svg2gcode.py
@ -4,14 +4,14 @@ from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
import sys
|
||||
import os
|
||||
import getopt
|
||||
import argparse
|
||||
import xml.etree.ElementTree as ET
|
||||
import shapes as shapes_pkg
|
||||
from shapes import point_generator
|
||||
from config import *
|
||||
|
||||
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'])
|
||||
gcode_file_path = " "
|
||||
|
||||
@ -26,24 +26,25 @@ def close_on_failure():
|
||||
os.remove(gcode_file_path)
|
||||
sys.exit(1)
|
||||
|
||||
def print_help():
|
||||
print("Usage:")
|
||||
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():
|
||||
parser = argparse.ArgumentParser(description='Generate gcode from vector graphics.')
|
||||
|
||||
def parse_arguments(argv):
|
||||
try:
|
||||
opts, args = getopt.getopt(argv,"hi:o:",["ifile=","ofile="])
|
||||
except getopt.GetoptError:
|
||||
print_help()
|
||||
for opt, arg in opts:
|
||||
if opt in ("-i", "--ifile"):
|
||||
inputfile = arg
|
||||
elif opt in ("-o", "--ofile"):
|
||||
outputfile = arg
|
||||
return (inputfile, outputfile)
|
||||
parser.add_argument("-i", "--input", dest='inputfile', metavar='image.svg', help="path to vector graphic file", required=True)
|
||||
parser.add_argument("-o", "--output", dest='outputfile', metavar='data.gcode', help="path to file for generated gcode", required=True)
|
||||
|
||||
parser.add_argument("-fr", "--feedrate", dest='feedrate', metavar=300, default=300, help="rate while laser is on", required=False)
|
||||
parser.add_argument("-mr", "--moverate", dest='moverate', metavar=1200, default=1200, help="rate while laser is off", required=False)
|
||||
|
||||
parser.add_argument("-p", "--passes", dest='passes', metavar=1, default=1, help="number of passes (for deeper cutting)", required=False)
|
||||
parser.add_argument("-lp", "--laserpower", dest='laserpower', metavar="0%", default="0%", help="laser power in %%", required=False)
|
||||
|
||||
parser.add_argument("-bx", "--bedsizex", dest='bedsizex', default="376", help="x size of bed in mm", required=False)
|
||||
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):
|
||||
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))
|
||||
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):
|
||||
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")
|
||||
@ -108,9 +109,19 @@ def generate_gcode(svg_file_root_tree, gcode_file):
|
||||
|
||||
if __name__ == "__main__":
|
||||
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 = parse_arguments(sys.argv[1:])
|
||||
|
||||
svg_file_path, gcode_file_path, feedrate, moverate, passes, laserpower, bedsizex, bedsizey, smoothness = parse_arguments()
|
||||
|
||||
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:
|
||||
with open(gcode_file_path, 'w') as gcode_file:
|
||||
generate_gcode(read_input_file(svg_file_path),gcode_file)
|
||||
|
45
test_data/arc_compare.gcode
Normal 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
@ -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 |
36
test_data/circle_10mm_gen.gcode
Normal 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
|
35
test_data/circle_10mm_man.gcode
Normal 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
@ -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
@ -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 |
@ -1,15 +1,29 @@
|
||||
G90 ;Absolute programming
|
||||
G21 ;Programming in millimeters (mm)
|
||||
M5 ;Disable laser
|
||||
; == Start of rect ==
|
||||
G1 X0.1 Y0.1
|
||||
M3 I S150 ;start laser
|
||||
G1 X0.1 Y0.1
|
||||
G1 X9.9 Y0.1
|
||||
G1 X9.9 Y9.9
|
||||
G1 X0.1 Y9.9
|
||||
G1 X0.1 Y0.1
|
||||
; == Start of path ==
|
||||
G1 X8.6 Y11.7
|
||||
M3 I S15 ;start laser
|
||||
G1 X8.6 Y11.7
|
||||
G1 X29.4 Y9.7
|
||||
G1 X41.5 Y22.1
|
||||
G1 X35.3 Y35.3
|
||||
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
|
||||
; == End of rect ==
|
||||
; == End of path ==
|
||||
G1 X0.0 Y0.0; Display printbed
|
||||
M02 ;End of program
|
||||
|