///|
/// 13-o-ring-groove-gauge
///
/// A parametric gauge for verifying O-ring groove dimensions.
/// Contains several standard groove sizes based on AS568 cross-sections.
///
/// Usage (stdout):
/// moon run --target native examples/13-o-ring-groove-gauge -- > gauge.step
///
/// Usage (write file):
/// moon run --target native examples/13-o-ring-groove-gauge -- -o gauge.step
async fn main {
let base_args_spec = {
"length": @cli.opt_double(
80.0,
help="Length of the gauge block (mm)",
min=10.0,
),
"width": @cli.opt_double(
60.0,
help="Width of the gauge block (mm)",
min=10.0,
),
"height": @cli.opt_double(
10.0,
help="Height of the gauge block (mm)",
min=5.0,
),
}
let args_spec = @cli.with_translate(@common.with_output_args(base_args_spec))
guard @cli.parse(
args_spec,
prog="13-o-ring-groove-gauge",
description="Generate a parametric O-ring groove gauge.",
)
is Some(args) else {
return
}
let block_length = args.double("length")
let block_width = args.double("width")
let notched_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("")
}
}
// Standard AS568 O-ring cross-sections and typical groove dimensions
// (cross_section, groove_width, groove_depth)
let standards = [
(1.78, 2.4, 1.4),
(2.62, 3.6, 2.25),
(3.53, 4.8, 3.1),
(5.33, 7.1, 4.75),
(6.99, 9.5, 6.25),
]
// Calculate notch positions by distributing remaining space as equal walls.
let mut total_groove_width = 0.0
for s in standards {
total_groove_width += s.1
}
let total_wall_width = block_width - total_groove_width
let wall_count = standards.length() + 1
let wall_size = total_wall_width / Double::from_int(wall_count)
if wall_size < 1.0 {
@cli.eprintln(
"error: block width (\{block_width}) is too small for these grooves (min wall 1.0mm)",
)
abort("")
}
let notches = []
let mut current_x = wall_size
for i in 0.. World -X (centered)
// Local Y (Height) -> World Z
// Local Z (Length) -> World Y
let gauge = notched_block(block_width, block_length, notched_height, notches)
.with_name("gauge-notches")
.with_color(@cad.Rgb::orange())
.rotate_x(90.0)
.rotate_z(180.0)
.translate(x=tx, y=ty, z=tz)
//
let design = @cad.Design::new(
name="o-ring-groove-gauge",
documentation=args.documentation(),
).add(gauge)
@common.write_output(design, output)
}
///|
fn notched_block(
width : Double,
length : Double,
height : Double,
notches : Array[(Double, Double, Double)],
) -> @cad.Shape {
let hw = width / 2.0
let pts = [(0.0, 0.0), (width, 0.0), (width, height)]
// Sort notches by X offset descending to process from right to left (maintaining CCW)
let sorted_notches = notches.copy()
sorted_notches.sort_by(fn(a, b) { b.0.compare(a.0) })
for notch in sorted_notches {
let (x, w, d) = notch
if x + w < width {
pts.push((x + w, height))
}
pts.push((x + w, height - d))
pts.push((x, height - d))
pts.push((x, height))
}
if pts[pts.length() - 1].0 > 0.0 {
pts.push((0.0, height))
}
let centered_profile = pts.map(fn(p) { (p.0 - hw, p.1) })
@cad.ExtrudedProfile::new(centered_profile, length)
}