$fn=64; // --- Parameters --- cols = 4; // Number of cell columns rows = 3; // Number of cell rows cell_size = 35; // Inner size of each square cell (mm) cell_h = 40; // Height of the cells (mm) res_h = 15; // Height of the bottom water reservoir (mm) wall = 1.6; // Wall thickness (mm) drain_d = 6; // Diameter of drainage holes (mm) lid_h = 50; // Height of the humidity lid (mm) clearance = 0.6; // Clearance for the lid to fit over the base (mm) // --- Calculated Dimensions --- W = cols * cell_size + (cols + 1) * wall; D = rows * cell_size + (rows + 1) * wall; H = cell_h + res_h; lid_W = W + 2 * clearance; lid_D = D + 2 * clearance; // --- Main Layout --- // Base unit base(); // Lid (rotated 180 degrees to print flat without supports) translate([0, D + 20 + lid_D + 2 * wall, lid_h]) rotate([180, 0, 0]) lid(); // --- Modules --- module base() { union() { // Main body and reservoir difference() { cube([W, D, H]); // Hollow out the entire inside translate([wall, wall, wall]) cube([W - 2 * wall, D - 2 * wall, H]); } // False bottom (floor of the cells) difference() { translate([wall, wall, res_h]) cube([W - 2 * wall, D - 2 * wall, wall]); // Drainage holes for(c = [0 : cols - 1]) { for(r = [0 : rows - 1]) { cx = wall + c * (cell_size + wall) + cell_size / 2; cy = wall + r * (cell_size + wall) + cell_size / 2; translate([cx, cy, res_h - 1]) cylinder(d=drain_d, h=wall + 2); } } } // Internal cell grid (X-axis walls) for(c = [1 : cols - 1]) { translate([c * (cell_size + wall), wall, res_h]) cube([wall, D - 2 * wall, cell_h]); } // Internal cell grid (Y-axis walls) for(r = [1 : rows - 1]) { translate([wall, r * (cell_size + wall), res_h]) cube([W - 2 * wall, wall, cell_h]); } // Pot rings (support under cells directing water to reservoir) for(c = [0 : cols - 1]) { for(r = [0 : rows - 1]) { cx = wall + c * (cell_size + wall) + cell_size / 2; cy = wall + r * (cell_size + wall) + cell_size / 2; difference() { // Ring body translate([cx, cy, wall]) cylinder(d=drain_d + 8, h=res_h - wall); // Inner hole translate([cx, cy, wall - 1]) cylinder(d=drain_d + 2, h=res_h + 2); // Water escape slots at the base of the ring translate([cx, cy, wall + 2]) cube([drain_d + 10, 2.5, 6], center=true); translate([cx, cy, wall + 2]) cube([2.5, drain_d + 10, 6], center=true); } } } // Outer lip for the lid to rest upon translate([0, 0, H - 10]) difference() { translate([-(clearance + wall), -(clearance + wall), 0]) cube([W + 2 * (clearance + wall), D + 2 * (clearance + wall), wall]); translate([-0.1, -0.1, -0.1]) cube([W + 0.2, D + 0.2, wall + 0.2]); } } } module lid() { difference() { // Outer shell cube([lid_W + 2 * wall, lid_D + 2 * wall, lid_h]); // Inner hollow translate([wall, wall, -1]) cube([lid_W, lid_D, lid_h - wall + 1]); // Top ventilation holes for(cx = [lid_W / 3, lid_W * 2 / 3]) { for(cy = [lid_D / 3, lid_D * 2 / 3]) { translate([cx + wall, cy + wall, lid_h - wall - 1]) cylinder(d=8, h=wall + 2); } } } }