$fn=64; // --- Parameters --- columns = 4; rows = 3; // Inside dimensions of a single cell cell_top_width = 38; cell_bottom_width = 25; cell_depth = 50; // Thickness and features wall_thickness = 1.2; lip_height = 2; lip_overhang = 3; drainage_hole_diameter = 6; corner_radius = 3; // --- Calculated Values --- spacing = cell_top_width + wall_thickness; outer_top_w = cell_top_width + wall_thickness * 2; outer_bot_w = cell_bottom_width + wall_thickness * 2; // --- Modules --- module rounded_square(w, r) { offset(r=r) square(w - 2*r, center=true); } module tapered_cell(w_bot, w_top, h, r) { hull() { linear_extrude(0.01) rounded_square(w_bot, r); translate([0, 0, h - 0.01]) linear_extrude(0.01) rounded_square(w_top, r); } } module top_lip() { w_lip = outer_top_w + lip_overhang * 2; r_lip = corner_radius + wall_thickness; translate([0, 0, cell_depth - lip_height]) linear_extrude(lip_height) hull() { translate([0, 0]) rounded_square(w_lip, r_lip); translate([(columns - 1) * spacing, 0]) rounded_square(w_lip, r_lip); translate([0, (rows - 1) * spacing]) rounded_square(w_lip, r_lip); translate([(columns - 1) * spacing, (rows - 1) * spacing]) rounded_square(w_lip, r_lip); } } // --- Main Object --- difference() { // Solid Tray Body union() { // Outer cell bodies for(x = [0 : columns - 1]) { for(y = [0 : rows - 1]) { translate([x * spacing, y * spacing, 0]) tapered_cell(outer_bot_w, outer_top_w, cell_depth, corner_radius + wall_thickness); } } // Top reinforcing lip top_lip(); } // Hollow out cells and add drainage holes for(x = [0 : columns - 1]) { for(y = [0 : rows - 1]) { // Hollow core (shifted up to leave the bottom wall, naturally protrudes out the top) translate([x * spacing, y * spacing, wall_thickness]) tapered_cell(cell_bottom_width, cell_top_width, cell_depth, corner_radius); // Drainage hole translate([x * spacing, y * spacing, -1]) cylinder(d=drainage_hole_diameter, h=wall_thickness + 2); } } }