svg2gcode 1.2.0__tar.gz → 2.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/PKG-INFO +40 -11
  2. svg2gcode-2.1.0/README.md +98 -0
  3. svg2gcode-2.1.0/svg2gcode/README.md +98 -0
  4. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/__init__.py +1 -1
  5. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/__main__.py +13 -4
  6. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/__init__.py +9 -7
  7. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/compiler/_compiler.py +66 -23
  8. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/svg_parser/_parser_methods.py +47 -32
  9. svg2gcode-1.2.0/README.md +0 -69
  10. svg2gcode-1.2.0/svg2gcode/README.md +0 -69
  11. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/LICENSE +0 -0
  12. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/pyproject.toml +0 -0
  13. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/.DS_Store +0 -0
  14. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/compiler/__init__.py +0 -0
  15. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/compiler/interfaces/__init__.py +0 -0
  16. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/compiler/interfaces/_abstract_interface.py +0 -0
  17. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/compiler/interfaces/_fan_controlled_gcode.py +0 -0
  18. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/compiler/interfaces/_gcode.py +0 -0
  19. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/formulas.py +0 -0
  20. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/geometry/__init__.py +0 -0
  21. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/geometry/_abstract_chain.py +0 -0
  22. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/geometry/_abstract_curve.py +0 -0
  23. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/geometry/_circular_arc.py +0 -0
  24. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/geometry/_cubic_bazier.py +0 -0
  25. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/geometry/_elliptical_arc.py +0 -0
  26. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/geometry/_line.py +0 -0
  27. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/geometry/_line_segment_chain.py +0 -0
  28. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/geometry/_matrix.py +0 -0
  29. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/geometry/_quadratic_bazier.py +0 -0
  30. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/geometry/_raster_image.py +0 -0
  31. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/geometry/_smooth_arc_chain.py +0 -0
  32. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/geometry/_vector.py +0 -0
  33. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/svg_parser/__init__.py +0 -0
  34. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/svg_parser/_path.py +0 -0
  35. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/svg_parser/_transformation.py +0 -0
  36. {svg2gcode-1.2.0 → svg2gcode-2.1.0}/svg2gcode/svg_to_gcode/svg_parser/debug_methods.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: svg2gcode
3
- Version: 1.2.0
3
+ Version: 2.1.0
4
4
  Summary: svg2gcode: convert an SVG (Scalable Vector Graphic) image to gcode.
5
5
  Keywords: scalable vector graphics,svg,image,laser cutter,laser engraving
6
6
  Author-email: Johannes Noordanus <mailjohannes.mailnoordanus@gmail.com>
@@ -16,27 +16,48 @@ Project-URL: Home, https://github.com/johannesnoordanus/svg2gcode
16
16
  A commandline steering program that enables laser cutting of svg drawings```<svg:path ..>tags``` and combined engraving of svg images```<svg:image ..>tags```.
