Files
Pier_v1/Code/운곡교P2판독/extract_r3.py
T
ahnyongjooandClaude Sonnet 5.5 964a841de1 chore(rebar): Pier_T_rebar 작업 폴더 초기 구성 및 외부 의존 파일 통합
- Code\rebar_pipeline, review_pipeline, pier-program을 정션에서 실제 폴더로 전환
- Code\rhino_mcp 및 CLAUDE_rhino배경.md 추가, .mcp.json은 PYTHONPATH로 새 위치 사용
- pier-program 내부 .git 제거(이력은 backup\pier-program_20261028.bundle에 보관)
- worktree 가이드 반영(CLAUDE.local.md, HANDOFF.md)
- D:\Rhino-MCP 경로 참조를 새 위치로 치환

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 11:20:18 +09:00

95 lines
5.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""R3 (footing rebar) reading of the Ungok P2 drawings -> params.footing_rebar / rebar_marks(B*) / expected.G3.
Drawn facts (D1 front / side view dots, relative to the view centre, z above the footing bottom):
- layer heights as P1 (F1 rule): 122 / 178 / 227.5 / 277 / 2073 / 2127; B10 rings 350..1950 @200, dots x 5093 / y 3818
- front (Y-direction bars at X): ends +-5075, series -4875 + 125 i (79) -> B2/B4; -4875 + 250 i (40) -> B1, B3
- side (X-direction bars at Y): as P1 (+-3800, -3625 + 125 i (59) / + 250 i (30))
- mid layers: B12 (front) 550/1350: +-1875, 2875, 3875; 950/1750: +-375 .. +-4375 -> 32 drawn (D3 38);
B11 (side) as P1 -> 28 (D3 28)
- B9 EREC lines x -4625 .. 4625 @250 (38), y -3500 .. 3500 @250 (29), z 150..2100 -> checker 551 drawn (D3 493)
Conflicts B9 / B12 count: drawn adopted (P1 rule F2), schedule difference recorded as planned FAIL.
"""
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(HERE))
from extract_r2 import schedule # noqa: E402
def series(start, pitch, n):
return [float(start + pitch * i) for i in range(n)]
def sym(vals):
return sorted([-v for v in vals] + list(vals))
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_R3_{stamp}.json")
fr = P["footing_rebar"]
y_bot = sorted([-5075.0, 5075.0] + series(-4875, 125, 79))
y_250 = sorted([-5075.0, 5075.0] + series(-4875, 250, 40))
L = fr["layers"]
L["bottom_Y1"]["pos"], L["bottom_Y3"]["pos"], L["top_Y"]["pos"] = y_bot, y_250, y_250
mid_y = {"550.0": sym([1875.0, 2875.0, 3875.0]), "950.0": sym([375.0, 1375.0, 2375.0, 3375.0, 4375.0]),
"1350.0": sym([1875.0, 2875.0, 3875.0]), "1750.0": sym([375.0, 1375.0, 2375.0, 3375.0, 4375.0])}
L["mid_Y"]["levels"] = mid_y
fr["a_x"], fr["a_y"] = float(S["B5"]["A"]) * 1000, float(S["B1"]["A"]) * 1000
fr["a_src"] = "D3 B5 a '10.150' (X bars), B1 a '7.600' (Y bars)"
fr["b9"].update({"grid_x": series(-4625, 250, 38), "count": 551,
"src": "D1 정면 EREC x -4625..4625 @250 (chain '450','37@250=9.250'), 측면 -3500..3500 @250; "
"checker parity as P1 -> 551 drawn; D3 개수 493 (= P1 value) -> CONFLICT, drawn adopted"})
fr["b10"].update({"size_x": float(S["B10"]["A"]) * 1000, "size_y": float(S["B10"]["B"]) * 1000,
"src": "D1 정면 '150','9@200=1.800'; dots x=5093 / y=3818; D3 B10 a 10.198 b 7.644"})
fr["_note"] = "Footing rebar B1-B12 (Ungok P2); z above the footing bottom EL 25.123"
rows = {}
for m in ("B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "B10", "B11", "B12"):
r = S[m]
rows[m] = [m, r["형식"], r.get("직경", ""), r["개수"], r["A"]] + [r[k] for k in ("B", "C") if k in r] + [r["길이"], r["총길이"]]
P["rebar_marks"][m] = {"dia": r["_dia"], "shape": r["형식"]}
fr["schedule"] = rows
fr["counts_check"] = {"bottom_Y1": len(y_bot), "bottom_X2": len(L["bottom_X2"]["pos"]), "bottom_Y3": len(y_250),
"bottom_X4": len(L["bottom_X4"]["pos"]), "top_Y": len(y_250), "top_X": len(L["top_X"]["pos"]),
"mid_X": sum(len(v) for v in L["mid_X"]["levels"].values()),
"mid_Y": sum(len(v) for v in mid_y.values())}
sched = {m: [round(float(S[m]["길이"]) * 1000), int(S[m]["개수"])] for m in rows}
g3 = E["G3"]
g3.update({
"schedule": sched,
"dia": {m: int(S[m]["_dia"][1:]) for m in rows},
"rows": {"Y_BOT": {"ends": [-5075, 5075], "start": -4875, "pitch": 125, "n": 79},
"Y_250": {"ends": [-5075, 5075], "start": -4875, "pitch": 250, "n": 40},
"X_BOT": {"ends": [-3800, 3800], "start": -3625, "pitch": 125, "n": 59},
"X_250": {"ends": [-3800, 3800], "start": -3625, "pitch": 250, "n": 30}},
"b10_size": [10198, 7644],
"b9_grid": {"x": {"start": -4625, "pitch": 250, "n": 38}, "y": {"start": -3500, "pitch": 250, "n": 29}},
"src": "D3 L·수량 (P2); D1 '100','200','78@125=9.750' / '39@250=9.750' / '100','175','58@125=7.250' / '29@250'; "
"F1 층 높이(작도점, P1과 같음); '150','9@200=1.800'; '450','37@250=9.250' / '300','28@250=7.000'; "
"EREC 150~2100; 중간층 작도점 [derived]",
})
pf = [x for x in E.get("planned_fail", []) if x["gate"] != "G3"]
pf += [{"gate": "G3", "item": "B12 bar count vs schedule", "reason": "작도 32본 채택 vs D3 38본 (P1 F2 규칙, P1도 28/34)",
"approved": "P1 결정(2026-10-07) 준용 — P2 사용자 확인 대기"},
{"gate": "G3", "item": "B9 bar count vs schedule", "reason": "작도 551본(38×29 엇갈림) 채택 vs D3 493본(P1 값 그대로)",
"approved": "P1 결정(2026-10-07) 준용 — P2 사용자 확인 대기"}]
E["planned_fail"] = pf
(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("counts", fr["counts_check"], "b9", fr["b9"]["count"], "a", fr["a_x"], fr["a_y"], "b10", fr["b10"]["size_x"])
print("schedule", sched)
if __name__ == "__main__":
main()