원격 전체 통합: B07 CAD 도각 분리·유역도 정리·도면층 국문화 + 용화 실무문서 #5

Merged
eomsangdon merged 70 commits from feat/B07-cad-block-library into main 2026-08-31 17:33:10 +09:00
70 Commits
Author SHA1 Message Date
eomsangdonandClaude Opus 5 8e6046b9d3 chore: push 확인용 잔재 파일을 지운다
origin/backend 브랜치를 합치면서 딸려 온 pushtest(2026-07 push 확인용,
내용 "evidence to proof the push")를 정리한다. 브랜치 이력은 합쳐진
상태로 남으므로 원격 브랜치를 지워도 이력 손실이 없다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 17:26:32 +09:00
eomsangdon ebd85f402c merge: 원격 backend 브랜치를 합쳐 원격 이력을 한 줄로 모은다 2026-08-31 17:26:18 +09:00
eomsangdon 3f98670637 merge: AutoCAD 리본 기능 조사자료 브랜치를 합친다 2026-08-31 17:26:12 +09:00
eomsangdon 66d24fdffa merge: main의 실무문서(2026 임도 용화)를 받아들이고 코드는 최신을 유지한다
# Conflicts:
#	B07_DesignDetail/openwebcad/src/App.css
#	B07_DesignDetail/openwebcad/src/commands/command.types.ts
#	B07_DesignDetail/openwebcad/src/commands/commands.annotate.ts
#	B07_DesignDetail/openwebcad/src/commands/commands.draw.ts
#	B07_DesignDetail/openwebcad/src/commands/commands.file.ts
#	B07_DesignDetail/openwebcad/src/commands/commands.insert.ts
#	B07_DesignDetail/openwebcad/src/commands/commands.modify.ts
#	B07_DesignDetail/openwebcad/src/commands/registry.ts
#	B07_DesignDetail/openwebcad/src/commands/run-command.ts
#	B07_DesignDetail/openwebcad/src/components/CommandLine.tsx
#	B07_DesignDetail/openwebcad/src/components/InspectorPanel.tsx
#	B07_DesignDetail/openwebcad/src/components/RibbonWidgets.tsx
#	B07_DesignDetail/openwebcad/src/components/StatusBar.tsx
#	B07_DesignDetail/openwebcad/src/components/Toolbar.tsx
#	B07_DesignDetail/openwebcad/src/inputController/input-controller.ts
#	B07_DesignDetail/openwebcad/src/main.tsx
#	B07_DesignDetail/openwebcad/src/ribbon/Ribbon.tsx
#	B07_DesignDetail/openwebcad/src/ribbon/ribbon.config.ts
#	B07_DesignDetail/openwebcad/src/tools/factories/sequence-tool.ts
2026-08-31 17:07:38 +09:00
eomsangdonandClaude Opus 5 0d90595a40 fix(B03/B04): PRJ 좌표계 판별을 문자열 매칭에서 WKT 정본+EPSG 라벨로 바꾼다
get_epsg_from_prj()가 WKT에 항상 있는 false_easting 때문에 EAST 분기가
무조건 걸려 모든 PRJ를 EPSG:5187로 판정했다(표준 WKT 6종 실측). 새 원청
자료의 5176(비표준 TOWGS84)·5179(AUTHORITY 없는 ESRI WKT)가 이 경로로
들어오면 최대 100km 어긋난다.

- common_util/common_util_crs.py 신설: 판별 사다리(pyproj DB 대조 →
  AUTHORITY 태그 → 투영 파라미터 지문)와 변환 입력 정규화. 수평 성분에
  TOWGS84가 박힌 PRJ는 EPSG로 갈아타지 않고 원문 WKT로 변환해 지역 보정을
  보존한다. 수직 성분의 bound(KNGeoid)는 2D 변환에 무관하므로 무시.
- B04 get_epsg_from_prj: 죽은 문자열 분기 제거, 유틸 위임. 시그니처 불변 —
  기존 COMPD_CS 프로젝트는 예전과 같은 EPSG:5187 문자열이 나온다.
- B03 _component_metadata: to_epsg 실패 시 사다리 라벨 보강,
  normalize_crs_metadata: BoundCRS 벗김(TOWGS84 PRJ 수평 탐색 실패 수정).

검증: tmp/tests/test_common_util_crs.py 13건 포함 스위트 29 passed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 16:27:13 +09:00
eomsangdonandClaude Opus 5 46ac54257e fix(B07): 수량 산출표 패널이 명령 입력칸을 덮던 것을 올린다
패널이 상태막대 바로 위에 떠 있어 명령행과 겹쳤고, 명령 입력칸을 클릭으로
누를 수 없었다. bottom에 --cad-command-height를 더해 명령행 위로 띄운다.
명령행을 접으면 이 값이 0이라 예전처럼 상태막대 위에 붙는다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 15:48:08 +09:00
eomsangdonandClaude Opus 5 9bf6de9b10 fix(B07): 잠금 도면층을 집던 경로 다섯 곳을 마저 닫는다
앞선 감사가 불완전했다. 같은 부류로 도각·원지반을 건드리던 곳이 더 있었다.

- select-tool.helpers pickEntityAt: 클릭 선택 후보에 잠금 객체가 섞여
  도각을 물면 아무 일도 안 일어나는 죽은 클릭이 됐다.
- eraser-tool: 자르기의 교차점 계산이 도각 선을 절단 경계로 썼다.
- property-tools OVERKILL: 선택이 없으면 전체가 대상이라 도각까지 지웠다.
- text-tools 찾기/바꾸기: 도각 표제란 글자를 바꿔 버렸다.
- selection-tools 유형/유사 선택: 잠금 객체까지 세어 토스트 개수가 틀렸다.

전부 getPickableEntities()로 바꾼다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 15:48:08 +09:00
eomsangdonandClaude Opus 5 008b0ede14 fix(B07): 유역도에서 노선을 살리고 방위표·정보표 배치와 절취면을 정리한다
노선이 유역 해칭 아래에 깔려 보이지 않았다. polyline_entity에 width를 더해
노선만 굵게(3) 그리고, 그리기 순서를 해칭·정보표 다음으로 옮긴다. bbox
계산에는 그대로 포함시켜 오른쪽 칸 위치는 흔들리지 않는다.

오른쪽 칸을 방위표(맨 위) → 유역 정보표(아래로 쌓기) 순으로 바꾸고 방위표를
14mm에서 26mm로 키운다. 도면 오른쪽 위 구석에 따로 놓던 옛 배치는 걷어낸다.

등고선·세류선 절취가 경계 바깥 점을 하나씩 물고 나와 외곽이 들쭉날쭉했다.
Liang-Barsky 선분 절취로 바꿔 끝점이 경계 위에 정확히 놓이게 하고, 그만큼
두었던 물림 여유(_CLIP_SLACK 14mm)를 없앤다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 15:21:38 +09:00
eomsangdonandClaude Opus 5 6a2c5d9f7b feat(B07): 기본 도면층 이름을 국문으로 바꾸고 방위표 템플릿을 정리한다
도면층 17종을 프로젝트가 이미 쓰는 용어로 맞춘다 — 원지반·계획선·구조물·
암 경계선·수량 산출표·도각·등고선·계류·노선·배수유역·유역 제원·표제·
그래프 격자·측점표·유토곡선·그래프 축·운반 구간. CAD 앱의 'Default'와
'New layer'도 기본·새 도면층으로 바꾼다. layerId는 그대로다.

방위표 템플릿(00_template_compass.json)에 원본 DXF의 표제란 글자 4개가
도면 반대편에 남아 있었다. 이 때문에 템플릿 bbox가 183x262mm로 부풀어,
긴 변을 14mm에 맞추는 compass_entities()가 방위표를 1.1x1.8mm로 줄여
놓고 있었다. 글자를 지우니 bbox 20.5x32.9mm, 방위표가 8.7x14mm로 나온다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 15:07:14 +09:00
eomsangdon 8ae61af7dd auto: 2026-08-31 14:38 (ESD_LAPTOP) 2026-08-31 14:38:53 +09:00
eomsangdonandClaude Opus 5 ee065091c1 fix(B07): 도각 같은 잠금 도면층을 설계 조작이 집지 않게 한다
잠금 필터가 공용 함수 없이 호출부마다 들어가 있어 넣은 곳은 막히고 안 넣은
곳은 샜다. Ctrl+A는 도각 103개·원지반 16개까지 전부 선택했고, 선택 삭제에는
잠금 검사가 없어 Ctrl+A → Delete 한 번에 도각이 사라졌다. 자르기와 트림·모따기
계열, 커서 강조도 도각을 집었다.

state.ts에 getPickableEntities()(잠금 도면층 제외)를 두고 집기 경로가 그걸
쓴다. 선택은 setSelectedEntityIds() 한 곳에서 막아, 앞으로 생길 선택 경로도
자동으로 잠금 객체를 담지 못한다.

