Documentation
Common patterns
Copy-paste recipes: rounded boxes, screw holes, arrays, shells, chamfers, text.
Rounded box, the base of an enclosure
The hull of four corner cylinders is a rounded rectangle; a module makes it reusable.
mod rbox(w, d, h, r) {
hull {
translate(r, r, 0) cylinder(h: h, r: r)
translate(w - r, r, 0) cylinder(h: h, r: r)
translate(r, d - r, 0) cylinder(h: h, r: r)
translate(w - r, d - r, 0) cylinder(h: h, r: r)
}
}
rbox(60, 40, 20, 3)Screw hole with a countersink
A through hole and a cone on top; the cone runs a tenth past the face so the cut is clean.
mod screw_hole(d, h, cs_d, cs_depth) {
// The through hole
cylinder(h: h, r: d / 2)
// The countersink
translate(0, 0, h - cs_depth)
cylinder(h: cs_depth + 0.1, r1: d / 2, r2: cs_d / 2)
}
// An M3 countersunk screw through a 5 mm plate
difference {
cube(20, 20, 5)
translate(10, 10, -0.5)
screw_hole(3.4, 6, 6.5, 1.8)
}Mounting hole pattern
Two nested loops over the two x and the two y positions make four holes.
mod mount_holes(w, d, h, hole_r, inset) {
for (x in [inset, w - inset]) {
for (y in [inset, d - inset]) {
translate(x, y, -0.5)
cylinder(h: h + 1, r: hole_r)
}
}
}
difference {
cube(60, 40, 3)
mount_holes(60, 40, 3, 1.7, 5)
}Fillet where a wall meets the floor
A square with a cylinder taken out of its corner is a concave fillet; lay it along the wall.
mod fillet(r, h) {
difference {
cube(r, r, h)
translate(r, r, -0.1)
cylinder(h: h + 0.2, r: r)
}
}
// A standing wall with a fillet at its foot
cube(40, 2, 20)
fillet(3, 20)Circular array
Rotate, then move out along x: the same part at every angle around the origin.
param count: int = 8 [3:24] "Number of items"
param radius: float = 25 [10:50] "Array radius (mm)"
for (i in [0:count - 1]) {
let angle = i * 360 / count
rotate(0, 0, angle)
translate(radius, 0, 0)
cylinder(h: 10, r: 3)
}Linear array with spacing
A loop over the count, each step moved along by the spacing.
param count: int = 5 [1:20] "Count"
param spacing: float = 15 [8:30] "Spacing (mm)"
for (i in [0:count - 1]) {
translate(i * spacing, 0, 0) cube(10, 10, 10)
}Hollow box, a shell
The inner box is the outer one minus the wall on every side, and runs out through the top.
param w: float = 60 [20:150] "Width (mm)"
param d: float = 40 [20:100] "Depth (mm)"
param h: float = 25 [10:60] "Height (mm)"
param wall: float = 2 [1.2:4:0.2] "Wall (mm)"
difference {
cube(w, d, h)
translate(wall, wall, wall)
cube(w - wall * 2, d - wall * 2, h)
}Chamfered edge
A box turned 45 degrees and placed on the edge cuts a chamfer off it.
param size: float = 30 [10:60] "Size (mm)"
param chamfer: float = 2 [0.5:5] "Chamfer (mm)"
difference {
cube(size, size, size)
translate(-0.5, 0, size - chamfer)
rotate(45, 0, 0)
cube(size + 1, chamfer * 2, chamfer * 2)
}Raised or sunken text
Extrude the text and add it for a raised label, or take it away inside a difference for a sunken one. The font is built in and plain.
param text_depth: float = 1 [0.4:3:0.2] "Text height (mm)"
cube(50, 20, 2)
translate(5, 5, 2)
extrude(text_depth)
text("HELLO", size: 10)Snap-fit clip
A cantilever arm with a hook at its end; the thickness decides how stiff it is.
param length: float = 10 [5:20] "Clip length (mm)"
param width: float = 5 [3:10] "Clip width (mm)"
param thickness: float = 1 [0.8:2:0.1] "Thickness (mm)"
param hook: float = 1.5 [0.5:3:0.5] "Hook depth (mm)"
// The arm
cube(length, width, thickness)
// The hook at its end
translate(length - thickness, 0, -hook)
cube(thickness, width, hook + thickness)Cable comb
A bar with one round slot per cable, each slot a cylinder turned to lie across the bar.
param cables: int = 6 [2:12] "Number of cables"
param cable_d: float = 5 [3:10:0.5] "Cable diameter (mm)"
param wall: float = 2 [1.5:4:0.5] "Wall (mm)"
param depth: float = 8 [5:15] "Depth (mm)"
let slot = cable_d + wall
let total_w = cables * slot + wall
difference {
cube(total_w, depth, cable_d + wall * 2)
for (i in [0:cables - 1]) {
translate(wall + i * slot + slot / 2, -0.5, wall + cable_d / 2)
rotate(-90, 0, 0)
cylinder(h: depth + 1, r: cable_d / 2)
}
}Tolerance test block
Five holes a tenth apart; print it once and read off the clearance your printer needs.
// Five clearances, a tenth of a millimetre apart
for (i in [0:4]) {
let clearance = 0.1 + i * 0.1
translate(i * 12, 0, 0) {
difference {
cube(10, 10, 5)
translate(5, 5, -0.5)
cylinder(h: 6, r: 3 + clearance)
}
}
}