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,150 @@
|
||||
"""G2 stage, form "straight" (Ramp-A P1, 2026-10-13): column on a drilled shaft, no footing. Straight main bars
|
||||
in one ring (bottom coupler to the shaft cage, not modelled as a solid), lapped half-ring hoops with 135-deg hooks,
|
||||
cross ties in X and Y (90-deg leg at one end, 135-deg hook at the other), from params `column_rebar`.
|
||||
|
||||
Run inside Rhino 8 via runner (globals PARAMS_PATH) after the G1 builder. Units mm, Z = EL x 1000.
|
||||
params column_rebar:
|
||||
main {mark, count, start_deg, radius, z0, z1, coupler_length}
|
||||
hoops {mark, radius, levels, a, lap, hook, join_deg [first, second]} joins alternate per level (K4)
|
||||
ties {mark, levels, straight, leg, hook_tail, y_lift} X tie at the level, Y tie y_lift above (K3);
|
||||
the 90-deg leg (down) and the 135-deg hook swap ends per level (K4)
|
||||
design lengths {mark: schedule-style original length per piece}
|
||||
Hosts for cover / anchorage: below the column bottom = pile top segment, above the column top = coping.
|
||||
"""
|
||||
import json
|
||||
import math
|
||||
|
||||
import Rhino
|
||||
import Rhino.Geometry as rg
|
||||
from Rhino.DocObjects import ObjectAttributes
|
||||
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"])
|
||||
COLORS = {m: tuple(c) for m, c in P["display"].get("column_mark_colours", {}).items()}
|
||||
Z_CL0, Z_CL1 = P["column"]["z0"], P["column"]["z1"]
|
||||
PILE_TOP = f"{PID}-PL{len(P['pile']['segments']):02d}"
|
||||
|
||||
|
||||
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 hosts(z):
|
||||
return PILE_TOP if z < Z_CL0 else (f"{PID}-CP" if z > Z_CL1 else "")
|
||||
|
||||
|
||||
def add_bar(curve, mark, occ, design_len, anchor, 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")
|
||||
common = dict(mark=mark, dia=dia, shape=shape, occurrence=occ, host=f"{PID}-CL", anchor_hosts=anchor,
|
||||
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}", COLORS.get(mark, (200, 140, 90))), 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):
|
||||
"""Straight part on the X (axis 0) or Y (axis 1) diameter at z; 90-deg leg `leg` down at one end, 135-deg hook
|
||||
(tail pointing down and back inwards) at the other; `flip` swaps the ends."""
|
||||
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}-R-P", f"{PID}-RC-P")):
|
||||
doc.Objects.Delete(o, True)
|
||||
cr = P["column_rebar"]
|
||||
DL = cr["design_lengths"]
|
||||
m = cr["main"]
|
||||
n = 0
|
||||
for i in range(m["count"]):
|
||||
th = m["start_deg"] + i * 360.0 / m["count"]
|
||||
c = rg.LineCurve(pt(m["radius"], th, m["z0"]), pt(m["radius"], th, m["z1"]))
|
||||
add_bar(c, m["mark"], f"{i + 1:02d}", DL[m["mark"]], f"{PILE_TOP},{PID}-CP",
|
||||
f"angle {th:.4f} deg; D2 단면 C-C DIVISION {m['count']} r {m['radius']:.0f}; 정면 EL {m['z0'] / 1000:.3f}"
|
||||
f"~{m['z1'] / 1000:.3f}; 하단 커플러 {m['coupler_length']:.0f} (K1)", coupler=m["coupler_length"])
|
||||
n += 1
|
||||
h = cr["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"]], hosts(z),
|
||||
f"EL {z / 1000:.3f}; 겹이음 {h['lap']:.0f} at {a0}/{a0 + 180} deg (K4 [추론])")
|
||||
n += 1
|
||||
t = cr["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"]], hosts(zt),
|
||||
f"EL {zt / 1000:.3f}; {name} 방향{' +' + str(t['y_lift']) + ' (K3 [추론])' if axis else ''}; "
|
||||
f"90° 다리·135° 갈고리 {'좌우 교번' if j % 2 else '기본'} (K4 [추론])")
|
||||
n += 1
|
||||
doc.Views.Redraw()
|
||||
print(json.dumps({"bars": n}))
|
||||
|
||||
|
||||
main()
|
||||
Reference in new issue
Block a user