///|
/// 17-living-hinge-sample
///
/// A working example that generates a STEP model for a living hinge sample.
///
/// Usage (stdout):
/// moon run --target native examples/17-living-hinge-sample -- --thickness 2 > hinge.step
async fn main {
let base_args_spec = {
"plateLength": @cli.opt_double(
30.0,
help="Length of the solid plates on either side (mm)",
min=1.0,
),
"width": @cli.opt_double(
50.0,
help="Total width of the hinge (mm)",
min=1.0,
),
"thickness": @cli.opt_double(2.0, help="Material thickness (mm)", min=0.1),
"hingeWidth": @cli.opt_double(
20.0,
help="Width of the slotted hinge section (mm)",
min=1.0,
),
"slotWidth": @cli.opt_double(1.0, help="Width of each slot (mm)", min=0.1),
"slotLength": @cli.opt_double(
10.0,
help="Length of each slot (mm)",
min=1.0,
),
"numRows": @cli.opt_double(7.0, help="Number of rows of slots", min=1.0),
}
let args_spec = @cli.with_translate(@common.with_output_args(base_args_spec))
guard @cli.parse(
args_spec,
prog="17-living-hinge-sample",
description="Generate a living hinge sample STEP model.",
)
is Some(args) else {
return
}
let plate_length = args.double("plateLength")
let width = args.double("width")
let thickness = args.double("thickness")
let hinge_width = args.double("hingeWidth")
let slot_width = args.double("slotWidth")
let slot_length = args.double("slotLength")
let num_rows = args.double("numRows").to_int()
let output = @common.output_paths(args)
let (tx, ty, tz) = match args.translate_xyz() {
Some(v) => v
None => {
@cli.eprintln("error: invalid translation")
return
}
}
let hinge = living_hinge(
plate_length, width, thickness, hinge_width, slot_width, slot_length, num_rows,
)
.with_name("living-hinge")
.with_color(@cad.Rgb::purple())
.translate(x=tx, y=ty, z=tz)
let design = @cad.Design::new(
name="living-hinge-sample",
documentation=args.documentation(),
).add(hinge)
@common.write_output(design, output)
}
///|
fn living_hinge(
plate_length : Double,
total_width : Double,
thickness : Double,
hinge_width : Double,
slot_width : Double,
slot_length : Double,
num_rows : Int32,
) -> @cad.Shape {
let total_length = 2.0 * plate_length + hinge_width
let outer = @cad.Profile2D::rect(total_length, total_width)
let holes = []
let row_spacing = hinge_width / Double::from_int(num_rows + 1)
for i in 0.. total_width - padding {
total_width - padding
} else {
current_y + slot_length
}
if y_end - y_start > 1.0 { // Minimum slot length
let sw = slot_width
let hole = [
(row_x - sw / 2.0, y_start),
(row_x + sw / 2.0, y_start),
(row_x + sw / 2.0, y_end),
(row_x - sw / 2.0, y_end),
].rev()
holes.push(hole)
}
current_y = current_y + spacing_y
}
}
@cad.ExtrudedProfile::new(outer, thickness, holes~)
}