- 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>
73 lines
4.8 KiB
Python
73 lines
4.8 KiB
Python
"""Saejae-1 P1 shape reading (G1 + G5 positions) from the general drawing -> 판독/g1_values.json.
|
||
|
||
Datums: front / side views are broken in the column (break symbol), so two z offsets: below the break
|
||
z(mm) = drawing y - 14716.5 (footing bottom y 24748.5 = EL 10.032), above the break (coping) z = y - 5816.5
|
||
(coping bottom flat y 35348.5 = EL 29.532, top left y 38348.5 = EL 32.532). Front CL x 33756.4, side CL x 61366.4.
|
||
Plan: column centre (34904.3, 55436.6) = model origin; plan y up = model +Y (선형 진행 방향).
|
||
"""
|
||
import json
|
||
import math
|
||
from pathlib import Path
|
||
|
||
from dxftools import doc, entities
|
||
|
||
D = doc("D1")
|
||
FX, SX = 33756.4, 61366.4
|
||
ZF, ZC = -14716.5, -5816.5
|
||
PCX, PCY = 34904.3, 55436.6
|
||
out = {}
|
||
|
||
# front view coping outline (Y = 0 section), CS-CONC-MAJR lines of the coping, x 27700..39800, y 35300..38800
|
||
lines = [(e.dxf.start, e.dxf.end) for e in entities("D1", 27700, 35300, 39800, 38800, "CS-CONC-MAJR")
|
||
if e.dxftype() == "LINE" and e.dxf.start.distance(e.dxf.end) > 1000]
|
||
horiz = sorted({(round(a.y, 1), round(min(a.x, b.x), 1), round(max(a.x, b.x), 1)) for a, b in lines if abs(a.y - b.y) < 0.5 and a.y > 38000})
|
||
steps = [{"x0": round(x0 - FX, 1), "x1": round(x1 - FX, 1), "z": round(y + ZC, 1)} for y, x0, x1 in horiz]
|
||
bottom = [(a, b) for a, b in lines if abs(a.y - b.y) < 0.5 and abs(a.y - 35348.5) < 1]
|
||
slope = [(a, b) for a, b in lines if abs(a.y - b.y) > 100 and abs(a.x - b.x) > 100]
|
||
verts = sorted({(round(a.x, 1), round(min(a.y, b.y), 1), round(max(a.y, b.y), 1)) for a, b in lines if abs(a.x - b.x) < 0.5})
|
||
out["coping_front"] = {
|
||
"z_bottom": 29532.0, "bottom_flat_half": round(max(abs(a.x - FX) for a, b in bottom), 1) if bottom else None,
|
||
"tip_x": 6000.0, "z_tip": round(37048.5 + ZC, 1),
|
||
"end_left": {"x": -6000.0, "z0": round(37048.5 + ZC, 1), "z1": steps[0]["z"]},
|
||
"end_right": {"x": 6000.0, "z0": round(37048.5 + ZC, 1), "z1": steps[-1]["z"]},
|
||
"top_steps": steps, "verts": verts,
|
||
"src": "D1 정면도 코핑 외곽 2F1A~2F27 (Y = 0 단면), 치수 '1.300', '1.704', '2.277', '3@2.507', '2.202'"}
|
||
# side view: coping 3,000 wide, flat bottom 2,200, side taper to EL 31.232
|
||
out["coping_side"] = {"half_width_top": 1500.0, "z_taper_top": round(37048.5 + ZC, 1), "half_width_bottom": 1100.0,
|
||
"z_bottom": 29532.0, "src": "D1 단면도 코핑 2DAF/2DB0 (±1,100 → ±1,500, 경사 1,746.4), 폭 3,000"}
|
||
out["column"] = {"d": 2200.0, "z0": 12632.0, "z1": 29532.0,
|
||
"src": "D1 정면 기둥 2.200, 높이 16.900(치수), 평면 원 r 1,100 (29C8~29CF)"}
|
||
out["footing"] = {"size_x": 7700.0, "size_y": 7700.0, "z0": 10032.0, "z1": 12632.0,
|
||
"src": "D1 정면 2E24~2E2E (7.700 × 2.600), 기초 평면도 7.700"}
|
||
out["lean"] = {"size_x": 7900.0, "size_y": 7900.0, "z0": 9932.0, "z1": 10032.0, "src": "D1 정면 2E24~2E27 (7.900 × 100)"}
|
||
# coping plan (rectangular, 12,000 x 3,000): 28FA~28FD
|
||
out["coping_plan"] = {"x": [28904.3 - PCX, 40904.3 - PCX], "y": [53936.6 - PCY, 56936.6 - PCY],
|
||
"step_lines_x": [round(x - PCX, 1) for x in (31181.7, 33688.7, 36195.6, 38702.5)],
|
||
"src": "D1 평면 28FA~2901 (직사각, 사각 없음)"}
|
||
|
||
|
||
def rect(h):
|
||
pts = [p[:2] for p in D.entitydb[h].get_points("xy")]
|
||
cx, cy = sum(p[0] for p in pts) / 4 - PCX, sum(p[1] for p in pts) / 4 - PCY
|
||
e = [(pts[(i + 1) % 4][0] - pts[i][0], pts[(i + 1) % 4][1] - pts[i][1]) for i in range(4)]
|
||
L = [math.hypot(*v) for v in e]
|
||
ia = max(range(4), key=lambda i: abs(e[i][1]))
|
||
vx, vy = e[ia] if e[ia][1] > 0 else (-e[ia][0], -e[ia][1])
|
||
return {"centre": [round(cx, 1), round(cy, 1)], "along": round(L[ia], 1), "across": round(L[(ia + 1) % 4], 1),
|
||
"rotation_deg": round(math.degrees(math.atan2(vx, vy)), 3), "src": f"D1 평면 {h}"}
|
||
|
||
|
||
# pads (outer 750 x 750 of three nested rectangles); NO.1-5 lower row (front, y < 0) left -> right, NO.6-10 upper row
|
||
outer = {10: "2989", 9: "298C", 8: "298F", 7: "2992", 6: "2995", 5: "2998", 4: "299B", 3: "299E", 2: "29A1", 1: "29A4"}
|
||
out["pads_outer"] = {no: rect(h) for no, h in outer.items()}
|
||
# pedestals: axis-aligned rectangles 1,300 (X) x 2,397 (Y), one per bearing station (both rows)
|
||
peds = []
|
||
for x0, x1 in ((29278.3, 30578.3), (31785.2, 33085.2), (34292.2, 35592.2), (36799.1, 38099.1), (39305.9, 40605.9)):
|
||
peds.append({"x": [round(x0 - PCX, 1), round(x1 - PCX, 1)], "y": [round(54236.9 - PCY, 1), round(56633.6 - PCY, 1)],
|
||
"src": "D1 평면 대좌 28D6~28F9"})
|
||
out["pedestals"] = peds
|
||
p = Path(__file__).resolve().parent / "판독" / "g1_values.json"
|
||
p.write_text(json.dumps(out, ensure_ascii=False, indent=1), encoding="utf-8")
|
||
print(json.dumps({k: v for k, v in out.items() if k not in ("pads_outer", "pedestals")}, ensure_ascii=False)[:1800])
|
||
print({k: (v["centre"], v["along"], v["across"], v["rotation_deg"]) for k, v in out["pads_outer"].items()})
|