Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lab Rax — Parametric 10" Rack Shelf with Front Panel (OpenSCAD)

A fully parametric OpenSCAD model of a 10-inch rack shelf with an integrated front panel, mechanically compatible with the Lab Rax 3D-printed rack system by Michael Klements (The DIY Life): 236.525 mm mounting raster, 1U = 44.45 mm, three M6 holes per U per side. Designed to print on ~250 mm beds (Bambu Lab A1, 256 × 256 mm) without supports.

Shelf assembly

Highlights

  • Panel and shelf are generated as a single printable monolith, already oriented for printing (panel face down, shelf growing upward).
  • A declarative cutout system: every hole in the panel or the shelf deck is one line in a list — circles, rectangles, slots, hexagons, grids, linear arrays, PC-fan presets, Raspberry Pi preset.
  • Mounting holes are horizontal slots for sideways adjustment, and they are skipped automatically wherever the shelf, its walls, ribs or gussets cover them from behind.
  • Extensive assert() validation with readable error messages: parts that exceed the build plate, the panel outline, or the rack geometry fail loudly at render time.
  • A standalone button generator (button.scad) for panel cutouts — including backlit transparent power buttons.

Requires OpenSCAD 2021.01 or newer.


Table of contents

  1. Quick start
  2. File layout
  3. Coordinate systems
  4. Main parameters (Customizer)
  5. The declarative cutout system
  6. The shelf and its walls
  7. Automatic mounting-hole management
  8. Printability
  9. The button generator
  10. Examples
  11. Calibration
  12. System constants

Quick start

  1. Open main.scad in OpenSCAD.
  2. Open Window → Customizer — all parameters (part, panel, shelf, walls, ribs, quality) are exposed as sliders and dropdowns.
  3. Define your cutouts in the panel_cutouts and shelf_holes lists in main.scad (see the cutout system).
  4. Press F6 to render, F7 to export STL. The model is already in print orientation — no rotation needed in the slicer.

Ready-made configurations live in examples/.

File layout

main.scad          entry point: Customizer parameters, part switch, assembly
config.scad        Lab Rax system constants + globals (hole_clearance, EPS)
button.scad        standalone button generator (round/rect face, flange, pin)
lib/rack_std.scad  u_height(), mount_hole_positions(), panel outline, validation
lib/cutouts.scad   declarative cutout system: cutout(spec) dispatcher + validation
lib/helpers.scad   rounded_rect(), slot2d(), hex2d(), hole_negative(), chamfers
panel.scad         module panel(u, cutouts, ...)
shelf.scad         module shelf(width, depth, wall_type, ..., holes)
examples/          self-contained example configurations

Library files do not include their own dependencies — main.scad (and each example) defines the include order. If you build your own top-level file, copy the include block from main.scad.

Coordinate systems

All dimensions are millimeters. Two 2D coordinate systems are used for cutouts, both viewed from the front of the rack:

List Origin [0,0] X axis Y axis
panel_cutouts panel center right up
shelf_holes deck center right toward the rack's back

The 3D model itself is built in print orientation: panel plane = XY, front face at z = 0 (bed side), rack depth along +Z.

Main parameters (Customizer)

Part & orientation

Parameter Default Description
part assembly assembly / panel / shelf — what to render. The printed part is the monolithic assembly; the single parts are for inspection.
orientation print print = as printed (export this); upright = in-use orientation for previewing.

Panel

Parameter Default Description
panel_u 2 Panel height in rack units (1–5).
panel_thickness 3 Panel thickness [mm].
corner_radius 3 Outline corner radius [mm].
edge_chamfer 0.6 45° chamfer on the outer edges of both faces [mm].
mount_slot_length 10 Overall length of the M6 mounting slots [mm]. 10 mm gives ±1.85 mm of sideways adjustment; 6.3 degenerates to a plain round hole.
panel_top_trim 0 Shortens the panel from the top [mm]. 15.875 removes exactly one hole row; the bottom edge and the coordinate system stay put. Holes that no longer fit are skipped automatically.

