Commit Graph
563 Commits
Author SHA1 Message Date
eomsangdonandClaude Opus 5 a756181067 feat(B05): 세월교 변형 성토면을 절취 영역 경계에 맞춰 채우고 잘라낸다
세월교 날개 사다리꼴이 안 채워지고, 채운 판이 절취 영역 밖으로 삐져나오던 문제.
원인은 패치 리본이 "노선 프레임 수직 행 × 소유 측점 단면 한 장" 스윕이라
비스듬한 날개 부채꼴과 방향·범위가 안 맞는 것이었다. 세월교 전용으로 고친다
(`section.ford` — BOX암거·기슭막이는 종전 경로 그대로).

- 종방향: `wingSpanOnRoute` 신설. 날개 고리 점을 frameAt로 0.25m 간격 훑어 노선에
  실투영한다. 종전 직선 전방 투영은 곡선+먼 편거리(-7.85m)에서 3m 어긋나 고리
  앞부분이 범위 밖으로 밀려났다. 범위는 점유 구간 ±5m로 묶는다.
- 횡방향: `wingRangeAt`이 행 횡단선 × 주황 고리 교점의 안쪽·바깥쪽 끝을 낸다.
  바깥은 `extendRunTo`, 안쪽은 `prependRunTo`(노견 클램프). 지반 핀·스커트 유지.
- `clipRunBelow`: 바닥판 상단 Z(ford slabTopElevation)를 넘는 점을 지운다.
  종단 shift 반영, 천장 지나는 마디에 교차점 삽입.
- `patchClip`: 패치를 maskFillByPlanCurves에 한 번 더 통과시켜 **지우는 규칙의
  반대**를 건다 — 절취 영역 밖 셀은 지우고, 걸친 셀은 clipCellByChord(inside)로
  안쪽 조각만 남긴다. 두 면이 같은 경계를 공유한다.
- 700줄 초과로 날개 몫 도구를 _Corridor_Carve_Wing.ts로 분리(순수 이동).
- `__corridorScene` 노출(검증용 레이캐스트 좌표 변환).
- BUILD_VERSION 67 -> 79.

자체검증: 삐져나온 패치 셀 우 74->0(145셀 마스크+조각 198), 좌 지느러미 47->0.
BOX암거·기슭막이 masked=0(무변화). 영역 안 구멍 우 66/98% -> 39/56%.
typecheck 통과, tmp/tests 213 passed·7 skipped, 변경 파일 prettier.
남은 작업: 좌측 96% 구멍(slope-projected 전폭 절취 vs fillSegments 0.25m),
BOX 패치 리본 축퇴 원인 확인.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 20:02:00 +09:00
eomsangdonandClaude Opus 5 a864acd17d feat(B05): 변형 성토면을 지반 교차선에서 끊고 구조물 자리 원지반을 되살린다
- 패치(변형 성토면) 바깥 끝 스커트 신설(_Corridor_Skirt.ts): 지형 메시 높이를
  밑선으로 성토면 → 원지반 −1m까지 판을 세운다. 성토 빗금 메시 서피스로 그린다
  (절취 측벽은 종전대로 일반 서피스). 소유 측점 행에서 지반에 닿는 줄만 대상
  (허용 0.5m) — 벽 뒷면·구체 상단에서 끝나는 줄은 제외해 BOX암거 앞면에 없던
  서피스가 생기던 회귀를 막는다.
- 패치 행을 그 행 지반선과 직접 교차시켜 자르고 연장한다(trimSlopeToGround).
- 날개 사다리꼴 몫만큼 패치 행 범위를 넓히고(wingSpanOf), 날개벽 평면 스케치는
  트림하지 않는다. BOX암거는 행 가로 방향을 기준 측점 좌향으로 고정한다.
- 구조물 안착 자리 원지반 재노출: 원본 성토 스케치 − (구조물 ∪ 변형 성토 스케치)를
  코리도 스트립에서 빼 지형을 남긴다(PlanLoopRegion·SubtractedRegion 신설).
- BUILD_VERSION 63 → 67: 저장본을 만료시켜야 기하 수정이 화면에 반영된다.

자체검증: 스커트 3리본 56판(최대 낙차 0.92m), 원지반 +2,104 삼각형,
tmp/tests 213 passed, typecheck·prettier 통과.
남은 작업: 세월교 날개 사다리꼴 채우기(날개 축 스윕) — 다음 세션.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 18:42:15 +09:00
eomsangdonandClaude Opus 5 4a5a98fe44 feat(B05): 구조물 구간 성토면을 B06 구간 배열대로 되메운다
B06 횡단이 내는 변형 성토선을 3D 포켓에 되메운다. 다단 기슭막이면 횡단이
성토 > 구조물 > 성토 > 구조물 > 성토라 성토선이 하나가 아니다 — 합치지 않고
구간 1줄 = 리본 1장으로 낸다.

- Station_Structure: StructureSilhouette.fillRuns 추가. 31점 폴리라인을 인덱스로
  쪼개지 않고 B06 배열(outletFill/basinFill.segments, ford fillSegments, box
  fillLine)에서 바로 담는다. 벽 전면은 안 담는다 — 구조물 솔리드 몫.
- Carve: 패치 리본을 실루엣당 1장이 아니라 run당 1장. 구간 배열을 쓸 때는 벽 트림을
  걸지 않는다 — 바깥 끝 하나로 자르는 규칙이라 단 사이 구간이 아랫단 벽 바깥까지
  통째로 잘려 사라졌다(실측: 0.86m 구간 2개 전멸). 배열이 비면 리본도 없다.
- Build: FILL_PATCH_APPLY 신규(옛 CARVE_APPLY 대체). 투영 커브·절취를 다 낸 뒤
  붙인다 — 먼저 넣으면 투영선이 패치에서 z를 읽어 절취 경계가 달라진다.
- Viewer: snapCorridorEdges에서 패치 제외. B06 성토 구간은 벽 뒷면·구체 최상단에서
  끝나는 게 정상인데 지형에 스냅해 4.1m 세로 지느러미가 생겼다(실측).
- BUILD_VERSION 60 -> 63.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 16:04:51 +09:00
eomsangdonandClaude Opus 5 106536b145 fix(B05): 측벽을 본 구조물·날개 **머지 영역의 경계**로만 세운다
절취 영역은 본 구조물 스트립과 날개 사다리꼴을 **합친 것**인데, 벽은 두 스케치의
변을 따로 세우고 있었다. 그래서 한쪽 영역의 변이 다른 영역 **안쪽**을 지나는 구간
(속살)에도 벽이 섰다 — 세월교 좌측 실측: 날개 광선 1.87m·1.77m 구간이 스트립 안에
통째로 잠겨 있었다(2026-08-27 사용자 지적).

직전 커밋(86d1d6ac)은 날개가 있는 측의 끝 횡단선을 통째로 뺐는데, 그러면 날개가
못 덮는 도로 쪽 구간이 비어 반대로 모자랐다. 되돌리고 **경계 트림**으로 바꾼다.

- Plan: `trimToUnionBoundary()` 신설 — 벽 후보 변을 다른 영역 테두리와의 교점에서
  쪼개고, 조각 가운데가 다른 영역 안이면 버린다. 2cm 미만 부스러기도 버린다.
  세트마다 벽 후보(스트립 끝 횡단선 2개 + 날개 [끝선→날개→끝선])와 근거 영역을
  모아 두었다가 세트가 끝날 때 한 번에 `cut-wall`로 낸다.
- BUILD_VERSION 59 → 60.

검증(실빌드 데이터, 구간 중점 양옆 2cm 판정):
- 8개 세트·측 **전부 경계 100%** — 속살(양옆 다 안쪽) 0, 영역 밖 0.
- 구간 수 세트당 2~8(84.3 2 · 149.73 6 · 200.92 8 · 275.71 2), 벽 판 16장/측,
  삼각형 32개/측, 판 길이 0.17~11.52m, 최대 높이 3.15m.
- 노견선·성토 끝선 위 판 0 유지.
- ISO 근접 캡처: BOX·세월교 절취부 옆면이 큰 판으로 이어지고 구멍 없음.
- npm run typecheck 통과, prettier 적용.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 12:55:49 +09:00
eomsangdonandClaude Opus 5 86d1d6ac13 fix(B05): 날개벽이 있는 측은 스트립 끝 횡단선 벽을 빼 중복을 없앤다
날개 사다리꼴 벽면이 이미 그 자리를 막는데 스트립 끝 횡단선 벽이 같은 자리에 한 장
더 서 있었다(2026-08-27 사용자). 날개벽을 낸 측은 끝 횡단선을 안 낸다.
날개가 없는 세트(파형강관 84.3·275.71)는 종전대로 끝 횡단선이 유일한 측벽이다.

- Plan: 세트마다 `wingWallSides`를 모아, 그 측은 `cut-wall`에 끝 횡단선을 안 담는다.
- BUILD_VERSION 58 → 59.

검증(실빌드 데이터):
- 벽 판 20 → **16장**(삼각형 40 → 32), 좌·우 동일.
- 세트별 벽 자리: 149.73·200.92는 날개 6마디만, 84.3·275.71은 끝 횡단선 2마디.
- 끝선(노견·성토 끝단) 위 판 0 유지, 벽 최대 높이 3.18m 불변.
- ISO 근접 캡처에서 구멍 없음 — 겹쳐 있던 판만 사라졌다.
- npm run typecheck 통과, prettier 적용.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 12:07:53 +09:00
eomsangdonandClaude Opus 5 93945d356c feat(B05): 측벽을 셀이 아니라 평면 스케치에서 바로 세운다
사용자 지적: 벽이 셀 단위 조각으로 깔린다(세월교 한 세트에 96~111조각, 길이
5~20cm). 절취가 평면 스케치 기준이었으니 벽도 스케치에서 바로 만들면 된다.

- Plan: `cut-wall` 소스 신설 — 벽이 설 자리만 담은 **열린 폴리라인**이다.
  · 비탈 스트립은 **양 끝 횡단선** 2개(긴 변은 노견선·성토 끝선이라 뺀다).
  · 날개 사다리꼴은 [끝선 교점 → 날개 시작 → 날개 끝 → 끝선 교점] 하나
    (`wingBoxLoops`가 `{loops, walls}`를 돌려준다).
