Kallax organization models.

This commit is contained in:
2025-11-02 21:49:31 -06:00
parent 9e771b3125
commit aa7725adef
9 changed files with 868 additions and 0 deletions
+140
View File
@@ -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]);
}
}
+14
View File
@@ -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]]
);}