화면맞춤(zoomToFitScreen)도 같은 목록에 맞춘다 — 도각까지 넣으면 A1 한 장
전체가 잡혀 화면의 40%가 여백으로 갔다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 14:38:48 +09:00
eomsangdonandClaude Opus 5 fb0b49bf60 fix(B07): 명령행 토글이 좌측 속성 패널 높이를 흔들지 않게 한다
.cad-inspector의 bottom이 --cad-command-height를 포함해서, 상태막대의
[명령행] 토글이 좌측 팔레트 높이까지 함께 바꿨다. 좌측 패널이 상위이므로
상태막대까지 내려 명령행 표시 여부와 무관하게 만든다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 10:35:13 +09:00
eomsangdonandClaude Opus 5 8ab10967cf fix(B07): 선택 그립이 선보다 아래에 찍히던 것을 바로잡는다
화면 좌표는 아래에서 위로 재는 규약인데(getCanvasPoint·drawLineScreen), 화면 사각형
채우기만 캔버스 y로 옮길 때 높이를 빼지 않았다. 그래서 아래 변에 놓아야 할 사각형이
높이만큼 아래로 내려가, 선택 그립이 선보다 8px 밑에 찍혔다. 화면 픽셀 단위 어긋남이라
줌을 해도 간격이 그대로였다.

커서 옆 입력칸은 같은 함수를 쓰므로 자리가 유지되도록 높이만큼 내려 잡았다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 21:27:53 +09:00
eomsangdonandClaude Opus 5 b4a653e682 fix(B07): 우클릭 뒤에도 선택 도구가 살아 있게 하고, 커서 옆 글자를 줄인다
선택 아이콘을 누르고 우클릭하면 커서 옆 안내가 사라졌다. 우클릭은 ENTER이고,
선택 도구는 ENTER로 최종 상태(SELECTION_COMPLETED, type: final)에 들어가 멈춘다.
그 끝남은 move·copy·rotate가 선택을 자식으로 불러 쓸 때 onDone으로 필요하므로 두고,
선택이 그 자체로 활성 도구일 때만 새로 세운다.

커서를 따라다니는 글자가 18px이라 컸다. 쓰이지 않던 상수
CANVAS_INPUT_FIELD_FONT_SIZE를 12로 낮춰 두 곳이 함께 쓰게 했다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 21:23:24 +09:00
eomsangdonandClaude Opus 5 8666bfdcfa revert(B07): 저지연 캔버스를 되돌린다 — 일부 스냅이 안 걸렸다
desynchronized+alpha:false로 합성 큐를 건너뛰게 했더니 일부 스냅이 동작하지 않는다는
지적. 커서 체감보다 스냅 정확도가 먼저다. 화면 캔버스를 원래 getContext('2d')로 되돌린다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 21:20:26 +09:00
eomsangdonandClaude Opus 5 9c1cdf8f4d perf(B07): 도면을 미리 받아 두고, 커서 지연과 토스트 이질감을 걷는다
도면을 열 때마다 0.8~1.0초가 걸렸다. 서버가 요청마다 도면을 새로 조립하고(0.3~0.6초),
구조물 모듈이 공유 캐시를 건너뛰고 종횡단 상세를 매번 다시 받았기 때문이다(0.2초).
진입 후 첫 장을 띄우고 나서 목록 전체를 배경에서 받아 캐시에 담고, 구조물 모듈은
B05·B06과 같은 Section_Store를 쓴다. 클릭에서 렌더까지 55~65ms로 줄었다.

CAD 알림은 react-toastify라 프로젝트 공용 토스트와 모양이 달랐다. 호출부 30여 곳을
그대로 두려고 vite alias로 라이브러리 자리에 다리를 끼워, 부모가 있으면 메시지로 넘겨
부모 토스트로 띄운다. 백업 되살리기처럼 누르는 안내를 위해 showToast에 onClick을 더했다.

커서가 미묘하게 끌리던 것은 프레임이 느려서가 아니라(16.7ms, 60fps) 합성 파이프라인
때문이다. 화면 캔버스를 desynchronized+alpha:false로 만들어 그 큐를 건너뛴다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 21:05:23 +09:00
eomsangdon bfaf32a043 Merge remote-tracking branch 'origin/feat/las-free-sheet-surface' into feat/B07-cad-block-library 2026-08-30 19:58:51 +09:00
eomsangdon 72ead694b1 fix(B05): 가까운 제어점 구간은 격자 탐색 없이 직결해 원청 계획노선을 보존한다
계획노선 CSV는 설계 원청이 지정한 기준선이라 프로그램이 바꾸면 안 되는데,
격자 Dijkstra가 제어점 사이에 셀 중심점을 끼워 넣어 평면이 틀어졌다.
제어점은 원좌표로 되박히지만 끼어든 점은 되박히지 않기 때문이다.

원인은 셀 크기와 정점 간격의 기하 관계다. LAS 프로젝트는 비용면 셀이
2.188m(원본 DTM 해상도, 다운샘플 배수 1)라 정점 간격(평균 2.61m·최대
3.25m)이 전부 8이웃 한 걸음에 들어가 중간점이 안 생겼다. 도엽 등고선
프로젝트는 DTM이 1.0m라 배수 2로 셀이 2.0m가 되고, 20쌍이 두 걸음으로
벌어져 22개 점이 끼어들었다(최대 이탈 2.08m, 평면 +4.72m, 곡선 경고 증가).
솔버에 LAS 전용 보존 코드는 없다 — 셀 2.0m에 LAS CSV를 스냅해도 두 걸음
쌍이 16개 생긴다.

제어점 쌍의 평면 거리가 ROUTE_DIRECT_LINK_CELL_FACTOR×셀 이하면 탐색을
건너뛰고 두 칸을 그대로 잇는다. 조밀 기준선(정점 전체가 제어점)은 평면이
원본과 완전히 같아지고, 간격이 문턱을 넘는 구간만 종전대로 탐색한다.
경사·곡선 제약은 이 구간에서 경고로만 남는다.

검증(프로젝트 0aca395f 실데이터, 원본 미변경 사본에서 재탐색):
- 셀 2.0m: 정점 156→135, 끼어든 점 22→0, 이탈 2.076→0.000m,
  평면 354.84→350.11m(CSV와 동일), 곡선 경고 9→8
- 셀 3.0m: 111→135 정점(같은 칸에 합쳐지던 24개도 살아남음), 이탈 0.000m
- LAS 프로젝트 c1bb453f: 재탐색 결과 xy 차 0.000000m — 결과 불변
- pytest 14 passed (직결·같은 칸 미병합·먼 구간 탐색 유지 3건 추가)
2026-08-30 19:38:24 +09:00
eomsangdon 932d85348e fix(배수유역): 관 지점에 좌표를 남겨 어느 노선으로 읽든 선 위에 앉힌다
사용자 지적(2026-08-30): "결국 노선 위에 위치해야 한다".

관 자리를 정한 선(계획노선 CSV)과 화면에 그려지는 선(B05 최적 경로)은 같은 자리를
지나면서 연장이 다르다 — 실측 350.11m vs 354.83m, 전 구간 이격은 평균 0.03m·최대
1.12m뿐인데 길이가 4.7m 차이난다. pipe_points.json이 누가거리만 저장해서 읽는 쪽이
쥔 선에 따라 같은 값이 3.3~4.3m 미끄러졌고, 노선 지문도 늘 어긋나 B05는 저장된 관을
매번 통째로 버렸다("노선 지문이 달라 저장된 관 지점 4건을 쓰지 않습니다").

- PipePoint에 x·y를 두고 저장 시 채운다(save_pipe_points에 노선을 넘긴다).
- 지문이 달라도 좌표가 있으면 읽는 쪽 노선에 투영해 이월한다(project_pipe_points).
  구간(start_m·end_m)은 기준점이 옮겨간 만큼 같이 민다 — 시설 치수는 불변.
- 좌표 없는 구 저장분만 종전대로 버린다.
- B05는 같은 로더(load_pipe_points_file)를 쓴다 — 두 화면의 판정 기준을 하나로.

검증: 프로젝트 5d18ebe3 실데이터 — 좌표 4/4 저장, B05 계획선으로 읽어 4건 전부 이월,
관에서 계획선까지 거리 최대 0.016m(종전 4건 전량 폐기). 누가거리는 +3.45~+4.29m
이동(연장 차이 그대로). pytest 11 passed(투영 이월·구 저장분 폐기 테스트 추가).
2026-08-30 18:48:24 +09:00
eomsangdon 06f72393a9 fix(B04): LAS 없는 설계에서도 확정 지표면 범위를 돌려준다
/surface/confirmed가 지형 가장자리를 structured.npz 또는
ground_points_{filter}.npz에서만 읽었다. 둘 다 LAS 산출물이라 LAS 없이
설계한 프로젝트에는 없고, bounds가 null로 나가 B05가
"지표면 범위 정보를 찾을 수 없습니다"로 막혀 3D 지형을 못 띄웠다.

두 파일이 없으면 확정 모델 격자(npz)의 bounds를 그대로 쓴다. 도엽 서피스
npz는 이미 같은 형식의 bounds(3×2)를 담고 있다.

