Toothpaste Squeezer
A flat slide-style squeezer for getting the last bit out of a toothpaste tube. Thread the flattened end of the tube through the slot and push the squeezer toward the cap. The slot has a 0.8 mm 45-degree chamfer on both faces so it does not cut the tube, and an optional hole lets you hang it up. The default size is 82 x 22 x 6 mm with a 60 x 2.6 mm slot. Print it flat with no supports; if the slot comes out too tight, raise the slot width in 0.2 mm steps. Adjustable parameters: slot length, slot width, body thickness, body width and the hanging hole.
# Toothpaste Squeezer - thread the tube end through the slot and push it up
@param 30..90 desc:"Slot length = flattened tube width + margin (mm)"
slot_l = 60
@param 1.5..5..0.1 desc:"Slot width (flattened tube thickness + margin, mm)"
slot_w = 2.6
@param 4..12 desc:"Body thickness (mm)"
thick = 6
@param 14..40 desc:"Body width (mm)"
body_w = 22
@param desc:"Add hanging hole"
hang = true
end_m = 7 # from slot end to body end
body_l = slot_l + end_m * 2 + (if hang then 8 else 0)
corner_r = 6
flare = 0.8 # chamfer at the slot entry/exit (gentle on the tube)
def rr(w, h, r) = rect (w - 2 * r) (h - 2 * r) | offset r
sx = if hang then -4 else 0 # shift the slot away from the hanging hole
body = rr(body_l, body_w, corner_r) | extrude thick | edges [>Z, <Z] | fillet 1
sr = slot_w * 0.45
def sl(e) = rr(slot_l + e * 2, slot_w + e * 2, sr + e)
slot = sl(flare + 0.5)
| loft [sl(flare), sl(0), sl(0), sl(flare), sl(flare + 0.5)] [0.5, flare + 0.5, thick - flare + 0.5, thick + 0.5, thick + 1] ruled:true
| translate sx 0 -0.5
hang_hole = cylinder 2.5 (thick + 2) at:((body_l / 2 - 6), 0, (thick / 2))
s0 = body - slot
if hang then s0 - hang_hole else s0