chore(rebar): Pier_T_rebar 작업 폴더 초기 구성 및 외부 의존 파일 통합
- 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>
This commit is contained in:
commit
964a841de1
3978 files changed
+58013356
No files matched your search
@@ -0,0 +1,180 @@
|
||||
"""G3 stage, form "shaft cage" (Ramp-A P1, 2026-10-13): drilled-shaft reinforcement cage (no footing). Straight main
|
||||
bars in two pieces joined by couplers (upper / lower mark), lapped half-ring hoops with 135-deg hooks, X / Y cross
|
||||
ties, bottom U bars in vertical planes through the centre, and the anti-uplift plate under them.
|
||||
|
||||
Run inside Rhino 8 via runner (globals PARAMS_PATH) after the G1 / G2 builders. Units mm, Z = EL x 1000.
|
||||
params shaft_rebar:
|
||||
main {count, start_deg, radius, pieces: [{mark, z0, z1}, ...] bottom to top, coupler_length}
|
||||
hoops {mark, radius, levels, a, lap, hook, join_deg [first, second]} joins alternate per level (S5)
|
||||
ties {mark, levels, straight, leg, hook_tail, y_lift} as column_rebar_straight.py (S5)
|
||||
u_bars {mark, count, z_bottom, half_bottom, half_top, leg_top_z, top_z, bend_r} one U per plane at main-bar angle
|
||||
i (i < count): bottom +-half_bottom at z_bottom, sloped legs to +-half_top at leg_top_z, vertical to top_z (S3)
|
||||
plate {size, thickness, z_top, colour} square, centred (S4)
|
||||
design_lengths {mark: schedule-style original length per piece}
|
||||
Bars below the pile segment boundary are hosted by the lower pile segment, above it by the upper one.
|
||||
"""
|
||||
import json
|
||||
import math
|
||||
|
||||
import Rhino
|
||||
import Rhino.Geometry as rg
|
||||
from Rhino.DocObjects import ObjectAttributes, ObjectColorSource
|
||||
from System.Drawing import Color
|
||||
|
||||
P = json.load(open(PARAMS_PATH, encoding="utf-8"))
|
||||
doc = __rhino_doc__
|
||||
TOL = 0.01
|
||||
PID = P["pier_id"]
|
||||
MARK = {m: (v["dia"], v["shape"]) for m, v in P["rebar_marks"].items()}
|
||||
DIA = {d: float(d[1:]) for d, _ in MARK.values()}
|
||||
CL_RGB = tuple(P["display"]["centreline_colour"])
|
||||
SEGS = P["pile"]["segments"]
|
||||
|
||||
|
||||
def layer(path, color):
|
||||
parent = -1
|
||||
parts = path.split("::")
|
||||
for i in range(1, len(parts) + 1):
|
||||
idx = doc.Layers.FindByFullPath("::".join(parts[:i]), -1)
|
||||
if idx < 0:
|
||||
lay = Rhino.DocObjects.Layer()
|
||||
lay.Name, lay.Color = parts[i - 1], Color.FromArgb(*color)
|
||||
if parent >= 0:
|
||||
lay.ParentLayerId = doc.Layers[parent].Id
|
||||
idx = doc.Layers.Add(lay)
|
||||
parent = idx
|
||||
return parent
|
||||
|
||||
|
||||
def min_bend_radius(dia_name):
|
||||
d = DIA[dia_name]
|
||||
return ((2 * d if d <= 16 else 3.5 * d) + d) / 2
|
||||
|
||||
|
||||
def host(z):
|
||||
for i, s in enumerate(SEGS, 1):
|
||||
if s["z0"] <= z <= s["z1"]:
|
||||
return f"{PID}-PL{i:02d}"
|
||||
return ""
|
||||
|
||||
|
||||
def add_bar(curve, mark, occ, design_len, src, coupler=0.0):
|
||||
dia, shape = MARK[mark]
|
||||
pipes = rg.Brep.CreatePipe(curve, DIA[dia] / 2, False, rg.PipeCapMode.Flat, False, TOL, math.radians(1))
|
||||
if not pipes or not pipes[0].IsSolid:
|
||||
raise RuntimeError(f"{mark} {occ}: pipe failed")
|
||||
bb = curve.GetBoundingBox(True)
|
||||
common = dict(mark=mark, dia=dia, shape=shape, occurrence=occ, host=host((bb.Min.Z + bb.Max.Z) / 2),
|
||||
anchor_hosts="", design_length=f"{design_len:.3f}", coupler_length=f"{coupler:.3f}", src=src)
|
||||
for geo, lay, prefix in ((curve, layer(f"{PID}::철근::중심선", CL_RGB), f"{PID}-RC"),
|
||||
(pipes[0], layer(f"{PID}::철근::말뚝::{mark}", (110, 110, 110)), f"{PID}-R")):
|
||||
attr = ObjectAttributes()
|
||||
attr.LayerIndex = lay
|
||||
oid = f"{prefix}-{mark}-{occ}"
|
||||
attr.Name = oid
|
||||
attr.SetUserString("id", oid)
|
||||
for k, v in common.items():
|
||||
attr.SetUserString(k, v)
|
||||
gid = doc.Objects.AddBrep(geo, attr) if isinstance(geo, rg.Brep) else doc.Objects.AddCurve(geo, attr)
|
||||
if gid == __import__("System").Guid.Empty:
|
||||
raise RuntimeError(f"{oid}: add failed")
|
||||
|
||||
|
||||
def pt(r, deg, z):
|
||||
t = math.radians(deg)
|
||||
return rg.Point3d(r * math.cos(t), r * math.sin(t), z)
|
||||
|
||||
|
||||
def hooked_arc(r, a0, a1, z, hook, bend_r):
|
||||
"""Arc a0 -> a1 (deg, ccw) with inward 135-deg hooks at both ends, fillet bend_r (as column_rebar_ring.py)."""
|
||||
arc = rg.ArcCurve(rg.Arc(pt(r, a0, z), pt(r, (a0 + a1) / 2, z), pt(r, a1, z)))
|
||||
pieces = []
|
||||
for at_start in (True, False):
|
||||
p = arc.PointAtStart if at_start else arc.PointAtEnd
|
||||
t = -arc.TangentAtStart if at_start else arc.TangentAtEnd
|
||||
n = rg.Vector3d(-p.X, -p.Y, 0)
|
||||
n.Unitize()
|
||||
d = t * math.cos(math.radians(135)) + n * math.sin(math.radians(135))
|
||||
d.Unitize()
|
||||
pieces.append(rg.LineCurve(p, p + d * hook))
|
||||
joined = rg.Curve.JoinCurves([pieces[0], arc, pieces[1]], TOL)[0]
|
||||
return rg.Curve.CreateFilletCornersCurve(joined, bend_r, TOL, math.radians(1)) or joined
|
||||
|
||||
|
||||
def tie_curve(axis, z, half, leg, tail, flip):
|
||||
"""As column_rebar_straight.py: straight part on the X / Y diameter, 90-deg leg down at one end, 135-deg hook."""
|
||||
u = rg.Vector3d(1, 0, 0) if axis == 0 else rg.Vector3d(0, 1, 0)
|
||||
s = -1 if flip else 1
|
||||
a, b = rg.Point3d(0, 0, z) - u * (s * half), rg.Point3d(0, 0, z) + u * (s * half)
|
||||
d = -u * s * math.cos(math.radians(45)) + rg.Vector3d(0, 0, -1) * math.sin(math.radians(45))
|
||||
return rg.PolylineCurve([a + rg.Vector3d(0, 0, -leg), a, b, b + d * tail])
|
||||
|
||||
|
||||
def main():
|
||||
for o in list(doc.Objects):
|
||||
oid = o.Attributes.GetUserString("id") or ""
|
||||
if oid.startswith((f"{PID}-PT",)) or (oid.startswith((f"{PID}-R-", f"{PID}-RC-"))
|
||||
and (o.Attributes.GetUserString("mark") or "") in SR_MARKS):
|
||||
doc.Objects.Delete(o, True)
|
||||
DL = SR["design_lengths"]
|
||||
m, n = SR["main"], 0
|
||||
for i in range(m["count"]):
|
||||
th = m["start_deg"] + i * 360.0 / m["count"]
|
||||
for pc in m["pieces"]:
|
||||
c = rg.LineCurve(pt(m["radius"], th, pc["z0"]), pt(m["radius"], th, pc["z1"]))
|
||||
add_bar(c, pc["mark"], f"{i + 1:02d}", DL[pc["mark"]],
|
||||
f"angle {th:.4f} deg; D4 단면 G-G·J-J 61개; r {m['radius']} (S2); EL {pc['z0'] / 1000:.3f}~{pc['z1'] / 1000:.3f}; "
|
||||
f"커플러 이음 (S6)", coupler=m["coupler_length"])
|
||||
n += 1
|
||||
h = SR["hoops"]
|
||||
r, ext = h["radius"], math.degrees(h["lap"] / 2 / h["radius"])
|
||||
for j, z in enumerate(h["levels"]):
|
||||
a0 = h["join_deg"][j % 2]
|
||||
for q, s in enumerate((a0, a0 + 180)):
|
||||
c = hooked_arc(r, s - ext, s + 180 + ext, z, h["hook"], min_bend_radius(MARK[h["mark"]][0]))
|
||||
add_bar(c, h["mark"], f"L{j + 1:03d}{'ab'[q]}", DL[h["mark"]],
|
||||
f"EL {z / 1000:.3f}; r {r} (S1); 겹이음 {h['lap']:.0f} at {a0}/{a0 + 180} deg (S5 [추론])")
|
||||
n += 1
|
||||
t = SR["ties"]
|
||||
rb = min_bend_radius(MARK[t["mark"]][0])
|
||||
for j, z in enumerate(t["levels"]):
|
||||
for axis, name in ((0, "X"), (1, "Y")):
|
||||
zt = z + (t["y_lift"] if axis == 1 else 0)
|
||||
pl = tie_curve(axis, zt, t["straight"] / 2, t["leg"], t["hook_tail"], flip=(j % 2 == 1))
|
||||
c = rg.Curve.CreateFilletCornersCurve(pl, rb, TOL, math.radians(1)) or pl
|
||||
add_bar(c, t["mark"], f"L{j + 1:02d}{name}", DL[t["mark"]],
|
||||
f"EL {zt / 1000:.3f}; {name} 방향 (S5 [추론])")
|
||||
n += 1
|
||||
u = SR["u_bars"]
|
||||
for i in range(u["count"]):
|
||||
th = m["start_deg"] + i * 360.0 / m["count"]
|
||||
e = rg.Vector3d(math.cos(math.radians(th)), math.sin(math.radians(th)), 0)
|
||||
P0 = lambda s, z: rg.Point3d(0, 0, z) + e * s
|
||||
pl = rg.PolylineCurve([P0(-u["half_top"], u["top_z"]), P0(-u["half_top"], u["leg_top_z"]),
|
||||
P0(-u["half_bottom"], u["z_bottom"]), P0(u["half_bottom"], u["z_bottom"]),
|
||||
P0(u["half_top"], u["leg_top_z"]), P0(u["half_top"], u["top_z"])])
|
||||
c = rg.Curve.CreateFilletCornersCurve(pl, u["bend_r"], TOL, math.radians(1)) or pl
|
||||
add_bar(c, u["mark"], f"{i + 1:02d}", DL[u["mark"]],
|
||||
f"plane {th:.4f} deg through the centre (S3 [추론]); bottom EL {u['z_bottom'] / 1000:.3f}; c {u['top_z'] - u['leg_top_z']:.0f} welded to P1-2")
|
||||
n += 1
|
||||
pt_ = SR["plate"]
|
||||
a = pt_["size"] / 2
|
||||
box = rg.Box(rg.BoundingBox(-a, -a, pt_["z_top"] - pt_["thickness"], a, a, pt_["z_top"])).ToBrep()
|
||||
attr = ObjectAttributes()
|
||||
attr.LayerIndex = layer(f"{PID}::철근::말뚝::PLATE", tuple(pt_["colour"]))
|
||||
attr.ObjectColor = Color.FromArgb(*pt_["colour"])
|
||||
attr.ColorSource = ObjectColorSource.ColorFromObject
|
||||
oid = f"{PID}-PT01"
|
||||
attr.Name = oid
|
||||
for k, v in (("id", oid), ("role", "anti-uplift plate"), ("host", host(pt_["z_top"])),
|
||||
("src", f"D4 떠오름 방지 PLATE {pt_['size']:.0f}x{pt_['size']:.0f}x{pt_['thickness']:.0f}; U형 바닥 아래 (S4 [추론])")):
|
||||
attr.SetUserString(k, v)
|
||||
if doc.Objects.AddBrep(box, attr) == __import__("System").Guid.Empty:
|
||||
raise RuntimeError("plate: add failed")
|
||||
doc.Views.Redraw()
|
||||
print(json.dumps({"bars": n, "plate": 1}))
|
||||
|
||||
|
||||
SR = P["shaft_rebar"]
|
||||
SR_MARKS = {pc["mark"] for pc in SR["main"]["pieces"]} | {SR[k]["mark"] for k in ("hoops", "ties", "u_bars")}
|
||||
main()
|
||||
Reference in new issue
Block a user