//
// stress_test_models.scad
// 20260317 ChatGPT
// $Id$
// $HeadURL$
//
// Example command lines:
//
//   openscad -D 'model="cube"'  -o cube_20260317_1335.stl  stress_test_models.scad
//   openscad -D 'model="ybar"'  -o ybar_20260317_1335.stl  stress_test_models.scad
//   openscad -D 'model="tower"' -o tower_20260317_1335.stl stress_test_models.scad
//   openscad -D 'model="all"'   -o all_20260317_1335.stl   stress_test_models.scad
//
// Suggested slicer use:
//
//   1) Print each model as a SEPARATE run.
//   2) For ybar, orient the LONG dimension along the printer's Y axis
//      so the bed moves the long way front-to-back.
//   3) Infill is set in Orca Slicer, not here.
//
// Suggested slicer settings:
//
//   cube:  0.20 layer, 3 perimeters, 20-25% grid or gyroid
//   ybar:  0.20 layer, 3 perimeters, 15-25% grid
//   tower: 0.20 layer, 3 perimeters, 0-10% infill, no brim at first;
//          add brim only if adhesion becomes the issue rather than motion
//

/* [General] */
model = "all";              // [cube,ybar,tower,all]
center_models = false;      // true / false
add_labels = true;          // true / false

/* [Cube Dimensions] */
cube_x = 40;
cube_y = 40;
cube_z = 40;

/* [Y Bar Dimensions] */
ybar_x = 20;
ybar_y = 150;
ybar_z = 50;

/* [Tower Dimensions] */
tower_x = 18;
tower_y = 18;
tower_z = 120;

/* [Edge Treatment] */
corner_radius = 1.2;        // 0 for sharp corners
$fn = 48;

/* [Labeling] */
label_depth = 0.6;
label_size  = 7;
label_font  = "Liberation Sans:style=Bold";

/* [Layout For model="all"] */
gap_between_models = 20;


// --------------------------------------------------
// Main
// --------------------------------------------------

if (model == "cube") {
    make_cube();
}
else if (model == "ybar") {
    make_ybar();
}
else if (model == "tower") {
    make_tower();
}
else if (model == "all") {
    make_all();
}
else {
    echo("ERROR: model must be one of: cube, ybar, tower, all");
}


// --------------------------------------------------
// Assemblies
// --------------------------------------------------

module make_all() {
    x0 = 0;
    x1 = x0 + cube_x + gap_between_models;
    x2 = x1 + ybar_x + gap_between_models;

    translate([x0, 0, 0]) make_cube();
    translate([x1, 0, 0]) make_ybar();
    translate([x2, 0, 0]) make_tower();
}


module make_cube() {
    difference() {
        rounded_box(cube_x, cube_y, cube_z, corner_radius, center_models);
        if (add_labels)
            place_top_label("CUBE", cube_x, cube_y, cube_z, center_models);
    }
}


module make_ybar() {
    difference() {
        rounded_box(ybar_x, ybar_y, ybar_z, corner_radius, center_models);
        if (add_labels)
            place_top_label("YBAR", ybar_x, ybar_y, ybar_z, center_models);
    }
}


module make_tower() {
    difference() {
        rounded_box(tower_x, tower_y, tower_z, corner_radius, center_models);
        if (add_labels)
            place_top_label("TOWER", tower_x, tower_y, tower_z, center_models);
    }
}


// --------------------------------------------------
// Geometry helpers
// --------------------------------------------------

module rounded_box(x, y, z, r=0, center_it=false) {
    if (r <= 0) {
        cube([x, y, z], center=center_it);
    } else {
        if (center_it) {
            translate([-x/2, -y/2, -z/2])
                rounded_box_uncentered(x, y, z, r);
        } else {
            rounded_box_uncentered(x, y, z, r);
        }
    }
}


module rounded_box_uncentered(x, y, z, r) {
    linear_extrude(height=z)
        offset(r=r)
            offset(delta=-r)
                square([x, y], center=false);
}

module place_top_label(txt, x, y, z, center_it=false) {

    // --- parameters ---
    margin = 2;  // mm clearance from edges

    // usable space
    usable_x = x - margin;
    usable_y = y - margin;

    // choose orientation: run along long axis
    rotate_text = (y > x);

    // limiting width after orientation
    limit = rotate_text ? usable_y : usable_x;

    // crude text width estimate factor (~0.6 * size * chars)
    est_char_width = 1.0;
    est_len = len(txt) * est_char_width;

    // compute size that fits
    auto_size = limit / est_len;

    // clamp to your preferred max size
    final_size = min(label_size, auto_size);

    // placement
    tx = center_it ? 0 : x/2;
    ty = center_it ? 0 : y/2;
    tz = center_it ? z/2 : z;

    translate([tx, ty, tz - label_depth])
        rotate([0, 0, rotate_text ? 90 : 0])
            linear_extrude(height=label_depth + 0.02)
                text(
                    txt,
                    size=final_size,
                    font=label_font,
                    halign="center",
                    valign="center"
                );
}
module place_top_labelOLD(txt, x, y, z, center_it=false) {
    tx = center_it ? 0 : x/2;
    ty = center_it ? 0 : y/2;
    tz = center_it ? z/2 : z;

    translate([tx, ty, tz - label_depth])
        linear_extrude(height=label_depth + 0.02)
            text(
                txt,
                size=label_size,
                font=label_font,
                halign="center",
                valign="center"
            );
}