17
17
  It is based on library SvgToGcode (*fork*: https://github.com/johannesnoordanus/SvgToGcode) which should be installed <sup>(*)</sup>.
18
18
 
19
- Drawings and images can be composed using Inkscape (for example) and saved to a .svg file. This file can be converted to gcode by svg2gcode.
19
+ Drawings and images can be composed using Inkscape (for example) and saved to a *.svg* file. This file can be converted to gcode by *svg2gcode*.
20
20
  Gcode produced in this way has the advantage that drawings and images have the same - relative - position and orientation as can be seen on the composer window.
21
21
  This makes combined cutting and engraving as easy as orientating the (wood) slab once.
22
22
 
23
23
  Controlling laser power, pixel size and other settings can be done via commandline parameters (see below) or within Inkscape using the XMLeditor.
24
- Image attributes ```gcode_pixelsize```, ```gcode_maxpower``` and ```gcode_speed``` can be set per object (they must be created: use **+**). Note that this overrides explicit or default commandline settings.
24
+ Image attributes ```gcode_pixelsize```, ```gcode_maxpower```, ```gcode_speed```, ```gcode_noise``` and ```gcode_speedmoves``` can be set per object (they must be created: use **+**). Note that this overrides explicit or default commandline settings.
25
+
26
+ Version 2.0.0 has important new speed optimizations. Engravings run significantly faster and skip from one image zone to the other at maximum speed. See options ```--speedmoves``` and ```--noise``` for example.
27
+
28
+ To summarize:
29
+
30
+ Optimized gcode
31
+ - draw pixels in one go until change of power
32
+ - emit X/Y coordinates only when they change
33
+ - emit linear move 'G1/G0' code minimally
34
+ - does not emit zero power (or below cutoff) pixels
35
+
36
+ General optimizations
37
+ - laser head has defered and sparse moves.
38
+ (XY locations are virtual, head does not always follow)
39
+ - moves at high speed (G0) over 10mm (default) or more zero pixels
40
+ - low burn levels (stray pixels) can be suppressed (default off)
41
+ - option *--constantburn* selects constant burn mode *M3* (for cutting and engraving) instead of default dynamic burn mode *M4*
42
+
43
+ **Tip**: use commandline program *grblhud* *(https://github.com/johannesnoordanus/grblhud)* to have full control over gcode execution,
44
+ also, program *image2gcode* has similar capabilities but handles raster images files (like *png* and *jpg*) directly.
25
45
 
26
- **Tip**: use commandline program grblhud (https://github.com/johannesnoordanus/grblhud) to have full control over gcode execution.
27
46
  ### Install:
28
47
  ```
29
48
  >
30
49
  > pip install svg2gcode
31
50
  ```
32
- <sup>(*)</sup> Note that library *svg_to_gcode* is included in this package.
51
+ <sup>(*)</sup> Note that this library is included.
33
52
  ### Usage:
34
53
  See notes below.
35
54
  ```
36
55
  $ svg2gcode --help
37
- usage: svg2gcode.py [-h] [--showimage] [--pixelsize <default:0.1>] [--imagespeed <default:800>] [--cuttingspeed <default:1000>] [--imagepower <default:300>]
38
- [--cuttingpower <default:0.85>] [--maxlaserpower <default:1000>] [--rapidmove] [--xmaxtravel <default:300>] [--ymaxtravel <default:400>] [--fan] [-V]
39
- svg gcode
56
+ usage: svg2gcode [-h] [--showimage] [--pixelsize <default:0.1>] [--imagespeed <default:800>]
57
+ [--cuttingspeed <default:1000>] [--imagepower <default:300>] [--cuttingpower <default:850>]
58
+ [--rapidmove <default:10>] [--noise <default:0>] [--constantburn] [--xmaxtravel <default:300>]
59
+ [--ymaxtravel <default:400>] [--fan] [-V]
60
+ svg gcode
40
61
 
41
62
  Convert svg to gcode for GRBL v1.1 compatible diode laser engravers.
42
63
 
@@ -54,16 +75,24 @@ options:
54
75
  --cuttingspeed <default:1000>
55
76
  cutting speed in mm/min
56
77
  --imagepower <default:300>
57
- maximum laser power while drawing an image (as a rule of thumb set to 1/3 of the machine maximum)
78
+ maximum laser power while drawing an image (as a rule of thumb set to 1/3 of the
79
+ machine maximum for a 5W laser)
58
80
  --cuttingpower <default:850>
59
81
  sets laser power of line drawings/cutting
60
- --rapidmove generate inbetween G0 moves
82
+ --rapidmove <default:10>
83
+ generate G0 moves between shapes, for images: G0 moves when skipping more than 10mm
84
+ (default), 0 is no G0 moves
85
+ --noise <default:0> reduces image noise by not emitting pixels with power lower or equal than this setting
86
+ --constantburn use constant burn mode M3 (a bit more dangerous!), instead of dynamic burn mode M4
87
+ --origin Xdelta Ydelta
88
+ translate origin by (Xdelta,Ydelta) (default not set)
61
89
  --xmaxtravel <default:300>
62
90
  machine x-axis lengh in mm
63
91
  --ymaxtravel <default:400>
64
92
  machine y-axis lengh in mm
65
93
  --fan set machine fan on
66
94
  -V, --version show version number and exit
95
+
67
96
  ```
68
97
  ### Notes:
69
98
  - example command to create two types of gcode file, one containing the drawings of the .svg, the other containing the images:
@@ -77,7 +106,7 @@ options:
77
106
  - drawing objects - within the composer - must be converted to a```path```to be translated to a gcode sequence
78
107
  - also, image objects should **not** be converted to a ```path```
79
108
  - images must be linked or embedded using base64.
80
- - images can be in several formats (my tests included ```.png``` and ```.jpg``` image files)
109
+ - images can be in several formats (my tests included *.png* and *.jpg* image files)
81
110
 
82
111
 
83
112
 
@@ -0,0 +1,98 @@
1
+ # svg2gcode
2
+
3
+ A commandline steering program that enables laser cutting of svg drawings```<svg:path ..>tags``` and combined engraving of svg images```<svg:image ..>tags```.
4
+ It is based on library SvgToGcode (*fork*: https://github.com/johannesnoordanus/SvgToGcode) which should be installed <sup>(*)</sup>.
5
+
6
+ Drawings and images can be composed using Inkscape (for example) and saved to a *.svg* file. This file can be converted to gcode by *svg2gcode*.
7
+ Gcode produced in this way has the advantage that drawings and images have the same - relative - position and orientation as can be seen on the composer window.
8
+ This makes combined cutting and engraving as easy as orientating the (wood) slab once.
9
+
10
+ Controlling laser power, pixel size and other settings can be done via commandline parameters (see below) or within Inkscape using the XMLeditor.
11
+ Image attributes ```gcode_pixelsize```, ```gcode_maxpower```, ```gcode_speed```, ```gcode_noise``` and ```gcode_speedmoves``` can be set per object (they must be created: use **+**). Note that this overrides explicit or default commandline settings.
12
+
13
+ Version 2.0.0 has important new speed optimizations. Engravings run significantly faster and skip from one image zone to the other at maximum speed. See options ```--speedmoves``` and ```--noise``` for example.
14
+
15
+ To summarize:
16
+
17
+ Optimized gcode
18
+ - draw pixels in one go until change of power
19
+ - emit X/Y coordinates only when they change
20
+ - emit linear move 'G1/G0' code minimally
21
+ - does not emit zero power (or below cutoff) pixels
22
+
23
+ General optimizations
24
+ - laser head has defered and sparse moves.
25
+ (XY locations are virtual, head does not always follow)
26
+ - moves at high speed (G0) over 10mm (default) or more zero pixels
27
+ - low burn levels (stray pixels) can be suppressed (default off)
28
+ - option *--constantburn* selects constant burn mode *M3* (for cutting and engraving) instead of default dynamic burn mode *M4*
29
+
30
+ **Tip**: use commandline program *grblhud* *(https://github.com/johannesnoordanus/grblhud)* to have full control over gcode execution,
31
+ also, program *image2gcode* has similar capabilities but handles raster images files (like *png* and *jpg*) directly.
32
+
33
+ ### Install:
34
+ ```
35
+ >
36
+ > pip install svg2gcode
37
+ ```
38
+ <sup>(*)</sup> Note that this library is included.
39
+ ### Usage:
40
+ See notes below.
41
+ ```
42
+ $ svg2gcode --help
43
+ usage: svg2gcode [-h] [--showimage] [--pixelsize <default:0.1>] [--imagespeed <default:800>]
44
+ [--cuttingspeed <default:1000>] [--imagepower <default:300>] [--cuttingpower <default:850>]
45
+ [--rapidmove <default:10>] [--noise <default:0>] [--constantburn] [--xmaxtravel <default:300>]
46
+ [--ymaxtravel <default:400>] [--fan] [-V]
47
+ svg gcode
48
+
49
+ Convert svg to gcode for GRBL v1.1 compatible diode laser engravers.
50
+
51
+ positional arguments:
52
+ svg svg file to be converted to gcode
53
+ gcode gcode output file
54
+
55
+ options:
56
+ -h, --help show this help message and exit
57
+ --showimage show b&w converted image
58
+ --pixelsize <default:0.1>
59
+ pixel size in mm (XY-axis): each image pixel is drawn this size
60
+ --imagespeed <default:800>
61
+ image draw speed in mm/min
62
+ --cuttingspeed <default:1000>
63
+ cutting speed in mm/min
64
+ --imagepower <default:300>
65
+ maximum laser power while drawing an image (as a rule of thumb set to 1/3 of the
66
+ machine maximum for a 5W laser)
67
+ --cuttingpower <default:850>
68
+ sets laser power of line drawings/cutting
69
+ --rapidmove <default:10>
70
+ generate G0 moves between shapes, for images: G0 moves when skipping more than 10mm
71
+ (default), 0 is no G0 moves
72
+ --noise <default:0> reduces image noise by not emitting pixels with power lower or equal than this setting
73
+ --constantburn use constant burn mode M3 (a bit more dangerous!), instead of dynamic burn mode M4
74
+ --origin Xdelta Ydelta
75
+ translate origin by (Xdelta,Ydelta) (default not set)
76
+ --xmaxtravel <default:300>
77
+ machine x-axis lengh in mm
78
+ --ymaxtravel <default:400>
79
+ machine y-axis lengh in mm
80
+ --fan set machine fan on
81
+ -V, --version show version number and exit
82
+
83
+ ```
84
+ ### Notes:
85
+ - example command to create two types of gcode file, one containing the drawings of the .svg, the other containing the images:
86
+ ```
87
+ > svg2gcode ambachtmanlogo.svg logo.gc
88
+ > ..
89
+ > ls *.gc
90
+ > logo.gc # all drawings
91
+ > logo_images.gc # all images
92
+ ```
93
+ - drawing objects - within the composer - must be converted to a```path```to be translated to a gcode sequence
94
+ - also, image objects should **not** be converted to a ```path```
95
+ - images must be linked or embedded using base64.
96
+ - images can be in several formats (my tests included *.png* and *.jpg* image files)
97
+
98
+
@@ -0,0 +1,98 @@
1
+ # svg2gcode
2
+
3
+ A commandline steering program that enables laser cutting of svg drawings```<svg:path ..>tags``` and combined engraving of svg images```<svg:image ..>tags```.
4
+ It is based on library SvgToGcode (*fork*: https://github.com/johannesnoordanus/SvgToGcode) which should be installed <sup>(*)</sup>.
5
+
6
+ Drawings and images can be composed using Inkscape (for example) and saved to a *.svg* file. This file can be converted to gcode by *svg2gcode*.
7
+ Gcode produced in this way has the advantage that drawings and images have the same - relative - position and orientation as can be seen on the composer window.
8
+ This makes combined cutting and engraving as easy as orientating the (wood) slab once.
9
+
10
+ Controlling laser power, pixel size and other settings can be done via commandline parameters (see below) or within Inkscape using the XMLeditor.
11
+ Image attributes ```gcode_pixelsize```, ```gcode_maxpower```, ```gcode_speed```, ```gcode_noise``` and ```gcode_speedmoves``` can be set per object (they must be created: use **+**). Note that this overrides explicit or default commandline settings.
12
+
13
+ Version 2.0.0 has important new speed optimizations. Engravings run significantly faster and skip from one image zone to the other at maximum speed. See options ```--speedmoves``` and ```--noise``` for example.
14
+
15
+ To summarize:
16
+
17
+ Optimized gcode
18
+ - draw pixels in one go until change of power
19
+ - emit X/Y coordinates only when they change
20
+ - emit linear move 'G1/G0' code minimally
21
+ - does not emit zero power (or below cutoff) pixels
22
+
23
+ General optimizations
24
+ - laser head has defered and sparse moves.
25
+ (XY locations are virtual, head does not always follow)
26
+ - moves at high speed (G0) over 10mm (default) or more zero pixels
27
+ - low burn levels (stray pixels) can be suppressed (default off)
28
+ - option *--constantburn* selects constant burn mode *M3* (for cutting and engraving) instead of default dynamic burn mode *M4*
29
+
30
+ **Tip**: use commandline program *grblhud* *(https://github.com/johannesnoordanus/grblhud)* to have full control over gcode execution,
31
+ also, program *image2gcode* has similar capabilities but handles raster images files (like *png* and *jpg*) directly.
32
+
33
+ ### Install:
34
+ ```
35
+ >
36
+ > pip install svg2gcode
37
+ ```
38
+ <sup>(*)</sup> Note that this library is included.
39
+ ### Usage:
40
+ See notes below.
41
+ ```
42
+ $ svg2gcode --help
43
+ usage: svg2gcode [-h] [--showimage] [--pixelsize <default:0.1>] [--imagespeed <default:800>]
44
+ [--cuttingspeed <default:1000>] [--imagepower <default:300>] [--cuttingpower <default:850>]
45
+ [--rapidmove <default:10>] [--noise <default:0>] [--constantburn] [--xmaxtravel <default:300>]
46
+ [--ymaxtravel <default:400>] [--fan] [-V]
47
+ svg gcode
48
+
49
+ Convert svg to gcode for GRBL v1.1 compatible diode laser engravers.
50
+
51
+ positional arguments:
52
+ svg svg file to be converted to gcode
53
+ gcode gcode output file
54
+
55
+ options:
56
+ -h, --help show this help message and exit
57
+ --showimage show b&w converted image
58
+ --pixelsize <default:0.1>
59
+ pixel size in mm (XY-axis): each image pixel is drawn this size
60
+ --imagespeed <default:800>
61
+ image draw speed in mm/min
62
+ --cuttingspeed <default:1000>
63
+ cutting speed in mm/min
64
+ --imagepower <default:300>
65
+ maximum laser power while drawing an image (as a rule of thumb set to 1/3 of the
66
+ machine maximum for a 5W laser)
67
+ --cuttingpower <default:850>
68
+ sets laser power of line drawings/cutting
69
+ --rapidmove <default:10>
70
+ generate G0 moves between shapes, for images: G0 moves when skipping more than 10mm
71
+ (default), 0 is no G0 moves
72
+ --noise <default:0> reduces image noise by not emitting pixels with power lower or equal than this setting
73
+ --constantburn use constant burn mode M3 (a bit more dangerous!), instead of dynamic burn mode M4
74
+ --origin Xdelta Ydelta
75
+ translate origin by (Xdelta,Ydelta) (default not set)
76
+ --xmaxtravel <default:300>
77
+ machine x-axis lengh in mm
78
+ --ymaxtravel <default:400>
79
+ machine y-axis lengh in mm
80
+ --fan set machine fan on
81
+ -V, --version show version number and exit
82
+
83
+ ```
84
+ ### Notes:
85
+ - example command to create two types of gcode file, one containing the drawings of the .svg, the other containing the images:
86
+ ```
87
+ > svg2gcode ambachtmanlogo.svg logo.gc
88
+ > ..
89
+ > ls *.gc
90
+ > logo.gc # all drawings
91
+ > logo_images.gc # all images
92
+ ```
93
+ - drawing objects - within the composer - must be converted to a```path```to be translated to a gcode sequence
94
+ - also, image objects should **not** be converted to a ```path```
95
+ - images must be linked or embedded using base64.
96
+ - images can be in several formats (my tests included *.png* and *.jpg* image files)
97
+
98
+
@@ -1,4 +1,4 @@
1
1
  """
2
2
  svg2gcode: convert an SVG (Scalable Vector Graphic) image to gcode.
3
3
  """
4
- __version__ = "1.2.0"
4
+ __version__ = "2.1.0"
@@ -23,9 +23,10 @@ def svg2gcode(args) -> int:
23
23
  # For line drawings 'pass_depth' controls how far down the tool moves after every pass. Set it to 0 if your machine does not support Z axis movement.
24
24
  gcode_compiler = Compiler(interfaces.Gcode, params={'laser_power':args.cuttingpower,'movement_speed':args.cuttingspeed, 'pixel_size':args.pixelsize,
25
25
  'maximum_image_laser_power':args.imagepower, 'image_movement_speed':args.imagespeed, 'fan':args.fan,'rapid_move':args.rapidmove,
26
- 'showimage':args.showimage, 'x_axis_maximum_travel':args.xmaxtravel,'y_axis_maximum_travel':args.ymaxtravel})
26
+ 'showimage':args.showimage, 'x_axis_maximum_travel':args.xmaxtravel,'y_axis_maximum_travel':args.ymaxtravel, 'image_noise':args.noise,
27
+ 'laser_mode':"constant" if args.constantburn else "dynamic" })
27
28
  # emit gcode for svg
28
- gcode_compiler.compile_to_file(args.gcode, parse_file(args.svg), passes=1)
29
+ gcode_compiler.compile_to_file(args.gcode, parse_file(args.svg, delta_origin=args.origin), passes=1)
29
30
 
30
31
  except Exception as error:
31
32
  print(error)
@@ -45,6 +46,8 @@ def main() -> int:
45
46
  cuttingpower_default = 850
46
47
  xmaxtravel_default = 300
47
48
  ymaxtravel_default = 400
49
+ rapidmove_default = 10
50
+ noise_default = 0
48
51
 
49
52
  # Define command line argument interface
50
53
  parser = argparse.ArgumentParser(description='Convert svg to gcode for GRBL v1.1 compatible diode laser engravers.')
@@ -58,10 +61,16 @@ def main() -> int:
58
61
  parser.add_argument('--cuttingspeed', default=cuttingspeed_default, metavar="<default:" + str(cuttingspeed_default)+">",
59
62
  type=int, help='cutting speed in mm/min')
60
63
  parser.add_argument('--imagepower', default=imagepower_default, metavar="<default:" +str(imagepower_default)+ ">",
61
- type=int, help="maximum laser power while drawing an image (as a rule of thumb set to 1/3 of the machine maximum)")
64
+ type=int, help="maximum laser power while drawing an image (as a rule of thumb set to 1/3 of the machine maximum for a 5W laser)")
62
65
  parser.add_argument('--cuttingpower', default=cuttingpower_default, metavar="<default:" +str(cuttingpower_default)+ ">",
63
66
  type=int, help="sets laser power of line drawings/cutting")
64
- parser.add_argument('--rapidmove', action='store_true', default=True, help='generate inbetween G0 moves' )
67
+ parser.add_argument('--rapidmove', default=rapidmove_default, metavar="<default:" +str(rapidmove_default)+ ">",
68
+ type=int, help='generate G0 moves between shapes, for images: G0 moves when skipping more than 10mm (default), 0 is no G0 moves' )
69
+ parser.add_argument('--noise', default=noise_default, metavar="<default:" +str(noise_default)+ ">",
70
+ type=int, help='reduces image noise by not emitting pixels with power lower or equal than this setting')
71
+ parser.add_argument('--constantburn', action='store_true', default=False, help='use constant burn mode M3 (a bit more dangerous!), instead of dynamic burn mode M4')
72
+ parser.add_argument('--origin', default=None, nargs=2, metavar=('Xdelta', 'Ydelta'),
73
+ type=float, help="translate origin by (Xdelta,Ydelta) (default not set)")
65
74
  parser.add_argument('--xmaxtravel', default=xmaxtravel_default, metavar="<default:" +str(xmaxtravel_default)+ ">",
66
75
  type=int, help="machine x-axis lengh in mm")
67
76
  parser.add_argument('--ymaxtravel', default=ymaxtravel_default, metavar="<default:" +str(ymaxtravel_default)+ ">",
@@ -24,11 +24,14 @@ SETTING = {
24
24
  "laser_mode", # LASERMODE set constant or dynamic laser power mode
25
25
  "maximum_image_laser_power",# positive integer sets laser power (maximum) for image drawings (this is typically 1/3) of 'maximum_laser_power')
26
26
  "image_movement_speed", # positive integer sets movement speed when drawing an image (typically a lot less than the 'maximum_rate')
27
+ "image_noise", # positive integer reduces image noise by not emitting pixels lower or equal this setting')
27
28
  # Configuration
28
29
  "unit", # UNITS sets machine unit (milimeters, inches), this also defines the Feed (movement) parameter (mm/min or in/min)
29
30
  "distance_mode", # DISTANCEMODE sets machine distance mode ('absolute' from 0,0 or 'incremental' from current position)
30
- "rapid_move", # boolean when false, do not use rapid move (G0) to go to the next line chain, use a 'slow' (G1) move with laser
31
- # power off (S0) (note that the first move - to the start of the first line chain - is still a rapid move)
31
+ "rapid_move", # positive integer when 0, no rapid moves, > 0, G0 moves to the next line chain (otherwise a slow G1 S0 move is used).
32
+ # (note that the first move - to the start of the first line chain - is always a rapid move)
33
+ # This setting is overloaded for images: a number 'n' > 0 means, do a rapid (G0) move when skipping
34
+ # more than 'n'mm
32
35
  "pixel_size", # float sets image pixel size (in mm)
33
36
  "showimage" # boolean show image used for conversion to gcode
34
37
  }
@@ -50,12 +53,13 @@ DEFAULT_SETTING = {
50
53
  "movement_speed": None, # MANDATORY
51
54
  "laser_power": 1000, # default set to 1
52
55
  "laser_mode": "dynamic", # default set to dynamic (M4 safest mode, laser is off when not moving)
53
- "maximum_image_laser_power":None, # MANDATORY should be ("maximum_laser_power" - "minimum_laser_power" / 3)
56
+ "maximum_image_laser_power":None, # MANDATORY should be ("maximum_laser_power" - "minimum_laser_power" / 3 for a 5W laser)
54
57
  "image_movement_speed": None, # MANDATORY
58
+ "image_noise": 0, # default set to not reduces images noise')
55
59
  # Configuration
56
60
  "unit": "mm", # default set to milimeters
57
61
  "distance_mode": "absolute", # default set to absolute
58
- "rapid_move": True, # default set to true
62
+ "rapid_move": 10, # default set to true, for images do a rapid move when skipping more than 10mm
59
63
  "pixel_size": 0.1, # laser kerf is mostly < 0.1mm
60
64
  "showimage": False # default image is not shown
61
65
  }
@@ -84,7 +88,7 @@ def check_setting(setting: dict[str,Any] =None) -> bool:
84
88
  raise ValueError(f"Unknown '{key}' value '{setting[key]}'. Please specify one of the following: {{True,False}}")
85
89
  if key in {"minimum_laser_power","maximum_laser_power","x_axis_maximum_rate","y_axis_maximum_rate", "movement_speed",
86
90
  "x_axis_maximum_travel","y_axis_maximum_travel", "maximum_image_laser_power",
87
- "image_movement_speed","laser_power" } and (not isinstance(setting[key],int) or setting[key] < 0):
91
+ "image_movement_speed","laser_power","rapid_move" } and (not isinstance(setting[key],int) or setting[key] < 0):
88
92
  raise ValueError(f"'{key}' has type {type(setting[key])} and value {setting[key]}, but should be of type {type(1)} and have a value >= 0")
89
93
  # Toolparameters
90
94
  if key in {"pass_depth","dwell_time"}:
@@ -98,8 +102,6 @@ def check_setting(setting: dict[str,Any] =None) -> bool:
98
102
  raise ValueError(f"Unknown '{key}' value '{setting[key]}'. Please specify one of the following: {UNITS}")
99
103
  if key == "distance_mode" and setting[key] not in DISTANCEMODE:
100
104
  raise ValueError(f"Unknown '{key}' value '{setting[key]}'. Please specify one of the following: {DISTANCEMODE}")
101
- if key == "rapid_move" and setting[key] not in {True,False}:
102
- raise ValueError(f"Unknown '{key}' value '{setting[key]}'. Please specify one of the following: {{True,False}}")
103
105
  if key in {"fan","showimage"} and setting[key] not in {True,False}:
104
106
  raise ValueError(f"Unknown '{key}' value '{setting[key]}'. Please specify one of the following: {{True,False}}")
105
107
  if key == "pixel_size" and setting[key] and (not isinstance(setting[key],(float)) or setting[key] <= 0):
@@ -126,7 +126,7 @@ class Compiler:
126
126
  Assembles the code in the header, body and footer.
127
127
  """
128
128
 
129
- header_gc = ["M5","M8", "M4"]
129
+ header_gc = ["M5","M8", 'M3' if self.settings["laser_mode"] == "constant" else 'M4']
130
130
  # laser off, fan off, program stop
131
131
  footer_gc = ["M5","M9","M2"]
132
132
 
@@ -250,11 +250,17 @@ class Compiler:
250
250
 
251
251
  # convert image to new size
252
252
  if img is not None:
253
- img = img.resize((int(float(img_attrib['width']) * 1/float(pixelsize)), int(float(img_attrib['height']) * 1/float(pixelsize))), Image.Resampling.LANCZOS)
253
+ # add alpha channel
254
+ img = img.convert("RGBA")
255
+
256
+ # create a white background and add it to the image
257
+ img_background = Image.new(mode = "RGBA", size = img.size, color = (255,255,255))
258
+ img = Image.alpha_composite(img_background, img)
259
+
260
+ # convert image to black&white (without alpha) and new size #reminder: 'img = img.convert("LA")'
261
+ img = img.resize((int(float(img_attrib['width']) * 1/float(pixelsize)),
262
+ int(float(img_attrib['height']) * 1/float(pixelsize))), Image.Resampling.LANCZOS).convert("L")
254
263
 
255
- # convert to B&W without alpha
256
- #img = img.convert("LA")
257
- img = img.convert("L")
258
264
  if self.settings['showimage']:
259
265
  img.show()
260
266
 
@@ -263,6 +269,14 @@ class Compiler:
263
269
 
264
270
  return None
265
271
 
272
+ def distance(self, A: (float,float),B: (float,float)):
273
+ """
274
+ Does Pythagoras
275
+ """
276
+ # |Ax - Bx|^2 + |Ay - By|^2 = C^2
277
+ # distance = √C^2
278
+ return math.sqrt(abs(A[0] - B[0])**2 + abs(A[1] - B[1])**2)
279
+
266
280
  def image2gcode(self, img_attrib: dict[str, Any], img=None, transformation = None):
267
281
 
268
282
  invert_intensity = True
@@ -272,9 +286,12 @@ class Compiler:
272
286
  pixelsize = img_attrib['gcode_pixelsize'] if 'gcode_pixelsize' in img_attrib else self.settings["pixel_size"]
273
287
  maxpower = img_attrib['gcode_maxpower'] if 'gcode_maxpower' in img_attrib else self.settings["maximum_image_laser_power"]
274
288
  speed = img_attrib['gcode_speed'] if 'gcode_speed' in img_attrib else self.settings["image_movement_speed"]
289
+ noise = img_attrib['gcode_noise'] if 'gcode_noise' in img_attrib else self.settings["image_noise"]
290
+ speedmoves = img_attrib['gcode_speedmoves'] if 'gcode_speedmoves' in img_attrib else self.settings["rapid_move"]
275
291
 
276
292
  # set header for this image
277
- self.gcode += [f"; image name: {img_attrib['id']}, pixelsize: {pixelsize}, speed: {speed}, maxpower: {maxpower}\n;"]
293
+ self.gcode += [f"; image name: {img_attrib['id']}, pixelsize: {pixelsize}, speed: {speed},\n"
294
+ f'; maxpower: {maxpower}, speedmoves {speedmoves}, noise level {noise}\n;\n']
278
295
 
279
296
  # set X/Y-axis precision to number of digits after the decimal separator
280
297
  XY_prec = len(str(pixelsize).split('.')[1])
@@ -304,6 +321,9 @@ class Compiler:
304
321
  #
305
322
  left2right = True
306
323
 
324
+ # current location of laser head
325
+ head = (X,Y)
326
+
307
327
  # start print
308
328
  for line in img:
309
329
 
@@ -322,40 +342,63 @@ class Compiler:
322
342
  # Note also that drawing form left to right differs subtly from the reverse
323
343
 
324
344
  # draw this pixel line
325
- #for count, bw in np.ndenumerate(line):
326
345
  for count, pixel in enumerate(line):
327
346
  # power proportional to maximum laser power
328
347
  laserpow = round((1.0 - float(pixel/255)) * maxpower) if invert_intensity else round(float(pixel/255) * maxpower)
329
- # delay emit first pixel (so all same power pixels can be emitted in one sweep)
348
+
330
349
  if count == 0:
350
+ # delay emit first pixel (so all same power pixels can be emitted in one sweep)
331
351
  prev_pow = laserpow
352
+ # set last head loaction on start of the line
353
+ lastloc = (X,Y)
332
354
 
333
355
  # draw points until change of power
334
356
  if laserpow != prev_pow or count == line.size-1:
335
- if transformation is not None:
336
- XYt = transformation.apply_affine_transformation(Vector(X, Y))
337
- code = f"X{round(XYt[0],XY_prec)}Y{round(XYt[1],XY_prec)}"
338
- code += f"S{prev_pow}"
357
+ if prev_pow > noise:
358
+ code = ""
359
+ if lastloc:
360
+ # head is not at correct location, go there
361
+
362
+ # Apply affine transformation (if needed)
363
+ # (Note that an affine transformation does not necessarily preserve angles between
364
+ # lines or distances between points!)
365
+ XYlastloc = (lastloc[0], lastloc[1]) if transformation is None else \
366
+ transformation.apply_affine_transformation(Vector(lastloc[0], lastloc[1]))
367
+
368
+ XYhead = (head[0], head[1]) if transformation is None else \
369
+ transformation.apply_affine_transformation(Vector(head[0], head[1]))
370
+
371
+ if speedmoves and (self.distance(XYhead,XYlastloc) > speedmoves):
372
+ # fast
373
+ code = f"G0 X{round(XYlastloc[0],XY_prec)}Y{round(XYlastloc[1],XY_prec)}\nG1\n"
374
+ else:
375
+ # normal speed
376
+ code = f"X{round(XYlastloc[0],XY_prec)}Y{round(XYlastloc[1],XY_prec)}S0\n"
377
+
378
+ # emit point
379
+ if transformation is not None:
380
+ XYt = transformation.apply_affine_transformation(Vector(X, Y))
381
+ code += f"X{round(XYt[0],XY_prec)}Y{round(XYt[1],XY_prec)}S{prev_pow}"
382
+ else:
383
+ code += f"X{X}S{prev_pow}"
384
+ self.gcode += [code]
385
+
386
+ # head at this location
387
+ head = (X,Y)
388
+ lastloc = None
339
389
  else:
340
- code = f"X{X}"
341
- code += f"S{prev_pow}"
342
- self.gcode += [code]
390
+ # didn't move head to location, save it
391
+ lastloc = (X,Y)
343
392
 
344
393
  if count == line.size-1:
345
394
  continue
346
- # if laserpow != prev_pow
347
- prev_pow = laserpow
395
+ prev_pow = laserpow # if laserpow != prev_pow
348
396
 
349
397
  # next point
350
398
  X = round(X + (pixelsize if left2right else -pixelsize), XY_prec)
351
399
 
352
- # go to next scan line
400
+ # next scan line (defer head movement: lazy head)
353
401
  Y = round(Y + pixelsize, XY_prec)
354
- if transformation is not None:
355
- XYt = transformation.apply_affine_transformation(Vector(X, Y))
356
- self.gcode += [f"X{round(XYt[0],XY_prec)}Y{round(XYt[1],XY_prec)}S0"]
357
- else:
358
- self.gcode += [f"Y{Y}S0"]
359
402
 
360
403
  # change print direction
361
404
  left2right = not left2right
@@ -19,7 +19,7 @@ def _has_style(element: ElementTree.Element, key: str, value: str) -> bool:
19
19
  return element.get(key) == value or (element.get("style") and f"{key}:{value}" in element.get("style"))
20
20
 
21
21
 
22
- def add_viewbox_transformation(transformation: Transformation, transform_origin, vwbox):
22
+ def add_viewbox_transformation(transformation: Transformation, transform_origin, vwbox, origin):
23
23
  """
24
24
  Transform SVG coordinate system to a math-cartesion coordinate system and correct its origin.
25
25
  When viewBox is missing the 'height' value of the viewport is used.
@@ -50,16 +50,28 @@ def add_viewbox_transformation(transformation: Transformation, transform_origin,
50
50
  # viewBox "width" and "height" represent the dimensions of the 'svg'
51
51
  # (a rectangle - left upper at (vwbox['x'],vwbox['y']) - in user space)
52
52
 
53
+ # Set origin back at viewbox position after flip updown and add
54
+ # the user specified origin.
55
+ # When no user origin is specified, this translation is skipped,
56
+ # which effectively places the viewbox lower left (mind you after
57
+ # flipupdown) at (0,0) (so the canvas has positive coordinates only).
58
+
59
+ # (transformations are in reverse order see 'Note' below)
60
+ if origin is not None and ((vwbox["x"] + origin[0]) or (vwbox["y"] + origin[1])):
61
+ up_transformation.add_translation(vwbox["x"] + origin[0],vwbox["y"] + origin[1])
62
+
53
63
  # Note: If A and B are the matrices of two linear transformations, then the effect of first applying A and then B
54
64
  # to a column vector x is given by B(Ax) == (BA)x
55
65
  # So, in the below case, transformation order is 'scale' first and 'translation' second.
66
+
67
+ # this effectively does a flip updown to set a carthesian coordinate system (origin at bottom left) gcode uses
56
68
  up_transformation.add_translation(0, vwbox["height"]) # Translation
57
69
  up_transformation.add_scale(1, -1) # T * Scale
58
70
  # applying it to a vector: # T * S * Vector(x,y)
59
71
 
60
72
  # viewBox "x" and "y" represent the upper left corner of the document.
61
- # when non zero, the upper left corner should be corrected to (0,0)
62
- # (a laser or CNC machine has a positive workarea only, which should be as large as possible)
73
+ # when non zero, the upper left corner should be corrected to (0,0) for
74
+ # the above flip updown to work correctly
63
75
  if vwbox["x"] or vwbox["y"]:
64
76
  up_transformation.add_translation(-vwbox["x"],-vwbox["y"])
65
77
 
@@ -97,7 +109,7 @@ def get_viewBox(root: ElementTree.Element) -> {}:
97
109
 
98
110
 
99
111
  def parse_root(root: ElementTree.Element, transform_origin=True, viewbox=None, draw_hidden=False,
100
- visible_root=True, root_transformation=None) -> List[Curve]:
112
+ visible_root=True, root_transformation=None, origin=None) -> List[Curve]:
101
113
 
102
114
  """
103
115
  Recursively parse an etree root's children into geometric curves.
@@ -109,6 +121,7 @@ def parse_root(root: ElementTree.Element, transform_origin=True, viewbox=None, d
109
121
  :param transform_origin: Whether or not to transform input coordinates from the svg coordinate system to standard
110
122
  cartesian system. Depends on viewBox height for calculations.
111
123
  :param draw_hidden: Whether or not to draw hidden elements based on their display, visibility and opacity attributes.
124
+ :param origin: translate origin to (origin[0],origin[1]); when None set viewbox upper left to (0,0)
112
125
  :param visible_root: Specifies whether or the root is visible. (Inheritance can be overridden)
113
126
  :param root_transformation: Specifies whether the root's transformation. (Transformations are inheritable)
114
127
  :return: A list of geometric curves describing the svg. Use the Compiler sub-module to compile them to gcode.
@@ -153,7 +166,7 @@ def parse_root(root: ElementTree.Element, transform_origin=True, viewbox=None, d
153
166
  if draw_hidden or visible:
154
167
  if element.tag == "{%s}path" % NAMESPACES["svg"]:
155
168
  path = Path(element.attrib['d'],
156
- add_viewbox_transformation(transformation, transform_origin, viewbox))
169
+ add_viewbox_transformation(transformation, transform_origin, viewbox, origin))
157
170
  curves.extend(path.curves)
158
171
  else:
159
172
  if element.tag == "{%s}image" % NAMESPACES["svg"]:
@@ -161,45 +174,47 @@ def parse_root(root: ElementTree.Element, transform_origin=True, viewbox=None, d
161
174
 
162
175
  # instantiate curve (image)
163
176
  ri = RasterImage(element.attrib, element.attrib["{%s}href" % NAMESPACES["xlink"]],
164
- add_viewbox_transformation(transformation, transform_origin, viewbox))
177
+ add_viewbox_transformation(transformation, transform_origin, viewbox, origin))
165
178
  curves.append(ri)
166
179
 
167
180
  # Continue the recursion
168
- curves.extend(parse_root(element, transform_origin, viewbox, draw_hidden, visible, transformation))
181
+ curves.extend(parse_root(element, transform_origin, viewbox, draw_hidden, visible, transformation, origin))
169
182
 
170
183
  # ToDo implement shapes class
171
184
  return curves
172
185
 
173
186
 
174
- def parse_string(svg_string: str, transform_origin=True, viewbox=None, draw_hidden=False) -> List[Curve]:
187
+ def parse_string(svg_string: str, transform_origin=True, viewbox=None, draw_hidden=False, delta_origin=None) -> List[Curve]:
175
188
  """
176
- Recursively parse an svg string into geometric curves. (Wrapper for parse_root)
177
-
178
- :param svg_string: The etree element who's children should be recursively parsed. The root will not be drawn.
179
- :param viewbox: ViewBox of the SVG, used to transform it to a math-cartesion coordinate system and
180
- correct its origin. When the viewBox is missing the viewport (of the root) is used. If the root
181
- does not contain a viewBox or viewport, it must be either manually specified or transform must be False.
182
- :param transform_origin: Whether or not to transform input coordinates from the svg coordinate system to standard cartesian
183
- system. Depends on canvas_height for calculations.
184
- :param draw_hidden: Whether or not to draw hidden elements based on their display, visibility and opacity attributes.
185
- :return: A list of geometric curves describing the svg. Use the Compiler sub-module to compile them to gcode.
189
+ Recursively parse an svg string into geometric curves. (Wrapper for parse_root)
190
+
191
+ :param svg_string: The etree element who's children should be recursively parsed. The root will not be drawn.
192
+ :param viewbox: ViewBox of the SVG, used to transform it to a math-cartesion coordinate system and
193
+ correct its origin. When the viewBox is missing the viewport (of the root) is used. If the root
194
+ does not contain a viewBox or viewport, it must be either manually specified or transform must be False.
195
+ :param transform_origin: Whether or not to transform input coordinates from the svg coordinate system to standard cartesian
196
+ system. Depends on canvas_height for calculations.
197
+ :param draw_hidden: Whether or not to draw hidden elements based on their display, visibility and opacity attributes.
198
+ :pram origin: translate origin to (origin[0],origin[1]), when None set viewbox upper left to (0,0)
199
+ :return: A list of geometric curves describing the svg. Use the Compiler sub-module to compile them to gcode.
186
200
  """
187
201
  root = ElementTree.fromstring(svg_string)
188
- return parse_root(root, transform_origin, viewbox, draw_hidden)
202
+ return parse_root(root, transform_origin, viewbox, draw_hidden, origin=delta_origin)
203
+
189
204
 
205
+ def parse_file(file_path: str, transform_origin=True, viewbox=None, draw_hidden=False, delta_origin=None) -> List[Curve]:
206
+ """
207
+ Recursively parse an svg file into geometric curves. (Wrapper for parse_root)
190
208
 
191
- def parse_file(file_path: str, transform_origin=True, viewbox=None, draw_hidden=False) -> List[Curve]:
209
+ :param file_path: The etree element who's children should be recursively parsed. The root will not be drawn.
210
+ :param viewbox: ViewBox of the SVG, used to transform it to a math-cartesion coordinate system and
211
+ correct its origin. When the viewBox is missing the viewport (of the root) is used. If the root
212
+ does not contain a viewBox or viewport, it must be either manually specified or transform must be False.
213
+ :param transform_origin: Whether or not to transform input coordinates from the svg coordinate system to standard cartesian
214
+ system. Depends on canvas_height for calculations.
215
+ :param draw_hidden: Whether or not to draw hidden elements based on their display, visibility and opacity attributes.
216
+ :param origin: translate origin to (origin[0],origin[1]), when None set viewbox upper left to (0,0)
217
+ :return: A list of geometric curves describing the svg. Use the Compiler sub-module to compile them to gcode.
192
218
  """
193
- Recursively parse an svg file into geometric curves. (Wrapper for parse_root)
194
-
195
- :param file_path: The etree element who's children should be recursively parsed. The root will not be drawn.
196
- :param viewbox: ViewBox of the SVG, used to transform it to a math-cartesion coordinate system and
197
- correct its origin. When the viewBox is missing the viewport (of the root) is used. If the root
198
- does not contain a viewBox or viewport, it must be either manually specified or transform must be False.
199
- :param transform_origin: Whether or not to transform input coordinates from the svg coordinate system to standard cartesian
200
- system. Depends on canvas_height for calculations.
201
- :param draw_hidden: Whether or not to draw hidden elements based on their display, visibility and opacity attributes.
202
- :return: A list of geometric curves describing the svg. Use the Compiler sub-module to compile them to gcode.
203
- """
204
219
  root = ElementTree.parse(file_path).getroot()
205
- return parse_root(root, transform_origin, viewbox, draw_hidden)
220
+ return parse_root(root, transform_origin, viewbox, draw_hidden, origin=delta_origin)
svg2gcode-1.2.0/README.md DELETED
@@ -1,69 +0,0 @@
1
- # svg2gcode
2
-
3
- A commandline steering program that enables laser cutting of svg drawings```<svg:path ..>tags``` and combined engraving of svg images```<svg:image ..>tags```.
4
- It is based on library SvgToGcode (*fork*: https://github.com/johannesnoordanus/SvgToGcode) which should be installed <sup>(*)</sup>.
5
-
6
- Drawings and images can be composed using Inkscape (for example) and saved to a .svg file. This file can be converted to gcode by svg2gcode.
7
- Gcode produced in this way has the advantage that drawings and images have the same - relative - position and orientation as can be seen on the composer window.
8
- This makes combined cutting and engraving as easy as orientating the (wood) slab once.
9
-
10
- Controlling laser power, pixel size and other settings can be done via commandline parameters (see below) or within Inkscape using the XMLeditor.
11
- Image attributes ```gcode_pixelsize```, ```gcode_maxpower``` and ```gcode_speed``` can be set per object (they must be created: use **+**). Note that this overrides explicit or default commandline settings.
12
-
13
- **Tip**: use commandline program grblhud (https://github.com/johannesnoordanus/grblhud) to have full control over gcode execution.
14
- ### Install:
15
- ```
16
- >
17
- > pip install svg2gcode
18
- ```
19
- <sup>(*)</sup> Note that library *svg_to_gcode* is included in this package.
20
- ### Usage:
21
- See notes below.
22
- ```
23
- $ svg2gcode --help
24
- usage: svg2gcode.py [-h] [--showimage] [--pixelsize <default:0.1>] [--imagespeed <default:800>] [--cuttingspeed <default:1000>] [--imagepower <default:300>]
25
- [--cuttingpower <default:0.85>] [--maxlaserpower <default:1000>] [--rapidmove] [--xmaxtravel <default:300>] [--ymaxtravel <default:400>] [--fan] [-V]
26
- svg gcode
27
-
28
- Convert svg to gcode for GRBL v1.1 compatible diode laser engravers.
29
-
30
- positional arguments:
31
- svg svg file to be converted to gcode
32
- gcode gcode output file
33
-
34
- options:
35
- -h, --help show this help message and exit
36
- --showimage show b&w converted image
37
- --pixelsize <default:0.1>
38
- pixel size in mm (XY-axis): each image pixel is drawn this size
39
- --imagespeed <default:800>
40
- image draw speed in mm/min
41
- --cuttingspeed <default:1000>
42
- cutting speed in mm/min
43
- --imagepower <default:300>
44
- maximum laser power while drawing an image (as a rule of thumb set to 1/3 of the machine maximum)
45
- --cuttingpower <default:850>
46
- sets laser power of line drawings/cutting
47
- --rapidmove generate inbetween G0 moves
48
- --xmaxtravel <default:300>
49
- machine x-axis lengh in mm
50
- --ymaxtravel <default:400>
51
- machine y-axis lengh in mm
52
- --fan set machine fan on
53
- -V, --version show version number and exit
54
- ```
55
- ### Notes:
56
- - example command to create two types of gcode file, one containing the drawings of the .svg, the other containing the images:
57
- ```
58
- > svg2gcode ambachtmanlogo.svg logo.gc
59
- > ..
60
- > ls *.gc
61
- > logo.gc # all drawings
62
- > logo_images.gc # all images
63
- ```
64
- - drawing objects - within the composer - must be converted to a```path```to be translated to a gcode sequence
65
- - also, image objects should **not** be converted to a ```path```
66
- - images must be linked or embedded using base64.
67
- - images can be in several formats (my tests included ```.png``` and ```.jpg``` image files)
68
-
69
-
@@ -1,69 +0,0 @@
1
- # svg2gcode
2
-
3
- A commandline steering program that enables laser cutting of svg drawings```<svg:path ..>tags``` and combined engraving of svg images```<svg:image ..>tags```.
4
- It is based on library SvgToGcode (*fork*: https://github.com/johannesnoordanus/SvgToGcode) which should be installed <sup>(*)</sup>.
5
-
6
- Drawings and images can be composed using Inkscape (for example) and saved to a .svg file. This file can be converted to gcode by svg2gcode.
7
- Gcode produced in this way has the advantage that drawings and images have the same - relative - position and orientation as can be seen on the composer window.
8
- This makes combined cutting and engraving as easy as orientating the (wood) slab once.
9
-
10
- Controlling laser power, pixel size and other settings can be done via commandline parameters (see below) or within Inkscape using the XMLeditor.
11
- Image attributes ```gcode_pixelsize```, ```gcode_maxpower``` and ```gcode_speed``` can be set per object (they must be created: use **+**). Note that this overrides explicit or default commandline settings.
12
-
13
- **Tip**: use commandline program grblhud (https://github.com/johannesnoordanus/grblhud) to have full control over gcode execution.
14
- ### Install:
15
- ```
16
- >
17
- > pip install svg2gcode
18
- ```
19
- <sup>(*)</sup> Note that library *svg_to_gcode* is included in this package.
20
- ### Usage:
21
- See notes below.
22
- ```
23
- $ svg2gcode --help
24
- usage: svg2gcode.py [-h] [--showimage] [--pixelsize <default:0.1>] [--imagespeed <default:800>] [--cuttingspeed <default:1000>] [--imagepower <default:300>]
25
- [--cuttingpower <default:0.85>] [--maxlaserpower <default:1000>] [--rapidmove] [--xmaxtravel <default:300>] [--ymaxtravel <default:400>] [--fan] [-V]
26
- svg gcode
27
-
28
- Convert svg to gcode for GRBL v1.1 compatible diode laser engravers.
29
-
30
- positional arguments:
31
- svg svg file to be converted to gcode
32
- gcode gcode output file
33
-
34
- options:
35
- -h, --help show this help message and exit
36
- --showimage show b&w converted image
37
- --pixelsize <default:0.1>
38
- pixel size in mm (XY-axis): each image pixel is drawn this size
39
- --imagespeed <default:800>
40
- image draw speed in mm/min
41
- --cuttingspeed <default:1000>
42
- cutting speed in mm/min
43
- --imagepower <default:300>
44
- maximum laser power while drawing an image (as a rule of thumb set to 1/3 of the machine maximum)
45
- --cuttingpower <default:850>
46
- sets laser power of line drawings/cutting
47
- --rapidmove generate inbetween G0 moves
48
- --xmaxtravel <default:300>
49
- machine x-axis lengh in mm
50
- --ymaxtravel <default:400>
51
- machine y-axis lengh in mm
52
- --fan set machine fan on
53
- -V, --version show version number and exit
54
- ```
55
- ### Notes:
56
- - example command to create two types of gcode file, one containing the drawings of the .svg, the other containing the images:
57
- ```
58
- > svg2gcode ambachtmanlogo.svg logo.gc
59
- > ..
60
- > ls *.gc
61
- > logo.gc # all drawings
62
- > logo_images.gc # all images
63
- ```
64
- - drawing objects - within the composer - must be converted to a```path```to be translated to a gcode sequence
65
- - also, image objects should **not** be converted to a ```path```
66
- - images must be linked or embedded using base64.
67
- - images can be in several formats (my tests included ```.png``` and ```.jpg``` image files)
68
-
69
-
File without changes
File without changes