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:
ahnyongjooandClaude Sonnet 5.5 committed 2026-10-28 11:20:18 +09:00
commit 964a841de1
3978 files changed
+58013356

No files matched your search

@@ -0,0 +1,85 @@
"""Stage order of the T-pier app and the Rhino step list for a build up to a given gate.
Gates follow the required work order: G1 shape -> G2 column rebar -> G3 footing rebar -> G4 coping rebar
-> G5 sole plates & bearings. A build "up to Gk" always rebuilds G1..Gk in a fresh document, so every
gate model is reproducible from params alone.
Per-pier options (2026-10-13, Ulsan P1 = second T-pier form):
params["scope"] gates modelled for this pier (default all); others are skipped ("범위 밖")
params["builders"] {gate: script} replacing the default builder (e.g. G1 -> concrete_tapered.py)
expected["checkers"] {gate: script} replacing the default checker (e.g. G1 -> g1_tapered.py)
"""
import json
from pathlib import Path
RHINO_DIR = Path(__file__).resolve().parent / "rhino"
GATES = [
("G1", "형상(콘크리트·말뚝·받침대좌·패드)", "concrete.py"),
("G2", "기둥 철근", "column_rebar.py"),
("G3", "확대기초 철근", "footing_rebar.py"),
("G4", "코핑 철근", "coping_rebar.py"),
("G5", "교량받침·솔플레이트", "bearings.py"),
]
CHECKERS = {"G1": "g1_shape.py", "G2": "g2_column_rebar.py", "G3": "g3_footing_rebar.py",
"G4": "g4_coping_rebar.py", "G5": "g5_bearings.py"}
# Object id prefixes created by each gate (after the pier id), used for negative tests and the
# "earlier gates unchanged" fingerprint comparison.
GATE_PREFIXES = {"G1": ["LC", "FT", "CL", "CP", "PL", "BS", "BP"], "G2": ["R-P", "RC-P"], "G3": ["R-B", "RC-B", "PT"],
"G4": ["R-C", "RC-C", "R-S", "RC-S"], "G5": ["BB", "SP"]}
# "PT": shaft cage plate (Ramp-A P1 G3, 2026-10-13). Ramp-A shaft cage bars carry "R-P1-1" etc. (marks P1-1 ...),
# so they fall under the G2 prefixes in the unchanged check; that is harmless (all earlier gates are compared)
REBAR_GATES = {"G2", "G3", "G4"}
TOLERANCE_MM = 0.001
def gate_ids():
return [g for g, _, _ in GATES]
def _json(path):
return json.loads(Path(path).read_text(encoding="utf-8")) if path and Path(path).exists() else {}
def scope_of(params_path):
"""Gates modelled for this pier (params["scope"], default all), in gate order."""
sc = _json(params_path).get("scope")
return [g for g in gate_ids() if not sc or g in sc]
def builder_of(params_path, gate):
default = {g: s for g, _, s in GATES}[gate]
return _json(params_path).get("builders", {}).get(gate, default)
def checker_of(expected_path, gate):
return _json(expected_path).get("checkers", {}).get(gate, CHECKERS[gate])
def build_steps(params_path, upto="G5"):
"""Rhino steps for G1..`upto`: builders, diameter colours after the last rebar stage, display state."""
ids = gate_ids()
if upto not in ids:
raise ValueError(f"unknown gate {upto}")
scope = scope_of(params_path)
chosen = [(g, n, builder_of(params_path, g)) for g, n, _ in GATES[: ids.index(upto) + 1] if g in scope]
glb = {"PARAMS_PATH": str(Path(params_path).resolve())}
steps = []
last_rebar = max((i for i, (g, _, _) in enumerate(chosen) if g in REBAR_GATES), default=None)
for i, (g, _, script) in enumerate(chosen):
steps.append({"name": f"{g}:{script}", "script": RHINO_DIR / script, "globals": dict(glb, GATE=g)})
if i == last_rebar:
steps.append({"name": f"{g}:rebar_colours.py", "script": RHINO_DIR / "rebar_colours.py", "globals": glb})
steps.append({"name": "display.py", "script": RHINO_DIR / "display.py", "globals": glb})
return steps
def check_steps(expected_path, out_dir, gates=None, tag=""):
"""Rhino steps running the gate checkers; each writes <out_dir>/<gate><tag>.json."""
steps = []
for g in gates or gate_ids():
chk = checker_of(expected_path, g)
steps.append({"name": f"{g}:{chk}", "script": RHINO_DIR / "checks" / chk,
"globals": {"EXPECTED_PATH": str(Path(expected_path).resolve()),
"RESULT_PATH": str(Path(out_dir).resolve() / f"{g}{tag}.json")}})
return steps