검증: 프로젝트 5d18ebe3(LAS 0개) B05 재진입 — /surface/confirmed 200,
preview·contour 요청이 뒤따라 나가고 안내문이 사라짐. 지형·등고선·코리도·
구조물 라벨까지 화면에 뜬 것 확인(152_b05.png).
2026-08-30 18:27:07 +09:00
eomsangdon 1d1b1c8c0b fix(B03): 자동 설계 체인이 확정된 지표면 선택값을 쓰게 한다
LAS 없이 설계한 프로젝트에서 WF1이 sheet_laplace로 자동 확정한 직후 체인이
config 기본값(csf/dtm)으로 B05 경로 계산을 걸어 404로 끊겼다.

  ERROR 자동 설계 체인 중단(B05 경로 계산 실패): status=404

stage 1 스냅샷(get_surface_confirmation_params)을 읽어 실제 확정값을 쓴다.
B05 초기화가 부르는 경로도 같은 함수라 함께 고쳐진다.

검증: 프로젝트 5d18ebe3(LAS 없이 도엽등고선으로 생성)에서 체인 재실행 —
B05 route_id=112 연장 354.84m, 횡단 19개, 배수유역 관 4개·세부유역 8개까지
완주. 확정 선택값 {"source_filter": "sheet_laplace", "method": "dtm",
"smooth": true} 그대로 사용.
2026-08-30 18:18:16 +09:00
eomsangdon 3ea6aa5b13 fix(B03): LAS 없이 설계를 켜면 LAS/LAZ를 아예 받지 않는다
사용자 보고(2026-08-30): 체크한 상태에서 실수로 넣은 LAS가 그대로 업로드됐다.
카드에 --disabled 클래스만 걸려 있어 회색으로 보일 뿐 선택 버튼과 input이
살아 있었고, 서버도 las_free일 때 LAS 1개를 정상 경로로 받아 줬다.

- 화면: 선택 버튼·file input을 실제로 잠그고, 켤 때 이미 고른 LAS는 내린다.
  파일 선택 영역·드롭으로 들어오는 것은 onFileSelected에서 걸러 낸다.
- 서버(신뢰 경계): /files는 las_free면 LAS 0개만 받는다. 큰 LAS가 타는
  청크 업로드 세션 생성도 같은 검사를 건다 — 여기서 막지 않으면 /files 검사를
  통째로 비켜 간다.
2026-08-30 18:11:19 +09:00
eomsangdon b59d0e4f2c fix(공통): storage가 링크일 때 업로드 경로 기준이 어긋나 터지던 것을 고친다
`storage/`를 심볼릭 링크·정션으로 두면(워크트리를 나눠 쓰면 실제로 그렇다)
프로젝트 루트는 링크 경로 그대로인데 저장 엔진(resolve_upload_destination·
resolve_chunk_session_dir)은 Path.resolve()로 링크를 따라가 실경로를 만든다.
그래서 chunk_path.relative_to(project_root)가 ValueError로 터졌다.

  '...본폴더\storage\1\3\{id}\B03_FileInput\chunks_temp\...\00000000.chunk'
  is not in the subpath of '...워크트리\storage\1\3\{id}'

프로젝트 루트와 임시 보관함 루트를 realpath로 돌려주어 기준을 하나로 맞춘다.
경로 검증(상대경로·.. 금지·루트 이탈)은 그대로다.

검증: tmp/tests/test_storage_symlink_root.py 추가 — 링크된 storage에서 반환
경로가 resolve() 결과와 같고 relative_to가 성립하는지. 전체 9 passed.
2026-08-30 18:03:30 +09:00
eomsangdon 37590b84d1 feat(B03): LAS 없는 설계도 스무딩 격자로 확정한다
2026-08-30 사용자 확정. 방식마다 dtm_sheet_*_smooth.npz를 같이 만들어 두므로
종·횡단이 LAS 경로와 같은 스무딩 격자를 샘플링한다.
2026-08-30 17:48:28 +09:00
eomsangdonandClaude Opus 5 e0760de3b8 fix(B07): 구조물이 깎은 설계선을 그리고, 한 변을 한 선으로 만든다
구조물을 세워도 설계선이 원래대로 지나갔다. 정본(design_line)에 담긴 건 트림 전
원본이고, 구조물이 깎아 내는 부분은 B06이 그릴 때 계산하기 때문이다. 수확기가
appendCrossDesignOverlay를 구조물 layout의 designTrim과 함께 태우고, 그 블록의
서버 설계선은 걷어낸다. 걷어낼 자리를 알도록 서버가 블록 테두리를 함께 내려준다.

곧은 사면 하나가 CAD에서 선 열댓 개였던 것은 B06이 설계선 점 사이마다 line 하나를
만들기 때문이다. 수확한 뒤 끝점이 맞물리는 선분을 잇고 공선점을 지운다(RDP).
측점 20m 18조각 → 폴리라인 3개(선분 7).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 17:42:59 +09:00
eomsangdon 154a318e30 feat(B04): 도엽 서피스 기본 보간을 라플라스로 확정한다
2026-08-30 사용자 확정. LAS 없이 설계할 때 WF1이 자동 확정하는
sheet_* 모델이 이 값을 따른다(B03_FileInput_Service_WF1).

라플라스는 5m 선 재추출 평면 이탈이 2m 초과 2.6%·95% 0.74m 로 6종 중
가장 작고, 평탄 셀도 0.235%로 TIN 계열(8~10%)보다 낮다.
2026-08-30 17:40:47 +09:00
eomsangdon 9fc4462d74 feat(B04): 도엽 보간에 TIN(도엽선)을 넣고 안 쓰는 3종을 뺀다
사용자 지시(2026-08-30): IDW·거리비례·TIN 곡면 제거, 5m 도엽등고선 기준 TIN 추가.

TIN(도엽선)은 격자에 구운 라인 셀이 아니라 벡터 등고선 정점의 원좌표를 그대로
Delaunay로 잇는다. 격자 밖은 100m 여유만 물고 자르며, 길이 필터는 두지 않는다
(짧은 봉우리 폐합 링을 버리면 마루가 통째로 평평해진다).

거리비례는 버튼에서만 빼고 함수는 남긴다 — 라플라스·TPS·ANUDEM·다중해상도가
초기추정으로 계속 쓴다. 기본 방식은 distance가 빠져 multires로 옮겼다.

검증: 실데이터 767×840·1m 6종 93.5s. 서피스에서 다시 뽑은 5m 선의 평면 이탈이
TIN(도엽선) 중앙 0.12m·2m초과 8.1%로 6종 중 최소(직전 최선 다중해상도
0.34m/18.3%). pytest 8 passed(격자와 어긋난 링 위 표고 재현 테스트 추가).
2026-08-30 17:36:17 +09:00
eomsangdon 87f65e275b auto: 2026-08-30 17:22 (ESD_LAPTOP) 2026-08-30 17:22:33 +09:00
eomsangdonandClaude Opus 5 35b70dd4c5 fix(B07): 도각 안쪽을 채우고, 수량표를 한 줄로 세운다
여백이 많다는 지적. 도각 안쪽 작도영역(770x594)에서 5%를 떼고 배치해 사방에
70mm 가까이가 비었다. 2%로 줄이니 같은 블록으로 3장이 2장이 된다(16/7).

표가 제각각 높이에 뜨던 것은 블록을 칸 한가운데 놓았기 때문이다. 수량표 높이는
모든 블록이 같으므로 칸 아래 변에 맞춰 놓으면 표가 한 줄로 선다. 단면 높이 차이는
위쪽이 흡수한다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 17:22:26 +09:00
eomsangdon 3a1b387deb revert(B04): 도엽 서피스 프리뷰 메시의 NURBS 곡면 적합을 되돌린다
DTM 스무딩(184296f5)이 표고 정본(npz)에서 이미 가우시안+B-spline을 걸므로
프리뷰에서 다시 NURBS를 적합하면 곡면 적합이 이중으로 걸린다. c2060f3b 이전의
격자 메시로 되돌리고, 쓰지 않게 된 NURBS import를 지운다.

검증: 프리뷰 glb 정점 표고 = npz 격자 표고 (|차이| 최대 0.0000m,
distance 원본·스무딩 각 161,280정점).
2026-08-30 17:01:37 +09:00
eomsangdonandClaude Opus 5 8b284459c6 feat(B07): 횡단도에 구조물을 그리고, 장을 빈틈없이 채운다
구조물(배수관·기슭막이·세월교·BOX암거·물넘이포장)이 횡단도에서 빠져 있었다.
기하 산식이 전부 B06 화면(TS)에 있어 서버가 도형을 만들 수 없었기 때문이다.
파이썬으로 옮겨 적는 대신, 화면에 붙이지 않은 SVG에 B06 그리기 함수를 그대로
불러 그린 뒤 그 도형을 CAD 엔티티로 옮긴다. 산식은 한 벌로 남고, 앞으로 B06에
붙는 구조물·치수·글자는 손대지 않아도 도면에 따라온다.

자리를 맞추려면 실좌표(m)를 종이(mm)로 옮긴 값이 필요하다 — 서버가 측점별
cross_placements로 실어 보낸다.

