/*
    FireFly tetrahedron adapter
    Base STL: tetrahedron40mmC.stl

    Purpose:
    - Import original 40 mm foldable tetrahedron STL
    - Scale it to 60 mm base geometry
    - Add cable holes, vent/drain holes, and optional PCB mounting holes

    Workflow:
    1. Set PART = "upper"
    2. Render with F6
    3. Export STL
    4. Set PART = "lower"
    5. Render with F6
    6. Export STL

    Notes:
    - Hole coordinates are defined on the original 40 mm STL coordinate system.
    - The script scales them automatically to 60 mm.
    - First export should be treated as v0.1 prototype.
*/


/* =========================
   Main selection
   ========================= */

PART = "upper";          // "upper", "lower", or "both_preview"


/* =========================
   Input file
   ========================= */

input_stl = "tetrahedron40mmC.stl";


/* =========================
   Scaling
   ========================= */

// Original tetrahedron edge length
original_edge_mm = 40;

// Target mechanical base size
target_edge_mm = 60;

// XY scale from 40 mm to 60 mm
scale_xy = target_edge_mm / original_edge_mm;   // 1.5

// Keep original thickness.
// Set to 1.2 or 1.3 if you want a slightly thicker part.
scale_z = 1.0;


/* =========================
   General hole settings
   ========================= */

hole_fn = 40;
cut_height = 20;


/* =========================
   Feature switches
   ========================= */

add_upper_cable_holes = true;
add_upper_hanger_hole = true;

add_lower_vent_holes = true;
add_lower_cable_holes = true;
add_lower_pcb_mount_holes = true;

// Keep this false for the first prototype.
// Standoffs may interfere with folding depending on print orientation.
add_lower_pcb_standoffs = false;


/* =========================
   Hole sizes
   ========================= */

cable_hole_d = 3.2;          // for small solar-panel wires
hanger_hole_d = 3.5;         // for small ring / wire / eyelet
vent_hole_d = 2.0;           // condensation vent / drain holes
pcb_screw_hole_d = 2.2;      // M2 clearance-ish
pcb_standoff_d = 6.0;
pcb_standoff_h = 3.0;


/* =========================
   Coordinate reference
   =========================

   The uploaded STL is approximately:

   X: -34.64 to +34.64
   Y: -20.00 to +60.00
   Z:  -0.10 to  +2.00

   The original model is a flat foldable tetrahedron net.
   Coordinates below are before scaling.
*/


/* =========================
   Upper part hole positions
   ========================= */

// Cable holes for three solar panels.
// Adjust after checking where your real panel wires exit.
upper_cable_points = [
    [-18, 20],
    [ 24,  7],
    [ 24, 33]
];

// Optional hanger hole close to one upper fold/vertex area.
// If this weakens the corner too much, disable it and use an external loop instead.
upper_hanger_points = [
    [0, 38]
];


/* =========================
   Lower part hole positions
   ========================= */

// Cable transfer holes between upper solar section and lower electronics bay.
lower_cable_points = [
    [-10, 20],
    [ 12, 13],
    [ 12, 27]
];

// Small vent/drain hole clusters near likely lower/edge areas.
// These are deliberately small.
lower_vent_centres = [
    [  0,  3],
    [  0, 37],
    [-30, 20],
    [ 31, 20]
];

// Approximate triangular PCB mounting pattern.
// Tune this after measuring your actual red triangle PCB.
lower_pcb_mount_points = [
    [  0,  8],
    [ 25, 20],
    [  0, 32]
];


/* =========================
   Basic modules
   ========================= */

module base_import_scaled()
{
    scale([scale_xy, scale_xy, scale_z])
        import(input_stl, convexity = 10);
}


module vertical_hole(p, d)
{
    translate([p[0] * scale_xy, p[1] * scale_xy, 1])
        cylinder(h = cut_height, d = d, center = true, $fn = hole_fn);
}


module vent_cluster(p)
{
    // Small 2 x 3 vent/drain pattern.
    // Pitch is in final millimetres, not original model coordinates.
    pitch = 3.0;

    for (ix = [-1, 0, 1])
        for (iy = [0, 1])
            translate([
                p[0] * scale_xy + ix * pitch,
                p[1] * scale_xy + iy * pitch,
                1
            ])
                cylinder(h = cut_height, d = vent_hole_d, center = true, $fn = hole_fn);
}


module pcb_standoff(p)
{
    // Standoff added on top of the flat STL.
    // Use only if you confirm it does not block folding.
    translate([p[0] * scale_xy, p[1] * scale_xy, 2.1 * scale_z])
        cylinder(h = pcb_standoff_h, d = pcb_standoff_d, center = false, $fn = hole_fn);
}


/* =========================
   Upper tetrahedron
   ========================= */

module upper_part()
{
    difference()
    {
        base_import_scaled();

        if (add_upper_cable_holes)
        {
            for (p = upper_cable_points)
                vertical_hole(p, cable_hole_d);
        }

        if (add_upper_hanger_hole)
        {
            for (p = upper_hanger_points)
                vertical_hole(p, hanger_hole_d);
        }
    }
}


/* =========================
   Lower tetrahedron
   ========================= */

module lower_part()
{
    difference()
    {
        union()
        {
            base_import_scaled();

            if (add_lower_pcb_standoffs)
            {
                for (p = lower_pcb_mount_points)
                    pcb_standoff(p);
            }
        }

        if (add_lower_cable_holes)
        {
            for (p = lower_cable_points)
                vertical_hole(p, cable_hole_d);
        }

        if (add_lower_vent_holes)
        {
            for (p = lower_vent_centres)
                vent_cluster(p);
        }

        if (add_lower_pcb_mount_holes)
        {
            for (p = lower_pcb_mount_points)
                vertical_hole(p, pcb_screw_hole_d);
        }
    }
}


/* =========================
   Output
   ========================= */

if (PART == "upper")
{
    upper_part();
}
else if (PART == "lower")
{
    lower_part();
}
else if (PART == "both_preview")
{
    translate([-80, 0, 0])
        upper_part();

    translate([80, 0, 0])
        lower_part();
}
else
{
    echo("Invalid PART setting. Use upper, lower, or both_preview.");
}
