"""Pergola with string lights, over the bench at Tidewater. Writes pergola.json for bridge/slbuild.py. Root = the SW post; everything else is relative to it (no rotation on the root). Claude Opus 5.5, 2026-10-10.""" import json import math W, D, H = 3.4, 2.3, 2.6 # x span between post centres, y span, post height POST, BEAM = 0.12, 0.1 WOOD, DARK = "#8a5f38", "#5a3f28" BULB = "#ffd9a0" prims = [] def add(**p): p.setdefault("texture", "blank") prims.append(p) # posts: root at local (0,0,0) is the SW post's centre; build bottom rests on the ground corners = [(0, 0), (W, 0), (0, D), (W, D)] for i, (x, y) in enumerate(corners): add(name="Tidewater Pergola" if i == 0 else "post", shape="box", size=[POST, POST, H], **({} if i == 0 else {"pos": [x, y, 0]}), color=DARK, bump="wood") top = H / 2 # beams along x on both long sides, a little proud of the posts for y in (0, D): add(name="beam", shape="box", size=[W + 0.5, BEAM, 0.16], pos=[W / 2, y, top + 0.04], color=WOOD, bump="wood") # rafters across, resting on the beams for k in range(6): x = -0.1 + k * (W + 0.2) / 5 add(name="rafter", shape="box", size=[0.07, D + 0.5, 0.12], pos=[round(x, 3), D / 2, top + 0.17], color=WOOD, bump="wood") # string lights: a sagging strand under each beam, bulbs at even steps, wire segments between them n, sag = 8, 0.28 for side, y in (("n", D - 0.04), ("s", 0.04)): pts = [] for k in range(n): t = k / (n - 1) x = 0.08 + t * (W - 0.16) z = top - 0.12 - sag * 4 * t * (1 - t) pts.append((x, z)) for k, (x, z) in enumerate(pts): bulb = dict(name="bulb", shape="sphere", size=[0.07, 0.07, 0.09], pos=[round(x, 3), y, round(z - 0.05, 3)], color=BULB, fullbright=True, glow=0.3) if side == "n" and k == n // 2: bulb["light"] = {"color": "#ffcf8a", "intensity": 0.8, "radius": 6, "falloff": 0.8} add(**bulb) for (x1, z1), (x2, z2) in zip(pts, pts[1:]): length = math.hypot(x2 - x1, z2 - z1) tilt = math.degrees(math.atan2(x2 - x1, z2 - z1)) # cylinder axis (+z) turned about y onto the segment add(name="wire", shape="cylinder", size=[0.012, 0.012, round(length, 3)], pos=[round((x1 + x2) / 2, 3), y, round((z1 + z2) / 2, 3)], rot=[0, round(tilt, 2), 0], color="#1a1a1a") with open("pergola.json", "w") as f: f.write("// generated by gen_pergola.py\n{\n \"name\": \"Tidewater Pergola\",\n \"desc\": \"Made by Tessel the AI (Claude)\",\n \"prims\": [\n") f.write(",\n".join(" " + json.dumps(p) for p in prims)) f.write("\n ]\n}\n") print(len(prims), "prims")