- 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>
62 lines
3.4 KiB
Python
62 lines
3.4 KiB
Python
#! python3
|
|
# read-only: centre-line key points and a, b, c, d, r of Ramp-A P3-1 / P3 (one bar each) in world and 2D (bar-plane) coordinates
|
|
import sys, os, json, math, traceback
|
|
sys.path.insert(0, r"C:\Users\User\AppData\Local\PierApp\jobs\c1_work")
|
|
import Rhino
|
|
import Rhino.Geometry as rg
|
|
from Rhino.Geometry.Intersect import Intersection
|
|
from c1_core import BASE
|
|
|
|
P = os.path.join(BASE, "Ramp-A교P1", "ramp-A G5_수정5_20261026.3dm")
|
|
OUT = r"C:\Users\User\AppData\Local\PierApp\jobs\c1_work\c1_hook_coords.json"
|
|
NAMES = ["P1-RC-P3-1-L01X", "P1-RC-P3-L01X"]
|
|
res = {}
|
|
try:
|
|
doc = Rhino.RhinoDoc.OpenHeadless(P)
|
|
st = Rhino.DocObjects.ObjectEnumeratorSettings()
|
|
st.HiddenObjects = True; st.LockedObjects = True; st.NormalObjects = True
|
|
objs = {o.Attributes.Name: o for o in doc.Objects.GetObjectList(st) if isinstance(o.Geometry, rg.Curve)}
|
|
for nm in NAMES:
|
|
c = objs[nm].Geometry
|
|
n = c.SegmentCount
|
|
s0, s1, s2, s3, s4 = [c.SegmentCurve(i) for i in range(5)]
|
|
l0 = rg.Line(s0.PointAtStart, s0.PointAtEnd)
|
|
l2 = rg.Line(s2.PointAtStart, s2.PointAtEnd)
|
|
ok, ta, tb = Intersection.LineLine(l0, l2)
|
|
V = l0.PointAt(ta) # vertex (leg line x horizontal line)
|
|
okh, arc = s3.TryGetArc()
|
|
oks, arc1 = s1.TryGetArc()
|
|
# 2D frame: origin = vertex V, u = along the horizontal run (towards the hook), v = up (z)
|
|
u = s2.PointAtEnd - s2.PointAtStart
|
|
u.Unitize()
|
|
v = rg.Vector3d(0, 0, 1)
|
|
def d2(p):
|
|
w = p - V
|
|
return [round(w * u, 2), round(w * v, 2)]
|
|
def wd(p):
|
|
return [round(p.X, 2), round(p.Y, 2), round(p.Z, 2)]
|
|
pts = {
|
|
"①_다리_끝(leg end)": s0.PointAtStart,
|
|
"②_꼭짓점(leg line x horizontal line)": V,
|
|
"③_모서리호_시작": s1.PointAtStart,
|
|
"④_모서리호_끝=수평선_시작": s1.PointAtEnd,
|
|
"⑤_갈고리호_시작(수평선_끝)": s3.PointAtStart,
|
|
"⑥_갈고리호_중심": arc.Center,
|
|
"⑦_갈고리호_끝=곧은구간_시작": s3.PointAtEnd,
|
|
"⑧_곧은구간_끝": s4.PointAtEnd,
|
|
}
|
|
out = {"bar_world_u_direction": [round(u.X, 4), round(u.Y, 4), round(u.Z, 4)],
|
|
"dims": {"a(다리: 끝~꼭짓점)": round(s0.PointAtStart.DistanceTo(V), 2), "b(꼭짓점~갈고리호 시작)": round(V.DistanceTo(s3.PointAtStart), 2),
|
|
"r(갈고리호 반지름, 중심선)": round(arc.Radius, 2), "호 각도(deg)": round(math.degrees(arc.Angle), 2),
|
|
"c(갈고리호 길이)": round(arc.Radius * arc.Angle, 2), "d(곧은 구간)": round(s4.GetLength(), 2),
|
|
"모서리호 반지름": round(arc1.Radius, 2), "모서리호 각도": round(math.degrees(arc1.Angle), 2),
|
|
"중심선 전체 길이": round(c.GetLength(), 2)},
|
|
"d_direction(곧은구간 방향 단위벡터 u,v)": [round(((s4.PointAtEnd - s4.PointAtStart) * u) / s4.GetLength(), 4), round(((s4.PointAtEnd - s4.PointAtStart) * v) / s4.GetLength(), 4)],
|
|
"points": {k: {"world": wd(p), "2D(u,v)": d2(p)} for k, p in pts.items()}}
|
|
res[nm] = out
|
|
doc.Dispose()
|
|
except Exception:
|
|
res["error"] = traceback.format_exc()
|
|
res["done"] = True
|
|
json.dump(res, open(OUT, "w", encoding="utf-8"), ensure_ascii=False, indent=1)
|