Compare commits
18 Commits
9e771b3125
...
d1055841fa
| Author | SHA1 | Date | |
|---|---|---|---|
| d1055841fa | |||
| 950cf6a2fd | |||
| 4e3dba66ec | |||
| 70ef92b45c | |||
| 510ccffa0d | |||
| 537e61d97b | |||
| 00b3272abe | |||
| 22a2b276f5 | |||
| 330998483a | |||
| be16bda8ee | |||
| 77daf344b7 | |||
| 0a44ab7907 | |||
| 58f789e1b9 | |||
| 09c532b234 | |||
| b71f1d2295 | |||
| 78bd6b9738 | |||
| 49ac2aa5f1 | |||
| aa7725adef |
@@ -0,0 +1,3 @@
|
||||
[submodule "lib/threads"]
|
||||
path = lib/threads
|
||||
url = git@github.com:rcolyer/threads-scad.git
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,637 @@
|
||||
include <../lib/chamfered-cube.scad>
|
||||
include <../lib/rounded-cube.scad>
|
||||
|
||||
// All units in mm
|
||||
$fn=128;
|
||||
outerWall=4;
|
||||
innerWall=2;
|
||||
layerClearance = 0.5;
|
||||
verStr="v12";
|
||||
font="Montserrat";
|
||||
ep = 0.01; // smallest unit to ensure overlap between shapes
|
||||
|
||||
// as a convention, outer dimensions refer to measurements from outside wall to
|
||||
// outside wall, as if you put a caliper around the whole thing. Inner
|
||||
// dimesions refers to inside or void dimensions: the space available to be
|
||||
// filled.
|
||||
layer1H = 44;
|
||||
layer2H = 40;
|
||||
|
||||
outerBoxLength = 300;
|
||||
outerBoxWidth = 154;
|
||||
outerBoxHeight = layer1H + layer2H + 2*outerWall;
|
||||
|
||||
innerBoxLength = outerBoxLength - 2*outerWall;
|
||||
innerBoxWidth = outerBoxWidth - 2*outerWall;
|
||||
|
||||
audioTraySide = 64;
|
||||
audioTrayHeight = 15;
|
||||
audioTrayIS = audioTraySide - 2*innerWall;
|
||||
audioTrayIH = audioTrayHeight - innerWall;
|
||||
|
||||
|
||||
module shellBottom(dims) {
|
||||
lipClearance = innerWall + 0.2;
|
||||
bottomShellH = dims[2]*0.75;
|
||||
difference() {
|
||||
union() {
|
||||
difference() {
|
||||
// main body
|
||||
chamferedCube(dims,
|
||||
chamfer=4);
|
||||
|
||||
// top-cut (75% up)
|
||||
translate([-outerWall, -outerWall, bottomShellH])
|
||||
cube([dims[0] + 2*outerWall, dims[1] + 2*outerWall, dims[2]]);
|
||||
}
|
||||
|
||||
// add lip to mate with top
|
||||
translate([lipClearance, lipClearance, bottomShellH - 2])
|
||||
chamferedCube(
|
||||
[dims[0] - 2*lipClearance, dims[1] - 2*lipClearance, 6 - 1],
|
||||
chamfer=1);
|
||||
}
|
||||
|
||||
// carve out the interior
|
||||
translate([outerWall, outerWall, outerWall])
|
||||
cube([dims[0] - 2*outerWall, dims[1] - 2*outerWall, dims[2]]);
|
||||
|
||||
// carve out a 0.6mm sliver for the fabric to sit in
|
||||
/*
|
||||
fabricClearance = 0.6;
|
||||
translate([
|
||||
lipClearance - fabricClearance,
|
||||
lipClearance - fabricClearance,
|
||||
bottomShellH - 4])
|
||||
difference() {
|
||||
roundedCube(
|
||||
[ dims[0] - 2*lipClearance + 2*fabricClearance,
|
||||
dims[1] - 2*lipClearance + 2*fabricClearance,
|
||||
7],
|
||||
[2, 2, 0]);
|
||||
|
||||
translate([fabricClearance, fabricClearance, -ep])
|
||||
roundedCube(
|
||||
[dims[0] - 2*lipClearance, dims[1] - 2*lipClearance, 8],
|
||||
[2, 2, 0]);
|
||||
}
|
||||
*/
|
||||
|
||||
// ropeway
|
||||
for (i = [1, 3]) {
|
||||
for (j = [-1, 1]) {
|
||||
/* Older, diagonal cut
|
||||
translate([dims[0]/2 - j*dims[0]/2 + j*1.5, i*dims[1]/4, -1])
|
||||
rotate([0, 0, 45 + 90*j])
|
||||
cube([4, 4, bottomShellH + 8]);
|
||||
*/
|
||||
translate([dims[0]/2 - j*dims[0]/2 - 1.5, i*dims[1]/4 - 2.5, -1])
|
||||
chamferedCube([3, 5, bottomShellH + 8], chamfer=1.5);
|
||||
}
|
||||
|
||||
/* Older, diagonal cut
|
||||
translate([-1, i*dims[1]/4, 1.5])
|
||||
rotate([-135, 0, 0])
|
||||
cube([dims[0] + 8, 4, 4]);
|
||||
*/
|
||||
translate([-1, i*dims[1]/4 - 2.5, -1.5])
|
||||
chamferedCube([dims[0] + 8, 5, 3], chamfer=1.5);
|
||||
}
|
||||
|
||||
// version marker
|
||||
color("black")
|
||||
translate([0.6, 26, 8]) rotate([90, 0,-90])
|
||||
linear_extrude(0.61) text(text = verStr, font = font, size = 8);
|
||||
}
|
||||
}
|
||||
|
||||
module shellTop(dims) {
|
||||
topShellH = dims[2]*0.25;
|
||||
difference() {
|
||||
union() {
|
||||
difference() {
|
||||
// main body
|
||||
chamferedCube(dims,
|
||||
chamfer=4);
|
||||
|
||||
// top-cut (75% up)
|
||||
translate([-outerWall, -outerWall, topShellH + 4])
|
||||
cube([dims[0] + 2*outerWall, dims[1] + 2*outerWall, dims[2]]);
|
||||
}
|
||||
}
|
||||
|
||||
// carve out the interior
|
||||
translate([outerWall, outerWall, outerWall])
|
||||
cube([dims[0] - 2*outerWall, dims[1] - 2*outerWall, dims[2]]);
|
||||
|
||||
// carve out the interior of the lip
|
||||
translate([innerWall - 0.2, innerWall - 0.2, topShellH])
|
||||
chamferedCube(
|
||||
[dims[0] - 2*innerWall + 0.4, dims[1] - 2*innerWall + 0.4, dims[2]],
|
||||
chamfer = 2);
|
||||
|
||||
/*
|
||||
// carve out a 0.6mm sliver for the fabric to sit in
|
||||
fabricClearance = 0.6;
|
||||
translate([
|
||||
layerClearance,
|
||||
layerClearance,
|
||||
topShellH - 4])
|
||||
difference() {
|
||||
roundedCube(
|
||||
[ dims[0] - 2*layerClearance,
|
||||
dims[1] - 2*layerClearance,
|
||||
7],
|
||||
[2, 2, 0]);
|
||||
|
||||
translate([fabricClearance, fabricClearance, -ep])
|
||||
roundedCube(
|
||||
[ dims[0] - 2*layerClearance - 2*fabricClearance,
|
||||
dims[1] - 2*layerClearance - 2*fabricClearance,
|
||||
8],
|
||||
[2, 2, 0]);
|
||||
}
|
||||
*/
|
||||
|
||||
// ropeway
|
||||
for (i = [1, 3]) {
|
||||
for (j = [-1, 1]) {
|
||||
/* Older, diagonal cut
|
||||
translate([dims[0]/2 - j*dims[0]/2 + j*1.5, i*dims[1]/4, -1])
|
||||
rotate([0, 0, 45 + 90*j])
|
||||
cube([4, 4, topShellH + 8]);
|
||||
*/
|
||||
translate([dims[0]/2 - j*dims[0]/2 - 1.5, i*dims[1]/4 - 2.5, -1])
|
||||
chamferedCube([3, 5, topShellH + 8], chamfer=1.5);
|
||||
}
|
||||
|
||||
/* Older, diagonal cut
|
||||
translate([-1, i*dims[1]/4, 1.5])
|
||||
rotate([-135, 0, 0])
|
||||
cube([dims[0] + 8, 4, 4]);
|
||||
*/
|
||||
translate([-1, i*dims[1]/4 - 2.5, -1.5])
|
||||
chamferedCube([dims[0] + 8, 5, 3], chamfer=1.5);
|
||||
}
|
||||
|
||||
// version marker
|
||||
color("black")
|
||||
translate([0.6, 26, 8]) rotate([90, 0,-90])
|
||||
linear_extrude(0.61) text(text = verStr, font = font, size = 8);
|
||||
|
||||
}
|
||||
|
||||
/* -45 = x + -y
|
||||
* x = y - 45
|
||||
*
|
||||
* 135 = x + y
|
||||
* y = 135 - x
|
||||
* y = 135 - (y - 45)
|
||||
* y = 180 - y
|
||||
* y = 90
|
||||
*
|
||||
*/
|
||||
|
||||
// tray indent location
|
||||
// X: innerWall + iW/2 - audioTraySide/2
|
||||
// 2 + (innerBoxWidth - 2*layerClearance - 2*innerWall)/2 - 64/2
|
||||
// 2 + ((outerBoxWidth - 2*outerWall) - 2*0.5 - 2*2)/2 - 32
|
||||
// 2 + (154 - 8 - 1 - 4)/2 - 32
|
||||
// 40.5
|
||||
//
|
||||
// Y: innerWall + iL - audioTraySide/2 - cableDia/2 - innerWall
|
||||
// 2 + (innerBoxLength - 2*layerClearance - 2*innerWall) - 64/2 - 130/2 - 2
|
||||
// 2 + (outerBoxLength - 2*outerWall) - 2*0.5 - 2*2 - 32 - 65 - 2
|
||||
// 300 - 8 - 1 - 4 - 32 - 65
|
||||
// 190
|
||||
//
|
||||
translate([
|
||||
40.5 + outerWall + layerClearance,
|
||||
190 + outerWall + layerClearance,
|
||||
1])
|
||||
//(dims[0] - audioTraySide)/2,
|
||||
//dims[1] - outerWall - innerWall - audioTraySide/2 - 130/2,
|
||||
//1])
|
||||
roundedCube(
|
||||
[ audioTraySide - 2*(innerWall + layerClearance),
|
||||
audioTraySide - 2*(innerWall + layerClearance),
|
||||
4],
|
||||
[1, 1, 1]);
|
||||
|
||||
}
|
||||
|
||||
module layer1() {
|
||||
oH = layer1H;
|
||||
oL = innerBoxLength - 2*layerClearance; // outer length
|
||||
oW = innerBoxWidth - 2*layerClearance; // outer width
|
||||
iL = oL - 2*innerWall; // inner length
|
||||
iW = oW - 2*innerWall; // inner width
|
||||
iH = oH - innerWall; // inner height
|
||||
|
||||
handleDia = 42;
|
||||
cableDia = 130;
|
||||
translate([innerWall, innerWall, innerWall])
|
||||
union() {
|
||||
difference() {
|
||||
// main shell
|
||||
translate([-innerWall, -innerWall, -innerWall])
|
||||
roundedCube([oW, oL, oH], [1, 1, 1]);
|
||||
|
||||
translate([0, 169, 0])
|
||||
mirror([0, 1, 0])
|
||||
union() {
|
||||
// screwdriver handle
|
||||
translate([handleDia / 2, handleDia / 2, handleDia / 2])
|
||||
sphere(d=handleDia);
|
||||
|
||||
translate([handleDia / 2, handleDia / 2, handleDia / 2])
|
||||
cylinder(d=handleDia, h = handleDia / 2 + innerWall);
|
||||
|
||||
translate([handleDia / 2, handleDia / 2 + 3, handleDia / 2])
|
||||
sphere(d=handleDia);
|
||||
|
||||
translate([handleDia / 2, handleDia / 2 + 3, handleDia / 2])
|
||||
cylinder(d=handleDia, h = handleDia / 2 + innerWall);
|
||||
|
||||
translate([(handleDia - 32) / 2, handleDia / 2, 7]) cube([32, 103 - handleDia/2, oH]);
|
||||
|
||||
// screw bits
|
||||
bitL = 112;
|
||||
bitW = 22;
|
||||
// plain cube version (we're going to oversize and chamfer to get
|
||||
// diagonal edges)
|
||||
// translate([(handleDia - bitW) / 2, handleDia / 2, 0]) cube([bitW, bitL + handleDia/2, oH]);
|
||||
translate([(handleDia - bitW) / 2 - 5, handleDia / 2 - 5, -ep])
|
||||
chamferedCube([bitW + 10, bitL + handleDia/2 + 10, 16], chamfer=5);
|
||||
|
||||
// power block cutout
|
||||
translate([(handleDia - 32) / 2 - 4, handleDia / 2 + 80, 7]) cube([40, 68, oH]);
|
||||
|
||||
// fingerway cut-outs
|
||||
translate([handleDia*0.6, 55, 0]) cube([24, 36, oH]);
|
||||
}
|
||||
|
||||
// lower-right cubby
|
||||
translate([handleDia + 2*innerWall, 0, 0])
|
||||
cube([iW - handleDia - 3*innerWall, 150, oH]);
|
||||
|
||||
// cable cut-out
|
||||
translate([iW/2, iL - cableDia/2 - innerWall, 0])
|
||||
cylinder(d=cableDia, h=oH);
|
||||
|
||||
// upper-left bits
|
||||
union() {
|
||||
// PortaPow
|
||||
translate([6.5, 249.5, 22])
|
||||
rotate([0, 0, 45])
|
||||
cube([44.5, 10.5, oH]);
|
||||
|
||||
// USB thumbdrive
|
||||
translate([5, 272, 1])
|
||||
rotate([0, 0, 45])
|
||||
cube([13, 5, oH]);
|
||||
|
||||
// fingerway
|
||||
translate([16, 271, iH + 15])
|
||||
sphere(d=46);
|
||||
}
|
||||
|
||||
// SD-card adapter + SIM removal tool
|
||||
union() {
|
||||
translate([iW - 27, 278, 9.5])
|
||||
rotate([0, 0, -45])
|
||||
cube([25, 2.5, 33]);
|
||||
|
||||
translate([iW - 8, 280, 4.5])
|
||||
rotate([0, 0, -135])
|
||||
cube([8.75, 1.5, 38]);
|
||||
|
||||
// fingerway
|
||||
translate([iW - 16, 271, iH + 15])
|
||||
sphere(d=46);
|
||||
}
|
||||
|
||||
// version marker
|
||||
color("black")
|
||||
translate([-innerWall + 0.6, 26, 4]) rotate([90, 0,-90])
|
||||
linear_extrude(0.61) text(text = verStr, font = font, size = 8);
|
||||
}
|
||||
|
||||
translate([handleDia*0.988, 77.5, -0.1])
|
||||
cylinder(d=9, oH - innerWall + 0.1);
|
||||
|
||||
translate([handleDia*0.988, 114.5, -0.1])
|
||||
cylinder(d=9, oH - innerWall + 0.1);
|
||||
|
||||
translate([iW/2 - audioTraySide/2, iL - audioTraySide/2 - cableDia/2 - innerWall, 0])
|
||||
difference() {
|
||||
translate([0, 0, -0.1])
|
||||
roundedCube([audioTraySide, audioTraySide, 1.1], [0.4, 0.4, 0.4]);
|
||||
translate([innerWall, innerWall, 0])
|
||||
cube([audioTraySide - 2*innerWall, audioTraySide - 2*innerWall, 2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module layer2() {
|
||||
oH = layer2H;
|
||||
oL = innerBoxLength - 2*layerClearance; // outer length
|
||||
oW = innerBoxWidth - 2*layerClearance; // outer width
|
||||
iL = oL - 2*innerWall; // inner length
|
||||
iW = oW - 2*innerWall; // inner width
|
||||
iH = oH - innerWall; // inner height
|
||||
|
||||
union() {
|
||||
|
||||
difference() {
|
||||
roundedCube([oW, oL, oH], [1, 1, 1]);
|
||||
|
||||
translate([innerWall, innerWall, innerWall])
|
||||
union() {
|
||||
// HDD
|
||||
translate([(iW - 131)/2, 0, 0])
|
||||
cube([131, 83, oH]);
|
||||
|
||||
// Tekton tool kit
|
||||
translate([2, 103 + innerWall, 0])
|
||||
cube([105.5, 61, oH]);
|
||||
|
||||
// Slice knife
|
||||
translate([114, 103 + innerWall, 0])
|
||||
cube([22.5, 156, oH]);
|
||||
|
||||
// cables
|
||||
translate([56, 226, 0])
|
||||
cylinder(d=110, h=oH);
|
||||
|
||||
// fingerways
|
||||
translate([30, 80, 0])
|
||||
cube([36, 30, oH]);
|
||||
|
||||
translate([105, 130, 0])
|
||||
cube([12, 36, oH]);
|
||||
}
|
||||
|
||||
// version marker
|
||||
color("black")
|
||||
translate([0.6, 26 + innerWall, 4]) rotate([90, 0,-90])
|
||||
linear_extrude(0.61) text(text = verStr, font = font, size = 8);
|
||||
}
|
||||
|
||||
translate([32, 96, 0]) scale([6, 22, 1]) cylinder(d=1, h=oH);
|
||||
translate([68, 96, 0]) scale([6, 22, 1]) cylinder(d=1, h=oH);
|
||||
translate([112.75, 132, 0]) scale([6.5, 6, 1]) cylinder(d=1, h=oH);
|
||||
}
|
||||
}
|
||||
|
||||
module audioTrayBlank(s, h) {
|
||||
difference() {
|
||||
union() {
|
||||
translate([0, 0, 1])
|
||||
roundedCube(
|
||||
[s, s, h - 1],
|
||||
[1, 1, 1]);
|
||||
|
||||
translate([innerWall + layerClearance, innerWall + layerClearance, 0])
|
||||
roundedCube(
|
||||
[ s - 2*(innerWall + layerClearance),
|
||||
s - 2*(innerWall + layerClearance),
|
||||
h - 1],
|
||||
[1, 1, 1]);
|
||||
}
|
||||
|
||||
// bottom edge chamfers
|
||||
translate([-1, (innerWall + layerClearance), 1])
|
||||
rotate([-30, 0, 0])
|
||||
translate([0, -2*(innerWall + layerClearance), -4])
|
||||
cube([audioTraySide+2, 2*(innerWall + layerClearance), 4]);
|
||||
|
||||
translate([-1, audioTraySide - (innerWall + layerClearance), 1])
|
||||
rotate([30, 0, 0])
|
||||
translate([0, 0, -4])
|
||||
cube([audioTraySide+2, 2*(innerWall + layerClearance), 4]);
|
||||
|
||||
translate([(innerWall + layerClearance), -1, 1])
|
||||
rotate([0, 30, 0])
|
||||
translate([-2*(innerWall + layerClearance), 0, -4])
|
||||
cube([2*(innerWall + layerClearance), audioTraySide+2, 4]);
|
||||
|
||||
translate([audioTraySide - (innerWall + layerClearance), -1, 1])
|
||||
rotate([0, -30, 0])
|
||||
translate([0, 0, -4])
|
||||
cube([2*(innerWall + layerClearance), audioTraySide+2, 4]);
|
||||
|
||||
// top lip cutaway
|
||||
translate([innerWall, innerWall, h - 1])
|
||||
cube([audioTrayIS,audioTrayIS, 4]);
|
||||
|
||||
// version marker
|
||||
translate([0.6, 30, 4]) rotate([90, 0,-90])
|
||||
linear_extrude(0.61) text(text = verStr, font = font, size = 8);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
module audioJackTray() {
|
||||
difference() {
|
||||
audioTrayBlank(s = audioTraySide, h = audioTrayHeight);
|
||||
|
||||
translate([2.5, innerWall, innerWall])
|
||||
union() {
|
||||
|
||||
for (i = [0, 1]) {
|
||||
translate([i*(11), i*60, 0])
|
||||
mirror([0, i, 0])
|
||||
union() {
|
||||
translate([6.5, 0, 6])
|
||||
rotate([-90, 0, 0]) cylinder(d=13, h=28);
|
||||
translate([0, 0, 6]) cube([13, 28, audioTrayIH]);
|
||||
|
||||
translate([6.5, 27.5, 6])
|
||||
rotate([-90, 0, 0]) cylinder(d=7, h=32.5);
|
||||
translate([3, 27.5, 6]) cube([7, 32.5, audioTrayIH]);
|
||||
|
||||
translate([6.5, 48, 3.5])
|
||||
rotate([-90, 0, 0]) cylinder(d=7, h=12);
|
||||
translate([3, 48, 3.5]) cube([7, 12, audioTrayIH]);
|
||||
|
||||
translate([6.5, 53, 11])
|
||||
sphere(d=14);
|
||||
}
|
||||
|
||||
translate([22 + i*(10), i*60, 0])
|
||||
mirror([0, i, 0])
|
||||
translate([0, 6, 0])
|
||||
union() {
|
||||
translate([6, 0, 7])
|
||||
rotate([-90, 0, 0]) cylinder(d=12, h=16);
|
||||
translate([0, 0, 7]) cube([12, 16, audioTrayIH]);
|
||||
|
||||
translate([6, 15.5, 7])
|
||||
rotate([-90, 0, 0]) cylinder(d=7, h=32.5);
|
||||
translate([2.5, 15.5, 7]) cube([7, 32.5, audioTrayIH]);
|
||||
|
||||
translate([6, 36, 4])
|
||||
rotate([-90, 0, 0]) cylinder(d=7, h=12);
|
||||
translate([2.5, 36, 4]) cube([7, 12, audioTrayIH]);
|
||||
|
||||
translate([6, 43, 11])
|
||||
sphere(d=13);
|
||||
}
|
||||
}
|
||||
|
||||
translate([audioTrayIS - 14, 8, 0])
|
||||
union() {
|
||||
translate([6, 0, 6.5]) rotate([-90, 0, 0]) cylinder(d=12, h=40);
|
||||
translate([0, 0, 6.5]) cube([12, 40, audioTrayIH]);
|
||||
|
||||
translate([6, 26, 5]) rotate([-90, 0, 0]) cylinder(d=12, h=14);
|
||||
translate([0, 26, 5]) cube([12, 14, audioTrayIH]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Show Cross-section
|
||||
// translate([-2, -1, -1]) cube([audioTraySide + 4, 20, audioTrayHeight + 4]);
|
||||
}
|
||||
}
|
||||
|
||||
module drumKeyTray() {
|
||||
difference() {
|
||||
audioTrayBlank(s = audioTraySide, h = audioTrayHeight);
|
||||
|
||||
translate([innerWall, innerWall, innerWall])
|
||||
union() {
|
||||
|
||||
// drum-key
|
||||
translate([audioTrayIS/2, 2*innerWall, 0])
|
||||
union() {
|
||||
translate([0, 0, 7.5])
|
||||
rotate([-90, 0, 0]) cylinder(d=11, h=36);
|
||||
translate([-5.5, 0, 7.5]) cube([11, 36, audioTrayIH]);
|
||||
|
||||
translate([-51/2, 0, 7.5 - 3]) cube([51, 9, audioTrayIH]);
|
||||
}
|
||||
|
||||
for (i = [-1, 1]) {
|
||||
translate([audioTrayIS/2 - 6 + i*20, 16, 0])
|
||||
union() {
|
||||
translate([6, 0, 7]) rotate([-90, 0, 0]) cylinder(d=12, h=40);
|
||||
translate([0, 0, 7]) cube([12, 40, audioTrayIH]);
|
||||
|
||||
translate([6, 26, 5]) rotate([-90, 0, 0]) cylinder(d=12, h=14);
|
||||
translate([0, 26, 5]) cube([12, 14, audioTrayIH]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Show Cross-section
|
||||
// translate([-2, -1, -1]) cube([audioTraySide + 4, 10, audioTrayHeight + 4]);
|
||||
}
|
||||
}
|
||||
|
||||
module headphoneAmpTray() {
|
||||
difference() {
|
||||
audioTrayBlank(s = audioTraySide, h = audioTrayHeight - 1);
|
||||
|
||||
translate([2*innerWall, (audioTrayIS - 43)/2, innerWall])
|
||||
cube([43, 43, audioTrayIH]);
|
||||
|
||||
translate([3*innerWall + 43, (audioTrayIS - 43)/2, innerWall])
|
||||
cube([12.4, 46, audioTrayIH]);
|
||||
|
||||
translate([50, 8 + innerWall*2, innerWall])
|
||||
cylinder(d=16, h=audioTrayIH);
|
||||
}
|
||||
}
|
||||
|
||||
module usbBitsTray() {
|
||||
difference() {
|
||||
audioTrayBlank(s = audioTraySide, h = audioTrayHeight);
|
||||
|
||||
translate([innerWall, innerWall, innerWall])
|
||||
union() {
|
||||
|
||||
// right-angle connectors (1st variation)
|
||||
translate([innerWall, innerWall, -1])
|
||||
for (i = [0, 1]) {
|
||||
translate([34*i, 16*i, 0])
|
||||
rotate([0, 0, 180*i])
|
||||
union() {
|
||||
// main body
|
||||
cube([22.5, 7, 14]);
|
||||
|
||||
// usb connector
|
||||
// 1.64 to edge, 4.64 thick
|
||||
translate([1.4, 0, 0]) cube([6, 16, 14]);
|
||||
|
||||
// release wedge
|
||||
translate([22.5, 0, 0])
|
||||
rotate([0, 15, 0])
|
||||
translate([-22, 0, 0])
|
||||
cube([22, 7, 14]);
|
||||
|
||||
// fingerway
|
||||
translate([-1, -1, 11])
|
||||
cube([36, 18, 3]);
|
||||
}
|
||||
}
|
||||
|
||||
// right-angle connectors (2nd variation)
|
||||
translate([innerWall, innerWall + 18, 5 + 0.1])
|
||||
for (i = [0, 1]) {
|
||||
translate([30*i, 36*i, 0])
|
||||
rotate([0, 0, 180*i])
|
||||
union() {
|
||||
// main body
|
||||
cube([25, 13, 7]);
|
||||
|
||||
// usb connector
|
||||
// 10.32 wide, 0.73 to edge
|
||||
cube([12, 22, 7]);
|
||||
|
||||
// release wedge
|
||||
translate([17, 0, 0])
|
||||
rotate([0, 30, 0])
|
||||
cube([8, 13, 7]);
|
||||
|
||||
// finergway
|
||||
translate([25, 6.5, 8]) sphere(d=13);
|
||||
}
|
||||
}
|
||||
|
||||
// usb A-C converers
|
||||
// 29 x 18 x 9
|
||||
translate([innerWall + 38, innerWall - 0.5, 3])
|
||||
for(i = [0,1]) {
|
||||
translate([0, 28.5*2*i, 0])
|
||||
mirror([0, i, 0])
|
||||
union() {
|
||||
// main body
|
||||
cube([18, 29, 10]);
|
||||
|
||||
// release wedge
|
||||
translate([0, 28.5, -4])
|
||||
rotate([-20, 0, 0])
|
||||
translate([0, -29, 0])
|
||||
cube([18, 29, 14]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
standoffX = outerBoxWidth + 10;
|
||||
standoffY = outerBoxLength + 10;
|
||||
|
||||
// test-print the lip
|
||||
// shellBottom([20, 30, 30]);
|
||||
// translate([24, 0, 0]) shellTop([20, 30, 30]);
|
||||
shellBottom([outerBoxWidth, outerBoxLength, outerBoxHeight]);
|
||||
translate([0, standoffY, 0]) shellTop([outerBoxWidth, outerBoxLength, outerBoxHeight]);
|
||||
translate([standoffX, 0, 0]) layer1();
|
||||
translate([standoffX, standoffY, 0]) layer2();
|
||||
translate([2*standoffX, 0, 0]) audioJackTray();
|
||||
translate([2*standoffX, 80, 0]) usbBitsTray();
|
||||
translate([2*standoffX, 160, 0]) headphoneAmpTray();
|
||||
translate([2*standoffX, 240, 0]) drumKeyTray();
|
||||
@@ -0,0 +1,75 @@
|
||||
$fn=256;
|
||||
|
||||
// all measurements in mm
|
||||
height = 100; // total
|
||||
hoseClampWidth = 12; // accomodate 5/16" (8mm) hose clamp width
|
||||
sectionHeight = 22; // (height - 2 * hoseClampWidth) / 3;
|
||||
centerHeight = height - 2 * (hoseClampWidth + sectionHeight);
|
||||
|
||||
/*
|
||||
difference() {
|
||||
union() {
|
||||
// main sections
|
||||
for (i = [-1,1]) {
|
||||
translate([0, 0, i * (hoseClampWidth + sectionHeight)])
|
||||
cylinder(d = 48, h = sectionHeight, center = true);
|
||||
}
|
||||
|
||||
// hose pipe fitting sections
|
||||
for (i = [-1,1]) {
|
||||
translate([0, 0, i * (0.1 + hoseClampWidth + sectionHeight) * 0.5])
|
||||
cylinder(d = 44, h = hoseClampWidth + 0.2, center = true);
|
||||
|
||||
translate([0, 0, i * ((sectionHeight + hoseClampWidth) * 0.5) + (hoseClampWidth * 0.5) - 1])
|
||||
cylinder(d1 = 44, d2 = 48, h = 2, center = true);
|
||||
|
||||
translate([0, 0, i * ((sectionHeight + hoseClampWidth) * 0.5) + (hoseClampWidth * 0.5) + 1 - hoseClampWidth])
|
||||
cylinder(d1 = 48, d2 = 44, h = 2, center = true);
|
||||
}
|
||||
|
||||
// center section
|
||||
cylinder(d = 48, h = sectionHeight, center = true);
|
||||
|
||||
// center ring
|
||||
translate([0, 0, -1.5]) cylinder(d1 = 48, d2 = 52, h = 3, center = true);
|
||||
translate([0, 0, 1.5]) cylinder(d1 = 52, d2 = 48, h = 3, center = true);
|
||||
}
|
||||
|
||||
// hollow out
|
||||
cylinder(d = 36, h = 100.2, center = true);
|
||||
}
|
||||
*/
|
||||
|
||||
difference() {
|
||||
union() {
|
||||
// main sections
|
||||
for (i = [-1,1]) {
|
||||
translate([0, 0, i * ((centerHeight + sectionHeight) * 0.5 + hoseClampWidth)])
|
||||
cylinder(d = 48, h = sectionHeight, center = true);
|
||||
}
|
||||
|
||||
// hose pipe fitting sections
|
||||
for (i = [-1,1]) {
|
||||
translate([0, 0, i * (0.1 + hoseClampWidth + centerHeight) * 0.5])
|
||||
cylinder(d = 44, h = hoseClampWidth + 0.2, center = true);
|
||||
|
||||
color("SlateGray")
|
||||
translate([0, 0, (hoseClampWidth / 2 - 1) + i * ((centerHeight + hoseClampWidth)* 0.5)])
|
||||
cylinder(d1 = 44, d2 = 48, h = 2, center = true);
|
||||
|
||||
color("SeaGreen")
|
||||
translate([0, 0, -(hoseClampWidth / 2 - 1) + i * ((centerHeight + hoseClampWidth)* 0.5)])
|
||||
cylinder(d1 = 48, d2 = 44, h = 2, center = true);
|
||||
}
|
||||
|
||||
// center section
|
||||
cylinder(d = 48, h = centerHeight, center = true);
|
||||
|
||||
// center ring
|
||||
translate([0, 0, -1.5]) cylinder(d1 = 48, d2 = 52, h = 3, center = true);
|
||||
translate([0, 0, 1.5]) cylinder(d1 = 52, d2 = 48, h = 3, center = true);
|
||||
}
|
||||
|
||||
// hollow out
|
||||
cylinder(d = 36, h = 100.2, center = true);
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,289 @@
|
||||
include <../lib/joints.scad>
|
||||
include <../lib/solids.scad>
|
||||
|
||||
// All linear dimensions are in millimeters, all angles in degrees
|
||||
boardThickness = 4;
|
||||
supportAngle = 30;
|
||||
width = 240;
|
||||
depth = 180;
|
||||
toeChop = 36;
|
||||
tenonDims = [boardThickness, boardThickness, 10];
|
||||
morticeDims = [boardThickness, boardThickness + 0.2, 10];
|
||||
|
||||
$fn = 128;
|
||||
|
||||
module triangleCutouts(h, rep = 2, wMul = 1) {
|
||||
tH = h - 2*boardThickness;
|
||||
tW = wMul * tH;
|
||||
tAng = atan(tH / tW);
|
||||
diagonalThickness = boardThickness / sin(tAng);
|
||||
|
||||
// triangle cutouts, 1st half
|
||||
cutoutOffset = tW + boardThickness;
|
||||
translate([cutoutOffset, -0.1, boardThickness]) rotate([0, 0, 90]) prism(boardThickness + 0.2, tW, tH);
|
||||
|
||||
translate([diagonalThickness, 0, 0]) for (i = [0:rep-1]) {
|
||||
setOffset = i * (2 * tW + 2 * diagonalThickness);
|
||||
translate([cutoutOffset + setOffset, -0.1, boardThickness]) mirror([1, 0, 0]) rotate([0, 90, 0]) rotate([0, 0, 90]) prism(boardThickness + 0.2, tH, tW);
|
||||
translate([cutoutOffset + setOffset - 0.1, -0.1, boardThickness]) rotate([0, 90, 0]) rotate([0, 0, 90]) prism(boardThickness + 0.2, tH, tW);
|
||||
translate([cutoutOffset + setOffset + diagonalThickness, -0.1, boardThickness]) mirror([1, 0, 0]) rotate([0, 0, 90]) prism(boardThickness + 0.2, tW, tH);
|
||||
translate([cutoutOffset + setOffset + 2*tW + diagonalThickness - 0.1, -0.1, boardThickness]) rotate([0, 0, 90]) prism(boardThickness + 0.2, tW, tH);
|
||||
|
||||
if (i == rep - 1) {
|
||||
translate([cutoutOffset + setOffset + 2*tW + 2*diagonalThickness, -0.1, boardThickness]) mirror([1, 0, 0]) rotate([0, 90, 0]) rotate([0, 0, 90]) prism(boardThickness + 0.2, tH, tW);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module sidePanel(cutWeight = true) {
|
||||
difference() {
|
||||
translate([0, -toeChop, 0]) difference() {
|
||||
cube([boardThickness, depth, 100]);
|
||||
translate([-0.1, 0, 0]) union() {
|
||||
rotate([supportAngle, 0, 0]) cube([boardThickness + 0.2, 240, 100]);
|
||||
rotate([supportAngle, 0, 0]) translate([0, 192, -80]) cube([boardThickness + 0.2, 40, 100]);
|
||||
translate([0, -0.1, -0.1]) cube([boardThickness + 0.2, toeChop + 0.1, 101]);
|
||||
translate([boardThickness/2 + 0.1, 90, 75]) rotate([0, 90, 0]) cylinder(h = boardThickness + 0.2, r = 50, center = true);
|
||||
|
||||
// Speed holes
|
||||
if (cutWeight) {
|
||||
translate([boardThickness/2 + 0.1, 60, 14]) rotate([0, 90, 0]) cylinder(h = boardThickness + 0.2, r = 10, center = true);
|
||||
translate([boardThickness/2 + 0.1, 84, 12]) rotate([0, 90, 0]) cylinder(h = boardThickness + 0.2, r = 8, center = true);
|
||||
translate([boardThickness/2 + 0.1, 104, 14]) rotate([0, 90, 0]) cylinder(h = boardThickness + 0.2, r = 9, center = true);
|
||||
translate([boardThickness/2 + 0.1, 130, 20]) rotate([0, 90, 0]) cylinder(h = boardThickness + 0.2, r = 14, center = true);
|
||||
translate([boardThickness/2 + 0.1, 158, 14]) rotate([0, 90, 0]) cylinder(h = boardThickness + 0.2, r = 10, center = true);
|
||||
translate([boardThickness/2 + 0.1, 156, 42]) rotate([0, 90, 0]) cylinder(h = boardThickness + 0.2, r = 14, center = true);
|
||||
translate([boardThickness/2 + 0.1, 158, 70]) rotate([0, 90, 0]) cylinder(h = boardThickness + 0.2, r = 9, center = true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// dovetail sockets
|
||||
|
||||
// back panel dovetail socket
|
||||
translate([boardThickness, -0.01, 10 + 4])
|
||||
rotate([-90, 90, 0])
|
||||
color("blue") dovetail(tailHeight = boardThickness + 0.01, tailWidthMin = 6, tailWidthMax = 10, depth = boardThickness + 0.01);
|
||||
|
||||
// front panel dovetail sockets
|
||||
translate([boardThickness, 144 - boardThickness, 10 + 12])
|
||||
rotate([-90, 90, 0])
|
||||
color("blue") dovetail(tailHeight = boardThickness + 0.01, tailWidthMin = 6, tailWidthMax = 10, depth = boardThickness + 0.01);
|
||||
|
||||
translate([boardThickness, 144 - boardThickness, 10 + 48])
|
||||
rotate([-90, 90, 0])
|
||||
color("blue") dovetail(tailHeight = boardThickness + 0.01, tailWidthMin = 6, tailWidthMax = 10, depth = boardThickness + 0.01);
|
||||
|
||||
// top panel dovetail sockets
|
||||
color("blue")
|
||||
translate([0, -toeChop, 0])
|
||||
rotate([supportAngle, 0, 0])
|
||||
union() {
|
||||
translate([boardThickness, toeChop + 16, -boardThickness])
|
||||
rotate([0, 0, 90])
|
||||
dovetail(tailHeight = boardThickness + 0.01, tailWidthMin = 6, tailWidthMax = 10, depth = boardThickness + 0.01);
|
||||
|
||||
translate([boardThickness, toeChop + 138, -boardThickness])
|
||||
rotate([0, 0, 90])
|
||||
dovetail(tailHeight = boardThickness + 0.01, tailWidthMin = 6, tailWidthMax = 10, depth = boardThickness + 0.01);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
module midPanel(cutWeight = true) {
|
||||
// main panel
|
||||
translate([0, -toeChop, 0])
|
||||
difference() {
|
||||
|
||||
cube([boardThickness, depth - boardThickness, 100]);
|
||||
|
||||
translate([-0.1, 0, 0])
|
||||
union() {
|
||||
// main cut establishing the angled plane
|
||||
rotate([supportAngle, 0, 0])
|
||||
translate([0, 0, -boardThickness])
|
||||
cube([boardThickness + 0.2, 240, 100]);
|
||||
|
||||
// cut off the top corner
|
||||
rotate([supportAngle, 0, 0])
|
||||
translate([0, 192, -80])
|
||||
cube([boardThickness + 0.2, 40, 100]);
|
||||
|
||||
// cut off the toe
|
||||
translate([0, -0.1, -0.1])
|
||||
cube([boardThickness + 0.2, toeChop + boardThickness + 0.1, 101]);
|
||||
|
||||
// cut out the main scoop
|
||||
translate([boardThickness/2 + 0.1, 90, 75])
|
||||
rotate([0, 90, 0])
|
||||
cylinder(h = boardThickness + 0.2, r = 50, center = true);
|
||||
|
||||
// cut speed holes
|
||||
if (cutWeight) {
|
||||
translate([boardThickness/2 + 0.1, 60, 14]) rotate([0, 90, 0]) cylinder(h = boardThickness + 0.2, r = 10, center = true);
|
||||
translate([boardThickness/2 + 0.1, 84, 12]) rotate([0, 90, 0]) cylinder(h = boardThickness + 0.2, r = 8, center = true);
|
||||
translate([boardThickness/2 + 0.1, 104, 14]) rotate([0, 90, 0]) cylinder(h = boardThickness + 0.2, r = 9, center = true);
|
||||
translate([boardThickness/2 + 0.1, 130, 20]) rotate([0, 90, 0]) cylinder(h = boardThickness + 0.2, r = 14, center = true);
|
||||
translate([boardThickness/2 + 0.1, 158, 14]) rotate([0, 90, 0]) cylinder(h = boardThickness + 0.2, r = 10, center = true);
|
||||
translate([boardThickness/2 + 0.1, 156, 42]) rotate([0, 90, 0]) cylinder(h = boardThickness + 0.2, r = 14, center = true);
|
||||
translate([boardThickness/2 + 0.1, 158, 70]) rotate([0, 90, 0]) cylinder(h = boardThickness + 0.2, r = 9, center = true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// top panel tenons
|
||||
translate([0, -toeChop, 0]) // adjust for the toe chop
|
||||
rotate([supportAngle, 0, 0]) // rotate the tenon plane to match the panel angle
|
||||
union() {
|
||||
// lower tenon
|
||||
// orient the tenon along the plane of the edge
|
||||
// 10 = bring tenon to origin
|
||||
// 43.9 = distance on the plane of the top to lip of the piece
|
||||
// 8 = offset to center the tenon on the piece
|
||||
translate([0, 10 + 43.9 + 8, -boardThickness])
|
||||
rotate([90, 0, 0]) // orient the tenon upright (facing positive Z)
|
||||
tenon(tenonDims);
|
||||
|
||||
// upper tenon
|
||||
// orient the tenon along the plane of the edge
|
||||
// 10 = bring tenon to origin
|
||||
// 159.3 = distance on the plane of the top to lip of the piece
|
||||
// 14.7 = offset to place the tenon on the piece
|
||||
translate([0, 10 + 159.3 + 14.7, -boardThickness]) // orient the tenon along the plane of the edge
|
||||
rotate([90, 0, 0]) // orient the tenon upright
|
||||
tenon(tenonDims);
|
||||
}
|
||||
|
||||
// front panel tenon
|
||||
translate([0, boardThickness, 4])
|
||||
mirror([0, 1, 0])
|
||||
tenon(tenonDims);
|
||||
|
||||
// back panel tenons
|
||||
translate([0, 144 - boardThickness, 8]) tenon(tenonDims);
|
||||
translate([0, 144 - boardThickness, 48]) tenon(tenonDims);
|
||||
}
|
||||
|
||||
module backPanel(cutWeight = true) {
|
||||
panelHeight = 18.4;
|
||||
translate([boardThickness, 0, 0])
|
||||
difference() {
|
||||
cube([width - boardThickness * 2, boardThickness, panelHeight]);
|
||||
|
||||
if (cutWeight) {
|
||||
triangleCutouts(h = panelHeight, rep = 3, wMul = 0.95);
|
||||
translate([width - boardThickness * 2, 0, 0]) mirror([1, 0, 0]) triangleCutouts(h = panelHeight, rep = 3, wMul = 0.95);
|
||||
}
|
||||
|
||||
translate([(width - 3*boardThickness) / 2, 0, 4]) morticeBlank(morticeDims);
|
||||
}
|
||||
|
||||
// dovetails to connect to the side panels
|
||||
translate([boardThickness, boardThickness, 4])
|
||||
rotate([0, -90, 90])
|
||||
dovetail(tailHeight = boardThickness, tailWidthMin = 6, tailWidthMax = 10, depth = boardThickness);
|
||||
|
||||
translate([width - boardThickness, 0, 4])
|
||||
rotate([0, -90, -90])
|
||||
dovetail(tailHeight = boardThickness, tailWidthMin = 6, tailWidthMax = 10, depth = boardThickness);
|
||||
|
||||
}
|
||||
|
||||
module frontPanel(cutWeight = true) {
|
||||
panelHeight = 72.2;
|
||||
translate([boardThickness, 0, 0])
|
||||
difference() {
|
||||
cube([width - boardThickness * 2, boardThickness, panelHeight]);
|
||||
|
||||
if (cutWeight) {
|
||||
triangleCutouts(h = panelHeight, rep = 1, wMul = 0.48);
|
||||
translate([width - boardThickness * 2, 0, 0]) mirror([1, 0, 0]) triangleCutouts(h = panelHeight, rep = 1, wMul = 0.48);;
|
||||
}
|
||||
|
||||
translate([(width - 3*boardThickness) / 2, 0, 8]) morticeBlank(morticeDims);
|
||||
translate([(width - 3*boardThickness) / 2, 0, 48]) morticeBlank(morticeDims);
|
||||
}
|
||||
|
||||
// dovetails to connect to the side panels
|
||||
translate([boardThickness, boardThickness, 12])
|
||||
rotate([0, -90, 90])
|
||||
dovetail(tailHeight = boardThickness, tailWidthMin = 6, tailWidthMax = 10, depth = boardThickness);
|
||||
|
||||
translate([width - boardThickness, 0, 12])
|
||||
rotate([0, -90, -90])
|
||||
dovetail(tailHeight = boardThickness, tailWidthMin = 6, tailWidthMax = 10, depth = boardThickness);
|
||||
|
||||
translate([boardThickness, boardThickness, 48])
|
||||
rotate([0, -90, 90])
|
||||
dovetail(tailHeight = boardThickness, tailWidthMin = 6, tailWidthMax = 10, depth = boardThickness);
|
||||
|
||||
translate([width - boardThickness, 0, 48])
|
||||
rotate([0, -90, -90])
|
||||
dovetail(tailHeight = boardThickness, tailWidthMin = 6, tailWidthMax = 10, depth = boardThickness);
|
||||
|
||||
}
|
||||
|
||||
module topPanel(cutWeight = true) {
|
||||
panelHeight = 26;
|
||||
|
||||
translate([boardThickness, 0, 0])
|
||||
difference() {
|
||||
cube([width - boardThickness * 2, boardThickness, panelHeight]);
|
||||
|
||||
if (cutWeight) {
|
||||
triangleCutouts(h = panelHeight, wMul = 0.9);
|
||||
translate([width - boardThickness * 2, 0, 0]) mirror([1, 0, 0]) triangleCutouts(h = panelHeight, wMul = 0.9);
|
||||
}
|
||||
|
||||
// mortice to connect to the mid piece
|
||||
translate([(width - 3*boardThickness)/2, -0.1, 8]) morticeBlank(morticeDims);
|
||||
}
|
||||
|
||||
// dovetails to connect to the side panels
|
||||
translate([boardThickness, boardThickness, 8])
|
||||
rotate([0, -90, 90])
|
||||
dovetail(tailHeight = boardThickness, tailWidthMin = 6, tailWidthMax = 10, depth = boardThickness);
|
||||
|
||||
translate([width - boardThickness, 0, 8])
|
||||
rotate([0, -90, -90])
|
||||
dovetail(tailHeight = boardThickness, tailWidthMin = 6, tailWidthMax = 10, depth = boardThickness);
|
||||
}
|
||||
|
||||
module assembled(cutWeight = true) {
|
||||
spaceBetween = (width - 3*boardThickness) / 2;
|
||||
|
||||
color("Tan") sidePanel(cutWeight);
|
||||
color("RosyBrown") translate([1*(boardThickness + spaceBetween), 0, 0]) midPanel(cutWeight);
|
||||
color("Tan") translate([2*(boardThickness + spaceBetween) + boardThickness, 0, 0]) mirror([1, 0, 0]) sidePanel(cutWeight);
|
||||
|
||||
color("DarkSeaGreen") backPanel(cutWeight);
|
||||
color("LightSeaGreen") translate([0, depth - toeChop - boardThickness, 0]) frontPanel(cutWeight);
|
||||
|
||||
color("SkyBlue") translate([0, -toeChop, 0]) rotate([1*(-90 + supportAngle), 0, 0]) translate([0, 0, 43.9]) topPanel(cutWeight);
|
||||
color("LightSteelBlue") translate([0, -toeChop, 0]) rotate([1*(-90 + supportAngle), 0, 0]) translate([0, 0, 166]) topPanel(cutWeight);
|
||||
}
|
||||
|
||||
|
||||
module flatPack(cutWeight = true) {
|
||||
color("Tan") translate([0, 60, boardThickness]) rotate([0, 90, 0]) sidePanel(cutWeight);
|
||||
color("Tan") translate([98, 144, 0]) mirror([0, 0, 1]) rotate([0, 90, 180]) sidePanel(cutWeight);
|
||||
color("RosyBrown") translate([180, 300, boardThickness]) mirror([0, 1, 0]) rotate([0, 90, 90]) midPanel(cutWeight);
|
||||
|
||||
color("DarkSeaGreen") translate([100, 0, 0]) rotate([90, 0, 90]) backPanel(cutWeight);
|
||||
|
||||
color("LightSeaGreen") translate([120, 0, 0]) rotate([90, 0, 90]) frontPanel(cutWeight);
|
||||
|
||||
color("SkyBlue") translate([194, 0, 0]) rotate([90, 0, 90]) topPanel(cutWeight);
|
||||
color("LightSteelBlue") translate([222, 0, 0]) rotate([90, 0, 90]) topPanel(cutWeight);
|
||||
|
||||
}
|
||||
|
||||
// backPanel();
|
||||
// midPanel();
|
||||
// topPanel();
|
||||
// sidePanel();
|
||||
|
||||
// assembled();
|
||||
flatPack();
|
||||
Binary file not shown.
@@ -0,0 +1,19 @@
|
||||
include <../../lib/metric-machine-screws.scad>;
|
||||
|
||||
$fn=128;
|
||||
difference() {
|
||||
union() {
|
||||
cylinder(d=20, h=6);
|
||||
translate([0, -10, 0]) cube([160, 20, 6]);
|
||||
translate([160, 0, 0]) cylinder(d=20, h=6);
|
||||
}
|
||||
|
||||
for (x = [7.5, 68.7, 152.5]) {
|
||||
translate([x, 0, -0.01]) union() {
|
||||
translate([0, 0, 2.02]) m4Nut(h = 4);
|
||||
cylinder(d=4, h=8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//color("blue") translate([80, 0, 0]) rotate([0, 90, 0]) import("Coat_Rack.stl");
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,18 @@
|
||||
$fn=128;
|
||||
length=95;
|
||||
|
||||
rotate([90, 0, 0]) translate([0, length / 2, 0]) difference() {
|
||||
union() {
|
||||
rotate([90, 0, 0]) cylinder(d=30, h=length, center=true);
|
||||
translate([10, 0, 0]) cube([20, length, 30], center=true);
|
||||
}
|
||||
|
||||
union() {
|
||||
translate([0, -0.01, 0]) rotate([90, 0, 0]) cylinder(d=20, h=length + 0.2, center=true);
|
||||
translate([20, -0.01, 0]) cube([40, length + 0.2, 20], center=true);
|
||||
}
|
||||
}
|
||||
|
||||
//translate([-4, -4, 0]) cylinder(d=14, h=5.2);
|
||||
|
||||
//translate([-1, -1]) cylinder(d=4, h=15);
|
||||
@@ -0,0 +1,49 @@
|
||||
include <../lib/metric-machine-screws.scad>
|
||||
|
||||
$fn=128;
|
||||
|
||||
h_handle = 200; // Length of the handle
|
||||
h_tilted = h_handle / sqrt(2);
|
||||
|
||||
d_handle = 20; // Diameter of the handle
|
||||
screw_distance_on_center = 88.5;
|
||||
|
||||
//translate([0, 0, h_tilted / 2])
|
||||
//rotate([45, 0, 0])
|
||||
//translate([0, d_handle / 2, 0])
|
||||
difference() {
|
||||
union() {
|
||||
cylinder(d=d_handle, h=h_handle, center=true); // Main handle body
|
||||
|
||||
for (i = [-1, 1]) {
|
||||
translate([0, 17, i * (screw_distance_on_center / 2)])
|
||||
rotate([90, 0, 0])
|
||||
cylinder(d=10, h=18, center=true);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = [-1, 1]) {
|
||||
translate([0, 5, i * (screw_distance_on_center / 2)])
|
||||
rotate([90, 0, 0])
|
||||
m3Nut(h=d_handle + 10, center=true, clearance=0.2);
|
||||
|
||||
translate([0, 7, i * (screw_distance_on_center / 2)])
|
||||
rotate([90, 0, 0])
|
||||
cylinder(d=3.2, h=40, center=true);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
translate([0, -0.2, h_tilted / 2])
|
||||
difference() {
|
||||
cube([1, h_tilted, h_tilted], center=true);
|
||||
|
||||
color("blue")
|
||||
translate([0, h_tilted / 2, h_tilted / 2])
|
||||
rotate([45, 0, 0])
|
||||
cube([2, h_handle, h_handle], center=true);
|
||||
}
|
||||
|
||||
translate([0, -h_tilted / 2, 40])
|
||||
cube([40, 1, 80], center=true);
|
||||
*/
|
||||
@@ -0,0 +1,6 @@
|
||||
difference() {
|
||||
cube([]);
|
||||
|
||||
union() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
This thing was created by Thingiverse user GhostsonAcid, and is licensed under GNU - GPL
|
||||
@@ -0,0 +1,4 @@
|
||||
Stronger wall-hook by GhostsonAcid on Thingiverse: https://www.thingiverse.com/thing:5587903
|
||||
|
||||
Summary:
|
||||
Here's a 2-part hook for safely hanging kitchen pans, or other 'heavy' things.-Use a single M4 screw. Also, I included a small hole at the bottom of the hook for an optional "finishing nail" (-diameter ≤1.5mm) to help prevent rotation.-Please note that the bottoms of each piece are designed to interlock with each-other, and thus will hold firmly in place, once installed. (-Refer to the picture above.)--> I would like to do more with this design, but right now I feel I just don't have so much time to devote to such a small project.For this, I simply wanted a stronger hook than most. The better (i.e. stronger) way to print a hook is with it lying on its side. -But then what about a back-plate that keeps it from twisting?..... So, this is what I arrived at.-Will update/change later, maybe.....
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,68 @@
|
||||
include <../lib/rounded-cube.scad>
|
||||
|
||||
$fn=256;
|
||||
|
||||
d=40;
|
||||
l=140;
|
||||
|
||||
module version1() {
|
||||
union() {
|
||||
difference() {
|
||||
union() {
|
||||
rotate([0, 10, 0]) cube([d, l, 50]);
|
||||
translate([1.5*d, 0, 0]) mirror([1, 0, 0]) rotate([0, 10, 0]) cube([d, l, 50]);
|
||||
}
|
||||
|
||||
translate([0.75*d, l+1, 0.5*d+12]) rotate([90, 0, 0]) cylinder(d=d, h=l+2);
|
||||
translate([-d, -1, 20]) cube([3*d, l + 2, 40]);
|
||||
translate([-d, -1, -10]) cube([3*d, l + 2, 10]);
|
||||
color("red") translate([-1, l*0.5+4, -124]) rotate([0, 90, 0]) cylinder(d=270, h=1.5*d+2);
|
||||
}
|
||||
|
||||
translate([0, 0, 0.01])
|
||||
difference() {
|
||||
rotate([-20, 0, 0])
|
||||
difference() {
|
||||
union() {
|
||||
rotate([0, 10, 0]) translate([0, 0, -15-0.01]) cube([1.4*d, 12, 30]);
|
||||
translate([1.5*d, 0, 0]) mirror([1, 0, 0]) rotate([0, 10, 0]) translate([0, 0, -15-0.01]) cube([1.4*d, 12, 30]);
|
||||
}
|
||||
}
|
||||
translate([-10, -10, -45]) cube([1.5*d + 20, 30, 35]);
|
||||
translate([-d, -10, 0]) cube([3.5*d, 40, 20]);
|
||||
translate([-10, -10, -20]) cube([1.5*d + 20, 10, 40]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module version2() {
|
||||
difference() {
|
||||
translate([0, 0, -10]) cube([1.5*d, l, 50]);
|
||||
|
||||
// mic handle cut-out
|
||||
translate([0.75*d, l+1, 0.5*d+12]) rotate([90, 0, 0]) cylinder(d=d, h=l+2);
|
||||
|
||||
// top cut
|
||||
translate([-10, -1, 0.5*d]) cube([1.5*d + 20, l+2, 50]);
|
||||
|
||||
// bottom notch cut
|
||||
translate([0, 12, 0]) rotate([-20, 0, 0]) translate([-1, 0, -20]) cube([1.5*d+2, 20, 20]);
|
||||
|
||||
// button flush cut
|
||||
translate([-1, 12, -20]) cube([1.5*d+2, l, 20]);
|
||||
|
||||
// MODX-8 button clearance
|
||||
union() {
|
||||
translate([0, 24, 0]) rotate([-20, 0, 0]) translate([-1, 0, -12]) cube([1.5*d+2, 20, 20.5]);
|
||||
translate([-1, 26.90, -12]) cube([1.5*d+2, l-50, 20]);
|
||||
translate([0, l-20, 0]) mirror([0, 1, 0]) rotate([-20, 0, 0]) translate([-1, 0, -12]) cube([1.5*d+2, 20, 20.5]);
|
||||
}
|
||||
|
||||
// side-cuts
|
||||
translate([-8, 0, 0]) rotate([0, 10, 0]) translate([0, -1, -20]) cube([10, l+2, 50]);
|
||||
color("red") translate([1.5*d, 0, 0]) mirror([1, 0, 0]) translate([-8, 0, 0])rotate([0, 10, 0]) translate([0, -1, -20]) cube([10, l+2, 50]);
|
||||
}
|
||||
}
|
||||
|
||||
//translate([2*d, 0, 0]) version1();
|
||||
version2();
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,27 @@
|
||||
include <../lib/threads/threads.scad>
|
||||
|
||||
$fn=256;
|
||||
|
||||
difference() {
|
||||
union() {
|
||||
translate([0, 0, 3.5]) cylinder(d1=34.3, d2=35.7, h=82, $fn=256);
|
||||
cylinder(d1=28, d2=34.3, h=3.5, $fn=256);
|
||||
}
|
||||
|
||||
translate([0, 0, 3.5]) cylinder(d=31, h=90, $fn=128);
|
||||
translate([0, 0, -1]) cylinder(d=27.6, h=10, $fn=128);
|
||||
|
||||
translate([0, 0, 82 + 3.5 - 20 - 4.3])
|
||||
difference() {
|
||||
AugerThread(outer_diam=36, inner_diam=29.8, height=20, pitch=3, tooth_angle=25, tip_min_fract=15);
|
||||
//ScrewThread(outer_diam=33, height=20, pitch=3, tooth_angle=5, tooth_height=0.8);
|
||||
|
||||
color("red")
|
||||
difference() {
|
||||
translate([0, 0, -1]) cylinder(d=40, h=22);
|
||||
translate([0, 0, -2]) cylinder(d=33, h=24);
|
||||
}
|
||||
}
|
||||
|
||||
translate([0, 0, 82 + 3.5 - 4.4]) cylinder(d=33, h=90, $fn=128);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
include <./insert-box.scad>;
|
||||
|
||||
$fn=64;
|
||||
dowelDiameter = 12.7; // 0.5 inch
|
||||
module dowel() {
|
||||
color("Sienna") rotate([0, 90, ])
|
||||
cylinder(h=innerSide, d=dowelDiameter, center=true);
|
||||
}
|
||||
|
||||
outerBox();
|
||||
supportingFelt();
|
||||
|
||||
translate([feltThickness + boardThickness, 0, feltThickness + boardThickness])
|
||||
union() {
|
||||
// Everything within this union is referenced off of the inner box. The outer
|
||||
// translate accounts for the felt and walls.
|
||||
|
||||
translate([innerSide/2, 0, innerSide - dowelDiameter*1.5]) // center dowels on X, raise Z
|
||||
union() {
|
||||
translate([0, kallaxDepth*0.25, 0]) dowel();
|
||||
translate([0, kallaxDepth*0.75, 0]) dowel();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
dowelDiameter = 12.7; // 1/2 inch in mm
|
||||
@@ -0,0 +1,8 @@
|
||||
$fn = 32;
|
||||
|
||||
l = 76;
|
||||
w = 50;
|
||||
th = 1;
|
||||
|
||||
color("black") cube([l, w, th], center=true);
|
||||
// color("white") translate([0, 0, th]) linear_extrude(0.2) text("Ethernet", font="monofur", halign="center", valign="center",size=12);
|
||||
@@ -0,0 +1,11 @@
|
||||
kallaxSide = 335; // Full width of a Kallax shelf
|
||||
kallaxDepth = 390; // Full depth of a Kallax shelf
|
||||
|
||||
shelfHeight = 160; // Height of a Kallax half-shelf (shelf insert)
|
||||
shelfWidth = 320; // Width of a Kallax half-shelf (shelf insert)
|
||||
shelfDepth = kallaxDepth - 20;
|
||||
|
||||
// boardThickness = 4.7; // 1/8" plywood
|
||||
boardThickness = 7.35;
|
||||
feltThickness = 2.5;
|
||||
feltWidth = 12;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,61 @@
|
||||
include <./constants.scad>;
|
||||
|
||||
boardThickness = 6.4;
|
||||
feltThickness = 2.4;
|
||||
feltWidth = 12;
|
||||
innerSide = kallaxSide - 2 * (feltThickness + boardThickness);
|
||||
|
||||
module feltStrip() {
|
||||
color("DimGray") cube([feltThickness, kallaxDepth, feltWidth]);
|
||||
}
|
||||
|
||||
module sideBoard() {
|
||||
difference() {
|
||||
color ("BurlyWood") cube([boardThickness, kallaxDepth, kallaxSide - 2*feltThickness]);
|
||||
color("black") translate([0.2, 100, 30]) rotate([90, 0, -90]) linear_extrude(0.3)
|
||||
text(font="Iosevka", size=16, halign="center", valign="center", "side - plywood");
|
||||
}
|
||||
}
|
||||
|
||||
module horizontalBoard() {
|
||||
difference() {
|
||||
color ("Wheat") cube([innerSide, kallaxDepth, boardThickness]);
|
||||
color("black") translate([110, 30, boardThickness - 0.2]) rotate([0, 0, 0]) linear_extrude(0.3)
|
||||
text(font="Iosevka", size=16, halign="center", valign="center", "top/bot - plywood");
|
||||
}
|
||||
}
|
||||
|
||||
module outerBox() {
|
||||
translate([feltThickness, 0, feltThickness]) union() {
|
||||
// left and right side boards
|
||||
translate([0, 0, 0]) sideBoard();
|
||||
translate([innerSide + boardThickness , 0, 0]) sideBoard();
|
||||
|
||||
// top and bottom horizontal boards
|
||||
translate([boardThickness, 0, 0]) horizontalBoard();
|
||||
translate([boardThickness, 0, innerSide + boardThickness]) horizontalBoard();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
module supportingFelt() {
|
||||
// felt strips for the left side
|
||||
translate([0, 0, feltThickness + 20]) feltStrip();
|
||||
translate([0, 0, (innerSide - feltThickness)/2]) feltStrip();
|
||||
translate([0, 0, feltThickness + innerSide - feltWidth - 20]) feltStrip();
|
||||
|
||||
// felt strips for the right side
|
||||
translate([innerSide + feltThickness + 2*boardThickness, 0, feltThickness + 20]) feltStrip();
|
||||
translate([innerSide + feltThickness + 2*boardThickness, 0, (innerSide - feltThickness)/2]) feltStrip();
|
||||
translate([innerSide + feltThickness + 2*boardThickness, 0, feltThickness + innerSide - feltWidth - 20]) feltStrip();
|
||||
|
||||
// felt strips for the top
|
||||
translate([feltWidth + boardThickness + 20, 0, 0]) rotate([0, -90, 0]) feltStrip();
|
||||
translate([(kallaxSide - feltWidth)/2, 0, 0]) rotate([0, -90, 0]) feltStrip();
|
||||
translate([kallaxSide - feltWidth - 20, 0, 0]) rotate([0, -90, 0]) feltStrip();
|
||||
|
||||
// felt strips for the bottom
|
||||
translate([feltWidth + 20, 0, kallaxSide - feltThickness]) rotate([0, -90, 0]) feltStrip();
|
||||
translate([(kallaxSide - feltWidth)/2, 0, kallaxSide - feltThickness]) rotate([0, -90, 0]) feltStrip();
|
||||
translate([kallaxSide - feltWidth - 20, 0, kallaxSide - feltThickness]) rotate([0, -90, 0]) feltStrip();
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
include <../lib/chamfered-cube.scad>
|
||||
include <../lib/rounded-cube.scad>
|
||||
include <./constants.scad>
|
||||
|
||||
$fn=128;
|
||||
l=shelfWidth/2;
|
||||
h=shelfHeight/2;
|
||||
|
||||
ep = 0.01;
|
||||
|
||||
horizontalBoardWidth = 141.5;
|
||||
drawerSideHeight = 53;
|
||||
sideOffset = 2*feltThickness + boardThickness;
|
||||
|
||||
module faceBlank() {
|
||||
size = [shelfWidth/2, shelfHeight/2, 8];
|
||||
chamfer = 4;
|
||||
difference() {
|
||||
roundedCube([l, h, 8], [1, 1, 1]);
|
||||
|
||||
// front face chamfers
|
||||
for (i = [1,3]) {
|
||||
// X-axis
|
||||
translate([-ep, size[1] * floor(i/2), size[2] * (i%2) - chamfer])
|
||||
rotate([45, 0, 0]) cube([size[0] + 2*ep, 1.414*chamfer, 1.414*chamfer]);
|
||||
|
||||
// Y-axis
|
||||
translate([size[0] * floor(i/2) - chamfer, -ep, size[2] * (i%2)])
|
||||
rotate([0, 45, 0]) cube([1.414*chamfer, size[1] + 2*ep, 1.414*chamfer]);
|
||||
}
|
||||
|
||||
// nameplate cutouts
|
||||
translate([(shelfWidth/2 - 76.4)/2, 30, 7]) cube([76.4, 36, 1 + ep]);
|
||||
translate([(shelfWidth/2 - 76.4)/2, 30 + 36, 7])
|
||||
rotate([30, 0, 0]) cube([76.4, 4, 4]);
|
||||
|
||||
// screw holes
|
||||
for (i = [-1, 1]) {
|
||||
color("red")
|
||||
translate([shelfWidth/4 + i*20, 16, -ep]) cylinder(d=3.4, h=8 + 2*ep);
|
||||
translate([shelfWidth/4 + i*20, 16, -ep]) cylinder(d=6.2, h=3 + ep);
|
||||
translate([shelfWidth/4 + i*20, 16, 3 - ep]) cylinder(d1=6.2, d2=3.4, h=1 + 2*ep);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module handle() {
|
||||
handleLen = 64;
|
||||
//difference() {
|
||||
chamferedCube([handleLen, 12, 12], chamfer=3);
|
||||
|
||||
// screw holes
|
||||
for (i = [-1, 1]) {
|
||||
difference() {
|
||||
translate([handleLen/2 + i*20, 6, 12-ep]) cylinder(d=6, h=8 + ep);
|
||||
translate([handleLen/2 + i*20, 6, 12-ep]) cylinder(d=3, h=8 + 2*ep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module lowerRight() {
|
||||
difference() {
|
||||
faceBlank();
|
||||
|
||||
// label
|
||||
color("blue")
|
||||
translate([shelfWidth/4 + 6, shelfHeight/4 - 6, -0.2]) mirror([1, 0, 0])
|
||||
linear_extrude(0.4) text(font="Iosevka", size=6, "LR");
|
||||
|
||||
// horizontal board recess
|
||||
translate([sideOffset, sideOffset, -ep])
|
||||
cube([horizontalBoardWidth, boardThickness, 4+ep]);
|
||||
|
||||
// vertical board recesses
|
||||
translate([sideOffset, sideOffset + boardThickness, -ep])
|
||||
cube([boardThickness, 62, 4+ep]);
|
||||
translate([sideOffset + horizontalBoardWidth - boardThickness, sideOffset + boardThickness, -ep])
|
||||
cube([boardThickness, 62, 4+ep]);
|
||||
}
|
||||
}
|
||||
|
||||
module lowerLeft() {
|
||||
difference() {
|
||||
faceBlank();
|
||||
|
||||
// label
|
||||
color("blue")
|
||||
translate([shelfWidth/4 + 6, shelfHeight/4 - 6, -0.2]) mirror([1, 0, 0])
|
||||
linear_extrude(0.4) text(font="Iosevka", size=6, "LL");
|
||||
}
|
||||
}
|
||||
|
||||
module upperRight() {
|
||||
difference() {
|
||||
faceBlank();
|
||||
|
||||
// label
|
||||
color("blue")
|
||||
translate([shelfWidth/4 + 6, shelfHeight/4 - 6, -0.2]) mirror([1, 0, 0])
|
||||
linear_extrude(0.4) text(font="Iosevka", size=6, "UR");
|
||||
}
|
||||
}
|
||||
|
||||
module upperLeft() {
|
||||
difference() {
|
||||
faceBlank();
|
||||
|
||||
// label
|
||||
color("blue")
|
||||
translate([shelfWidth/4 + 6, shelfHeight/4 - 6, -0.2]) mirror([1, 0, 0])
|
||||
linear_extrude(0.4) text(font="Iosevka", size=6, "UL");
|
||||
}
|
||||
}
|
||||
|
||||
lowerRight();
|
||||
translate([0, 200, 0]) handle();
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,525 @@
|
||||
// System to divide a Kallax half-shelf into four equal drawers
|
||||
// All units measured in millimeters
|
||||
include <../lib/mortice-and-tenon.scad>
|
||||
include <./constants.scad>
|
||||
|
||||
$fn = 32;
|
||||
|
||||
module sampleBox(dims, wallThickness) {
|
||||
// base
|
||||
cube([dims[0], dims[1], wallThickness]);
|
||||
|
||||
// top
|
||||
translate([0, 0, dims[2] - wallThickness])
|
||||
cube([dims[0], dims[1], wallThickness]);
|
||||
|
||||
// middle shelf
|
||||
translate([0, 0, (dims[2] - wallThickness) / 2])
|
||||
cube([dims[0], dims[1], wallThickness]);
|
||||
|
||||
// left wall
|
||||
cube([wallThickness, dims[1], dims[2]]);
|
||||
|
||||
// middle divider
|
||||
translate([(dims[0] - wallThickness) / 2, 0, 0])
|
||||
cube([wallThickness, dims[1], dims[2]]);
|
||||
|
||||
// right wall
|
||||
translate([dims[0] - wallThickness, 0, 0])
|
||||
cube([wallThickness, dims[1], dims[2]]);
|
||||
|
||||
}
|
||||
|
||||
module tally(count, rightAlign = false) {
|
||||
groups = floor(count / 5);
|
||||
rem = count % 5;
|
||||
xAlign = rightAlign ? -(6 * groups) - (rem * 1.2) : 0;
|
||||
translate([xAlign, 0, 0])
|
||||
union() {
|
||||
if (count > 4) {
|
||||
for (i = [0: max(0, groups - 1)]) {
|
||||
translate([6*i, 0, 0]) for (j = [0:3])
|
||||
translate([j*1.2, 0, 0])
|
||||
cube([0.6, 4, 0.41]);
|
||||
translate([6*i - 0.8, 0.6, 0]) rotate([0, 0, -60]) cube([0.6, 6.2, 0.41]);
|
||||
}
|
||||
}
|
||||
|
||||
if (rem != 0) {
|
||||
translate([6*groups, 0, 0])
|
||||
for (j = [0: rem - 1])
|
||||
translate([j*1.2, 0, 0])
|
||||
cube([0.6, 4, 0.41]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wallThickness = 4; // Thickness of walls
|
||||
feltClearance = 2.5; // Clearance for felt pads
|
||||
|
||||
// Dimensions for the box that fits inside a Kallax half-shelf
|
||||
boxWidth = kallaxSide - 2 * feltClearance;
|
||||
boxDepth = kallaxDepth;
|
||||
boxHeight = shelfHeight - 2 * feltClearance;
|
||||
|
||||
drawerWidth = (boxWidth - 3 * wallThickness) / 2;
|
||||
drawerHeight = (boxHeight - 3 * wallThickness) / 2;
|
||||
|
||||
tenonThickness = wallThickness * 0.6;
|
||||
//tenon([6, 8, 2.6]);
|
||||
//morticeBlank([6, 8, 2.6], 0.1);
|
||||
|
||||
|
||||
// Frame for the box will be made in sections to fit on the print bed
|
||||
// There are three identical horizontal layers (base, middle shelf, top) that
|
||||
// will each be made of four pieces. Looking down overhead from the Z axis they
|
||||
// are:
|
||||
//
|
||||
// x1 x2
|
||||
// ├──┴──┼─┴─┤
|
||||
// ┌─────┬───┐ ┬
|
||||
// │ C │ D │ │
|
||||
// ├─────┼───┤ ├y
|
||||
// │ A │ B │ │
|
||||
// └─────┴───┘ ┴
|
||||
//
|
||||
// There are three identical drawer sides for the lower drawers that are split
|
||||
// into two pieces. Looking from the side, along the X axis they are:
|
||||
//
|
||||
// ├───y───┤
|
||||
// ┌───┬───┐ ┬
|
||||
// │ F │ E │ ├drawerHeight
|
||||
// └───┴───┘ ┴
|
||||
//
|
||||
// There are three identical drawer sides for the upper drawers that are split
|
||||
// into two pieces. Looking from the side, along the X axis they are:
|
||||
//
|
||||
// ├───y───┤
|
||||
// ┌───┬───┐ ┬
|
||||
// │ H │ G │ ├drawerHeight
|
||||
// └───┴───┘ ┴
|
||||
|
||||
x1 = boxWidth * 0.6;
|
||||
x2 = boxWidth - x1;
|
||||
y = boxDepth / 2;
|
||||
tenonDims = [6, 8, tenonThickness];
|
||||
tenonZOffset = (wallThickness - tenonThickness) / 2;
|
||||
verticalTenonDims = [6, wallThickness, tenonThickness];
|
||||
throughTenonDims = [6, 8 + wallThickness, tenonThickness];
|
||||
morticeClearance = 0.1;
|
||||
|
||||
module leftSideHorizontalPiece(cutWeight = true) {
|
||||
difference() {
|
||||
cube([x1, y, wallThickness]);
|
||||
|
||||
if (cutWeight) {
|
||||
union() {
|
||||
// cutouts to save materials
|
||||
translate([2*wallThickness, 2*wallThickness, -0.1])
|
||||
cube([drawerWidth - 2*wallThickness, y/2 - 3*wallThickness, wallThickness + 0.2]);
|
||||
|
||||
translate([2*wallThickness, y/2 + wallThickness, -0.1])
|
||||
cube([drawerWidth - 2*wallThickness, y/2 - 3*wallThickness, wallThickness + 0.2]);
|
||||
|
||||
translate([drawerWidth + 3*wallThickness, 2*wallThickness, -0.1])
|
||||
cube([x1 - drawerWidth - 5*wallThickness, y/2 - 3*wallThickness, wallThickness + 0.2]);
|
||||
|
||||
translate([drawerWidth + 3*wallThickness, y/2 + 2*wallThickness, -0.1])
|
||||
cube([x1 - drawerWidth - 5*wallThickness, y/2 - 3*wallThickness, wallThickness + 0.2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module rightSideHorizontalPiece(cutWeight = true) {
|
||||
difference() {
|
||||
cube([x2, y, wallThickness]);
|
||||
|
||||
if (cutWeight) {
|
||||
union() {
|
||||
// cutouts to save materials
|
||||
translate([2*wallThickness, 2*wallThickness, -0.1])
|
||||
cube([x2 - 4*wallThickness, y/2 - 3*wallThickness, wallThickness + 0.2]);
|
||||
translate([2*wallThickness, y/2 + wallThickness, -0.1])
|
||||
cube([x2 - 4*wallThickness, y/2 - 3*wallThickness, wallThickness + 0.2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module sidePiece(cutWeight = true) {
|
||||
union() {
|
||||
difference() {
|
||||
cube([wallThickness, y, drawerHeight]);
|
||||
|
||||
if (cutWeight) {
|
||||
// cutouts to save materials
|
||||
translate([-0.1, 2*wallThickness, 2*wallThickness])
|
||||
cube([wallThickness + 0.2, y - 4*wallThickness, drawerHeight - 3*wallThickness]);
|
||||
}
|
||||
}
|
||||
|
||||
if (cutWeight) {
|
||||
translate([0, wallThickness, 1.414*wallThickness])
|
||||
rotate([-41, 0, 0])
|
||||
cube([wallThickness, wallThickness, drawerHeight * 1.19]);
|
||||
|
||||
translate([0, y - 2*wallThickness, 1.414*wallThickness])
|
||||
rotate([65, 0, 0])
|
||||
cube([wallThickness, wallThickness, drawerHeight * 1.97]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module pieceA(cutWeight = true) {
|
||||
difference() {
|
||||
union() {
|
||||
leftSideHorizontalPiece(cutWeight);
|
||||
|
||||
// tenons for joining to piece C
|
||||
translate([x1*0.2, y, tenonZOffset]) tenon(tenonDims);
|
||||
translate([x1*0.7, y, tenonZOffset]) tenon(tenonDims);
|
||||
|
||||
// tenons for joining to piece B
|
||||
translate([x1, y*0.2, tenonZOffset])
|
||||
mirror([0, 1, 0]) rotate([0, 0, -90]) tenon(tenonDims);
|
||||
translate([x1, y*0.7, tenonZOffset])
|
||||
mirror([0, 1, 0]) rotate([0, 0, -90]) tenon(tenonDims);
|
||||
}
|
||||
|
||||
union() {
|
||||
// mortices for joining to piece vertical pieces
|
||||
translate([tenonZOffset, y* 0.3, 0]) rotate([90, 0, 90])
|
||||
morticeBlank(verticalTenonDims, morticeClearance);
|
||||
translate([tenonZOffset, y* 0.8, 0]) rotate([90, 0, 90])
|
||||
morticeBlank(verticalTenonDims, morticeClearance);
|
||||
|
||||
translate([drawerWidth + wallThickness + tenonZOffset, y* 0.3, 0])
|
||||
rotate([90, 0, 90]) morticeBlank(verticalTenonDims, morticeClearance);
|
||||
translate([drawerWidth + wallThickness + tenonZOffset, y* 0.8, 0])
|
||||
rotate([90, 0, 90]) morticeBlank(verticalTenonDims, morticeClearance);
|
||||
|
||||
// piece label
|
||||
translate([2, 2, wallThickness - 0.4]) tally(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module pieceB(cutWeight = true) {
|
||||
difference() {
|
||||
union() {
|
||||
rightSideHorizontalPiece(cutWeight);
|
||||
|
||||
// tenons for joining to piece D
|
||||
translate([x2*0.2, y, tenonZOffset]) tenon(tenonDims);
|
||||
translate([x2*0.7, y, tenonZOffset]) tenon(tenonDims);
|
||||
}
|
||||
|
||||
union() {
|
||||
// mortices for joining to piece A
|
||||
translate([0, y*0.2, tenonZOffset])
|
||||
mirror([0, 1, 0]) rotate([0, 0, -90])
|
||||
morticeBlank(tenonDims, morticeClearance);
|
||||
translate([0, y*0.7, tenonZOffset])
|
||||
mirror([0, 1, 0]) rotate([0, 0, -90])
|
||||
morticeBlank(tenonDims, morticeClearance);
|
||||
|
||||
// mortices for joining to piece vertical pieces
|
||||
translate([x2 - wallThickness + tenonZOffset, y* 0.3, 0])
|
||||
rotate([90, 0, 90]) morticeBlank(tenonDims, morticeClearance);
|
||||
|
||||
translate([x2 - wallThickness + tenonZOffset, y* 0.8, 0])
|
||||
rotate([90, 0, 90]) morticeBlank(tenonDims, morticeClearance);
|
||||
|
||||
// piece label
|
||||
translate([2, 2, wallThickness - 0.4]) tally(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module pieceC(cutWeight = true) {
|
||||
difference() {
|
||||
union() {
|
||||
leftSideHorizontalPiece(cutWeight);
|
||||
|
||||
// tenons for joining to piece D
|
||||
translate([x1, y*0.2, tenonZOffset])
|
||||
mirror([0, 1, 0]) rotate([0, 0, -90]) tenon(tenonDims);
|
||||
translate([x1, y*0.7, tenonZOffset])
|
||||
mirror([0, 1, 0]) rotate([0, 0, -90]) tenon(tenonDims);
|
||||
}
|
||||
|
||||
union() {
|
||||
|
||||
// mortices for joining to piece A
|
||||
translate([x1*0.2, 0, tenonZOffset])
|
||||
morticeBlank(tenonDims, morticeClearance);
|
||||
translate([x1*0.7, 0, tenonZOffset])
|
||||
morticeBlank(tenonDims, morticeClearance);
|
||||
|
||||
// mortices for joining to piece F/H
|
||||
translate([tenonZOffset, y* 0.3, 0]) rotate([90, 0, 90])
|
||||
morticeBlank(verticalTenonDims, morticeClearance);
|
||||
translate([tenonZOffset, y* 0.8, 0]) rotate([90, 0, 90])
|
||||
morticeBlank(verticalTenonDims, morticeClearance);
|
||||
|
||||
translate([drawerWidth + wallThickness + tenonZOffset, y* 0.3, 0])
|
||||
rotate([90, 0, 90]) morticeBlank(verticalTenonDims, morticeClearance);
|
||||
translate([drawerWidth + wallThickness + tenonZOffset, y* 0.8, 0])
|
||||
rotate([90, 0, 90]) morticeBlank(verticalTenonDims, morticeClearance);
|
||||
|
||||
// piece label
|
||||
translate([2, 2, wallThickness - 0.4]) tally(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module pieceD(cutWeight = true) {
|
||||
difference() {
|
||||
rightSideHorizontalPiece(cutWeight);
|
||||
|
||||
union() {
|
||||
// mortices for joining to piece C
|
||||
translate([0, y*0.2, tenonZOffset])
|
||||
mirror([0, 1, 0]) rotate([0, 0, -90])
|
||||
morticeBlank(tenonDims, morticeClearance);
|
||||
translate([0, y*0.7, tenonZOffset])
|
||||
mirror([0, 1, 0]) rotate([0, 0, -90])
|
||||
morticeBlank(tenonDims, morticeClearance);
|
||||
|
||||
// mortices for joining to piece B
|
||||
translate([x2*0.2, 0, tenonZOffset])
|
||||
morticeBlank(tenonDims, morticeClearance);
|
||||
translate([x2*0.7, 0, tenonZOffset])
|
||||
morticeBlank(tenonDims, morticeClearance);
|
||||
// mortices for joining to piece F/H
|
||||
translate([x2 - wallThickness + tenonZOffset, y* 0.3, 0])
|
||||
rotate([90, 0, 90]) morticeBlank(tenonDims, morticeClearance);
|
||||
|
||||
translate([x2 - wallThickness + tenonZOffset, y* 0.8, 0])
|
||||
rotate([90, 0, 90]) morticeBlank(tenonDims, morticeClearance);
|
||||
|
||||
// piece label
|
||||
translate([2, 2, wallThickness - 0.4]) tally(4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module pieceE(cutWeight = true) {
|
||||
difference() {
|
||||
union() {
|
||||
sidePiece(cutWeight);
|
||||
|
||||
// tenons for joining to horizontal pieces
|
||||
translate([tenonZOffset, y*0.3, 0]) mirror([1, 0, 0])
|
||||
rotate([-90, 0, 90]) tenon(verticalTenonDims);
|
||||
translate([tenonZOffset, y*0.8, 0]) mirror([1, 0, 0])
|
||||
rotate([-90, 0, 90]) tenon(verticalTenonDims);
|
||||
|
||||
// tenon for joining to piece F
|
||||
translate([tenonZOffset, y, drawerHeight/2]) mirror([0, 0, 1])
|
||||
rotate([0, 90, 00]) tenon(tenonDims);
|
||||
|
||||
// tenons for joining to piece G
|
||||
translate([tenonZOffset, y*0.3, drawerHeight]) rotate([90, 0, 90])
|
||||
tenon(throughTenonDims);
|
||||
translate([tenonZOffset, y*0.8, drawerHeight]) rotate([90, 0, 90])
|
||||
tenon(throughTenonDims);
|
||||
//translate([tenonZOffset, y*0.8, 0]) mirror([1, 0, 0])
|
||||
// rotate([-90, 0, 90]) tenon(verticalTenonDims);
|
||||
}
|
||||
|
||||
// piece label
|
||||
translate([0.4, 2, 2]) rotate([90, 0, -90]) tally(5, true);
|
||||
}
|
||||
}
|
||||
|
||||
module pieceF(cutWeight = true) {
|
||||
difference() {
|
||||
union() {
|
||||
sidePiece(cutWeight);
|
||||
|
||||
// tenons for joining to horizontal pieces
|
||||
translate([tenonZOffset, y*0.3, 0]) mirror([1, 0, 0])
|
||||
rotate([-90, 0, 90]) tenon(verticalTenonDims);
|
||||
translate([tenonZOffset, y*0.8, 0]) mirror([1, 0, 0])
|
||||
rotate([-90, 0, 90]) tenon(verticalTenonDims);
|
||||
|
||||
// tenons for joining to piece H
|
||||
translate([tenonZOffset, y*0.3, drawerHeight]) rotate([90, 0, 90])
|
||||
tenon(throughTenonDims);
|
||||
translate([tenonZOffset, y*0.8, drawerHeight]) rotate([90, 0, 90])
|
||||
tenon(throughTenonDims);
|
||||
|
||||
}
|
||||
|
||||
union() {
|
||||
// mortice for joining to piece E
|
||||
translate([tenonZOffset, 0, drawerHeight/2]) mirror([0, 0, 1])
|
||||
rotate([0, 90, 00]) tenon(tenonDims);
|
||||
|
||||
// piece label
|
||||
translate([0.4, 2, 2]) rotate([90, 0, -90]) tally(6, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module pieceG(cutWeight = true) {
|
||||
difference() {
|
||||
union() {
|
||||
sidePiece(cutWeight);
|
||||
|
||||
// tenons for joining to vertical pieces above
|
||||
translate([tenonZOffset, y*0.3, drawerHeight]) rotate([90, 0, 90])
|
||||
tenon(verticalTenonDims);
|
||||
translate([tenonZOffset, y*0.8, drawerHeight]) rotate([90, 0, 90])
|
||||
tenon(verticalTenonDims);
|
||||
|
||||
// tenon for joining to piece H
|
||||
translate([tenonZOffset, y, drawerHeight/2]) mirror([0, 0, 1])
|
||||
rotate([0, 90, 00]) tenon(tenonDims);
|
||||
|
||||
|
||||
}
|
||||
|
||||
union() {
|
||||
// mortices for joining to piece E
|
||||
translate([tenonZOffset, y*0.3, 0]) rotate([90, 0, 90])
|
||||
morticeBlank(verticalTenonDims, morticeClearance);
|
||||
translate([tenonZOffset, y*0.8, 0]) rotate([90, 0, 90])
|
||||
morticeBlank(verticalTenonDims, morticeClearance);
|
||||
|
||||
// piece label
|
||||
translate([0.4, 2, 2]) rotate([90, 0, -90]) tally(7, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module pieceH(cutWeight = true) {
|
||||
difference() {
|
||||
union() {
|
||||
sidePiece(cutWeight);
|
||||
|
||||
// tenons for joining to vertical pieces above
|
||||
translate([tenonZOffset, y*0.3, drawerHeight]) rotate([90, 0, 90])
|
||||
tenon(verticalTenonDims);
|
||||
translate([tenonZOffset, y*0.8, drawerHeight]) rotate([90, 0, 90])
|
||||
tenon(verticalTenonDims);
|
||||
}
|
||||
|
||||
union() {
|
||||
// mortices for joining to piece F
|
||||
translate([tenonZOffset, y*0.3, 0]) rotate([90, 0, 90])
|
||||
morticeBlank(verticalTenonDims, morticeClearance);
|
||||
translate([tenonZOffset, y*0.8, 0]) rotate([90, 0, 90])
|
||||
morticeBlank(verticalTenonDims, morticeClearance);
|
||||
|
||||
// mortice for joining to piece G
|
||||
translate([tenonZOffset, 0, drawerHeight/2]) mirror([0, 0, 1])
|
||||
rotate([0, 90, 00]) tenon(tenonDims);
|
||||
|
||||
// piece label
|
||||
translate([0.4, 2, 2]) rotate([90, 0, -90]) tally(8, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Mortice and tenon test pieces
|
||||
// rotate([0, 90, 0]) union() {
|
||||
// cube([10, 16, wallThickness]);
|
||||
// translate([2, 16, tenonZOffset]) tenon(tenonDims);
|
||||
// }
|
||||
//
|
||||
// translate([10, 0, 0]) rotate([0, 90, 0]) difference() {
|
||||
// cube([10, 16, wallThickness]);
|
||||
// translate([2 - 0.1, 16 - 0.1, tenonZOffset - 0.1])
|
||||
// mirror([0, 1, 0]) morticeBlank(tenonDims, morticeClearance);
|
||||
// }
|
||||
|
||||
module completeBox(gap = 10, cutWeight = true) {
|
||||
|
||||
// vertical layers
|
||||
for (i = [0:2]) {
|
||||
z = i * (wallThickness + 1.5*gap + drawerHeight);
|
||||
translate([0, 0, z]) pieceA(cutWeight);
|
||||
translate([x1 + gap, 0, z]) pieceB(cutWeight);
|
||||
translate([0, y + gap, z]) pieceC(cutWeight);
|
||||
translate([x1 + gap, y + gap, z]) pieceD(cutWeight);
|
||||
}
|
||||
|
||||
// lower box walls
|
||||
for (i = [0:2]) {
|
||||
x = i * (wallThickness + drawerWidth) +
|
||||
(i == 2 ? gap : 0);
|
||||
|
||||
translate([x, 0, wallThickness + gap]) pieceE(cutWeight);
|
||||
translate([x, y + gap, wallThickness + gap]) pieceF(cutWeight);
|
||||
}
|
||||
|
||||
// upper box walls
|
||||
for (i = [0:2]) {
|
||||
x = i * (wallThickness + drawerWidth) +
|
||||
(i == 2 ? gap : 0);
|
||||
|
||||
translate([x, 0, drawerHeight + 2*wallThickness + 2*gap]) pieceG(cutWeight);
|
||||
translate([x, y + gap, drawerHeight + 2*wallThickness + 2*gap]) pieceH(cutWeight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module printStack() {
|
||||
for (i = [0:2]) {
|
||||
translate([0, 0, i * (wallThickness + 0.4)]) pieceA();
|
||||
translate([0, 0, (i+3) * (wallThickness + 0.4)]) pieceC();
|
||||
translate([0, 0, (i+6) * (wallThickness + 0.4)]) pieceB();
|
||||
translate([0, 0, (i+9) * (wallThickness + 0.4)]) pieceD();
|
||||
|
||||
translate([
|
||||
0,
|
||||
y + drawerHeight +throughTenonDims[1] + 4,
|
||||
i * (wallThickness + 0.4) + wallThickness])
|
||||
rotate([90, 90, 0]) pieceE();
|
||||
|
||||
translate([0,
|
||||
y + drawerHeight +throughTenonDims[1] + 4,
|
||||
(i+3) * (wallThickness + 0.4) + wallThickness])
|
||||
rotate([90, 90, 0]) pieceF();
|
||||
|
||||
translate([
|
||||
0,
|
||||
y + drawerHeight +throughTenonDims[1] + 4,
|
||||
(i+6) * (wallThickness + 0.4) + wallThickness])
|
||||
rotate([90, 90, 0]) pieceG();
|
||||
|
||||
translate([
|
||||
0,
|
||||
y + drawerHeight +throughTenonDims[1] + 4,
|
||||
(i+9) * (wallThickness + 0.4) + wallThickness])
|
||||
rotate([90, 90, 0]) pieceH();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
module testStack() {
|
||||
for (i = [0:2]) {
|
||||
translate([0, 0, i * (wallThickness + 0.4)]) pieceA();
|
||||
translate([0, 0, (i+3) * (wallThickness + 0.4)]) pieceB();
|
||||
|
||||
translate([
|
||||
0,
|
||||
y + drawerHeight +throughTenonDims[1] + 4,
|
||||
i * (wallThickness + 0.4) + wallThickness])
|
||||
rotate([90, 90, 0]) pieceE();
|
||||
|
||||
translate([0,
|
||||
y + drawerHeight +throughTenonDims[1] + 4,
|
||||
(i+3) * (wallThickness + 0.4) + wallThickness])
|
||||
rotate([90, 90, 0]) pieceF();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
completeBox(gap = 10, cutWeight = false);
|
||||
// testStack();
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,632 @@
|
||||
include <./constants.scad>
|
||||
include <../lib/metric-machine-screws.scad>
|
||||
include <../lib/chamfered-cube.scad>
|
||||
include <../lib/rounded-cube.scad>
|
||||
|
||||
// all measurements in mm
|
||||
$fn=128;
|
||||
ep = 0.01;
|
||||
clipThickness = boardThickness + 2*feltThickness;
|
||||
clipWallThickness = 4;
|
||||
clipFlangeLength = 24;
|
||||
clipFlangeWidth = 16;
|
||||
drawerSideOffset = 2*feltThickness + boardThickness;
|
||||
|
||||
// measurements for the wooden panels to cut:
|
||||
//
|
||||
// ───────────── - top board (A)
|
||||
// │ │ │
|
||||
// │───────────│
|
||||
// │ │ │
|
||||
// │───────────│
|
||||
//
|
||||
//
|
||||
// top board: 320.0 x 370.0
|
||||
// bottom board: 305.6 x 370.0 (320 - 2*4.7 - 2*2.5) x 370
|
||||
// side boards: 152.8 x 370.0 (160 - 4.7 - 2.5) x 370
|
||||
// inner boards: 70.45 x 370.0 ((160 - 3*4.7 - 2*2.5)/2) x 370
|
||||
//
|
||||
|
||||
function drawerWidth(boxDims) = (boxDims[0] - 3*boardThickness - 4*feltThickness)/2 + 2;
|
||||
function drawerHeight(boxDims) = (boxDims[2] - 3*boardThickness - 4*feltThickness)/2;
|
||||
|
||||
module fastenerBlank() {
|
||||
translate([0, 0.1 + 2 * clipWallThickness + boardThickness, 0])
|
||||
rotate([90, 0, 0])
|
||||
m3Nut(h=2.41);
|
||||
|
||||
translate([0, 2.4, 0])
|
||||
rotate([90, 0, 0])
|
||||
m3Nut(h=2.41);
|
||||
|
||||
translate([0, 0.1 + 2 * clipWallThickness + boardThickness, 0])
|
||||
rotate([90, 0, 0])
|
||||
cylinder(d = 3.2, center = false, $fn=128,
|
||||
h = 0.2 + 2 * clipWallThickness + boardThickness);
|
||||
}
|
||||
|
||||
module dowelBlank() {
|
||||
translate([0, 0.1 + 2 * clipWallThickness + boardThickness, 0])
|
||||
rotate([90, 0, 0])
|
||||
cylinder(d = 3.175, center = false, $fn=128,
|
||||
h = 0.2 + 2 * clipWallThickness + boardThickness);
|
||||
}
|
||||
|
||||
module cornerClipA() {
|
||||
difference() {
|
||||
cube([clipFlangeLength, clipFlangeLength, clipFlangeLength]);
|
||||
|
||||
translate([clipWallThickness, clipWallThickness, clipWallThickness])
|
||||
union() {
|
||||
cube([clipFlangeLength, boardThickness, clipFlangeLength]);
|
||||
cube([boardThickness, clipFlangeLength, clipFlangeLength]);
|
||||
}
|
||||
|
||||
translate([
|
||||
boardThickness + 2*clipWallThickness,
|
||||
boardThickness + 2*clipWallThickness,
|
||||
-1 ])
|
||||
cube([clipFlangeLength, clipFlangeLength, clipFlangeLength + 2]);
|
||||
|
||||
for (i = [-1, 0]) {
|
||||
rotate([0, 0, i * 180])
|
||||
mirror([i * 1, i * 1, 0])
|
||||
translate([
|
||||
clipFlangeLength - clipWallThickness,
|
||||
0,
|
||||
clipFlangeLength - clipWallThickness])
|
||||
dowelBlank();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module cornerClip() {
|
||||
difference() {
|
||||
cube([clipThickness, clipThickness, clipThickness]);
|
||||
|
||||
translate([feltThickness, feltThickness, feltThickness])
|
||||
cube([boardThickness, clipThickness, clipThickness]);
|
||||
|
||||
translate([feltThickness, feltThickness, feltThickness])
|
||||
cube([clipThickness, boardThickness, clipThickness]);
|
||||
}
|
||||
}
|
||||
|
||||
module sideClipA() {
|
||||
translate([clipFlangeLength, 0, 0])
|
||||
difference() {
|
||||
translate([-clipFlangeLength, 0, 0])
|
||||
cube([2 * clipFlangeLength, clipFlangeLength, clipFlangeLength + boardThickness]);
|
||||
|
||||
translate([0, clipWallThickness, clipWallThickness])
|
||||
union() {
|
||||
translate([-0.1 - clipFlangeLength, 0, 0])
|
||||
cube([2*clipFlangeLength + 0.2, clipFlangeLength, boardThickness]);
|
||||
|
||||
translate([-boardThickness/2, 0, 0])
|
||||
cube([boardThickness, clipFlangeLength, clipFlangeLength + boardThickness]);
|
||||
}
|
||||
|
||||
for (i = [0, 1]) {
|
||||
mirror([i, 0, 0])
|
||||
translate([
|
||||
clipWallThickness + boardThickness/2,
|
||||
-0.1,
|
||||
2*clipWallThickness + boardThickness])
|
||||
cube(clipFlangeLength+0.2);
|
||||
}
|
||||
|
||||
for (i = [0:2]) {
|
||||
translate([0, 0, boardThickness/2 + clipWallThickness])
|
||||
rotate([0, i*-90, 0])
|
||||
translate([
|
||||
clipFlangeLength - 2*clipWallThickness,
|
||||
clipFlangeLength - 2*clipWallThickness,
|
||||
-boardThickness/2 - clipWallThickness])
|
||||
rotate([90, 0, 0])
|
||||
dowelBlank();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module sideClip() {
|
||||
difference() {
|
||||
cube([clipThickness, 2 * clipThickness, clipThickness]);
|
||||
|
||||
translate([-0.1, feltThickness, feltThickness])
|
||||
cube([clipThickness + 0.2, boardThickness, clipThickness]);
|
||||
|
||||
translate([feltThickness, feltThickness, feltThickness])
|
||||
cube([boardThickness, 2 * clipThickness, clipThickness]);
|
||||
}
|
||||
}
|
||||
|
||||
module crossClipA() {
|
||||
cutoutLength = 2*clipFlangeLength + boardThickness;
|
||||
//translate([cutoutLength/2, 0, cutoutLength/2])
|
||||
difference() {
|
||||
translate([-cutoutLength/2, 0, -cutoutLength/2])
|
||||
cube([cutoutLength, clipFlangeLength, cutoutLength]);
|
||||
|
||||
translate([-cutoutLength/2-0.1, clipWallThickness, -boardThickness/2])
|
||||
cube([2*clipFlangeLength + boardThickness + 0.2, clipFlangeLength, boardThickness]);
|
||||
|
||||
translate([-boardThickness/2, clipWallThickness, -cutoutLength/2-0.1])
|
||||
cube([boardThickness, clipFlangeLength, 2*clipFlangeLength + boardThickness + 0.2]);
|
||||
|
||||
for (i = [0:3]) {
|
||||
rotate([0, i*90, 0])
|
||||
translate([
|
||||
clipWallThickness + boardThickness/2,
|
||||
-0.1,
|
||||
clipWallThickness + boardThickness/2])
|
||||
cube(clipFlangeLength+0.2);
|
||||
}
|
||||
|
||||
for (i = [0:3]) {
|
||||
rotate([0, i*-90, 0])
|
||||
translate([clipFlangeLength - clipWallThickness, clipFlangeLength - 1.5*clipWallThickness, -clipWallThickness - boardThickness/2])
|
||||
rotate([90, 0, 0])
|
||||
dowelBlank();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module printableSet() {
|
||||
difference() {
|
||||
translate([0, 0, -1.4])
|
||||
union() {
|
||||
for (i = [0:7])
|
||||
translate([i * (clipThickness + 2), clipThickness, 0])
|
||||
rotate([45, 0, 0])
|
||||
cornerClip();
|
||||
|
||||
for (i = [0:7])
|
||||
translate([i * (clipThickness + 2), 3 * clipThickness, 0])
|
||||
rotate([0, 0, 0])
|
||||
sideClip();
|
||||
|
||||
for (i = [0:1])
|
||||
translate([i * (2 * clipThickness + 2), 7 * clipThickness, 0])
|
||||
rotate([45, 0, 0])
|
||||
crossClip();
|
||||
}
|
||||
|
||||
translate([-1, -1, -1.4]) cube([100, 100, 1.4]);
|
||||
}
|
||||
}
|
||||
|
||||
module printableSetA() {
|
||||
difference() {
|
||||
union() {
|
||||
translate([20, 0, -4.82])
|
||||
for (i = [0:7])
|
||||
translate([i%4 * (clipFlangeLength + 16), 2*floor(i/4) * clipFlangeLength, 0])
|
||||
rotate([45, -45, 0])
|
||||
cornerClipA();
|
||||
|
||||
translate([0, 0, -2])
|
||||
for (i = [0:7])
|
||||
translate([i%4 * (2*clipFlangeLength + 16), (4 + 2*floor(i/4)) * clipFlangeLength, 0])
|
||||
rotate([45, 0, 0])
|
||||
sideClipA();
|
||||
|
||||
for (i = [0:1])
|
||||
translate([30 + i * (2 * clipFlangeLength + 16), 8.5 * clipFlangeLength, 0])
|
||||
rotate([90, 0, 0])
|
||||
crossClipA();
|
||||
}
|
||||
|
||||
translate([-20, -20, -10]) cube([500, 300, 10]);
|
||||
}
|
||||
}
|
||||
|
||||
module containingBox(boxDims) {
|
||||
difference() {
|
||||
cube([boxDims[0] + 12, boxDims[1], boxDims[2] + 12]);
|
||||
translate([6, -0.1, 6])
|
||||
cube([boxDims[0], boxDims[1] + 0.2, boxDims[2]]);
|
||||
}
|
||||
}
|
||||
|
||||
module feltClearanceBox(boxDims) {
|
||||
difference() {
|
||||
cube([boxDims[0], boxDims[1], boxDims[2]]);
|
||||
|
||||
translate([feltThickness, -0.1, feltThickness])
|
||||
cube([boxDims[0] - 2*feltThickness, boxDims[1] + 0.2, boxDims[2] - 2*feltThickness]);
|
||||
}
|
||||
}
|
||||
|
||||
module topPanel(boxDims) {
|
||||
difference() {
|
||||
color("BurlyWood") cube([boxDims[0], boxDims[1], boardThickness]);
|
||||
color("black") translate([10, 10, boardThickness - 1]) linear_extrude(1.1)
|
||||
text(font="Iosevka", size=16, "top - plywood");
|
||||
}
|
||||
}
|
||||
|
||||
module sidePanel(boxDims) {
|
||||
difference() {
|
||||
color("Wheat") cube([boxDims[2] - boardThickness, boxDims[1], boardThickness]);
|
||||
color("black") rotate([0, 0, -90]) translate([-10, 10, boardThickness - 1]) linear_extrude(1.1)
|
||||
text(font="Iosevka", halign = "right", size=16, "side - plywood");
|
||||
}
|
||||
}
|
||||
|
||||
module innerPanel(boxDims) {
|
||||
difference() {
|
||||
color("BlanchedAlmond") cube([(boxDims[2] - 3*boardThickness) / 2, boxDims[1], boardThickness]);
|
||||
color("black") rotate([0, 0, -90]) translate([-10, 10, boardThickness - 1]) linear_extrude(1.1)
|
||||
text(font="Iosevka", halign = "right", size=16, "inner panel - plywood");
|
||||
}
|
||||
}
|
||||
|
||||
module bottomPanel(boxDims) {
|
||||
difference() {
|
||||
color ("Tan") cube([boxDims[0] - 2*boardThickness, boxDims[1], boardThickness]);
|
||||
color("black") translate([10, 10, boardThickness - 1]) linear_extrude(1.1)
|
||||
text(font="Iosevka", size=16, "bottom - plywood");
|
||||
}
|
||||
}
|
||||
|
||||
module drawerFacePlateBlank(boxDims) {
|
||||
size = [boxDims[0]/2 - 1, boxDims[2]/2 - 1, 8];
|
||||
chamfer = 4;
|
||||
|
||||
difference() {
|
||||
roundedCube(size, [1, 1, 1]);
|
||||
|
||||
// front face chamfers
|
||||
for (i = [1,3]) {
|
||||
// X-axis
|
||||
translate([-ep, size[1] * floor(i/2), size[2] * (i%2) - chamfer])
|
||||
rotate([45, 0, 0]) cube([size[0] + 2*ep, 1.414*chamfer, 1.414*chamfer]);
|
||||
|
||||
// Y-axis
|
||||
translate([size[0] * floor(i/2) - chamfer, -ep, size[2] * (i%2)])
|
||||
rotate([0, 45, 0]) cube([1.414*chamfer, size[1] + 2*ep, 1.414*chamfer]);
|
||||
}
|
||||
|
||||
// nameplate cutouts
|
||||
translate([(boxDims[0]/2 - 76)/2, 30, 7]) cube([76, 36, 1 + ep]);
|
||||
translate([(boxDims[0]/2 - 76)/2, 30 + 36, 7])
|
||||
rotate([30, 0, 0]) cube([76, 4, 4]);
|
||||
|
||||
// screw holes
|
||||
for (i = [-1, 1]) {
|
||||
color("red")
|
||||
translate([boxDims[0]/4 + i*20, 16, -ep]) cylinder(d=3.4, h=8+2*ep);
|
||||
translate([boxDims[0]/4 + i*20, 16, -ep]) cylinder(d=6.2, h=3+ep);
|
||||
//translate([boxDims[0]/4 + i*20, 16, 3 - ep]) cylinder(d1=6.2, d2=3.4, h=1+2*ep);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
module lowerLeftDrawerFace(outerDims, boxDims) {
|
||||
rotate([90, 0, 0])
|
||||
difference() {
|
||||
drawerFacePlateBlank(outerDims);
|
||||
|
||||
// label
|
||||
color("blue")
|
||||
translate([outerDims[0]/4 + 6, outerDims[2]/4 - 6, -0.2]) mirror([1, 0, 0])
|
||||
linear_extrude(0.4) text(font="Iosevka", size=6, "LL");
|
||||
|
||||
// horizontal board recess
|
||||
translate([drawerSideOffset, drawerSideOffset, -ep])
|
||||
cube([drawerWidth(boxDims), boardThickness, 4+ep]);
|
||||
|
||||
// vertical board recesses
|
||||
translate([drawerSideOffset, drawerSideOffset + boardThickness - ep, -ep])
|
||||
cube([boardThickness, drawerHeight(boxDims) - boardThickness + ep, 4+ep]);
|
||||
translate([
|
||||
drawerSideOffset + drawerWidth(boxDims) - boardThickness,
|
||||
drawerSideOffset + boardThickness - ep,
|
||||
-ep])
|
||||
cube([boardThickness, drawerHeight(boxDims) - boardThickness + ep, 4+ep]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
module lowerRightDrawerFace(outerDims, boxDims) {
|
||||
rotate([90, 0, 0])
|
||||
difference() {
|
||||
translate([1, 0, 0])
|
||||
drawerFacePlateBlank(outerDims);
|
||||
|
||||
// label
|
||||
color("blue")
|
||||
translate([outerDims[0]/4 + 6, outerDims[2]/4 - 6, -0.2]) mirror([1, 0, 0])
|
||||
linear_extrude(0.4) text(font="Iosevka", size=6, "LR");
|
||||
|
||||
union() {
|
||||
// horizontal board recess
|
||||
translate([feltThickness + boardThickness/2, drawerSideOffset, -ep])
|
||||
cube([drawerWidth(boxDims), boardThickness, 4+ep]);
|
||||
|
||||
// vertical board recesses
|
||||
translate([feltThickness + boardThickness/2, drawerSideOffset + boardThickness - ep, -ep])
|
||||
cube([boardThickness, drawerHeight(boxDims) - boardThickness + ep, 4+ep]);
|
||||
translate([
|
||||
feltThickness + boardThickness/2 + drawerWidth(boxDims) - boardThickness,
|
||||
feltThickness + boardThickness/2 + boardThickness - ep,
|
||||
-ep])
|
||||
cube([boardThickness, drawerHeight(boxDims) - boardThickness + ep, 4+ep]);
|
||||
|
||||
}
|
||||
|
||||
// translate([-1, -1, 4-ep]) cube([outerDims[0], outerDims[2], 5]);
|
||||
}
|
||||
}
|
||||
|
||||
module upperRightDrawerFace(outerDims, boxDims) {
|
||||
rotate([90, 0, 0])
|
||||
difference() {
|
||||
translate([1, 0, 0])
|
||||
drawerFacePlateBlank(outerDims);
|
||||
|
||||
// label
|
||||
color("blue")
|
||||
translate([outerDims[0]/4 + 6, outerDims[2]/4 - 6, -0.2]) mirror([1, 0, 0])
|
||||
linear_extrude(0.4) text(font="Iosevka", size=6, "UR");
|
||||
|
||||
union() {
|
||||
// horizontal board recess
|
||||
translate([feltThickness + boardThickness/2, feltThickness + boardThickness/2, -ep])
|
||||
cube([drawerWidth(boxDims), boardThickness, 4+ep]);
|
||||
|
||||
// vertical board recesses
|
||||
translate([
|
||||
feltThickness + boardThickness/2,
|
||||
feltThickness + boardThickness/2 + boardThickness - ep,
|
||||
-ep])
|
||||
cube([boardThickness, drawerHeight(boxDims) - boardThickness + ep, 4+ep]);
|
||||
translate([
|
||||
feltThickness + boardThickness/2 + drawerWidth(boxDims) - boardThickness,
|
||||
feltThickness + boardThickness/2 + boardThickness - ep,
|
||||
-ep])
|
||||
cube([boardThickness, drawerHeight(boxDims) - boardThickness + ep, 4+ep]);
|
||||
}
|
||||
|
||||
// translate([-1, -1, 4-ep]) cube([outerDims[0], outerDims[2], 5]);
|
||||
}
|
||||
}
|
||||
|
||||
module upperLeftDrawerFace(outerDims, boxDims) {
|
||||
rotate([90, 0, 0])
|
||||
difference() {
|
||||
drawerFacePlateBlank(outerDims);
|
||||
|
||||
// label
|
||||
color("blue")
|
||||
translate([boxDims[0]/4 + 6, boxDims[2]/4 - 6, -0.2]) mirror([1, 0, 0])
|
||||
linear_extrude(0.4) text(font="Iosevka", size=6, "UL");
|
||||
|
||||
union() {
|
||||
// horizontal board recess
|
||||
translate([drawerSideOffset, feltThickness + boardThickness/2, -ep])
|
||||
cube([drawerWidth(boxDims), boardThickness, 4+ep]);
|
||||
|
||||
// vertical board recesses
|
||||
translate([
|
||||
drawerSideOffset,
|
||||
feltThickness + boardThickness/2 + boardThickness - ep,
|
||||
-ep])
|
||||
cube([boardThickness, drawerHeight(boxDims) - boardThickness + ep, 4+ep]);
|
||||
translate([
|
||||
drawerSideOffset + drawerWidth(boxDims) - boardThickness,
|
||||
feltThickness + boardThickness/2 + boardThickness - ep,
|
||||
-ep])
|
||||
cube([boardThickness, drawerHeight(boxDims) - boardThickness + ep, 4+ep]);
|
||||
}
|
||||
|
||||
// translate([-1, -1, 4-ep]) cube([outerDims[0], outerDims[2], 5]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
module drawerHandle() {
|
||||
handleLen = 64;
|
||||
//difference() {
|
||||
chamferedCube([handleLen, 12, 12], chamfer=3);
|
||||
|
||||
// screw holes
|
||||
for (i = [-1, 1]) {
|
||||
difference() {
|
||||
translate([handleLen/2 + i*20, 6, 12-ep]) cylinder(d=6, h=8 + ep);
|
||||
translate([handleLen/2 + i*20, 6, 12-ep]) cylinder(d=2.8, h=8 + 2*ep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module drawerBottom(boxDims, includeClips = false) {
|
||||
difference() {
|
||||
color ("Tan")
|
||||
cube([
|
||||
drawerWidth(boxDims),
|
||||
boxDims[1], boardThickness]);
|
||||
color("black") translate([10, 10, boardThickness - 1]) linear_extrude(1.1)
|
||||
text(font="Iosevka", size=16, "drawer bottom - plywood");
|
||||
}
|
||||
}
|
||||
|
||||
module drawerSide(boxDims, includeClips = false) {
|
||||
difference() {
|
||||
color("Wheat")
|
||||
cube([
|
||||
drawerHeight(boxDims) - boardThickness, boxDims[1], boardThickness]);
|
||||
color("black") rotate([0, 0, -90]) translate([-10, 10, boardThickness - 1]) linear_extrude(1.1)
|
||||
text(font="Iosevka", halign = "right", size=16, "drawer side - plywood");
|
||||
}
|
||||
}
|
||||
|
||||
module assembled(outerBoxDims, includeClips = false) {
|
||||
translate([-6, 0, -6])
|
||||
color("darkgrey")
|
||||
containingBox(outerBoxDims);
|
||||
|
||||
color("brown")
|
||||
feltClearanceBox(outerBoxDims);
|
||||
|
||||
clipOffset = includeClips ? clipWallThickness : 0;
|
||||
|
||||
innerBoxDims = includeClips ?
|
||||
[ outerBoxDims[0] - 2*feltThickness - 2*clipWallThickness,
|
||||
outerBoxDims[1] - 2*clipWallThickness,
|
||||
outerBoxDims[2] - 2*feltThickness - 2*clipWallThickness ] :
|
||||
[ outerBoxDims[0] - 2*feltThickness,
|
||||
outerBoxDims[1],
|
||||
outerBoxDims[2] - 2*feltThickness ];
|
||||
|
||||
translate([feltThickness, 0, feltThickness])
|
||||
union() {
|
||||
translate([ clipOffset, clipOffset, clipOffset])
|
||||
union() {
|
||||
translate([0, 0, innerBoxDims[2] - boardThickness]) topPanel(innerBoxDims);
|
||||
|
||||
translate([boardThickness, 0, 0]) rotate([0, -90, 0]) sidePanel(innerBoxDims);
|
||||
translate([innerBoxDims[0], 0, 0]) rotate([0, -90, 0]) sidePanel(innerBoxDims);
|
||||
|
||||
translate([(innerBoxDims[0] + boardThickness)/2, 0, boardThickness]) rotate([0, -90, 0]) innerPanel(innerBoxDims);
|
||||
translate([(innerBoxDims[0] + boardThickness)/2, 0, 2*boardThickness + (innerBoxDims[2] - 3*boardThickness)/2]) rotate([0, -90, 0]) innerPanel(innerBoxDims);
|
||||
|
||||
translate([boardThickness, 0, boardThickness + (innerBoxDims[2] - 3*boardThickness)/2]) bottomPanel(innerBoxDims);
|
||||
translate([boardThickness, 0, 0]) bottomPanel(innerBoxDims);
|
||||
|
||||
// drawers
|
||||
translate([boardThickness + feltThickness, 0, boardThickness + feltThickness])
|
||||
for (i = [0:3]) {
|
||||
// felt box
|
||||
color("brown")
|
||||
translate([
|
||||
(i%2)*(innerBoxDims[0]-boardThickness)/2 - feltThickness,
|
||||
0.01,
|
||||
floor(i/2)*(innerBoxDims[2]-boardThickness)/2 - feltThickness])
|
||||
feltClearanceBox([
|
||||
innerBoxDims[0]/2 - 1.5*boardThickness,
|
||||
innerBoxDims[1],
|
||||
innerBoxDims[2]/2 - 1.5*boardThickness]);
|
||||
|
||||
//bottom
|
||||
translate([
|
||||
(i%2)*(innerBoxDims[0]-boardThickness)/2,
|
||||
0,
|
||||
floor(i/2)*(innerBoxDims[2]-boardThickness)/2])
|
||||
drawerBottom(innerBoxDims);
|
||||
|
||||
// side
|
||||
for (j = [0,1]) {
|
||||
translate([
|
||||
boardThickness + (i%2)*(innerBoxDims[0]-boardThickness)/2 +
|
||||
j*(drawerWidth(innerBoxDims) - boardThickness),
|
||||
0,
|
||||
boardThickness + floor(i/2)*(innerBoxDims[2]-boardThickness)/2])
|
||||
rotate([0, -90, 0]) drawerSide(innerBoxDims);
|
||||
}
|
||||
}
|
||||
|
||||
translate([-feltThickness, 0, -feltThickness])
|
||||
lowerLeftDrawerFace(outerBoxDims, innerBoxDims);
|
||||
|
||||
translate([outerBoxDims[0]/2 - feltThickness, 0, -feltThickness])
|
||||
lowerRightDrawerFace(outerBoxDims, innerBoxDims);
|
||||
|
||||
translate([-feltThickness, 0, outerBoxDims[2] / 2 - feltThickness])
|
||||
upperLeftDrawerFace(outerBoxDims, innerBoxDims);
|
||||
|
||||
translate([outerBoxDims[0]/2 - feltThickness, 0, outerBoxDims[2] / 2 - feltThickness])
|
||||
upperRightDrawerFace(outerBoxDims, innerBoxDims);
|
||||
|
||||
}
|
||||
|
||||
if (includeClips) {
|
||||
for(i = [0:1]) {
|
||||
translate([0, i * (2 * clipWallThickness + innerBoxDims[1]), 0])
|
||||
mirror([0, i * 1, 0])
|
||||
union() {
|
||||
rotate([-90, -90, 0])
|
||||
cornerClipA();
|
||||
|
||||
translate([0, 0, 2 * clipWallThickness + innerBoxDims[2]])
|
||||
rotate([-90, 0, 0])
|
||||
cornerClipA();
|
||||
|
||||
translate([2 * clipWallThickness + innerBoxDims[0], 0, 0])
|
||||
rotate([-90, -180, 0])
|
||||
cornerClipA();
|
||||
|
||||
translate([2 * clipWallThickness + innerBoxDims[0], 0, 2 * clipWallThickness + innerBoxDims[2]])
|
||||
rotate([-90, -270, 0])
|
||||
cornerClipA();
|
||||
|
||||
translate([clipWallThickness + innerBoxDims[0]/2 - clipFlangeLength, 0, 0])
|
||||
sideClipA();
|
||||
|
||||
translate([clipWallThickness + innerBoxDims[0]/2 + clipFlangeLength, 0, 2 * clipWallThickness + innerBoxDims[2]])
|
||||
rotate([0, 180, 0])
|
||||
sideClipA();
|
||||
|
||||
translate([0, 0, innerBoxDims[2]/2 + clipFlangeLength + clipWallThickness])
|
||||
rotate([0, 90, 0])
|
||||
sideClipA();
|
||||
|
||||
translate([innerBoxDims[0] + 2*clipWallThickness, 0, innerBoxDims[2]/2 - clipFlangeLength + clipWallThickness])
|
||||
rotate([0, 270, 0])
|
||||
sideClipA();
|
||||
|
||||
translate([innerBoxDims[0]/2 + clipWallThickness, 0, innerBoxDims[2]/2 + clipWallThickness])
|
||||
crossClipA();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module allCutParts(outerBoxDims, includeClips = false) {
|
||||
innerBoxDims = includeClips ?
|
||||
[ outerBoxDims[0] - 2*feltThickness - 2*clipWallThickness,
|
||||
outerBoxDims[1] - 2*clipWallThickness,
|
||||
outerBoxDims[2] - 2*feltThickness - 2*clipWallThickness ] :
|
||||
[ outerBoxDims[0] - 2*feltThickness,
|
||||
outerBoxDims[1],
|
||||
outerBoxDims[2] - 2*feltThickness ];
|
||||
|
||||
topPanel(innerBoxDims);
|
||||
|
||||
translate([innerBoxDims[0] + 8, 0, 0])
|
||||
bottomPanel(innerBoxDims);
|
||||
|
||||
translate([0, innerBoxDims[1] + 8, 0])
|
||||
sidePanel(innerBoxDims);
|
||||
|
||||
translate([innerBoxDims[2], innerBoxDims[1] + 8, 0])
|
||||
innerPanel(innerBoxDims);
|
||||
|
||||
}
|
||||
|
||||
shelfDims = [shelfWidth, shelfDepth, shelfHeight];
|
||||
//assembled(shelfDims);
|
||||
|
||||
//translate([shelfWidth + 20, 0, 0])
|
||||
//allCutParts(shelfDims);
|
||||
|
||||
//translate([300, shelfDepth + 40, 0])
|
||||
//rotate([0, 0, 90])
|
||||
//printableSetA();
|
||||
|
||||
innerBoxDims =
|
||||
[ shelfDims[0] - 2*feltThickness,
|
||||
shelfDims[1],
|
||||
shelfDims[2] - 2*feltThickness ];
|
||||
|
||||
|
||||
//drawerBottom(innerBoxDims);
|
||||
//lowerLeftDrawerFace(shelfDims, innerBoxDims);
|
||||
//lowerRightDrawerFace(shelfDims, innerBoxDims);
|
||||
//upperLeftDrawerFace(shelfDims, innerBoxDims);
|
||||
upperRightDrawerFace(shelfDims, innerBoxDims);
|
||||
//drawerHandle();
|
||||
+20
-24
@@ -1,24 +1,20 @@
|
||||
module chamferedCube(size = [1, 1, 1], chamfer = 1) {
|
||||
ep = 0.01;
|
||||
difference() {
|
||||
cube(size);
|
||||
|
||||
// X-axis
|
||||
for (i = [0:3]) {
|
||||
translate([-ep, size[1] * floor(i/2), size[2] * (i%2) - chamfer])
|
||||
rotate([45, 0, 0]) cube([size[0] + 2*ep, 1.414*chamfer, 1.414*chamfer]);
|
||||
}
|
||||
|
||||
// Y-axis
|
||||
for (i = [0:3]) {
|
||||
translate([size[0] * floor(i/2) - chamfer, -ep, size[2] * (i%2)])
|
||||
rotate([0, 45, 0]) cube([1.414*chamfer, size[1] + 2*ep, 1.414*chamfer]);
|
||||
}
|
||||
|
||||
// Z-axis
|
||||
for (i = [0:3]) {
|
||||
translate([size[0] * floor(i/2), size[1] * (i%2) - chamfer, -ep])
|
||||
rotate([0, 0, 45]) cube([1.414*chamfer, 1.414*chamfer, size[2] + 2*ep]);
|
||||
}
|
||||
}
|
||||
}
|
||||
module chamferedCube(size = [1, 1, 1], chamfer = 1) {
|
||||
ep = 0.01;
|
||||
difference() {
|
||||
cube(size);
|
||||
|
||||
for (i = [0:3]) {
|
||||
// X-axis
|
||||
translate([-ep, size[1] * floor(i/2), size[2] * (i%2) - chamfer])
|
||||
rotate([45, 0, 0]) cube([size[0] + 2*ep, 1.414*chamfer, 1.414*chamfer]);
|
||||
|
||||
// Y-axis
|
||||
translate([size[0] * floor(i/2) - chamfer, -ep, size[2] * (i%2)])
|
||||
rotate([0, 45, 0]) cube([1.414*chamfer, size[1] + 2*ep, 1.414*chamfer]);
|
||||
|
||||
// Z-axis
|
||||
translate([size[0] * floor(i/2), size[1] * (i%2) - chamfer, -ep])
|
||||
rotate([0, 0, 45]) cube([1.414*chamfer, 1.414*chamfer, size[2] + 2*ep]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
// Create a tenon with chamfered edges on the front face. The tenon is facing
|
||||
// the positive Y direction. It is offset by -0.01 in Y to make it easy to
|
||||
// ensure that it intersects with the main body it is attached to.
|
||||
module tenon(dims) {
|
||||
translate([0, -0.01, 0])
|
||||
difference() {
|
||||
cube([dims[0], dims[1] + 0.01, dims[2]]);
|
||||
|
||||
// chamfers
|
||||
color("blue") union() {
|
||||
translate([-0.5, dims[1] + 0.1, dims[2] - 1.1]) rotate([45, 0, 0]) cube([dims[0] + 1, 2, 2]);
|
||||
translate([-0.5, dims[1] + 0.1, -1.7]) rotate([45, 0, 0]) cube([dims[0] + 1, 2, 2]);
|
||||
translate([-0.4, dims[1]-1, -0.5]) rotate([0, 0, 45]) cube([2, 2, dims[2] + 1]);
|
||||
translate([dims[0]+0.4, dims[1]-1, -0.5]) rotate([0, 0, 45]) cube([2, 2, dims[2] + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module morticeBlank(dims, clearance = 0) {
|
||||
translate([-clearance, -clearance-0.01, -clearance])
|
||||
cube([dims[0] + 2 * clearance, dims[1] + 2 * clearance+0.01, dims[2] + 2 * clearance]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
module rectDowel(dim = [6, 16, 3]) {
|
||||
// rectangular dowel
|
||||
translate([-dim[0]/2, -dim[1]/2, -dim[2]/2])
|
||||
cube(dim);
|
||||
}
|
||||
|
||||
// Create a cube with a mortice cut out of the center for a snap fit tenon.
|
||||
// The mortice is aligned on the Y-axis: the dimension in X determines the
|
||||
// width of the piece and mortice, the dimension in Y determines the depth or
|
||||
// length of the piece, and the dimension in Z determines the height thickness.
|
||||
//
|
||||
// The morticeDim dimensions will be enlarged slightly to allow for adequate
|
||||
// fitment of the tenon based on the clearance (defaults to 0.2).
|
||||
module morticeWithSnap(
|
||||
dim = [10, 20, 5],
|
||||
morticeDim = [6, 8, 3],
|
||||
snapDepth = 2,
|
||||
snapHeight = 1,
|
||||
clearance = 0.3) {
|
||||
|
||||
mDim = [morticeDim[0] + 2*clearance,
|
||||
morticeDim[1] + clearance,
|
||||
morticeDim[2] + clearance];
|
||||
difference() {
|
||||
// block
|
||||
translate([-dim[0]/2, 0, -dim[2]/2]) cube(dim);
|
||||
|
||||
// cutout
|
||||
translate([-mDim[0]/2, -clearance, -mDim[2]/2]) union() {
|
||||
cube(mDim); // mortice cutout
|
||||
|
||||
// snap fit cutout
|
||||
translate([0, morticeDim[1] - snapDepth, morticeDim[2] + clearance - 0.01])
|
||||
cube([morticeDim[0] + clearance,
|
||||
snapDepth + clearance,
|
||||
snapHeight + clearance + 0.01]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a cube with a tenon and cantilevered snap fit on one side.
|
||||
// The tenon is aligned on the Y-axis: the dimension in X determines the
|
||||
// width of the piece and tenon, the dimension in Y determines the depth or
|
||||
// length of the piece, and the dimension in Z determines the height thickness.
|
||||
module tenonWithSnap(
|
||||
dim = [10, 20, 5],
|
||||
tenonDim = [6, 8, 3],
|
||||
snapDepth = 2,
|
||||
snapHeight = 1) {
|
||||
|
||||
// block
|
||||
translate([-dim[0]/2, 0, -dim[2]/2]) cube(dim);
|
||||
|
||||
// tenon
|
||||
translate([-tenonDim[0]/2, dim[1] - 0.01, -tenonDim[2]/2]) union() {
|
||||
// main tenon body
|
||||
tenonFlexArmThickness = min(tenonDim[2] / 2, 1);
|
||||
color("blue") translate([0, 0, tenonDim[2] - tenonFlexArmThickness])
|
||||
cube([tenonDim[0], tenonDim[1], tenonFlexArmThickness]);
|
||||
|
||||
// fillet on front edge of tenon
|
||||
/*
|
||||
translate([0, tenonDim[1] / 4 - 0.05, tenonDim[2] / 4 + 0.03])
|
||||
difference() {
|
||||
color("blue") cube([tenonDim[0], tenonDim[1] / 8, tenonDim[2] / 4]);
|
||||
color("green") translate([tenonDim[0] /2, tenonDim[1]/8 - tenonDim[2]/16, 0]) rotate([0, 90, 0])
|
||||
cylinder(r = tenonDim[2] / 4, h = tenonDim[0] + 0.02, center=true);
|
||||
}
|
||||
*/
|
||||
|
||||
// 45-degree chamfer on top edges of tenon base (alignment feature)
|
||||
difference() {
|
||||
cube([tenonDim[0], tenonDim[1]*0.4, tenonDim[2]]);
|
||||
translate([-0.01, tenonDim[1]*0.4, -tenonDim[2]/2]) rotate([45, 0, 0])
|
||||
cube([tenonDim[0] + 0.02, tenonDim[1] / 4, tenonDim[2] / 2]);
|
||||
}
|
||||
|
||||
// cantilevered snap fit
|
||||
translate([0, tenonDim[1] - snapDepth, tenonDim[2] - 0.01])
|
||||
difference() {
|
||||
cube([tenonDim[0], snapDepth, snapHeight + 0.01]);
|
||||
color("red") union() {
|
||||
// front-edge chamfer
|
||||
translate([-0.01, -snapDepth, snapHeight*0.66]) rotate([-10, 0, 0])
|
||||
cube([tenonDim[0] + 0.02, snapDepth, snapHeight + 0.01]);
|
||||
|
||||
// back-edge chamfer
|
||||
translate([-0.01, snapDepth, snapHeight / 8]) rotate([15, 0, 0])
|
||||
cube([tenonDim[0] + 0.02, snapDepth, snapHeight + 0.01]);
|
||||
|
||||
// side chamfers
|
||||
translate([-tenonDim[0]/4, 0, snapHeight*0.66]) rotate([0, 10, 0])
|
||||
cube([tenonDim[0] / 4, snapDepth + 0.02, snapHeight]);
|
||||
translate([tenonDim[0], 0, snapHeight*0.60]) rotate([0, -10, 0])
|
||||
cube([tenonDim[0] / 4, snapDepth + 0.02, snapHeight]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Creates the tail of a dovetail for a dovetail joint. The tail is oriented in
|
||||
// the positive Y direction. It is exactly (tailHeight + 0.01) tall (in the Y
|
||||
// direction) and positioned so that its base is at Y=-0.01 to make it easy to
|
||||
// overlap with the main body it is attached to.
|
||||
module dovetail(tailHeight, tailWidthMin, tailWidthMax, depth) {
|
||||
angle = atan((tailWidthMax - tailWidthMin) / (2 * tailHeight));
|
||||
|
||||
translate([0, tailHeight, 0])
|
||||
mirror([0, 1, 0])
|
||||
difference() {
|
||||
cube([tailWidthMax, tailHeight + 0.01, depth + 0.01]);
|
||||
color("blue") translate([tailWidthMax, 0, -0.1]) rotate([0, 0, angle]) cube([tailWidthMax, tailHeight*2, depth+0.2]);
|
||||
color("blue") rotate([0, 0, -angle]) translate([-tailWidthMax, 0, -0.1]) cube([tailWidthMax, tailHeight*2, depth+0.2]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
module m3Nut(h = 2.4, clearance = 0, center=false) {
|
||||
$fn=6;
|
||||
cylinder(d=6.35 + 2*clearance, h=h, center=center);
|
||||
}
|
||||
|
||||
module m4Nut(h = 3.2, clearance = 0, center=false) {
|
||||
$fn=6;
|
||||
cylinder(d=8.08 + 2*clearance, h=h, center=center);
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
module tenon(dims) {
|
||||
translate([0, -0.01, 0])
|
||||
difference() {
|
||||
cube([dims[0], dims[1] + 0.01, dims[2]]);
|
||||
|
||||
// chamfers
|
||||
color("blue") union() {
|
||||
translate([-0.5, dims[1]*0.95, dims[2]*0.9]) rotate([45, 0, 0])
|
||||
translate([0, 0, -dims[2]/2]) cube([dims[0] + 1, 2, 2]);
|
||||
translate([-0.5, dims[1]*0.95, -dims[2]*0.8]) rotate([45, 0, 0])
|
||||
translate([0, 0, -dims[2]/2]) cube([dims[0] + 1, 2, 2]);
|
||||
translate([-0.4, dims[1]-1, -0.5]) rotate([0, 0, 45])
|
||||
cube([2, 2, dims[2] + 1]);
|
||||
translate([dims[0]+0.4, dims[1]-1, -0.5]) rotate([0, 0, 45])
|
||||
cube([2, 2, dims[2] + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module morticeBlank(dims, clearance) {
|
||||
translate([-clearance, -clearance-0.01, -clearance])
|
||||
cube([dims[0] + 2 * clearance, dims[1] + 2 * clearance+0.01, dims[2] + 2 * clearance]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
module rectDowel(dim = [6, 16, 3]) {
|
||||
// rectangular dowel
|
||||
translate([-dim[0]/2, -dim[1]/2, -dim[2]/2])
|
||||
cube(dim);
|
||||
}
|
||||
|
||||
// Create a cube with a mortice cut out of the center for a snap fit tenon.
|
||||
// The mortice is aligned on the Y-axis: the dimension in X determines the
|
||||
// width of the piece and mortice, the dimension in Y determines the depth or
|
||||
// length of the piece, and the dimension in Z determines the height thickness.
|
||||
//
|
||||
// The morticeDim dimensions will be enlarged slightly to allow for adequate
|
||||
// fitment of the tenon based on the clearance (defaults to 0.2).
|
||||
module morticeWithSnap(
|
||||
dim = [10, 20, 5],
|
||||
morticeDim = [6, 8, 3],
|
||||
snapDepth = 2,
|
||||
snapHeight = 1,
|
||||
clearance = 0.3) {
|
||||
|
||||
mDim = [morticeDim[0] + 2*clearance,
|
||||
morticeDim[1] + clearance,
|
||||
morticeDim[2] + clearance];
|
||||
difference() {
|
||||
// block
|
||||
translate([-dim[0]/2, 0, -dim[2]/2]) cube(dim);
|
||||
|
||||
// cutout
|
||||
translate([-mDim[0]/2, -clearance, -mDim[2]/2]) union() {
|
||||
cube(mDim); // mortice cutout
|
||||
|
||||
// snap fit cutout
|
||||
translate([0, morticeDim[1] - snapDepth, morticeDim[2] + clearance - 0.01])
|
||||
cube([morticeDim[0] + clearance,
|
||||
snapDepth + clearance,
|
||||
snapHeight + clearance + 0.01]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a cube with a tenon and cantilevered snap fit on one side.
|
||||
// The tenon is aligned on the Y-axis: the dimension in X determines the
|
||||
// width of the piece and tenon, the dimension in Y determines the depth or
|
||||
// length of the piece, and the dimension in Z determines the height thickness.
|
||||
module tenonWithSnap(
|
||||
dim = [10, 20, 5],
|
||||
tenonDim = [6, 8, 3],
|
||||
snapDepth = 2,
|
||||
snapHeight = 1) {
|
||||
|
||||
// block
|
||||
translate([-dim[0]/2, 0, -dim[2]/2]) cube(dim);
|
||||
|
||||
// tenon
|
||||
translate([-tenonDim[0]/2, dim[1] - 0.01, -tenonDim[2]/2]) union() {
|
||||
// main tenon body
|
||||
tenonFlexArmThickness = min(tenonDim[2] / 2, 1);
|
||||
color("blue") translate([0, 0, tenonDim[2] - tenonFlexArmThickness])
|
||||
cube([tenonDim[0], tenonDim[1], tenonFlexArmThickness]);
|
||||
|
||||
// fillet on front edge of tenon
|
||||
/*
|
||||
translate([0, tenonDim[1] / 4 - 0.05, tenonDim[2] / 4 + 0.03])
|
||||
difference() {
|
||||
color("blue") cube([tenonDim[0], tenonDim[1] / 8, tenonDim[2] / 4]);
|
||||
color("green") translate([tenonDim[0] /2, tenonDim[1]/8 - tenonDim[2]/16, 0]) rotate([0, 90, 0])
|
||||
cylinder(r = tenonDim[2] / 4, h = tenonDim[0] + 0.02, center=true);
|
||||
}
|
||||
*/
|
||||
|
||||
// 45-degree chamfer on top edges of tenon base (alignment feature)
|
||||
difference() {
|
||||
cube([tenonDim[0], tenonDim[1]*0.4, tenonDim[2]]);
|
||||
translate([-0.01, tenonDim[1]*0.4, -tenonDim[2]/2]) rotate([45, 0, 0])
|
||||
cube([tenonDim[0] + 0.02, tenonDim[1] / 4, tenonDim[2] / 2]);
|
||||
}
|
||||
|
||||
// cantilevered snap fit
|
||||
translate([0, tenonDim[1] - snapDepth, tenonDim[2] - 0.01])
|
||||
difference() {
|
||||
cube([tenonDim[0], snapDepth, snapHeight + 0.01]);
|
||||
color("red") union() {
|
||||
// front-edge chamfer
|
||||
translate([-0.01, -snapDepth, snapHeight*0.66]) rotate([-10, 0, 0])
|
||||
cube([tenonDim[0] + 0.02, snapDepth, snapHeight + 0.01]);
|
||||
|
||||
// back-edge chamfer
|
||||
translate([-0.01, snapDepth, snapHeight / 8]) rotate([15, 0, 0])
|
||||
cube([tenonDim[0] + 0.02, snapDepth, snapHeight + 0.01]);
|
||||
|
||||
// side chamfers
|
||||
translate([-tenonDim[0]/4, 0, snapHeight*0.66]) rotate([0, 10, 0])
|
||||
cube([tenonDim[0] / 4, snapDepth + 0.02, snapHeight]);
|
||||
translate([tenonDim[0], 0, snapHeight*0.60]) rotate([0, -10, 0])
|
||||
cube([tenonDim[0] / 4, snapDepth + 0.02, snapHeight]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
module roundedCube(dims = [10, 10, 10], cornerRadii = [2, 2, 2]) {
|
||||
innerDims = [
|
||||
dims[0] - cornerRadii[0]*2,
|
||||
dims[1] - cornerRadii[1]*2,
|
||||
dims[2] - cornerRadii[2]*2 ];
|
||||
|
||||
// X-Y
|
||||
translate(cornerRadii)
|
||||
scale([cornerRadii[0], cornerRadii[1], 1])
|
||||
cylinder(r=1, h = innerDims[2]);
|
||||
translate([cornerRadii[0], cornerRadii[1] + innerDims[1], cornerRadii[2]])
|
||||
scale([cornerRadii[0], cornerRadii[1], 1])
|
||||
cylinder(r=1, h = innerDims[2]);
|
||||
translate([cornerRadii[0] + innerDims[0], cornerRadii[1] + innerDims[1], cornerRadii[2]])
|
||||
scale([cornerRadii[0], cornerRadii[1], 1])
|
||||
cylinder(r=1, h = innerDims[2]);
|
||||
translate([cornerRadii[0] + innerDims[0], cornerRadii[1], cornerRadii[2]])
|
||||
scale([cornerRadii[0], cornerRadii[1], 1])
|
||||
cylinder(r=1, h = innerDims[2]);
|
||||
|
||||
translate([cornerRadii[0], cornerRadii[1], 0]) cube([innerDims[0], innerDims[1], dims[2]]);
|
||||
|
||||
// X-Z
|
||||
translate(cornerRadii)
|
||||
scale([cornerRadii[0], 1, cornerRadii[2]])
|
||||
rotate([-90, 0, 0]) cylinder(r=1, h = innerDims[1]);
|
||||
translate([cornerRadii[0] + innerDims[0], cornerRadii[1], cornerRadii[2]])
|
||||
scale([cornerRadii[0], 1, cornerRadii[2]])
|
||||
rotate([-90, 0, 0]) cylinder(r=1, h = innerDims[1]);
|
||||
translate([cornerRadii[0], cornerRadii[1], cornerRadii[2] + innerDims[2]])
|
||||
scale([cornerRadii[0], 1, cornerRadii[2]])
|
||||
rotate([-90, 0, 0]) cylinder(r=1, h = innerDims[1]);
|
||||
translate([cornerRadii[0] + innerDims[0], cornerRadii[1], cornerRadii[2] + innerDims[2]])
|
||||
scale([cornerRadii[0], 1, cornerRadii[2]])
|
||||
rotate([-90, 0, 0]) cylinder(r=1, h = innerDims[1]);
|
||||
|
||||
translate([cornerRadii[0], 0, cornerRadii[2]]) cube([innerDims[0], dims[1], innerDims[2]]);
|
||||
|
||||
// Y-Z
|
||||
translate([cornerRadii[0] + innerDims[0], cornerRadii[1] + innerDims[1], cornerRadii[2]])
|
||||
scale([1, cornerRadii[1], cornerRadii[2]])
|
||||
rotate([-90, 0, 90]) cylinder(r=1, h = innerDims[0]);
|
||||
translate([cornerRadii[0] + innerDims[0], cornerRadii[1], cornerRadii[2]])
|
||||
scale([1, cornerRadii[1], cornerRadii[2]])
|
||||
rotate([-90, 0, 90]) cylinder(r=1, h = innerDims[0]);
|
||||
translate([cornerRadii[0] + innerDims[0], cornerRadii[1] + innerDims[1], cornerRadii[2] + innerDims[2]])
|
||||
scale([1, cornerRadii[1], cornerRadii[2]])
|
||||
rotate([-90, 0, 90]) cylinder(r=1, h = innerDims[0]);
|
||||
translate([cornerRadii[0] + innerDims[0], cornerRadii[1], cornerRadii[2] + innerDims[2]])
|
||||
scale([1, cornerRadii[1], cornerRadii[2]])
|
||||
rotate([-90, 0, 90]) cylinder(r=1, h = innerDims[0]);
|
||||
|
||||
translate([0, cornerRadii[1], cornerRadii[2]]) cube([dims[0], innerDims[1], innerDims[2]]);
|
||||
|
||||
|
||||
// corners
|
||||
translate(cornerRadii)
|
||||
scale(cornerRadii) sphere(r=1);
|
||||
translate([cornerRadii[0] + innerDims[0], cornerRadii[1], cornerRadii[2]])
|
||||
scale(cornerRadii) sphere(r=1);
|
||||
translate([cornerRadii[0] + innerDims[0], cornerRadii[1] + innerDims[1], cornerRadii[2]])
|
||||
scale(cornerRadii) sphere(r=1);
|
||||
translate([cornerRadii[0], cornerRadii[1] + innerDims[1], cornerRadii[2]])
|
||||
scale(cornerRadii) sphere(r=1);
|
||||
|
||||
translate([cornerRadii[0], cornerRadii[1], cornerRadii[2] + innerDims[2]])
|
||||
scale(cornerRadii) sphere(r=1);
|
||||
translate([cornerRadii[0] + innerDims[0], cornerRadii[1], cornerRadii[2] + innerDims[2]])
|
||||
scale(cornerRadii) sphere(r=1);
|
||||
translate([cornerRadii[0] + innerDims[0], cornerRadii[1] + innerDims[1], cornerRadii[2] + innerDims[2]])
|
||||
scale(cornerRadii) sphere(r=1);
|
||||
translate([cornerRadii[0], cornerRadii[1] + innerDims[1], cornerRadii[2] + innerDims[2]])
|
||||
scale(cornerRadii) sphere(r=1);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
module prism(l, w, h) {
|
||||
polyhedron(// pt 0 1 2 3 4 5
|
||||
points=[[0,0,0], [0,w,h], [l,w,h], [l,0,0], [0,w,0], [l,w,0]],
|
||||
// top sloping face (A)
|
||||
faces=[[0,1,2,3],
|
||||
// vertical rectangular face (B)
|
||||
[2,1,4,5],
|
||||
// bottom face (C)
|
||||
[0,3,5,4],
|
||||
// rear triangular face (D)
|
||||
[0,4,1],
|
||||
// front triangular face (E)
|
||||
[3,2,5]]
|
||||
);}
|
||||
Submodule
+1
Submodule lib/threads added at 4ae9aeb3b1
@@ -0,0 +1,72 @@
|
||||
$fn = 256;
|
||||
|
||||
d_i = 10.8; // Inner diameter of the cymbal mount hole
|
||||
|
||||
d_o_top = 24; // Diameter of the outer top of the cymbal support
|
||||
h_top = 11; // Height of the top part of the cymbal support
|
||||
|
||||
d_o_bot = 19; // Diameter of the outer bottom of the cymbal support
|
||||
h_bot = 10.2; // Height of the bottom part of the cymbal support
|
||||
|
||||
h_dome = 6.8; // Height of the dome part of the cymbal support
|
||||
h_neck = 5; // Height of the neck part of the cymbal support
|
||||
|
||||
h_flange = 17.5;
|
||||
w_flange = 3;
|
||||
|
||||
h_full = h_bot + h_neck + h_top + h_dome;
|
||||
|
||||
difference() {
|
||||
union() {
|
||||
// Bottom part of the cymbal support
|
||||
translate([0, 0, h_bot/2 + 0.1])
|
||||
cylinder(h = h_bot + 0.2, d = d_o_bot, center = true);
|
||||
|
||||
// Neck of the cymbal support
|
||||
translate([0, 0, h_bot + h_neck / 2])
|
||||
cylinder(h = h_neck, d1 = d_o_bot, d2 = d_o_top, center = true);
|
||||
|
||||
// Top part of the cymbal support
|
||||
translate([0, 0, h_bot + h_neck + h_top/2 + 0.1])
|
||||
cylinder(h = h_top + 0.2, d = d_o_top, center = true);
|
||||
|
||||
// Dome on top of the cymbal support
|
||||
translate([0, 0, h_bot + h_neck + h_top])
|
||||
scale([1, 1, (2*h_dome + 2) / d_o_top])
|
||||
sphere(d = d_o_top);
|
||||
|
||||
// Flange at the bottom of the cymbal support
|
||||
translate([-w_flange / 2, d_i / 2, 0]) cube([w_flange, 22, h_flange]);
|
||||
|
||||
// screw support
|
||||
translate([d_o_bot / 2 - 0.2, 0, 9.2 / 2])
|
||||
rotate([0, -90, 0]) cylinder(h = 1, d = 9.2, center = true);
|
||||
|
||||
translate([d_o_bot / 2 - 0.7, -9.2 / 2, 9.2 / 2])
|
||||
cube([1, 9.2, h_bot]);
|
||||
|
||||
}
|
||||
|
||||
// Cut out the inner hole for mounting
|
||||
translate([0, 0, 13])
|
||||
cylinder(h = 26.02, d = d_i, center = true);
|
||||
|
||||
translate([0, 0, 27])
|
||||
cylinder(h = 2, d1 = d_i, d2 = 8.4, center = true);
|
||||
|
||||
translate([0, 0, 27 + (h_full - 27)/2])
|
||||
cylinder(h = 1 + h_full - 27, d = 8.4, center = true);
|
||||
|
||||
// Cut out the screw hole
|
||||
translate([d_o_bot / 2 - 0.2, 0, 9.2 / 2])
|
||||
rotate([0, -90, 0]) cylinder(h = d_o_bot + 1, d = 4.6, center = true);
|
||||
|
||||
// Cut off the top (flatten the dome)
|
||||
translate([0, 0, h_bot + h_neck + h_top + h_dome+ 2]) cube([d_o_top, d_o_top, 4], center = true);
|
||||
|
||||
// Cut off the flange at an angle
|
||||
translate([0, d_i/2 + 9, 0])
|
||||
rotate([33.18, 0, 0])
|
||||
translate([-(w_flange + 0.2) / 2, 0, -10])
|
||||
cube([w_flange + 0.2, h_flange + 0.2, 10]);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
$fn=36;
|
||||
|
||||
ep = 0.01;
|
||||
height = 4.5;
|
||||
|
||||
iDepth = 3.5;
|
||||
oDepth = 9;
|
||||
|
||||
iWidth = 13;
|
||||
oWidth = 20;
|
||||
|
||||
clipWidth=5;
|
||||
|
||||
overhang=5;
|
||||
|
||||
pinClear = 2.2; // pin clearance
|
||||
slideClear = 1.8;
|
||||
|
||||
union() {
|
||||
// base bracket
|
||||
difference() {
|
||||
translate([-oWidth/2, 0, 0]) cube([oWidth, oDepth, height + ep]);
|
||||
|
||||
translate([-iWidth/2, -ep, -ep]) cube([iWidth, iDepth + ep, height + 3*ep]);
|
||||
}
|
||||
|
||||
// clip
|
||||
difference() {
|
||||
translate([-clipWidth/2, -overhang, height]) cube([clipWidth, oDepth + overhang, 4]);
|
||||
|
||||
color("red") union() {
|
||||
translate([-oWidth/2, -2.5, height + 1.25]) rotate([0, 90, 0]) cylinder(d=3, h=oWidth);
|
||||
translate([-clipWidth/2 - ep, -overhang - ep, height - ep]) cube([clipWidth + 2*ep, overhang + ep, 1.5 + ep]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
// all measurements in mm
|
||||
$fn=128;
|
||||
|
||||
// Version History
|
||||
// 1 - id=25.6, od1=31, od2=29, h=44, tabHeight=13, tabClearance=0.4
|
||||
// 2 - id=27, od1=31, od2=29, h=44, tabHeight=13, tabClearance=0.1
|
||||
// 3 - id=27, od1=31, od2=29, h=44, tabHeight=13, tabClearance=0
|
||||
// 4 - id=26, od1=31, od2=29, h=44, tabHeight=13, tabClearance=0
|
||||
// 5 - id=26, od1=31, od2=29, h=44, tabHeight=13, tabClearance=-0.1, angle in tab
|
||||
version = "5";
|
||||
|
||||
id = 26;
|
||||
od1 = 31;
|
||||
od2 = 29;
|
||||
h = 44;
|
||||
tabClearance = -0.1;
|
||||
tabHeight = 13;
|
||||
|
||||
module tab() {
|
||||
translate([id/2 + 0.2, 0, -6.5]) rotate([0, 0, 7]) difference() {
|
||||
// tab
|
||||
translate([0, -0.01, 0]) cube([1.6, 4.01, tabHeight]);
|
||||
// tab chamfers
|
||||
union() {
|
||||
translate([0 - 0.2, 2, 0]) rotate([-75, 0, 0]) cube([2, 4, 4]);
|
||||
translate([0 - 0.2, 2, tabHeight]) mirror([0, 0, 1]) rotate([-75, 0, 0]) cube([2, 4, 4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module tabCutout() {
|
||||
translate([-id/2 - 3, -5, -(tabHeight + tabClearance)/2]) cube([6, 5.01, tabHeight + tabClearance]);
|
||||
}
|
||||
|
||||
module catchRing() {
|
||||
translate([0, 0, 9]) difference() {
|
||||
cylinder(h=0.8, d=od2, center = true);
|
||||
translate([0, 0, -0.05]) cylinder(h=1, d=id - 0.8, center = true);
|
||||
}
|
||||
}
|
||||
|
||||
module mainCylinderBody() {
|
||||
difference() {
|
||||
union() {
|
||||
difference() {
|
||||
// outer cylinder
|
||||
cylinder(h=h, d1=od1, d2=od2, center = true);
|
||||
|
||||
// cylinder bore and top chamfer
|
||||
union() {
|
||||
// inner bore
|
||||
translate([0, 0, -0.01]) cylinder(h=h + 0.1, d=id, center = true);
|
||||
|
||||
// top chamfer
|
||||
translate([0, 0, h/2-0.02]) difference() {
|
||||
cylinder(h=2.2, d1=od1+3, d2=od2+3, center = true);
|
||||
translate([0, 0, -0.01]) cylinder(h=2.24, d1=od2+0.1, d2=id-0.2, center = true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
catchRing();
|
||||
}
|
||||
// cutout half
|
||||
translate([-(od2+4)/2, 0, -h/2 - 1]) cube([od1 + 4, od1, h + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
difference() {
|
||||
union() {
|
||||
mainCylinderBody();
|
||||
tab();
|
||||
}
|
||||
|
||||
union() {
|
||||
tabCutout();
|
||||
translate([0, -0.2-id/2, 4-h/2]) rotate([90, 0, 180])
|
||||
linear_extrude(0.8)
|
||||
text(str("v", version), size=6, halign="center", valign="center", font="Iosevka");
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
$fn=180;
|
||||
ow=23; // outer width
|
||||
od=18; // outer depth
|
||||
oh=10; // outer height
|
||||
oh=10; // outer height
|
||||
ep = 0.01;
|
||||
|
||||
iw=17.4; // inner width
|
||||
id=12.5; // inner depth
|
||||
id=12.5; // inner depth
|
||||
ih=7.6; // inner height
|
||||
|
||||
sphMul = 4;
|
||||
@@ -51,6 +51,10 @@ difference() {
|
||||
ct = 1.3; // cross thickness
|
||||
|
||||
// inner cylinder
|
||||
// there are conflicting constraints here: the diameter needs to be thick
|
||||
// enough to have strong walls, particularly at the points where the
|
||||
// cross cutaway comes close to them, but the whole cylinder also needs
|
||||
// to fit into the recess allowed in the keypost
|
||||
color("DimGray") translate([ow/2, od/2, 1.4]) cylinder(d=5.3, h=ih - 1.4);
|
||||
|
||||
// inner cross recess (post hole)
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
// measurements in inches
|
||||
width = 40;
|
||||
height = 99.5;
|
||||
depth = 19.5;
|
||||
|
||||
cubeSize = 13.5;
|
||||
|
||||
shelfThickness = 0.5;
|
||||
wallThickness = 1;
|
||||
|
||||
module shelvingUnit(includeFitTest = false) {
|
||||
color("#242424") union() {
|
||||
// sides
|
||||
cube([wallThickness, depth, height]);
|
||||
translate([width - wallThickness, 0, 0]) cube([wallThickness, depth, height]);
|
||||
|
||||
// top and bottom
|
||||
cube([width, depth, wallThickness]);
|
||||
translate([0, 0, height - wallThickness]) cube([width, depth, wallThickness]);
|
||||
}
|
||||
|
||||
color("#384048") union() {
|
||||
// shelves
|
||||
for (i = [1 : floor((height - 2 * wallThickness) / (cubeSize + wallThickness))]) {
|
||||
translate([wallThickness, 0, i*cubeSize + (i-1)*shelfThickness + wallThickness])
|
||||
cube([width - 2 * wallThickness, depth, shelfThickness]);
|
||||
}
|
||||
|
||||
// dividers
|
||||
for (i = [1 : floor((width - 2 * wallThickness) / (cubeSize + wallThickness))]) {
|
||||
translate([i * (cubeSize + wallThickness), 0, wallThickness])
|
||||
cube([wallThickness, depth, height - 2 * wallThickness]);
|
||||
}
|
||||
}
|
||||
|
||||
if (includeFitTest) {
|
||||
// test box fits
|
||||
color("CornflowerBlue") union() {
|
||||
// main boxes
|
||||
translate([wallThickness, 0.01, wallThickness])
|
||||
for (i = [0 : floor((height - 2 * wallThickness) / (cubeSize + wallThickness))])
|
||||
for (j = [0 : floor((width - 2 * wallThickness) / (cubeSize + wallThickness)) - 1])
|
||||
translate([j * (cubeSize + wallThickness), 0, i * (cubeSize + shelfThickness)])
|
||||
cube([cubeSize, depth, cubeSize]);
|
||||
|
||||
// corner box
|
||||
translate([30, 0.01, wallThickness])
|
||||
for (i = [0 : floor((height - 2 * wallThickness) / (cubeSize + wallThickness))])
|
||||
translate([0, 0, i * (cubeSize + shelfThickness)]) cube([9, depth, cubeSize]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
difference() {
|
||||
shelvingUnit();
|
||||
|
||||
// cutout for corner box
|
||||
union() {
|
||||
translate([39, depth + 0.01, -1]) rotate([0, 0, 180]) difference() {
|
||||
cube([9, depth - wallThickness, height + 2]);
|
||||
translate([9, 0, -1]) rotate([0, 0, atan(9 / (depth - 2*wallThickness))]) cube([9, depth*2, height + 4]);
|
||||
}
|
||||
translate([width - wallThickness - 0.1, -0.1, -0.1]) cube([wallThickness + 0.2, depth + 0.2, height + 0.2]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user