A review of major changes and what's next
Example vector graphic
A pen plotter attachment is used to draw the SVG on a 3D printer
Quoting Thomas Kole on Twitter:
It’s written in rust and was super easy to compile for the [Raspberry] Pi. I first tried a python implementation, but this is orders of magnitude faster. It’s crazy fast.
I initially released svg2gcode in 2019 as part of a project to build a pen plotter. The Inkscape extension we tried to use for that was overly complicated so I set out to build a standalone tool from scratch. The project has changed considerably since then – there are several noteworthy features which I’ll discuss below.
After talking to a few users over email, I realized that there were significant barriers preventing wider use of svg2gcode:
I created a web app for svg2gcode to address these challenges:
The web interface is functionally equivalent to the CLI tool. There are some added ergonomics like saving settings to Web Storage and on-the-fly validation:
For those comfortable with the CLI but not too familiar with Rust, I set up prebuilt binary downloads. The Rust Release Binary action publishes binaries for platforms with x86-64 processors running Linux, Windows or OS X.
Users can now specify a G-Code sequence to run at the beginning/end of a program and when the tool is turned on/off. This makes it possible to target just about any machine that accepts G-Code.
Enabling this involved a pretty comprehensive overhaul of how the tool handles G-Code. Most of the logic was pulled out into the g-code crate: an all-in-one library for parsing, formatting, and outputting G-Code.
error: could not parse gcode ┌─ begin_sequence:1:27 │ 1 │ G0 X0 Y0 (unclosed comment │ ^ expected closing parenthesis
These tokens are inserted into the output where appropriate. For instance, the tool on/off sequences are inserted at the start/end of each path segment:
> svg2gcode --on '(tool on)' --off '(tool off)' examparse, format, and emitples/Vanderbilt_Commodores_logo.svg G0 X59.02125187621354 Y114.1597945756128(tool on) G1 X44.163311191869035 Y73.15496298711147 F300 ... G1 X59.02125187621354 Y114.1597945756128 F300;svg > g > g > path (tool off)
When converting to G-Code, the tool must do something called curve flattening: curves are converted into a series of connected line segments within a given tolerance. The tolerance is kept small enough that there is no discernible difference between the original and flattened curves in the end product. We can see the difference close up using a G-Code viewer:
A close-up visualization of the G-Code for this circle reveals the line segments
While flattening to line segments works well, some machines also support circular arc segments: given start/end points and a radius, the machine interpolates along a circular arc between the two. Circular arc segments are much better at approximating curves. Output file size is decreased by a lot and the machine can better control velocity and acceleration while executing the program.
I implemented circular interpolation following Kaewsaiha & Dejdumrong’s paper Modeling of Bézier Curves Using a Combination of Linear and Circular Arc Approximations.
A truer approximation with circular interpolation enabled
Aside from that I ironed out some bugs with the logic for geometric transformations on elliptical arcs. Vitaly Putzin’s svgpath was a really good reference for this.
I have a whole laundry list of ideas to take svg2gcode even further. To name a few:
Builds and packaging:
But I only have so much time! 😅