장 배치는 전체 블록의 최대치로 칸을 통일하던 것을 버리고, 블록 크기를 먼저 재서
가장 많이 담기는 행 수를 고른다. 열폭은 그 열의 최대폭, 행높이는 그 행의 최대높이라
행·열은 그대로 맞는다. 같은 노선에서 4장이 3장이 됐다(12/6/5).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 16:49:57 +09:00
eomsangdonandClaude Opus 5 184296f526 feat(B04): 도엽 서피스에 DTM 스무딩을 적용한다
LAS DTM 스무딩과 같은 두 단계를 계수 그대로 옮겨 방식마다
{stem}_smooth.npz·_smooth_preview.glb를 만든다(계수 변경 금지 — 사용자 지시):
정규화 가우시안(SURFACE_SMOOTHING_DTM_SIGMA_M) → C2 바이큐빅 B-spline 재평가
(kx=ky=3, s=SURFACE_SMOOTHING_DTM_SPLINE_SMOOTH). smooth_dtm()은 라이다
발자국(TerrainContext)을 받아 그대로 못 쓴다.

- 결측이 하나라도 있으면 스플라인 결과가 통째로 NaN이 된다(TIN·TIN 곡면은
  볼록껍질 밖이 결측). 최근접 표고로 메워 적합하고 원래 마스크로 되돌린다.
- 재평가 격자는 원본보다 성기게 잡지 않는다 — 이 npz는 스무딩 확정 시 종·횡단이
  샘플링하는 표고 정본이라 화면 정점 상한으로 해상도를 깎으면 안 된다.
  메시 정점 수는 _preview_mesh가 알아서 줄인다.
- 화면: 방식 버튼 줄에 스무딩 드롭다운을 놓고 기본값을 켜 둔다.

실측(c1bb453f, 8종): 격자 767x840 1m 유지, 거칠기 감소(거리비례 0.341→0.217,
TIN 0.067→0.051), 표고 변화 3~33mm. build_surface_sampler(smooth=True) 정상.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 16:49:23 +09:00
eomsangdonandClaude Opus 5 c2060f3b6f feat(B04): 도엽 서피스 프리뷰 메시를 NURBS 곡면으로 만든다
격자 삼각형을 그대로 이으면 1m 셀 경계가 톱니로 보인다. LAS NURBS 모델이 쓰는
fit_nurbs_spline·evaluate_nurbs_spline을 그대로 걸어 곡면을 평가한 뒤 메시를
만든다. 제어 간격은 같은 config(SURFACE_NURBS_PATCH_SIZE_M ÷ 축당 제어점 수,
최소 1셀). 무효 셀은 최근접 표고로 메워 적합하고 원래 유효 마스크로 다시 도려낸다.
적합이 실패하면 격자 메시로 되돌린다.

표고 정본(npz)은 격자 그대로다 — 종·횡단·배수는 격자를 샘플링하므로 계산값에
영향이 없다. 실측에서도 8종 지표가 모두 동일했다. 생성 83s → 108s.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 16:40:31 +09:00
eomsangdonandClaude Opus 5 8fedbd77ac feat(B04): 미착수였던 ANUDEM형·다중해상도 보간을 더해 8종으로 만든다
- ANUDEM형: 등고선의 국소 최대 곡률점(코너)에서 능선·계곡 구조선을 뽑아
  (굽은 안쪽이 높으면 계곡, 낮으면 능선) 이웃 표고끼리 이어 앵커로 심고,
  박판 스플라인으로 풀고, 형태학적 재구성으로 가짜 웅덩이를 메운다.
  Topo to Raster가 밟는 세 단계를 그대로 옮긴 것. 메운 웅덩이는 평탄해지지
  않게 안쪽으로 cm 단위 경사를 남긴다(Garbrecht·Martz 평탄면 해소).
- 다중해상도: 1/8→1/4→1/2→1 격자로 내려오며 앞 단계 해를 시작값으로 쓴다.
- 박판 솔버를 solve_min_curvature()로 분리해 두 방식이 함께 쓴다.
- 화면 버튼 순서에 두 방식을 넣었다(버튼이 곧 하이드·쇼).

실측(c1bb453f, 8종 83s) 평탄 셀: TPS 0.003 / 다중해상도 0.003 /
거리비례 0.014 / TIN 곡면 0.026 / ANUDEM형 0.046 / 라플라스 0.235 /
TIN 선형 10.36 / IDW 69.13 %. LiDAR 대비 |dz|는 2.59~3.00m로 차이가 작다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 16:31:41 +09:00
eomsangdonandClaude Opus 5 b2d707f91d feat(B04): 등고선 보간 6종을 만들어 화면에서 비교하게 한다
문헌(ANUDEM Hutchinson 1988/89, DEM 보간 비교연구)은 지형에 따라 우열이
갈려 단일 최적해가 없다고 본다. 방식을 하나로 고르지 않고 전부 만들어 두고
사용자가 눈으로 비교해 정하도록 했다(2026-08-30 사용자 지시).

신규 B04_PreProcess_Engine_SheetMethods.py — 거리비례 / TPS(박판, 감쇠
최소곡률 LSMR) / 라플라스 / TIN 선형 / TIN 곡면(Clough-Tocher) / IDW.
방식마다 dtm_sheet_{key}.npz + 프리뷰를 만들어 surface_models에
source_filter=sheet_{key}로 등록하므로 기존 뷰어·등고선·프리뷰 경로가 그대로
돈다. 폐합 링 안쪽 처리는 방식과 무관하게 똑같이 적용한다.

화면: 도엽등고 3D 서피스 컨테이너에 방식 전환 버튼과 '라이다 겹쳐 보기'
토글(반투명 파랑)을 달았다. 라이다는 같은 좌표계라 같은 자리에 겹친다.

실측(c1bb453f, 6종 65s): 평탄 셀 TPS 0.003% / 거리비례 0.014% /
TIN 곡면 0.026% / 라플라스 0.235% / TIN 선형 10.4% / IDW 69.1%.
LAS 대비 노선 |dz| 평균은 2.59~3.00m로 방식 간 차이가 작다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 16:11:08 +09:00
eomsangdonandClaude Opus 5 8c828992f7 fix(B07): 집기 반경을 화면 기준으로 잡고, 누른 채 끄는 선택을 살린다
- 집기 반경이 월드 거리였다. HIGHLIGHT_ENTITY_DISTANCE를 월드 거리와 그대로 비교해
  확대할수록 화면상 반경이 같이 커졌다(1369%에서 15월드 ≈ 205px). helpers/pick-radius로
  확대율을 나눠 쓰고 상수를 화면 픽셀 10으로 낮췄다. 하이라이트·선택·그립·시퀀스 도구가
  같은 반경을 본다.
- 누른 채 끄는 선택이 없었다. 왼쪽 버튼은 mouseup에서만 클릭을 보내 누르고 끌어도 점이
  하나만 찍혔고, 그래서 좌→우(창)·우→좌(교차) 구분이 먹히지 않는 것처럼 보였다.
  선택 도구일 때만 누를 때 첫 점을 보내고, 4px 넘게 끌고 놓으면 그 자리로 사각형을 닫는다.
  다른 도구는 예전처럼 놓을 때 한 점만 받는다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 15:52:25 +09:00
eomsangdonandClaude Opus 5 15ce46d54d fix(B04): 등고선 보간을 등간격으로 — 얇은 래스터·앵커 제거·최소 다듬기
사용자 지적(1m 보간선이 등간격 아님)의 원인 세 가지를 잡았다.
- 등고 라인 래스터가 all_touched=True라 2px 두께였다. 그 폭만큼 정확히 5m
  배수 표고인 평탄 띠가 생겨(격자의 7.6%) 사이 1m 선 간격이 찌그러졌다.
  서피스 전용 얇은 래스터화(all_touched=False)로 바꾸고, 봉우리 폐합 링이
  사라지지 않도록 길이 필터도 뺐다.
- 계곡 앵커를 1m로 양자화해 제약에 섞은 탓에 제약 표고가 29단→121단이 되어
  계곡 주변만 1m 간격이 됐다. 앵커를 뺐다 — V자 등고선이 계곡 하강을 이미
  담고 있어 거리 보간만으로 충분하다.
- 등고선 고정 완화를 수렴시키면 harmonic 해가 되어 마루가 눌린다. z=r은
  biharmonic이라서다 — ANUDEM/Topo to Raster가 라플라스가 아니라 thin plate
  spline을 쓰는 이유(Hutchinson 1988/89, 조사 결과). 다듬기를 omega=1·5회로
  줄였다. 합성 원뿔 검증: 거리보간 오차 0.121m·간격 CV 2.18 → 5회 0.118m·1.43,
  20회 이상 CV 50↑ 악화. 원뿔 회귀 테스트를 남겼다.

실측(c1bb453f): 평탄 셀 0.00%, 5m 구간 표고 분포 8.4~10.3%(균등),
생성 6.3s, 노선 |Δz| 2.64m.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 15:51:08 +09:00
eomsangdonandClaude Opus 5 31e3eb4ecf fix(B04): 도엽 서피스를 2D 거리보간으로 만든다 — TIN 제거
메시(TIN)로 먼저 만들고 거기서 등고선을 뽑던 순서가 계단의 원인이었다.
사용자 지시대로 2D를 먼저 완결한다:
- Delaunay TIN 제거. 표고별 거리장에서 각 셀의 가장 가까운 두 '서로 다른'
  등고 라인을 찾아 z=(L1·d2+L2·d1)/(d1+d2)로 보간한다. 같은 표고 정점
  3개짜리 평탄 삼각형이 없으므로 계단이 원리적으로 생기지 않는다.
