///|
/// 14-bolt-length-gauge
///
/// A physical "ruler" for bolts that includes embossed size markings and
/// 5 mm/10 mm scribed tick marks on the top face.
///
/// Usage (stdout):
/// moon run --target native examples/14-bolt-length-gauge -- > gauge.step
///
/// Usage (write file):
/// moon run --target native examples/14-bolt-length-gauge -- -o gauge.step
async fn main {
let base_args_spec = {
"length": @cli.opt_double(100.0, help="Length of the gauge (mm)", min=50.0),
"width": @cli.opt_double(50.0, help="Width of the gauge (mm)", min=20.0),
"height": @cli.opt_double(10.0, help="Height of the gauge (mm)", min=5.0),
}
let args_spec = @cli.with_translate(@common.with_output_args(base_args_spec))
guard @cli.parse(
args_spec,
prog="14-bolt-length-gauge",
description="Generate a bolt length gauge.",
)
is Some(args) else {
return
}
let length = args.double("length")
let width = args.double("width")
let height = args.double("height")
let output = @common.output_paths(args)
let (tx, ty, tz) = match args.translate_xyz() {
Some(v) => v
None => {
@cli.eprintln("error: invalid translation")
abort("")
}
}
//
let bolt_sizes = [
("M3", 3.4),
("M4", 4.4),
("M5", 5.4),
("M6", 6.4),
("M8", 8.4),
]
let slot_width = 10.0
let font = @cad.load_font("baloo")
let scribe_depth = 0.5
let scribe_width = 0.8
// 1. Through-holes shared by both layers (ruler slot and bolt holes).
let through_holes = []
// Ruler slot (as a through-hole)
let slot_poly = [
(-slot_width / 2.0, 5.0),
(slot_width / 2.0, 5.0),
(slot_width / 2.0, length - 5.0),
(-slot_width / 2.0, length - 5.0),
].rev() // must be CW
through_holes.push(slot_poly)
// Bolt holes
let hole_spacing = length / Double::from_int(bolt_sizes.length() + 1)
for i in 0.. length - 2.0 {
continue
}
let major = i % 2 == 0
let len = if major { major_len } else { minor_len }
if len <= 0.5 {
continue
}
let x1 = tick_x0 + len
scribe_holes.push(
[
(tick_x0, y - scribe_width / 2.0),
(x1, y - scribe_width / 2.0),
(x1, y + scribe_width / 2.0),
(tick_x0, y + scribe_width / 2.0),
].rev(),
)
}
// 3. Lower slab plus a thin marking layer. The scribe slots are holes in the
// marking layer only, so the marks are shallow face notches, not cut-outs.
let outer = @cad.Profile2D::rect(width, length).map(fn(p) {
(p.0 - width / 2.0, p.1)
})
let lower = @cad.ExtrudedProfile::new(
outer,
height - scribe_depth,
holes=through_holes,
)
.with_name("gauge-base")
.with_color(@cad.Rgb::purple())
let top_holes = through_holes.copy()
top_holes.push_iter(scribe_holes.iter())
let top = @cad.ExtrudedProfile::new(outer, scribe_depth, holes=top_holes)
.with_name("gauge-marking-face")
.with_color(@cad.Rgb::purple())
.translate(z=height - scribe_depth)
let mut design = @cad.Design::new(
name="bolt-length-gauge",
documentation=args.documentation(),
)
.add(lower)
.add(top)
// 4. Add labels
for i in 0..