Files
Pier_v1/Code/검토수정/스크립트/add_hookb_protrude_xlsx.py
T
ahnyongjooandClaude Sonnet 5.5 964a841de1 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>
2026-10-28 11:20:18 +09:00

113 lines
7.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""갈고리 직선 b 보정(R-17)과 Ramp-A P3-1 콘크리트 돌출 오류(M-9)를 엑셀에 반영한다 (2026-10-26).
- 교량별 항목 합본 / 개별 항목: Ramp-A M-9 (P3-1 콘크리트 밖으로 튀어나감) 행
- 수정 내역 R-17, 수정 증거(마크별) 행, 미수정·보류 행, 수정 파일·해시(Ramp-A 수정5, 옥성 수정6 최신)
같은 R-17 이 이미 있으면 중단(이중 적용 방지).
"""
import copy
import datetime
import hashlib
import json
import sys
from pathlib import Path
import openpyxl
from openpyxl.styles import PatternFill
ROOT = Path(r"D:\★Pier 자료\프로그램\Pier_T")
REV = ROOT / "검토파일"
RES = ROOT / "Code" / "검토수정" / "결과"
XLSX = REV / "4개교_공통사항_종합.xlsx"
fx = json.loads((RES / "c1_hook_b_fix.json").read_text(encoding="utf-8"))
pr = json.loads((RES / "c1_protrude_check.json").read_text(encoding="utf-8"))
wb = openpyxl.load_workbook(XLSX)
ws = wb["수정 내역"]
if any(r[0].value == "R-17" for r in ws.iter_rows(min_row=4)):
sys.exit("R-17 이 이미 있음 - 중단")
GREEN = PatternFill("solid", fgColor="FFE2EFDA")
ORANGE = PatternFill("solid", fgColor="FFF8CBAD")
def append_like(sheet, values, like_row):
r = sheet.max_row + 1
for j, v in enumerate(values, 1):
c = sheet.cell(row=r, column=j, value=v)
s = sheet.cell(row=like_row, column=j)
c.font = copy.copy(s.font)
c.fill = copy.copy(s.fill)
c.border = copy.copy(s.border)
c.alignment = copy.copy(s.alignment)
c.number_format = s.number_format
sheet.auto_filter.ref = "A3:%s%d" % (openpyxl.utils.get_column_letter(sheet.max_column), r)
return r
b4, a4 = pr["before(수정2)"]["bars"], pr["after(수정5)"]["bars"]
p5, p3, p31 = fx["okseong"]["sample"]["P5"], fx["rampa"]["sample"]["P3"], fx["rampa"]["sample"]["P3-1"]
n_p5, n_p3, n_p31 = fx["okseong"]["stat"]["P5_done"], fx["rampa"]["stat"]["P3_done"], fx["rampa"]["stat"]["P3-1_done"]
CONTENT = ("Ramp-A교 P3-1(H16, 48본)이 기존 모델에서 콘크리트(기둥) 밖으로 튀어나가 있음 (사용자 지적 2026-10-26). "
"측정(콘크리트 솔리드 기준): 기존 모델 P3-1 중심선이 기둥 표면에 놓여 중심 피복 최소 %.1f mm (< 철근 반지름 8 mm → 파이프가 표면 밖으로 돌출), P3 는 최소 %.1f mm (경미)" %
(b4["P3-1"]["min_centre_cover_inside_mm"], b4["P3"]["min_centre_cover_inside_mm"]))
DIFF = ("기존: P3-1 다리가 기둥 표면 위(중심 피복 0.1). b 보정(R-17) 후 수정5: P3-1 %d본 중 %d본의 갈고리 일부가 콘크리트 밖 (최대 %.0f mm 길이) — 악화" %
(a4["P3-1"]["n"], a4["P3-1"]["bars_with_part_outside_concrete"], a4["P3-1"]["max_outside_length_mm"]))
STATUS = ("미해결: 도면 치수(a 200, b 2,137, r135 c165 d150)대로 만들면 다리가 기둥 표면에 걸리고 갈고리가 밖으로 나감. "
"기둥 단면(콘크리트 외곽)과 P3-1 배치 위치·방향을 도면에서 다시 확인해 위치를 조정해야 함 — 설계자 확인")
# 합본 / 개별
wg = wb["교량별 항목 합본"]
like = next(r[0].row for r in wg.iter_rows(min_row=4) if r[8].value == "도면↔모델")
append_like(wg, ["Ramp-A교", "M-9", "P3-1", CONTENT, "콘크리트 솔리드 ↔ 철근 중심선 (샘플 15 mm 간격)", DIFF,
"도면 상세 P3-1: r135 a200 b2,137 c165 d150 (갈고리 직선). 배치 높이·방향은 도면에 직접 표기 없음 [추론]", STATUS, "도면↔모델 (피복·돌출)", "개별"], like)
wi = wb["개별 항목"]
like_i = next(r[0].row for r in wi.iter_rows(min_row=4) if r[5].value == "도면↔모델")
append_like(wi, ["Ramp-A교", "M-9", "P3-1", CONTENT, DIFF, "도면↔모델 (피복·돌출)", STATUS], like_i)
# 수정 내역
r = append_like(ws, ["R-17", "옥성·Ramp-A", "갈고리 직선 b 보정 (R-15 후속)", "옥성 P5, Ramp-A P3·P3-1",
"b = 꺾임 꼭짓점까지 잰 값: P5 %.1f / P3 %.1f / P3-1 %.1f (도면 b 보다 57.9 짧음 = R24×tan67.5°)" % (p5["b_before"], p3["b_before"], p31["b_before"]),
"b = 다리선에서 호 시작점까지 (도면): P5 2,341 / P3 1,832 / P3-1 2,137. 중심선 길이 P5 %.1f / P3 %.1f / P3-1 %.1f" % (p5["len_after"], p3["len_after"], p31["len_after"]),
n_p5 + n_p3 + n_p31,
"사용자 질문 2026-10-26('P3, P3-1 형상 제대로 만들었니?') 점검에서 발견: 도면 b 는 다리선~호 시작점. 호 뒤쪽(호+끝)을 직선 방향으로 57.9 평행 이동",
"옥성교P1_G5_수정6_20261026.3dm / ramp-A G5_수정5_20261026.3dm",
"수정 후 재측정: a·b 가 도면과 일치(P5 160/2,341, P3 200/1,832, P3-1 200/2,137). 객체 수 동일",
"P3-1 은 b 를 늘리자 갈고리가 콘크리트 밖으로 나감 (M-9, 미해결). P3·P5 는 콘크리트 안"], 4)
ws.cell(row=r, column=1).fill = GREEN
ev = wb["수정 증거(마크별)"]
for m, br, s, n in (("P5", "옥성교", p5, n_p5), ("P3", "Ramp-A교", p3, n_p3), ("P3-1", "Ramp-A교", p31, n_p31)):
append_like(ev, [br, m, "H16", "갈고리 직선 b 보정", n, "b %.1f / 길이 %.1f" % (s["b_before"], s["len_before"]), "b %.1f / 길이 %.1f" % (s["b_after"], s["len_after"]),
round((s["len_after"] - s["len_before"]) * n, 1), "도면 b = 다리선~호 시작점. 호·끝을 +57.9 평행 이동"], 4)
append_like(ev, ["Ramp-A교", "P3-1", "H16", "콘크리트 돌출 측정(기둥 솔리드)", 48, "중심 피복 최소 %.1f mm, 콘크리트 밖 0본" % b4["P3-1"]["min_centre_cover_inside_mm"],
"수정5: 밖 %d본, 최대 %.0f mm" % (a4["P3-1"]["bars_with_part_outside_concrete"], a4["P3-1"]["max_outside_length_mm"]), None,
"c1_protrude_check.py (콘크리트 솔리드 IsPointInside / ClosestPoint). 기존 = ramp-A G5_검토완료.3dm"], 4)
hold = wb["미수정·보류"]
append_like(hold, ["Ramp-A교", "P3-1 (H16)", "48본", "기존 모델에서 콘크리트 밖으로 튀어나감 (중심 피복 0.1 mm), 수정5 에서는 26본 갈고리가 밖으로 나감",
"도면 치수(b 2,137, 갈고리)대로면 기둥 표면에 걸림. 배치 위치·방향 재확인 필요. 'M-9', '수정 내역' R-17",
"도면에서 P3-1 배치와 기둥 단면 확인(설계자)", "M-9"], 4)
fs = wb["수정 파일·해시"]
def sha(p):
h = hashlib.sha256()
with open(p, "rb") as f:
for blk in iter(lambda: f.read(1 << 20), b""):
h.update(blk)
return h.hexdigest()
for row in fs.iter_rows(min_row=4):
n = str(row[1].value).split("/")[-1]
if n in ("ramp-A G5_수정3_20261026.3dm", "ramp-A G5_수정4_20261026.3dm", "옥성교P1_G5_수정5_20261026.3dm") and row[3].value == "최신":
row[3].value = "중간본"
row[3].fill = PatternFill(fill_type=None)
for b, rel, what in (("Ramp-A교", "Ramp-A교P1/ramp-A G5_수정5_20261026.3dm", "P3·P3-1 b 보정 포함 (P3-1 은 콘크리트 돌출 미해결) — 전체 수정 포함"),
("옥성교", "검토_옥성교P1/옥성교P1_G5_수정6_20261026.3dm", "P5 b 보정 포함 — 전체 수정 포함(전단철근 수정3 제외)")):
p = REV / rel
st = p.stat()
rr = append_like(fs, [b, "검토파일/" + rel, what, "최신", round(st.st_size / 1e6, 1),
datetime.datetime.fromtimestamp(st.st_mtime).strftime("%Y-%m-%d %H:%M"), sha(p)], 4)
fs.cell(row=rr, column=4).fill = GREEN
wb.save(XLSX)
print("saved")