"""Add the column rebar (G2: P1~P5) to the app pier '옥성교P1' (Ulsan ring builder with the Okseong options). params = 판독/g2_values.json (front / section reading) + decisions Q1-Q4 (2026-10-14); expected = schedule L / N / r (구조도(4)) and the front dimension chains, typed in by hand. Backs up params.json / expected.json to data/옥성교P1/backup/2026-10-14_g2/ first. Refuses if G2 is in scope. """ import json import shutil import sys from pathlib import Path HERE = Path(__file__).resolve().parent D = HERE.parents[1] / "Code" / "교각모델링앱" / "data" / "옥성교P1" V = json.loads((HERE / "판독" / "g2_values.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 "G2" in P["scope"]: sys.exit("G2 already in scope") bk = D / "backup" / "2026-10-14_g2" bk.mkdir(parents=True, exist_ok=True) for f in ("params.json", "expected.json"): shutil.copy2(D / f, bk / f) h = V["hoops_chain"] P["scope"] = ["G1", "G2", "G5"] P["builders"]["G2"] = "column_rebar_ring.py" P["rebar_marks"] = {"P1": {"dia": "H25", "shape": "VI"}, "P2": {"dia": "H25", "shape": "VI"}, "P3": {"dia": "H25", "shape": "coupler_half"}, "P4": {"dia": "H19", "shape": "coupler_half"}, "P5": {"dia": "H16", "shape": "tie-90/135"}} P["rebar_marks_src"] = "구조도(4) 철근 재료표·상세 (기둥 P1~P5)" P["column_rebar"] = { "form": "ring", "main": {"mark": "P1", "count": 60, "start_deg": 0.0, "radius": 1125.0, "hook_leg_z": 12325.0, "bend_r": 270.0, "hook_leg": 500.0, "straight_from": 12595.0, "straight_len": 8313.0, "inner": {"mark": "P2", "radius": 1080.0}, "src": "단면 r 1,125 / 1,080 × 60 (0°, 6°); 상세 a 8,313 r 270 c 500; 다리 EL 12.325 = 사슬 '150' (Q2, 작도 12.375)"}, "hoops": {"radius": 1150.0, "zones": [ {"mark": "P3", "type": "coupler_half", "levels": h[0:3], "a": 3533.0, "gap": 80.0, "radius": 1150.0}, {"mark": "P4", "type": "coupler_half", "levels": h[3:19], "a": 3538.0, "gap": 65.0, "radius": 1147.0}, {"mark": "P3", "type": "coupler_half", "levels": h[19:], "a": 3533.0, "gap": 80.0, "radius": 1150.0}], "src": "사슬 '띠철근외측' = 작도 29선; 상세 r 1,150 / 1,147, a, b(커플러); 커플러 90°/270° (Q4 [추론])"}, "ties": {"mark": "P5", "shape": "90-135", "levels": V["ties_chain"], "straight": 2341.0, "leg": 160.0, "tail": 150.0, "y_lift": 16.0, "design_length": 2722.0, "src": "사슬 '크로스타이' 20단; 상세 a 160, b 2,341, c 141, d 80; Y +16 (Q3), 교번 (Q4 [추론]); 꼬리 작도 150 [추론]"}, } X["checkers"]["G2"] = "g2_ring.py" X["negative"]["G2"] = [{"mark": "P1", "d": [5, 0, 0]}, {"mark": "P3", "d": [0, 0, 5]}] X["G2"] = {"schedule_L": {"P1": 9237, "P2": 9237, "P3": 7226, "P4": 7206, "P5": 2722}, "schedule_n": {"P1": 60, "P2": 60, "P3": 13, "P4": 16, "P5": 40}, "dia": {"P1": 25, "P2": 25, "P3": 25, "P4": 19, "P5": 16}, "main": {"mark": "P1", "radius": 1125, "divisions": 60, "start_deg": 0.0, "bottom_above_footing": 150, "top_parts": [150, 270, 8313], "inner": {"mark": "P2", "radius": 1080}}, "hoop_chain": {"start": [150, 1450], "groups": [[2, 300], [16, 150], [8, 300], [2, 600]]}, "hoop_zones": [["P3", 3], ["P4", 16], ["P3", 10]], "r_hoop": 1150, "r_hoop_by_mark": {"P3": 1150, "P4": 1147}, "tie": {"mark": "P5", "chain": {"start": [150, 1500], "groups": [[1, 450], [8, 300], [8, 300], [2, 600]]}, "per_level": 2, "offset": 0, "y_lift": 16}, "no_fillet_marks": ["P1", "P2", "P3", "P4"], "src": "재료표 L·N·r; 단면 r 1,125 / 1,080 DIVISION 60; 사슬 '띠철근외측'·'크로스타이' (기초 바닥 EL 12.175 기준); Q1~Q4 (2026-10-14)"} (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("G2 added; backup", bk)