Drawer Divider Grid
An organizer insert that sizes itself to your drawer: enter the drawer's inner width, depth and height plus the number of columns and rows (or a target cell size), and the grid of equal cells is calculated with a small clearance to the drawer walls. Each cell has rounded vertical corners and a filleted floor joint so small parts can be scooped out with a fingertip, and optional U-shaped finger notches in the top of every wall make the cells easy to reach into and the insert easy to lift out. Drawers larger than the print bed are split automatically into identical tiles that stand side by side, each with its own frame, so print the single tile as many times as reported. The default insert for a 200 x 160 x 50 mm drawer with 4 x 3 cells measures 199 x 159 x 48 mm. It prints upright on its floor with no supports. Adjustable parameters include drawer width, depth and height, clearance, top gap, columns, rows, target cell size, wall thickness, corner radius, floor on or off, floor thickness, finger notches and notch radius, and the usable bed size.
# Drawer Divider Grid - an organizer insert that sizes itself to the drawer
# Enter the drawer's inner width / depth / height and the number of columns and
# rows (or a target cell size); the script computes an equal-cell grid that
# drops into the drawer with a small clearance all round.
#
# Bed limit: drawers larger than the print bed are split into identical tiles.
# tiles_x / tiles_y are computed as ceil(insert size / bed size), and each tile
# carries its own full frame, so the tiles stand side by side in the drawer
# (the seam is a double wall). The output is ONE tile; print it
# tiles_x * tiles_y times. The columns must divide evenly between the tiles
# along X (rows along Y) so that every cell is the same size.
#
# Printed upright, open side up, floor on the bed. Cell corners are rounded
# (vertical inner edges) and the floor joint is filleted, so small parts can
# be scooped out with a fingertip. Optional finger notches in the top of
# every wall make it easy to reach into a cell and to lift the insert out.
# ---- Drawer ----
@param 40..600 group:"Drawer" desc:"Drawer inner width, X (mm)"
drawer_w = 200
@param 40..600 group:"Drawer" desc:"Drawer inner depth, Y (mm)"
drawer_d = 160
@param 15..120 group:"Drawer" desc:"Drawer inner height (mm)"
drawer_h = 50
@param 0..2..0.1 group:"Drawer" desc:"Clearance to each drawer wall (mm)"
clearance = 0.5
@param 0..10..0.5 group:"Drawer" desc:"Gap below the drawer top / runner (mm)"
top_gap = 2
# ---- Grid ----
@param 1..20 group:"Grid" desc:"Columns along X (used when cell_size = 0)"
columns = 4
@param 1..20 group:"Grid" desc:"Rows along Y (used when cell_size = 0)"
rows = 3
@param 0..150 group:"Grid" desc:"Target cell size (mm, 0 = use columns / rows)"
cell_size = 0
@param 1.2..3..0.1 group:"Grid" desc:"Wall thickness (mm)"
wall = 1.6
@param 0..15..0.5 group:"Grid" desc:"Inner corner radius of each cell (mm)"
corner_r = 4
@param group:"Grid" desc:"Add a floor (off = open grid frame)"
has_floor = true
@param 0.8..3..0.1 group:"Grid" desc:"Floor thickness (mm)"
floor_t = 1.2
@param group:"Grid" desc:"Finger notches in the top of the walls"
notch = true
@param 3..15..0.5 group:"Grid" desc:"Finger notch radius (mm)"
notch_r = 8
# ---- Printer ----
@param 100..400 group:"Printer" desc:"Usable bed size (mm, square)"
bed = 220
# ===== Layout =====
iw = drawer_w - 2 * clearance # whole insert footprint
id = drawer_d - 2 * clearance
H = drawer_h - top_gap # insert height
tiles_x = ceil(iw / bed)
tiles_y = ceil(id / bed)
TW = iw / tiles_x # one tile
TD = id / tiles_y
# Cell counts per tile. With a target size, round to the nearest whole number of cells.
nx = if cell_size > 0 then max(1, round((TW - wall) / (cell_size + wall))) else columns / tiles_x
ny = if cell_size > 0 then max(1, round((TD - wall) / (cell_size + wall))) else rows / tiles_y
cw = (TW - wall) / nx - wall # cell width (inside)
cd = (TD - wall) / ny - wall # cell depth (inside)
cr = min(corner_r, cw / 2 - 0.1, cd / 2 - 0.1)
fz = if has_floor then floor_t else 0
bot_r = min(cr - 0.2, 3, (H - fz) / 2) # floor-to-wall fillet
assert nx == floor(nx) # columns must divide evenly between tiles_x tiles
assert ny == floor(ny) # rows must divide evenly between tiles_y tiles
assert cw >= 10 # cells narrower than 10 mm are not usable
assert cd >= 10
assert H > fz + 5
def rr(w, h, r) = rect (w - 2 * r) (h - 2 * r) | offset r
# Outer block of one tile, outer corner follows the cell corner plus the wall
outer = rr(TW, TD, cr + wall) | extrude H
# One cell pocket: rounded vertical corners; with a floor, also a rounded floor joint
pocket_floor = rr(cw, cd, cr) | extrude (H + 1) | edges <Z | fillet bot_r | translate 0 0 fz
pocket_open = rr(cw, cd, cr) | extrude (H + 2) | translate 0 0 -1
pocket = if has_floor then pocket_floor else pocket_open
cx = [wall + cw / 2 + i * (cw + wall) - TW / 2 for i in range(nx)]
cy = [wall + cd / 2 + j * (cd + wall) - TD / 2 for j in range(ny)]
assert cx[nx - 1] + cw / 2 ~ TW / 2 - wall tol:0.001 # outer wall = wall on both sides
assert cy[ny - 1] + cd / 2 ~ TD / 2 - wall tol:0.001
pockets = union [pocket | translate cx[k % nx] cy[k // nx] 0 for k in range(nx * ny)]
body = outer - pockets
# Finger notches: a U cut at the top of every wall, centered on each cell span
nr = min(notch_r, (H - fz) * 0.6, cw / 2, cd / 2)
notch_y = [cylinder nr (TW + 2) | rotate 0 90 0 | translate 0 y H for y in cy]
notch_x = [cylinder nr (TD + 2) | rotate 90 0 0 | translate x 0 H for x in cx]
notches = union [union notch_y, union notch_x]
tile = if notch then body - notches else body
assert tile.solids == 1
assert tile.bbox.x ~ TW tol:0.01
assert tile.bbox.y ~ TD tol:0.01
assert tile.bbox.z ~ H tol:0.01
assert tile.bbox.min[2] ~ 0 tol:0.01
assert TW <= bed # every tile fits the bed
assert TD <= bed
print "tiles (x, y)" tiles_x tiles_y
print "cells per tile (x, y)" nx ny
print "cell inside (w, d)" cw cd
print "tile (w, d, h)" TW TD H
tile