Files
Pier_v1/Code/울산P2판독/extract_r2.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

108 lines
6.6 KiB
Python

"""R2 (column rebar) reading of the Ulsan P2 drawing (배근도(4)) -> data/산외교울산P2 params.column_rebar / rebar_marks /
display palette, expected.G2; adds G2 to the pier scope. Same form as P1 (script copied 2026-10-15); P2 differences read from the sheet:
main P1 A 32.110 (P1 27.510), hoops P3 12 / P4 31 / P2 82 (chains 625, 11@150=1.650, 31@150=4.650, 82@300=24.600), ties P5 19 levels x 4 = 76
(chain 150, 625, 3@1.800 + 13@1.800 = 16 x 1.800, 1.200, 900; ends at the hoop chain top FB + 31.675 m like P1). Original P1 docstring follows.
배근도(1) (sheet x 0..46000): front view footing bottom y -40253.3, column CL x 10473.9; sections C-C / D-D / E-E.
- main P1: 68 bars (CSBSEC1 inserts) on r 1125, pitch 360/68, start 0 deg; drawn 0/180-deg bars: vertical from
FB+540, R340 bend (B041/B042), leg at FB+200 outwards; schedule A 27.510, B 534 (= pi/2 x 340), C 500
- hoops R 1.149 (schedule; drawn arc 1147.5): chain '150','625','11@150=1.650','25@150=3.750','70@300=21.000'
-> P3 (V, coupler 55) 12 levels in the footing, P4 (X, coupler 55) 25, P2 (VI, laps 380, hooks 200) 70
- ties P5 (I, 2.295 + 2 x 150): chain '150','625','3@1.800','11@1.800','1.200' -> 16 levels x 4 (64);
section lines at 0 / 42.4 / 90 / 132.4 deg (bar positions 0, 8, 17, 25)
"""
import json
import shutil
import sys
import time
from pathlib import Path
HERE = Path(__file__).resolve().parent
APP = HERE.parent / "교각모델링앱"
PIER = APP / "data" / "산외교울산P2"
FB = 38916
S = json.loads((HERE / "판독" / "schedule.json").read_text(encoding="utf-8"))
ROWS = {r["mark"]: r for t in S.values() for r in t["rows"]}
def L(m):
"""Schedule length (first value right of J/R columns) in mm."""
return round(float(ROWS[m]["_right"][-2][1]) * 1000)
def chain(start, groups, base):
z = base + sum(start)
out = [z]
for n, p in groups:
for _ in range(n):
z += p
out.append(z)
return out
def main():
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")
(PIER / "backup").mkdir(exist_ok=True)
for f in ("params.json", "expected.json"):
shutil.copy2(PIER / f, PIER / "backup" / f"{Path(f).stem}_before_R2_{stamp}.json")
hoop_chain = {"start": [150, 625], "groups": [[11, 150], [31, 150], [82, 300]]}
levels = chain(hoop_chain["start"], hoop_chain["groups"], FB)
zones = [("P3", 12), ("P4", 31), ("P2", 82)]
cut = [0, 12, 43, 125]
tie_chain = {"start": [150, 625], "groups": [[16, 1800], [1, 1200], [1, 900]]}
a = lambda m: round(float(ROWS[m]["A"]) * 1000) if "." in ROWS[m]["A"] else int(ROWS[m]["A"])
P["column_rebar"] = {
"form": "ring",
"schedule": {m: {k: v for k, v in ROWS[m].items() if k not in ("y", "_right")} | {"L": ROWS[m]["_right"][-2][1]}
for m in ("P1", "P2", "P3", "P4", "P5")},
"main": {"mark": "P1", "count": 68, "start_deg": 0.0, "radius": 1125.0, "hook_leg_z": FB + 200, "bend_r": 340,
"hook_leg": 500, "straight_from": FB + 540, "straight_len": a("P1"),
"src": "배근도(1) 단면 C-C/D-D/E-E CSBSEC1 68개 r 1,125 (start 0 deg); 정면 B041/B042 R340, A91D/A920 시작 FB+540; 재료표 P1"},
"hoops": {"radius": 1149, "zones": [
{"mark": "P3", "type": "coupler_half", "levels": levels[cut[0]:cut[1]], "a": a("P3"), "gap": int(ROWS["P3"]["B"])},
{"mark": "P4", "type": "coupler_ring", "levels": levels[cut[1]:cut[2]], "a": a("P4"), "gap": int(ROWS["P4"]["B"])},
{"mark": "P2", "type": "lap_half", "levels": levels[cut[2]:cut[3]], "a": a("P2"), "lap": int(ROWS["P2"]["J"]),
"hook": int(ROWS["P2"]["B"])}],
"src": "재료표 R 1.149 (단면 원호 작도 1,147.5); 정면 사슬 '150','625','11@150','25@150','70@300'; 이음 위치 [추론]"},
"ties": {"mark": "P5", "levels": chain(tie_chain["start"], tie_chain["groups"], FB),
"angles_deg": [0.0, 8 * 360 / 68, 90.0, 25 * 360 / 68], "straight": a("P5"), "hook": int(ROWS["P5"]["B"]),
"z_offset": 16 / 2 + 19 / 2,
"src": "정면 사슬 '3@1.800','11@1.800','1.200' (+ 첫 단 775) = 16단 x 4 = 64; 단면 선 0/42.4/90/132.4 deg; 갈고리 아래 [추론]"},
}
P["rebar_marks"] = {m: {"dia": r["dia"], "shape": r["shape"]} for m, r in ROWS.items()}
P["rebar_marks_src"] = "배근도(3) 철근재료표 SD400·SD500 (34 마크)"
pal = P["display"]["rebar_palette"]
pal.setdefault("22", [23, 190, 207])
pal.setdefault("13", [140, 86, 75])
P["display"]["column_mark_colours"] = {"P1": [200, 40, 40], "P2": [40, 120, 200], "P3": [40, 170, 170],
"P4": [90, 90, 220], "P5": [140, 60, 160]}
P["display"]["src"] = "R8 팔레트(2026-10-07) + 울산 확장 H22 (23,190,207), H13 (140,86,75) [2026-10-13]; 숨김 없음"
P["scope"] = sorted(set(P["scope"]) | {"G2"})
P["builders"]["G2"] = "column_rebar_ring.py"
E["rebar_palette"] = dict(E["rebar_palette"], **{"22": [23, 190, 207], "13": [140, 86, 75]})
E["checkers"]["G2"] = "g2_ring.py"
E["negative"]["G2"] = [{"mark": "P1", "d": [5, 0, 0]}, {"mark": "P2", "d": [0, 0, 5]}]
E["G2"] = {
"schedule_L": {m: L(m) for m in ("P1", "P2", "P3", "P4", "P5")},
"schedule_n": {m: int(ROWS[m]["n"]) for m in ("P1", "P2", "P3", "P4", "P5")},
"dia": {m: int(ROWS[m]["dia"][1:]) for m in ("P1", "P2", "P3", "P4", "P5")},
"main": {"mark": "P1", "radius": 1125, "divisions": 68, "start_deg": 0.0, "bottom_above_footing": 200,
"top_parts": [540, a("P1")]},
"hoop_chain": hoop_chain, "hoop_zones": zones, "r_hoop": 1149,
"tie": {"mark": "P5", "chain": tie_chain, "per_level": 4, "offset": 17.5},
"no_fillet_marks": ["P1", "P3", "P4"],
"src": "재료표 L·수량·R; 단면 '125','1.125','1.125','125', DIVISION 68; 정면 사슬(띠철근 외측·크로스타이); P1 갈고리 작도 높이 200/540",
}
(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("hoop levels", len(levels), levels[0], levels[-1], "ties", len(P["column_rebar"]["ties"]["levels"]),
P["column_rebar"]["ties"]["levels"][-1])
print("schedule L", E["G2"]["schedule_L"], "scope", P["scope"])
if __name__ == "__main__":
main()