""" Under-desk clamp-on homelab rack — single source of truth for all geometry. MATERIAL: Columbia Forest Products PureBond Birch Plywood, 3/4 in. nominal. Home Depot lists the ACTUAL thickness as 0.703" (23/32"), 7-ply, ~70 lb per 4x8 sheet, face grain running the 96" length. Everything thickness-dependent is derived from T — change T and re-run. TARGET ENVELOPE: 33" wide x 10" deep x 10" high (revised). Bay clear height is 3-15/16" so the walls are a markable size; overall height lands at 9.984", i.e. 1/64" under 10". Coordinate system (all units INCHES): X : width, 0 = left outer face, 33 = right outer face Y : depth, 0 = FRONT edge (toward user), + = toward the WALL Z : height, 0 = bottom of rack, + = up toward the desk underside Cross-section is two opposite-facing U shapes sharing the middle shelf: z= 9.984 +==================================+ TOP PANEL (against desk) | [doubler] SWITCH lives | FRONT | REAR / CABLE BAY here | -> OPEN TO WALL WALL | 3-15/16" clear | z= 5.344 +==================================+ MIDDLE SHELF (5 x 2" grommets) | | | FRONT / EQUIPMENT BAY | REAR WALL OPEN <-- | 3-15/16" clear | 6 x 2" pass-throughs TO USER | 4 mini PCs + FireCuda | z= 0.703 +==================================+ BOTTOM PANEL (12 x 1.5" vents) y=0 (front) y=10 (wall) """ # --------------------------------------------------------------------------- # Global parameters # --------------------------------------------------------------------------- T = 0.703 # ACTUAL thickness of HD PureBond birch 3/4" nominal W = 33.0 # overall width D = 10.0 # overall depth (front to wall) CLEAR = 3.9375 # clear internal height of EACH bay (3-15/16") H = 3 * T + 2 * CLEAR # = 9.984 overall height MATERIAL = "3/4 in. PureBond Birch Plywood (actual 0.703 in.)" SHEET = (96.0, 48.0) SHEET_LB = 70.0 PLY_LB_PER_SQFT = SHEET_LB / (SHEET[0] * SHEET[1] / 144.0) # = 2.1875 # Key Z stations Z_BOT_0, Z_BOT_1 = 0.0, T Z_MID_0, Z_MID_1 = T + CLEAR, 2 * T + CLEAR Z_TOP_0, Z_TOP_1 = H - T, H # Key Y stations Y_FRONT_WALL_0, Y_FRONT_WALL_1 = 0.0, T Y_REAR_WALL_0, Y_REAR_WALL_1 = D - T, D Y_DOUBLER_0, Y_DOUBLER_1 = D - 2.75, D # Clear interior X_IN_0, X_IN_1 = T, W - T INNER_LEN = W - 2 * T # 31.594 — length of every "inner" panel SIDE_HT = 2 * CLEAR + T # 8.578 — height of the side panels CLEAR_W = INNER_LEN # 31.594 clear width, both bays CLEAR_D = D - T # 9.297 clear depth, both bays (one wall each) # --------------------------------------------------------------------------- # Equipment layout # The Ethernet switch moved UP into the cable bay: at 33" wide the front bay # could only give six devices 0.40" of air each. With five it gives 1.12", # and the switch is now sitting with the patch leads it belongs to. # --------------------------------------------------------------------------- DEVICES = [ # FRONT / EQUIPMENT BAY — name, center X, width, depth, height ("Beelink mini PC #1", 4.375, 5.10, 5.10, 2.00), ("Beelink mini PC #2", 10.625, 5.10, 5.10, 2.00), ("Beelink mini PC #3", 16.875, 5.10, 5.10, 2.00), ("Beelink mini PC #4", 23.125, 5.10, 5.10, 2.00), ("Seagate FireCuda HDD", 29.000, 4.40, 7.90, 1.90), ] DEVICE_Y0 = 0.50 # set back 1/2" from the open front edge CABLE_DEVICES = [ # REAR / CABLE BAY — name, center X, width, depth, height, Y0 ("Ethernet switch", 16.500, 4.00, 6.50, 1.10, 1.50), ] DEVICE_X = [d[1] for d in DEVICES] # 5 front-bay centrelines # =========================================================================== # HOLE SCHEDULE — 23 holes, 3 panels, 2 hole saws (1-1/2" and 2") # =========================================================================== # --- MIDDLE SHELF: one 2" grommet directly behind each front-bay device ---- GROMMET_DIA = 2.00 GROMMET_Y = 7.50 # 0.797" clear of the rear wall GROMMET_X = list(DEVICE_X) # 5 holes, on the device centrelines # --- BOTTOM PANEL: 12 x 1-1/2" vents, 2 rows x 6 columns at an even pitch -- VENT_DIA = 1.50 VENT_Y = [2.50, 5.00] VENT_PITCH = 5.25 VENT_X = [3.25 + VENT_PITCH * i for i in range(6)] # --- REAR WALL: 6 x 2" cable pass-throughs, equally spaced ---------------- REAR_HOLE_DIA = 2.00 REAR_HOLE_PITCH = INNER_LEN / 6.0 REAR_HOLE_X_LOCAL = [REAR_HOLE_PITCH * (i + 0.5) for i in range(6)] REAR_HOLE_X = [X_IN_0 + x for x in REAR_HOLE_X_LOCAL] REAR_HOLE_Z = Z_BOT_1 + CLEAR / 2.0 # mid-height of the wall # --------------------------------------------------------------------------- # Clamp bearing zones on the TOP panel — 4 clamps at an even W/8 pitch # --------------------------------------------------------------------------- CLAMP_X = [W / 8.0 * k for k in (1, 3, 5, 7)] # 4-1/8, 12-3/8, 20-5/8, 28-7/8 CLAMP_Y_MIN, CLAMP_Y_MAX = D - 2.5, D CLAMP_PAD = 2.00 # --------------------------------------------------------------------------- # Panel schedule. box = (x0, y0, z0, x1, y1, z1) # axis = direction the panel is extruded through its thickness # holes = (u, v, dia) in the panel's own plane, in world coordinates # --------------------------------------------------------------------------- PANELS = [ dict( key="bottom", name="Bottom panel", qty=1, part=7, box=(0.0, 0.0, Z_BOT_0, W, D, Z_BOT_1), size=(W, D), axis="z", color="#33333b", note='12 x 1-1/2" vent holes, 2 rows of 6', holes=[(x, y, VENT_DIA) for y in VENT_Y for x in VENT_X], ), dict( key="rear_wall", name="Rear wall", qty=1, part=6, box=(X_IN_0, Y_REAR_WALL_0, Z_BOT_1, X_IN_1, Y_REAR_WALL_1, Z_MID_0), size=(INNER_LEN, CLEAR), axis="y", color="#45454f", note='6 x 2" cable pass-throughs, equally spaced', holes=[(x, REAR_HOLE_Z, REAR_HOLE_DIA) for x in REAR_HOLE_X], ), dict( key="side_l", name="Side panel (left)", qty=2, part=5, box=(0.0, 0.0, Z_BOT_1, T, D, Z_TOP_0), size=(D, SIDE_HT), axis="x", color="#3d3d46", note="fits between the top and bottom panels", holes=[], ), dict( key="side_r", name="Side panel (right)", qty=0, part=5, box=(W - T, 0.0, Z_BOT_1, W, D, Z_TOP_0), size=(D, SIDE_HT), axis="x", color="#3d3d46", note="", holes=[], ), dict( key="middle", name="Middle shelf", qty=1, part=4, box=(X_IN_0, 0.0, Z_MID_0, X_IN_1, D, Z_MID_1), size=(INNER_LEN, D), axis="z", color="#3a3a43", note='5 x 2" grommet holes, one per device', holes=[(x, GROMMET_Y, GROMMET_DIA) for x in GROMMET_X], ), dict( key="front_wall", name="Front wall", qty=1, part=3, box=(X_IN_0, Y_FRONT_WALL_0, Z_MID_1, X_IN_1, Y_FRONT_WALL_1, Z_TOP_0), size=(INNER_LEN, CLEAR), axis="y", color="#45454f", note="the clean face you see from the chair", holes=[], ), dict( key="doubler", name="Clamp doubler", qty=1, part=2, box=(X_IN_0, Y_DOUBLER_0, Z_TOP_0 - T, X_IN_1, Y_DOUBLER_1, Z_TOP_0), size=(INNER_LEN, 2.75), axis="z", color="#5a5a68", note="doubles the top panel where the clamp jaws bite", holes=[], ), dict( key="top", name="Top panel", qty=1, part=1, box=(0.0, 0.0, Z_TOP_0, W, D, Z_TOP_1), size=(W, D), axis="z", color="#33333b", note="bears flat on the desk underside; clamps grip here", holes=[], ), ] PANELS_BY_KEY = {p["key"]: p for p in PANELS} # --------------------------------------------------------------------------- # Sheet nesting on one 96" x 48" sheet. # (x, y) is the lower-left corner; (w, h) is the piece footprint. # --------------------------------------------------------------------------- RIPS = [(0.0, 10.0, "R1"), (10.0, 10.0, "R2"), (20.0, 6.6875, "R3")] NEST = [ # key, x, y, w, h, rip ("top", 0.0, 0.0, W, D, "R1"), ("bottom", 33.5, 0.0, W, D, "R1"), ("middle", 0.0, 10.0, INNER_LEN, D, "R2"), ("side_l", 32.0, 10.0, D, SIDE_HT, "R2"), ("side_r", 43.0, 10.0, D, SIDE_HT, "R2"), ("front_wall", 0.0, 20.0, INNER_LEN, CLEAR, "R3"), ("rear_wall", 32.0, 20.0, INNER_LEN, CLEAR, "R3"), ("doubler", 0.0, 23.9375, INNER_LEN, 2.75, "R3"), ] # --------------------------------------------------------------------------- # Derived clear volumes # --------------------------------------------------------------------------- EQUIP_BAY = dict(x=(X_IN_0, X_IN_1), y=(0.0, Y_REAR_WALL_0), z=(Z_BOT_1, Z_MID_0)) CABLE_BAY = dict(x=(X_IN_0, X_IN_1), y=(Y_FRONT_WALL_1, D), z=(Z_MID_1, Z_TOP_0))