- Cut: `SkirtBuilder`(셀 훑기) 제거. `cut-wall` 커브 마디마다 판 하나를 세우고,
  표고는 성토 리본에서 읽는다(`sampleRibbon` — 행은 XY상 직선이라 점을 그 선분에
  투영해 서피스 z·원지반 z를 같은 자리에서 보간). 밑선은 원지반 − 1m 유지.
- Mesh: `cut-wall` 커브는 선으로 안 그린다(벽 서피스로만 나간다).
- BUILD_VERSION 57 → 58.

검증(실빌드 데이터):
- 벽 삼각형 852/824 → **40/40**(판 20장씩). 판 길이 0.17~11.52m, 중앙 2.0~2.4m
  (종전 세월교 조각 길이 중앙 5~10cm).
- 노견선·성토 끝선 위를 달리는 판 **0**(양측). 벽 최대 높이 3.18m.
- ISO 근접 캡처: BOX암거·세월교 절취부 옆면이 큰 판 몇 장으로 막힌다. 바닥은 열림.
- npm run typecheck 통과, prettier 적용.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 12:01:50 +09:00
eomsangdonandClaude Opus 5 b9938dfa18 fix(B05): 노견 쪽·성토 끝단 쪽 리본 경계에는 측벽을 세우지 않는다
거기서 잘린 게 아니라 리본이 끝난 자리다(2026-08-27 사용자).

- 통째로 지운 셀의 모서리 벽: 열 방향 이웃이 리본 밖이면 건너뛴다(`col > 0`,
  `col < cols - 2`). 행 방향(노선 앞뒤)은 종전대로.
- 걸친 셀의 교점 직선: 두 교점이 모두 안쪽 끝(노견)이나 바깥 끝(성토 끝선) 위를
  달리면 건너뛴다. 판정은 **열 좌표 기준 ±0.1열**(셀 폭의 10%) — 커브가 끝선과
  나란히 지나면 교점이 가로 모서리에 걸려 열 좌표가 3~5mm 빗나간다(실측).
- BUILD_VERSION 55 → 57.

검증(실빌드 데이터):
- 벽 삼각형 1,450/1,358 → 852/824(우/좌).
- 성토끝단선 위를 달리는 벽 구간 8/6 → **0**, 노견선 위 2/2 → **0**
  (구간 길이 3cm 이상, 선까지 거리 1cm 이내 기준).
- 벽 ↔ 절단커브 거리는 그대로 중앙값 0.000m. 리본 조각 삼각형 814/787 불변.
- npm run typecheck 통과, prettier 적용.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 11:18:32 +09:00
eomsangdonandClaude Opus 5 d70908f973 fix(B05): 측벽을 격자 계단이 아니라 실제로 잘린 선에 세운다
사용자 지적: 벽이 최종 절단면이 아니라 셀 격자를 따라간다. 실측으로 확인 —
벽 정점이 리본 격자점과 100% 일치하고, 실제 절단커브까지 거리 중앙값 5.6~5.9cm
최대 21~30cm(셀 대각선 크기)였다. 격자는 재배치 후(0.2m) 격자가 맞았고, 문제는
`pushSkirt`가 마스크 격자 윤곽을 그대로 밀어낸 것이었다.

- `clipCellByChord`가 남길 조각과 함께 **교점 직선**(chord)을 돌려준다.
- `SkirtBuilder` 신설 — 걸친 셀은 그 셀을 자른 교점 직선에, 통째로 지운 셀은
  **안 지워진 이웃 쪽 모서리**에만 벽을 세운다(걸친 셀은 조각이 모서리까지 덮으므로
  모서리 벽을 세우지 않는다). 밑선은 원지반 − 1m, 교점 위 점은 원지반을 이중선형 보간.
- `traceMaskLoops` 기반 스커트 제거(그 함수는 `cut-merged` 표시 커브에만 남는다).
- BUILD_VERSION 54 → 55.

검증(실빌드 데이터):
- 벽 ↔ 절단커브 거리: 중앙값 0.000 · p90 0.000 · 평균 0.001/0.000 · 최대 0.091/0.010m
  (종전 중앙값 0.056/0.059 · 최대 0.213/0.298).
- 격자점과 일치 100% → 71.6/71.8%(나머지는 교점 위 점 = 격자 밖).
- 벽 삼각형 360/356 → 1,450/1,358. 리본 조각 삼각형 814/787 불변.
- ISO 화면에서 절취부 테두리 계단이 사라졌다.
- npm run typecheck 통과, prettier 적용.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 11:08:19 +09:00
eomsangdonandClaude Opus 5 e9914af675 fix(B05): 절취 측벽에서 빗금을 뺀다
벽은 방향성을 표현하는 면이 아니다(2026-08-27 사용자). 성토면 빗금은 그대로 두고
벽만 단색으로 그린다.

- Mesh: 벽 재질에서 `map`(빗금 텍스처)과 uv 속성을 뺀다.
- Cut/Build: 벽이 UV를 안 쓰므로 `CorridorCutWall.uvs`와 수집 코드를 지운다.
- Corridor: 저장본에서 `uvsBase64` 제거, ENVELOPE_VERSION 4 → 5.

검증: 재빌드 후 벽 서피스 우 360·좌 356 삼각형 그대로, `uvs` 필드 없음.
ISO 화면에서 벽면이 단색, 주변 성토면 빗금은 유지. npm run typecheck 통과, prettier 적용.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 10:54:04 +09:00
eomsangdonandClaude Opus 5 43804f2f5b feat(B05): 절취 측벽을 별도 서피스로 빼고 원지반 아래 1m 여유를 준다
측벽을 성토 리본 메시에 섞지 않고 **구조물처럼 별도 서피스**로 낸다(2026-08-27
사용자). UV·법선이 리본에 묶이지 않아 다음 단계(구조물 안착 바닥면·트림)에서 따로
다룰 수 있다. 밑선은 원지반에서 **1m 더 내린다** — 지반 보간 오차만큼 밑이 뜨는 걸
막고, 지형은 코리도 자리에서 이미 잘려 있어 여유분은 가려진다.

- Build: `CorridorCutWall`(삼각형 수프 + UV) 추가, 빌드 결과에 `cutWalls`로 싣는다.
- Cut: 벽 삼각형을 `trimTris`에서 분리해 `walls`로 돌려준다. `SKIRT_MARGIN_M = 1`.
- Mesh: 벽마다 메쉬를 따로 만든다(`corridor-cut-wall:{측}:{번호}`) — 색·빗금은
  성토와 같아 한 몸으로 보이되 객체는 분리.
- Corridor: 저장본에 `cutWalls` 담고 ENVELOPE_VERSION 3 → 4, BUILD_VERSION 53 → 54.
- Viewer: 검증 훅 `raw`에 `cutWalls` 추가.

검증(실빌드 데이터):
- 리본 조각 삼각형 우 814·좌 787(벽 빠짐), 벽 서피스 삼각형 우 360·좌 356.
- 벽 높이 최소 1.00m(여유분) / 평균 2.26·2.87 / 최대 3.80·6.25m — 1차 대비 정확히 +1m.
- ISO 화면: BOX·세월교 절취부 옆면이 벽으로 막히고 바닥만 열려 있다(다음 작업).
- npm run typecheck 통과, prettier 적용.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 10:46:19 +09:00
eomsangdonandClaude Opus 5 86a20cccb4 feat(B05): 절취 윤곽을 z로 밀어내 측벽을 세우고 성토면에 머지한다
자를 때 쓴 평면 스케치(절취 윤곽)를 z축으로 밀어내 성토면 ↔ 원지반을 잇는 측벽을
세운다(2026-08-27 사용자). 벽은 성토 리본과 **같은 메쉬·같은 재질**에 담아 별도
서피스가 아니라 머지된 한 면으로 그려진다. 구조물이 안착된 성토부 방향(바닥)
서피스는 다음 작업.

- Build: 성토 리본에 격자점별 원지반 표고 `groundZ`를 싣는다(행 지반선을 rows에
  보관해 flush에서 offset으로 읽는다). 벽의 밑선이다.
- Cut: `pushSkirt()` — 절취 윤곽 모서리마다 [서피스 z → 원지반 z] 사각형을 삼각형
  둘로 세워 `trimTris`에 함께 담는다. UV는 u=누가거리/2, v=z/2로 빗금이 세로로도
  실척으로 이어진다. 높이 0인 구간(성토 끝선)은 건너뛴다.
- Corridor: BUILD_VERSION 52 → 53.

검증(실빌드 데이터):
- 벽 삼각형 우 417·좌 418(조각 삼각형 합계 1,166·1,135), groundZ 적재 확인.
- 벽 높이 우 0.001~2.80m(평균 1.08)·좌 0.003~5.25m(평균 1.61).
- ISO 화면에서 세월교·BOX암거 절취부 옆면이 청록 벽으로 막혔다. 바닥은 아직 열림.
- npm run typecheck 통과, prettier 적용.

남은 것: 벽이 격자 모서리를 타 6cm×0.2m 계단이 보인다(교점 직선으로 세우면 없어진다).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 10:35:31 +09:00
eomsangdonandClaude Opus 5 2daaf127b8 feat(B05): 날개벽 사다리꼴을 절취 영역에 합치고 병합 커브를 새 데이텀에 낸다
날개벽이 있는 구조물(세월교·BOX암거)도 절취한다. 평면 스케치에 이미 사다리꼴
(`wing-box`)이 있으므로 **비탈 투영선과 XY 합집합**으로 묶어 한 번에 자른다
(2026-08-27 사용자). 어디가 잘리는지 눈으로 보려고, 잘린 자리 윤곽을 **현 평면
대비 +3m 새 데이텀**에 `cut-merged` 커브로 따로 낸다. 기존 평면 커브는 그대로 둔다.

- Cut: `CUT_SOURCES`에 `wing-box` 추가. 마스크된 셀 덩어리의 격자 윤곽을 추적해
  (`traceMaskLoops` + 직선 구간 점 버리기) 병합 커브를 만든다. 반환형이
  `{ribbons, curves}`로 바뀐다.
- Plan: `cut-merged` 소스 추가. Mesh: 라임 `0x84cc16`.
- Build: Cut이 돌려준 커브를 planCurves 뒤에 이어 붙인다.
- Corridor: BUILD_VERSION 51 → 52.

검증(실빌드 데이터):
- 마스크 셀 우 6,611→7,856(+1,245)·좌 6,237→6,925(+688). 조각 삼각형 711→814·728→787.
- 합집합 기준 안쪽인데 남은 셀 0, 완전 바깥인데 지운 셀 0(좌·우).
- 병합 커브 8개(좌우×4세트), z가 전부 세트 평면 +3.00m 정확
  (542.05→545.05 / 535.6→538.6 / 540.2→543.2 / 544.76→547.76).
- 화면: BOX·세월교 절취부가 날개 따라 사다리꼴로 벌어지고 라임 커브가 그 윤곽을 덮는다.
- npm run typecheck 통과, prettier 적용.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 09:59:10 +09:00
eomsangdonandClaude Opus 5 f4a3cb7b44 fix(B05): 절단 실패 셀을 안쪽 면적 비율로 갈라 경계 잔여 메쉬를 지운다
투영 커브 경계 주변에 미세한 성토 메쉬가 남던 문제(사용자 보고). 원인은
`clipCellByChord`가 자를 직선을 못 세운 셀을 **통째로 남기던** 폴백이다.

저장 코리도 실좌표로 셀을 재현해 보니 절단 실패 셀 627개(우 314·좌 313) 중
**622개가 셀 안쪽 비율 1.00** — 속은 통째로 커브 안인데 귀퉁이가 경계에 딱 붙어
`inCount === 4` 판정을 못 받고 걸친 셀로 내려간 뒤, 바깥 귀퉁이가 없어 `keepSign`을
못 잡은 셀들이었다(no-keepsign 491 · degenerate-chord 122 · 교점<2 14).

- Cut: `coverage()` 추가(4×4 이중선형 표본) — 절단 실패 셀만 안쪽 비율로 가른다.
  0.5 이상이면 마스크, 미만이면 종전대로 남긴다. 정상 절단 경로·정점은 불변.
- Corridor: BUILD_VERSION 50 → 51(기하 변경 — 안 올리면 옛 저장본이 복원된다).

검증:
- 실빌드 데이터(공용 브라우저 `__corridorBuild.raw`): 안쪽인데 남은 셀 **0**(좌·우),
  커브 밖인데 지운 셀 **0**. 마스크 셀 우 6,611·좌 6,237, 조각 삼각형 711·728.
- 같은 카메라 전후 스크린샷: 바뀐 픽셀의 수정 전 색이 성토면 청록 5,831 → 수정 후 14.
  투영선·스케치선 픽셀은 그대로 — 지워진 건 성토 메쉬뿐이다.
- 저장본 시뮬레이션: 잔여 우 2.17㎡·좌 4.50㎡ → 0.00㎡, 과절단 합 0.0011㎡.
- npm run typecheck 통과, prettier 적용.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-27 07:25:39 +09:00
eomsangdonandClaude Opus 5 753e8fcb44 feat(B05): 투영 커브 안쪽 성토면을 셀 단위로 지운다
빨간 투영선이 감싸는 자리의 성토면을 지운다. 지울 영역은 결국 **상단 평면 스케치가
덮는 XY 영역** 하나이고 투영선이 그 XY를 그대로 복사한 것이므로, 구조물 종류를
가리지 않고 한 가지 방법으로 자른다(사용자 확정).

- Cut(신규): 격자 셀 중심·귀퉁이로 안팎을 가려 안쪽 셀은 마스크하고, 걸친 셀은
  교점 두 개가 만드는 직선으로 잘라 바깥 조각만 삼각형으로 되살린다. 정점은
  하나도 안 건드린다. 교점이 2개 미만이면 셀을 통째로 남긴다 — 모자라게 자를지언정
  더 자르지 않는다.
- Build: CorridorRibbon에 cellMask·trimTris·trimUvs 추가.
- Mesh: 마스크된 셀의 삼각형을 빼고, 조각 삼각형을 뒤에 이어 붙인다.
- Plan: BOX암거 커브의 **안쪽 끝도 박스 축**으로 쏜다(boxInner + castToToe).
  종전엔 바깥만 박스 축이고 안쪽은 노선 흐름이라 가로대가 비스듬했다 —
  평면 스케치의 횡단 방향은 박스가 놓인 전역 단방향이어야 한다(사용자 확정).
- Corridor: 저장본에 마스크·조각 삼각형을 담고 BUILD_VERSION을 올린다.

검증(공용 브라우저 캐시 데이터 실측):
- BOX 커브 가로대 각도차 0.00°(좌·우) — 전역 단방향 확인. 다른 세트는 노선 흐름대로
  1.1~48.8°.
- 걸친 셀에서 되살린 조각 면적이 기대치와 일치 — 우 2.07㎡ vs 2.07, 좌 4.60 vs 4.61.
- 커브 밖을 지운 셀 0. 도로부·측구·절토 리본 행 수 불변(1768/1768/1768/15/26/23/13).

남은 것: 걸친 셀 1,230개 중 약 600개가 교점 부족으로 통째로 남아 경계에 잔여가
생긴다(우 2.09㎡·좌 4.36㎡). 더 잘리는 문제는 없다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 22:32:35 +09:00
eomsangdonandClaude Opus 5 398b5bdffd feat(B05): 탑뷰 스케치 파란 커브를 절·성토면에 투영해 빨간 선으로 얹는다
구조물 상단 +5m 평면에 눕혀 두던 파란 스케치(slope-original, 유입 실선·유출 파선)의
XY를 그대로 쓰고 z만 그 자리 절·성토면에서 읽어 빨간 투영선(slope-projected)으로
낸다. 스케치는 평면에 그대로 남는다. 투영선이 격자 모서리에 앉도록 구조물 점유
구간 경계를 코리도 행으로 끼워 넣는다.

- Plan: slope-projected 소스 추가. 리본을 받아 `측|누가거리` 색인을 만들고 그 행의
  열 폴리라인에서 z를 읽는다. 절토·성토 모두 대상. 밑에 면이 없으면 점을 버려 끊는다.
- Plan: 파란 스케치 안쪽 기준을 소유 측점 노견 편거리 → **그 행 절·성토면이 실제로
  시작하는 자리**로 바꿨다. 종전에는 노폭 연장·측구를 못 따라가 커브가 면 밖(도로 위)에
  얹혔다 — 275.71 좌측은 노견 4m 확장분만큼 안쪽이었다.
- Plan: 비탈 리본 열 순서가 좌우 반대(조각은 편거리 오름차순, +offset=좌측)라 우측에서
  안쪽 끝을 반대로 집었다. 색인 단계에서 안쪽→바깥으로 방향을 통일한다.
- Mesh: 커브를 점의 z로 그린다(평면 커브는 z에 planZ가 들어 있어 동작 불변).
  투영선 색 = 빨강 0xff3b30, 서피스에서 0.02m 띄운다.
- Build: 구조물 구간 [from, to]를 행 경계로 강제 삽입. 안쪽 블록 걸음은 상수로 뺐다
  (지금은 바깥과 같은 0.2m — 경계 행만 새로 생긴다).
- Corridor: 저장본은 입력 해시로만 무효화되어 기하 코드를 고쳐도 옛 저장본이 계속
  복원된다. ENVELOPE_VERSION을 올리고 그 함정을 주석으로 박았다.
- Viewer: 검증용 __corridorBuild 훅(기존 __corridorClip과 같은 용도).

검증(공용 브라우저 캐시 데이터 실측):
- 3D 회귀 없음 — 외곽선 행 1756→1768, 기존 1756행 좌표까지 전부 불변, 추가된 12행은
  구조물 구간 경계뿐(79.3·83.3·85.3·89.3·144.73·154.73·199.72·202.12·270.71·
  274.71·276.71·280.71). 측구·절토 리본 행 수 불변.
- 투영선 안쪽 끝 8벌 전부 서피스 시작점과 XY·Z 정확 일치(gap 0, dz 0).
- 바깥 끝은 XY 일치, z만 최대 1.01m 차 — 세월교 날개벽·다단 기슭막이 앞면처럼
  거의 수직인 면이라 한 XY에 z가 여럿인 구간이다. 규칙 확정은 후속.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 21:51:54 +09:00
eomsangdonandClaude Opus 5 d857d3d48a fix(B06): 인접 측점에 남던 집수정 트림을 지워 성토선을 살린다
trimLinkedLayout이 링크(인접) 측점 카드에서 구조물 도형만 지우고, 그 구조물이
만든 설계선 트림(designTrim)과 성토부선은 스프레드로 통과시켰다. 집수정은 조작량이
0이면 대체 사면선(minSlope/maxSlope)도 없어서, 구조물은 안 그려지는데 설계선만
노견 밖에서 끊겼다 — 4측점(80.0m, 관 84.3m)·14측점(280.0m, 관 275.71m) 성토선 삭제.

- keepTrimSides(): 살아남지 못한 쪽의 트림을 ∓Infinity로 되돌리고 그쪽
  Elevation·Slope를 뺀다. 양쪽 다 없으면 designTrim = null.
- 집수정은 링크 측점에 서지 않으므로 유입 쪽 트림은 언제나 지운다.
- 연장 밖 유출 벽의 outletFill, 집수정에 딸린 basinFill도 함께 비운다.
- 유입이 min·max 어느 쪽인지는 관 양 끝 offset 대소로 가른다.

3D 무영향: trimLinkedLayout은 export되지 않고 유일한 호출자 computeCardCulvert는
B06 Cross_View만 import한다. B05 코리도는 computeCulvertLayout을 직접 부르며 소유
측점에서만 돈다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 19:58:05 +09:00
eomsangdonandClaude Opus 5 ce77e0735f fix(B05): 세월교 본 바닥·날개 바닥·에이프런을 한 면으로 맞춘다
원인은 종단경사 보정(dz)이었다. 세월교 본체(측벽·바닥판)는 dz를 타서 양끝이
들린 사발 모양인데(앞끝 +0.0907 / 측점 0 / 뒤끝 +0.1613) 날개벽·에이프런은
dz = 0으로 측점 표고에 평평히 놓였다. 접합부 틈 0.0907·0.1613m이 그 dz와
소수점까지 일치했다. 표고 자체는 이미 같았다 — 어긋난 건 dz뿐이다.

본체는 그대로 두고 날개·에이프런을 경사에 태운다(사용자 선택).

- `buildWingSolids`에 선택 인자 `baseElevationM` 추가 — 넘기면 날개·에이프런
  링이 붙는 자리의 dz(end.designZ − baseElevationM)를 탄다. 세월교만 넘기고
  BOX암거는 안 넘겨 dz = 0 현행을 유지한다.
- 에이프런을 본 바닥판과 한 장으로 만든다. ① 밑변을 판이 밀려들어간 뿌리가
  아니라 바닥판 끝면 그 자리에서 시작한다. ② 단면을 직사각형 근사 대신 바닥판
  폴리곤 그대로 쓴다(뿌리 offset 기준으로 다시 잡아 끝으로 갈수록 0으로 줄인다).
  종전엔 사다리꼴 바닥판(2.669~4.283)을 직사각형(2.747~4.283)으로 근사해
  안쪽 모서리가 0.078m 어긋났다.
- `BUILD_VERSION` 39 → 40.

실측: 에이프런 밑변 4꼭짓점이 본 바닥판 끝면 꼭짓점과 거리 0.0000m(4장 전부).
날개·에이프런 dz가 붙는 자리 값을 그대로 타고 같은 자리의 날개와 에이프런이
같은 dz다. 회귀 없음 — 아령 벌어짐 유지, 날개 바깥 세로선↔구체 측면 8장 전부
0.0000m, 성토끝 박스 4/4·4/4.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 18:38:30 +09:00
eomsangdonandClaude Opus 5 392e471dce feat(B05): BOX암거 비탈 투영 커브를 박스 방향 단일축으로 긋는다
원본·변형 성토면 투영 커브는 행마다 그 자리 노선 프레임을 써서, 곡선 구간이면
가로 방향이 행마다 틀어져 커브가 뒤틀린다. BOX암거는 날개벽처럼 박스 방향
하나로 그어야 한다(사용자).

BOX암거 세트만(`section.box`) 행 자리는 노선 위 그대로 두고 가로 방향만 기준
측점 좌향으로 고정한다. 세월교·배수관은 종전대로 그 행의 노선 프레임을 쓴다.

원본 커브의 바깥 끝은 그 행의 코리도 윤곽 점을 그대로 썼는데 가로 방향이
고정되면 어긋나므로, 고정 방향으로 쏜 선이 성토 끝선과 만나는 자리를 바깥
끝으로 삼는다(`castToToe`를 공개로 돌려 재사용). 끝은 여전히 실제 성토 끝선
위다. `BUILD_VERSION` 37 → 38.

실측(한 커브 안 행별 가로 방향 분산, ±180 감김 보정): BOX 200.92는 원본·변형
× 좌·우 4개 모두 0.00°. 배수관 84.3 11.42~50.80°, 세월교 149.73 22.84~23.02°,
배수관 275.71 2.28~8.95°로 그대로다. 행 손실 없음 — BOX 변형 6행·원본 13행.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 18:27:26 +09:00
eomsangdonandClaude Opus 5 96be8fe233 fix(B05): 날개벽 바깥 세로선을 구체 측면에 붙여 단을 없앤다
날개 판이 축 위에 가운데 정렬이라, 뿌리를 구체 측면에 놓으면 절반(두께/2)이
측면 밖으로 삐져나와 투영 커브에 단이 졌다.

각도 틸팅 방식은 그대로 두고 판을 축을 따라 뒤로 민다 — 바깥쪽 세로선이 측면에
닿는 데 필요한 양은 (두께/2) × |cos각| / sin각 = (두께/2) × cot각이다. 각이
아주 작으면 cot이 발산하므로 날개 길이의 절반으로 자른다. 세월교·BOX암거 둘 다
적용한다(사용자가 둘 다 지목). 에이프런도 새 뿌리를 따른다.
`BUILD_VERSION` 36 → 37.

실측: 뿌리 링의 바깥 세로선이 구체 측면 평면에서 떨어진 거리가 세월교 4장·BOX
4장 전부 0.0000m. 안쪽 세로선은 0.1414m 안으로 박힌다(= 두께 0.2 × cos45°).
회귀 없음 — 아령 벌어짐 유지(149.73 좌 10.73 → 14.02m, 우 8.63 → 10.81m,
200.92 2.26 → 5.08m), 성토끝 박스 4/4·4/4, 에이프런 4장·0장, 기준 직선 이탈 0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 18:20:41 +09:00
eomsangdonandClaude Opus 5 a8793819af feat(B05): 세월교 날개 투영 커브를 노선 흐름에 맞춰 긋는다
성토끝 박스 옆선이 날개 4장 전부 기준 측점의 고정 좌향을 쓰고 있었다. 세월교는
날개가 저마다 다른 자리의 노선 프레임에 붙는데 커브만 한 방향이라 흐름과 어긋난다.
박스암거는 그 고정 방향이 맞으므로 유지한다(사용자).

방향을 구조물에 실어 보낸다 — `CorridorStructure.wingAxis`(단위벡터). 세월교
날개를 만들 때 그 자리 노선 프레임의 좌향을 담고, `wingBoxLoops`가
`structure.wingAxis ?? 측점 좌향`으로 고른다. Plan 쪽에 새 배관이 없다.
`wing` 표식은 `true` → `"station" | "route"`로 바꿔 어느 규칙으로 만든 날개인지
남긴다(문자열이라 기존 truthy 검사는 그대로 통한다). `BUILD_VERSION` 35 → 36.

실측: 149.73 날개 4장 모두 route, 실어 보낸 축이 기준 측점 좌향과 −20.45°/+2.57°
어긋난다. 박스 옆선 각도가 그 값과 정확히 일치(좌 −20.45°·2.57°, 우 159.55°·
−177.43° = 같은 축 반대 방향). 200.92는 4장 모두 station, 옆선 0°·−180°로 무변화.
박스 4/4·4/4, 에이프런 4장·0장, 기준 직선 이탈 0.0000m.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 18:13:29 +09:00
eomsangdonandClaude Opus 5 24bc9480a5 fix(B05): 세월교 날개벽이 오므라들던 것을 벌어지게 정정
위에서 봤을 때 아령처럼 유입·유출부가 커져야 물을 받는다(사용자). 그런데 노선
프레임 경로에서 앞뒤 기준이 뒤집혀 세월교 날개가 오므라들었다.

뿌리는 frameAt(측점 + along × 반폭)으로 누가거리 기준으로 잡는데, 벌어지는
방향은 dir × along으로 측점 로컬 기준을 쓴다. 이 프레임의 dir은 누가거리가
줄어드는 쪽을 향해 둘이 반대였다 — 뿌리가 벌어짐 방향의 반대편에 앉는다.
실측: 149.73 날개가 (−3.65, 종 3.88) → (−4.48, 종 2.06)으로 종방향이 0에
가까워졌다. BOX암거는 뿌리·방향이 같은 기준이라 영향이 없었다.

부호를 가정하지 않는다. 측점 ± 반폭 두 자리를 다 뽑아 `along` 방향에 놓인 쪽을
고른다(`endFrameOf`) — 누가거리 부호와 진행 방향 부호가 반대인 노선에도 맞는다.
`BUILD_VERSION` 34 → 35.

실측: 같은 측 두 날개의 종방향 간격이 뿌리 → 끝으로 커진다. 149.73 좌 10.89 →
14.19m, 우 8.74 → 10.92m. BOX 200.92는 2.40 → 5.22m로 정정 전과 동일(무변화).
파생물 회귀 없음 — 에이프런 4장(기준 직선 이탈 0.0000m), 성토끝 박스 4/4·4/4.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 18:10:50 +09:00
eomsangdonandClaude Opus 5 bad291f720 feat(B05): 세월교 날개벽을 노선 흐름에 태우고 바닥 에이프런 추가
세월교 측벽·바닥판은 ringsOf(half, half)로 노선 스플라인을 따라가는데 날개벽만
기준 측점 프레임에서 직선으로 ±월류폭/2 자리에 뿌리를 잡아, 곡선 구간에서 측벽
끝단과 어긋났다. BOX암거는 직선 규칙이 맞으므로 건드리지 않는다(사용자 ②).

- `buildWingSolids`에 선택 인자 `endFrameAt` 추가 — 넘기면 날개 뿌리와 축을
  측벽 끝단부 자리의 노선 프레임에서 뽑는다. 세월교만 `frameAt`을 넘긴다.
  안 넘기면 계산이 옛 식과 완전히 같다(BOX 무변화).
- `WingAnchor.apron` 추가 — 세월교 바닥 에이프런. 날개 끝점과 바닥판 종방향
  끝점을 이은 직선을 외곽으로 하는 평면 삼각형을 바닥 두께로 세운다(사용자 ④).
  링을 뿌리→날개끝으로 깔고 링 좌향을 뿌리→바닥판끝으로 잡아 폭을 |P0P2| → 0으로
  좁히는 방식이라 기존 로프트 모델을 그대로 쓴다.
- 에이프런도 `wing` 표식을 달므로 성토끝 박스 대상은 `kind === "revet"`로 좁혔다.
- `BUILD_VERSION` 33 → 34.

실측: BOX 200.92 날개 뿌리 이동량 0.000m·에이프런 0개(무변화 확인). 세월교
149.73 뿌리 이동량 0.102~1.119m, 뿌리가 측벽 끝단 링 횡단선 위(종방향 잔차 0).
에이프런 4장, 바깥 모서리가 기준 직선 위 이탈 0.0000m. 성토끝 박스는 두 세트
모두 4/4 — 앞서 막혀 있던 149.73 우측 날개 1장도 뿌리 이동으로 풀렸다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 18:06:33 +09:00
eomsangdonandClaude Opus 5 2da4ecb038 feat(B05): 날개벽 탑뷰 투영 — 판 풋프린트 + 성토끝 사다리꼴 박스
날개벽 링은 노선이 아니라 날개 축을 탄다. 그래서 링 폴리곤의 편거리가 노선
편거리가 아니라 패널 두께(±0.10m)라 노견 클립 max(−0.10, +2)에 걸려 날개벽
투영 고리가 0개였다. 실측: 링 좌향과 노선 좌향 정렬 align=0.71, 링 중심의 노선
편거리 2.74~4.16(좌)·−4.01~−2.60(우) — 이미 노견 밖이다.

