"""R2 (column rebar) reading of the Ungok P2 drawings -> data/운곡교p2 params.column_rebar / rebar_marks(P*) / expected.G2. Findings (D1 front view + sections C-C/D-D/E-E, D3 schedule): - sections identical to P1 drawing: main bars r 870.5 / 825.5 (46 div, start 0.001 deg), hoop arc 897.5 drawn - D3: P4/P5 R904 (H29, coupler gap 85), P3 R899 (H19), P1 A 16.343, P2 16.683, P3 37 pcs - D1 labels 'P4 H29@100', 'P5 H29@100', chain '150','1.030','8@120','22@120','37@300=11.100', ties '8@1.800' - front view: P2 bottom = footing bottom + 300 (214CA), P1 leg at +300 with R340 / leg 500 (214CB/214CC) Rules reused from P1 (HITL H1/H2): main radii = section CAD, hoop radius = schedule R, bar tops = schedule. """ import json import shutil import sys import time from pathlib import Path HERE = Path(__file__).resolve().parent APP = HERE.parent / "교각모델링앱" PIER = APP / "data" / "운곡교p2" sys.path.insert(0, str(APP)) from engine import reader # noqa: E402 FB = 25123 # footing bottom (R1) def schedule(): texts = json.loads((PIER / "drawings" / "texts.json").read_text(encoding="utf-8")) out = {} for t in reader.table_candidates(texts): if not t["key"].startswith("schedule"): continue last = None for _, r in reader.table_records(t["rows"], lambda s: bool(reader.MARK_RE.match(s))): dia = r.get("직경", "") last = last if dia in ('"', "") else dia r["_dia"] = last out[r["_key"]] = r return out def chain(start, groups, base): z = base + sum(start) pts = [z] for n, p in groups: for _ in range(n): z += p pts.append(z) return pts def main(): S = schedule() P = json.loads((PIER / "params.json").read_text(encoding="utf-8")) E = json.loads((PIER / "expected.json").read_text(encoding="utf-8")) stamp = time.strftime("%Y%m%d_%H%M%S") for f in ("params.json", "expected.json"): shutil.copy2(PIER / f, PIER / "backup" / f"{Path(f).stem}_before_R2_{stamp}.json") sch = {} for m in ("P1", "P2", "P3", "P4", "P5", "P6"): r = S[m] d = {"mark": m, "shape": r["형식"], "dia": r.get("직경", ""), "n": r["개수"], "L": r["길이"]} for k in ("A", "B", "C", "R"): if k in r: d[k] = r[k] sch[m] = d groups = [[8, 120], [22, 120], [37, 300]] levels = chain([150, 1030], groups, FB) marks = ["P4"] * 9 + ["P5"] * 22 + ["P3"] * 37 ties = chain([150, 1030], [[8, 1800]], FB) a1, a2 = float(S["P1"]["A"]) * 1000, float(S["P2"]["A"]) * 1000 cr = P["column_rebar"] cr["_note"] = "Column rebar P1-P6 (Ungok P2). Z = EL x 1000. Angles from +X counter-clockwise (plan)." cr["schedule"] = sch mb = cr["main_bars"] mb["p1"].update({"hook_leg_z": FB + 300, "straight_from": FB + 300 + 340, "straight_len": round(a1)}) mb["p2"].update({"z0": FB + 300, "length": round(a2)}) mb["src"] = {"radii": "D1 단면 C-C/D-D/E-E dots 870.5 / 825.5 (46 each, start 0.001 deg) = P1 drawing (HITL H2 rule)", "bottom": "D1 정면도 214CA bottom = footing bottom + 300; 214CB leg 500, 214CC R340", "top": "D3 schedule A (P1 16.343, P2 16.683) -> top EL 42.106 both (P1 rule H1)"} cr["hoops"] = {"radius": 904, "radius_by_mark": {"P3": 899}, "levels": levels, "marks": marks, "src": {"levels": "D1 정면도 '150','1.030','8@120=960','22@120=2.640','37@300=11.100'; front dots 1180 + 120n", "radius": "D3 R: P4/P5 904 (2*pi*904 = 5680 = L), P3 899 (pi*899 = A 2.824); " "section arc drawn 897.5 = P1 drawing not updated -> schedule adopted (P1 rule H2)"}} cr["ties"].update({"levels": ties, "src": {"levels": "D1 정면도 '150','1.030','8@1.800=14.400'", "angles": "D1 단면 tie lines 0/45/90/135 (1795 drawn), D3 P6 A 1.836 / B 150"}}) for m, r in sch.items(): P["rebar_marks"][m] = {"dia": S[m]["_dia"], "shape": r["shape"]} dia = {m: int(S[m]["_dia"][1:]) for m in sch} E["G2"] = { "schedule_L": {m: round(float(S[m]["길이"]) * 1000) for m in sch}, "schedule_n": {m: int(S[m]["개수"]) for m in sch}, "dia": dia, "hoop_chain": {"start": [150, 1030], "groups": groups}, "hoop_marks_by_zone": [["P4", 9], ["P5", 22], ["P3", 37]], "tie_chain": {"start": [150, 1030], "groups": [[8, 1800]]}, "tie_offset": dia["P4"] / 2 + dia["P6"] / 2, "r_outer": 870.5, "r_inner": 825.5, "r_hoop": 904, "main_divisions": 46, "bottom_above_footing": 300, "p1_top_parts": [300, int(S["P1"]["R"]), round(a1)], "no_fillet_marks": ["P1", "P2", "P4", "P5"], "src": "D3 L·수량·R·A (Ungok P2); D1 '150','1.030','8@120=960','22@120=2.640','37@300=11.100','8@1.800=14.400'; " "section radii (HITL H2 rule); tie offset = H29/2 + H16/2 (hoop P4 H29 label, P6 H16)", } (PIER / "params.json").write_text(json.dumps(P, ensure_ascii=False, indent=1), encoding="utf-8") (PIER / "expected.json").write_text(json.dumps(E, ensure_ascii=False, indent=1), encoding="utf-8") print("levels", len(levels), levels[0], levels[-1], "ties", ties[0], ties[-1]) print("marks dia", {m: P["rebar_marks"][m] for m in sch}) print("schedule L", E["G2"]["schedule_L"], "n", E["G2"]["schedule_n"]) if __name__ == "__main__": main()