Desk Cable Grommet
A two-part grommet for the standard 60 mm cable hole in a desk top. The ring has a flange that rests on the desk and a skirt that goes through the hole, with a notch for the cables and a small lip near the bottom that snaps under the desk top; three slits let the skirt flex over the lip. A cap sits on a ledge inside the ring with a cable slot of its own: turn it to line the slot up with the notch or to close the hole. The default fits a 60 mm hole in a 25 mm top; the ring is 74 mm across and 32 mm tall, and the cap 56 mm across. Both parts print flat as laid out, ring upside down on its flange, with no supports. Adjustable parameters: hole diameter, desk thickness, skirt clearance, flange width, wall thickness, notch width and cap clearance.
# Desk Cable Grommet - two-part grommet for a 60 mm desk hole with a snap-in lip and a cable notch
#
# A ring that drops into the standard 60 mm cable hole of a desk top: a flange rests on
# the desk and a skirt goes through the hole, with a notch in the skirt for the cables.
# A cap sits in the ring with a cable slot of its own; turn it to open or close the slot
# against the notch. The skirt carries a small lip near its bottom that snaps under the
# desk top, so the ring stays put. Print both parts flat as laid out, no supports.
@param 50..80 step:1 group:"Hole" desc:"Desk hole diameter (mm)"
$hole_d = 60
@param 15..40 step:1 group:"Hole" desc:"Desk top thickness (mm)"
$desk_t = 25
@param 0.2..0.8 step:0.1 group:"Hole" desc:"Clearance of the skirt in the hole (mm, on the diameter)"
$play = 0.5
@param 4..10 step:1 group:"Ring" desc:"Flange width around the hole (mm)"
$flange_w = 7
@param 2..3.5 step:0.1 group:"Ring" desc:"Wall thickness (mm)"
$wall = 2.6
@param 15..35 step:1 group:"Cables" desc:"Cable notch width in the skirt and the cap (mm)"
$notch = 22
@param 0.2..0.6 step:0.05 group:"Cap" desc:"Clearance of the cap in the ring (mm, on the diameter)"
$cap_play = 0.4
$r_hole = $hole_d / 2
$r_skirt = $r_hole - $play / 2 # skirt outer radius
$r_in = $r_skirt - $wall # ring bore
$r_flange = $r_hole + $flange_w
$flange_t = 3
$skirt_h = $desk_t + 4 # skirt reaches 4 mm below the desk top
$lip = 1.0 # snap lip under the desk
$r_cap = $r_in - $cap_play / 2
$cap_t = 3
$cap_step = $wall - 1.0 # the cap's rim sits on this ledge cut into the flange, 1 mm of skirt wall remains
# --- Ring: flange on top, skirt below, lip at the bottom, cable notch through the skirt ---
$flange = (cylinder $r_flange $flange_t center:(true, true, false)) | edges >Z | fillet 1
$skirt = (cylinder $r_skirt $skirt_h center:(true, true, false)) | translate 0 0 (-$skirt_h + 0.01)
$lip_ring = cone ($r_skirt + $lip) $r_skirt 2 center:(true, true, false) | translate 0 0 (-$skirt_h) # 45 deg lead-in, flat top under the desk
$bore = (cylinder $r_in ($skirt_h + $flange_t + 2) center:(true, true, false) | translate 0 0 (-$skirt_h - 1))
+ (cylinder ($r_in + $cap_step) ($cap_t + 1) center:(true, true, false) | translate 0 0 ($flange_t - $cap_t)) # step for the cap
$ring_body = ($flange + $skirt + $lip_ring) - $bore
$ring_notch = box $notch ($r_flange + 2) ($skirt_h + 2) center:(true, false, false) | translate 0 0 (-$skirt_h - 1)
$ring = $ring_body - $ring_notch
# three slits around the skirt let it flex over the lip
$slits = box 1 ($r_skirt + 2) ($skirt_h - 4) center:(true, false, false) | polar 4 0 | translate 0 0 (-$skirt_h - 1) # the one at 0 deg falls inside the notch
$ring = $ring - $slits
assert $ring.solids == 1
assert $ring.bbox.x ~ (2 * $r_flange)
assert $ring.bbox.z ~ ($skirt_h + $flange_t)
# --- Cap: disc that sits on the step, with its own cable slot and a finger recess ---
$cap_disc = cylinder ($r_cap + $cap_step - $cap_play) $cap_t center:(true, true, false)
$cap_slot = box ($notch - 2) ($r_cap + $cap_step) ($cap_t + 2) center:(true, false, false) | translate 0 0 -1
$cap = ($cap_disc - $cap_slot) | edges >Z | fillet 1
assert $cap.solids == 1
# the cap in place (slot turned to the notch) clears the ring
$cap_in = $cap | translate 0 0 ($flange_t - $cap_t)
assert clear($cap_in, $ring)
assert $skirt_h - 4 > $desk_t - 8 # slits reach past the desk top so the lip can flex
# --- Print layout: ring upside down (flange on the bed), cap beside it ---
$ring_p = $ring | rotate 180 0 0 | floor
$cap_p = $cap | translate (2 * $r_flange + 10) 0 0
$out = $ring_p + $cap_p
assert $out.solids == 2
print "ring" $ring_p.bbox
print "cap" $cap_p.bbox
$out