- 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>
112 lines
6.9 KiB
Python
112 lines
6.9 KiB
Python
"""R3 (footing rebar) reading of the Ulsan P1 drawing -> data/산외교울산P1 params.footing_rebar, expected.G3;
|
|
adds G3 to the pier scope (builder footing_rebar_mats.py, checker g3_mats.py).
|
|
|
|
배근도(1) front view (CX 10473.9, FB y -40253.3) and side view (CX 24604.3); footing 7,500 x 7,500 x 2,500.
|
|
- position chains: top '100','150','28@250=7.000','50','100(상면)'; bottom '100','150','56@125=7.000','50','100(하면)';
|
|
middle '100','400','13@500=6.500','400','100(중앙)'. The side-view top chain ends with '150','100' -> B4 last
|
|
bar at 3,650 (front view: 3,600) - drawing inconsistency, modelled as drawn.
|
|
- Y-direction (front): bottom z 127.5 = B2 (U, legs up 2,250, on the top-row positions, 31) + B3 (other 28);
|
|
top z 2,422.5 = B1 (31). X-direction (side): bottom z 172.5 = B5 (U) + B6; top z 2,377.5 = B4.
|
|
The B5 positions follow the front top row (bottom chain has no 3,650) [추론].
|
|
- B8 perimeter hoops centreline ±3,672.5, z 375..2,175 @300 (7); B9 (X) / B10 (Y) mid layer z 1,275 at the
|
|
drawn positions, legs 100 down; both at the same z (drawn) -> cross at the intersections (recorded).
|
|
- B7 verticals on the 14 x 14 grid -3,250..3,250 @500, checkerboard (i+j even) = 98 [추론]; drawn z 150..2,400,
|
|
A 2,218 centred -> z0 166 [추론]; legs 100 along +Y (avoids the X-direction bottom bars) [추론].
|
|
"""
|
|
import json
|
|
import shutil
|
|
import time
|
|
from pathlib import Path
|
|
|
|
HERE = Path(__file__).resolve().parent
|
|
APP = HERE.parent / "교각모델링앱"
|
|
PIER = APP / "data" / "산외교울산P1"
|
|
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"]}
|
|
MARKS = [f"B{i}" for i in range(1, 11)]
|
|
|
|
ROW_DEF = {
|
|
"bottom": {"first": [-3650], "start": -3500, "pitch": 125, "n": 57, "last": [3600]},
|
|
"top_front": {"first": [-3650], "start": -3500, "pitch": 250, "n": 29, "last": [3600]},
|
|
"top_side": {"first": [-3650], "start": -3500, "pitch": 250, "n": 29, "last": [3650]},
|
|
"grid": {"start": -3250, "pitch": 500, "n": 14},
|
|
}
|
|
MID = [-3250, -2250, -1250, -250, 750, 1750, 2750]
|
|
|
|
|
|
def row(spec):
|
|
return sorted(spec.get("first", []) + [spec["start"] + spec["pitch"] * i for i in range(spec["n"])] + spec.get("last", []))
|
|
|
|
|
|
def mm(v):
|
|
return round(float(v) * 1000) if "." in v else int(v)
|
|
|
|
|
|
def L(m):
|
|
return round(float(ROWS[m]["_right"][0][1]) * 1000) # first value right of the J column = L
|
|
|
|
|
|
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")
|
|
for f in ("params.json", "expected.json"):
|
|
shutil.copy2(PIER / f, PIER / "backup" / f"{Path(f).stem}_before_R3_{stamp}.json")
|
|
bottom, tf, ts = row(ROW_DEF["bottom"]), row(ROW_DEF["top_front"]), row(ROW_DEF["top_side"])
|
|
on = [v for v in bottom if v in tf]
|
|
off = [v for v in bottom if v not in tf]
|
|
a = mm(ROWS["B1"]["A"])
|
|
leg_u = mm(ROWS["B2"]["B"])
|
|
lap = mm(ROWS["B2"]["J"])
|
|
hook = mm(ROWS["B9"]["B"])
|
|
src_f, src_s = "배근도(1) 정면도 기초", "배근도(1) 측면도 기초"
|
|
groups = [
|
|
dict(mark="B1", axis="Y", z=2422.5, pos=tf, a=a, leg=0, src=f"{src_f} 상면 사슬 '28@250' (끝 3,600)"),
|
|
dict(mark="B2", axis="Y", z=127.5, pos=on, a=a, leg=leg_u, lap=lap, src=f"{src_f} 하면 U형 (상면 위치), 이음 J {lap} 길이만"),
|
|
dict(mark="B3", axis="Y", z=127.5, pos=off, a=a, leg=0, src=f"{src_f} 하면 '56@125' 중 B2 외"),
|
|
dict(mark="B4", axis="X", z=2377.5, pos=ts, a=a, leg=0, src=f"{src_s} 상면 사슬 (끝 '150','100' -> 3,650, 정면과 불일치)"),
|
|
dict(mark="B5", axis="X", z=172.5, pos=on, a=a, leg=leg_u, lap=lap, src=f"{src_s} 하면 U형 (정면 상면 위치) [추론]"),
|
|
dict(mark="B6", axis="X", z=172.5, pos=off, a=a, leg=0, src=f"{src_s} 하면 B5 외"),
|
|
dict(mark="B9", axis="X", z=1275, pos=MID, a=a, leg=-hook, src=f"{src_s} 중앙 (작도 위치, 비대칭)"),
|
|
dict(mark="B10", axis="Y", z=1275, pos=MID, a=a, leg=-hook, src=f"{src_f} 중앙 (작도 위치, 비대칭; B9와 같은 높이)"),
|
|
]
|
|
hoop = dict(mark="B8", half=3672.5, levels=[375 + 300 * i for i in range(7)],
|
|
design_length=2 * mm(ROWS["B8"]["A"]) + 2 * mm(ROWS["B8"]["B"]) + 4 * mm(ROWS["B8"]["J"]),
|
|
src="정면·측면 둘레 띠 ±3,672.5, z 375~2,175 @300; 길이 2A+2B+4J")
|
|
grid = row(ROW_DEF["grid"])
|
|
vert = dict(mark="B7", grid_x=grid, grid_y=grid, parity=0, z0=150 + (2250 - mm(ROWS["B7"]["A"])) / 2,
|
|
a=mm(ROWS["B7"]["A"]), leg=mm(ROWS["B7"]["B"]), leg_axis="Y",
|
|
src="14x14 격자 @500 중 체크무늬 98 [추론]; 작도 z 150~2,400, A 중앙 배치 [추론]; 갈고리 +Y [추론]")
|
|
P["footing_rebar"] = {"form": "mats", "groups": groups, "hoops": hoop, "verticals": vert,
|
|
"src": "배근도(1) 정면·측면 기초 배근 + 배근도(3) 재료표 B1~B10"}
|
|
P["scope"] = [g for g in ("G1", "G2", "G3", "G4", "G5") if g in set(P["scope"]) | {"G3"}]
|
|
P["builders"]["G3"] = "footing_rebar_mats.py"
|
|
E["checkers"]["G3"] = "g3_mats.py"
|
|
E["negative"]["G3"] = [{"mark": "B3", "d": [5, 0, 0]}, {"mark": "B7", "d": [0, 0, 5]}]
|
|
E["G3"] = {
|
|
"schedule": {m: [L(m), int(ROWS[m]["n"])] for m in MARKS},
|
|
"dia": {m: int(ROWS[m]["dia"][1:]) for m in MARKS},
|
|
"rows": ROW_DEF,
|
|
"layers": {
|
|
"B1": {"axis": "Y", "z": 2422.5, "row": "top_front"},
|
|
"B2": {"axis": "Y", "z": 127.5, "row": "bottom", "subset": "on", "of": "top_front"},
|
|
"B3": {"axis": "Y", "z": 127.5, "row": "bottom", "subset": "off", "of": "top_front"},
|
|
"B4": {"axis": "X", "z": 2377.5, "row": "top_side"},
|
|
"B5": {"axis": "X", "z": 172.5, "row": "bottom", "subset": "on", "of": "top_front"},
|
|
"B6": {"axis": "X", "z": 172.5, "row": "bottom", "subset": "off", "of": "top_front"},
|
|
"B9": {"axis": "X", "z": 1275, "pos": MID, "leg": -hook},
|
|
"B10": {"axis": "Y", "z": 1275, "pos": MID, "leg": -hook},
|
|
},
|
|
"hoops": {"mark": "B8", "half": 3672.5, "chain": {"start": [375], "groups": [[6, 300]]}},
|
|
"verticals": {"mark": "B7", "grid_x": "grid", "grid_y": "grid", "parity": 0, "z0": 166, "a": 2218},
|
|
"src": "재료표 L·수량; 정면·측면 위치 사슬(상면·하면·중앙); 층 높이는 작도값 [derived]",
|
|
}
|
|
(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", {g["mark"]: len(g["pos"]) for g in groups}, "B7", sum(1 for i in range(14) for j in range(14) if (i + j) % 2 == 0))
|
|
print("scope", P["scope"], "B8 len", hoop["design_length"], "B7 z0", vert["z0"], "palette", sorted(P["display"]["rebar_palette"]))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|