Shelf

Parameter Default Description
shelf_enable true Generate the shelf at all.
shelf_width 180 Deck width [mm]. Limited by the panel width (250), not by the 222 mm post clearance — see hole management.
shelf_depth 100 Deck depth [mm] (= print height − panel thickness).
shelf_thickness 3 Deck thickness [mm].
shelf_x_offset 0 Sideways shift of the shelf relative to the panel center [mm].
shelf_z_offset 6 Height of the deck's bottom plane above the panel's bottom edge [mm].

Walls

Parameter Default Description
wall_type slant none / slant / rect (see walls).
wall_height 15 Wall height at the panel, measured above the deck's top surface [mm].
wall_end_height 0 slant only: wall height at the deck's far end [mm]. 0 = slope all the way down to the deck.
wall_thickness 0 Wall thickness [mm]; 0 = same as deck thickness.
wall_left / wall_right / wall_back true Which edges get walls.

Ribs & gussets

Parameter Default Description
ribs_enable false Stiffening ribs under the deck (vertical fins running along the depth).
ribs_count 3 Number of ribs, evenly spaced across the deck width.
ribs_height 8 Rib height below the deck [mm]; clipped to the panel's bottom edge.
gusset_enable false Triangular panel-to-deck gussets at the deck's side edges.
gusset_size 10 Gusset leg length [mm]; clipped to shelf_z_offset.

Quality

Parameter Default Description
preview_quality 24 $fn used in the F5 preview — keep it low for smooth model rotation.
render_quality 128 $fn used for F6 render / STL export — high for smooth arcs on the print.

Switching is automatic via OpenSCAD's $preview variable; you never have to change it by hand.

Globals (config.scad)

Parameter Default Description
hole_clearance 0.3 Added to the diameter of every screw hole (M6 slots, fan screws, presets). Tune after a test print.
EPS 0.01 Epsilon used to oversize negative volumes (avoids z-fighting / non-manifold booleans).

The declarative cutout system

A cutout is a vector: [type, [x, y], parameters...]. Optional trailing parameters can simply be omitted. Adding or removing a hole is a one-line edit.

Spec Description
["circle", [x,y], d, chamfer, chamfer_side] Round hole of diameter d.
["rect", [x,y], [w,h], r, chamfer, rot, chamfer_side] Rectangle; r = corner radius, rot = rotation in degrees.
["slot", [x,y], l, d, rot, chamfer, chamfer_side] Slot / stadium; l = overall length including the end arcs, d = width.
["hex", [x,y], af, rot, chamfer, chamfer_side] Regular hexagon; af = across-flats (wrench size), e.g. for captive nuts.
["grid", [x,y], child, nx, ny, [px,py]] nx × ny grid of any child cutout; [x,y] = grid center, [px,py] = pitch.
["linear", [x,y], child, n, pitch, rot] Linear array of n child cutouts, centered at [x,y].
["fan", [x,y], size, chamfer, chamfer_side] PC fan preset: size ∈ {40, 80, 120}. Opening + four Ø4.3 screw holes (spacings: 40→32 mm/Ø38, 80→71.5 mm/Ø76.5, 120→105 mm/Ø116.5).
["rpi5", [x,y], rot] Raspberry Pi 5/4/3B+ preset: 58 × 49 mm pattern, M2.5 holes (deck).
["grid_m3" | "grid_m4", [x,y], nx, ny, [px,py]] Generic M3 / M4 screw grids.

Details:

  • chamfer — width of a 45° countersink chamfer in mm. chamfer_side"front" (default), "back" or "both". "Front" means the panel's visible face, or the deck's top surface.
  • rot — rotation of the cutout around its own center, degrees.
  • child in grid/linear is a complete cutout spec (normally with position [0,0]); patterns may be nested arbitrarily (e.g. a grid of slots, a linear array of hexes).
  • Every screw-hole preset already includes the global hole_clearance.

