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

+165
View File
@@ -0,0 +1,165 @@
"""운곡교 '대조표_C1-C16_도면모델_분류_V2.xlsx' 형식(분류 안내 / ① 도면↔모델 불일치(+캡처) / ② 전체 대조표 / ③ 미검토 / ④ 측정 근거)으로
교량별 검토 엑셀을 만든다. 사용: python -I make_review_xlsx.py <cfg.json> <out.xlsx>
cfg: bridge, title, purpose, legend_counts(자동), items[{code,mark,content,cmp,diff,drawing_side,action,kind,image}],
rows[{no,mark,item,table,detail,model,verdict,note,kind}], unchecked[{item,content,note,status}], basis[{item,content,note}]
도면 내부 불일치는 이 엑셀에 넣지 않는다(별도 보관 파일).
"""
import sys, json, os
sys.path.insert(0, r"C:\Users\User\AppData\Local\Temp\claude\D--Rhino-MCP-rhino-mcp-main\f46b47bc-9105-4079-9b62-fcbee31b26ae\scratchpad\pylib")
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.drawing.image import Image as XImage
from openpyxl.utils import get_column_letter
from PIL import Image as PImage
cfg = json.load(open(sys.argv[1], encoding="utf-8"))
OUT = sys.argv[2]
thin = Side(style="thin", color="999999")
BR = Border(left=thin, right=thin, top=thin, bottom=thin)
HF = PatternFill("solid", fgColor="D9D9D9")
FILL = {"도면↔모델": PatternFill("solid", fgColor="F8CBAD"), "기준↔모델": PatternFill("solid", fgColor="E6C84A"),
"도면 내부": PatternFill("solid", fgColor="FFF2CC"), "일치": PatternFill("solid", fgColor="E2F0D9"),
"미확인": PatternFill("solid", fgColor="D9D9D9")}
TOPW = Alignment(wrap_text=True, vertical="top")
CEN = Alignment(wrap_text=True, vertical="center", horizontal="center")
wb = Workbook()
# ------------------------------------------------ 분류 안내
ws = wb.active
ws.title = "분류 안내"
ws.append([cfg["title"]])
ws["A1"].font = Font(bold=True, size=14)
ws.append([cfg["purpose"]])
ws["A2"].alignment = TOPW
ws.merge_cells("A2:E2")
ws.row_dimensions[2].height = 64
ws.append([])
ws.append(["색", "구분", "뜻", "항목 수", "볼 시트"])
for c in range(1, 6):
ws.cell(row=4, column=c).font = Font(bold=True)
ws.cell(row=4, column=c).fill = HF
ws.cell(row=4, column=c).border = BR
cnt = {}
for r in cfg["rows"]:
cnt[r["kind"]] = cnt.get(r["kind"], 0) + 1
legend = [("주황", "도면↔모델", "도면에는 정보가 있거나 없는데 모델이 다르게 만들어졌거나 가정한 것 (모델 확인·수정 대상)", "① 도면↔모델 불일치"),
("진한 노랑", "기준↔모델", "설계기준(KDS 24 14 21)에 모델이 맞는지 (도면에는 정보 없음)", "① 도면↔모델 불일치"),
("초록", "일치", "도면(재료표·철근상세)과 모델이 일치", "② 전체 대조표"),
("회색", "미확인", "도면에 정보가 없어 확인하지 못한 것", "② 전체 대조표 · ③")]
for col, kind, mean, sheet in legend:
n = len([i for i in cfg["items"] if i["kind"] == kind]) if kind in ("도면↔모델", "기준↔모델") else cnt.get(kind, 0)
ws.append([col, kind, mean, str(n), sheet])
r = ws.max_row
ws.cell(row=r, column=2).fill = FILL[kind]
for c in range(1, 6):
ws.cell(row=r, column=c).border = BR
ws.cell(row=r, column=c).alignment = TOPW
ws.row_dimensions[r].height = 40
ws.append([])
ws.append(["※ 도면 내부 불일치(도면끼리 다른 것)는 이 파일에 넣지 않고 '도면내부_오류_보관.md' 에 따로 보관 — 요청 시 보고."])
ws.append(["※ ② 전체 대조표의 구분 열은 마크 행 수 기준, ① 의 항목 수는 코드(M-n) 수 기준."])
for i, w in enumerate([12, 14, 80, 10, 26], 1):
ws.column_dimensions[get_column_letter(i)].width = w
# ------------------------------------------------ ① 도면↔모델 불일치
w1 = wb.create_sheet("① 도면↔모델 불일치")
w1.append(["① 도면 ↔ 모델 불일치 (최우선 확인) — 주황 / 진한 노랑 / 회색"])
w1["A1"].font = Font(bold=True, size=13)
w1.append([cfg["sheet1_desc"]])
w1["A2"].alignment = TOPW
w1.merge_cells("A2:I2")
w1.row_dimensions[2].height = 48
w1.append([])
heads = ["번호", "마크", "내용", "비교", "차이 크기", "도면 쪽 상태", "확인·조치 필요 사항", "구분", "캡처 (왼쪽·위 도면 / 오른쪽·아래 모델)"]
w1.append(heads)
for c in range(1, 10):
cell = w1.cell(row=4, column=c)
cell.font = Font(bold=True)
cell.fill = HF
cell.border = BR
cell.alignment = CEN
w1.row_dimensions[4].height = 30
MAXH = 520
for it in cfg["items"]:
w1.append([it["code"], it["mark"], it["content"], it["cmp"], it["diff"], it["drawing_side"], it["action"], it["kind"], None])
r = w1.max_row
for c in range(1, 9):
cell = w1.cell(row=r, column=c)
cell.border = BR
cell.alignment = TOPW
w1.cell(row=r, column=8).fill = FILL[it["kind"]]
w1.cell(row=r, column=1).font = Font(bold=True)
if it.get("image") and os.path.exists(it["image"]):
im = PImage.open(it["image"])
h = MAXH
w = int(im.width * h / im.height)
xi = XImage(it["image"])
xi.width, xi.height = w, h
w1.add_image(xi, "I%d" % r)
w1.row_dimensions[r].height = h * 0.75 + 6
w1.column_dimensions["I"].width = max(w1.column_dimensions["I"].width or 0, w / 7.0)
w1.cell(row=r, column=9).border = BR
for i, w in enumerate([8, 12, 62, 24, 26, 34, 52, 12], 1):
w1.column_dimensions[get_column_letter(i)].width = w
w1.freeze_panes = "A5"
# ------------------------------------------------ ② 전체 대조표
w2 = wb.create_sheet("② 전체 대조표")
w2.append(["② 도면(재료표·철근상세) · 라이노 모델 대조표 — 전 마크"])
w2["A1"].font = Font(bold=True, size=13)
w2.append(["구분 열 색: 초록=일치 / 주황=도면↔모델 / 진한 노랑=기준↔모델 / 회색=미확인. 모델 치수는 중심선 꼭짓점 사이 거리(각진 치수), 길이는 모델 철근의 설계길이(user string)."])
w2.append([])
h2 = ["번호", "마크", "검토 항목", "도면 재료표 (L × N = 총길이)", "도면 철근상세 (치수)", "라이노 모델", "판정", "비고 / 근거", "구분"]
w2.append(h2)
for c in range(1, 10):
cell = w2.cell(row=4, column=c)
cell.font = Font(bold=True)
cell.fill = HF
cell.border = BR
cell.alignment = CEN
for r_ in cfg["rows"]:
w2.append([r_["no"], r_["mark"], r_["item"], r_["table"], r_["detail"], r_["model"], r_["verdict"], r_["note"], r_["kind"]])
r = w2.max_row
for c in range(1, 10):
cell = w2.cell(row=r, column=c)
cell.border = BR
cell.alignment = TOPW
w2.cell(row=r, column=9).fill = FILL[r_["kind"]]
n = max(len(str(r_["note"])) / 40.0, len(str(r_["model"])) / 34.0, len(str(r_["detail"])) / 30.0, 1)
w2.row_dimensions[r].height = max(32, 17 * (int(n) + 1))
for i, w in enumerate([6, 9, 26, 30, 32, 38, 14, 52, 12], 1):
w2.column_dimensions[get_column_letter(i)].width = w
w2.freeze_panes = "C5"
# ------------------------------------------------ ③ 미검토
w3 = wb.create_sheet("③ 미검토·확인 불가")
w3.append(["항목", "내용", "비고", "상태"])
for c in range(1, 5):
w3.cell(row=1, column=c).font = Font(bold=True)
w3.cell(row=1, column=c).fill = HF
for u in cfg["unchecked"]:
w3.append([u["item"], u["content"], u["note"], u["status"]])
for c in range(1, 5):
w3.cell(row=w3.max_row, column=c).alignment = TOPW
w3.row_dimensions[w3.max_row].height = 50
for i, w in enumerate([22, 80, 40, 12], 1):
w3.column_dimensions[get_column_letter(i)].width = w
# ------------------------------------------------ ④ 측정 근거
w4 = wb.create_sheet("④ 측정 근거")
w4.append(["항목", "측정/내용", "비고"])
for c in range(1, 4):
w4.cell(row=1, column=c).font = Font(bold=True)
w4.cell(row=1, column=c).fill = HF
for b in cfg["basis"]:
w4.append([b["item"], b["content"], b.get("note", "")])
for c in range(1, 4):
w4.cell(row=w4.max_row, column=c).alignment = TOPW
w4.row_dimensions[w4.max_row].height = 48
for i, w in enumerate([30, 95, 52], 1):
w4.column_dimensions[get_column_letter(i)].width = w
try:
wb.save(OUT)
print("saved", OUT)
except PermissionError:
print("열려 있어 저장 실패:", OUT)