more variable name expansion

master
Sameer Puri 5 years ago
parent 13c1f32d1f
commit f768c4f450

@ -116,7 +116,7 @@ struct ProgramOptions {
origin: (f64, f64) origin: (f64, f64)
} }
fn svg2program(doc: &svgdom::Document, opts: ProgramOptions, mach: Machine) -> Vec<Command> { fn svg2program(doc: &svgdom::Document, options: ProgramOptions, mach: Machine) -> Vec<Command> {
let mut turtle = Turtle::new(mach); let mut turtle = Turtle::new(mach);
let mut program = vec![ let mut program = vec![
@ -153,8 +153,8 @@ fn svg2program(doc: &svgdom::Document, opts: ProgramOptions, mach: Machine) -> V
attributes.get_value(AttributeId::Width), attributes.get_value(AttributeId::Width),
attributes.get_value(AttributeId::Height), attributes.get_value(AttributeId::Height),
) { ) {
let width_in_mm = length_to_mm(width, opts.dpi); let width_in_mm = length_to_mm(width, options.dpi);
let height_in_mm = length_to_mm(height, opts.dpi); let height_in_mm = length_to_mm(height, options.dpi);
turtle.stack_scaling( turtle.stack_scaling(
euclid::Transform2D::create_scale(width_in_mm, -height_in_mm) euclid::Transform2D::create_scale(width_in_mm, -height_in_mm)
.post_translate(math::vector(0.0, height_in_mm)), .post_translate(math::vector(0.0, height_in_mm)),
@ -208,16 +208,16 @@ fn svg2program(doc: &svgdom::Document, opts: ProgramOptions, mach: Machine) -> V
PathSegment::MoveTo { abs, x, y } => turtle.move_to(*abs, *x, *y), PathSegment::MoveTo { abs, x, y } => turtle.move_to(*abs, *x, *y),
PathSegment::ClosePath { abs: _ } => { PathSegment::ClosePath { abs: _ } => {
// Ignore abs, should have identical effect: [9.3.4. The "closepath" command]("https://www.w3.org/TR/SVG/paths.html#PathDataClosePathCommand) // Ignore abs, should have identical effect: [9.3.4. The "closepath" command]("https://www.w3.org/TR/SVG/paths.html#PathDataClosePathCommand)
turtle.close(None, opts.feedrate) turtle.close(None, options.feedrate)
} }
PathSegment::LineTo { abs, x, y } => { PathSegment::LineTo { abs, x, y } => {
turtle.line(*abs, *x, *y, None, opts.feedrate) turtle.line(*abs, *x, *y, None, options.feedrate)
} }
PathSegment::HorizontalLineTo { abs, x } => { PathSegment::HorizontalLineTo { abs, x } => {
turtle.line(*abs, *x, None, None, opts.feedrate) turtle.line(*abs, *x, None, None, options.feedrate)
} }
PathSegment::VerticalLineTo { abs, y } => { PathSegment::VerticalLineTo { abs, y } => {
turtle.line(*abs, None, *y, None, opts.feedrate) turtle.line(*abs, None, *y, None, options.feedrate)
} }
PathSegment::CurveTo { PathSegment::CurveTo {
abs, abs,
@ -235,9 +235,9 @@ fn svg2program(doc: &svgdom::Document, opts: ProgramOptions, mach: Machine) -> V
*y2, *y2,
*x, *x,
*y, *y,
opts.tolerance, options.tolerance,
None, None,
opts.feedrate, options.feedrate,
), ),
PathSegment::SmoothCurveTo { abs, x2, y2, x, y } => turtle PathSegment::SmoothCurveTo { abs, x2, y2, x, y } => turtle
.smooth_cubic_bezier( .smooth_cubic_bezier(
@ -246,9 +246,9 @@ fn svg2program(doc: &svgdom::Document, opts: ProgramOptions, mach: Machine) -> V
*y2, *y2,
*x, *x,
*y, *y,
opts.tolerance, options.tolerance,
None, None,
opts.feedrate, options.feedrate,
), ),
PathSegment::Quadratic { abs, x1, y1, x, y } => turtle.quadratic_bezier( PathSegment::Quadratic { abs, x1, y1, x, y } => turtle.quadratic_bezier(
*abs, *abs,
@ -256,18 +256,18 @@ fn svg2program(doc: &svgdom::Document, opts: ProgramOptions, mach: Machine) -> V
*y1, *y1,
*x, *x,
*y, *y,
opts.tolerance, options.tolerance,
None, None,
opts.feedrate, options.feedrate,
), ),
PathSegment::SmoothQuadratic { abs, x, y } => turtle PathSegment::SmoothQuadratic { abs, x, y } => turtle
.smooth_quadratic_bezier( .smooth_quadratic_bezier(
*abs, *abs,
*x, *x,
*y, *y,
opts.tolerance, options.tolerance,
None, None,
opts.feedrate, options.feedrate,
), ),
PathSegment::EllipticalArc { PathSegment::EllipticalArc {
abs, abs,
@ -288,8 +288,8 @@ fn svg2program(doc: &svgdom::Document, opts: ProgramOptions, mach: Machine) -> V
*x, *x,
*y, *y,
None, None,
opts.feedrate, options.feedrate,
opts.tolerance, options.tolerance,
), ),
}); });
} }