Validation: a cutout extending outside the panel/deck outline stops the render with a descriptive assert. A cutout that may collide with a mounting slot produces an echo warning (a conservative circumscribed-circle test — expect occasional false positives; check visually).

Worked example — a 2U panel with two 80 mm fans:

panel_cutouts = [
    ["fan",  [-45, 0], 80, 1, "front"],
    ["fan",  [ 45, 0], 80, 1, "front"],
    ["grid", [  0, 0], ["hex", [0,0], 6], 1, 5, [0, 8]],  // hex column between fans
];

And mounting a Mini-ITX board on the deck:

shelf_holes = [
    // 4× M3 standoff holes, 157.48 × 154.94 mm pattern (2×2 grid)
    ["grid", [0, 0], ["circle", [0,0], 3.4], 2, 2, [157.48, 154.94]],
];

The shelf and its walls

The shelf is a monolith with the panel: a deck perpendicular to the panel, extending into the rack. shelf_z_offset positions the deck's bottom plane relative to the panel's bottom edge.

Wall types (wall_type):

  • none — bare deck.
  • rect — vertical walls of constant height wall_height.
  • slant — vertical side walls whose top edge slopes along the depth: wall_height at the panel, descending to wall_end_height at the deck's far end (0 = all the way down).

The back wall is always vertical (90° to the deck). In slant mode its height equals wall_end_height (so it lines up with the sloped side walls; with 0 it is omitted), in rect mode it is wall_height. Walls taller than the panel are clipped to the panel's top edge (with an INFO message).

Automatic mounting-hole management

The shelf width is limited by the panel width (250 mm), not by the 222 mm clearance between the rack posts — this allows wide boards to sit directly on the deck. The trade-off: a wide shelf, its walls, ribs or gussets can end up right behind some of the panel's mounting slots.

The model resolves this automatically: shelf_panel_keepouts() computes the exact shelf-to-panel contact zones, and panel() skips every mounting slot that collides with one (with a 0.5 mm material margin), emitting an INFO message per skipped hole. Slots above and below an obstacle are still cut. Combined with panel_top_trim this lets you design panels with exactly the rows of mounting holes you can actually reach.

If you call panel() directly (as the examples do), pass the keepouts yourself:

panel(u = 2, cutouts = my_cutouts,
      mount_keepouts = shelf_panel_keepouts(u = 2, width = 240,
                                            thickness = 3, z_offset = 6,
                                            wall_type = "slant",
                                            wall_height = 15));

Printability

Print orientation: panel face down on the bed, shelf growing upward — the exported STL is already oriented this way.

  • The deck, side walls (rect and slant, any slope), ribs and gussets print without supports: every layer is contained within the one below it.
  • The back wall is an overhang (a horizontal cantilever at the top of the print) — the model emits a warning. Either disable it (wall_back = false), or print with a small local support.
  • Hole chamfers on the front face print as 45° rings directly on the bed — no bridging problems.
  • Asserts guard the build volume: any part larger than 256 mm in X/Y/Z aborts the render with a clear message.

Suggested settings: PETG or PLA, 3–4 perimeters, no supports (except the back wall case above).

The button generator

