// Defines the box for the Fabula Open Source storyteller. // This is the box, without any cutout nor electronics components mount. // Global dimensions, change here width = 180; height = 90; depth = 40; screw_diameter = 3; // Internal global variables rounded_edge_diameter = height; box_cut_height = 10; flange_height = 3; standoff_diameter=screw_diameter*3; // Screw standoff module standoff() { cylinder(h = depth, d = standoff_diameter, center = true); } // Screw hole, to be subtracted from standoff and box module screw_hole() { // Hole where the screw will thread into cylinder(h = depth - 2, d = screw_diameter, center = true); // Hole where the screw will pass with slack, without threading (in the lid) translate([0, 0, depth/2 - box_cut_height/2]) { cylinder(h = box_cut_height + 12, d = screw_diameter*1.5, center = true); } // Screw head bevel bevel_depth = 1; translate([0, 0, depth/2 - bevel_depth/2 + 6]) { cylinder(h = bevel_depth, d2 = screw_diameter * 2.5, d1 = screw_diameter*1.5, center = true); } } // Main body module main_body() { module half_body() { cube([width - rounded_edge_diameter/2, height/2, depth]); cylinder(h = depth, d = rounded_edge_diameter, $fn=256); } union() { translate([-(width - rounded_edge_diameter)/2, 0, -depth/2]) { half_body(); } translate([(width - rounded_edge_diameter)/2, 0, -depth/2]) { mirror([1, 0, 0]) { mirror([0, 1, 0]) { half_body(); } } } } } // Closed Box module closed_box() { difference() { union() { // Hollow box difference() { // Round all edges to avoid danger for the children minkowski() { $fn = 64; main_body(); sphere(6); } main_body(); } // Screws standoffs near curved edges translate([width/2 - rounded_edge_diameter/2, -height/2, 0]) { standoff(); } translate([-width/2 + rounded_edge_diameter/2, height/2, 0]) { standoff(); } // Screws standoff near sharp edges translate([-width/2 + standoff_diameter/2, -height/2, 0]) { standoff(); } translate([width/2 - standoff_diameter/2, height/2, 0]) { standoff(); } } // Screw holes near curved edges translate([width/2 - rounded_edge_diameter/2, -height/2, 0]) { screw_hole(); } translate([-width/2 + rounded_edge_diameter/2, height/2, 0]) { screw_hole(); } // Screws holes near sharp edges translate([-width/2 + standoff_diameter/2, -height/2, 0]) { screw_hole(); } translate([width/2 - standoff_diameter/2, height/2, 0]) { screw_hole(); } } } // Lower box module box() { difference() { closed_box(); translate([0, 0, depth - box_cut_height]) { cube([width*2, height*2, depth], true); } } } // Upper cap lip module lip() { // Lip support translate([0, 0, box_cut_height + 5]) { intersection() { difference() { main_body(); scale([0.95, 0.95, 0.95]) main_body(); } cube([width*2, height*2, box_cut_height], true); } } // Chamfered lip difference() { for (i = [0:10]) { translate([0, 0, box_cut_height - i * 0.5]) { intersection() { difference() { scale_ratio = 1 - i * 0.001; scale([scale_ratio, scale_ratio, scale_ratio]) { main_body(); } scale([0.95, 0.95, 0.95]) main_body(); } cube([width*2, height*2, 0.5], true); } } } // Leave space for screws standoffs near curved edges translate([width/2 - rounded_edge_diameter/2, -height/2, 0]) { scale([1.2, 1.2, 1]) standoff(); } translate([-width/2 + rounded_edge_diameter/2, height/2, 0]) { scale([1.2, 1.2, 1]) standoff(); } // Leave space for screws standoff near sharp edges translate([-width/2 + standoff_diameter/2, -height/2, 0]) { scale([1.2, 1.2, 1]) standoff(); } translate([width/2 - standoff_diameter/2, height/2, 0]) { scale([1.2, 1.2, 1]) standoff(); } } } // Upper cap module cap() { difference() { closed_box(); translate([0, 0, - box_cut_height]) { cube([width*2, height*2, depth], true); } } lip(); } translate([0, -60, 0]) box(); translate([0, 60, 0]) rotate([180, 0, 0]) cap();