diff --git a/enclosure/box.scad b/enclosure/box.scad new file mode 100644 index 0000000..8e3525d --- /dev/null +++ b/enclosure/box.scad @@ -0,0 +1,179 @@ +// 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(); diff --git a/enclosure/cutouts.scad b/enclosure/cutouts.scad new file mode 100644 index 0000000..de79329 --- /dev/null +++ b/enclosure/cutouts.scad @@ -0,0 +1,2 @@ +// The cutouts to allow external components (such as buttons and connectors) to be mounted on the box + diff --git a/enclosure/fabula_enclosure.scad b/enclosure/fabula_enclosure.scad index 4bf0392..a6b0d7c 100644 --- a/enclosure/fabula_enclosure.scad +++ b/enclosure/fabula_enclosure.scad @@ -1,180 +1,18 @@ +use +use +use + // FABULA open source storyteller enclosure // TODO: open hardware logo, Fabula logo, cutouts for components and buttons, tag slot with led 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); +module fabula_enclosure_bottom() { + cap(); } -// 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); - } +module fabula_enclosure_top() { + box(); } - -// 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(); +translate([0, -60, 0]) rotate([180, 0, 0]) fabula_enclosure_bottom(); +translate([0, 60, 0]) fabula_enclosure_top(); diff --git a/enclosure/supports.scad b/enclosure/supports.scad new file mode 100644 index 0000000..1a4bc55 --- /dev/null +++ b/enclosure/supports.scad @@ -0,0 +1,8 @@ +// Supports to mount internal components in the box + +module supports_speaker() { + difference() { + cylinder(d = 84, h = 2); + cylinder(d = 80, h = 2); + } +} diff --git a/enclosure/test_fit.scad b/enclosure/test_fit.scad index 47864af..5ec7daf 100644 --- a/enclosure/test_fit.scad +++ b/enclosure/test_fit.scad @@ -16,5 +16,4 @@ module test_fit_components() { } test_fit_components(); -//#closed_box(); -translate([0, 0, 20]) rotate([0, 0, -90]) #box(); \ No newline at end of file +translate([0, 0, 20]) rotate([0, 0, -90]) #fabula_enclosure_bottom(); \ No newline at end of file