- 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
3.1 KiB
Python
73 lines
3.1 KiB
Python
#! python3
|
|
# capture the hook of one hooked bar (Front view) and project key points: arc start / centre / arc end / tail end, leg end
|
|
import os, json, math, traceback
|
|
import Rhino
|
|
import Rhino.Geometry as rg
|
|
import System
|
|
import System.Drawing
|
|
|
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
cfg = json.load(open(os.path.join(HERE, "hook_cfg.json"), encoding="utf-8"))
|
|
res = {"key": cfg["key"]}
|
|
try:
|
|
doc = Rhino.RhinoDoc.ActiveDoc
|
|
st = Rhino.DocObjects.ObjectEnumeratorSettings()
|
|
st.HiddenObjects = True; st.LockedObjects = True; st.NormalObjects = True
|
|
for l in doc.Layers:
|
|
if not l.IsDeleted:
|
|
doc.Layers.ForceLayerVisible(l.Index)
|
|
objs = list(doc.Objects.GetObjectList(st))
|
|
pipe = [o for o in objs if o.Attributes.Name == cfg["pipe"]][0]
|
|
cen = [o for o in objs if o.Attributes.Name == cfg["curve"]][0]
|
|
# optional pile solids for context
|
|
ctx = []
|
|
if cfg.get("show_pile"):
|
|
for o in objs:
|
|
if o.Attributes.Name in ("P1-PL01", "P1-PL02"):
|
|
ctx.append(o.Id)
|
|
for o in objs:
|
|
if o.Id == pipe.Id or o.Id in ctx:
|
|
doc.Objects.Show(o, True)
|
|
else:
|
|
doc.Objects.Hide(o, True)
|
|
c = cen.Geometry
|
|
n = c.SegmentCount
|
|
hook = c.SegmentCurve(n - 2)
|
|
tail = c.SegmentCurve(n - 1)
|
|
ok, arc = hook.TryGetArc()
|
|
leg = c.SegmentCurve(0)
|
|
pts = {"arc_start": hook.PointAtStart, "arc_end": hook.PointAtEnd, "center": arc.Center, "tail_end": tail.PointAtEnd, "leg_end": leg.PointAtStart,
|
|
"vertex": c.SegmentCurve(1).PointAtEnd}
|
|
view = doc.Views.ActiveView
|
|
vp = view.ActiveViewport
|
|
vp.SetProjection(Rhino.Display.DefinedViewportProjection.Front, "Front", False)
|
|
vp.DisplayMode = Rhino.Display.DisplayModeDescription.FindByName("Ghosted") or vp.DisplayMode
|
|
bb = rg.BoundingBox.Empty
|
|
for p in (arc.Center, hook.PointAtStart, hook.PointAtEnd, tail.PointAtEnd):
|
|
bb.Union(p)
|
|
bb.Inflate(120.0)
|
|
vp.ZoomBoundingBox(bb)
|
|
view.Redraw()
|
|
Rhino.RhinoApp.Wait()
|
|
cw, ch = vp.Size.Width, vp.Size.Height
|
|
W = 1500
|
|
H = int(round(W * ch / float(cw)))
|
|
sc = W / float(cw)
|
|
bmp = view.CaptureToBitmap(System.Drawing.Size(W, H))
|
|
png = os.path.join(cfg["out"], "%s.png" % cfg["key"])
|
|
bmp.Save(png, System.Drawing.Imaging.ImageFormat.Png)
|
|
def px(p):
|
|
q = vp.WorldToClient(p)
|
|
return [q.X * sc, q.Y * sc]
|
|
res.update({"png": png, "size": [bmp.Width, bmp.Height], "px": {k: px(v) for k, v in pts.items()},
|
|
"radius": arc.Radius, "angle_deg": math.degrees(arc.Angle), "arc_len": arc.Radius * arc.Angle, "tail_len": tail.GetLength(),
|
|
"pxmm": (px(rg.Point3d(pts["center"].X + 100, pts["center"].Y, pts["center"].Z))[0] - px(pts["center"])[0]) / 100.0})
|
|
except Exception:
|
|
res["error"] = traceback.format_exc()
|
|
res["done"] = True
|
|
json.dump(res, open(os.path.join(cfg["out"], "%s_capture.json" % cfg["key"]), "w", encoding="utf-8"), ensure_ascii=False, indent=1)
|
|
try:
|
|
Rhino.RhinoDoc.ActiveDoc.Modified = False
|
|
except Exception:
|
|
pass
|