- 폐합 등고선 안쪽은 거리보간이 분화구를 만들므로, 안에 다른 제약이 없는
  영역을 마루/웅덩이로 보고 바깥 사면 경사로 ±(간격-0.5m)까지 연장한다.
- 계곡 구조선 앵커는 1m 양자화해 같은 격자에 제약으로 굽는다.
- 등고 라벨 40개 상한(긴 것부터) — 1m 등고선이 잘게 쪼개져 라벨 수백 개가
  매 프레임 재계산되며 화면이 멈췄다(사용자 보고). 61 FPS 회복.

실측(c1bb453f): 평탄 셀 2.48%→0.02%, 최대 평탄 덩어리 2406→912㎡,
경사 2% 미만 셀 17145→14444, 생성 36.5s→8.0s, 노선 |Δz| 2.76m.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 15:33:56 +09:00
eomsangdonandClaude Opus 5 3a86e02747 fix(B07): 리본 패널 슬라이드아웃이 잘려 캔버스에 가리던 것을 띄운다
패널 줄이 가로 스크롤 상자(overflow-x: auto)라, CSS 규칙상 세로도 auto로 계산되어
슬라이드아웃 메뉴가 리본 높이에서 잘렸다. 캔버스에 가려 보이는 증상이 이것이다.

메뉴를 화면 좌표(position: fixed)로 띄우고 라벨 버튼의 위치에서 자리를 잡는다.
오른쪽·아래로 넘치지 않게 좌표를 물리고 높이를 72vh로 제한했다.
캔버스 위에 뜨게 됐으므로 바깥을 누르면 닫히고, 다른 패널을 열면 먼저 열린 것이 닫힌다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 15:31:46 +09:00
eomsangdonandClaude Opus 5 cb1c5261e2 feat(B04): 사이 등고선을 2D 가상 등고라인으로 뽑아 반복 이분한다
앞서는 등거리 '점'을 5셀 간격으로 흩뿌려 점 사이가 벌어진 곳에 평탄
삼각형이 남았고 한 단계(+2.5m)만 넣어 그 안에서 계단이 남았다.
사용자 지시(2D에서 사이 등고선을 먼저 만들고 3D화)대로 등거리선을
연속 셀 선으로 뽑아 새 레벨로 등록하고, 그 선들 사이를 다시 이분한다
(SHEET_SURFACE_MIDLINE_ROUNDS=2 → 5m 주곡선이 2.5m·1.25m 가상 등고로).
정점 간격도 5셀에서 2m로 좁혔다. 거리장은 라운드 간 재사용한다.

실측(c1bb453f): 평탄 셀 3.96%→2.48%(최초 9.35%), 경사 2% 미만 셀
27163→17145, 노선 |Δz| 2.56m 유지. 생성 16.4s→36.5s — 라운드 수는
config로 조절 가능.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 15:22:30 +09:00
eomsangdonandClaude Opus 5 ea5ce92725 feat(B07): 표를 객체로 만들어 도면의 표가 진짜 표가 되게 한다
표가 DXF의 표로 나가야 한다(사용자 확정). 지금까지 도면의 표는 선과 문자 뭉치라
내보낼 때 고를 수 있는 길이 하나뿐이었다.

- TableEntity: 열별 폭·행별 높이·칸 문자·병합을 한 객체가 들고 있다. 격자선은 담지
  않고 병합 자리에서 선을 끊는 규칙을 표가 스스로 안다(helpers/table-geometry.ts).
  회전·대칭은 지원하지 않는다 — 표는 축에 붙어 있다.
- 명령: TABLE을 표 객체 생성으로 다시 쓰고 TABLEEDIT(칸 문자)·TABLEROW·TABLECOL·
  TABLEMERGE·TABLEUNMERGE를 더했다. EXPLODE는 표를 선과 문자로 흩는다.
- 그립: 좌측 상단으로 표를 옮기고, 열·행 경계로 폭·높이를 바꾼다.
- 백엔드: 유역 정보표와 횡단 수량 산출표를 표 객체로 낸다. 횡단표는 머리행이 폭
  8등분, 본문이 11열 가중치로 격자가 서로 달라 두 경계를 합친 18열로 만들고 병합으로
  원래 칸을 되살렸다 — 손으로 하던 가로선 끊기가 사라졌다.
- 수량 역추출: 값 Text의 결정적 id로 읽던 것을 칸에 실은 key로 읽도록 옮겼다. 이미
  저장된 도면을 위해 옛 방식을 폴백으로 남겼다.

토적도·종단표는 값이 칸이 아니라 측점 위치에 놓이는 성격이라 이관하지 않았다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 15:12:19 +09:00
eomsangdonandClaude Opus 5 0dae8e3016 feat(B04): 도엽 서피스를 구조선(계곡·능선) 기반 보간으로 개선한다
5m 등고선만 보고 보간하던 것을 구조선 기준으로 보강(2026-08-30 사용자 확정):
- 계곡: 도엽_하천중심선을 기준선으로, 등고선 교차점을 Z 앵커 삼아 선 길이
  비례로 보간한 정점열을 TIN에 추가 — 계곡 바닥이 등고선 사이에서도
  연속으로 내려간다 (실데이터 605정점, 480~599m)
- 능선: 마루 캡을 고정 +2.5m에서 마지막 등고선 바깥 사면의 국소 경사
  연장으로 교체(상한 +간격−0.5m, 경사 불명 시 돔 폴백) — 마루가 주변
  사면 기울기를 따라 이어진다

실측: 평탄 셀 5.14%→3.96%(최초 9.35%), 노선 |Δz| 불변(2.57m), 생성 16.4s.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 15:10:04 +09:00
eomsangdonandClaude Opus 5 10f175d6b4 feat(B04): 마지막 등고선 안쪽 평탄 마루를 골격 캡으로 돋운다
다음 등고선이 없는 봉우리·능선 마루는 TIN이 마지막 등고 표고로 평탄하게
채워 'ㅜ'가 갑자기 'ㅡ'로 변하는 단이 생긴다(2026-08-30 사용자 지적).
등표고 평탄 컴포넌트 중 바깥 유효 이웃이 전부 낮은 것(=마루)만 골라,
경계 거리 비례로 중심 골격이 +간격/2(주곡선 5m 기준 +2.5m)가 되게 올린다.
실제 마루는 마지막 등고와 +간격 사이가 보장되므로 오차 상한이 데이터
불확실성 이내다. 골짜기 바닥은 배수 방향을 모르므로 불변.
값별 사전 필터와 컴포넌트 bbox 창 연산으로 전체 생성 11.8s 유지.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 14:59:50 +09:00
eomsangdonandClaude Opus 5 80979960d3 feat(B04): 도엽 서피스에 인접 등고선 사이 중간 보간선을 넣어 계단을 없앤다
등고선 정점만의 Delaunay TIN은 같은 표고 정점 3개짜리 평탄 삼각형이
굴곡부·능선에서 계단(terrace)을 만든다(2026-08-30 사용자 지적).
인접 표고 등고선 쌍의 등거리 중간선을 EDT로 찾아 평균 표고 정점으로
추가하되, 멀리 있는 다른 표고 쌍에 우연히 등거리인 지점을 거르기 위해
'그 지점의 최근접 등고선이 바로 그 쌍'일 때만 인정한다.

실측(c1bb453f): 평탄 셀 9.35%→5.31%, LAS 대비 노선 |Δz| 평균
2.65→2.57m·최대 13.11→13.07m. 최고 등고선 안쪽 봉우리·같은 표고 사이
골짜기 바닥은 원천 데이터 한계로 평탄 유지.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 14:47:20 +09:00
eomsangdonandClaude Opus 5 e599884888 feat(B07): 그립으로 고치고, 음수·극좌표를 받고, 편집분을 잃지 않는다
조사표 8~13절 검토에서 "기본 기능"으로 고른 것을 반영한다.

- 좌표 입력: 절대·상대 좌표가 양수만 받아 `@-100,50`을 거부했다. 부호를 허용하고
  극좌표 `@거리<각도`·`거리<각도`를 더했다. `-`·`+`가 확대·축소 단축키로 먼저
  잡혀 음수의 첫 글자를 먹고 있어 그 두 단축키를 뺐다(줌은 휠·뷰 막대·명령).
- 그립 편집: 선택 객체에 그립을 그리고 집어서 옮긴다. 선 끝점·중점, 폴리선 정점,
  사각형 모서리, 원 중심·반지름, 문자·점 기준점. 폴리선은 세그먼트 중점을 끌면
  정점이 늘고 정점 위 Ctrl+클릭이면 준다. 형상 필드가 private이라 공개 생성자로
  다시 만들어 바꿔 끼우고 id·도면층·색·그룹을 물려받는다.
- 자동 백업·복구: 5초 디바운스로 복구 전용 키에 저장하고, 시작할 때 백업이 있으면
  눌러서 되살리는 안내를 띄운다. 저장(QSAVE)에 성공하면 백업을 지운다.
- 선택 순환: 같은 자리를 다시 클릭하면 겹친 후보를 차례로 돌린다.
- 상태막대: `극좌표 추적` 버튼이 `직교`와 같은 onClick이라 같은 일을 하고 있었다.
  각각 45°·90°를 켜고 끄도록 고치고, 스냅 추적 토글과 F3·F7·F8·F10을 붙였다.
