"""Saejae-1 P1 footing rebar (G3: B1~B12) -> centreline polylines for the generic builder rebar_polylines.py (GATE G3). Same rules as Okseong P1 (decisions F1-F5 applied again 2026-10-15): mats U-bars with two marks alternating along the sorted positions, X bars 22.5 beside the Y bars, B12 (Y mid bars) lifted 19, B9 'ㄷ' ties from the drawn grid rule, UM not modelled, laps not modelled. Inputs: 판독/g3_values.json. Output: 판독/g3_bars.json. Model axes: X along the coping, Y across, Z = EL x 1000, footing centre = origin. """ import json from pathlib import Path HERE = Path(__file__).resolve().parent V = json.loads((HERE / "판독" / "g3_values.json").read_text(encoding="utf-8")) bars = [] H = 3750.0 # a 7,500 / 2 def rb(d): return ((2 * d if d <= 16 else 3.5 * d) + d) / 2 def add(mark, occ, pts, dia, L, src, r=None): bars.append({"mark": mark, "occ": occ, "pts": [[round(v, 2) for v in p] for p in pts], "r": rb(dia) if r is None else r, "design_length": L, "src": src}) def u_y(x, z, leg): return [(x, -H, z + leg), (x, -H, z), (x, H, z), (x, H, z + leg)] def u_x(y, z, leg): return [(-H, y, z + leg), (-H, y, z), (H, y, z), (H, y, z + leg)] for key, marks, axis, leg, L, src in ( ("y_bars_bottom", ("B2", "B4"), "Y", 1800, 12010, "정면 하면 점 EL 10.132, 측면 다리 1,800"), ("x_bars_bottom", ("B6", "B8"), "X", 2400, 13210, "측면 하면 점 EL 10.1545, 정면 다리 2,400"), ("y_bars_top", ("B1", "B3"), "Y", -900, 10590, "정면 상면 점 EL 12.532, 측면 다리 900"), ("x_bars_top", ("B5", "B7"), "X", -1200, 11190, "측면 상면 점 EL 12.5095, 정면 다리 1,200")): z = V[key]["z"] pos = V[key]["x"] if axis == "Y" else V[key]["y"] for i, v in enumerate(pos): add(marks[i % 2], f"{axis.lower()}{v:+.1f}", u_y(v, z, leg) if axis == "Y" else u_x(v, z, leg), 25, L, src + f"; {marks[0]}/{marks[1]} 교번, 겹이음 j 미모델 (F3 [추론])") for zs, xs in V["mid_y_bars"].items(): for x in xs: add("B12", f"z{zs}x{x:+.0f}", u_y(x, float(zs) + 19, -100), 19, 7700, f"정면 중간 점 EL {float(zs) / 1000:.3f} (+19, F4 [추론])") for zs, ys in V["mid_x_bars"].items(): for y in ys: add("B11", f"z{zs}y{y:+.0f}", u_x(y, float(zs), -100), 19, 7700, f"측면 중간 점 EL {float(zs) / 1000:.3f} (F4 [추론])") c = V["b10_corner"] for zs in V["b10_levels"]: add("B10", f"z{zs:.0f}", [(-c, 0, zs), (-c, -c, zs), (c, -c, zs), (c, c, zs), (-c, c, zs), (-c, 0, zs)], 19, 32416, "정면·측면 모서리 점 ±3,772.5, 재료표 7,544 x 7,544, 겹이음 560 x 4 미모델") b9 = V["b9"] for k, y in enumerate(b9["rows"]): for x in (b9["cols_even"] if k % 2 == 0 else b9["cols_odd"]): a2, cc, zt, zb = b9["a"] / 2, b9["c"], b9["zt"], b9["zb"] add("B9", f"x{x:+.0f}y{y:+.0f}", [(x, y - a2 + cc, zb), (x, y - a2, zb), (x, y - a2, zt), (x, y + a2, zt), (x, y + a2, zb), (x, y + a2 - cc, zb)], 19, 6332, "정면 연직선 15곳 @500(짝수 행 8·홀수 행 7), 측면 다리 행 6 @1,200; 상세 a 1,244 b 2,444 c 100 [행·열 규칙, F1/F2형 추론]") count = {} for b in bars: count[b["mark"]] = count.get(b["mark"], 0) + 1 out = {"bars": bars, "summary": {"bars": len(bars), "per_mark": count}} (HERE / "판독" / "g3_bars.json").write_text(json.dumps(out, ensure_ascii=False), encoding="utf-8") print(json.dumps(out["summary"], ensure_ascii=False))