button.scad is a standalone generator for panel buttons (e.g. a power button extender above a motherboard's tactile switch). The button goes into the panel cutout from the back:

Parameter Default Description
button_shape circle circle or rect face.
hole_d / hole_w, hole_h, hole_r 12 / 14, 6.5, 1 Dimensions of the panel cutout — the same numbers you used in panel_cutouts; the clearance is subtracted automatically.
clearance 0.25 Face-to-cutout play per side [mm].
face_proud 1.5 How far the face protrudes in front of the panel [mm].
face_round 0.8 Rounding radius of the face edge [mm] (0 = sharp).
panel_t 3 Panel thickness the body passes through [mm].
flange_w / flange_t 1.5 / 1.5 Flange (retaining collar) width per side / thickness [mm].
pin_d / pin_l 4 / 2 Central pin diameter / length behind the flange [mm]. Measure pin_l on the assembled unit: distance from the panel's back to the switch, minus ~0.5 mm so the button does not hold the switch pressed.

Print face-down (as generated): the face comes out smooth with a clean rounded edge. The flange is a plain overhang — use small supports under it. For a backlit power button print in transparent filament with 100% infill; the board's LED will glow through the whole button.

Examples

Each file in examples/ is self-contained — open, render, export:

File Contents
blank_panel_1u.scad 1U blank panel — fit-test print for hole_clearance tuning.
keystone_panel_1u.scad 1U keystone patch panel: 6 snap-in ports (RJ45/USB/HDMI couplers), printed 2 mm thick so the keystone latch engages.
cable_panel_1u.scad 1U cable pass-through: wide chamfered slot + zip-tie anchor slots for strain relief.
vent_panel_2u.scad 2U vent panel: 2× 80 mm fan + hex-grid column.
rpi5_shelf_2u.scad 1U Raspberry Pi 5 shelf: slant walls, gussets, rpi5 preset, vent slots.
pi_cluster_2u.scad 2U dual Raspberry Pi 5 cluster shelf: boards side by side, ports facing front, per-board port windows in the panel, rotated rpi5 pattern.
ssd_shelf_2u.scad 2U shelf for two 2.5" drives: SFF bottom-mount M3 pattern, vent slots under the drives and in the panel.
tray_3u.scad Deep 3U tray: rect side walls, ribs, gussets, M3 grid, cable slot in the panel.
mini_itx_3u.scad 3U Mini-ITX shelf: M3 standoff pattern, ATX I/O window in the panel, ventilation. Demonstrates deriving cutout positions from a few measured variables.

The examples show the recommended pattern for real builds: put your measured dimensions in named variables and derive the cutout positions from them, so a single correction shifts everything consistently.

Gallery

Keystone patch panel 1U keystone patch panel (6 ports) Cable pass-through 1U cable pass-through with zip-tie anchors
2U vent panel 2U vent panel: 2× 80 mm fans Pi cluster shelf Dual Raspberry Pi 5 cluster shelf
Raspberry Pi shelf Raspberry Pi 5 shelf SSD shelf Dual 2.5" drive shelf
3U tray Deep 3U tray with ribs Mini-ITX shelf Mini-ITX shelf with ATX I/O window
Button Generated button (button.scad)

Calibration

  1. Print examples/blank_panel_1u.scad.
  2. Check the fit in your rack: M6 screws through the slots into the post inserts.
  3. Too tight / too loose? Adjust hole_clearance in config.scad (affects every screw hole in the project) and reprint.

System constants

Defined in config.scad. Do not change — they encode Lab Rax compatibility:

Constant Value Meaning
RACK_U 44.45 mm Height of one rack unit.
MOUNT_HOLE_SPACING_X 236.525 mm Horizontal center-to-center mounting spacing.
RACK_CLEARANCE_W 222 mm Clear width between the rack posts (informational).
MOUNT_HOLE_D 6 mm M6 mounting screws (clearance added on top).
HOLE_PATTERN_1U 6.35 / 22.225 / 38.1 mm Hole positions within 1U, from the U's bottom edge.
PANEL_W 250 mm Total panel width including ears (project decision, fits a 256 mm bed).

License & credits

Licensed under Creative Commons Attribution 4.0 International (CC BY 4.0) — see LICENSE. You are free to share and adapt this work, including commercially, as long as you give appropriate credit.

Compatible with the Lab Rax rack system by Michael Klements (The DIY Life). This model is an independent parametric implementation; verify all dimensions against your own rack before committing to long prints.

About

Parametric OpenSCAD shelf with front panel for 10" Lab Rax racks — declarative cutout system, fan/RPi presets, support-free printing

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages