Files
Pier_v1/context-migration/교각모델링앱_요구사항.md
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

157 lines
28 KiB
Markdown
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.
# 교각 도면 모델링 앱 — 요구사항 검토 결과
```
소유자: 심영표
확정일: 2026-10-08
최근확인일: 2026-10-15
재확인 조건: 앱 개발 착수·기술 기반 결정 시 / 두 번째 교각 도면으로 규칙을 검증할 때 / 요구사항 검토서 판이 바뀔 때
```
## 정본
- `DOC/01_기획/기획_교각도면모델링앱요구사항검토_2026-10-08_v0.1.01.md` (확정, 9장 + 부록)
- 근거: 운곡교 P1 실작업 전체(모델 v0.1.09, 판독서 2, 설계서 v0.1.10, 검증 v0.1.05, 도면 검토보고서 v0.1.01, 스크립트 25종)
## 요지 (재조사 불필요)
- 공정: 입력·판독 → 형상(G1) → 기둥 철근(G2) → 기초 철근(G3) → 코핑 철근(G4) → 솔플레이트·받침(G5) → 검토보고서. 게이트 = 독립 기대값 + 음성 대조(수평·높이) + 재로드 + 숨김 포함 집계 + 지문 불변
- 추가 입력: 실작업 결정 32건을 7유형(범위·표현·충돌 해소·추정 확인·기준·보고·표시 상태)으로 표준화. 외부 자료: 측량좌표·선형, 설계기준, 표준 상세, 디자인 지침
- 검토 예외: 예정된 FAIL(B12, C9~C13 폭), 기록 전용(반올림·곡선길이·피복·굽힘 R 미달), 검사 대상 외(철근 간섭, 시공성, 구조 계산), 예외 승인 절차
- 권고 `[추론]`: 판독·규칙·검사 Python 엔진 + B-rep 생성(Rhino.Compute/플러그인) + 박스 웹앱 UI. 로드맵 P0(스크립트 라이브러리화·회귀 고정) → P1(CLI 게이트) → P2(웹 UI) → P3(복수 도면 범용화)
- 의사결정 4건 → OPEN #17 **해소(2026-10-08)**
## 개발 현황 (2026-10-08, 최근확인일 2026-10-08)
- 앱 위치: `Code/교각모델링앱/` (원본 `Code/교각모델링/`은 수정하지 않음). 결정: 반자동 MVP · 로컬 Rhino 8 자동 실행 · Flask + 단순 HTML · T형만 · .3dm · local 좌표
- 단계: P0 완료(엔진 라이브러리화 + v0.1.09 지문 회귀 **3,190/3,190 동일**) → P1 완료(CLI 게이트 `tools/run_gates.py`, G1~G5 PASS) → P2 완료(Flask, 사용자 승인 2026-10-12) → P3 완료(보고서). 단계마다 정지·승인(사용자). **2026-10-12 사용자 확정(화면 포함), 개발 마감.** 남은 과제는 OPEN #18·#19
- P2 완료(2026-10-12): `web/app.py` (127.0.0.1:5000, 인증 없음 → 로컬 전용)
- 판독은 '입력 폼 + 도면 문자 검색'(사용자 선택). 표 3종(ELEVATION, 솔플레이트, 재료표 SD400/500)만 후보값 자동 비교. EL 문자는 목록만 보여 줌
- 운곡교 P1 도면 치수는 DIMENSION이 아니라 TEXT(CS-DIMT 레이어)
- 확정·승인은 해시 기반: 값이 바뀌면 자동으로 무효. E2E 41/41 (`tools/test_web.py`)
- P3 완료(2026-10-12): 검토보고서 초안 자동 생성(`engine/report.py`, 8장, MD + PDF)
- 승인된 계획 FAIL은 '불일치', 미계획 FAIL과 표 값 차이는 '확인 필요'로 등록
- E2E 49/49
- Rhino 정체(2026-10-12 오후부터, 원인 미확인): 시작이 23분 늦거나, 결과 기록 뒤 종료하지 않음
- 실행기(`runner.py`)가 결과 후 30초 유예 → 강제 종료, 시작 10분 초과 → 1회 재시도로 대응
- 강제 종료 뒤 다음 Rhino 시작은 정상(`tools/test_runner_stall.py`)
- 작업 상태: 작업 고유 번호·프로세스 번호를 기록. 서버가 중간에 멈춰 남은 '실행 중'은 '중단됨'으로 표시하고 재실행 허용
- 일괄 기능(2026-10-12, 사용자 요청)
- 묶음 일괄 확정, G1~G5 연속 실행·자동 승인
- PASS만 승인, 의견 '일괄 실행 자동 승인', 기록 이름은 누른 사람
- 최신 PASS 결과는 재실행 없이 승인
- 나머지는 단일 Rhino 세션(`run_batch_session`)에서 실행: 게이트 검사·음성 시험만, 중간 저장·재로드 없음, G5만 저장(사용자 결정)
- 일괄 실행 게이트의 재로드·불변은 '생략'. 저장·재로드 검증은 개별 실행으로 함
- 두 번째 형식(2026-10-13, 산외교 울산 P1)
- 교각별 `params.scope` / `builders`, `expected.checkers` / `negative`로 형식을 확장
- 생성기 `concrete_tapered.py`(직선 경사 코핑·직접기초), 검사기 `g1_tapered.py`
- Rhino 불리언 함정: 칼날형 끝·동일 평면 접촉·접선 면은 교차·합치기·필렛이 실패함
- 우회: 한 번 압출한 뒤 분할 원호 외측 오프셋 커터로 빼기
- AddBrep은 무효 브렙을 오류 없이 거부함 → 생성기에서 IsValid와 Guid를 확인
- 철근(2026-10-13): G2 `column_rebar_ring.py`/`g2_ring.py`(원형 기둥 1열 주철근·띠철근 구간), G3 `footing_rebar_mats.py`/`g3_mats.py`(명시 위치 묶음·둘레 띠·연직근), G4 `rebar_polylines.py`/`g4_polylines.py`(철근별 중심선 꺾은선을 판독 스크립트가 만들고 생성기는 범용)
- 울산 결과: G1 104 · G2 35 · G3 63 · G4 129 · G5 75 전부 PASS. 판독 스크립트 `Code/울산P1판독/extract_r2~r4.py`
- 판독 요령: 재료표 L은 'L 열'(시트 x 111,000~112,500) 값으로 읽음(형상 열이 추가된 행은 끝에서 두 번째가 총길이). 형상표 II 주기 a=(1,250×2+2,000)/3+D로 스터럽 3조 해석. 코핑 평면 R500 모서리의 바깥 철근은 R400 원호까지 단축
- 보호 템플릿(2026-10-13, 사용자 선택 "보호된 템플릿 목록 신설")
- `data/_템플릿/<이름>/`에 params·expected·template.json(설명, 원본, 저장일, 입력 해시) 고정 사본. 교각 목록에 나오지 않고 앱 화면에서 고칠 수 없음
- 저장은 `tools/make_template.py`로만 함(재저장 시 이전 사본은 `_템플릿/_이전/`). 현재 `운곡교P1형`, `산외교울산P1형`
- 새 교각 화면: '보호 템플릿'(값 `tpl:<이름>`)과 '기존 교각 복사' 두 묶음. pier.json의 template = "템플릿: <이름>"
- 경위: 사용자가 원본 산외교울산P1을 앱에서 삭제(13:11, 휴지통 보존) → 산외교울산P1형은 휴지통 사본에서 만듦(G1~G5 PASS 입력과 바이트 동일)
- 울산 형식 앱 시험(2026-10-13, `tools/test_ulsan_e2e.py` 44/44): 판독기 결함 2건 수정
- 받침별 값: 울산 expected G5 h3·L·T는 받침 번호별 사전 → 후보값이 받침 번호를 함께 넘겨 그 칸과 비교·반영(이전: 거짓 '다름' 8건, 반영 시 사전을 숫자로 덮어씀)
- 여러 줄 머리행: 재료표 머리행 아래 2단 이내 문자 줄을 머리행에 합침(단위 줄 제외), 같은 열 아래 표 제목에서 읽기 종료 → 울산 재료표 34마크 인식, 보고서 6장 34행 일치
- 보고서 자체 점검: 철근 마크가 있는데 재료표를 못 읽으면 미통과(`schedule_unread`)
- 시험 함정: 입력 하나를 바꾸면 전 게이트 승인이 무효(입력 해시) → 잘못된 입력 시험은 G1부터
- 확정 범위 보완(2026-10-13, 사용자 "진행해줘", `tools/test_confirm_required.py` 13/13, 회귀 8종 전부 통과)
- 경위: 일괄 확정은 `web/store.py`의 `COMMON`·`GATE_SECTIONS` 묶음만 확정 → 울산 교각에 미확정 8개가 남음
- 실행 설정 `params.scope`·`builders`, `expected.checkers`·`negative`는 게이트 결과를 바꾸므로 필수 확정으로 추가. 묶음이 없으면(운곡교 형식) 요구하지 않음(`OPTIONAL`)
- 참고 묶음(`_`로 시작, `_src`로 끝남, `hitl_decisions*`)은 게이트가 쓰지 않음 → 화면에 '확정 불필요(참고)'로 표시(`store.is_info`)
- 필수 확정 묶음 수: 운곡교 형식 23개, 울산 형식 26개
- 함께 고친 결함: `OPTIONAL` 판정이 params 파일만 확인 → expected 묶음은 있어도 요구 목록에서 빠졌음. 묶음이 속한 파일을 확인하도록 수정
- 사용설명서 정본 `DOC/04_실행/실행_T형교각모델링앱사용설명서_2026-10-14_v0.2.05.md`(Ramp-A 형식 반영; 구판은 backup)
- 세 번째 형식(2026-10-13, Ramp-A교 P1, 사용자 결정 "앱 형식 확장", 범위 G1·G5)
- 형식: 단일 현장타설말뚝(Ø2,350 암반 근입 7,500 + Ø2,500 5,200) + 원형 기둥 Ø2,000 + Y형 코핑(하면 R5,000, 끝면 = 평면 볼록 원호→상단 직선 선직면, 상면 315 단차, 측면 2,200→2,000 테이퍼) + 받침 2개(회전 −5.55°·−9.19°)
- 생성기 `concrete_shaft.py`(coping form "y_shaft"), 검사기 `g1_shaft.py`. G5는 기존 `bearings.py`·`g5_bearings.py` 그대로(대좌 `seat_z`, `bearing_size` "AB", thick_end −Y)
- 코핑 = 정면 윤곽 압출 ∩ 측면 윤곽 압출 − 양 끝 커터(두 단면 직선 로프트 = 선직면). 각 입체를 상대 면 너머로 뻗어 일치·접선 면을 피함 → 불리언 1회 통과
- 함정: Rhino `Point3d`에 2D 튜플을 넘기면 SerializationInfo 생성자 오류. 검사 단면을 X=0으로 자르면 상면 단차면과 겹쳐 고리가 쪼개짐 → X=+1
- 판독기 보완 3건: 천 단위 쉼표 `_int`, 머리행 선택(아래 첫 숫자 줄이 칸 수 절반 이상), 다른 종류 표 제목에서 창 하단 자름. 운곡교·울산 표 레코드·후보 불변(`tools/test_rampa.py`)
- 결과: G1 97/97, G5 39/39 PASS(엔진 실행; 앱 확정·승인은 담당자 몫). 보호 템플릿 `Ramp-A교P1형`. 판독서 `DOC/02_분석/분석_Ramp-A교P1교각도면판독_2026-10-13_v0.1.01.md`, 판독 스크립트 `Code/RampA판독/`
- 판독 요령: D1 z = 도면 y + 534,115.2. 평면 끝 원호는 LWPOLYLINE bulge(0.136, 처짐 150)로만 표현됨
- 기둥 철근 G2(2026-10-13, 사용자 결정: 기둥 P1·P2·P3만, 말뚝 철근망은 범위 밖): 생성기 `column_rebar_straight.py`·검사기 `g2_straight.py`(form "straight": 곧은 주철근+하단 커플러, 반원 2조각 겹이음 띠철근, X·Y 연결철근). G2 26/26 PASS, 객체 764
- 판독 요령: D2 정면 파단(4,000 생략) → 높이는 치수선 끝점으로 읽음. 사슬 기점 EL 45.492(말뚝 상단 +40). 띠철근 작도선은 파단 위아래로 50 어긋남 → 사슬 격자 + 재료표 N으로 확정(K2)
- 결정 K1~K4: 커플러 40(작도 16,260 + 40 = L), P2 43.542+150k ×107, P3 43.692+300k ×54 × X·Y(Y +16), 이음·갈고리 단마다 교번
- 함정: 기둥-코핑·말뚝 단 사이 동일 평면 접촉 → 콘크리트 합집합 실패(0개) → 피복은 기둥 구간 측면 피복으로 기록. 재료표에 형식 열이 없으면 판독기가 형상 None을 제안 → 지름만 비교로 수정
- 말뚝 철근망 G3(2026-10-13, 사용자 결정: 철근 5마크 + PLATE, SPACER는 공식만): 생성기 `shaft_rebar.py`·검사기 `g3_shaft.py`(form "shaft_cage"). G3 48/48, 모델 객체 1,357. `pipeline.GATE_PREFIXES` G3에 `PT` 추가
- 판독 요령: D4 정면은 개략도(길이 불일치) → 높이는 구조물 치수표 + 사슬('110'·'260'·'100')로. 첫~끝 띠철근 단 = P1-1 + P1-2 L 합(12,150) 정확히 일치. 단면 기호 r 1,002.5, 첫 각 1.475°
- 결정 S1~S6: 띠철근 r 1,025(재료표 r 929·J-J '2,300' 오기), 주철근 r 999.5, U형 중심 통과 30면, PLATE U형 바닥 아래, 이음·갈고리 교번, 커플러 0
- 말뚝 철근 id는 'R-P1-1-..'이라 G2 접두('R-P')에 걸리지만 불변 검사에는 무해(앞 게이트 전체 비교)
- 코핑 철근 G4(2026-10-14, 사용자 결정: 20마크 한 Task, 울산식 중심선): `Code/RampA판독/extract_g4.py`가 449본 꺾은선 생성 → 범용 `rebar_polylines.py`, 검사기 `g4_ramp.py` 신설. G4 126/126, 모델 2,255 객체. Ramp-A G1~G5 전 범위 완료
- 판독 요령: 스터럽 위치는 정면 작도선 55곳(사슬 58@125는 59곳이라 불일치), 하단 = 하면 R+77.5 원호. 재료표 가변 마크 L은 b 최댓값·양 끝 평균 기준이라 위치별 평균과 다름(기록만). C13·C14 = 단마다 동심 수평 고리 3개(정면 수평선 10단)
- 앱 확정 대상 보완(2026-10-14): `store.GATE_SECTIONS`에 `pile`(G1)·`shaft_rebar`(G3) 추가, `lean_concrete`·`footing`·`footing_rebar`를 OPTIONAL로 → 이전에는 Ramp-A G1·G3가 앱에서 '없음'으로 막혔음(엔진 직접 실행이라 드러나지 않았음). 필수 확정 14개. 시험 `tools/test_rampa_web.py`
- 함정: 코핑 끝면이 평면 볼록 원호 → y ±1,000 모서리에서 정면 작도 위치 철근이 밖으로 나감 → 끝면 피복 40 단축(울산 R500과 같은 방식). 같은 x의 안쪽·바깥 스터럽은 상면 변이 일직선으로 겹침 → 안쪽 +20
- 네 번째 교각(2026-10-14, 옥성교 P1, 범위 G1·G5): T형 말뚝기초 + 직선 경사 코핑 + 측면 테이퍼 + **평면 사각 18°** + 묶음 대좌(앞뒤 받침 공유, 상면 경사)
- 생성기: 울산 `concrete_tapered.py`에 선택 옵션(piles, coping.side_taper, coping.skew_deg = 전단 x' = x − tan·y, bearing_seats.pedestals) 추가(사용자 결정 '울산 생성기 확장'). 검사기 `g1_skew.py` 신설. G5 `g5_bearings.py`는 패드 축을 윗면에서 구함
- 결과: G1 147/147, G5 183/183(엔진 실행). 보호 템플릿 `옥성교P1형`. 판독서 `DOC/02_분석/분석_옥성교P1교각도면판독_2026-10-14_v0.1.01.md`, 판독 스크립트 `Code/옥성P1판독/`
- 판독 요령: 한 DWG에 일반도·배근도가 함께 있음. z = 도면 y − 314,374.9. 정면도 코핑 외곽은 y = 0 단면이고, 평면 사각은 전단으로 재현(상면 단 경계선도 같은 전단으로 일치 ✓)
- 함정: 옆 표(ELEVATION)의 행이 솔플레이트 표 창에 끼어듦 → 머리행 x 범위 밖 숫자 줄은 건너뜀. **머리행 규칙을 다른 방식으로 바꾸면 울산(3줄 머리행)·Ramp-A(라벨 줄)가 깨짐 — 동일 방식 재시도 금지**. 기울어진 패드 바닥 → 무게중심이 평면 중심과 다름(검사는 bbox 중심)
- 기둥 철근 G2(2026-10-14): 울산 `column_rebar_ring.py`·`g2_ring.py`에 옵션 추가(main.inner 안쪽 링·안쪽 갈고리, zone.radius, ties.shape "90-135" + y_lift). 사용자가 처음 '운곡교 생성기 재사용'을 골랐으나 판독 결과(커플러 반원 띠철근, 갈고리 주철근)로 울산 쪽을 제안해 변경 승인(Q1). G2 39/39
- 판독 요령: 구조도(1) 정면 z = 도면 y − 309,179.8, 기둥 단면은 1/4 원호 4개(CIRCLE 아님). 사슬 '띠철근외측'이 작도 띠철근과 정확히 일치. 작도 주철근 다리(12.375)와 사슬·재료표(12.325) 50 차이 → 치수 채택(Q2)
- 기초 철근 G3(2026-10-14, 사용자 결정: 철근별 중심선): 범용 `rebar_polylines.py`를 G3에도 씀 — 엔진이 생성기에 `GATE` 전역값을 넘기고(G3 → params footing_rebar, 그 외 coping_rebar). 검사기 `g3_poly.py`. G3 75/75, 518본
- 판독 요령: 기초 평면의 B9 기호는 아래 절반만 작도, 그중 일부가 상세 표시 점선 원에 가려 빠짐 → 작도 점을 대칭 복사하지 말고 열·행 규칙으로 격자 생성. 운곡교 기초 생성기는 마크 배치가 하드코딩돼 다른 교각에 재사용 불가
- 결정(사용자, 권장안 전부): F1 B9 한 곳 빼서 171본 · F2/F3 권장안(B9 a 567 평균, 마크 두 개 가장자리부터 교번, 겹이음 미모델) · F4 Y방향 중간근 +19 위로 · F5 UM(조립용 받침) 기록만. F2~F4는 [추론] — 사용자 확인 대기
- 스크립트: `Code/옥성P1판독/extract_g3.py`→`판독/g3_values.json`, `extract_g3_bars.py`→`판독/g3_bars.json`, `add_g3.py`(백업 `data/옥성교P1/backup/2026-10-14_g3/`). 엔진 패치 `tools/patches/2026-10-14_patch_gate_global.py`(백업 `backup/2026-10-14_okseong_g3/`)
- 회귀(전부 PASS): Ramp-A G4 126/126·G5 39/39, test_web_batch 20·test_web 49·test_web_ulsan_full 16·test_ulsan_e2e 44, 빠른 시험 okseong 14·templates 12·open19 38·rampa 24·confirm_required 13. 모델 1,536 객체. 로그 `prompt/심영표/2026-10-14/Task_옥성교P1기초철근_2026-10-14_v0.1.00.md`, 판독서 v0.1.05
- 코핑·교좌면 철근 G4(2026-10-14, 사용자 결정 H1~H6 권장안): 범용 `rebar_polylines.py`(coping_rebar)·엔진 수정 없음. `Code/옥성P1판독/extract_g4.py`(1,163본, `판독/g4_bars.json`)·`g4_shapes_dump.py`(모양표↔재료표 (L, N) 짝맞춤)·`add_g4.py`(백업 `data/옥성교P1/backup/2026-10-14_g4/`), 검사기 `g4_okseong.py`. **G4 251/251**, G1~G5 전부 PASS·불변 확인, 모델 3,862 객체. 판독서 v0.1.07, 사용설명서 v0.2.07, 로그 `prompt/심영표/2026-10-14/Task_옥성교P1코핑철근_2026-10-14_v0.1.00.md`
- 판독 요령(재판독 불필요): 한 DWG에 4장(구조도 1~4)이 x 방향으로 나열. 재료표 x 714,965~ / 모양표 x 689,900~712,000. **재료표 수량이 해독 열쇠** — 스터럽 연직선 106 = 39(C8)+27(C10)+40(C12), 정면 점 117 = C18, C7 13 = 9+2+2, 측면 고리 6+6단 × 4줄 = 24, S1~S4 = 대좌 1개분·S5~S8 = 4개분(5 대좌). 정면 선은 철근 중심선보다 22.5 안쪽(스터럽 위·아래), b 3,207 = 3,050 / cos18°(고리 변이 끝면과 평행)
- 코핑 철근은 단면(y = 0) 좌표로 만든 뒤 코핑과 같은 전단 x' = x − tan18°·y 적용(스터럽·고리·C18 포함), 교좌면 철근은 모델 좌표(대좌 평행사변형 방향: 긴 철근 = 끝면과 평행, 짧은 철근 = X)
- 함정: 모따기 20 mm 미만이면 파이프 생성 실패(C9 x −5725) / 낮은 단 C18 다리를 아래로 두면 코핑 하면 밖(피복 −8) → 위로 / 전단된 고리의 bbox는 모서리 필렛 때문에 최대 37 mm 줄어듦 → 검사 허용 오차 명시
- 앱 데이터 주의: Ramp-A·울산 `runs/current/*_gate.json`이 웹 일괄 시험(11:17)에 '저장·재로드 안 함' 모드로 덮어써져 test_rampa가 FAIL → Ramp-A는 `Code/RampA판독/run_gates.py G1~G5`로 복원. 울산은 미복원(OPEN #25)
- 다음 작업: 옥성교 P1 G1~G5 전 범위 완료. 남은 것은 담당자의 앱 확정·승인·육안 확인과 [추론] 확인(OPEN #24)
- 환경: 이 세션에서 Rhino MCP 서버 연결 실패(CONNECTION_CLOSED) — 엔진 직접 실행에는 영향 없음
- 일반화 보완(2026-10-13, OPEN #19 A3~A7, `tools/test_open19.py` 전 항목 PASS, 회귀 9종 FAIL 0, 사용설명서 v0.2.04)
- A3: `reader.table_records` 허용 거리 = 셀 쪽 이웃 머리열 간격 × 0.6(이전: 표 최소 간격 × 0.6 → 넓은 열의 범위 문자 탈락). 추가된 칸만 생김(운곡교 P1·P2 C12·C13 A, 울산 C7~C13 A·B 7칸), 기존 칸 변화 0
- A4: `reader.proposals`가 같은 표 값을 params 별도 행으로 냄(`bearing_seats.bearings[no]` el_x·h1·h2·A·B, `sole_plates.table[no]` S·L·W·T·h3, 공통 h3는 `sole_plates.h3`). params에 있는 칸만. 현행 params와 '다름' 0(운곡교 P1·P2 각 91행, 울산 40행) → 후보 총 행수 운곡교 166 → 257
- 함정: `_get`이 목록 인덱스를 못 따라가 params 행이 조용히 빠졌음 → 정수 키 처리 추가
- A5: 묶음 저장 시 `{"chain": "시작, 증분, n@간격"}`를 숫자 목록으로 펼침(`store.chain`·`expand_chains`). params에는 목록만 저장 → 생성기·검사기·지문 불변
- A6: [도면 문자 검색] 화면의 '핸들 조회'(`reader.entity_info`): 종류·레이어·좌표·길이·호 반지름·bbox. P2 D1 21A76 = LINE 10,350, 20E89 = ARC R12,000 확인
- A7: `gates.negative_moves` 재정의 없을 때 기본 받침 id가 expected G5 el_x 번호 밖이면 마지막 받침 번호로 대체(받침 10개는 기본값 그대로)
- 수정 전 사본 `Code/교각모델링앱/backup/2026-10-13_open19/`, 회귀 기준 `검증/open19_snapshot_before.json`(`tools/open19_snapshot.py`)
- 지문 함정(2026-10-12): FAST 지문(관 부피 생략)은 Rhino가 관 솔리드 bbox를 관 반지름만큼 작게 돌려줌 → FAST와 전체 지문을 섞어 비교하면 가짜 차이(569건)가 남. `compare_fingerprints.py`가 혼합 비교를 거부함
- 운곡교 P2 판독(2026-10-12): G1~G5 PASS, 엔진 일반화 2건 수정(말뚝 `pitch_x/pitch_y`, `hoops.radius_by_mark`), P1 회귀 동일. 판독서 `DOC/02_분석/분석_운곡교P2교각도면판독_2026-10-12_v0.1.00.md`
- Windows 함정: 스레드 간 JSON 파일 공유 시 `write_text`는 빈 파일이 읽힐 수 있음
- 원자적 교체(`os.replace`)를 쓰고, 교체 순간의 PermissionError는 읽기·쓰기 양쪽에서 재시도(`web/store.py`)
- 검사 독립성: 검사기는 `data/<교각>/expected.json`(도면 문자·표 값, 계획 FAIL 목록)만 읽고 params는 읽지 않음. 이관 검사기 = 기존 verify 5종과 646항목 값·판정 일치
- 게이트 PASS 조건: 미계획 FAIL 0 + 음성(수평·수직 이동) 검출 + 재로드 객체 수 일치 + 앞 게이트 객체 지문 불변
- Rhino 자동 실행 사실: `"Rhino.exe" /nosplash /notemplate /runscript="_-RunPythonScript <ASCII경로> _-Exit"` — `/runscript="..."` 형식만 인식(인자 전체 따옴표·Git Bash 경로 변환 시 무동작), 끝에 `doc.Modified=False` 필요. 작업 폴더 `%LOCALAPPDATA%\PierApp\jobs`. 전체 모델 생성 17초, 부피 포함 지문 약 12분
- 앱 매개변수 규격 `pier-T/1` = 기존 params + 상수 이관 필드(`rebar_marks`, `footing_rebar.a_x/a_y`, `coping_rebar.soffit_arc_centre`(0.1mm 반올림값 유지), 스터럽 상단 구간표, `materials.fck`, `sole_plates.h3`, `display`)
## 주의
- 근거 도면 1세트 — 54.3 오프셋·층 구성 등은 운곡교 P1 관찰값이며 고정 상수로 쓰지 않는다
## 앱 개선 기획 (2026-10-14, 구현 전)
- 정본: `DOC/01_기획/기획_입력묶음확인확정개편_2026-10-14_v0.1.00.md` (초안 `[미확정]`). 교각 화면 「2. 입력 묶음 확인·확정」 개편
- 결정(사용자 2026-10-14): D1 **앱 확인 + 사람 확정**(앱은 확정 기록을 만들지 않음, 앱 확인은 `autocheck.json` 별도 층), D2 표 밖 치수 = **규칙 + 템플릿 앵커**(신뢰 등급 A·B·C·없음, 억지 후보 금지)
- 변수 등급: V1 값 / V2 목록 / V3 생성(판독 스크립트가 만든 큰 목록, 편집 차단) / F 고정(형식 정의). 철근 중심선 목록이 확정 필요 묶음 용량의 84~95 %(울산·Ramp-A·옥성)라 손 대조 불가가 핵심 문제
- 가장 위험한 문제(P2): 템플릿 복사값을 새 도면 대조 없이 확정하면 원본 교각 모델이 PASS → 앱 확인 C3 '템플릿 원본 잔존'으로 막을 것(가장 쉬워 1순위)
- 대기: D3~D6 (OPEN #26). 확정·게이트 승인은 어떤 단계에서도 앱이 대신하지 않는다(시험은 별도 폴더에서만)
## 다섯 번째 교각 — 새재1교 P1 (2026-10-15, 범위 G1·G5)
- 직접기초(말뚝 없음, 7.7 × 7.7 × 2.6) + 원형 기둥 Ø2.2(높이 16.9) + 직선 경사 코핑(끝면 수직, 상면 5단, 측면 3,000 → 2,200 테이퍼, **평면 직사각**) + 받침 10개(**대좌 5개 공유**, 앞·뒤 열 패드가 서로 다른 각도 −2.15° / −6.45°로 회전). 같은 도면 틀(옥성교와 같은 설계사)·구조도(1)~(4) 철근도 있음(철근 미판독)
- 결과: G1 138/138, G5 183/183(엔진 실행), 모델 39객체. 보호 템플릿 `새재1교P1형`. 판독서 `DOC/02_분석/분석_새재1교P1교각도면판독_2026-10-15_v0.1.00.md`, 스크립트 `Code/새재1교P1판독/`(`convert_index`·`extract_g1`·`make_pier [--update]`·`run_gates`), 로그 `prompt/심영표/2026-10-15/Task_새재1교P1모델링_2026-10-15_v0.1.00.md`
- 엔진 변경 없음: 생성기 `concrete_tapered.py`(말뚝 없음·측면 테이퍼·공유 대좌) 그대로, 검사기 `g1_pedestal.py` 신설(옥성교 `g1_skew.py` 복사본 + 말뚝 선택·사각 0° 허용) → 다른 교각 영향 없음
- 판독 요령: 정면·단면도 **기둥이 중간에서 절단 표시로 끊겨 z 오프셋이 둘**(기초 쪽 y − 14,716.5, 코핑 쪽 y − 5,816.5). 단 높이 = EL.'X' − h1 − h2인데 표의 앞열·뒤열 값이 1 mm 어긋남(표 반올림) → 평균(.5)을 써서 앞·뒤 0.5 mm 안(작도선 소수 .1을 그대로 쓰면 패드 윗면 FAIL 3건). 받침 평면 위치·회전은 패드 폴리라인 3겹(750/650/550)의 바깥 사각형에서
- 결정(사용자): N1 G1+G5 먼저, N2 대좌 상면 = 앞·뒤 받침 사이 평면 경사 [추론], N3 기둥 fck 35 MPa [추론]. 솔플레이트 두꺼운 쪽 −Y(S < 0, 운곡교 규칙 [추론], OPEN #16)
- 다음 작업: 철근 G2~G4(구조도 1~4) — 요청 시. 앱 확정·승인·육안 확인은 담당자 몫
- 기둥 철근 G2(2026-10-15): 옥성교와 같은 `column_rebar_ring.py`·`g2_ring.py` 재사용(엔진 변경 없음). 스크립트 `extract_g2.py`·`add_g2.py`. **G2 41/41**, G5 재실행 183/183, 앞 게이트 663 불변. 판독서 v0.1.01
- 판독 요령: 주철근 두 겹 49본씩(r 975 / 930, 7.347°), 띠철근 72단·크로스타이 40단은 **치수 사슬이 전부**(기둥이 절단 표시로 끊겨 도면은 일부만 그림). 띠철근 구간은 표 수량(P3 45 / P4 27)과 사슬 그룹 크기(5·18·36·9·4)로 맞춤. 띠철근 반지름 = 주철근 바깥 + 주철근 r + 띠철근 r(표 '1.004'는 1,003.5의 반올림 → 표값을 쓰면 곡선 길이 FAIL)
- 다음 작업: 기초 철근 G3(B1~B12), 코핑 철근 G4(C1~C20, S1·S2, 대좌 5개) — 요청 시
- 기초 철근 G3(2026-10-15, 옥성교 F1~F5 재적용): 범용 `rebar_polylines.py`(G3)·엔진 변경 없음. `extract_g3.py`(점 목록 → `g3_values.json`)·`extract_g3_bars.py`(307본)·`add_g3.py`, 검사기 `g3_sj.py` 신설(옥성교 `g3_poly.py` 복사본, 위치는 작도 점 목록). **G3 72/76(계획 FAIL 4)**, G5 재실행 183/183, 앞 게이트 1,277 불변. 판독서 v0.1.02
- 판독 요령: Y방향 61곳(정면 점)·X방향 **51곳**(측면 점; 재료표는 53 → 계획 FAIL, OPEN #28)이 핵심. X철근은 Y철근보다 22.5 위·아래(작도 관례). 평면 치수 '8.000'은 사슬 합(7,700 + 300, '−300' 보정) — 기초 평면 선은 7,700. B9는 정면 연직선 15곳(x @500, 짝수 행 8·홀수 행 7) + 측면 다리 행 6(@1,200, 다리는 행 중심 ±600 작도 = ±622 표) → 45본
- 다음 작업: 코핑 철근 G4(C1~C20, S1·S2, 대좌 5개) — 요청 시
### 새재1교 P1 코핑·받침좌 철근 G4 (2026-10-15)
- 결과: G4 189/189(873본, 엔진 실행), G5 재실행 183/183, 모델 3,043객체. 보호 템플릿 `새재1교P1형` 재저장(G1~G5). 판독서 `DOC/02_분석/분석_새재1교P1교각도면판독_2026-10-15_v0.1.03.md` 10장, 스크립트 `Code/새재1교P1판독/`(`extract_g4`·`add_g4`), 검사기 `engine/rhino/checks/g4_sj.py`, 로그 `prompt/심영표/2026-10-15/Task_새재1교P1코핑철근_2026-10-15_v0.1.00.md`
- 도면에서 확인한 규칙: 스터럽 윗단은 받침 단 모서리가 아니라 도면 구역 경계에서 바뀐다(윗면 − 124.5 = 중심 − 102 + 그림 겹침 22.5). 단 모서리에서 바꾸면 피복이 사라진다.
- [추론] 사용자 확인 필요: 받침좌 S1·S2 배치, C7 올린 줄 덮개, C18 아래 3단 다리 위, 스터럽 x 어긋남, 마크 교번.
## 앱 화면 개편 PRD·디자인 시스템·시안 (2026-10-15)
- 문서: `DOC/01_기획/웹앱디자인시안/PRD.md`(v0.1.02, 화면 13종), `design.md`(v0.1.01, Prism v0.1.1 앱 프로파일), `시안/index.html`(S04·S05·S07·S10 동작 시안, jsdom 19항 PASS), 캔버스 시안 13화면(앱 이름 PierProof). 기획서 `기획_입력묶음확인확정개편_2026-10-15_v0.1.01.md`(D1~D6 결정 완료).
- 결정(심영표 2026-10-15): D3 경고+사유, D4 일치 묶음만+근거표 열람, D5 A→B 먼저, D6 옥성교·Ramp-A교부터 / UX1 R8을 Prism으로 대체, UX2 Prism 상태색, UX3 Pretendard 내장(파일 `web/static/fonts/`에 배치만), UX4 마커 도형 승인, UX5 다크 시험 제외, UX6 HTML 시안 제작.
- 앱 구조 답변: Flask + HTML, 로컬 전용(127.0.0.1:5000), Rhino 8을 `/runscript`로 작업마다 실행 후 종료, 다른 PC 사용은 설치 필요, 네트워크 공유는 인증 추가 필요.
- 미결: 템플릿 구분 기준(OPEN #30, `템플릿구분기준과도면기반추천_논의.md`), 앱 코드 반영(기획서 A→B 착수 시, 계획서 승인 후).