납품 도면 2장을 B07 도면 목록에 새로 붙였다. 계산은 하지 않는다 —
유토곡선은 B06 확정 시 저장한 산출물(longitudinal_sections.data.mass_haul)을,
유역도는 B04 세부유역 GeoJSON과 도엽 등고선·세류선을 읽어 좌표만 종이 mm로 옮긴다.
- 도면 종류 확장: kind에 mass_haul·watershed 추가(Schema·Api_Fetch·openwebcad
App.types), 12분류 라벨에 연결, 목록에 단장 도면 2건 상시 노출
- 엔진 신규: _Engine_Cad_MassHaul.py(축·곡선·평형선·띠 현·balloon·측점 테이블),
_Engine_Cad_Basin.py(등고선·세류선 배경·노선·유역·구역별 정보표·방위표)
- 척도 상수: 유토곡선 H 1/2,000 · 세로 1mm=50㎥, 유역도 1/6,000 (A1 고정)
- 유토곡선 저장 payload에 띠·잔여의 기하 필드 추가 — 파이썬에 곡선 보간·토량 배분
로직을 복제하지 않기 위해 값을 낳는 쪽(TS 엔진)에서 함께 남긴다
- 유역도 배경은 여러 도엽을 합쳐 받은 뒤 도곽 크기로 절취(clip_line_to_box)
- 배수규격은 소요 관경이 아니라 규격관(recommended_diameter_mm)으로 표기
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
다단 벽을 고르면 단 수·옵션 행이 사라지던 문제. 두 값은 그 단이 딸린 부모 벽의
것이므로 다단 쪽으로 옮기지 않고 부모 칸에 남긴다.
- Adjust_Dock: EXTRA_ROWS에서 단 수·옵션을 빼고, 행 이동을 moveRows()로 묶어
다단 선택 시 형태·높이·구간값은 다단 칸으로, 단 수·옵션은 부모 칸으로 보낸다.
- Cross_Structure_Panel: extra/bextra 선택에서도 단 수 채널을 부모 쪽(outlet·basin)
으로 열어 둔다.
저장소 사고(2026-08-30 01:12)로 유실된 커밋 bc8a3477의 작업물을 복원한 것이다.
원 작업자는 병렬 B05/B06 세션이며 워킹트리에 남아 있던 변경을 그대로 커밋했다.
구조물 측점 빈 칸의 세로선이 이웃 규칙 측점 값 한가운데를 지나고, 곡선 L/R 칸
경계와 x가 겹쳐 곡선 행 구분선이 위 행들까지 이어진 것처럼 보였다. 세로선을
곡선 행에만 남기고 값 행에서는 지운다 (2026-08-30 사용자 지시).
저장소 사고(2026-08-30 01:12)로 유실된 커밋 84d02b68의 작업물을 복원한 것이다.
원 작업자는 병렬 B05/B06 세션이며 워킹트리에 남아 있던 변경을 그대로 커밋했다.
저장소 사고로 잃은 4개 커밋(38eb7cd4·b8a11756·281528bf·f60b488d)의 작업물을
하나로 다시 담았다. 내용은 동일하다.
■ 구조
- commands/: 명령 정의(id·AutoCAD 별칭·글리프·도구/즉시실행)를 단일 소스로 두고
리본·명령행·단축키가 모두 이 레지스트리를 읽는다. tools/tool.consts.ts 폐지.
- ribbon/: 탭→패널→명령 데이터(ribbon.config.ts)와 범용 렌더러 분리.
AutoCAD 배치(홈·삽입·주석·뷰·출력)와 패널 확장(▾)을 따른다.
- tools/factories/sequence-tool.ts: 점·숫자·문자·객체·선택 단계를 선언하면
xstate 머신을 만들어 주는 공장. 명령당 170줄 보일러플레이트 제거.
- helpers/geometry/: 3점 호·정다각형·타원·스플라인·구름형·평행이동·해치 스캔선·
점렬 샘플링 등 상태 없는 순수 함수.
- Toolbar 483줄을 QuickAccessBar/Ribbon/InspectorPanel/StatusBar/CommandLine/
ViewControls/PropertiesEditor/QuickProperties로 분해.
■ 명령 (조사표 기준)
- 1절 그리기 21건, 2절 수정 27건, 3절 도면층·특성·그룹·유틸리티 39건 전부 반영.
- 5절 주석 34건 중 26건 반영(문자·치수 16종·지시선·표·구름형·주석 축척).
- HatchEntity 추가(solid·pattern·cross·gradient) + JSON 왕복, Layer에 색·선가중치·
선종류·동결·투명도 필드 추가, 그리기 루프가 동결·숨김·투명도를 반영.
■ 화면 실측에서 고친 결함
- 명령행 포커스 상태에서 ENTER가 도구로 가지 않던 문제
- 명령행 문자 입력이 접두사가 같은 명령으로 실행되던 문제
- 명령이 끝나도 입력을 계속 먹던 문제(점 입력 명령만 반복, 나머지는 선택 도구 복귀)
- 시퀀스 단계 인덱스 오사용 9건 + 단계 값 종류 검사 추가
- 해치 내부를 클릭해도 선택되지 않던 문제
미반영 8건(맞춤법 검사·꺾기 치수·치수 끊기/재연관/검사 치수·기하공차·지시선 수집·
축척 리스트 편집)은 조사표 `반영` 열과 PLAN.md에 사유를 적었다.
배관 유입·유출과 독립 좌·우 기준벽에서는 [추가 기슭막이(단)]과 [옵션]이
상태와 무관하게 자리를 지킨다. 링크 카드에서 만져도 제어기가 소유 측점 값을
고치므로 안전하다. 집수정 유입은 종전대로 계류측 단 자리가 있을 때만 뜬다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
다단은 유출 채널(extra)과 유입·계류측 채널(bextra)로 갈린다. 칸이 늘 유출구
아래 고정이라 어느 쪽 단인지 자리로 읽히지 않았다. 고른 단의 채널을 창이
알려 주고, 칸을 그 쪽(배관 유입구·유출구 / 독립 좌·우) 바로 아래로 옮겨 세운다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
조정창에서 옮겨 오는 [추가 기슭막이(단)] 행과 같은 값이라 두 벌이었다.
단 수 정본은 횡단 설계 patch(extra_wall_counts)이고 조작은 그 행이 한다 —
폼 칸과 그 값을 나르던 배선(tierCount·setTierCount)을 함께 걷어낸다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
clipPath id는 문서 전역인데 이름을 벽 키 + 배면 offset으로 지어, 같은 벽을
소유 측점과 연동 측점이 함께 그리면 이름이 겹쳤다. url(#id)는 문서에서 처음
만난 clipPath를 쓰므로 뒤 카드의 해칭이 앞 카드 좌표로 잘려 통째로 사라졌다.
벽을 옮기면 두 카드가 같은 offset으로 다시 겹쳐 증상이 재발했다.
측정(14+0.0 화면): 6개 중 4개 id가 중복 → 수정 후 10개 전부 고유, 모든 카드의
해칭 그룹이 화면에 폭을 갖는다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
다른 브랜치(feat/B05B06-구조물패널-일원화)의 B05·B06 구조물 배치 폼 일원화
결과를 받는다. 충돌 없음 — 그쪽은 B05/B06만, 이쪽은 B07/B08만 건드렸다.
그쪽 브랜치에 남아 있던 옛 폴더(B08_DesignDetail, B07_Quantity)는 이쪽 삭제가
반영돼 사라진다. main.py·라우트·척도 등 B07 작업물은 이쪽 것이 유지된다.
벽 선택은 카드가 먼저 처리하고 폼 교체가 뒤따른다. 그래서 다른 기슭막이를 보다가
배관 유출 벽을 고르면, 이식 시점의 목적지 칸이 아직 이전 시설 것이라 행이 엉뚱한
칸으로 가고 강조도 남지 않았다. 폼이 갈아 끼워진 뒤 refreshAdjustSlots()로 한 번 더
이식한다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 단 수를 바깥 행에서 좌·우 칸 안으로 옮긴다. 저장 키도 좌·우 각각
(inlet_revet_tiers·outlet_revet_tiers, 옛 tiers는 폴백·호환 기록).
폼 값은 다단 채널(extra·bextra)로 가고, 폼은 그 채널 값을 되읽는다.
- 좌·우 칸에도 조정창 행 이식 자리를 두어, 벽을 고르면 배관 유입구·유출구와
같이 그 칸이 강조되고 조정 항목이 옮겨 온다. 칸 이름표는 좌·우 그대로 둔다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 설치 측·단 수를 컨테이너 밖 한 행으로 빼고, 벽 제원은 [기슭막이 (좌)]·
[기슭막이 (우)] 두 칸으로 나눈다. 설치 측이 한쪽이면 그 칸만 뜬다.
좌·우 이름표는 그 측점 오르막 방향(uphill_side)이 정한다.
- 두 칸은 배관 유출구와 같은 양식이다 — [구조][형태] + 길이·높이·전/후.
구조 선택지는 기슭막이 하나뿐이지만 레이아웃을 맞추려 그대로 둔다.
- 값은 유입/유출 키로 좌·우 따로 저장한다(옛 한 벌 저장분은 양쪽으로 펼쳐 읽는다).
- 단 수에 [-][값][+] 조정칸을 붙이고, 폼 단 수를 다단 채널(extra·bextra)로
보낸다 — 배수관 측점처럼 횡단도에 단이 선다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
도면이 한 장뿐인 그룹(종단면도)과 아직 만들지 않은 그룹은 접이식 컨테이너에
항목 하나를 넣을 이유가 없다. 그룹 이름을 단 버튼 하나로 바꾼다.
- 0~1장: 컨테이너 없이 버튼 하나 (없으면 비활성 + '준비 중')
- 2장 이상(횡단면도): 기존 접이식 컨테이너 유지
- 버튼 생성은 drawingButton() 헬퍼로 합침
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
도면 구성이 확정된 12분류(표지~용지도)를 좌측 패널에 순서대로 세운다.
아직 만들지 않는 도면은 접힌 채 '준비 중'으로 자리만 잡는다.
- DRAWING_GROUPS 상수로 12개 그룹 정의, kind가 있는 둘(종단면도·횡단면도)만
서버 목록으로 채운다
- 빈 그룹은 data-pending=true + is-collapsed, 제목만 흐리게
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
작성 척도(횡단 1/100)를 도면 좌표에 넣고, A1 한 장에 들어가는 만큼 단면을 담는다.
- 횡단 좌표를 종이 mm로(x10). 수량표도 종이 치수로 재조정(폭 108mm, 행 5mm)
- 단면 폭 = 설계선이 원지반에서 갈라졌다 만나는 구간 + 여유 1.5m.
지표선도 그 범위로 자른다. 실측 갈라짐 폭 4.0~15.0m (종전 전폭 40m)
- Engine_Cad_Sheet 신설: 칸 크기는 최대 블록 기준, 좌하단부터 아래→위,
그다음 오른쪽 열로 채우고 넘치면 다음 장. 23측점 -> 4장(3열x2행)
- 목록·확정을 장 단위로. 확정 시 담긴 측점 전부의 B06 단면적을 재계산하고
수량표는 측점별로 매니페스트에 보관
- 700줄 제한: 수량표를 Engine_Cad_Table로, 라우터 동기 헬퍼를 Router_Support로 분리
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
배관 유출구 기슭막이가 폼과 다른 형태로 그려졌다. 폼은 저장된 옵션을,
그림은 조정값(m·h)을 쓰는데 둘이 어긋나도 맞추는 자리가 없었다.
조작이 정본이므로 폼이 그려진 값을 따라간다 — wallForm 의존성을 추가하고
형태·높이는 빈칸 채우기가 아니라 덮어쓰기로 바꾼다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
좌측 폼의 실시간 반영은 **고른 항목**에만 걸린다. 아무것도 고르지 않은 상태에서
형태·높이를 바꾸면 값이 조용히 버려져 "형태별 모양이 안 그려진다"로 보였다.
패널에 hasSelection()을 열고, B06에서 선택 없이 폼이 바뀌면 안내한다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
도면에 척도 개념이 없어 도각을 콘텐츠 크기에 맞춰 늘렸다 줄였다. 사용자가 정한
작성 척도로 그림 크기가 결정되도록 좌표를 종이 밀리미터로 옮긴다.
- config_system에 DRAWING_SCALE_* 상수 추가 (종단 1/1,000 x 1/200, 횡단 1/100, A1)
- 종단 좌표를 종이 mm로: 거리 x1.0, 표고는 기준선 기준 x5.0 (세로 5배 과장)
- 기준선(datum)을 종이 y=0으로 정규화, Y축 눈금 라벨은 실제 표고 유지
- frame_entities(fit=False) 추가 — 도각을 실치수 1:1로 두고 위치만 맞춘다.
콘텐츠가 작도 영역(693x468mm)을 넘으면 경고 로그
- 실측: 도각 840x594mm(A1 실치수), 콘텐츠 370x213mm (노선 350m = 350mm)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 유입구·유출구 이름표에 지금 만지는 구조물을 괄호로 단다 — "유입구 (기슭막이)".
추가 기슭막이 칸은 "추가 기슭막이 (2단)". 선택이 풀리면 원래 문구로 돌아간다.
- 추가 기슭막이 칸이 설 때 그 자리로 스크롤한다(칸이 화면 밖에서 생겼다).
- 독립 기슭막이 형태·높이가 그림에 안 실리던 두 자리를 고친다:
① 정본 읽기가 옛 전용 키(form·height_m)만 봐서 배관 키 한 벌로 저장된
값을 놓쳤다 → 배관 키 우선, 옛 키는 폴백.
② 다단 전개에 소유 벽 형태를 안 넘겨 단들이 늘 메쌓기로 그려졌다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 옵션 토글 켜짐 색을 주 액션 색으로 바꾼다(붉은 채움이 경고처럼 읽혔다).
- 같은 문구 토스트가 연달아 오면 앞 토스트가 떠 있는 동안 무시한다.
- 벽 내부 표현을 형태별로 나눈다: 메=돌, 찰=돌+줄눈, 콘크리트=사선 해칭,
돌망태=2열 격자, 통나무=원, 바자=말뚝+엮음. 배관용·독립용·추가용이
공용 `appendWallHatch` 하나를 쓴다(배관 오버레이의 중복 코드 제거).
- 추가(다단) 기슭막이를 고르면 유입구·유출구 아래에 전용 칸이 서고
형태·높이·구간값·옵션 행이 그 칸으로 옮겨 간다. 선택이 풀리면 사라진다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
원인 추적 결과 두 겹이었다.
① 배관 벽 높이는 spec.revet_height_m을 쓰지 않는다 — revetWallSpec이 관경 기준
하한과 조정값(adjust.h)만 본다. 폼 값을 스펙에만 넣어 그림이 안 바뀌었다.
이제 폼의 높이·형태를 조정창과 같은 채널(revetOffset.update)로 보낸다.
② 형태마다 높이 한계가 있다(돌쌓기(메) 2.0m). 한계를 넘겨 입력하면 그림은 그대로인데
폼 숫자만 커져 '제어가 안 된다'로 보였다. 기하가 적용한 값을 폼에 되돌리고
한계를 토스트로 알린다.
폼 기본 높이도 스펙이 아니라 지금 그려진 순수 높이(조정창 표시값)를 쓴다.
확대가 이벤트 1회당 10% 고정이라 트랙패드처럼 잔 델타를 초당 수십 번 보내는
입력에서 튀었고, 두 손가락 이동은 팬이 아니라 확대로 먹혔다.
- zoomScreen을 부호 기반에서 델타 비례 지수식 exp(-delta*지수)로 변경.
마우스 휠 한 칸(deltaY 100)은 종전과 같은 10%, 트랙패드 잔 델타는 그만큼만
- 트랙패드 두 손가락 이동은 panScreen으로 — 마우스 휠은 한 칸이 100/120px로
딱 떨어지고 가로 델타가 없다는 성질로 기기를 가른다
- 핀치(ctrl+휠)는 기기 무관 확대, 전용 지수로 천천히
- deltaMode(줄·쪽 단위) 픽셀 환산 추가
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-29 사용자 지적 2건:
① 폼에서 높이·길이·기준측점 전/후를 고쳐도 도면이 그대로였다 — 조정창 조작값
(revet_adjust.h·m)이 폼 값보다 우선이라 그림이 옛 값을 유지했다. 폼이 높이·
형태를 정하면 그 벽의 조정값을 비워 폼 값이 이기게 했다.
② 폼 기본값은 예전 조정창이 보여주던 값이 기준이다 — 관 옵션이 비어 있으면
횡단 스펙(culvert 스펙: 형태·높이·길이·전/후·집수정 구간값·관종·관경)에서
채워 폼과 조정창이 같은 원천을 보게 했다. 저장된 옵션이 있으면 그쪽이 이긴다.
핀치는 ctrl+wheel 이벤트인데 CAD 휠 처리가 preventDefault를 하지 않아 브라우저
기본 확대가 그대로 실행됐다. 캔버스 밖(리본·패널)에는 휠 핸들러조차 없었다.
- 캔버스 휠 리스너를 passive:false로 등록하고 handleMouseWheel에서 preventDefault
- document에 ctrl+wheel만 막는 리스너 — 리본·패널 위 핀치도 브라우저 확대 금지,
ctrl 없는 휠은 남겨 패널 스크롤 유지
확대 감각(세기)·방향·로그는 건드리지 않았다 — 별도 제안으로 PLAN.md 보류 항목.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-29 사용자: 구조물 배치 컨테이너를 B06으로 가져온 이유가 이것이다 —
폼의 기준 측점 숫자를 바꾸면 관이 옮겨져야 한다.
- 관 저장기에 이동 예약(queueMove)을 더했다. 세션 키 b06:culvertmove에 담고,
[저장]·[확정]의 flush가 옵션 병합과 함께 pipe_points에 반영한다. 세부 배수유역
재분할은 서버가 관 목록을 다시 받아 처리한다.
- 폼에서 측점을 옮기면 목록·폼 캐시가 즉시 새 자리를 따르고, 옵션은 옮기기 전
자리로 예약한다(저장 시점 관 목록이 그 자리 기준).
- 이동 안내는 차단 문구에서 '저장 뒤 다시 계산' 알림으로 바꿨다.
원인: 이동 판정 기준이 0.005m였다. 폼의 측점 표기는 0.1m로 반올림되므로(관이
275.71m면 폼은 275.7m) 높이만 고쳐도 0.01m 차이가 나 이동으로 잡혔다.
- 판정 기준을 관 매칭과 같은 0.51m로 맞춘다.
- 실제로 옮긴 경우에도 함께 온 제원은 반영한다 — 위치만 못 옮길 뿐 B05·B06이
같은 데이터를 쓰는 한 화면이다.
원인: 좌측 폼의 실시간 반영이 세션 예약(culvertopt)과 목록 캐시까지만 갱신하고,
횡단 캐시(section.culvert 스펙)를 건드리지 않아 카드가 옛 값으로 남았다.
- 폼 옵션 키를 culvert 스펙 자리로 옮기는 applyPipeOptionsToCache 추가
(관종·관경, 유입·유출 기슭막이 형태·높이·길이·전/후, 집수정 구간값, 구조).
- 연장이 덮는 범위의 카드만 다시 그린다 — 조정창 조작과 같은 흐름.
- 화면 캐시만 고친다. 영구저장은 [저장]·[확정] 그대로.
원인: 단 수·옵션 행 DOM을 유입구·유출구로 옮긴 뒤, 다음 선택에서 clearSideSlots가
replaceChildren으로 그 행을 없앴다. 창은 카드당 하나라 같은 카드에서 다른 벽을
고르면 행이 영영 돌아오지 않았다.
- 옮길 때 제자리에 주석 표식을 남기고, 선택이 바뀌면 그 자리로 되돌린다.
- 단 수 행은 **기준(소유) 측점**에서만 다룬다 — 연동으로 넘어온 링크 카드에서는
숨긴다(2026-08-29 사용자).
검증: 유출→유입→유출로 옮겨 다녀도 단 수·옵션이 매번 제자리에 복귀.
링크 카드(4+0.0)에서는 옵션만 뜨고 단 수는 숨김.
iframe 안 CAD가 다크 색을 하드코딩하고 있어 앱의 화이트/블랙 토글과 따로 놀던
것을 고친다. 색 정의처는 앱과 같은 ui_template_theme.css 하나로 모은다.
- openwebcad가 ui_template_theme.css를 직접 import — App.css의 하드코딩 색
88개를 var(--color-*)로 전량 치환, CAD 골격용 별칭 토큰만 새로 붙임
- src/theme.ts 신설: 동일 오리진 localStorage(frd_theme) + storage 이벤트로
부모 토글을 리로드 없이 추종(부모 코드 수정 없음), 시스템 폴백 유지
- 캔버스 배경·그리드는 토큰 경유, 저장된 도면 색은 라이트 모드에서 그릴 때만
휘도 보정(paintColor) — 저장 데이터는 불변
- 테마 변경 시 bumpSceneVersion()으로 정적 장면 캐시 비트맵 재생성
- Button/LayerManager의 tailwind 색 유틸 제거, index.html의 bg-* 고정 제거
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
원인: 앞선 커밋에서 넣은 '대표 벽 자동 선택'(selectDefaultWall)이 카드를 고를
때마다 벽을 골라 조정창까지 띄웠다(2026-08-29 사용자 보고: 기슭막이(유출) 창이
계속 떠 있음).
- selectDefaultWall과 그에 딸린 자동 선택 표시(withAutoAdopt 등)를 걷어냈다.
- 카드·목록 선택 리스너에서 남아 있는 벽 선택을 비운다. 벽을 찍어 카드가 딸려
선택된 경우는 건드리지 않는다(isWallSelecting 가드).
부작용: 단 수·옵션 행은 도면에서 벽을 고른 뒤에만 유입구·유출구에 붙는다
(사용자 확인: 측점 선택 시 자동 구조물 선택은 필요 없음).
검증: 목록 선택·카드 선택 시 조정창 0개·강조 없음, 벽 클릭 시 기슭막이(유출) 창
+ 유출구 강조 + 단 수·옵션 행 표시.
- <label>이 [-][입력][+] 묶음을 감싸면 암묵 대상이 **첫 버튼(-)**이 된다.
입력에 id를 붙이고 label.htmlFor로 명시 연결해 라벨·입력 위 커서가 -를
활성화하거나 라벨 클릭이 값을 줄이던 동작을 없앴다(2026-08-29 사용자 보고).
- 제목(라벨)과 항목 간격도 --b05-label-gap(2px) 한 변수로 묶고 라벨 글자를
caption 크기로 맞췄다. 측점 행은 가로 배치라 열 간격 6px 유지.
검증: label.control=INPUT, 라벨 클릭 후 값 10 불변, 커서 올려도 - 배경 투명.
시설·이식·메모·구조물군 라벨 간격 모두 2px·라벨 높이 14px.