- `CorridorStructure.wing` 표식 신설, `_Structures_Wing.ts`가 붙인다.
- 날개벽은 도로부 클립을 생략하고 링 위치로 측을 가린다 — 판 두께 × 날개 길이
  직사각형이 나온다.
- `wing-box` 커브 신설(주황) — 밑변은 날개 시작~끝 모서리, 양 옆선은 구조물 축
  (측점 좌향 벡터)과 평행한 고정 직선, 바깥 변은 원본 성토 최하단 끝선 그대로.
  노선 곡률을 따라 각도가 바뀌지 않는다(사용자 확정).
- 성토 끝선은 세트 ±40m만 잘라 쓰고 사거리 15m로 조인다 — 안 조이면 헤어핀
  건너편 끝선에 걸려 −29m짜리 박스(점 115개)가 나온다.
- 교점 탐색은 광선이 아니라 양방향 직선이다 — 세월교 날개는 끝이 성토 끝선
  밖이라(4.16 vs 2.60) 바깥으로만 쏘면 통째로 빠진다.
- `BUILD_VERSION` 32 → 33.

실측: 판 고리가 측당 2장씩 n=11로 살아났다. 박스는 200.92 4/4, 149.73 3/4.
박스 바깥 변의 점은 전부 성토 끝선 위(이탈 0.000m). 149.73 우측 날개 1장은
그 자리에 끝선이 없어 안 그린다 — 처리 방침은 사용자 확정 대기.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 17:47:12 +09:00
eomsangdonandClaude Opus 5 5c8986d46c fix(B05): 구조물 투영 커브를 부재별로 표기 · 저장본 판번호 상향
화면이 안 바뀐 원인은 저장본 캐시였다. `BUILD_VERSION`을 안 올려 코리도 해시가
그대로였고 서버 저장본(planCurves 20개)이 재사용됐다. 실측으로 확인 — 저장본
hash 95cafe53 vs 새 코드 hash 0e67c470. 31 → 32로 올려 만료시킨다.

