Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ struct Opt {
///
/// Useful to print the label of layer on SVG generated by Inkscape
extra_attribute_name: Option<String>,
#[arg(long)]
/// Reorder paths to minimise pen-up travel using a TSP heuristic
optimize: bool,
}

fn main() -> io::Result<()> {
Expand Down Expand Up @@ -168,6 +171,7 @@ fn main() -> io::Result<()> {
}

settings.conversion.extra_attribute_name = opt.extra_attribute_name;
settings.conversion.optimize_path_order = opt.optimize;

if let Version::Unknown(ref unknown) = settings.version {
error!(
Expand Down
2 changes: 2 additions & 0 deletions lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ serde = ["dep:serde", "dep:serde_repr", "g-code/serde"]

[dependencies]
g-code.workspace = true
rand = "0.8"
rustc-hash = "1"
rust_decimal = { version = "1", default-features = false }
lyon_geom = "=1.0.6"
euclid = "0.22"
Expand Down
53 changes: 50 additions & 3 deletions lib/src/converter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ use uom::si::{
};

use self::units::CSS_DEFAULT_DPI;
use crate::{Machine, turtle::*};
use crate::{
Machine, tsp,
turtle::{collect::DrawingCommand, *},
};

#[cfg(feature = "serde")]
mod length_serde;
Expand All @@ -36,6 +39,9 @@ pub struct ConversionConfig {
pub origin: [Option<f64>; 2],
/// Set extra attribute to add when printing node name
pub extra_attribute_name: Option<String>,
/// Reorder paths to minimise pen-up travel using a TSP heuristic
#[cfg_attr(feature = "serde", serde(default))]
pub optimize_path_order: bool,
}

const fn zero_origin() -> [Option<f64>; 2] {
Expand All @@ -50,6 +56,7 @@ impl Default for ConversionConfig {
dpi: 96.0,
origin: zero_origin(),
extra_attribute_name: None,
optimize_path_order: false,
}
}
}
Expand Down Expand Up @@ -160,7 +167,7 @@ pub fn svg2program<'a, 'input: 'a>(
dpi: config.dpi,
}),
_config: config,
options,
options: options.clone(),
name_stack: vec![],
viewport_dim_stack: vec![],
};
Expand All @@ -169,7 +176,47 @@ pub fn svg2program<'a, 'input: 'a>(
.terrarium
.push_transform(origin_transform);
conversion_visitor.begin();
visit::depth_first_visit(doc, &mut conversion_visitor);

if config.optimize_path_order {
// Collect all transformed strokes for TSP optimization
let mut collect_visitor = ConversionVisitor {
terrarium: Terrarium::new(DpiConvertingTurtle {
inner: StrokeCollectingTurtle::default(),
dpi: config.dpi,
}),
_config: config,
options,
name_stack: vec![],
viewport_dim_stack: vec![],
};
collect_visitor.terrarium.push_transform(origin_transform);
collect_visitor.begin();
visit::depth_first_visit(doc, &mut collect_visitor);
collect_visitor.end();
collect_visitor.terrarium.pop_transform();
let strokes = collect_visitor.terrarium.turtle.inner.strokes;

// Optimize ordering
let strokes = tsp::optimize_path_order(strokes);

// Replay optimized strokes into the GCode turtle
let turtle = &mut conversion_visitor.terrarium.turtle;
for stroke in strokes {
turtle.move_to(stroke.start_point);
for cmd in stroke.commands {
match cmd {
DrawingCommand::LineTo(to) => turtle.line_to(to),
DrawingCommand::Arc(arc) => turtle.arc(arc),
DrawingCommand::CubicBezier(cbs) => turtle.cubic_bezier(cbs),
DrawingCommand::QuadraticBezier(qbs) => turtle.quadratic_bezier(qbs),
DrawingCommand::Comment(s) => turtle.comment(s),
}
}
}
} else {
visit::depth_first_visit(doc, &mut conversion_visitor);
}

conversion_visitor.end();
conversion_visitor.terrarium.pop_transform();

Expand Down
2 changes: 2 additions & 0 deletions lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ mod machine;
/// Operations that are easier to implement while/after G-Code is generated, or would
/// otherwise over-complicate SVG conversion
mod postprocess;
/// Reorders strokes to minimize pen-up travel using TSP heuristics
mod tsp;
/// Provides an interface for drawing lines in G-Code
/// This concept is referred to as [Turtle graphics](https://en.wikipedia.org/wiki/Turtle_graphics).
mod turtle;
Expand Down
Loading