svg2gcode 2.3.1__tar.gz → 2.5.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 (34) hide show
  1. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/PKG-INFO +12 -10
  2. {svg2gcode-2.3.1/svg2gcode → svg2gcode-2.5.0}/README.md +11 -9
  3. {svg2gcode-2.3.1 → svg2gcode-2.5.0/svg2gcode}/README.md +11 -9
  4. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/__init__.py +1 -1
  5. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/__main__.py +11 -2
  6. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/compiler/_compiler.py +5 -5
  7. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/svg_parser/_parser_methods.py +13 -9
  8. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/LICENSE +0 -0
  9. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/pyproject.toml +0 -0
  10. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/.DS_Store +0 -0
  11. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/__init__.py +0 -0
  12. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/compiler/__init__.py +0 -0
  13. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/compiler/interfaces/__init__.py +0 -0
  14. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/compiler/interfaces/_abstract_interface.py +0 -0
  15. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/compiler/interfaces/_fan_controlled_gcode.py +0 -0
  16. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/compiler/interfaces/_gcode.py +0 -0
  17. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/formulas.py +0 -0
  18. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/geometry/__init__.py +0 -0
  19. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/geometry/_abstract_chain.py +0 -0
  20. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/geometry/_abstract_curve.py +0 -0
  21. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/geometry/_circular_arc.py +0 -0
  22. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/geometry/_cubic_bazier.py +0 -0
  23. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/geometry/_elliptical_arc.py +0 -0
  24. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/geometry/_line.py +0 -0
  25. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/geometry/_line_segment_chain.py +0 -0
  26. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/geometry/_matrix.py +0 -0
  27. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/geometry/_quadratic_bazier.py +0 -0
  28. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/geometry/_raster_image.py +0 -0
  29. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/geometry/_smooth_arc_chain.py +0 -0
  30. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/geometry/_vector.py +0 -0
  31. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/svg_parser/__init__.py +0 -0
  32. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/svg_parser/_path.py +0 -0
  33. {svg2gcode-2.3.1 → svg2gcode-2.5.0}/svg2gcode/svg_to_gcode/svg_parser/_transformation.py +0 -0
  34. {svg2gcode-2.3.1 → svg2gcode-2.5.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: 2.3.1
3
+ Version: 2.5.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>
@@ -57,11 +57,11 @@ also, program *image2gcode* has similar capabilities but handles raster images f
57
57
  See notes below.
58
58
  ```
59
59
  $ svg2gcode --help
60
- usage: svg2gcode [-h] [--showimage] [--pixelsize <default:0.1>] [--imagespeed <default:800>]
61
- [--cuttingspeed <default:1000>] [--imagepower <default:300>] [--cuttingpower <default:850>]
62
- [--rapidmove <default:10>] [--noise <default:0>] [--constantburn] [--origin Xdelta Ydelta]
63
- [--scale Xfactor Yfactor] [--splitfile] [--xmaxtravel <default:300>] [--ymaxtravel <default:400>]
64
- [--fan] [-V] svg gcode
60
+ usage: svg2gcode [-h] [--showimage] [--pixelsize <default:0.1>] [--imagespeed <default:800>] [--cuttingspeed <default:1000>]
61
+ [--imagepower <default:300>] [--cuttingpower <default:850>] [--passes <default:1>] [--pass_depth <default:0>]
62
+ [--rapidmove <default:10>] [--noise <default:0>] [--constantburn] [--origin Xdelta Ydelta] [--scale Xfactor Yfactor]
63
+ [--rotate <default:0>] [--splitfile] [--xmaxtravel <default:300>] [--ymaxtravel <default:400>] [--fan] [-V]
64
+ svg gcode
65
65
 
66
66
  Convert svg to gcode for GRBL v1.1 compatible diode laser engravers.
67
67
 
@@ -79,19 +79,21 @@ options:
79
79
  --cuttingspeed <default:1000>
80
80
  cutting speed in mm/min
81
81
  --imagepower <default:300>
82
- maximum laser power while drawing an image (as a rule of thumb set to 1/3 of the
83
- machine maximum for a 5W laser)
82
+ maximum laser power while drawing an image (as a rule of thumb set to 1/3 of the machine maximum for a 5W laser)
84
83
  --cuttingpower <default:850>
85
84
  sets laser power of line drawings/cutting
85
+ --passes <default:1> Number of passes (iterations) for line drawings, only active when pass_depth is set
86
+ --pass_depth <default:0>
87
+ cutting depth in mm for one pass, only active for passes > 1
86
88
  --rapidmove <default:10>
87
- generate G0 moves between shapes, for images: G0 moves when skipping more than 10mm
88
- (default), 0 is no G0 moves
89
+ generate G0 moves between shapes, for images: G0 moves when skipping more than 10mm (default), 0 is no G0 moves
89
90
  --noise <default:0> reduces image noise by not emitting pixels with power lower or equal than this setting
90
91
  --constantburn use constant burn mode M3 (a bit more dangerous!), instead of dynamic burn mode M4
91
92
  --origin Xdelta Ydelta
92
93
  translate origin by (Xdelta,Ydelta) (default not set)
93
94
  --scale Xfactor Yfactor
94
95
  scale svg with (Xfactor,Yfactor) (default not set)
96
+ --rotate <default:0> number of degrees to rotate
95
97
  --splitfile split gcode output of SVG path and image objects
96
98
  --xmaxtravel <default:300>
97
99
  machine x-axis lengh in mm
@@ -44,11 +44,11 @@ also, program *image2gcode* has similar capabilities but handles raster images f
44
44
  See notes below.
45
45
  ```
46
46
  $ svg2gcode --help
47
- usage: svg2gcode [-h] [--showimage] [--pixelsize <default:0.1>] [--imagespeed <default:800>]
48
- [--cuttingspeed <default:1000>] [--imagepower <default:300>] [--cuttingpower <default:850>]
49
- [--rapidmove <default:10>] [--noise <default:0>] [--constantburn] [--origin Xdelta Ydelta]
50
- [--scale Xfactor Yfactor] [--splitfile] [--xmaxtravel <default:300>] [--ymaxtravel <default:400>]
51
- [--fan] [-V] svg gcode
47
+ usage: svg2gcode [-h] [--showimage] [--pixelsize <default:0.1>] [--imagespeed <default:800>] [--cuttingspeed <default:1000>]
48
+ [--imagepower <default:300>] [--cuttingpower <default:850>] [--passes <default:1>] [--pass_depth <default:0>]
49
+ [--rapidmove <default:10>] [--noise <default:0>] [--constantburn] [--origin Xdelta Ydelta] [--scale Xfactor Yfactor]
50
+ [--rotate <default:0>] [--splitfile] [--xmaxtravel <default:300>] [--ymaxtravel <default:400>] [--fan] [-V]
51
+ svg gcode
52
52
 
53
53
  Convert svg to gcode for GRBL v1.1 compatible diode laser engravers.
54
54
 
@@ -66,19 +66,21 @@ options:
66
66
  --cuttingspeed <default:1000>
67
67
  cutting speed in mm/min
68
68
  --imagepower <default:300>
69
- maximum laser power while drawing an image (as a rule of thumb set to 1/3 of the
70
- machine maximum for a 5W laser)
69
+ maximum laser power while drawing an image (as a rule of thumb set to 1/3 of the machine maximum for a 5W laser)
71
70
  --cuttingpower <default:850>
72
71
  sets laser power of line drawings/cutting
72
+ --passes <default:1> Number of passes (iterations) for line drawings, only active when pass_depth is set
73
+ --pass_depth <default:0>
74
+ cutting depth in mm for one pass, only active for passes > 1
73
75
  --rapidmove <default:10>
74
- generate G0 moves between shapes, for images: G0 moves when skipping more than 10mm
75
- (default), 0 is no G0 moves
76
+ generate G0 moves between shapes, for images: G0 moves when skipping more than 10mm (default), 0 is no G0 moves
76
77
  --noise <default:0> reduces image noise by not emitting pixels with power lower or equal than this setting
77
78
  --constantburn use constant burn mode M3 (a bit more dangerous!), instead of dynamic burn mode M4
78
79
  --origin Xdelta Ydelta
79
80
  translate origin by (Xdelta,Ydelta) (default not set)
80
81
  --scale Xfactor Yfactor
81
82
  scale svg with (Xfactor,Yfactor) (default not set)
83
+ --rotate <default:0> number of degrees to rotate
82
84
  --splitfile split gcode output of SVG path and image objects
83
85
  --xmaxtravel <default:300>
84
86
  machine x-axis lengh in mm
@@ -44,11 +44,11 @@ also, program *image2gcode* has similar capabilities but handles raster images f
44
44
  See notes below.
45
45
  ```
46
46
  $ svg2gcode --help
47
- usage: svg2gcode [-h] [--showimage] [--pixelsize <default:0.1>] [--imagespeed <default:800>]
48
- [--cuttingspeed <default:1000>] [--imagepower <default:300>] [--cuttingpower <default:850>]
49
- [--rapidmove <default:10>] [--noise <default:0>] [--constantburn] [--origin Xdelta Ydelta]
50
- [--scale Xfactor Yfactor] [--splitfile] [--xmaxtravel <default:300>] [--ymaxtravel <default:400>]
51
- [--fan] [-V] svg gcode
47
+ usage: svg2gcode [-h] [--showimage] [--pixelsize <default:0.1>] [--imagespeed <default:800>] [--cuttingspeed <default:1000>]
48
+ [--imagepower <default:300>] [--cuttingpower <default:850>] [--passes <default:1>] [--pass_depth <default:0>]
49
+ [--rapidmove <default:10>] [--noise <default:0>] [--constantburn] [--origin Xdelta Ydelta] [--scale Xfactor Yfactor]
50
+ [--rotate <default:0>] [--splitfile] [--xmaxtravel <default:300>] [--ymaxtravel <default:400>] [--fan] [-V]
51
+ svg gcode
52
52
 
53
53
  Convert svg to gcode for GRBL v1.1 compatible diode laser engravers.
54
54
 
@@ -66,19 +66,21 @@ options:
66
66
  --cuttingspeed <default:1000>
67
67
  cutting speed in mm/min
68
68
  --imagepower <default:300>
69
- maximum laser power while drawing an image (as a rule of thumb set to 1/3 of the
70
- machine maximum for a 5W laser)
69
+ maximum laser power while drawing an image (as a rule of thumb set to 1/3 of the machine maximum for a 5W laser)
71
70
  --cuttingpower <default:850>
72
71
  sets laser power of line drawings/cutting
72
+ --passes <default:1> Number of passes (iterations) for line drawings, only active when pass_depth is set
73
+ --pass_depth <default:0>
74
+ cutting depth in mm for one pass, only active for passes > 1
73
75
  --rapidmove <default:10>
74
- generate G0 moves between shapes, for images: G0 moves when skipping more than 10mm
75
- (default), 0 is no G0 moves
76
+ generate G0 moves between shapes, for images: G0 moves when skipping more than 10mm (default), 0 is no G0 moves
76
77
  --noise <default:0> reduces image noise by not emitting pixels with power lower or equal than this setting
77
78
  --constantburn use constant burn mode M3 (a bit more dangerous!), instead of dynamic burn mode M4
78
79
  --origin Xdelta Ydelta
79
80
  translate origin by (Xdelta,Ydelta) (default not set)
80
81
  --scale Xfactor Yfactor
81
82
  scale svg with (Xfactor,Yfactor) (default not set)
83
+ --rotate <default:0> number of degrees to rotate
82
84
  --splitfile split gcode output of SVG path and image objects
83
85
  --xmaxtravel <default:300>
84
86
  machine x-axis lengh in mm
@@ -1,4 +1,4 @@
1
1
  """
2
2
  svg2gcode: convert an SVG (Scalable Vector Graphic) image to gcode.
3
3
  """
4
- __version__ = "2.3.1"
4
+ __version__ = "2.5.0"
@@ -24,9 +24,9 @@ def svg2gcode(args) -> int:
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
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", 'splitfile':args.splitfile})
27
+ 'pass_depth':args.pass_depth, 'laser_mode':"constant" if args.constantburn else "dynamic", 'splitfile':args.splitfile})
28
28
  # emit gcode for svg
29
- gcode_compiler.compile_to_file(args.gcode, parse_file(args.svg, delta_origin=args.origin, scale_factor=args.scale), passes=1)
29
+ gcode_compiler.compile_to_file(args.gcode, parse_file(args.svg, delta_origin=args.origin, scale_factor=args.scale, rotate_deg=args.rotate), passes=args.passes)
30
30
 
31
31
  except Exception as error:
32
32
  print(error)
@@ -48,6 +48,9 @@ def main() -> int:
48
48
  ymaxtravel_default = 400
49
49
  rapidmove_default = 10
50
50
  noise_default = 0
51
+ pass_depth_default = 0
52
+ passes_default = 1
53
+ rotate_default = 0
51
54
 
52
55
  # Define command line argument interface
53
56
  parser = argparse.ArgumentParser(description='Convert svg to gcode for GRBL v1.1 compatible diode laser engravers.')
@@ -64,6 +67,10 @@ def main() -> int:
64
67
  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)")
65
68
  parser.add_argument('--cuttingpower', default=cuttingpower_default, metavar="<default:" +str(cuttingpower_default)+ ">",
66
69
  type=int, help="sets laser power of line drawings/cutting")
70
+ parser.add_argument('--passes', default=passes_default, metavar="<default:" +str(passes_default)+ ">",
71
+ type=int, help="Number of passes (iterations) for line drawings, only active when pass_depth is set")
72
+ parser.add_argument('--pass_depth', default=pass_depth_default, metavar="<default:" + str(pass_depth_default)+">",
73
+ type=float, help="cutting depth in mm for one pass, only active for passes > 1")
67
74
  parser.add_argument('--rapidmove', default=rapidmove_default, metavar="<default:" +str(rapidmove_default)+ ">",
68
75
  type=int, help='generate G0 moves between shapes, for images: G0 moves when skipping more than 10mm (default), 0 is no G0 moves' )
69
76
  parser.add_argument('--noise', default=noise_default, metavar="<default:" +str(noise_default)+ ">",
@@ -73,6 +80,8 @@ def main() -> int:
73
80
  type=float, help="translate origin by (Xdelta,Ydelta) (default not set)")
74
81
  parser.add_argument('--scale', default=None, nargs=2, metavar=('Xfactor', 'Yfactor'),
75
82
  type=float, help="scale svg with (Xfactor,Yfactor) (default not set)")
83
+ parser.add_argument('--rotate', default=rotate_default, metavar="<default:" +str(rotate_default)+ ">",
84
+ type=int, help="number of degrees to rotate")
76
85
  parser.add_argument('--splitfile', action='store_true', default=False, help='split gcode output of SVG path and image objects' )
77
86
  parser.add_argument('--xmaxtravel', default=xmaxtravel_default, metavar="<default:" +str(xmaxtravel_default)+ ">",
78
87
  type=int, help="machine x-axis lengh in mm")
@@ -261,7 +261,7 @@ class Compiler:
261
261
  def convert_image(self, image:str, img_attrib: dict[str, Any]):
262
262
 
263
263
  # get svg image attributes info or default
264
- pixelsize = img_attrib['gcode_pixelsize'] if 'gcode_pixelsize' in img_attrib else 0.1
264
+ pixelsize = img_attrib['gcode_pixelsize'] if 'gcode_pixelsize' in img_attrib else self.settings["pixel_size"]
265
265
 
266
266
  # convert image from base64 string
267
267
  img = self.decode_base64(image)
@@ -275,13 +275,13 @@ class Compiler:
275
275
  img_background = Image.new(mode = "RGBA", size = img.size, color = (255,255,255))
276
276
  img = Image.alpha_composite(img_background, img)
277
277
 
278
- # convert image to black&white (without alpha) and new size #reminder: 'img = img.convert("LA")'
279
- img = img.resize((int(float(img_attrib['width']) * 1/float(pixelsize)),
280
- int(float(img_attrib['height']) * 1/float(pixelsize))), Image.Resampling.LANCZOS).convert("L")
281
-
282
278
  if self.settings['showimage']:
283
279
  img.show()
284
280
 
281
+ # convert image to black&white (without alpha) and new size #reminder: 'img = img.convert("LA")'
282
+ img = img.resize((int(float(img_attrib['width'])/float(pixelsize)),
283
+ int(float(img_attrib['height'])/float(pixelsize))), Image.Resampling.LANCZOS).convert("L")
284
+
285
285
  # convert to nparray for fast handling
286
286
  return np.array(img)
287
287
 
@@ -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, origin, scale):
22
+ def add_viewbox_transformation(transformation: Transformation, transform_origin, vwbox, origin, scale, rotate):
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.
@@ -60,6 +60,10 @@ def add_viewbox_transformation(transformation: Transformation, transform_origin,
60
60
  if origin is not None and ((vwbox["x"] + origin[0]) or (vwbox["y"] + origin[1])):
61
61
  up_transformation.add_translation(vwbox["x"] + origin[0],vwbox["y"] + origin[1])
62
62
 
63
+ # rotate it (around the origin)
64
+ if rotate is not None and rotate > 0:
65
+ up_transformation.add_rotation(rotate)
66
+
63
67
  # scale it
64
68
  if scale is not None:
65
69
  up_transformation.add_scale(scale[0],scale[1])
@@ -113,7 +117,7 @@ def get_viewBox(root: ElementTree.Element) -> {}:
113
117
 
114
118
 
115
119
  def parse_root(root: ElementTree.Element, transform_origin=True, viewbox=None, draw_hidden=False,
116
- visible_root=True, root_transformation=None, origin=None, scale=None) -> List[Curve]:
120
+ visible_root=True, root_transformation=None, origin=None, scale=None, rotate=None) -> List[Curve]:
117
121
 
118
122
  """
119
123
  Recursively parse an etree root's children into geometric curves.
@@ -170,7 +174,7 @@ def parse_root(root: ElementTree.Element, transform_origin=True, viewbox=None, d
170
174
  if draw_hidden or visible:
171
175
  if element.tag == "{%s}path" % NAMESPACES["svg"]:
172
176
  path = Path(element.attrib['d'],
173
- add_viewbox_transformation(transformation, transform_origin, viewbox, origin, scale))
177
+ add_viewbox_transformation(transformation, transform_origin, viewbox, origin, scale, rotate))
174
178
  curves.extend(path.curves)
175
179
  else:
176
180
  if element.tag == "{%s}image" % NAMESPACES["svg"]:
@@ -178,17 +182,17 @@ def parse_root(root: ElementTree.Element, transform_origin=True, viewbox=None, d
178
182
 
179
183
  # instantiate curve (image)
180
184
  ri = RasterImage(element.attrib, element.attrib["{%s}href" % NAMESPACES["xlink"]],
181
- add_viewbox_transformation(transformation, transform_origin, viewbox, origin, scale))
185
+ add_viewbox_transformation(transformation, transform_origin, viewbox, origin, scale, rotate))
182
186
  curves.append(ri)
183
187
 
184
188
  # Continue the recursion
185
- curves.extend(parse_root(element, transform_origin, viewbox, draw_hidden, visible, transformation, origin, scale))
189
+ curves.extend(parse_root(element, transform_origin, viewbox, draw_hidden, visible, transformation, origin, scale, rotate))
186
190
 
187
191
  # ToDo implement shapes class
188
192
  return curves
189
193
 
190
194
 
191
- def parse_string(svg_string: str, transform_origin=True, viewbox=None, draw_hidden=False, delta_origin=None, scale_factor=None) -> List[Curve]:
195
+ def parse_string(svg_string: str, transform_origin=True, viewbox=None, draw_hidden=False, delta_origin=None, scale_factor=None, rotate_deg=None) -> List[Curve]:
192
196
  """
193
197
  Recursively parse an svg string into geometric curves. (Wrapper for parse_root)
194
198
 
@@ -203,10 +207,10 @@ def parse_string(svg_string: str, transform_origin=True, viewbox=None, draw_hidd
203
207
  :return: A list of geometric curves describing the svg. Use the Compiler sub-module to compile them to gcode.
204
208
  """
205
209
  root = ElementTree.fromstring(svg_string)
206
- return parse_root(root, transform_origin, viewbox, draw_hidden, origin=delta_origin, scale=scale_factor)
210
+ return parse_root(root, transform_origin, viewbox, draw_hidden, origin=delta_origin, scale=scale_factor, rotate=rotate_deg)
207
211
 
208
212
 
209
- def parse_file(file_path: str, transform_origin=True, viewbox=None, draw_hidden=False, delta_origin=None, scale_factor=None) -> List[Curve]:
213
+ def parse_file(file_path: str, transform_origin=True, viewbox=None, draw_hidden=False, delta_origin=None, scale_factor=None, rotate_deg=None) -> List[Curve]:
210
214
  """
211
215
  Recursively parse an svg file into geometric curves. (Wrapper for parse_root)
212
216
 
@@ -221,4 +225,4 @@ def parse_file(file_path: str, transform_origin=True, viewbox=None, draw_hidden=
221
225
  :return: A list of geometric curves describing the svg. Use the Compiler sub-module to compile them to gcode.
222
226
  """
223
227
  root = ElementTree.parse(file_path).getroot()
224
- return parse_root(root, transform_origin, viewbox, draw_hidden, origin=delta_origin, scale=scale_factor)
228
+ return parse_root(root, transform_origin, viewbox, draw_hidden, origin=delta_origin, scale=scale_factor, rotate=rotate_deg)
File without changes
File without changes