그리고 겹친 부재를 하나로 머지하지 않는다(사용자: "구조물은 머지하지 말고
표현할 것, 나중에 한번에 진행 예정"). 링 경로 그룹핑·구간 병합을 빼고 부재마다
고리 하나를 낸다.

배관은 투영 면적에서 계속 뺀다 — 다른 부재가 감싸고 있는 구조라는 사용자 확정.

실측(링 횡단선 되투영, 이탈 최대 0.0000m): 84.3 고리 4개 — 집수정 상·하단
2.000~2.650 각 31점, 기슭막이 상단 −2.946~−2.000·하단 −3.250~−2.000 각 47점.
149.73 8개, 200.92 10개(날개벽 4장 각각), 275.71 4개.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 17:25:41 +09:00
eomsangdonandClaude Opus 5 b29113ba22 fix(B05): 구조물 탑뷰 풋프린트를 링별 편거리 병합으로 재구현
기하 합집합(`_Corridor_Union.ts`)이 겹친 스트립에서 무너졌다. "같은 토막이
짝수 번 나오면 버린다"는 내부 칸막이 제거 규칙이 **외곽의 공유 변까지** 지웠다.
4+4.3(84.3m)에서 집수정 두 단은 탑뷰 사각형이 완전히 같아 네 변 전부 소멸해
좌측 커브가 0개였고, 기슭막이 두 단은 안쪽 변 −1.98을 공유해 23칸이 소멸,
0.34×0.92m 쪼가리만 남았다.

합집합을 버리고 구조물이 스윕 솔리드라는 성질을 그대로 쓴다 — 링 경로가 같은
부재끼리 묶고, 링마다 편거리 창을 도로 밖으로 자른 뒤 1차원 병합해 레인으로
잇는다. 기하 불리언이 없어 퇴화 케이스가 원리적으로 없다.

- `_Corridor_Plan_Footprint.ts` 신규 — 위 알고리즘.
- `_Corridor_Plan.ts` — `structureLoops` 제거, 신규 모듈 호출.
- `_Corridor_Carve.ts` — 죽은 `outlineLoops()` 제거(`outerAt`은 유지).
- `_Corridor_Union.ts` — 죽은 `unionOutline`·`insideQuad`·`splitEdges` 제거.
  `UnionQuad`/`unionQuadOf`는 `outerAt`이 계속 쓴다. 189 → 34줄.

실측: 커브 각 점을 가장 가까운 링 횡단선에 되투영해 편거리를 읽었다 — 링선
이탈 최대 0.0000m. 84.3 좌(집수정) 2.000~2.650 31점, 우(기슭막이) −3.250~−2.000
47점으로 전 링이 살아난다. 275.71·149.73·200.92 세트도 날개벽까지 각각 나온다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 17:18:47 +09:00
eomsangdonandClaude Opus 5 25ae04b2cd fix(B05): 변형 실루엣 투영 커브를 행마다 지반선에 트림
실루엣은 소유 측점 단면 한 장이라 그대로 밀면 구간 내내 같은 폭이 됐다.
0.5m 행마다 종단경사만큼 올린 뒤 `trimSlopeToGround`로 그 행 지반과 만나는
자리까지 잘라 실제 발끝을 따라가게 한다. 표기 커브만 바뀐다 — 서피스 절단·
패치는 손대지 않았다(`CARVE_APPLY` 계속 false, 사용자 지시).

4+4.3 우측 실측: 바깥끝 offset −3.25 고정 → −2.96~−4.42(지형 따라), 행 11 → 21.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 16:24:56 +09:00
eomsangdonandClaude Opus 5 5a3b2ebe39 feat(B05): 구조물 탑뷰 투영 커브 재작성 — 세트별 상단+5m 평면·유입/유출 분리
구조물 추가 뒤 3D 투영 영역이 제대로 안 만들어지던 문제. 평면고가 구조물과
무관한 모델 전체 최고표고였고, 구조물 커브와 비탈 커브가 다른 기준으로 따로
나왔으며, 성토면 표면 위에도 절단 투영선이 겹쳐 그려져 이중 표기였다.

- `_Corridor_Plan.ts` 신규 — 구조물 세트(같은 측점 소유)별로 투영 평면을
  그 세트 구조물 최고표고 +5m에 잡고, 유입/유출을 나눠 커브를 만든다.
  세트당 구조물·비탈(변형 실루엣)·비탈(원본 성토선) × 유입/유출.
  도로부(노견 안쪽)는 전 커브에서 빼 좌우가 끊긴 두 루프가 된다.
- `_Corridor_Carve.ts` — 투영 전용 함수(풋프린트 평면 투영·유입유출 판정·
  절단 트레이스 조립) 삭제, `ringEdges` 공개. 패치 리본 경로만 남겼다.
- `_Corridor_Build.ts` — 성토면 위 절단 투영선(`carveTraces`) 생성 삭제,
  `structurePlan`/`fillPlan` → `planCurves` 하나로 교체.
- `_Corridor_Mesh.ts` — 표면 위 투영선 그리기 삭제. 커브를 각자 평면고에
  종류별 색(구조물 노랑/변형 분홍/원본 하늘), 유입 실선·유출 파선으로 그린다.
- `_Corridor.ts` — 저장 코리도 봉투에 `planCurves` 포함, 형식 버전 1→2.
  안 담으면 저장본으로 복원한 코리도에서 커브가 통째로 사라진다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 09:42:35 +09:00
eomsangdonandClaude Opus 5 f6296fa7c5 feat(B05·B06): 구조물 3D 투영 표기 · 직교 카메라 · 조정창 템플릿 일원화
3D 구조물과 성토면의 관계를 "잘라내기"에서 "투영 표기"로 바꾸고, 세월교·BOX암거
조정창을 기슭막이 템플릿으로 통일했다.

B05 코리도
- 구조물 탑뷰 투영 산출(_Corridor_Carve.ts 신규): 구조물 솔리드 링 사이 실좌표
  사각형 + 변형 성토면 영역. 노선 파라미터가 아니라 행 횡단선과 실좌표로 교차시켜
  곡선 구간·날개벽 벌어짐이 그대로 잡힌다.
- 사각형 합집합 경계(_Corridor_Union.ts 신규): 변을 교점에서 토막 내고 내부·공유
  토막을 버려 최외곽 윤곽만 남긴다(측정 133 -> 13 루프).
- 표기 모드(CARVE_APPLY=false): 서피스를 자르지 않고 ① 성토면 위 절단 투영선
  ② 원지반 최고 표고 위 Z평면에 구조물 윤곽(노랑)과 유입·유출 성토부 윤곽
  (하늘·주황)을 따로 그린다. 구조물 커브는 성토면 없다고 보고, 성토부 커브는
  구조물 없다고 보고 만든다.
- 구조물 실루엣 공용화(_Corridor_Station_Structure.ts 신규): 기슭막이·BOX암거·
  세월교 실루엣을 한 자료형으로. 성토면 강제 변형은 스위치로 끄고
  (STRUCTURE_SILHOUETTE_OVERRIDE), 노견 확장만 상시 적용(shoulderSpans).
- 평면 영역 분리(_Corridor_Region.ts), 절단기 일반화(clipGeometry가 영역 배열·
  전체 정점 속성 보간 — 리본 UV 유지). 지형은 코리도 스트립만 도려낸다.
- BOX암거 3D를 측점 프레임 직선 압출로(노선 추종 금지), 날개벽 계산 공용화
  (_Corridor_Structures_Wing.ts 신규) 후 세월교에도 날개벽 4매 추가.
- 세월교 보어를 관 련수만큼 뚫고, 보어 밴드를 단면 표고로 클램프해 구멍 찌그러짐
  제거. 날개벽 뿌리를 벽 외측면 모서리로 교정.
- 직교 카메라(_Viewer_Camera.ts 신규) — 원근 왜곡 없이 탑뷰 판독. 커서 피벗 줌이
  직교에서 camera.zoom을 함께 조인다.

B06 횡단
- 조정창 공용 부품(_Cross_Panel_Base.ts 신규): 머리줄·2행 항목·D-pad·키보드
  방향키. 세월교·BOX 조정창을 같은 템플릿으로 옮기고 십자 세트를 창 맨 아래로.
- 세월교 조정창에 날개벽 항목 추가(설치·짧은쪽 높이·길이·각도) — 정본
  pipe_points 되쓰기, 바닥판 연장은 길이×cos각으로 즉시 재계산.
- 세월교 좌우 이동을 집수정 규칙으로: 노견 수평 확장 + 상하 이동분만 성토선.

BUILD_VERSION 19 -> 31(저장 코리도 캐시 무효화). typecheck·prettier 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 20:03:42 +09:00
eomsangdonandClaude Opus 5 07fb2ccf46 fix(B06): BOX암거·세월교를 소유 측점 횡단도 한 장에만 그림
attach_culvert_sets()가 도로 방향 폭(span_m)의 절반을 reach로 잡아 소유 측점
전후 측점에도 같은 스펙을 붙였다. BOX암거는 폭 2.4m라 0.92m 떨어진 옆 측점까지
걸려 횡단도가 한 벌 더 그려졌고, 같은 값을 읽는 3D도 박스 솔리드를 어긋난 채
두 벌 만들었다.

구조물 종류별 연동 표(_SPAN_LINKED_TYPES)를 두고 reach를 분기한다. 지금은 빈
집합이라 세월교·BOX암거 모두 소유 측점 한 곳에만 선다. 3D 스윕 길이는 소유
측점이 span_m으로 직접 내므로 줄지 않는다.

기슭막이 연동은 프론트 culvertOwnerFor 별도 경로라 그대로 살아 있고, 집수정은
이미 링크 카드에서 빠져 있다.

검증(프로젝트 c1bb453f route 85): pytest 208 passed. 횡단도 200.0m 카드에서
box-barrel 사라지고 200.92m에만 남음. 3D 솔리드 42 -> 32, 200.0m 10 -> 0,
200.92m 10 유지, span_m 2.4 불변.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 17:41:40 +09:00
eomsangdonandClaude Opus 5 6e87dd6cdf fix(B05): BOX암거 날개벽을 구체 모서리에 붙이고 에이프런을 평면 사다리꼴로
날개벽 시작점을 측점 중앙 프레임으로 잡아 곡선 구간에서 구체 끝과 0.15m 어긋났다.
그 모서리 링의 프레임으로 잡아 정확히 붙인다.

또 에이프런이 평면에서 직사각형이라 각도만큼 벌어진 날개벽 발치가 바닥 밖으로
나갔다. 날개벽 선을 따라 안쪽 변이 물러나는 **사다리꼴**로 바꿔 발치를 받는다
(2026-08-25 사용자 지적).

검증(10+0.9): 날개벽 4매 모두 구체 모서리와 거리 0.000m,
에이프런 링별 안쪽 변 [4.158, 2.744, 2.744, 4.158] — 바깥 링에서 폭 0으로 닫힌다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 15:41:31 +09:00
eomsangdonandClaude Opus 5 a87182496e feat(B06·B05): BOX암거 조정창 · 구체 기울기 · 3D 벽 구간 정리
조정창에서 좌·우 끝을 따로 잡는다 — ◀▶는 구체 길이, ▲▼는 그 끝의 구체 표고를
0.1m씩 움직인다. 좌·우 표고가 달라지면 구체가 기울고, 날개벽 구간 바닥(에이프런)은
각 끝 표고에서 수평을 지킨다(2026-08-25 사용자).

- `computeBoxLayout`이 좌·우를 따로 푼다: 끝 표고·길이·성토선·에이프런
- 성토선은 그쪽 표고 기준으로 물매 1:1.2를 지키므로 표고를 내리면 구체가 길어진다
- 조정창 `_Cross_Box_Panel.ts` + 제어 `createBoxControls` + `design.box_adjust` 저장
  (세션 → 캐시 → 확정 payload, 세월교와 같은 체계)
- 3D: 구체 밖(날개벽 구간)에 서 있던 벽을 없앴다 — 천장 없는 통로가 생기던 자리는
  날개벽 몫이다. 이제 상판·구체 저판·측벽 2매·에이프런 2매 + 날개벽 4매로 나뉜다
- 카드 렌더러의 구체 배선(선택 토글·강조·조정창)을 `_Cross_View_Bodies.ts`로 분리,
  연동 플래그 세션은 `_Page_Link_Session.ts`로 분리(700줄 제한)

검증(10+0.9): 구체 5.34m·수평 → ◀ 1회 5.44m → ▼ 2회 표고 −0.2m·물매 1:28.4,
에이프런 두 장 모두 수평 유지, ↺ 원복. 3D 솔리드 10개(측벽 링 0.2m).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 15:03:53 +09:00
eomsangdonandClaude Opus 5 2fe8f617da fix(B06): BOX암거 성토선을 박스 최상단 모서리에서 끝냄
모서리 밖은 구체 개구부·날개벽이라 성토가 아니다(2026-08-25 사용자). 원지반까지
잇던 구간을 지운다 — 성토선은 노견 → (수평 연장) → 박스 최상단까지만이다.

검증(10+0.9): 좌 [(2, 535.821) → (2.744, 535.201)],
우 [(−2, 535.701) → 수평 → (−2.744, 535.201)] — 두 선 모두 상단 표고에서 종료.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 12:55:00 +09:00
eomsangdonandClaude Opus 5 55e97b8925 fix(B06): BOX암거 성토선 추가 — 박스 최상단을 지나고 노견은 수평 연장
박스 위 성토선이 빠져 있었다. 물매 1:1.2를 고정하고 성토선이 **박스 최상단
모서리**를 지나게 하면, 박스를 길게 잡을수록 노견이 저절로 수평 연장되고 각도는
그대로다(기슭막이 "벽이 밖으로 나간 만큼 노폭 연장"과 같은 규칙, 2026-08-25 사용자).

- 구체 길이 = 노폭 + 2 × (노면 − 박스 상단) × 1.2. 노면이 크라운이라 좌·우 필요량이
  다르므로 큰 쪽에 맞춰 대칭으로 잡고, 남는 쪽은 노견을 수평 연장한다
- 성토선 = 노견 → (수평 연장) → 박스 최상단 모서리 → 1:1.2로 원지반까지
- 노견 밖 설계선은 이 성토선이 대신하므로 다시 트림한다

검증(10+0.9): 구체 ±2.744m, 저판 8.32m, 좌 성토선 물매 1.200·1.200,
우 성토선 수평 0.144m 뒤 1.200·1.200.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 12:52:40 +09:00
eomsangdonandClaude Opus 5 d4c8de738a feat(B05·B06): BOX암거 횡단도 · 3D 중공 셸·날개벽·관통 보어
BOX암거를 세월교와 같은 계류 방향 절단면으로 그리고, 3D는 속이 빈 서피스 셸로
만든다. 관통 컷·중공 튜브는 배수관 세트와 세월교에도 함께 적용한다.

B06 횡단도
- `_box_set()` — 내공 폭·높이(B05 옵션), 부재 두께 세월교 승계(측벽 0.2·상하판 0.3),
  복토 0.5m(별표2 교차 참조), 날개벽 투영 저판 연장
- 상판 윗면 = 노면 − 복토, 구체는 수평 설치(교본 3장). 계류 하상과의 고저차는 툴팁 표기
- 구체가 노면 아래 묻히므로 계획선은 자르지 않는다(세월교와 다른 점)

3D
- 로프트가 **링별 폴리곤**을 받는다 — 구조물을 위·아래 조각으로 갈라 링마다 틈을
  벌려 빈 공간을 만든다. 틈 0이면 속 찬 단면 그대로라 토폴로지가 유지된다
- BOX = 내공 구간만 틈을 벌려 측벽이 저절로 생기는 셸 + 날개벽 4매(날개 축 프레임)
- 관통 보어 = 링 y에서 틈 높이 2·√(r²−(y−y₀)²) → 배관 외측 기준 원형 구멍.
  기슭막이·집수정·세월교 측벽에 적용
- 배관은 중공 튜브(바깥·안쪽 원통 + 양 끝 고리)로 내부 유로를 보인다

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 12:45:32 +09:00
eomsangdonandClaude Opus 5 98380056cc fix(B06): 세월교 관 위 성토 채움 삭제
채움 색이 --color-chart-0(파랑 rgb 91,141,239)이라 관 선 색(rgb 79,142,247)과
겹쳐 관 일부처럼 읽혔다. 사용자 확정에 따라 면 자체를 지운다 — 배수관 세트와
같이 관 위는 비워 둔다.

- FordLayout.fill·FordSideLayout.roadFace와 전용 보조 함수 제거
- .b06-chart__ford-fill 스타일 삭제

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 12:12:55 +09:00
eomsangdonandClaude Opus 5 81bb505cc4 feat(B05·B06): 세월교 횡단 구체·조정창·3D 예상형상
B05 세월교 옵션에 BOX암거 날개벽 한 벌(설치·짧은쪽 높이 1m·길이 2m·각도 45°)을
그대로 붙이고, B06 횡단도에 세월교 구체를 그린다. 구체는 양측 ㄴ형 집수정 측벽 +
그 사이를 잇는 바닥판 + 바닥판 상면에 안힌 관 + 관 위 성토(노체) 채움이다.

- 바닥판 편측 연장 = 날개벽 길이 × cos(각도) — 각도는 관축 기준 벌어짐각
- 측벽은 buildBasin 재사용이라 1:0.3 기움·좌우·상하 대각 이동·계류측 성토부선이
  집수정과 같은 규칙으로 따라온다 (기슭막이 다단·재질과는 연계하지 않음)
- 구체는 월류 폭만큼 도로 방향으로 이어져 기준 측점 전후 절반까지 붙는다
- 조정창: 측벽 높이·좌우·상하, 관경·수량(정본 pipe_points 되쓰기).
  높이·좌우·상하는 세션 + design.ford_adjust에 저장
- 3D 예상형상: 구체 부재는 월류 폭 구간 스윕, 관은 련수만큼 폭 안 등간격
- 부재 두께: 바닥판 0.3m(교본 물넘이 물받이 최소 30cm), 측벽 0.2m(집수정 승계)

700줄 제한으로 카드 렌더러·측점 제어기·페이지에서 배선을 분리했다
(_Cross_View_Ford, _Page_Ford_Controls, _Page_Patches, Culvert_Const 구간값 헬퍼).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 12:05:42 +09:00
eomsangdonandClaude Opus 5 0e2309f5ce fix(B05): 지운 구조물 부활 차단 · 임시저장이 캐시 수정분을 저장하도록
사용자 확정 모델: 초기 계산값은 **원복용으로 그대로 두고**, 사용자가 제어한 수정
1세트가 최종본이다. 여러 세트는 두지 않는다. 두 곳이 이 모델을 어기고 있었다.

① 지운 구조물이 되살아난다 — B05는 그려질 때마다 종단 정본의 비정규 측점을 모아
   `/structures/migrate`를 부른다. 서버의 "멱등" 기준이 **지금 그 자리에 구조물이
   있는가**여서, 사용자가 지우면 자리가 비고 다음 진입에서 같은 구조물이 다시
   생성됐다(진행단계 오버레이로 오가면 매번). 옮긴 자리를 `structures.json`의
   `migrated_legacy`에 **이력으로** 남기고, 이력에 있으면 구조물이 없어도 다시 만들지
   않는다. 원천(비정규 측점)은 원복용으로 손대지 않는다. 이력은 일반 저장 경로에서도
   보존한다 — 사라지면 삭제분이 부활한다.

② 임시저장이 캐시 수정분을 버린다 — B05 [임시저장]이 `cross_patches`를 보내지 않고
   `invalidateSectionDetail`로 공유 캐시를 비웠다. B06에서 만져 캐시에 얹힌 구조물
   조정(4축·다단·연동·표시 반폭)이 영구저장소에 못 가고 사라졌다. 계획선·비정규 측점
   저장 **뒤에** 캐시 수정분을 `saveSections`로 남기고, 그 다음에 캐시를 비운다 —
   순서가 뒤바뀌면 재계산이 사용자 수정을 덮는다.

`saveCachedCrossPatches`·`crossPatchesFromCache`는 공유 캐시 모듈에 뒀다 — B05 페이지
파일이 이미 700줄을 넘겨 더 불리지 않기 위함이다(기존 부채).

tsc/ruff/prettier 통과, pytest 200 passed(기존 실패 1건 유지).
신규 검증: tmp/tests/test_b05_structures_migration_history.py 4건.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 19:56:40 +09:00
eomsangdonandClaude Opus 5 38fd7e49e0 fix(B05): 구조물 성토 비탈 Z 반전 — 유출측 실루엣 배열 방향 정규화
사용자 3D 제보: 구조물 자리의 성토가 경사 방향이 뒤집혀 위로 솟는다.

원인은 직전 커밋(b5ceb861)에서 유출측 편거리 정렬을 뺀 것이다. 뒤쪽 코드가 비탈의
도로측 끝점을 **배열 위치**로 집는다 — `slopeRelative`(Corridor_Station)와 코리도
빌더(Corridor_Build)가 `side === "right" ? points.at(-1) : points[0]`로 잡고,
비탈 보간기도 오름차순 배열을 전제한다. 유출이 우측인 측점은 수집 순서(도로 → 바깥)가
편거리 내림차순이라 **바깥 끝을 도로측으로** 잡았고, 그만큼 비탈이 뒤집혀 얹혔다.

정렬로 되돌리면 다단 계단 순서가 다시 깨지므로, 체인은 그대로 두고 **배열 방향만**
오름차순으로 뒤집는다(첫 점이 마지막 점보다 바깥이면 reverse). 점 순서(성토선 >
본 기슭막이 > 추가 성토선 > 추가 기슭막이)는 보존된다.

BUILD_VERSION 18 → 19(저장 코리도 만료).
tsc/prettier 통과, pytest 196 passed(기존 실패 1건 유지).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 19:42:07 +09:00
eomsangdonandClaude Opus 5 b5ceb8613a fix(B05·B06): 기슭막이 조작의 3D 즉시 반영 · 성토 비탈 실루엣 순서 복구
사용자 보고: 기슭막이 위치(본·연동)를 바꿔도, 추가(다단) 기슭막이를 세워도 3D가
바뀌지 않는다. 형상은 성토선 > 본 기슭막이 > 추가 성토선 > 추가 기슭막이 순이어야
한다. 원인이 둘이었다.

① 조작값이 캐시에 안 실렸다 — 사용자 확정 흐름은 "영구저장소 → 브라우저 캐시 →
   3D는 캐시로 플롯, 편집하면 캐시를 갱신하고 그 캐시로 다시 플롯"이다. 그런데
   조정창 조작값(4축·다단 단 수·유입 구조물·집수정·연동 플래그)은 sessionStorage에만
   있고 확정·임시저장 때만 design에 실렸다. 이제 편집 즉시 `section.design`(B05·B06이
   공유하는 같은 객체)에 함께 기록한다. 세션은 리로드 복원용 사본으로 남는다.
② 기하 캐시가 낡았다 — `culvertLayoutOf`의 WeakMap이 측점 객체만 키로 써서, 캐시를
   제자리 고치면 옛 기하가 그대로 살아남는다. 입력 요약 해시를 함께 담아 무효화한다.
③ 비탈 실루엣이 순서를 잃었다 — 수집한 점을 편거리로 정렬한 뒤 재추출했다. 기슭막이
   앞면이 거의 수직이라 편거리 정렬은 순서를 보장하지 못하고, 다단 계단은 안팎을 오가
   뒤섞인다. 유출측은 수집 순서를 그대로 잇고, 추가 성토선과 추가 기슭막이를 번갈아
   밀어 계단 순서를 맞춘다. 유입측(집수정·절토)은 범위 밖이라 종전 정렬 유지.
④ 성토 조각 해상도 20 → 48열 — 호길이 균등 재추출이 수직면을 뭉갠다. 열을 꼭짓점에
   맞춰 배분하면 측점마다 열 수가 달라 리본이 꼬이므로, 파라미터화는 그대로 두고
   해상도로 해결했다. 절토는 20 유지(다단이 붙지 않는다).

성토 물매 불변: 이번 수정은 trimSlope·outletFill 점을 만들지 않는다 — 잇는 순서와
재추출 열 수만 바꿨고, 물매 산출 경로(layout.fillSlope.ratio)는 손대지 않았다.

BUILD_VERSION 17 → 18(저장 코리도 만료).
tsc/prettier 통과, pytest 196 passed(기존 실패 1건 유지).
작업이력·자체검증 기록: docs/raw/PLAN.md §4-10.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 19:37:14 +09:00
eomsangdonandClaude Opus 5 cd8d14f105 feat(B05·B06): 기슭막이 구간값 조정창 · 연동 기슭막이 옵션 · 가림 구간 선 정리
기슭막이 범위(길이·기준측점 전/후)를 B06 횡단도 조정창에서 지정하게 하고, 그
범위가 덮는 옆 측점의 기슭막이를 "연동" 파생물로 다루도록 체계를 세웠다.
값의 원천은 배수관 옵션(pipe_points) 하나다 — 같은 숫자를 B06 정본에 따로 담으면
B05 배수관 카드와 갈려 어느 쪽이 참인지 알 수 없다.

① 집수정 전/후 필드 신설 — inlet_basin_before_m·after_m(기본 각 1m), 길이 2m 유지.
   종방향 구간 계산을 revetSpanOfSpec·basinSpanOfSpec 한 곳으로 모아 2D 링크 판정과
   3D 스윕이 같은 값을 쓰게 했다.
② B06 조정창에 길이·전·후 행 — 기슭막이(유입·유출)·집수정 모두. 캐시를 고쳐 즉시
   보여주고 저장은 조작이 멎으면 한 번만 나간다(세부유역 재계산이 매번 돌지 않게).
   길이를 바꾸면 늘어난 몫만 지금 비율대로 나눠 담는다 — 총길이에서 비율로 다시
   계산하면 0.1m 반올림이 쌓여 5.0/5.0이 5.6/5.4로 어긋난다.
③ 링크 카드 선택 허용 — "소유 측점 통째 복사"에서 "위치 4축만 물려받고 원지반
   접합은 이 측점 지형으로 재계산"으로 바꿨다. 구조물 형식은 언제나 소유 측점 값이다.
   손대기 전에도 어긋나지 않게 소유 측점이 실제로 적용한 4축(revetShift)을 명시값으로
   물려준다.
④ 연동(측점별)·경사(전체 공통) 토글 — 연동 조작은 소유 측점 키에 실리고 그 연장이
   덮는 측점을 함께 다시 그린다. 경사는 3D 전용 스위치다(끄면 스윕 프레임 dz=0).
   횡단도까지 -dz로 밀면 노견에서 출발하는 성토선까지 내려가 노견과 벌어진다.
⑤ 가림 구간 선 정리 — 유입부 접속선과 유출부 접지 후 절토선을 2D·3D 모두에서
   빼되 기하는 남긴다. 면적·수량 계산은 건드리지 않았다(전면 개편 대상).
⑥ 집수정은 소유 측점 횡단도 하나에만 — 링크 카드에서 집수정·계류측 다단을 뺀다.
⑦ 3D 구간 겹침 정리 — 측점 간격이 구조물 연장보다 좁으면 두 구간 제어점이 번갈아
   서서 짧은 쪽(집수정 2m)이 잘려 보였다. 두 소유 측점의 중간에서 끊는다.
⑧ 조정창 정리 — 십자·9키를 맨 아래로, 창을 위쪽 기준 오버레이로(낮은 횡단도에서
   제목이 잘리던 문제), 연동·경사를 1행 토글 버튼으로, 스크롤 자리 유지.

파일 분리: B06_Section_UI_Cross_View_Structure.ts(조정창 배선),
B06_Section_Api_Culvert_Options.ts(구간값 저장) — 700줄 제한.
BUILD_VERSION 14 → 17(저장 코리도 만료).
tsc/ruff/prettier 통과, pytest 196 passed(기존 실패 1건 유지).
작업이력·자체검증 기록: docs/raw/PLAN.md §4-9.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 19:26:35 +09:00
eomsangdonandClaude Opus 5 83eb58a251 feat(B05·B06): 배수관 측점 정본화 · 코리도 단차 제거 · 인접 측점 기슭막이 링크
3D 예상형상은 종단·횡단 확정 뒤의 최종 산출물이고 3D 쪽 편집 경로는 없다
(2026-08-24 사용자 확정). 그런데 구조물(비정규) 측점은 횡단 정본 자체가 없어
조회할 때마다 프리뷰 기본값이 재계산됐고, 조정창 조작값은 세션에서 사라졌다.
정본 경로를 열고, 그 위에서 코리도 단차를 걷어냈다.

① 구조물 측점 정본화 — 확정·임시저장이 종단 정본 stations 중 DB 행이 없는
   측점을 대상에 넣어 upsert. cross_sections 19 → 23행.
② 조정창 조작값 정본화 — 기슭막이 4축(x·d·h·m)·다단 단 수를 design.revet_adjust
   / extra_wall_counts로 저장하고, 3D culvertLayoutOf가 그 값을 기하 입력으로 쓴다.
   카드 우선순위는 세션 → 정본 → 자동.
③ 노폭 연장의 노견 편입 — PIECE_COLS.shoulder 2→3으로 원 노견 끝 꺾임을 남기고,
   조기 return을 없애 확폭이 구조물 구간 내내 유지되게 했다.
④ 종단 기울기 반영 — 구조물 구간 복사 단면에 계획고 차이를 전량 얹는다.
   노견 표고 단차 0.49~0.61m 제거.
⑤ 접속 테이퍼 — 구간 경계를 제어점으로 세워 "복사 vs 보간" 두 규칙을 하나로
   통합. 노폭 3.0m·성토비탈 8.1m 단차 제거. 접속 길이 = 인접 측점까지.
   제어점 생성은 B05_Profile_UI_Corridor_Frames.ts로 분리(Build 699 → 635줄).
⑥ 인접 측점 링크 — 기슭막이 연장(기본 10m)이 덮는 옆 측점 횡단도에도 소유 측점
   단면을 계획고 차이만 얹어 그린다. 요소별 연장 판정(관·집수정 제외), 표시 전용.

BUILD_VERSION 11 → 14 (저장 코리도 만료).
tsc/ruff/prettier 통과, pytest 192 passed (기존 실패 1건 유지).
작업이력·자체검증 기록: docs/raw/PLAN.md §4-8.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 17:11:21 +09:00
eomsangdonandClaude Opus 5 22d4df5aff feat(B05): 3D 예상형상에 배수관 세트 구조물 반영
B06 횡단(computeCulvertLayout)을 그대로 재사용해 3D 코리도에 기슭막이·집수정·
배관을 세우고, 그 구간 성토/절토 단면을 횡단도와 같은 형상으로 다시 그린다.

구조물 솔리드(_Corridor_Structures.ts 신규)
- 기슭막이: 단면 폴리곤을 노선 따라 1m 간격 로프트 스윕(직선 압출 아님)
- 집수정: 부재 외곽 직육면체, 연장 basin_length_m(기본 2m) 전후 균등
- 배관: 관 하단선 축 원통(관경 지름)
- 스윕 프레임에 계획고 차(dz)를 실어 종단 경사 반영
- flat 법선 + EdgesGeometry 모서리 검은선(성토부·노폭 리본과 같은 규칙)

단면 재구성(_Corridor_Station.ts)
- 구조물 측 비탈 = 노견 → (노폭 연장) → 구조물 상단 → 전면 → 벽 하단 성토부선
  → 다단 기슭막이 → 지반/절토선 끝 한 줄(PIECE_COLS cut·fill 9 -> 20)
- 성토로 늘어난 노폭은 비탈이 아니라 노견 리본을 넓힌다
- 집수정 계류측 cutLine까지 이어 원지반을 그만큼 걷어낸다

구간 처리(_Corridor_Build.ts)
- 구조물 점유 구간(기준측점 전/후)이 다음 측점을 넘어가도 같은 단면 유지
- 그 구간은 지반 트림 생략, 비탈 앵커를 노견 조각 바깥 끝으로 통일

길이·전후 입력
- 레지스트리 pipe 옵션 추가: inlet/outlet_revet_before_m·after_m(5/5),
  inlet_basin_length_m(2)
- B05 배수관 서브폼에 기준측점 전/후 칸(전+후=길이 연동)·집수정 길이 칸
- _side_spec이 전/후·집수정 길이를 CulvertSideSpec으로 전달

비정규 측점 프레임 정정(_Page_Helpers.ts)
- left_xy 선형보간(단위길이 깨짐·방향이 현 쪽으로 누움) -> 노선 폴리라인 접선에서
  직접 산출(left = (-ty, tx)), 폴백은 각도 보간

BUILD_VERSION 10 — 저장본 자동 만료

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 21:46:48 +09:00
eomsangdonandClaude Fable 5 5371534fc3 feat(B06): 기슭막이 높이·자리 체계 개편 + 조정창 방향키 조작
- 조정창 십자 키패드 키보드 방향키 조작(집수정 9키는 십자 축만)
- 배관 기슭막이 높이 = 순수 높이(바닥~상단), 하한·기본 = 관경+1.0m (고정 2.0m 폐기)
- 매몰 시 전면 발끝 지반 추적 바닥 심화 삭제 — 바닥 = invert-0.5 고정
- 상하(d) 0점 = 성토선 0 지점(벽 상단=노견), 기본 자리 = 성토사면 경사길이 4m 지점
  (d=null 자동, 저장·표시·정수맞춤 pinned 판정 연동, 구세션 d=0 호환)
- 유입 접속 절토선: 지반 교차 없으면 1m 공간 확보에서 끝
- 자동 집수정 기본 형상 L형 -> I형 (선택지 밖 구조물 그려지던 불일치)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-23 20:34:30 +09:00
eomsangdon 7217747e81 auto: 2026-08-23 19:34 (ESD_LAPTOP) 2026-08-23 19:34:26 +09:00
eomsangdonandClaude Opus 5 eb41202bf4 fix(B06): 교차점 자동 줌아웃이 5m 사면 규칙에 잘리던 문제
자동 줌아웃 판정이 배수관용 slopeToeOffset(성토사면 5m에서 컷오프)을 써서, 사면이
5m를 넘는 측점은 필요 폭을 과소 산정했고 교차점이 화면 밖에 남았다(2026-08-23
사용자 보고).

- _UI_Cross_Fit 재작성: 설계선(design_line)과 지반선의 **실제 교차점**을 0.1m
  간격으로 훑어 찾는다(노면·노견·측구 구간은 건너뜀). 설계선이 만나기 전에 끝나면
  끝단 기울기 차로 외삽하고 1m 올림.
- 카드 자동 줌아웃(effectiveHalfWidth)이 이 값을 쓴다. 보유 샘플 밖으로는 넓히지
  않는다(지반이 없어 빈 화면이 될 뿐).
- [적용]은 전 측점 중 필요한 최대 폭까지 함께 넓힌다 — 20m를 넘으면 그 값으로
  재생성해 각 카드가 자동 줌아웃할 지반을 확보한다.

자체검증: node tmp/tests/test_toe_extrapolate.mjs (사면 18m 교차점을 5m 컷오프
없이 탐색, 설계선이 15m에서 끊겨도 외삽으로 같은 자리), tsc --noEmit 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 18:54:38 +09:00
eomsangdonandClaude Opus 5 91f843b5bb fix(B06): 표고(Y) 눈금 최소 단위 1m
확대하면 0.5m·0.2m 눈금까지 내려가 도면에서 읽을 일 없는 값이 표기됐다
(2026-08-23 사용자 지시). 횡단·종단 모두 표고 눈금 간격을 1m로 하한을 둔다
— 라벨은 항상 정수. 편거리(X) 눈금은 종전대로.

자체검증: node tmp/tests/test_cross_y_ticks.mjs (모든 눈금 정수·간격 1m 이상),
test_cross_axes_zoom.mjs 재실행, tsc --noEmit 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 18:50:19 +09:00
eomsangdonandClaude Opus 5 8f9e628b0b fix(B06): 횡단 보기 설정 한 줄 정렬
ui-field가 세로 배치(라벨·입력·오류 슬롯)라 [적용]이 오류 슬롯 높이만큼 내려가
수평이 안 맞았다. 이 줄에서만 필드를 가로로 눕히고(라벨-입력-버튼) 오류 슬롯을
접어 한 줄에 정렬한다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 18:48:56 +09:00
eomsangdonandClaude Opus 5 dff1e3aff9 feat(B06): 횡단 보기 반폭을 별도 컨테이너로 분리 + 사이드 양식 B05 정렬
- 「횡단 보기 설정」 컨테이너 신설: 반폭 입력 + [적용] 버튼 한 줄. 표준 횡단면
  설정의 [전체 측점 반영]에 물려 있던 반폭 적용을 떼어냈다 — 보유 샘플(20m) 안이면
  전 측점 설계 재계산 없이 즉시 반영된다.
- 표준 횡단면 설정 컨테이너는 기본 접힘.
- 사이드 컨테이너 양식(여백·글자 크기·색)을 B05 .b05-route__panel-section 값으로
  맞춤. 접힘 토글·외곽선은 이미 공용(ui-collapsible / ui-sidebar-section)이었다.
  표준단면 「변수 위치 안내」 모식도 스타일은 현행 유지.
- 표준패널의 미사용 extraControl 인자 제거.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 18:47:36 +09:00
eomsangdonandClaude Opus 5 bab1f6b2c2 fix(B06): 재생성이 구조물(비정규) 측점을 지우던 문제
_regeneration_options가 extra_stations를 넘기지 않아, 반폭 재생성 한 번에
구조물 측점 횡단도가 통째로 사라졌다(2026-08-23 사용자 보고). 옵션 스냅샷
(data.options.extra_stations)에서 목록을 읽어 재생성 옵션에 실어 준다.

자체검증: ./venv/Scripts/python.exe -m pytest tmp/tests/test_regeneration_extra_stations.py -q (2 passed)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 18:43:32 +09:00
eomsangdonandClaude Opus 5 5ac61cb4cc fix(B06): ⤢(오토핏) 기본값을 전역 횡단 반폭 보기값으로
⤢가 항상 교차점 맞춤 폭으로 가서 전역 보기값보다 좁아지기도 했다. 이제 초기화는
전역 보기값이 기본이고, 그 폭에서 절·성토선과 원지반 교차점이 안 보이는 측점만
교차점이 보이는 폭(그 측점의 기본값)으로 되돌린다(2026-08-23 사용자 지시).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 18:34:50 +09:00