- 문자 굵게·기울임을 캔버스·SVG·JSON·스타일 패널에 연결했다.
- 조사표: 이미 되어 있던 5건의 표기를 정정하고, 출력·내보내기(9절)는 결재창 이후
  PDF·DXF·DWG로 반영할 것이라 보류(P)로 구분해 사유를 남겼다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 14:43:46 +09:00
eomsangdonandClaude Opus 5 462b71e896 fix(B04): 도엽 서피스 npz에 bounds를 넣어 등고선과 메시 원점을 맞춘다
dtm_sheet.npz에 bounds가 없어 등고선 API가 LAS structured.npz bounds로
폴백했고, 메시(glb)는 sheet 격자 중심으로 만들어져 등고선이 X -7.1m,
Y +3.4m, Z +3.3m 떠 보였다. LAS 없는 프로젝트면 등고선 생성 자체가 실패한다.
glb와 같은 bounds(3x2)를 npz에 저장해 두 산출물이 같은 원점을 공유한다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 14:38:24 +09:00
eomsangdonandClaude Opus 5 3572694f73 feat(B03/B04): LAS 없이 도엽등고선으로 3D 서피스를 만들어 설계한다
- B03: 'LAS 없이 설계' 토글 — LAS 필수카드 비활성화, las_free 플래그로
  업로드·완료 검증 면제, 계획노선 CSV를 WF1 분석 입력으로 사용
- B04: 신규 Engine_SheetSurface — 도엽_등고선.geojson을 노선 bbox+300m
  직사각형으로 절취, 배수유역 엔진의 등고선 정점구름·Delaunay TIN 보간을
  재사용해 dtm_sheet.npz(1m 격자, LAS DTM과 동일 형식) + 프리뷰 glb 생성.
  build_surface_sampler('sheet','dtm')로 종·횡단·배수 하류 계산 무수정 동작
- WF1: las_free면 run_sheet_surface_analysis로 분기, sheet/dtm 자동 확정.
  VWorld·도엽 확보 블록을 download_geodata()로 추출해 두 경로가 공유
- LAS가 있어도 도엽 서피스를 함께 생성·등록(참고용), B04에
  '도엽등고 3D 서피스' 별도 컨테이너로 표시

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 14:27:41 +09:00
eomsangdonandClaude Opus 5 3fccf8278b feat(B07): 그린 것을 블록으로 저장해 다시 놓고, 사진 넣기를 되살린다
조사표 4·7절 검토 결과를 반영한다.

- 블록 라이브러리: 선택한 객체를 이름 붙여 저장(BLOCK)하고 팔레트에서 골라
  클릭 한 번으로 놓는다(INSERT). 정의-참조 링크 없는 클론 방식이라 새 엔티티
  타입 없이 기존 직렬화·groupId를 그대로 쓴다. 기준점은 선택 영역 중심.
  라이브러리는 도면과 분리해 브라우저에 두고, 유실 대비로 파일 내보내기·
  가져오기를 붙였다.
- 사진 넣기: IMAGEATTACH가 파일 선택창을 띄우지 않아 도구가 FILE_SELECTED를
  영원히 기다리고 있었다. 도구형 명령도 run()을 함께 부르게 하고 파일 선택을
  붙여 되살렸다.
- 조사표 4·7절의 반영 등급·반영 열을 실제 코드에 맞춰 정정하고, 반영하지
  않기로 한 항목의 사유를 절마다 남겼다. 7절은 신규 구현 없음.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 14:00:42 +09:00
eomsangdon eb4303253a auto: 2026-08-30 13:45 (ESD_LAPTOP) 2026-08-30 13:45:27 +09:00
eomsangdonandClaude Opus 5 6d8fd46d87 fix(B06): BOX암거를 고르면 그 끝이 강조되게 한다
좌·우 끝을 골라도 횡단도에 아무 표시가 없었다. 강조 토글(`is-active`)은 이미
클릭 판정용 **투명 겹면**에 걸리고 있었는데, 그 클래스에는 강조 규칙이 없어
그대로 투명했다.

겹면에 `b06-chart__box-hit`를 하나 더 달고 그 클래스에만 강조를 준다 — 기슭막이·
집수정과 같은 색 계열이되 면이 넓어 채도를 낮췄다(danger 16% + 점선 테두리).
구체 부재(저판·상판·내공)는 좌·우가 한 몸이라 그쪽을 칠하면 어느 끝을 고른
것인지 되레 흐려진다.

자체검증(공용 브라우저 5174, 측점 10+0.9 BOX암거):
- tsc --noEmit 통과.
- 우측 끝 선택 → 그 겹면만 `is-active`, 계산 스타일 fill
  `color(srgb 0.909804 0.411765 0.352941 / 0.16)` · stroke `rgb(232, 105, 90)`.
  수정 전에는 `fill: transparent`라 아무것도 안 보였다.
- 스크린샷 `tmp/browser/shots/110_boxhl.png` — 구체 우측 절반이 붉게 칠해진다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 13:41:30 +09:00
eomsangdonandClaude Opus 5 1c9ff90dfd feat(B06): BOX암거 좌측 폼을 세월교와 같은 규칙으로 연결한다
세월교와 같은 문제가 BOX암거에도 있었다 — 좌측 「구조물 배치」의 본체 규격·날개벽을
바꿔도 도면이 그대로였고, 폼 기본값이 스펙에서 오지 않았으며, 구체를 골라도 좌측
칸이 서지 않았다. `applyPipeOptionsToCache`가 `section.box`를 모르고 즉시 return하던
것이 뿌리다(세월교와 동일).

- `applyBoxFormOptions()` — 폼 옵션(`body_*`·`wing_*`)을 제어기로 보낸다.
  `BoxControl`에 `setBody`·`setWing`을 더했다: 캐시(`section.box`)를 먼저 고치고
  (`span_m`은 백엔드 `_box_set`과 같은 식으로 다시 잡는다) 정본 예약 + 카드 갱신.
- 날개벽 옵션 조립·해석을 `wingOptions()`·`wingPatchFrom()`으로 묶어 세월교와 나눠
  쓴다 — 세월교 쪽 중복 코드가 사라졌다.
- `withBoxSpec()` — 폼 기본값을 `section.box`(내공 폭·높이, 날개벽)에서 읽는다.
- 좌·우 끝을 고르면 폼의 **날개벽(유입)/(유출)** 칸이 선다. 좌·우 ↔ 유입/유출
  매핑은 기하가 날개벽을 고르는 기준(`uphill_side`)과 같다. 조정창은 결국 지우고
  폼 이름(유입/유출)만 쓰기로 한 사용자 확정(2026-08-30)을 따랐다.

구체 길이·표고는 폼에 대응 칸이 없어 조정창 축으로 남는다(본체 높이는 규격이 이미
정한다 — 2026-08-30 사용자).

자체검증(공용 브라우저 5174 + 워크트리 백엔드 8001, 측점 10+0.9 BOX암거):
- tsc --noEmit 통과.
- 구체 선택 시 좌측 `날개벽(유입) (BOX암거)` 칸 강조(수정 전 강조 없음).
- 본체 규격 2.0×2.0 → 3.0×3.0 → 도면 라벨 `BOX 3.0×3.0`, 다시 2.0×2.0 → `BOX
  2.0×2.0`. 한 번 고른 상태에서 연속 조작도 그대로 먹는다. 수정 전에는 라벨이
  5.34m 구체와 함께 전혀 움직이지 않았다.
- 회귀: 세월교 날개 길이 2→4→2에서 조정창 표시가 4.0m→2.0m로 따라온다
  (`wingOptions`/`wingPatchFrom` 공용화 뒤에도 동일).
- 조작값은 원래대로(BOX 2.0×2.0 · 세월교 날개 길이 2m) 되돌려 놓았다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 13:37:43 +09:00
eomsangdonandClaude Opus 5 93f7786c62 fix(B07): 유역 해칭·번호 배지를 넣고 토적도 balloon 숫자를 뺀다
화면 실측에서 나온 지적 세 가지를 반영했다.

- 세부유역에 격자 해칭(Hatch style=cross, 유역색)을 넣는다. openwebcad Hatch
  엔티티라 CAD에서 무늬·간격을 그대로 편집할 수 있다.
- 유역 번호를 동그라미 배지로 바꾼다 — 흰 원판(solid 해치) + 유역색 테두리 +
  검은 숫자. 해칭 위에서도 읽히고, 화면(어두운 배경)·인쇄(흰 배경) 양쪽에서 남는다.
  배지는 엔티티 목록 맨 뒤에 몰아 그려 뒤따르는 해칭·정보표에 가리지 않는다.
- 토적도 balloon의 장비명 뒤 숫자를 뺀다. 납품 도면에는 "도자 11"처럼 붙지만
  그 숫자의 정체가 확인되지 않았다(2026-08-30 사용자 확정 — 확인되면 붙인다).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 13:31:44 +09:00
