
끌어서 회전, 휠·두 손가락으로 확대
이 모형에 대하여
엘리자베스 타워는 1834년 화재로 소실된 웨스트민스터 궁전을 재건하면서 세운 시계탑이다. 건축가 찰스 배리가 궁전 전체를 설계했고, 탑의 설계는 오거스터스 퓨진이 맡았다. 1859년 완공되었으며, 원래 '시계탑'으로 불리다가 2012년 엘리자베스 2세 즉위 60주년을 기념해 지금의 이름이 붙었다. 흔히 부르는 '빅벤'은 본래 탑 안에 걸린 가장 큰 종의 별칭이다.
탑은 벽돌 구조에 앤스턴 석회암을 덧댔고, 위쪽 지붕과 첨탑은 주철로 덮었다. 네 면에는 지름 약 7m의 시계판이 있으며, 주철 틀에 유백색 유리를 끼워 넣은 구조다. 시계판은 금박 장식이 든 정사각 테두리 안에 놓이고, 그 위로 종루와 가파른 사각뿔 지붕, 의회 개회 중에 불을 밝히는 에어턴 라이트 랜턴이 이어진다.
이 모델은 실제 비례를 따라 탑신, 시계층, 종루, 지붕, 랜턴, 첨탑을 쌓아 올렸다. 탑신의 수직 패널과 뾰족아치, 시계판의 로마 숫자와 방사형 철골, 2017~2022년 보수 때 되살린 프러시안 블루 철골과 금박 장식의 배색을 표현했다.
만든 방법
한 면(-Y)의 패널·창·시계판을 만들어 하나의 메시로 합친 뒤, 탑 중심축으로 90°씩 돌린 링크 복제로 나머지 세 면을 채웠다. 뾰족아치 테두리와 창은 원호 두 개로 계산한 2D 윤곽을 돌출해 만들었고, 시계판은 원판·토러스 고리·방사형 살·텍스트를 메시로 바꾼 로마 숫자로 구성했다. 지붕과 첨탑, 시계층 아래 내민 받침은 4분할 회전체를 45° 돌려 사각뿔대로 만들었다. 실제 탑신의 세밀한 퍼펜디큘러 트레이서리와 조각, 시계판 아래 라틴어 명문은 단순한 패널과 금박 띠로 줄였고, 궁전 본관과 이어지는 부분은 생략해 탑만 독립시켰다.
build.py
이 파일 하나를 Blender 에서 실행하면 위의 모형이 만들어집니다. 329줄.
# 엘리자베스 타워(빅벤), 영국 런던 웨스트민스터 궁전 — 높이 약 96m 실측 비례 모델.# 정사각 탑신·시계층·종루·주철 지붕·랜턴·첨탑을 아래에서 위로 쌓았다.# 한 면(-Y 쪽)의 패널·아치·시계판을 만들어 하나로 합친 뒤, 탑 중심축으로 90°씩 돌린# 링크 복제로 나머지 세 면을 채웠다. 시계판은 원판 + 토러스 고리 + 방사형 살 + 로마 숫자(텍스트→메시),# 뾰족아치 테두리는 2D 윤곽을 돌출(extrude)해 만들고, 지붕과 첨탑은 4분할 회전체로 사각뿔을 냈다.import mathfrom atelier import *SHOT = {"azimuth": -58, "elevation": 9, "lens": 60, "light": "day", "background": "#26303d"}# ── 재질 ────────────────────────────────────────────────STONE = mat('Anston_Limestone', '#cdb88f', 0.8)RECESS = mat('Limestone_Shadowed', '#a8916b', 0.85)PLINTH = mat('Plinth_Stone', '#a59479', 0.85)DARK = mat('Belfry_Interior', '#2a2622', 0.9)WIN = mat('Window_Glass', '#2e3742', 0.2, 0.1)DIAL = mat('Opal_Dial_Glass', '#efe6cf', 0.35, emit='#fff1d0', emit_strength=0.25)IRON = mat('Prussian_Blue_Iron', '#1d2a48', 0.4, 0.5)GOLD = mat('Gold_Leaf', '#d4a84a', 0.28, 1.0)ROOF = mat('Cast_Iron_Roof', '#3a4652', 0.5, 0.45)LAMP = mat('Ayrton_Light_Glass', '#ead9a6', 0.3, emit='#ffe2a0', emit_strength=0.6)H = 6.0 # 탑신 반폭(12m 정사각)SQ = math.sqrt(2)HB = 6.4 # 버트레스·시계층 반폭def face_group(objs, name): """한 면 부품을 합치고, 원점을 탑 중심축에 둔 뒤 나머지 세 면을 링크 복제.""" ob = join(objs, name) ob.data.transform(ob.matrix_world) ob.matrix_world = Matrix.Identity(4) for k in (1, 2, 3): duplicate(ob, loc=(0, 0, 0), rot=(0, 0, k * math.pi / 2), name=f'{name}_{k}') return obdef arch_curve(w, rise, n=8): """폭 w, 높이 rise 인 뾰족아치 곡선 점(왼쪽 밑→정점→오른쪽 밑), 기준 z=0.""" a = w / 2 R = (a * a + rise * rise) / (2 * a) # 정점 높이가 rise 가 되는 반지름 cx = -a + R left = [] for i in range(n + 1): t = i / n ang0 = math.pi ang1 = math.pi - math.asin(rise / R) ang = ang0 + (ang1 - ang0) * t나머지 281줄 펼치기접기
left.append((cx + R * math.cos(ang), R * math.sin(ang))) left[-1] = (0.0, rise) right = [(-x, z) for x, z in reversed(left[:-1])] return left + rightdef arch_spandrel(name, w, rise, top, x, z, y, depth, material): """패널 윗부분: 사각형에서 뾰족아치를 빼낸 돌 테두리.""" pts = arch_curve(w, rise) + [(w / 2, top), (-w / 2, top)] ob = extrude_profile(name, pts, depth, loc=(x, y, z), material=material) return obdef lancet(name, w, h, rise, x, z, y, depth, material): """직사각 + 뾰족아치 머리의 창(창유리 판).""" arc = arch_curve(w, rise) pts = [(-w / 2, -h)] + [(px, pz) for px, pz in arc] + [(w / 2, -h)] pts = list(reversed(pts)) return extrude_profile(name, pts, depth, loc=(x, y, z + h), material=material)def sq_lathe(name, profile, material): """4분할 회전체를 45° 돌려 사각뿔(대)로 만들고, 회전을 메시에 굳힌다. profile 의 r 은 반폭.""" ob = lathe(name, [(r * SQ, z) for r, z in profile], material=material, seg=4, shade_smooth=False) ob.data.transform(Matrix.Rotation(math.pi / 4, 4, 'Z')) return obdef text_mesh(name, body, size, depth, material): t = text3d(name + '_txt', body, size=size, depth=depth, material=material) t.data.align_y = 'CENTER' dg = bpy.context.evaluated_depsgraph_get() me = bpy.data.meshes.new_from_object(t.evaluated_get(dg)) bpy.data.objects.remove(t, do_unlink=True) ob = bpy.data.objects.new(name, me) link(ob) assign(ob, material) return ob# ── 기단과 탑신 몸체 ──────────────────────────────────────box('Plinth', (13.4, 13.4, 2.5), material=PLINTH, base=True)box('Plinth_Cap', (13.6, 13.6, 0.35), loc=(0, 0, 2.5), material=STONE, base=True)box('Shaft_Core', (2 * H, 2 * H, 48.0), loc=(0, 0, 2.5), material=RECESS, base=True)for sx in (-1, 1): for sy in (-1, 1): b = box('Corner_Buttress', (1.5, 1.5, 47.6), loc=(sx * (HB - 0.75), sy * (HB - 0.75), 2.85), material=STONE, base=True)# ── 탑신 한 면: 수직 패널 5열 × 층별 뾰족아치, 가운데 3열에 창 ─────────parts = []X0, X1 = -4.9, 4.9NCOL = 5colw = (X1 - X0) / NCOLRIB = 0.32YF = -H - 0.3 # 리브 바깥면DEP = 0.36 # 리브 깊이(코어 속으로 0.06 박힘)YC = -H - 0.3 + DEP / 2 - 0.0TIER_Z = [2.85 + i * 5.9 for i in range(9)] # 8층 패널 + 꼭대기for i in range(NCOL + 1): x = X0 + i * colw w = RIB if 0 < i < NCOL else 0.5 parts.append(box('Shaft_Rib', (w, DEP, 47.15), loc=(x, YC, 2.85), material=STONE, base=True))for zi, z in enumerate(TIER_Z): parts.append(box('Shaft_StringCourse', (10.5, DEP + 0.1, 0.34), loc=(0, YC - 0.05, z), material=STONE, base=True)) if zi < len(TIER_Z) - 1: parts.append(box('Shaft_Transom', (10.0, DEP - 0.08, 0.2), loc=(0, YC + 0.04, z + 2.6), material=STONE, base=True))for zi in range(len(TIER_Z) - 1): z0, z1 = TIER_Z[zi] + 0.34, TIER_Z[zi + 1] for c in range(NCOL): cx = X0 + (c + 0.5) * colw pw = colw - RIB # 아치 머리(돌 테두리) parts.append(arch_spandrel('Panel_Arch', pw, 1.15, 1.3, cx, z1 - 1.3, YC, DEP, STONE)) parts.append(arch_spandrel('Panel_Arch_Low', pw, 0.8, 0.9, cx, z0 + 2.46 - 0.9, YC + 0.04, DEP - 0.08, STONE)) # 가운데 3열: 좁은 쌍창 if 1 <= c <= 3 and zi >= 1: for dx in (-0.3, 0.3): parts.append(lancet('Shaft_Window', 0.42, 1.75, 0.35, cx + dx, z1 - 3.15, -H - 0.04, 0.12, WIN)) parts.append(box('Window_Mullion', (0.12, 0.2, 2.2), loc=(cx, -H - 0.08, z1 - 3.2), material=STONE, base=True))face_group(parts, 'Shaft_Face')# ── 시계층(50~62m) ───────────────────────────────────────ZC0, ZC1 = 50.0, 62.0DZ = 56.2 # 시계판 중심 높이R = 3.5 # 시계판 반지름(지름 7m)HC = 6.75 # 시계층 반폭(탑신보다 내민다)box('Clock_Stage', (2 * HC - 0.2, 2 * HC - 0.2, ZC1 - ZC0), loc=(0, 0, ZC0), material=STONE, base=True)box('Clock_Stage_Corbel', (2 * HC + 0.2, 2 * HC + 0.2, 0.7), loc=(0, 0, ZC0 - 0.1), material=STONE, base=True)sq_lathe('Clock_Stage_Corbel_Slope', [(0, ZC0 - 1.6), (HB + 0.05, ZC0 - 1.6), (HC + 0.1, ZC0 - 0.1), (0, ZC0 - 0.1)], STONE)parts = []YS = -HC + 0.1 # 시계층 벽면S = 4.3 # 금박 사각 테두리 반폭# 사각 안의 원: 네 모서리 스팬드럴(금박)for qx in (-1, 1): for qz in (-1, 1): pts = [(R + 0.05, 0), (S, 0), (S, S), (0, S), (0, R + 0.05)] for i in range(1, 12): a = math.pi / 2 * (1 - i / 12) pts.append(((R + 0.05) * math.cos(a), (R + 0.05) * math.sin(a))) pts = [(qx * x, qz * z) for x, z in pts] if qx * qz < 0: pts = list(reversed(pts)) parts.append(extrude_profile('Dial_Spandrel', pts, 0.2, loc=(0, YS - 0.08, DZ), material=GOLD)) # 스팬드럴 장미창 장식 rx, rz = qx * 3.42, qz * 3.42 parts.append(cylinder('Spandrel_Rosette', r=0.42, h=0.08, loc=(rx, YS - 0.27, DZ + rz), rot=(math.pi / 2, 0, 0), material=IRON, seg=24)) parts.append(torus('Spandrel_Rosette_Ring', R=0.42, r=0.06, loc=(rx, YS - 0.33, DZ + rz), rot=(math.pi / 2, 0, 0), material=GOLD, seg=24, rseg=6)) parts.append(sphere('Spandrel_Boss', r=0.12, loc=(rx, YS - 0.35, DZ + rz), material=GOLD, seg=10, rings=6))# 돌 사각 테두리for sz in (-1, 1): parts.append(box('Dial_Frame_H', (2 * S + 1.0, 0.4, 0.5), loc=(0, YS - 0.1, DZ + sz * (S + 0.25)), material=STONE))for sx in (-1, 1): parts.append(box('Dial_Frame_V', (0.5, 0.4, 2 * S + 1.0), loc=(sx * (S + 0.25), YS - 0.1, DZ), material=STONE))# 테두리 위 작은 박공과 아래 금박 명문 띠parts.append(box('Inscription_Band', (2 * S, 0.12, 0.55), loc=(0, YS - 0.06, DZ - S - 1.05), material=GOLD))parts.append(box('Inscription_Frame', (2 * S + 1.0, 0.25, 0.25), loc=(0, YS - 0.05, DZ - S - 1.55), material=STONE))# 시계판 유리YD = YS - 0.05parts.append(cylinder('Dial_Glass', r=R, h=0.25, loc=(0, YD + 0.2, DZ), rot=(math.pi / 2, 0, 0), material=DIAL, seg=96))YD -= 0.05 # 유리 앞면# 철골: 고리for rr, tube in ((R, 0.11), (3.15, 0.05), (2.5, 0.06), (1.55, 0.05), (0.6, 0.05)): parts.append(torus('Dial_Ring', R=rr, r=tube, loc=(0, YD, DZ), rot=(math.pi / 2, 0, 0), material=IRON, seg=96, rseg=6))# 분 눈금for m in range(60): a = 2 * math.pi * m / 60 L = 0.3 if m % 5 == 0 else 0.18 rc = 3.15 + 0.05 + L / 2 parts.append(box('Dial_Minute', (0.05 if m % 5 else 0.09, 0.06, L), loc=(rc * math.sin(a), YD, DZ + rc * math.cos(a)), rot=(0, a, 0), material=IRON))# 방사형 살(안쪽 장식 트레이서리)for k in range(24): a = 2 * math.pi * k / 24 r0, r1 = (0.6, 2.5) if k % 2 == 0 else (1.55, 2.5) rc, L = (r0 + r1) / 2, r1 - r0 parts.append(box('Dial_Spoke', (0.06, 0.06, L), loc=(rc * math.sin(a), YD, DZ + rc * math.cos(a)), rot=(0, a, 0), material=IRON))# 로마 숫자(바깥을 향해 방사형으로)ROMAN = ['XII', 'I', 'II', 'III', 'IIII', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI']for h, s in enumerate(ROMAN): a = 2 * math.pi * h / 12 rc = 2.83 t = text_mesh('Dial_Numeral_' + s, s, 0.6, 0.025, IRON) t.location = (rc * math.sin(a), YD - 0.02, DZ + rc * math.cos(a)) t.rotation_euler = (math.pi / 2, a, 0) parts.append(t)# 바늘(10시 10분): 평판 창 모양을 돌출def hand(name, length, tail, w, angle, y): pts = [(0, -tail), (w * 0.9, -tail + 0.15), (w * 0.5, 0), (w, length * 0.7), (w * 0.35, length * 0.85), (0, length), (-w * 0.35, length * 0.85), (-w, length * 0.7), (-w * 0.5, 0), (-w * 0.9, -tail + 0.15)] pts = list(reversed(pts)) return extrude_profile(name, pts, 0.07, loc=(0, y, DZ), rot=(0, angle, 0), material=IRON)parts.append(hand('Hour_Hand', 2.2, 0.45, 0.17, 2 * math.pi * (10 + 10 / 60) / 12, YD - 0.12))parts.append(hand('Minute_Hand', 3.1, 0.8, 0.12, 2 * math.pi * 10 / 60, YD - 0.21))parts.append(cylinder('Dial_Hub', r=0.22, h=0.32, loc=(0, YD + 0.02, DZ), rot=(math.pi / 2, 0, 0), material=GOLD, seg=24))# 시계층 위·아래 장식 아치 띠for c in range(7): cx = -4.8 + c * 1.6 parts.append(arch_spandrel('Clock_Upper_Arcade', 1.3, 0.6, 0.85, cx, ZC1 - 1.25, YS - 0.1, 0.3, STONE))face_group(parts, 'Clock_Face')# 시계층 모서리 첨탑pin = cylinder('Clock_Corner_Pinnacle', r=0.75, h=ZC1 + 2.6 - ZC0, loc=(HC - 0.5, HC - 0.5, ZC0), material=STONE, seg=8)pin_cap = cone('Clock_Corner_Pinnacle_Spire', r=0.82, h=3.4, loc=(HC - 0.5, HC - 0.5, ZC1 + 2.6), material=ROOF, seg=8)pin_tip = sphere('Clock_Corner_Pinnacle_Orb', r=0.22, loc=(HC - 0.5, HC - 0.5, ZC1 + 6.05), material=GOLD, seg=12, rings=8)for ob in (pin, pin_cap, pin_tip): for k in (1, 2, 3): a = k * math.pi / 2 x, y = ob.location.x, ob.location.y duplicate(ob, loc=(x * math.cos(a) - y * math.sin(a), x * math.sin(a) + y * math.cos(a), ob.location.z))# ── 코니스와 난간 ───────────────────────────────────────box('Clock_Cornice', (2 * HC + 0.5, 2 * HC + 0.5, 0.6), loc=(0, 0, ZC1), material=STONE, base=True)parts = []for i in range(17): x = -5.6 + i * 0.7 parts.append(box('Parapet_Post', (0.16, 0.2, 1.0), loc=(x, -HC - 0.05, ZC1 + 0.6), material=GOLD, base=True))parts.append(box('Parapet_Rail', (11.6, 0.26, 0.18), loc=(0, -HC - 0.05, ZC1 + 1.6), material=GOLD, base=True))face_group(parts, 'Parapet')# ── 종루(62.6~73m) ──────────────────────────────────────ZB0, ZB1 = ZC1 + 0.6, 73.0HBF = 5.5box('Belfry_Core', (2 * HBF, 2 * HBF, ZB1 - ZB0), loc=(0, 0, ZB0), material=DARK, base=True)parts = []YB = -HBF - 0.2NB = 5span = 2 * (HBF - 0.9)pier = 0.42ow = (span - (NB - 1) * pier) / NBOZ0, OZ1 = ZB0 + 1.6, 70.6parts.append(box('Belfry_Sill', (2 * HBF + 0.3, 0.5, OZ0 - ZB0), loc=(0, YB, ZB0), material=STONE, base=True))for sx in (-1, 1): parts.append(box('Belfry_Corner_Pier', (0.95, 0.5, ZB1 - ZB0), loc=(sx * (HBF - 0.475 + 0.1), YB, ZB0), material=STONE, base=True))for i in range(NB): cx = -span / 2 + ow / 2 + i * (ow + pier) if i < NB - 1: parts.append(box('Belfry_Pier', (pier, 0.5, OZ1 - OZ0), loc=(cx + ow / 2 + pier / 2, YB, OZ0), material=STONE, base=True)) parts.append(arch_spandrel('Belfry_Arch', ow, 1.1, 1.4, cx, OZ1 - 1.4, YB, 0.5, STONE)) # 루버 for j in range(7): parts.append(box('Belfry_Louvre', (ow - 0.02, 0.06, 0.12), loc=(cx, -HBF - 0.02, OZ0 + 0.5 + j * 0.62), rot=(0.6, 0, 0), material=ROOF))parts.append(box('Belfry_Frieze', (2 * HBF + 0.3, 0.5, ZB1 - OZ1), loc=(0, YB, OZ1), material=STONE, base=True))for i in range(12): parts.append(box('Belfry_Frieze_Shield', (0.36, 0.08, 0.5), loc=(-4.4 + i * 0.8, YB - 0.28, OZ1 + 0.95), material=GOLD))face_group(parts, 'Belfry_Face')box('Belfry_Cornice', (2 * HBF + 1.0, 2 * HBF + 1.0, 0.5), loc=(0, 0, ZB1), material=STONE, base=True)box('Belfry_Crest', (2 * HBF + 0.7, 2 * HBF + 0.7, 0.35), loc=(0, 0, ZB1 + 0.5), material=GOLD, base=True)# 종루 모서리 소첨탑bp = cylinder('Belfry_Pinnacle', r=0.42, h=1.6, loc=(HBF + 0.1, HBF + 0.1, ZB1 + 0.85), material=STONE, seg=8)bc = cone('Belfry_Pinnacle_Spire', r=0.48, h=2.4, loc=(HBF + 0.1, HBF + 0.1, ZB1 + 2.45), material=GOLD, seg=8)for ob in (bp, bc): for k in (1, 2, 3): a = k * math.pi / 2 x, y = ob.location.x, ob.location.y duplicate(ob, loc=(x * math.cos(a) - y * math.sin(a), x * math.sin(a) + y * math.cos(a), ob.location.z))# ── 주철 지붕(사각뿔) ───────────────────────────────────ZR0, ZR1 = ZB1 + 0.85, 87.6RW0, RW1 = 5.35, 1.35def roof_half(z): t = (z - ZR0) / (ZR1 - ZR0) return RW0 + (RW1 - RW0) * tsq_lathe('Roof_Pyramid', [(0.0, ZR0), (RW0, ZR0), (RW1, ZR1), (0.0, ZR1)], ROOF)parts = []# 도머창(아래 3개, 위 1개)for zc, xs, sc in ((ZR0 + 2.2, (-2.6, 0, 2.6), 1.0), (ZR0 + 6.4, (-1.2, 1.2), 0.75), (ZR0 + 10.0, (0,), 0.6)): hz = roof_half(zc) for x in xs: dw, dh = 1.1 * sc, 1.6 * sc y = -hz - 0.25 parts.append(box('Dormer_Body', (dw, 1.6, dh), loc=(x, y + 0.8, zc - dh / 2), material=ROOF, base=True)) parts.append(lancet('Dormer_Window', dw * 0.55, dh * 0.55, 0.25 * sc, x, zc - dh / 2 + 0.2, y - 0.02, 0.05, LAMP)) parts.append(extrude_profile('Dormer_Gable', [(-dw / 2 - 0.12, 0), (dw / 2 + 0.12, 0), (0, 0.9 * sc)], 1.7, loc=(x, y + 0.82, zc + dh / 2), material=GOLD)) parts.append(cone('Dormer_Finial', r=0.06, h=0.5 * sc, loc=(x, y - 0.02, zc + dh / 2 + 0.85 * sc), material=GOLD, seg=6))face_group(parts, 'Roof_Face')# 용마루(모서리) 금박 크로켓parts = []NCR = 11for i in range(NCR): t = (i + 0.5) / NCR z = ZR0 + (ZR1 - ZR0) * t hw = roof_half(z) + 0.02 parts.append(cone('Hip_Crocket', r=0.17, h=0.45, loc=(hw, -hw, z), material=GOLD, seg=6))hip = curve_tube('Hip_Rib', [(RW0, -RW0, ZR0), (RW1, -RW1, ZR1)], radius=0.09, material=GOLD, resolution=1, bevel_res=1)face_group(parts, 'Roof_Hip_Crockets')for k in (1, 2, 3): duplicate(hip, loc=(0, 0, 0), rot=(0, 0, k * math.pi / 2), name='Hip_Rib')# ── 에어턴 라이트 랜턴(86~89.6m) ─────────────────────────ZL0, ZL1 = ZR1, 90.4HL = 1.35box('Lantern_Base', (2 * HL + 0.5, 2 * HL + 0.5, 0.4), loc=(0, 0, ZL0), material=GOLD, base=True)box('Lantern_Light', (2 * HL - 0.3, 2 * HL - 0.3, ZL1 - ZL0 - 0.4), loc=(0, 0, ZL0 + 0.4), material=LAMP, base=True)parts = []for sx in (-1, 0, 1): w = 0.42 if sx else 0.2 parts.append(box('Lantern_Post', (w, 0.3, ZL1 - ZL0 - 0.4), loc=(sx * (HL - w / 2) if sx else 0, -HL + 0.1, ZL0 + 0.4), material=ROOF, base=True))for sx in (-1, 1): parts.append(arch_spandrel('Lantern_Arch', HL - 0.31, 0.6, 0.8, sx * (HL / 2 - 0.05), ZL1 - 0.8, -HL + 0.1, 0.3, ROOF))face_group(parts, 'Lantern_Face')box('Lantern_Cornice', (2 * HL + 0.5, 2 * HL + 0.5, 0.35), loc=(0, 0, ZL1), material=GOLD, base=True)# ── 첨탑과 피니얼 ───────────────────────────────────────ZS0, ZS1 = ZL1 + 0.35, 95.2sq_lathe('Spire', [(0.0, ZS0), (1.25, ZS0), (0.6, ZS0 + 1.2), (0.06, ZS1), (0.0, ZS1)], ROOF)for zt, hw in ((ZS0 + 1.2, 0.63), (ZS0 + 2.5, 0.42)): box('Spire_Gold_Band', (2 * hw, 2 * hw, 0.18), loc=(0, 0, zt), material=GOLD, base=True)cylinder('Finial_Rod', r=0.06, h=1.6, loc=(0, 0, ZS1 - 0.3), material=GOLD, seg=8)sphere('Finial_Orb', r=0.24, loc=(0, 0, ZS1 + 0.25), material=GOLD, seg=16, rings=10)box('Finial_Cross_Bar', (0.7, 0.08, 0.08), loc=(0, 0, ZS1 + 0.95), material=GOLD)box('Finial_Cross_Bar', (0.08, 0.7, 0.08), loc=(0, 0, ZS1 + 0.95), material=GOLD)






