Skip to content

Instantly share code, notes, and snippets.

@dm
Created April 15, 2026 09:58
Show Gist options
  • Select an option

  • Save dm/436c7532de629d0e3eeba19650c73ba8 to your computer and use it in GitHub Desktop.

Select an option

Save dm/436c7532de629d0e3eeba19650c73ba8 to your computer and use it in GitHub Desktop.
Compost Bin Builder — SketchUp 2020
# ============================================================
# Compost Bin Builder — SketchUp 2020
# ============================================================
# How to use:
# 1. Open SketchUp 2020
# 2. Go to Extensions > Ruby Console
# 3. Paste this entire script and press Enter
# 4. The model builds automatically — File > Save As to keep it
#
# Axes:
# X = left → right
# Y = back → front (0 = outer back face of back board)
# Z = up (0 = ground level)
#
# All dimensions in mm, converted to inches for SketchUp internally.
# ============================================================
model = Sketchup.active_model
model.entities.clear!
model.start_operation('Build Compost Bin', true)
F = 1.0 / 25.4 # mm to inches
add_box = lambda do |model, x, y, z, w, d, h|
grp = model.entities.add_group
ents = grp.entities
pts = [
Geom::Point3d.new( x * F, y * F, z * F),
Geom::Point3d.new((x+w) * F, y * F, z * F),
Geom::Point3d.new((x+w) * F, (y+d) * F, z * F),
Geom::Point3d.new( x * F, (y+d) * F, z * F)
]
face = ents.add_face(pts)
face.pushpull(h * F) if face
grp
end
# ── Dimensions (mm) ─────────────────────────────────────────
POST = 75.0 # post cross-section (square)
BT = 22.0 # board thickness
BH = 150.0 # board height per layer
LAYERS = 7 # boards stacked → 1050 mm total wall height
PHT = 1500.0 # post height shown (notional 300 mm below grade + 1200 mm above)
BURY = 600.0 # how deep posts go into the ground (shown below z=0)
INT = 1000.0 # interior clear dimension (both X and Y)
GAP = 26.0 # drop-board channel gap (22 mm board + 4 mm clearance)
# Derived
OW = POST*2 + BT*2 + INT # outer width = 1194 mm
# ── Y key positions (back → front) ──────────────────────────
# -POST … 0 B2 post (outside / behind back board)
# 0 … BT Back board (22 mm thick)
# BT … BT+POST L1 / R1 posts
# BT+POST … BT+POST+INT Side boards & interior (1000 mm)
# BT+POST+INT-POST … BT+POST+INT L3 / R3 posts
# BT+POST+INT … BT+POST+INT+GAP Drop-board channel (26 mm)
# BT+POST+INT+GAP … +POST FL / FR guide posts
# ── POSTS ───────────────────────────────────────────────────
POST_TOP = 1000 # 1m above ground
POST_H = 1800 # full post length (1.8m), extrudes downward leaving 80cm below z=0
# B2 — centre-back bracing post, sits OUTSIDE (behind) the back board
add_box.call(model, OW/2 - POST/2, -POST, POST_TOP, POST, POST, -POST_H)
# Left posts: L1 (back), L2 (mid), L3 (front-end of side boards)
add_box.call(model, 0, BT, POST_TOP, POST, POST, -POST_H) # L1
add_box.call(model, 0, BT + INT/2 - POST/2, POST_TOP, POST, POST, -POST_H) # L2
add_box.call(model, 0, BT + INT - POST, POST_TOP, POST, POST, -POST_H) # L3
# Right posts: R1, R2, R3 (mirror of left)
add_box.call(model, OW-POST, BT, POST_TOP, POST, POST, -POST_H) # R1
add_box.call(model, OW-POST, BT + INT/2 - POST/2, POST_TOP, POST, POST, -POST_H) # R2
add_box.call(model, OW-POST, BT + INT - POST, POST_TOP, POST, POST, -POST_H) # R3
# Guide posts: FL, FR — define the front drop-board slide channel
add_box.call(model, 0, BT + INT + GAP, POST_TOP, POST, POST, -POST_H) # FL
add_box.call(model, OW - POST, BT + INT + GAP, POST_TOP, POST, POST, -POST_H) # FR
# ── BOARDS ──────────────────────────────────────────────────
# Back boards (7 stacked) — outside-back of L1/R1, screwed from outside in
LAYERS.times do |i|
add_box.call(model, 0, 0, (i+1)*BH, OW, BT, -BH)
end
# Left side boards (7 stacked) — flush with inner face of back board, screwed inside out
LAYERS.times do |i|
add_box.call(model, POST, BT, (i+1)*BH, BT, INT, -BH)
end
# Right side boards (7 stacked) — flush with inner face of back board, screwed inside out
LAYERS.times do |i|
add_box.call(model, POST+BT+INT, BT, (i+1)*BH, BT, INT, -BH)
end
# Front drop boards (7 stacked) — removable, shown in channel position
drop_y = BT + INT
LAYERS.times do |i|
add_box.call(model, 0, drop_y, (i+1)*BH, OW, BT, -BH)
end
# ── Finish ──────────────────────────────────────────────────
model.commit_operation
model.active_view.zoom_extents
puts ""
puts "=== Compost bin built! ==="
puts " Outer footprint: #{(OW).round} mm wide x #{(BT+POST+INT+GAP+POST).round} mm deep"
puts " Interior clear: #{INT.round} x #{INT.round} mm"
puts " Wall height: #{(LAYERS*BH).round} mm (#{LAYERS} boards x #{BH.round} mm)"
puts " Posts: 9 total (L1-3, R1-3, FL, FR, B2)"
puts ""
puts " Tip: use View > Toolbars > Styles to apply a wood material,"
puts " or select all geometry and use the Paint Bucket tool."
puts " Save with File > Save As to keep the .skp file."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment