"""Add the coping + bearing-seat rebar (G4: C1~C20, S1~S2, centreline polylines) to the app pier '새재1교P1'. params = 판독/g4_bars.json (extract_g4.py; Okseong rules H1-H6 applied again, 2026-10-15); builder rebar_polylines.py (GATE G4) expected = schedule L / N, drawn levels / positions / dimension chains, typed in by hand from the reading (판독서 v0.1.03 §10). Backs up params.json / expected.json to data/새재1교P1/backup/2026-10-15_g4/ first. Refuses if G4 is in scope. """ import json import math import shutil import sys from pathlib import Path HERE = Path(__file__).resolve().parent D = HERE.parents[1] / "Code" / "교각모델링앱" / "data" / "새재1교P1" B = json.loads((HERE / "판독" / "g4_bars.json").read_text(encoding="utf-8")) P = json.loads((D / "params.json").read_text(encoding="utf-8")) X = json.loads((D / "expected.json").read_text(encoding="utf-8")) if "G4" in P["scope"]: sys.exit("G4 already in scope") bk = D / "backup" / "2026-10-15_g4" bk.mkdir(parents=True, exist_ok=True) for f in ("params.json", "expected.json"): shutil.copy2(D / f, bk / f) TABLE = { # mark: (dia, L mm, N) -- 구조도(3)(4) 재료표 "C1": ("H29", 15233, 12), "C4": ("H29", 15233, 11), "C2": ("H29", 13260, 12), "C3": ("H29", 13260, 12), "C5": ("H29", 13260, 11), "C6": ("H29", 13260, 11), "C7": ("H29", 14292, 12), "C8": ("H25", 8388, 74), "C9": ("H25", 11016, 74), "C10": ("H25", 10261, 38), "C11": ("H25", 10196, 38), "C12": ("H25", 8915, 76), "C13": ("H25", 9056, 76), "C14": ("H22", 21269, 7), "C15": ("H22", 7434, 42), "C16": ("H22", 31302, 4), "C17": ("H22", 13001, 24), "C18": ("H19", 3490, 92), "C19": ("H19", 2692, 23), "C20": ("H19", 3122, 69), "S1": ("H13", 3697, 55), "S2": ("H13", 2600, 100)} SHAPE = {"C1": "top-legs", "C2": "top-legs", "C3": "top-legs", "C4": "top-legs", "C5": "top-legs", "C6": "top-legs", "C7": "soffit", "C8": "stirrup", "C9": "stirrup-pent", "C10": "stirrup", "C11": "stirrup-pent", "C12": "stirrup", "C13": "stirrup-pent", "C14": "loop", "C15": "tie", "C16": "loop", "C17": "tie", "C18": "U", "C19": "U", "C20": "L", "S1": "U", "S2": "U"} P["scope"] = ["G1", "G2", "G3", "G4", "G5"] P["builders"]["G4"] = "rebar_polylines.py" P["rebar_marks"].update({m: {"dia": d, "shape": SHAPE[m]} for m, (d, _, _) in TABLE.items()}) P["coping_rebar"] = {"form": "polylines", "host": "CP", "group": "코핑", "bars": B["bars"], "not_modelled": "135도 갈고리 C15·C17, 겹이음 j(C1~C7·C14·C16·C17), 스터럽 이음 c 630", "src": "Code/새재1교P1판독/extract_g4.py -> 판독/g4_bars.json; 판독서 v0.1.03 §10, 옥성교 H1~H6 규칙 재적용 (2026-10-15)"} X["checkers"]["G4"] = "g4_sj.py" X["negative"]["G4"] = [{"mark": "C1", "d": [0, 5, 0]}, {"mark": "C7", "d": [0, 0, 5]}] def y_out(z): return min(1375.0, 971.6 + 0.235294 * (z - 29532.0)) Y23 = [-1375.0 + 125 * k for k in range(23)] X["G4"] = { "schedule": {m: [L, n] for m, (_, L, n) in TABLE.items()}, "dia": {m: int(d[1:]) for m, (d, _, _) in TABLE.items()}, # polyline length = drawn a + legs (L minus lap j for C1~C6); other marks vary with x / level and are only recorded "fixed_length": {"C1": 13924, "C4": 13924, "C2": 11950, "C3": 11950, "C5": 11950, "C6": 11950, "C19": 2691.8, "C20": 3122, "S1": 3697, "S2": 2600}, "y23": Y23, "top": {"C1": {"z": 32407.0, "leg": 1087, "parity": 0}, "C4": {"z": 32407.0, "leg": 1087, "parity": 1}, "C2": {"z": 32332.0, "leg": 100, "parity": 0}, "C5": {"z": 32332.0, "leg": 100, "parity": 1}, "C3": {"z": 32232.0, "leg": 100, "parity": 0}, "C6": {"z": 32232.0, "leg": 100, "parity": 1}, "x_end": 5875}, "c19": {"z": 32811.1, "x": [3923.2, 5875.0], "leg": 370}, "c20": [{"z": 32508.0, "x": [-3597.6, -845.6]}, {"z": 32609.0, "x": [-1090.6, 1661.3]}, {"z": 32710.1, "x": [1416.3, 4168.2]}], "c20_leg": 370, "c7": {"flat_z": [29657.0] * 8 + [30184.0] * 2 + [31246.5] * 2, "x_end": 5875, "top_end_z": 31845.3, "raised_top_z": 32372.3, "cap_z": 32400.0}, "stirrups": {"x": [-5788.0 + 125 * k for k in range(94)], "zone_cut": [-1200.0, 1200.0], "marks": {"left": ["C8", "C9"], "centre": ["C10", "C11"], "right": ["C12", "C13"]}, "off": {"R": [-12.5, 12.5], "P": [-37.5, 37.5]}, "step_b": [-3600.5, -1100.5, 1399.5, 3899.5], "step_z": [32531.5, 32632.5, 32733.5, 32834.5, 32936.0], "top_below": 102.0, "flat_bottom": 29634.5, "cover_n": 102.5, "soffit_slope": 1700.0 / 4800.0, "flat_half": 1200.0, "rect_y": [[-875.0, 625.0], [-625.0, 875.0]], "pent_in": 375.0, "pent_out": 1375.0}, "loops": {"upper": {"marks": ["C16", "C17"], "z": [32182.0, 31932.0, 31682.0, 31432.0], "x": [5875.0] * 4, "y": [1352.5] * 4}, "lower": {"marks": ["C14", "C15"], "z": [31182.0, 30932.0, 30682.0, 30432.0, 30182.0, 29932.0, 29682.0], "x": [5484.4, 4778.6, 4072.7, 3366.8, 2660.9, 1955.0, 1249.1], "y": [1337.3, 1278.5, 1219.6, 1160.8, 1102.0, 1043.2, 984.3]}, "tie_y": [-852.5, -602.5, -352.5, 352.5, 602.5, 852.5]}, "c18": {"levels": {"32457.0": 10, "32432.0": 10, "32309.5": 25, "32209.5": 25, "31682.0": 12, "30682.0": 8, "29682.0": 2}, "width": {"32457.0": 2750, "32432.0": 2750, "32309.5": 2750, "32209.5": 2750, "31682.0": 2 * round(y_out(32052.0), 1), "30682.0": 2 * round(y_out(31052.0), 1), "29682.0": 2 * round(y_out(30052.0), 1)}}, "seats": {"s1_t": [-600.0] + [-500.0 + 125 * k for k in range(9)] + [600.0], "s1_len": 2297, "s2_o": [-1148.5] + [-1062.5 + 125 * k for k in range(18)] + [1148.5], "s2_len": 1200, "top_below": 50, "leg": 700}, "src": "재료표 L·N, 철근 상세 a·b·c; 구조도(1) 정면·측면 철근 선·점(상면 3단·C19·C20·C7·스터럽 94곳·측면 고리 11단·C18 92점); " "구조도(2) 코핑 단면 사슬·교좌면 보강 상세; 옥성교 H1~H6 규칙 재적용 [추론] (2026-10-15)", } (D / "params.json").write_text(json.dumps(P, ensure_ascii=False, indent=1), encoding="utf-8") (D / "expected.json").write_text(json.dumps(X, ensure_ascii=False, indent=1), encoding="utf-8") print("G4 added:", len(B["bars"]), "bars; backup", bk)