
끌어서 회전, 휠·두 손가락으로 확대
이 모형에 대하여
허블 우주망원경은 미국 항공우주국(NASA)과 유럽우주국(ESA)이 함께 운용하는 우주망원경이다. 1990년 4월 우주왕복선 디스커버리호(STS-31)에 실려 지구 저궤도에 올랐다. 대기의 흔들림과 흡수가 없는 궤도에서 지름 2.4m 주경으로 자외선부터 근적외선까지 관측해 왔다.
발사 직후 주경의 구면수차가 발견되었고, 1993년 첫 정비 임무에서 보정 광학계를 설치해 바로잡았다. 이후 2009년까지 모두 다섯 차례 우주비행사들이 우주왕복선으로 찾아가 관측 장비와 자이로스코프, 태양전지판, 배터리를 교체했다. 우주 팽창 속도 측정과 '허블 딥 필드' 같은 관측으로 천문학의 여러 분야에 기여했다.
이 모델은 마지막 정비(2009년) 이후의 모습을 실제 크기로 재현했다. 은박 단열재로 싸인 원통형 몸체, 앞쪽의 열린 개구부 덮개, 몸통 가운데 장비 구획에서 양옆으로 펼친 강체형 태양전지판(SA3), 위아래 붐 끝의 고이득 안테나 두 기, 몸통 곳곳의 노란 손잡이를 표현했다. 우주에 떠 있는 물체이므로 전시용 받침대 위에 올려 두었다.
만든 방법
몸통은 망원경 축을 따라 단면을 돌린 회전체(lathe)로 후방 덮개, 10각형 장비 구획, 전방 차광통을 차례로 쌓았다. 은박 단열재의 구김은 고정 시드 난수로 원통 반지름을 수 밀리미터씩 흔들어 반사광이 고르지 않게 나오도록 했다. 태양전지판은 셀 격자를 bmesh 루프로 한 장 만들고 링크 복제로 네 장을 붙였으며, 개구부 덮개와 전지판의 기울기는 변환 행렬로 배치했다. 고이득 안테나는 포물선 단면을 회전한 뒤 두께를 주었고, 손잡이는 커브 튜브로 만들었다. 미세 유도 센서·관측 장비의 실제 문 배치, 단열재 덧댐의 정확한 위치, 내부 광학계는 단순화했다.
build.py
이 파일 하나를 Blender 에서 실행하면 위의 모형이 만들어집니다. 313줄.
# 허블 우주망원경 (Hubble Space Telescope) — 2009년 마지막 정비(SM4) 이후의 궤도 위 모습.# 망원경 축을 X 축(+X 가 개구부)으로 눕혀 실제 크기(길이 약 13.2m, 후방 지름 4.2m)로 만들었다.# 몸통은 회전체(lathe)로 후방 덮개·장비 구획(10각 베이)·전방 차광통을 쌓고, 차광통 안쪽은 어두운 내벽과# 주경·부경 스파이더까지 넣었다. 태양전지판(SA3)은 셀 격자를 bmesh 루프로 한 장 만든 뒤# 링크 복제로 네 장을 붙였고, 열린 개구부 덮개·고이득 안테나(포물면 회전체)·노란 손잡이(커브 튜브)를 더했다.# 은박 단열재(MLI)와 흰 NOBL 덮개는 Principled 상수 재질로 구분했다. 전시용 받침대 위에 올려 둔다.from atelier import *import randomrandom.seed(1990)SHOT = {"azimuth": -38, "elevation": 22, "lens": 50, "light": "studio", "background": "#1c2433"}H = 5.6 # 망원경 축 높이(받침대 위)R_AFT = 2.10 # 후방 덮개 반지름R_ES = 2.24 # 장비 구획(10각) 외접 반지름R_LS = 1.53 # 전방 셸·차광통 반지름X_ES0, X_ES1 = 3.50, 5.00X_FRONT = 13.05M_MLI = mat('MLI_Silver_Foil', '#c8ccd2', rough=0.28, metal=1.0)M_AFT = mat('Aft_Shroud_Aluminized', '#aeb3ba', rough=0.38, metal=0.9)M_NOBL = mat('NOBL_White_Blanket', '#dedcd4', rough=0.62)M_DARK = mat('Baffle_Black', '#16171a', rough=0.85)M_MECH = mat('Mechanism_Gray', '#4a4e55', rough=0.45, metal=0.6)M_CELL = mat('Solar_Cell_Blue', '#1a2f66', rough=0.2, metal=0.3)M_FRAME = mat('Solar_Frame_Gold', '#b88d43', rough=0.35, metal=0.85)M_RAIL = mat('Handrail_Yellow', '#d8a823', rough=0.5)M_DISH = mat('HGA_Dish_White', '#d6d3ca', rough=0.55)M_DOOR = mat('Aperture_Door_Coating', '#c3c6cb', rough=0.45, metal=0.35)M_MIRROR = mat('Primary_Mirror', '#8fa3b8', rough=0.08, metal=1.0)M_STAND = mat('Display_Stand_Graphite', '#2b2e34', rough=0.4, metal=0.5)AX = (0, math.pi / 2, 0) # lathe 의 Z 축 → 월드 +Xdef P(x, r, th): """망원경 축 좌표(x, 반지름, 각도θ) → 월드 좌표. θ=0 은 +Y, 90° 는 위(+Z).""" return Vector((x, r * math.cos(th), H + r * math.sin(th)))def axial(name, profile, x0, material, seg=64, sm=True): return lathe(name, profile, loc=(x0, 0, H), rot=AX, material=material, seg=seg, shade_smooth=sm)def shell_patch(name, r, t, a0, a1, x0, x1, material, n=10): """원통 표면에 붙는 곡면 패널(두께 t).""" bm = bmesh.new()나머지 265줄 펼치기접기
vs = [] for rr in (r, r + t): ring = [] for i in range(n + 1): a = a0 + (a1 - a0) * i / n ring.append((bm.verts.new(P(x0, rr, a)), bm.verts.new(P(x1, rr, a)))) vs.append(ring) inn, out = vs for i in range(n): bm.faces.new((out[i][0], out[i + 1][0], out[i + 1][1], out[i][1])) bm.faces.new((inn[i][1], inn[i + 1][1], inn[i + 1][0], inn[i][0])) bm.faces.new((inn[i][0], inn[i + 1][0], out[i + 1][0], out[i][0])) bm.faces.new((out[i][1], out[i + 1][1], inn[i + 1][1], inn[i][1])) bm.faces.new((inn[0][0], out[0][0], out[0][1], inn[0][1])) bm.faces.new((inn[n][1], out[n][1], out[n][0], inn[n][0])) bmesh.ops.recalc_face_normals(bm, faces=bm.faces) me = bpy.data.meshes.new(name) bm.to_mesh(me) bm.free() ob = bpy.data.objects.new(name, me) link(ob) smooth(ob) return assign(ob, material)def rail(name, x0, x1, r, th, h=0.13, rad=0.022): """축 방향 손잡이: 양 끝 받침이 있는 ㄷ자 관.""" pts = [P(x0, r - 0.01, th), P(x0, r + h, th), P(x1, r + h, th), P(x1, r - 0.01, th)] return curve_tube(name, [tuple(p) for p in pts], radius=rad, material=M_RAIL, resolution=2, bevel_res=2)def ring_band(name, x, r, w, t, material, seg=64): return axial(name, [(r - 0.01, -w / 2), (r + t, -w / 2), (r + t, w / 2), (r - 0.01, w / 2)], x, material, seg)def crinkled_tube(name, r, x0, x1, material, rows, seg=96, amp=0.008, lip=None): """은박 단열재의 구김: 반지름을 고정 시드 난수로 조금씩 흔든 원통.""" prof = [] for i in range(rows + 1): x = x0 + (x1 - x0) * i / rows prof.append((r, x)) if lip: prof.append((r - lip, x1)) ob = axial(name, prof, 0.0, material, seg=seg) for v in ob.data.vertices: rr = math.hypot(v.co.x, v.co.y) if rr > r - 0.001 and x0 + 0.05 < v.co.z < x1 - 0.05: k = 1 + random.uniform(-amp, amp) / r v.co.x *= k v.co.y *= k return ob# ---------------------------------------------------------------- 1. 몸통# 후방 덮개(Aft Shroud) + 후방 격벽axial('Aft_Shroud_Bulkhead_Edge', [(0.0, 0.0), (1.70, 0.0), (1.95, 0.05), (R_AFT, 0.20), (R_AFT, 0.30)], 0.0, M_AFT, seg=96)crinkled_tube('Aft_Shroud', R_AFT, 0.30, X_ES0, M_AFT, rows=30, amp=0.005)axial('Aft_Bulkhead_Plate', [(0.0, -0.03), (1.60, -0.03), (1.60, 0.01), (0.0, 0.01)], 0.0, M_MECH, sm=False)for k in range(8): th = math.radians(22.5 + 45 * k) rib = box(f'Aft_Bulkhead_Rib_{k}', (0.06, 1.15, 0.10), loc=P(-0.06, 0.95, th), material=M_AFT) rib.rotation_euler = (th, 0, 0)axial('Aft_Bulkhead_Center_Port', [(0.0, -0.10), (0.38, -0.10), (0.42, -0.03), (0.42, 0.0)], 0.0, M_AFT, seg=32)ring_band('Aft_Shroud_Flange', 0.22, R_AFT, 0.08, 0.035, M_MECH)ring_band('Aft_Shroud_Ring_Mid', 1.80, R_AFT, 0.05, 0.02, M_MECH)ring_band('Aft_Shroud_Forward_Ring', X_ES0 - 0.04, R_AFT, 0.08, 0.06, M_MECH)# 장비 구획(SSM Equipment Section): 10개 베이의 다각형 링axial('Equipment_Section', [(R_AFT - 0.05, 0.0), (R_ES, 0.0), (R_ES, X_ES1 - X_ES0), (R_LS - 0.02, X_ES1 - X_ES0)], X_ES0, M_MLI, seg=10, sm=False)# 전방 셸 + 차광통(Light Shield): 바깥 은박 + 앞 테두리crinkled_tube('Forward_Shell_Light_Shield', R_LS, X_ES1 - 0.01, X_FRONT, M_MLI, rows=80, lip=0.07)axial('Light_Shield_Inner_Baffle', [(R_LS - 0.07, X_FRONT), (R_LS - 0.07, 5.6), (0.0, 5.6)], 0.0, M_DARK)ring_band('Forward_Shell_Joint_Ring', 9.0, R_LS, 0.10, 0.03, M_MECH)for i, x in enumerate((6.0, 7.0, 8.0, 10.0, 11.0, 12.0)): ring_band(f'Light_Shield_Seam_{i}', x, R_LS, 0.035, 0.012, M_AFT)ring_band('Light_Shield_Front_Lip', X_FRONT - 0.06, R_LS, 0.12, 0.04, M_MECH)# 차광통 안: 주경(가운데 구멍), 내부 차광 링, 부경과 4갈래 스파이더axial('Primary_Mirror', [(0.32, 5.62), (1.22, 5.62), (1.22, 5.70), (0.32, 5.70)], 0.0, M_MIRROR, sm=False)for i, x in enumerate((7.4, 9.2, 11.0)): axial(f'Internal_Baffle_Ring_{i}', [(R_LS - 0.07, x), (R_LS - 0.22, x + 0.02), (R_LS - 0.22, x + 0.05), (R_LS - 0.07, x + 0.05)], 0.0, M_DARK, sm=False)axial('Secondary_Mirror_Housing', [(0.0, 10.15), (0.20, 10.15), (0.20, 10.55), (0.05, 10.62), (0.0, 10.62)], 0.0, M_MECH)for k in range(4): th = math.radians(45 + 90 * k) a, b = P(10.38, 0.18, th), P(10.38, R_LS - 0.08, th) mid, d = (a + b) / 2, (b - a) vane = box(f'Spider_Vane_{k}', (0.30, d.length, 0.018), loc=mid, material=M_DARK) vane.rotation_euler = (th, 0, 0)# ---------------------------------------------------------------- 2. 장비 베이 문(10개)bay_w = 2 * R_ES * math.sin(math.radians(18)) * 0.86apo = R_ES * math.cos(math.radians(18))bay_mats = [None, M_NOBL, M_NOBL, M_MLI, M_NOBL, None, M_NOBL, M_MLI, M_NOBL, M_NOBL]for k in range(10): th = math.radians(36 * k) c = P((X_ES0 + X_ES1) / 2, apo + 0.025, th) if bay_mats[k] is None: # 태양전지판 뿌리 부분: 구동 장치 상자 d = box(f'SA_Drive_Housing_{k}', (1.25, 0.55, 0.10), loc=c, material=M_MECH) else: d = box(f'Equipment_Bay_Door_{k}', (1.30, bay_w, 0.05), loc=c, material=bay_mats[k]) rail(f'Bay_Handrail_{k}', X_ES0 + 0.25, X_ES1 - 0.25, apo + 0.05, th + math.radians(10.5), h=0.10) d.rotation_euler = (th - math.pi / 2, 0, 0)# ---------------------------------------------------------------- 3. 후방 덮개 문·손잡이for k in range(4): th0 = math.radians(45 + 90 * k) shell_patch(f'Aft_Shroud_Door_{k}', R_AFT, 0.03, th0 - math.radians(28), th0 + math.radians(28), 0.55, 3.15, M_MLI) for s in (-1, 1): rail(f'Aft_Door_Handrail_{k}_{"L" if s < 0 else "R"}', 0.75, 2.95, R_AFT + 0.03, th0 + s * math.radians(33))for k in range(4): th = math.radians(90 * k) rail(f'Aft_Shroud_Handrail_{k}', 0.40, 3.30, R_AFT, th)# 후방 격벽 저이득 안테나cylinder('Aft_LGA_Mast', 0.05, 0.55, loc=(0.0, 0, H + 1.1), rot=(0, -math.pi / 2, 0), material=M_MECH, seg=12)cone('Aft_Low_Gain_Antenna', 0.16, 0.30, loc=(-0.55, 0, H + 1.1), rot=(0, -math.pi / 2, 0), material=M_DISH, seg=20)# ---------------------------------------------------------------- 4. 전방 셸·차광통 외부 부품# 자기 토커 막대 4개(NOBL 덮개)for k in range(4): th = math.radians(45 + 90 * k) c = P(10.9, R_LS + 0.13, th) bar = cylinder(f'Magnetic_Torquer_{k}', 0.07, 3.2, loc=c, rot=(0, math.pi / 2, 0), material=M_NOBL, seg=16, base=False) for j, x in enumerate((9.5, 12.3)): st = box(f'Magnetic_Torquer_{k}_Standoff_{j}', (0.10, 0.08, 0.16), loc=P(x, R_LS + 0.06, th), material=M_MECH) st.rotation_euler = (th - math.pi / 2, 0, 0)# 차광통 손잡이for k, th in enumerate((0.0, math.pi)): rail(f'Light_Shield_Handrail_{k}', 6.2, 12.6, R_LS, th) rail(f'Forward_Shell_Handrail_{k}', 5.3, 8.6, R_LS, th + math.radians(25))# 태양 센서·고정 별추적기 상자for k, (x, th) in enumerate(((12.4, math.radians(-30)), (12.4, math.radians(210)), (5.6, math.radians(-125)))): s = box(f'Sun_Sensor_{k}', (0.35, 0.28, 0.18), loc=P(x, R_LS + 0.08, th), material=M_MECH) s.rotation_euler = (th - math.pi / 2, 0, 0)# 전방 저이득 안테나cylinder('Forward_LGA_Mast', 0.04, 0.9, loc=P(11.6, R_LS - 0.02, math.radians(-90)), rot=(math.pi, 0, 0), material=M_MECH, seg=10)cone('Forward_Low_Gain_Antenna', 0.14, 0.26, loc=P(11.6, R_LS + 0.86, math.radians(-90)), rot=(math.pi, 0, 0), material=M_DISH, seg=20)# ---------------------------------------------------------------- 5. 개구부 덮개(열린 상태)HINGE = Vector((X_FRONT + 0.05, 0, H + R_LS + 0.10))R_DOOR = 1.62OPEN = math.radians(100)door_m = Matrix.Translation(HINGE) @ Matrix.Rotation(-OPEN, 4, 'Y') @ Matrix.Translation((0, 0, -R_DOOR - 0.0)) @ Matrix.Rotation(math.pi / 2, 4, 'Y')door = cylinder('Aperture_Door', R_DOOR, 0.10, material=M_DOOR, seg=64, base=False)door.matrix_world = door_m @ Matrix.Translation((0, 0, 0.03))door_in = cylinder('Aperture_Door_Inner_Black', 1.50, 0.02, material=M_DARK, seg=64, base=False)door_in.matrix_world = door_m @ Matrix.Translation((0, 0, -0.03))door_rib = lathe('Aperture_Door_Rim', [(R_DOOR - 0.06, 0.07), (R_DOOR + 0.02, 0.07), (R_DOOR + 0.02, 0.11), (R_DOOR - 0.06, 0.11)], material=M_MECH, seg=64, shade_smooth=False)door_rib.matrix_world = door_mfor k in range(3): st = box(f'Aperture_Door_Stiffener_{k}', (0.06, 2 * R_DOOR * 0.92 * math.cos(math.radians(30 * (k - 1))) * 0.9, 0.04), material=M_MECH) st.matrix_world = door_m @ Matrix.Translation((R_DOOR * 0.92 * math.sin(math.radians(30 * (k - 1))) * 0.9, 0, 0.10))cylinder('Aperture_Door_Hinge', 0.08, 1.1, loc=HINGE, rot=(math.pi / 2, 0, 0), material=M_MECH, seg=16, base=False)for s in (-1, 1): box(f'Aperture_Door_Hinge_Bracket_{"L" if s < 0 else "R"}', (0.55, 0.10, 0.16), loc=(HINGE.x - 0.22, s * 0.42, H + R_LS + 0.03), material=M_MECH)# 덮개 개폐 구동기curve_tube('Aperture_Door_Actuator', [tuple(P(12.2, R_LS + 0.02, math.radians(90))), tuple(P(12.2, R_LS + 0.18, math.radians(90))), tuple(HINGE + Vector((-0.05, 0, 0.02)))], radius=0.035, material=M_MECH, resolution=2)# ---------------------------------------------------------------- 6. 태양전지판 (SA3 강체형) 2날개SA_X = (X_ES0 + X_ES1) / 2SA_TILT = math.radians(50)SA_L, SA_W = 7.1, 1.24SA_ROOT = 2.75NCOL, NROW, GAP = 5, 22, 0.014bm = bmesh.new()bmesh.ops.create_cube(bm, size=1.0)bmesh.ops.scale(bm, vec=(SA_W, SA_L, 0.035), verts=bm.verts)bmesh.ops.translate(bm, vec=(SA_W / 2, SA_L / 2, 0), verts=bm.verts)cw = (SA_W - GAP * (NCOL + 1)) / NCOLch = (SA_L - GAP * (NROW + 1)) / NROWframe_me = bpy.data.meshes.new('SA_Panel_Frame')bm.to_mesh(frame_me)bm.free()bm = bmesh.new()for i in range(NCOL): for j in range(NROW): g = bmesh.ops.create_cube(bm, size=1.0) bmesh.ops.scale(bm, vec=(cw, ch, 0.012), verts=g['verts']) bmesh.ops.translate(bm, vec=(GAP + cw / 2 + i * (cw + GAP), GAP + ch / 2 + j * (ch + GAP), 0.0175 + 0.004), verts=g['verts'])cell_me = bpy.data.meshes.new('SA_Panel_Cells')bm.to_mesh(cell_me)bm.free()bm = bmesh.new()bmesh.ops.create_cube(bm, size=1.0)bmesh.ops.scale(bm, vec=(SA_W - 0.04, SA_L - 0.04, 0.008), verts=bm.verts)bmesh.ops.translate(bm, vec=(SA_W / 2, SA_L / 2, -0.0175 - 0.002 - 0.004), verts=bm.verts)back_me = bpy.data.meshes.new('SA_Panel_Back')bm.to_mesh(back_me)bm.free()back_ob = assign(link(bpy.data.objects.new('SA_Panel_Back', back_me)), M_AFT)frame_ob = assign(link(bpy.data.objects.new('SA_Panel_Frame', frame_me)), M_FRAME)cell_ob = assign(link(bpy.data.objects.new('SA_Panel_Cells', cell_me)), M_CELL)first = Truefor side, name in ((1, 'Plus'), (-1, 'Minus')): W = Matrix.Translation((SA_X, 0, H)) @ Matrix.Rotation(SA_TILT, 4, 'Y') if side < 0: W = W @ Matrix.Rotation(math.pi, 4, 'Z') for h, off in (('A', 0.07), ('B', -0.07 - SA_W)): L = Matrix.Translation((off, SA_ROOT, 0)) if first: f, c, b = frame_ob, cell_ob, back_ob f.name, c.name, b.name = f'SA_{name}_Panel_{h}_Frame', f'SA_{name}_Panel_{h}_Cells', f'SA_{name}_Panel_{h}_Back' first = False else: f = duplicate(frame_ob, name=f'SA_{name}_Panel_{h}_Frame') c = duplicate(cell_ob, name=f'SA_{name}_Panel_{h}_Cells') b = duplicate(back_ob, name=f'SA_{name}_Panel_{h}_Back') f.matrix_world = W @ L c.matrix_world = W @ L b.matrix_world = W @ L mast = cylinder(f'SA_{name}_Mast', 0.06, SA_ROOT + SA_L + 0.15 - 2.05, material=M_MECH, seg=12) mast.matrix_world = W @ Matrix.Translation((0, 2.05, 0)) @ Matrix.Rotation(-math.pi / 2, 4, 'X') for j, u in enumerate((SA_ROOT, SA_ROOT + SA_L)): beam = box(f'SA_{name}_Cross_Beam_{j}', (2 * SA_W + 0.18, 0.08, 0.07), material=M_FRAME) beam.matrix_world = W @ Matrix.Translation((0, u, 0)) hub = cylinder(f'SA_{name}_Deploy_Mechanism', 0.16, 0.45, material=M_MECH, seg=16) hub.matrix_world = W @ Matrix.Translation((0, 2.15, 0)) @ Matrix.Rotation(-math.pi / 2, 4, 'X')# ---------------------------------------------------------------- 7. 고이득 안테나(HGA) 2기HGA_X = 7.7BOOM = 2.5f_len, r_dish = 0.48, 0.66prof = [(r_dish * i / 10, (r_dish * i / 10) ** 2 / (4 * f_len)) for i in range(11)]dish_src = lathe('HGA_Dish', prof, material=M_DISH, seg=40)solidify(dish_src, 0.025)apply_all(dish_src)for s, name in ((1, 'Upper'), (-1, 'Lower')): th = s * math.pi / 2 base = P(HGA_X, R_LS - 0.02, th) tip = P(HGA_X, R_LS + BOOM, th) boom = cylinder(f'HGA_{name}_Boom', 0.09, BOOM + 0.02, loc=base, rot=(0 if s > 0 else math.pi, 0, 0), material=M_AFT, seg=14) box(f'HGA_{name}_Boom_Hinge', (0.22, 0.22, 0.22), loc=P(HGA_X, R_LS + 0.10, th), material=M_MECH) box(f'HGA_{name}_Gimbal', (0.26, 0.26, 0.24), loc=tip, material=M_MECH) n = Vector((0.55, -0.80, 0.22 * s)).normalized() q = n.to_track_quat('Z', 'Y') D = Matrix.Translation(tip + n * 0.22) @ q.to_matrix().to_4x4() dish = dish_src if s > 0 else duplicate(dish_src) dish.name = f'HGA_{name}_Dish' dish.matrix_world = D yoke = cylinder(f'HGA_{name}_Yoke', 0.05, 0.24, material=M_MECH, seg=10) yoke.matrix_world = Matrix.Translation(tip) @ q.to_matrix().to_4x4() feed = cylinder(f'HGA_{name}_Feed', 0.06, 0.12, material=M_MECH, seg=12, base=False) feed.matrix_world = D @ Matrix.Translation((0, 0, f_len)) for k in range(3): a = 2 * math.pi * k / 3 rim = D @ Vector((0.6 * math.cos(a), 0.6 * math.sin(a), 0.6 ** 2 / (4 * f_len))) curve_tube(f'HGA_{name}_Feed_Strut_{k}', [tuple(rim), tuple(D @ Vector((0, 0, f_len - 0.05)))], radius=0.012, material=M_MECH, resolution=1, bevel_res=1)# ---------------------------------------------------------------- 8. 전시 받침대STAND_X = 1.75cylinder('Display_Stand_Base', 1.5, 0.14, loc=(STAND_X, 0, 0), material=M_STAND, seg=48)cylinder('Display_Stand_Plinth', 0.45, 0.20, loc=(STAND_X, 0, 0.14), material=M_STAND, seg=32)cylinder('Display_Stand_Post', 0.14, H - R_AFT - 0.34 + 0.05, loc=(STAND_X, 0, 0.34), material=M_STAND, seg=20)shell_patch('Display_Stand_Cradle', R_AFT + 0.0, 0.06, math.radians(-106), math.radians(-74), STAND_X - 0.35, STAND_X + 0.35, M_STAND)






