$fn=64; // --- Parameters --- tray_length = 180; // Overall length of the tray tray_width = 140; // Overall width of the tray tray_height = 35; // Overall height of the walls to contain dice wall_thickness = 4; // Thickness of the outer walls base_thickness = 3; // Thickness of the bottom base (flat for felt application) corner_radius = 20; // Radius of the tray corners // --- Modules --- module rounded_box(length, width, height, radius) { hull() { translate([-length/2 + radius, -width/2 + radius, 0]) cylinder(r=radius, h=height); translate([length/2 - radius, -width/2 + radius, 0]) cylinder(r=radius, h=height); translate([-length/2 + radius, width/2 - radius, 0]) cylinder(r=radius, h=height); translate([length/2 - radius, width/2 - radius, 0]) cylinder(r=radius, h=height); } } // --- Main Geometry --- difference() { // Outer body rounded_box(tray_length, tray_width, tray_height, corner_radius); // Inner hollowed area for rolling // Z is translated up by base_thickness to create the flat floor // Height is extended slightly to ensure a clean cutout at the top translate([0, 0, base_thickness]) rounded_box( tray_length - (wall_thickness * 2), tray_width - (wall_thickness * 2), tray_height, // Extends past the top max(1, corner_radius - wall_thickness) // Maintain uniform wall thickness ); }