- 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>
70 lines
6.3 KiB
Python
70 lines
6.3 KiB
Python
"""옥성교 J 겹침(기초 B1~B8·B11·B12, 코핑 C1~C6, 수정7 2026-10-27)을 엑셀에 반영. 백업(양쪽) → Pier_T → 원본 복사 → SHA 확인."""
|
||
import copy, datetime, hashlib, json, shutil, sys
|
||
from pathlib import Path
|
||
import openpyxl
|
||
from openpyxl.drawing.image import Image as XLImage
|
||
from openpyxl.styles import Alignment, PatternFill
|
||
ROOT = Path(r"D:\★Pier 자료\프로그램\Pier_T"); REV = ROOT / "검토파일"; ORIG = Path(r"D:\★Pier 자료\심수석님 검토 파일"); NAME = "4개교_공통사항_종합.xlsx"
|
||
res = json.load(open(r"C:\Users\User\AppData\Local\PierApp\jobs\c1_work\c1_lap_okseong.json", encoding="utf-8-sig"))
|
||
J = {"B1": 1530, "B3": 1530, "B5": 1530, "B7": 1530, "B2": 1070, "B4": 1070, "B6": 1070, "B8": 1070, "B11": 560, "B12": 560, "C1": 1510, "C2": 1510, "C3": 1510, "C4": 1510, "C5": 1510, "C6": 1510}
|
||
stamp = datetime.date.today().strftime("%Y%m%d")
|
||
for d in (REV, ORIG):
|
||
shutil.copy2(d / NAME, d / ("4개교_공통사항_종합_백업_%s_옥성J겹침.xlsx" % stamp))
|
||
wb = openpyxl.load_workbook(REV / NAME)
|
||
ws = wb["수정 내역"]
|
||
if any(r[0].value == "R-22" for r in ws.iter_rows(min_row=4)):
|
||
sys.exit("R-22 이미 있음")
|
||
GREEN = PatternFill("solid", fgColor="FFE2EFDA")
|
||
|
||
|
||
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
|
||
|
||
|
||
nb = sum(v for k, v in res["stat"].items() if k.startswith("B")); nc = sum(v for k, v in res["stat"].items() if k.startswith("C"))
|
||
r = append_like(ws, ["R-22", "옥성교", "J(겹침이음) 반영 — 기초 B1~B8·B11·B12 + 코핑 C1~C6",
|
||
"기초 B1~B8(j 1,530/1,070), B11·B12(j 560), 코핑 C1~C6(j 1,510)",
|
||
"도면 철근 상세에 j 가 있으나 모델은 1본 연속 형상(재료표 L 에만 반영)",
|
||
"긴 직선 구간 중앙에서 2조각이 j 만큼 겹침(산외교 기초·코핑과 같은 방식). 기초 %d본, 코핑 %d본" % (nb, nc),
|
||
nb + nc, "사용자 요청 2026-10-27: 나머지 교량도 코핑부·기초부 J 처럼 수정. 대조표의 j 값(B1 1.530 등)을 사용, 재료표 L = a+2b+j 로 확인(B1 9,400+1,800+1,530 = 12,730)",
|
||
"옥성교P1_G5_수정7_20261027.3dm", "객체 수 %d → %d. 조각 길이 합 = 기존 + j (B1 11,144 → 12,674 등), 파이프 부피 오차 0.5%% 이내, Rhino 캡처 확인" % (res["objects_before"], res["objects_after"]),
|
||
"미작업: 코핑 C7(j1,050 경사형), 루프형 C14·C16(j550×4)·B10(j560×6) — 겹침 위치·조각 구성을 도면 그림으로 확인 필요, C15·C17(모델 직선 vs 도면 갈고리, 형상 불일치 먼저). 운곡교는 재료표에 J 열 값이 없어 대상 없음, Ramp-A 는 C14(j290)만 있고 루프형이라 보류"], 4)
|
||
ws.cell(row=r, column=1).fill = GREEN
|
||
ev = wb["수정 증거(마크별)"]
|
||
for m, i in res["info"].items():
|
||
append_like(ev, ["옥성교", m, "-", "J 겹침 2조각(j %d)" % J[m], i["bars"], "1본 연속, 길이 평균 %.1f" % i["avg_len_old"], "2조각 j 겹침, 조각 길이 합 평균 %.1f" % i["avg_len_new_sum_of_pieces"],
|
||
round(i["avg_len_new_sum_of_pieces"] - i["avg_len_old"], 1), "R-22. 파일 옥성교P1_G5_수정7_20261027.3dm"], 4)
|
||
fs = wb["수정 파일·해시"]
|
||
sha = lambda p: hashlib.sha256(Path(p).read_bytes()).hexdigest()
|
||
for row in fs.iter_rows(min_row=4):
|
||
if str(row[1].value).endswith("옥성교P1_G5_수정6_20261026.3dm") and row[3].value == "최신":
|
||
row[3].value = "중간본"; row[3].fill = PatternFill(fill_type=None)
|
||
p = REV / "검토_옥성교P1" / "옥성교P1_G5_수정7_20261027.3dm"; s = p.stat()
|
||
rr = append_like(fs, ["옥성교", "검토파일/검토_옥성교P1/옥성교P1_G5_수정7_20261027.3dm", "기초 B1~B8·B11·B12, 코핑 C1~C6 J 겹침 — 전체 수정 포함", "최신", round(s.st_size / 1e6, 1),
|
||
datetime.datetime.fromtimestamp(s.st_mtime).strftime("%Y-%m-%d %H:%M"), sha(p)], 4)
|
||
fs.cell(row=rr, column=4).fill = GREEN
|
||
hold = wb["미수정·보류"]
|
||
append_like(hold, ["옥성교", "J 겹침 미작업: C7, C14·C16, B10, C15·C17", "-", "코핑 C7(경사형 j1,050), 루프형 C14·C16(j550×4)·B10(j560×6), C15·C17(모델 직선·도면 갈고리 불일치)",
|
||
"겹침 위치·조각 구성을 도면 그림으로 확인해야 함. 'R-22'", "도면 그림 확인 후 진행"], 4)
|
||
append_like(hold, ["운곡교·Ramp-A교", "J 겹침 대상 확인", "-", "운곡교: 재료표 J 열에 값 없음(대상 없음). Ramp-A: 대조표에 j 는 C14(j290)만 있고 루프형", "루프형 겹침 구성은 도면 그림 확인 필요. 'R-22'", "Ramp-A C14 도면 확인"], 4)
|
||
wd = wb["공통 문제 상세(이미지)"]
|
||
nr = wd.max_row + 1; like = nr - 1
|
||
vals = {1: "C-3", 2: "[개별] 옥성교 J(겹침이음) 반영 — 기초 B1~B8·B11·B12 + 코핑 C1~C6 (수정7)",
|
||
7: "도면 철근 상세에 j 가 있으나(B1 1,530, B2 1,070, B11·B12 560, C1~C6 1,510) 모델은 1본 연속 형상",
|
||
8: "긴 직선 구간 중앙에서 2조각 j 겹침 (기초 %d본, 코핑 %d본)" % (nb, nc),
|
||
9: "수정 완료(2026-10-27) 'R-22'. 루프형·경사형·C15·C17 은 도면 그림 확인 후 진행"}
|
||
for col, v in vals.items():
|
||
c = wd.cell(row=nr, column=col, value=v); s2 = wd.cell(row=like, column=col)
|
||
c.font = copy.copy(s2.font); c.fill = copy.copy(s2.fill); c.border = copy.copy(s2.border); c.alignment = Alignment(wrap_text=True, vertical="top")
|
||
wd.cell(row=nr, column=9).fill = copy.copy(GREEN)
|
||
wd.row_dimensions[nr].height = 560
|
||
im = XLImage(str(REV / "수정후_캡처" / "옥성교_J겹침_전후.png")); w0, h0 = im.width, im.height
|
||
im.width, im.height = 1000, int(1000 * h0 / w0); wd.add_image(im, "F%d" % nr)
|
||
wb.save(REV / NAME); shutil.copy2(REV / NAME, ORIG / NAME)
|
||
print("sha equal:", sha(REV / NAME) == sha(ORIG / NAME), sha(REV / NAME)[:16], "images:", len(openpyxl.load_workbook(REV / NAME)["공통 문제 상세(이미지)"]._images), "row", nr)
|