Lattice Pen Holder
A lightweight pen holder whose wall is a 45-degree lattice of diagonal struts. Diamond windows are cut through the cylinder in staggered rows, with solid bands left at the bottom and top for strength. The window size, row count and spacing are all derived from the radius, window count and strut width, so the lattice stays even whatever you change. Overall size is 72 x 72 x 100 mm. Print it standing on its base with no supports; the upper edges of the diamonds are exactly 45 degrees, so good cooling helps. You can change the outer radius, height, wall thickness, number of windows around and strut width.
# Lattice Pen Holder - cylindrical pen cup with a 45 deg diamond lattice wall
# Diamond windows are cut through the cylinder wall in a staggered pattern, leaving only the diagonal struts.
# Window positions are computed with a list comprehension.
@param 25..50 desc:"Outer radius (mm)"
r_out = 36
@param 60..140 desc:"Height (mm)"
height = 100
@param 2..5 step:0.5 desc:"Wall thickness (mm)"
wall = 3.0
@param 8..20 desc:"Windows around"
n_around = 12
@param 1.6..5 step:0.2 desc:"Strut width (mm)"
strut = 2.6
bottom_t = 3.0 # bottom thickness
band_bot = 8 # height of the solid band at the bottom (no windows)
band_top = 6 # height of the solid rim at the top (no windows)
# Diamond windows: circumferential pitch P, rows offset by half a pitch, row pitch = P/2 gives a 45 deg lattice
P = 2 * pi * r_out / n_around
s = P / sqrt(2) - strut # side of the diamond (square rotated 45 deg)
diag = s * sqrt(2) # diamond diagonal (both vertical and horizontal)
pz = P / 2 # row pitch
zone = height - band_bot - band_top
n_rows = floor((zone - diag) / pz) + 1
z0 = band_bot + (zone - (n_rows - 1) * pz) / 2 # center the window rows between the bands
step = 360 / n_around
rm = r_out - wall / 2
body = cylinder r_out height | floor
cavity = cylinder (r_out - wall) height | floor | translate 0 0 bottom_t
# Window k: row i = k // n_around, column j = k % n_around
windows = union [
(box (wall + 6) s s
| rotate 45 0 0
| translate rm 0 (z0 + (k // n_around) * pz)
| rotate 0 0 ((k % n_around) * step + ((k // n_around) % 2) * step / 2))
for k in range(n_rows * n_around)
]
body - cavity - windows