eomsangdonandClaude Opus 5 8106b1ed9b fix(B06): 월류 전 노면 점선을 측벽 상단 꼭짓점에 붙인다
날개벽 상단(바닥판 바깥 끝)까지 내려 이으니 점선이 구체 밖으로 크게 벌어져 읽기
나빴다. 좌측 벽이면 **좌상단**, 우측 벽이면 **우상단** — 측벽 상단의 계류측
꼭짓점에 붙인다(2026-08-30 사용자, 각도는 무시).

- `FordSideLayout.wingTop` → `wallTopOuter`로 바꿨다. 벽 폴리곤의 상단 두 점 중
  계류측 것이라 날개벽 설치 여부와 무관하게 항상 있다(널 분기가 사라졌다).

자체검증(공용 브라우저 5174 + 워크트리 백엔드 8001, 측점 7+9.7):
- tsc --noEmit 통과.
- 점선 오른쪽 끝 `404.125,89.644` = 우측 벽 폴리곤의 우상단 꼭짓점과 좌표 일치
  (벽 = `399.25,133.519 399.25,89.644 404.125,89.644 404.125,133.519`).
  왼쪽 끝도 대칭으로 좌상단에 붙는다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 13:19:58 +09:00
eomsangdonandClaude Opus 5 8fa1652e62 feat(B06): 세월교 월류 전 노면 점선을 날개벽 상단까지 대각으로 잇는다
점선(월류가 없었을 때의 계획고)이 노견에서 뚝 끊겨, 구체 밖에서 노면이 어디로
떨어지는지 읽히지 않았다. 양 끝을 그 측 **날개벽 상단**까지 대각으로 내려 잇는다
(2026-08-30 사용자).

- `FordSideLayout.wingTop` — 바닥판 바깥 끝(계류측 극점) × 바닥판 상면 + 날개벽
  짧은쪽 높이. 날개벽 설치가 없으면 null이고, 그 측은 노견에서 끊는다.
- `appendFordSurfaceDropPlan`이 세월교 기하를 받아 한 폴리라인으로 그린다:
  좌 날개벽 상단 → 좌 노견 → 우 노견 → 우 날개벽 상단.

자체검증(공용 브라우저 5174 + 워크트리 백엔드 8001, 측점 7+9.7):
- tsc --noEmit 통과.
- 점선 폴리라인 4점 확인(수정 전 2점). 양 끝이 바닥판 바깥 상단 자리로 나간다.
- 날개벽 상단이 원래 계획고보다 21.70px 아래 = 0.890m (y축 1m = 24.375px).
  바닥판 상면~원래 계획고 1.89m − 날개 짧은쪽 높이 1.0m = 0.89m와 일치.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 13:12:23 +09:00
eomsangdon 30a7553447 auto: 2026-08-30 13:01 (ESD_LAPTOP) 2026-08-30 13:01:46 +09:00
eomsangdonandClaude Opus 5 a1dc0ee235 feat(B07): 토적도(유토곡선)·유역도(수리집수면적유역도)를 도면으로 낸다
납품 도면 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>
2026-08-30 13:01:39 +09:00
eomsangdonandClaude Opus 5 353ccc2b4e chore(config): vite API 프록시 포트를 AISLO_API_PORT로 바꿀 수 있게 한다
병행 작업(CLAUDE.md 7장)에서 워크트리마다 자기 백엔드를 봐야 하는데 프록시 대상이
8000으로 하드코딩돼 있었다. 워크트리 vite(5174)를 `AISLO_API_PORT=8001`로 띄우면
그쪽 백엔드를 본다. 기본값이 8000이라 메인 폴더 동작은 그대로다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 12:54:36 +09:00
eomsangdonandClaude Opus 5 933f513da0 feat(B06): 세월교 노면을 월류 높이만큼 내려 앉힌다
횡단도에 그려지던 노면은 사실 월류부 가장 아래를 자른 자리다 — 구체 위 노면은
월류 높이만큼 낮게 앉아야 한다(2026-08-30 사용자 확정). 계획고를 통째로 내려
잡아 측벽·바닥판·십자선·절성토 면적이 한 번에 따라오게 했다. 전폭 평행 하강이라
횡단경사·측구·사면 규칙은 그대로다.

백엔드
- `_ford_set`이 `ford_height_m`을 `overflow_depth_m`으로 스펙에 싣는다.
- `compute_cross_design(surface_drop_m=)` — 계획고를 그만큼 내려 계산하고, 내린
  양을 `surface_drop_m`으로 echo한다(프론트가 점선을 되그리는 데 쓴다).
- `ford_surface_drops()`·`ford_drop_at()` — 관 지점 정본에서 측점별 하강량을 읽는다
  (포장 구간과 같은 방식). 설계 계산 경로 전부(기본값·재계산·프리뷰·종횡단 확정)에
  물렸다.
- `enforce_ford_surface_drops()` — 저장분이 옛 계획고면 상세 조회에서 다시 계산한다.
  월류 높이를 지우면 같은 경로로 원래 계획고로 되돌아온다.

프론트
- 십자선을 하강량만큼 내려 찍는다(`cardDesignElevation`). 종단 계획고를 그대로
  쓰던 자리다.
- `appendFordSurfaceDropPlan()` — "월류가 없었다면" 노면을 점선으로 남긴다.
  물넘이포장의 「기존 계획고 점선」과 같은 표기라 한 규칙으로 읽힌다.
- 측벽·바닥판은 내려간 설계선(`design_line`)에 그대로 붙으므로 따로 손대지 않았다.

자체검증(공용 브라우저 5174 + 워크트리 백엔드 8001, 측점 7+9.7, 월류 높이 0.39m):
- `tmp/tests/test_ford_surface_drop.py` 2건 통과 — 계획고·좌우 노견이 정확히
  0.39m 내려가고, 절토는 늘고 성토는 줄며, 하강이 없으면 `surface_drop_m` 키 자체가
  없다.
- 화면 실측: y축 눈금 1m = 24.375px에서 십자선이 점선보다 9.50px 아래
  (= 0.390m, 오차 0.001m). 수정 전에는 두 선이 같은 자리였다.
- 세월교 측벽 자동 높이 1.70m → 1.50m. 이론값 1.31m이나 하한(관경 1.0 + 최소 토피
  0.5 = 1.5m)에 걸린 값이다 — 기존 규칙 그대로다.
- 성토 면적 18.46 → 13.85 ㎡. 이웃 일반 측점에는 점선이 그려지지 않는다.
- 검증에 쓴 `pipe_points.json` 임시 옵션은 백업본으로 되돌렸다(정본 무변경).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 12:54:29 +09:00
eomsangdonandClaude Opus 5 7385b4d76f fix(B06): 월류 폭을 바꾸면 월류 높이(필요 수심)가 따라오게 한다
`syncFordSummary`가 "빈 칸이거나 계산값보다 작을 때만" 높이를 채워 넣어, 폭을
바꿔 필요 수심이 **낮아지는** 쪽으로 움직이면 칸이 옛 값 그대로 남았다. 안내문
(설계유량·필요 수심·필요 단면)만 바뀌고 높이는 안 바뀌는 것으로 보였다.

칸이 아직 **직전에 자동으로 채운 값 그대로**인지 본다(±0.005m). 그대로면 자동
상태로 보고 계산값을 계속 따라가고, 사용자가 다른 값을 넣었으면 그때부터 그
값이 이긴다. 시설을 새로 폼에 올릴 때는 추적을 끊어(`fordAutoDepthM = null`)
저장돼 있던 높이를 사용자 값으로 대접한다.

자체검증(공용 브라우저 5174, 측점 7+9.7 세월교, 설계유량 36.734 ㎥/s):
- tsc --noEmit 통과.
- 자동 상태(폭 10 → 높이 0.39)에서 폭 5 → 0.63(올라감), 폭 20 → 0.25(내려감).
  수정 전에는 0.63에서 내려오지 않았다.
- 높이를 2.5로 직접 넣은 뒤 폭 20→5 → 2.5 유지(사용자 값 우선).
- 조작값은 원래대로(폭 10 · 높이 자동 0.39) 되돌려 놓았다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 12:23:38 +09:00
eomsangdonandClaude Opus 5 f8086e786d fix(B06): 세월교 월류 높이가 자동 계산되지 않던 것을 고친다
B06 좌측 폼이 계곡 통과 시설 목록을 만들 때 `design_flow_m3s: null`을 그대로
박아 넣고 있었다. 개략 단면(필요 수심 = 월류 높이 자동값)은 담당 유역의 설계
유량에서 나오므로, 값이 없으면 "담당 유역의 설계유량이 아직 없습니다" 안내만
뜨고 월류 폭을 넣어도 높이가 채워지지 않았다.

같은 응답(`/drainage/pipe-points`)에 유역(`basins`)이 함께 오므로 B05
(`B05_Profile_UI_Drainage_Panel`)와 같은 규칙 — 누가거리 0.51m 이내 짝짓기 —
으로 설계유량을 실어 준다.

자체검증(공용 브라우저 5174, 측점 7+9.7 세월교):
- tsc --noEmit 통과.
- 벽 선택 시 안내문 "설계유량 36.734 ㎥/s · 필요 수심 0.39 m · 필요 단면
  3.89 ㎡ · 유속 9.43 m/s", 월류 높이 칸 자동 0.39 (수정 전 빈 칸).
