Skip to content

Commit 407a6d3

Browse files
authored
Experimental path reordering, closes #13 (#98)
1 parent 8c40dd1 commit 407a6d3

11 files changed

Lines changed: 667 additions & 4 deletions

File tree

Cargo.lock

Lines changed: 67 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli/src/main.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ struct Opt {
9292
///
9393
/// Useful to print the label of layer on SVG generated by Inkscape
9494
extra_attribute_name: Option<String>,
95+
#[arg(long)]
96+
/// Reorder paths to minimize travel time
97+
optimize_path_order: bool,
9598
}
9699

97100
fn main() -> io::Result<()> {
@@ -168,6 +171,7 @@ fn main() -> io::Result<()> {
168171
}
169172

170173
settings.conversion.extra_attribute_name = opt.extra_attribute_name;
174+
settings.conversion.optimize_path_order = opt.optimize_path_order;
171175

172176
if let Version::Unknown(ref unknown) = settings.version {
173177
error!(

lib/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ serde = ["dep:serde", "dep:serde_repr", "g-code/serde"]
1212

1313
[dependencies]
1414
g-code.workspace = true
15+
rand = "0.8"
16+
rustc-hash = "1"
1517
rust_decimal = { version = "1", default-features = false }
1618
lyon_geom = "=1.0.6"
1719
euclid = "0.22"

lib/src/converter/mod.rs

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@ use uom::si::{
1212
};
1313

1414
use self::units::CSS_DEFAULT_DPI;
15-
use crate::{Machine, turtle::*};
15+
use crate::{
16+
Machine, Turtle, tsp,
17+
turtle::{
18+
DpiConvertingTurtle, GCodeTurtle, PreprocessTurtle, StrokeCollectingTurtle, Terrarium,
19+
},
20+
};
1621

1722
#[cfg(feature = "serde")]
1823
mod length_serde;
@@ -36,6 +41,9 @@ pub struct ConversionConfig {
3641
pub origin: [Option<f64>; 2],
3742
/// Set extra attribute to add when printing node name
3843
pub extra_attribute_name: Option<String>,
44+
/// Reorder paths to minimize travel time
45+
#[cfg_attr(feature = "serde", serde(default))]
46+
pub optimize_path_order: bool,
3947
}
4048

4149
const fn zero_origin() -> [Option<f64>; 2] {
@@ -50,6 +58,7 @@ impl Default for ConversionConfig {
5058
dpi: 96.0,
5159
origin: zero_origin(),
5260
extra_attribute_name: None,
61+
optimize_path_order: false,
5362
}
5463
}
5564
}
@@ -160,7 +169,7 @@ pub fn svg2program<'a, 'input: 'a>(
160169
dpi: config.dpi,
161170
}),
162171
_config: config,
163-
options,
172+
options: options.clone(),
164173
name_stack: vec![],
165174
viewport_dim_stack: vec![],
166175
};
@@ -169,7 +178,43 @@ pub fn svg2program<'a, 'input: 'a>(
169178
.terrarium
170179
.push_transform(origin_transform);
171180
conversion_visitor.begin();
172-
visit::depth_first_visit(doc, &mut conversion_visitor);
181+
182+
if config.optimize_path_order {
183+
// Collect strokes in machine space
184+
let strokes = {
185+
let mut collect_visitor = ConversionVisitor {
186+
terrarium: Terrarium::new(DpiConvertingTurtle {
187+
inner: StrokeCollectingTurtle::default(),
188+
dpi: config.dpi,
189+
}),
190+
_config: config,
191+
options,
192+
name_stack: vec![],
193+
viewport_dim_stack: vec![],
194+
};
195+
collect_visitor.terrarium.push_transform(origin_transform);
196+
collect_visitor.begin();
197+
visit::depth_first_visit(doc, &mut collect_visitor);
198+
collect_visitor.end();
199+
collect_visitor.terrarium.pop_transform();
200+
collect_visitor.terrarium.turtle.inner.into_strokes()
201+
};
202+
203+
// Optimize order
204+
let strokes = tsp::minimize_travel_time(strokes);
205+
206+
// Replay reordered strokes into the g-code turtle
207+
let turtle = &mut conversion_visitor.terrarium.turtle;
208+
for stroke in strokes {
209+
turtle.move_to(stroke.start_point());
210+
for cmd in stroke.commands() {
211+
cmd.apply(turtle);
212+
}
213+
}
214+
} else {
215+
visit::depth_first_visit(doc, &mut conversion_visitor);
216+
}
217+
173218
conversion_visitor.end();
174219
conversion_visitor.terrarium.pop_transform();
175220

lib/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ mod machine;
77
/// Operations that are easier to implement while/after G-Code is generated, or would
88
/// otherwise over-complicate SVG conversion
99
mod postprocess;
10+
/// Reorders strokes to minimize pen-up travel using TSP heuristics
11+
mod tsp;
1012
/// Provides an interface for drawing lines in G-Code
1113
/// This concept is referred to as [Turtle graphics](https://en.wikipedia.org/wiki/Turtle_graphics).
1214
mod turtle;

0 commit comments

Comments
 (0)