Files
3d-models/kallax-organization/quarter-drawers.scad
T
2025-12-26 13:24:46 -06:00

388 lines
11 KiB
OpenSCAD

include <./constants.scad>
include <../lib/metric-machine-screws.scad>
// all measurements in mm
// boardThickness = 4.7; // 1/8" plywood
boardThickness = 7.35;
feltThickness = 2.5;
feltWidth = 12;
clipThickness = boardThickness + 2*feltThickness;
clipWallThickness = 4;
clipFlangeLength = 24;
clipFlangeWidth = 16;
// 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
//
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");
}
}
// TODO
module drawerFacePlate(outerBoxDims, includeClips = false) {
}
module drawerBottom(outerBoxDims, includeClips = false) {
}
module drawerSide(outerBoxDims, includeClips = false) {
}
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);
}
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();