- 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>
122 lines
5.9 KiB
Python
122 lines
5.9 KiB
Python
"""Read bearing pedestal (h1) and pad (h2) geometry and append `bearing_seats` to params.json.
|
|
|
|
Sources (read only): 판독/plan.json (D1 평면도 entities), 판독/2_survey.json (D2 ELEVATION TABLE).
|
|
Base pattern = girder line 5 as drawn in D1 평면도. Girder lines 1..4 = base shifted in X by
|
|
(k-5) * 7516/3 (D1 평면도 dim '3@2.505=7.516'); lines 3·4 are checked against drawn vertices,
|
|
lines 1·2 are not drawn ([추론], approved by user 2026-10-07).
|
|
Existing params.json keys are left unchanged; only `bearing_seats` is (re)written.
|
|
"""
|
|
import json
|
|
import math
|
|
from pathlib import Path
|
|
|
|
from calc_bearing_seat import table_rows
|
|
|
|
HERE = Path(__file__).resolve().parent
|
|
DATUM = (12162.4, 26412.3) # D1 평면도 pier centre (CS-CNTL 1BFBF x 1C113)
|
|
PITCH = 7516 / 3
|
|
|
|
|
|
def entities():
|
|
return {r["h"]: r for r in json.loads((HERE / "판독" / "plan.json").read_text(encoding="utf-8"))}
|
|
|
|
|
|
def rel(p):
|
|
return [round(p[0] - DATUM[0], 1), round(p[1] - DATUM[1], 1)]
|
|
|
|
|
|
def centre(q):
|
|
return [sum(p[0] for p in q) / 4, sum(p[1] for p in q) / 4]
|
|
|
|
|
|
def angle_deg(a, b):
|
|
"""Rotation of edge a->b from the +Y axis, clockwise positive (plan view)."""
|
|
return math.degrees(math.atan2(b[0] - a[0], b[1] - a[1]))
|
|
|
|
|
|
def main():
|
|
E = entities()
|
|
pt = lambda h, i: E[h]["pts"][i]
|
|
# Pedestal outline girder 5: 1C0D1 start (front-left), 1C0CE end (rear-left), 1C0CF end, 1C0D0 end
|
|
ped = [pt("1C0D1", 1), pt("1C0CE", 1), pt("1C0CF", 1), pt("1C0D0", 1)]
|
|
split = [pt("1CAD4", 0), pt("1CAD4", 1)] # left / right point of the front|rear split line
|
|
front_half = [ped[0], split[0], split[1], ped[3]]
|
|
rear_half = [split[0], ped[1], ped[2], split[1]]
|
|
pads = {"front": dict(bottom="1C124", top="1C125"), "rear": dict(bottom="1C11B", top="1C11C")}
|
|
rows = {r["no"]: r for r in table_rows()}
|
|
|
|
checks = []
|
|
# Parallel-translation check on drawn girder lines 4 (full) and 3 (half, x >= datum)
|
|
g4 = [pt("1C0D9", 1), pt("1C0D6", 1), pt("1C0D7", 1), pt("1C0D8", 1)]
|
|
for a, b in zip(ped, g4):
|
|
checks.append(dict(item="girder4 pedestal vertex", dx=round(b[0] - (a[0] - PITCH), 2),
|
|
dy=round(b[1] - a[1], 2)))
|
|
g3 = [pt("1C0DC", 1), pt("1C0DD", 1)] # rear-right, front-right corners of girder 3
|
|
for a, b in zip([ped[2], ped[3]], g3):
|
|
checks.append(dict(item="girder3 pedestal vertex", dx=round(b[0] - (a[0] - 2 * PITCH), 2),
|
|
dy=round(b[1] - a[1], 2)))
|
|
for row, hs in (("front", ("1C124", "1C127")), ("rear", ("1C11B", "1C11E"))):
|
|
c5, c4 = centre(E[hs[0]]["pts"]), centre(E[hs[1]]["pts"])
|
|
checks.append(dict(item=f"girder4 {row} pad centre", dx=round(c4[0] - (c5[0] - PITCH), 2),
|
|
dy=round(c4[1] - c5[1], 2)))
|
|
|
|
pad_rows = {}
|
|
for row, h in pads.items():
|
|
q, qt = E[h["bottom"]]["pts"], E[h["top"]]["pts"]
|
|
pad_rows[row] = dict(
|
|
centre_rel_girder5=rel(centre(q)),
|
|
rotation_deg=round(angle_deg(q[0], q[1]), 3),
|
|
drawn_bottom_along=round(math.dist(q[0], q[1]), 1),
|
|
drawn_bottom_across=round(math.dist(q[1], q[2]), 1),
|
|
drawn_top_along=round(math.dist(qt[0], qt[1]), 1),
|
|
drawn_top_across=round(math.dist(qt[1], qt[2]), 1),
|
|
src=f"D1 평면도 {h['bottom']} (bottom), {h['top']} (top)")
|
|
|
|
bearings = []
|
|
for no in range(1, 11):
|
|
r = rows[no]
|
|
girder = (no - 1) % 5 + 1
|
|
row = "front" if no <= 5 else "rear"
|
|
p = pad_rows[row]
|
|
bearings.append(dict(
|
|
no=no, type=r["type"], girder_line=girder, row=row,
|
|
centre=[round(p["centre_rel_girder5"][0] + (girder - 5) * PITCH, 1), p["centre_rel_girder5"][1]],
|
|
rotation_deg=p["rotation_deg"],
|
|
el_x=round(r["el_x"] * 1000), h1=r["h1"], h2=r["h2"], A=None, B=None,
|
|
inferred=girder <= 2))
|
|
# A and B per bearing from D2 TABLE (columns A, B)
|
|
texts = json.loads((HERE / "판독" / "2_survey.json").read_text(encoding="utf-8"))["texts"]
|
|
ys = {r["no"]: r["src_y"] for r in rows.values()}
|
|
for b in bearings:
|
|
for t in texts:
|
|
if abs(round(t["y"]) - ys[b["no"]]) <= 1 and 21000 < t["x"] < 37500:
|
|
if abs(t["x"] - 29742) < 200:
|
|
b["A"] = int(t["text"])
|
|
elif abs(t["x"] - 30642) < 200:
|
|
b["B"] = int(t["text"])
|
|
|
|
seats = dict(
|
|
_note="pedestal (h1) per girder line, split into front/rear halves; pad (h2) = frustum "
|
|
"bottom (A+200)x(B+200) -> top (A+100)x(B+100), height h2, rotated per row",
|
|
plan_datum=list(DATUM), pitch_x=PITCH,
|
|
pedestal_girder5=dict(front_half=[rel(p) for p in front_half], rear_half=[rel(p) for p in rear_half],
|
|
rotation_deg=round(angle_deg(ped[0], ped[1]), 3),
|
|
src="D1 평면도 1C0CE~1C0D1 (outline 2500x1200), 1CAD4 (front/rear split)"),
|
|
pad_rows=pad_rows, bearings=bearings, translation_checks=checks,
|
|
src={"h1_h2_A_B_ELX": "D2 교량받침 ELEVATION TABLE", "row_mapping":
|
|
"front(전열)=3500kN NO.1-5 (S1 852), rear(후열)=2800kN NO.6-10 (S1 950); 852+1298+950=3100",
|
|
"girder_mapping": "NO.k / NO.k+5 -> girder line k, left->right (EL.'X' rises with coping steps)",
|
|
"pad_size_rule": "D1 평면도 front pad 900x840 / 800x740 = (A+200)x(B+200) / (A+100)x(B+100) for "
|
|
"A=700,B=640; side view 900->800 over 50"})
|
|
params_path = HERE / "params.json"
|
|
params = json.loads(params_path.read_text(encoding="utf-8"))
|
|
params["bearing_seats"] = seats
|
|
params_path.write_text(json.dumps(params, ensure_ascii=False, indent=2), encoding="utf-8")
|
|
print(json.dumps(dict(pedestal_rotation=seats["pedestal_girder5"]["rotation_deg"], pad_rows=pad_rows,
|
|
checks=checks, AB=[(b["no"], b["A"], b["B"]) for b in bearings]),
|
|
ensure_ascii=False, indent=1))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|