- 월류 폭 10→5 → 필요 수심 0.63으로 다시 계산되고 높이도 0.63으로 올라간다.
  (폭을 10으로 되돌려도 0.63은 유지 — 계산값 이상은 사용자 입력으로 본다는
  기존 규칙 그대로다.)
- 조작값은 원래대로(폭 10·높이 0.39) 되돌려 놓았다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 12:16:50 +09:00
eomsangdonandClaude Opus 5 e78feab5ed feat(B06): 세월교 좌측 폼을 배관 측점과 같은 양식으로 맞춘다
사용자 지시 3건(2026-08-30).

1) 횡단도에서 세월교 측벽을 고르면 좌측 폼의 그 측 칸이 선다 — 배관 기슭막이가
   쓰던 경로를 그대로 탄다. `SideSlots`에 `wingInlet`·`wingOutlet`을 더하고
   `slotOf()`가 배관 칸 → 독립 기슭막이 칸 → 날개벽 칸 순으로 지금 서 있는 쪽을
   고른다. 세월교 조정창은 `dataset.side`·`dataset.panelTitle`을 세워 어느 칸을
   가리키는지 알린다. 벽 선택 뒤 `refreshAdjustSlots()`도 배관과 같게 붙였다.

2) 월류 폭·높이·수량·개략 단면 결과를 관경 바로 다음으로 옮겼다(바닥 경사도 같은
   묶음에 둔다 — 물넘이포장 전용이라 세월교에서는 숨는다). 개략 단면 안내문은
   읽는 글이라 10px·opacity 0.75로 줄였다.

3) 세월교·날개벽 숫자 칸을 기슭막이·집수정과 같은 [-][값][+] 묶음으로 바꿨다
   (월류 폭·높이·바닥 경사·수량·날개 높이·길이·각도). `stepper()`에 표시 자릿수
   인자를 더해 련·각도는 정수로 보인다("1.0련"·"45.0°" 방지). 기본값 1이라 기존
   호출부는 그대로다.

자체검증(공용 브라우저 5174, 측점 7+9.7 세월교):
- tsc --noEmit 통과.
- 유입 측벽 선택 → `날개벽(유입) (세월교)` 칸 강조, 유출 측벽 → `날개벽(유출)
  (세월교)`. 한 번에 한 칸만 선다.
- 폼 항목 순서 실측: 관종 > 관경 > 월류 폭 > 월류 높이 > 수량 > 날개벽(유입) …
  안내문 font-size 10px, 보이는 스텝 묶음 9개.
- 수량 + → 폼 "2"·조정창 "2련", 각도 + → 폼 "50"·조정창 "50°" (소수점 없음).
- 회귀: 배관 측점 기슭막이 선택 → `유출구 (기슭막이(유출))` 강조 + 높이·길이·
  기준측점 전/후 행 이식 정상.
- 조작값은 원래대로(수량 1·각도 45) 되돌려 놓았다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 12:05:22 +09:00
eomsangdonandClaude Opus 5 03840ff3d6 feat(B06): 세월교 좌측 「구조물 배치」 폼을 조정창 로직에 연결한다
좌측 폼의 세월교 상세 항목(관종·관경·수량·월류 폭·날개벽 유입/유출)이 도면에
전혀 반영되지 않았다. `applyPipeOptionsToCache`가 `section.culvert`만 보고
세월교 측점(`section.ford`)에서는 즉시 return했기 때문이다.

프론트는 구조물 배치의 상세 UI를 쓰고 로직은 조정창 제어기 것을 쓴다
(2026-08-30 사용자 확정).

- `applyFordFormOptions()` 신설 — 폼 옵션 키를 `FordControl.setPipe`/`setWing`
  인자로 옮긴다. 캐시 반영·바닥판 연장 재계산·정본 예약·카드 갱신은 제어기에
  이미 있어 새로 만들지 않았다.
- `FordControl.setPipe` 확장 — `pipe_kind`(관종)·`ford_width_m`(월류 폭 =
  `span_m`) 추가. 두 값은 조정창에 칸이 없고 폼만 보낸다.
- `withFordSpec()` — 폼 기본값을 `section.ford` 스펙에서 읽는다. 두 창이 같은
  스펙을 보므로 어느 쪽에서 만졌든 값이 갈리지 않는다(수량(련) 빈 칸 해소).

월류 높이(`ford_height_m`)는 백엔드 `_ford_set`이 읽지 않는다 — 세월교는 구체
위 노면이라 파임이 없고, 물넘이포장 전용 값이다. 폼에는 남되 도면 반영처는 없다.

자체검증(공용 브라우저 5174, 측점 7+9.7 세월교):
- tsc --noEmit 통과.
- 폼 날개 길이(유입) 2→4 → 조정창 「날개 길이 4.0m」, 바닥판 7.63m→9.04m
  (= +2×cos45°). 수정 전에는 둘 다 그대로였다.
- 폼 수량 3 → 조정창 「3련」, 폼 관경 Ø1200 → 조정창 select 1200.
- 재선택 왕복: 월류폭 12·수량 3·관경 1200·날개길이 4 그대로 되읽힘(스펙 정본).
- 진입 시 수량(련) 칸 = 1(수정 전 빈 칸), 관종 파형강관.
- 조작값은 원래 값(10/1/1000/2)으로 되돌려 놓았다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 11:44:54 +09:00
eomsangdon 14044de50e fix(B06): 추가 기슭막이를 골라도 부모 벽의 단 수·옵션을 세워 둔다
다단 벽을 고르면 단 수·옵션 행이 사라지던 문제. 두 값은 그 단이 딸린 부모 벽의
것이므로 다단 쪽으로 옮기지 않고 부모 칸에 남긴다.

- Adjust_Dock: EXTRA_ROWS에서 단 수·옵션을 빼고, 행 이동을 moveRows()로 묶어
  다단 선택 시 형태·높이·구간값은 다단 칸으로, 단 수·옵션은 부모 칸으로 보낸다.
- Cross_Structure_Panel: extra/bextra 선택에서도 단 수 채널을 부모 쪽(outlet·basin)
  으로 열어 둔다.

저장소 사고(2026-08-30 01:12)로 유실된 커밋 bc8a3477의 작업물을 복원한 것이다.
원 작업자는 병렬 B05/B06 세션이며 워킹트리에 남아 있던 변경을 그대로 커밋했다.
2026-08-30 02:23:52 +09:00
eomsangdon 465ff2b8ef fix(B05): 종단테이블 구조물 측점 빈 칸의 세로선을 지운다
구조물 측점 빈 칸의 세로선이 이웃 규칙 측점 값 한가운데를 지나고, 곡선 L/R 칸
경계와 x가 겹쳐 곡선 행 구분선이 위 행들까지 이어진 것처럼 보였다. 세로선을
곡선 행에만 남기고 값 행에서는 지운다 (2026-08-30 사용자 지시).

저장소 사고(2026-08-30 01:12)로 유실된 커밋 84d02b68의 작업물을 복원한 것이다.
원 작업자는 병렬 B05/B06 세션이며 워킹트리에 남아 있던 변경을 그대로 커밋했다.
2026-08-30 02:23:51 +09:00
eomsangdon ea9d9685be feat(B07): CAD를 AutoCAD 명령 체계로 재구성한다 (조사표 1·2·3·5절)
저장소 사고로 잃은 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에 사유를 적었다.
2026-08-30 01:34:13 +09:00
eomsangdonandClaude Opus 5 c8ce7ae02a fix(B06): 추가 기슭막이 선택 시 부모 칸의 단 수·옵션 유지
단 수·옵션 행은 조정창 사본에서 DOM째 빌려온 행이라, 다단 벽을 고르면
clearSideSlots()가 되돌린 뒤 다시 채우지 못해 유입구·유출구 칸이 비었다.
다단 벽에서도 tierChannel을 부모 채널로 열어 두 행을 살리고(revetWall에
isExtra 포함), 이식은 부모 칸으로 보낸다. 추가 기슭막이 칸에는 형태·
높이·구간값만 남긴다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 00:32:09 +09:00
eomsangdonandClaude Opus 5 c8b5a8bf38 fix(B05): 종단테이블 구조물 측점 빈 칸의 세로선 제거
구조물 측점(세월교·BOX암거 등) 빈 칸의 border-left가 이웃 규칙 측점 값
한가운데를 지나고, 곡선 L/R 칸 경계와 x가 정확히 겹쳐 절토고~곡선 R를
관통하는 한 줄로 보였다. 값 행에서만 선을 지우고 곡선 행 구분선은 유지한다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 00:32:09 +09:00
eomsangdon 487539bba1 auto: 2026-08-29 23:30 (ESD_LAPTOP) 2026-08-29 23:30:04 +09:00
eomsangdonandClaude Opus 5 03840407f6 chore(resources): AutoCAD 리본·주요 기능 조사자료 추가
B07 CAD 화면 개선 참조용. AutoCAD 2024 Windows 기본 2D 제도 기능 기준,
Autodesk 공식 명령 참조·2024 신규/변경 명령·상태막대와 재대조한 조사 결과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-29 23:20:07 +09:00
junghoonkim cfcba27481 PushTest 2026-07-28 06:10:38 +09:00