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,186 @@
|
||||
"""G3 stage: footing rebar B1-B12 (centreline + pipe solid) from params `footing_rebar`.
|
||||
|
||||
Run inside Rhino 8 via runner (globals PARAMS_PATH) after concrete.py.
|
||||
Ported from Code/교각모델링/build_footing_rebar_rhino.py (Ungok P1, model v0.1.09).
|
||||
Rules: 설계서 v0.1.06 §6 (HITL F1-F3 approved 2026-10-07). z in params is above the footing bottom.
|
||||
`design_length` = schedule original length (a, a+2b, 2(a+b), a+b+c); curve length is measured separately.
|
||||
"""
|
||||
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"]
|
||||
FB = P["footing"]["z_bottom"]
|
||||
MARK = {m: (v["dia"], v["shape"]) for m, v in P["rebar_marks"].items() if m.startswith("B")}
|
||||
DIA = {d: float(d[1:]) for d, _ in MARK.values()} # 'S25' -> 25.0
|
||||
CL_RGB = tuple(P["display"]["centreline_colour"])
|
||||
FT_RGB = tuple(P["display"]["footing_layer_colour"])
|
||||
LEGS = P["footing_rebar"]["legs"]
|
||||
|
||||
|
||||
def leg(mark):
|
||||
"""Signed end-leg length of a footing bar mark (+ up / - down) from params `legs`."""
|
||||
v = LEGS[mark]
|
||||
n = v.get("leg", v.get("hook"))
|
||||
return n if v["dir"].startswith("up") else -n
|
||||
|
||||
|
||||
def layer(path, color):
|
||||
parent = -1
|
||||
parts = path.split("::")
|
||||
for i in range(1, len(parts) + 1):
|
||||
sub = "::".join(parts[:i])
|
||||
idx = doc.Layers.FindByFullPath(sub, -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_r(dia):
|
||||
d = DIA[dia]
|
||||
return ((2 * d if d <= 16 else 3.5 * d) + d) / 2 # box rule (REBAR_BENDS_20260914)
|
||||
|
||||
|
||||
def poly(pts, dia):
|
||||
pl = rg.PolylineCurve([rg.Point3d(*p) for p in pts])
|
||||
if len(pts) < 3:
|
||||
return pl
|
||||
f = rg.Curve.CreateFilletCornersCurve(pl, min_r(dia), TOL, math.radians(1))
|
||||
return f or pl
|
||||
|
||||
|
||||
def add_bar(curve, mark, occ, design_len, src):
|
||||
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}-FT", anchor_hosts="",
|
||||
design_length=f"{design_len:.3f}", coupler_length="0.000", src=src)
|
||||
for geo, lay, prefix in ((curve, layer(f"{PID}::철근::중심선", CL_RGB), f"{PID}-RC"),
|
||||
(pipes[0], layer(f"{PID}::철근::기초::{mark}", FT_RGB), 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)
|
||||
(doc.Objects.AddBrep if isinstance(geo, rg.Brep) else doc.Objects.AddCurve)(geo, attr)
|
||||
|
||||
|
||||
def bar_y(x, z, a, end, dz):
|
||||
"""Bar along Y (length a) at x, height z; end legs of length dz (+up / -down) or none."""
|
||||
h = a / 2
|
||||
if not end:
|
||||
return [(x, -h, z), (x, h, z)]
|
||||
return [(x, -h, z + dz), (x, -h, z), (x, h, z), (x, h, z + dz)]
|
||||
|
||||
|
||||
def bar_x(y, z, a, end, dz):
|
||||
h = a / 2
|
||||
if not end:
|
||||
return [(-h, y, z), (h, y, z)]
|
||||
return [(-h, y, z + dz), (-h, y, z), (h, y, z), (h, y, z + dz)]
|
||||
|
||||
|
||||
def sched(m):
|
||||
row = P["footing_rebar"]["schedule"][m]
|
||||
nums = [float(t) for t in row[3:] if t.replace(".", "", 1).isdigit()]
|
||||
return row, nums
|
||||
|
||||
|
||||
def mm(v):
|
||||
return v * 1000 if v < 100 else v
|
||||
|
||||
|
||||
def main():
|
||||
for o in list(doc.Objects):
|
||||
oid = o.Attributes.GetUserString("id") or ""
|
||||
if oid.startswith((f"{PID}-R-B", f"{PID}-RC-B")):
|
||||
doc.Objects.Delete(o, True)
|
||||
fr = P["footing_rebar"]
|
||||
L = fr["layers"]
|
||||
n = 0
|
||||
a_y, a_x = fr["a_y"], fr["a_x"] # D3 a of Y-bars (B1-B4, B12) / X-bars (B5-B8, B11)
|
||||
# bottom layer 1 (Y): B2 U (legs up) at the outermost positions and alternate from the next; B4 straight
|
||||
pos = L["bottom_Y1"]["pos"]
|
||||
edge = max(abs(x) for x in pos)
|
||||
inner = [x for x in pos if abs(x) != edge]
|
||||
for i, x in enumerate(pos):
|
||||
mark = "B2" if abs(x) == edge or inner.index(x) % 2 == 0 else "B4"
|
||||
z = FB + L["bottom_Y1"]["z"]
|
||||
if mark == "B2":
|
||||
c, dl = poly(bar_y(x, z, a_y, True, leg("B2")), MARK["B2"][0]), a_y + 2 * abs(leg("B2"))
|
||||
else:
|
||||
c, dl = poly(bar_y(x, z, a_y, False, 0), MARK["B4"][0]), a_y
|
||||
add_bar(c, mark, f"x{x:+.0f}", dl, "D1 정면도 하면 점 z122 / D1·D2 '70@125=8.750'")
|
||||
n += 1
|
||||
pos = L["bottom_X2"]["pos"]
|
||||
edge = max(abs(y) for y in pos)
|
||||
inner = [y for y in pos if abs(y) != edge]
|
||||
for y in pos:
|
||||
mark = "B6" if abs(y) == edge or inner.index(y) % 2 == 0 else "B8"
|
||||
z = FB + L["bottom_X2"]["z"]
|
||||
if mark == "B6":
|
||||
c, dl = poly(bar_x(y, z, a_x, True, leg("B6")), MARK["B6"][0]), a_x + 2 * abs(leg("B6"))
|
||||
else:
|
||||
c, dl = poly(bar_x(y, z, a_x, False, 0), MARK["B8"][0]), a_x
|
||||
add_bar(c, mark, f"y{y:+.0f}", dl, "D1 단면도 하면 점 z178 / D1 '58@125=7.250'")
|
||||
n += 1
|
||||
for key, mark, axis, a in (("bottom_Y3", "B3", "Y", a_y), ("bottom_X4", "B7", "X", a_x),
|
||||
("top_Y", "B1", "Y", a_y), ("top_X", "B5", "X", a_x)):
|
||||
z, dz, dia = FB + L[key]["z"], leg(mark), MARK[mark][0]
|
||||
for v in L[key]["pos"]:
|
||||
pts = bar_y(v, z, a, True, dz) if axis == "Y" else bar_x(v, z, a, True, dz)
|
||||
add_bar(poly(pts, dia), mark, f"{axis.lower()}{v:+.0f}", a + 2 * abs(dz),
|
||||
f"D1 {'정면도' if axis == 'Y' else '단면도'} 점 z{L[key]['z']}")
|
||||
n += 1
|
||||
for key, mark, axis, a in (("mid_X", "B11", "X", a_x), ("mid_Y", "B12", "Y", a_y)):
|
||||
for zs, vs in L[key]["levels"].items():
|
||||
z = FB + float(zs)
|
||||
dz = leg(mark)
|
||||
for v in vs:
|
||||
pts = bar_y(v, z, a, True, dz) if axis == "Y" else bar_x(v, z, a, True, dz)
|
||||
add_bar(poly(pts, MARK[mark][0]), mark, f"z{float(zs):.0f}{axis.lower()}{v:+.0f}", a + 2 * abs(dz),
|
||||
f"D1 {'정면도' if axis == 'Y' else '단면도'} 중앙 점 z{zs}")
|
||||
n += 1
|
||||
b10 = fr["b10"]
|
||||
hx, hy = b10["size_x"] / 2, b10["size_y"] / 2
|
||||
for k, zs in enumerate(b10["levels"]):
|
||||
z = FB + zs
|
||||
pts = [(-hx, 0, z), (-hx, -hy, z), (hx, -hy, z), (hx, hy, z), (-hx, hy, z), (-hx, 0.0, z)]
|
||||
c = poly(pts, MARK["B10"][0])
|
||||
add_bar(c, "B10", f"z{zs}", 2 * (b10["size_x"] + b10["size_y"]),
|
||||
"D1 정면도 '150','9@200'; D3 B10 9.198x7.644 (closed, start/end at -X mid side)")
|
||||
n += 1
|
||||
b9 = fr["b9"]
|
||||
rc = b9["c"] / math.pi # 180-degree hook developed length = c
|
||||
for i, x in enumerate(b9["grid_x"]):
|
||||
for j, y in enumerate(b9["grid_y"]):
|
||||
if (i + j) % 2 != b9["checker_parity"]:
|
||||
continue
|
||||
z0, z1 = FB + b9["z0"], FB + b9["z0"] + b9["a"]
|
||||
base = poly([(x + b9["b"], y, z0), (x, y, z0), (x, y, z1)], MARK["B9"][0])
|
||||
top = rg.ArcCurve(rg.Arc(rg.Point3d(x, y, z1), rg.Point3d(x + rc, y, z1 + rc),
|
||||
rg.Point3d(x + 2 * rc, y, z1)))
|
||||
c = rg.Curve.JoinCurves([base, top], TOL)[0]
|
||||
add_bar(c, "B9", f"x{x:+.0f}y{y:+.0f}", b9["a"] + b9["b"] + b9["c"],
|
||||
"D1 EREC grid @250 checker (i+j even) [추론]; count 493 [역산]")
|
||||
n += 1
|
||||
doc.Views.Redraw()
|
||||
print(json.dumps({"footing_bars": n}))
|
||||
|
||||
|
||||
main()
|
||||
Reference in new issue
Block a user