@ -8,26 +8,26 @@ use lyon_geom::{ArcFlags, CubicBezierSegment, QuadraticBezierSegment, SvgArc};
/// Turtle graphics simulator for paths that outputs the gcode representation for each operation. /// Turtle graphics simulator for paths that outputs the gcode representation for each operation.
/// Handles trasforms, scaling, position, offsets, etc. See https://www.w3.org/TR/SVG/paths.html /// Handles trasforms, scaling, position, offsets, etc. See https://www.w3.org/TR/SVG/paths.html
pub struct Turtle { pub struct Turtle {
curpos: F64Point, current_position: F64Point,
initpos: F64Point, initial_position: F64Point,
curtran: Transform2D<f64>, current_transform: Transform2D<f64>,
scaling: Option<Transform2D<f64>>, scaling: Option<Transform2D<f64>>,
transtack: Vec<Transform2D<f64>>, transform_stack: Vec<Transform2D<f64>>,
pub machine: Machine, pub machine: Machine,
prev_ctrl: Option<F64Point>, previous_control: Option<F64Point>,
} }
impl Turtle { impl Turtle {
/// Create a turtle at the origin with no scaling or transform /// Create a turtle at the origin with no scaling or transform
pub fn new(machine: Machine) -> Self { pub fn new(machine: Machine) -> Self {
Self { Self {
curpos: point(0.0, 0.0), current_position: point(0.0, 0.0),
initpos: point(0.0, 0.0), initial_position: point(0.0, 0.0),
curtran: Transform2D::identity(), current_transform: Transform2D::identity(),
scaling: None, scaling: None,
transtack: vec![], transform_stack: vec![],
machine, machine,
prev_ctrl: None, previous_control: None,
} }
} }
} }
@ -40,22 +40,22 @@ impl Turtle {
X: Into<Option<f64>>, X: Into<Option<f64>>,
Y: Into<Option<f64>>, Y: Into<Option<f64>>,
{ {
let invtran = self.curtran.inverse().unwrap(); let inverse_transform = self.current_transform.inverse().unwrap();
let origcurpos = invtran.transform_point(self.curpos); let original_current_position = inverse_transform.transform_point(self.current_position);
let x = x let x = x
.into() .into()
.map(|x| if abs { x } else { origcurpos.x + x }) .map(|x| if abs { x } else { original_current_position.x + x })
.unwrap_or(origcurpos.x); .unwrap_or(original_current_position.x);
let y = y let y = y
.into() .into()
.map(|y| if abs { y } else { origcurpos.y + y }) .map(|y| if abs { y } else { original_current_position.y + y })
.unwrap_or(origcurpos.y); .unwrap_or(original_current_position.y);
let mut to = point(x, y); let mut to = point(x, y);
to = self.curtran.transform_point(to); to = self.current_transform.transform_point(to);
self.curpos = to; self.current_position = to;
self.initpos = to; self.initial_position = to;
self.prev_ctrl = None; self.previous_control = None;
self.machine self.machine
.tool_off() .tool_off()
@ -98,22 +98,22 @@ impl Turtle {
{ {
// See https://www.w3.org/TR/SVG/paths.html#Segment-CompletingClosePath // See https://www.w3.org/TR/SVG/paths.html#Segment-CompletingClosePath
// which could result in a G91 G1 X0 Y0 // which could result in a G91 G1 X0 Y0
if (self.curpos - self.initpos) if (self.current_position - self.initial_position)
.abs() .abs()
.lower_than(vector(std::f64::EPSILON, std::f64::EPSILON)) .lower_than(vector(std::f64::EPSILON, std::f64::EPSILON))
.all() .all()
{ {
return vec![]; return vec![];
} }
self.curpos = self.initpos; self.current_position = self.initial_position;
self.machine self.machine
.tool_on() .tool_on()
.iter() .iter()
.chain(self.machine.absolute().iter()) .chain(self.machine.absolute().iter())
.chain(std::iter::once(&Self::linear_interpolation( .chain(std::iter::once(&Self::linear_interpolation(
self.initpos.x.into(), self.initial_position.x.into(),
self.initpos.y.into(), self.initial_position.y.into(),
z.into(), z.into(),
f.into(), f.into(),
))) )))
@ -130,21 +130,21 @@ impl Turtle {
Z: Into<Option<f64>>, Z: Into<Option<f64>>,
F: Into<Option<f64>>, F: Into<Option<f64>>,
{ {
let invtran = self.curtran.inverse().unwrap(); let inverse_transform = self.current_transform.inverse().unwrap();
let origcurpos = invtran.transform_point(self.curpos); let original_current_position = inverse_transform.transform_point(self.current_position);
let x = x let x = x
.into() .into()
.map(|x| if abs { x } else { origcurpos.x + x }) .map(|x| if abs { x } else { original_current_position.x + x })
.unwrap_or(origcurpos.x); .unwrap_or(original_current_position.x);
let y = y let y = y
.into() .into()
.map(|y| if abs { y } else { origcurpos.y + y }) .map(|y| if abs { y } else { original_current_position.y + y })
.unwrap_or(origcurpos.y); .unwrap_or(original_current_position.y);
let mut to = point(x, y); let mut to = point(x, y);
to = self.curtran.transform_point(to); to = self.current_transform.transform_point(to);
self.curpos = to; self.current_position = to;
self.prev_ctrl = None; self.previous_control = None;
self.machine self.machine
.tool_on() .tool_on()
@ -172,8 +172,8 @@ impl Turtle {
) -> Vec<Command> { ) -> Vec<Command> {
let z = z.into(); let z = z.into();
let f = f.into(); let f = f.into();
let last_point = std::cell::Cell::new(self.curpos); let last_point = std::cell::Cell::new(self.current_position);
let mut cubic: Vec<Command> = cbs let cubic: Vec<Command> = cbs
.flattened(tolerance) .flattened(tolerance)
.map(|point| { .map(|point| {
last_point.set(point); last_point.set(point);
@ -185,11 +185,11 @@ impl Turtle {
) )
}) })
.collect(); .collect();
self.curpos = last_point.get(); self.current_position = last_point.get();
// See https://www.w3.org/TR/SVG/paths.html#ReflectedControlPoints // See https://www.w3.org/TR/SVG/paths.html#ReflectedControlPoints
self.prev_ctrl = point( self.previous_control = point(
2.0 * self.curpos.x - cbs.ctrl2.x, 2.0 * self.current_position.x - cbs.ctrl2.x,
2.0 * self.curpos.y - cbs.ctrl2.y, 2.0 * self.current_position.y - cbs.ctrl2.y,
) )
.into(); .into();
@ -221,20 +221,20 @@ impl Turtle {
Z: Into<Option<f64>>, Z: Into<Option<f64>>,
F: Into<Option<f64>>, F: Into<Option<f64>>,
{ {
let from = self.curpos; let from = self.current_position;
let mut ctrl1 = point(x1, y1); let mut ctrl1 = point(x1, y1);
let mut ctrl2 = point(x2, y2); let mut ctrl2 = point(x2, y2);
let mut to = point(x, y); let mut to = point(x, y);
if !abs { if !abs {
let invtran = self.curtran.inverse().unwrap(); let inverse_transform = self.current_transform.inverse().unwrap();
let origcurpos = invtran.transform_point(self.curpos); let original_current_position = inverse_transform.transform_point(self.current_position);
ctrl1 += origcurpos.to_vector(); ctrl1 += original_current_position.to_vector();
ctrl2 += origcurpos.to_vector(); ctrl2 += original_current_position.to_vector();
to += origcurpos.to_vector(); to += original_current_position.to_vector();
} }
ctrl1 = self.curtran.transform_point(ctrl1); ctrl1 = self.current_transform.transform_point(ctrl1);
ctrl2 = self.curtran.transform_point(ctrl2); ctrl2 = self.current_transform.transform_point(ctrl2);
to = self.curtran.transform_point(to); to = self.current_transform.transform_point(to);
let cbs = lyon_geom::CubicBezierSegment { let cbs = lyon_geom::CubicBezierSegment {
from, from,
ctrl1, ctrl1,
@ -262,18 +262,18 @@ impl Turtle {
Z: Into<Option<f64>>, Z: Into<Option<f64>>,
F: Into<Option<f64>>, F: Into<Option<f64>>,
{ {
let from = self.curpos; let from = self.current_position;
let ctrl1 = self.prev_ctrl.unwrap_or(self.curpos); let ctrl1 = self.previous_control.unwrap_or(self.current_position);
let mut ctrl2 = point(x2, y2); let mut ctrl2 = point(x2, y2);
let mut to = point(x, y); let mut to = point(x, y);
if !abs { if !abs {
let invtran = self.curtran.inverse().unwrap(); let inverse_transform = self.current_transform.inverse().unwrap();
let origcurpos = invtran.transform_point(self.curpos); let original_current_position = inverse_transform.transform_point(self.current_position);
ctrl2 += origcurpos.to_vector(); ctrl2 += original_current_position.to_vector();
to += origcurpos.to_vector(); to += original_current_position.to_vector();
} }
ctrl2 = self.curtran.transform_point(ctrl2); ctrl2 = self.current_transform.transform_point(ctrl2);
to = self.curtran.transform_point(to); to = self.current_transform.transform_point(to);
let cbs = lyon_geom::CubicBezierSegment { let cbs = lyon_geom::CubicBezierSegment {
from, from,
ctrl1, ctrl1,
@ -299,15 +299,15 @@ impl Turtle {
Z: Into<Option<f64>>, Z: Into<Option<f64>>,
F: Into<Option<f64>>, F: Into<Option<f64>>,
{ {
let from = self.curpos; let from = self.current_position;
let ctrl = self.prev_ctrl.unwrap_or(self.curpos); let ctrl = self.previous_control.unwrap_or(self.current_position);
let mut to = point(x, y); let mut to = point(x, y);
if !abs { if !abs {
let invtran = self.curtran.inverse().unwrap(); let inverse_transform = self.current_transform.inverse().unwrap();
let origcurpos = invtran.transform_point(self.curpos); let original_current_position = inverse_transform.transform_point(self.current_position);
to += origcurpos.to_vector(); to += original_current_position.to_vector();
} }
to = self.curtran.transform_point(to); to = self.current_transform.transform_point(to);
let qbs = QuadraticBezierSegment { from, ctrl, to }; let qbs = QuadraticBezierSegment { from, ctrl, to };
self.bezier(qbs.to_cubic(), tolerance, z, f) self.bezier(qbs.to_cubic(), tolerance, z, f)
@ -330,17 +330,17 @@ impl Turtle {
Z: Into<Option<f64>>, Z: Into<Option<f64>>,
F: Into<Option<f64>>, F: Into<Option<f64>>,
{ {
let from = self.curpos; let from = self.current_position;
let mut ctrl = point(x1, y1); let mut ctrl = point(x1, y1);
let mut to = point(x, y); let mut to = point(x, y);
if !abs { if !abs {
let invtran = self.curtran.inverse().unwrap(); let inverse_transform = self.current_transform.inverse().unwrap();
let origcurpos = invtran.transform_point(self.curpos); let original_current_position = inverse_transform.transform_point(self.current_position);
to += origcurpos.to_vector(); to += original_current_position.to_vector();
ctrl += origcurpos.to_vector(); ctrl += original_current_position.to_vector();
} }
ctrl = self.curtran.transform_point(ctrl); ctrl = self.current_transform.transform_point(ctrl);
to = self.curtran.transform_point(to); to = self.current_transform.transform_point(to);
let qbs = QuadraticBezierSegment { from, ctrl, to }; let qbs = QuadraticBezierSegment { from, ctrl, to };
self.bezier(qbs.to_cubic(), tolerance, z, f) self.bezier(qbs.to_cubic(), tolerance, z, f)
@ -369,18 +369,18 @@ impl Turtle {
let z = z.into(); let z = z.into();
let f = f.into(); let f = f.into();
let from = self.curpos; let from = self.current_position;
let mut to: F64Point = point(x, y); let mut to: F64Point = point(x, y);
to = self.curtran.transform_point(to); to = self.current_transform.transform_point(to);
if !abs { if !abs {
to -= vector(self.curtran.m31, self.curtran.m32); to -= vector(self.current_transform.m31, self.current_transform.m32);
to += self.curpos.to_vector(); to += self.current_position.to_vector();
} }
let mut radii = vector(rx, ry); let mut radii = vector(rx, ry);
radii = self.curtran.transform_vector(radii); radii = self.current_transform.transform_vector(radii);
let sarc = SvgArc { let arc = SvgArc {
from, from,
to, to,
radii, radii,
@ -392,10 +392,10 @@ impl Turtle {
sweep, sweep,
}, },
}; };
let last_point = std::cell::Cell::new(self.curpos); let last_point = std::cell::Cell::new(self.current_position);
let mut ellipse = vec![]; let mut ellipse = vec![];
sarc.for_each_flattened(tolerance, &mut |point: F64Point| { arc.for_each_flattened(tolerance, &mut |point: F64Point| {
ellipse.push(Self::linear_interpolation( ellipse.push(Self::linear_interpolation(
point.x.into(), point.x.into(),
point.y.into(), point.y.into(),
@ -404,8 +404,8 @@ impl Turtle {
)); ));
last_point.set(point); last_point.set(point);
}); });
self.curpos = last_point.get(); self.current_position = last_point.get();
self.prev_ctrl = None; self.previous_control = None;
self.machine self.machine
.tool_on() .tool_on()
@ -420,7 +420,7 @@ impl Turtle {
/// This is useful for handling things like the viewBox /// This is useful for handling things like the viewBox
/// https://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute /// https://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute
pub fn stack_scaling(&mut self, scaling: Transform2D<f64>) { pub fn stack_scaling(&mut self, scaling: Transform2D<f64>) {
self.curtran = self.curtran.post_transform(&scaling); self.current_transform = self.current_transform.post_transform(&scaling);
if let Some(ref current_scaling) = self.scaling { if let Some(ref current_scaling) = self.scaling {
self.scaling = Some(current_scaling.post_transform(&scaling)); self.scaling = Some(current_scaling.post_transform(&scaling));
} else { } else {
@ -432,32 +432,32 @@ impl Turtle {
/// Could be any valid CSS transform https://drafts.csswg.org/css-transforms-1/#typedef-transform-function /// Could be any valid CSS transform https://drafts.csswg.org/css-transforms-1/#typedef-transform-function
/// https://www.w3.org/TR/SVG/coords.html#InterfaceSVGTransform /// https://www.w3.org/TR/SVG/coords.html#InterfaceSVGTransform
pub fn push_transform(&mut self, trans: Transform2D<f64>) { pub fn push_transform(&mut self, trans: Transform2D<f64>) {
self.transtack.push(self.curtran); self.transform_stack.push(self.current_transform);
if let Some(ref scaling) = self.scaling { if let Some(ref scaling) = self.scaling {
self.curtran = self self.current_transform = self
.curtran .current_transform
.post_transform(&scaling.inverse().unwrap()) .post_transform(&scaling.inverse().unwrap())
.pre_transform(&trans) .pre_transform(&trans)
.post_transform(&scaling); .post_transform(&scaling);
} else { } else {
self.curtran = self.curtran.post_transform(&trans); self.current_transform = self.current_transform.post_transform(&trans);
} }
} }
/// Pop a generic transform off the stack, returning to the previous transform state /// Pop a generic transform off the stack, returning to the previous transform state
/// This means that most recent transform went out of scope /// This means that most recent transform went out of scope
pub fn pop_transform(&mut self) { pub fn pop_transform(&mut self) {
self.curtran = self self.current_transform = self
.transtack .transform_stack
.pop() .pop()
.expect("popped when no transforms left"); .expect("popped when no transforms left");
} }
/// Reset the position of the turtle to the origin in the current transform stack /// Reset the position of the turtle to the origin in the current transform stack
pub fn reset(&mut self) { pub fn reset(&mut self) {
self.curpos = point(0.0, 0.0); self.current_position = point(0.0, 0.0);
self.curpos = self.curtran.transform_point(self.curpos); self.current_position = self.current_transform.transform_point(self.current_position);
self.prev_ctrl = None; self.previous_control = None;
self.initpos = self.curpos; self.initial_position = self.current_position;
} }
} }

Loading…
Cancel
Save