- CLAUDE.md: 프로젝트 전체 가이드 및 워크플로우 정의 - CONSIDERATIONS.md: 8개 영역 고려사항 분석 (기술, 품질, 배포, UX) - PROGRESS.md: 진행 상황 추적 및 체크리스트 - PLAN.md: 단계 5~9 상세 계획 및 에이전트 역할 정의 - 메모리: 프로젝트 정보 저장 다음: 단계 5 (에이전트/커맨드/스킬/훅 아이디어 제안)
16 KiB
로드맵 — 일반 도면 세트 → 3D → IFC
지금 파이프라인은 평면도 + 단면도 조합에서 검증됐다(맨홀 일반도 4매, 11파트). 2026-08-07 에 두 번째 도면군(교량 설계지침 삽도 7장)을 넣어 1장을 관통시켰다 (중앙분리대 방호벽, 4.8058 m³ — 모델러·해석 일치). 궁극 목표는 평면 · 입면 · 단면 · 좌측면 · 우측면을 읽어 IFC 구조로 내보내는 것.
이 문서는 거기까지 무엇이 남았는지, 어떤 순서로 하면 되는지를 적는다.
두 번째 도면군이 바꾼 것. 남은 일 목록이 「연산이 부족하다」에서 「입력 해석 가정이 부족하다」로 옮겨갔다. 교량에서 실제로 막은 것은 sweep·revolve 가 아니라 단위·축척·뷰 제목·레이어·폐곡선이었다. 자세한 것은
methodology.html11장, 교훈은2d-3d-conversion.md#20~#26.
그 위에 얹은 파라메트릭 설계 층은
parametric.md에 따로 있다. 구현됐다(fit/build 분리 · 규칙 · 편집 UI). 본체 목표(2D→3D)를 대체하지 않는다.
1. 뷰 종류의 일반화
지금 titles.views 는 뷰 제목을 네 가지 kind 로 분류한다.
plan 평면도 DWG(x,y) → 프로젝트(X, Y)
long 종단면 DWG(x,y) → 프로젝트(X, Z)
cross 횡단면 DWG(x,y) → 프로젝트(Y, Z)
horizontal 수평 단면 DWG(x,y) → 프로젝트(Y, X) (swapUV)
정면도·배면도·좌측면도·우측면도를 넣으면 이렇게 된다.
| 뷰 | 보는 방향 | 평면 | 비고 |
|---|---|---|---|
| 평면도 | −Z (위에서) | XY | |
| 저면도 | +Z | XY | 좌우 반전 → flip |
| 정면도 | +Y | XZ | |
| 배면도 | −Y | XZ | 좌우 반전 → flip |
| 좌측면도 | +X | YZ | |
| 우측면도 | −X | YZ | 좌우 반전 → flip |
| 종단면 | ±Y | XZ | 정면도와 같은 평면 |
| 횡단면 | ±X | YZ | 측면도와 같은 평면 |
| 수평 단면 | −Z | XY | 평면도와 같은 평면 |
결국 평면은 셋(XY · XZ · YZ)뿐이고, 나머지는 반전 여부의 문제다.
kind 라는 이름이 오해를 부른다 — 앞으로는 plane + flip 으로 부르는 게 맞다.
할 일
titles.views항목을{ plane, u0, v0, flip, flipV, swapUV }한 덩어리로 합친다. 지금은titles.views와anchors로 나뉘어 있어 뷰 하나가 두 곳에 흩어져 있다.- 뷰가 어느 방향에서 본 것인지 도면에서 검출할 방법을 찾는다.
단면은 절단 기호(
SYM)로 알 수 있지만, 입면도는 제목 말고 단서가 없다. → 제목 규칙(정면도/좌측면도…)을 설정에 두는 게 현실적이다.
2. 입면도가 단면도와 다른 점
단면도는 잘린 면만 그리지만 입면도는 보이는 모든 것을 그린다. 그래서 입면도의 폐곡선은 구조체 경계가 아니라 투영 윤곽이다.
| 단면도 | 입면도 | |
|---|---|---|
| 폐곡선의 의미 | 재료 영역 | 보이는 면의 윤곽 (여러 깊이가 겹침) |
| 압출 가능? | 그대로 가능 | 불가. 깊이 정보가 없다 |
| 쓸모 | 형상 생성 | 형상 검증, 높이·폭 확인, 개구부 위치 |
입면도로 솔리드를 만들려 하지 말 것. 입면도는
- 다른 뷰에서 만든 형상의 외곽 검증
- 창·문·개구부의 XZ(또는 YZ) 위치 확보
- 마감선·레벨선 확인
에 쓰고, 실제 압출은 평면도(footprint) + 단면도(높이)로 한다.
할 일
- 입면도용 검증 도구: 만든 3D 를 그 방향으로 투영해 입면도 윤곽과 대조
- 개구부 위치만 뽑아 쓰는 경로 (지금
rect()+expect()로 하는 것과 같은 방식)
3. 곡면 · 원호
지금은 직선 선분만 다룬다(src/core/parse.mjs 의 toSegments).
ARC · CIRCLE · ELLIPSE 는 버린다.
| 대상 | 필요한 것 |
|---|---|
| 모따기·필렛 | 이미 직선으로 그려져 있으면 그대로 됨 (지금 잘 되고 있다) |
| 원형 관통 (Ø900·Ø100) | 됨 — collectCircles → circles() → cylinder |
| 원호 벽체 | ARC 를 선분으로 근사(tessellate)하거나 IR 에 호 지원 추가 |
| 나선계단 | 전용 연산. Sweep1 또는 파라메트릭 생성 |
CIRCLE — 된다 (2026-08-06)
node src/build.mjs <도면> --circles # 뷰별 원 목록 (지름 · 레이어 · 좌표)
circles('평 면 도', 900, /^-전력구$/) // 지름으로 집는다. 폐곡선과 같은 규칙
circle('평 면 도', 100) // 정확히 하나일 때. 여럿이면 예외
선분과 섞지 않는다. 원을 다각형으로 근사해 평면 분할에 넣으면 폐곡선이 그
윤곽을 따라 돌아 프로파일이 오염된다. 원은 그 자체가 형상이라 cylinder 로 바로 간다.
뷰 귀속은 중심 좌표로 한다 — 뷰 분리(조각 클러스터링)에 원을 넣으면 관통 구멍 하나가 뷰를 잇는 다리가 될 수 있다. 이 도면은 133개 중 129개가 귀속됐다.
부수 효과: 평면도에 v0 앵커가 필요해졌다. 평면도는 세로축이 표고가 아니라
폭방향(Y)인데, 지금까지 치수(폭×높이)만 봐서 드러나지 않았다. 좌표를 직접 쓰는
순간 필요해진다. 수평 단면(H/I/J)과 같은 문제였다.
남은 것: Ø100 관통 5개(환기구 4 · 배수관 1). 평면도에 있는 1개는
X=17,690 으로 맨홀 #2 영역이라 그 형상을 세운 뒤에 뚫는다.
4. IFC 출력
이미 확보된 것
레이어가 재질을 인코딩한다는 사실(노하우 문서 교훈 #6). 그래서 클래스·재질 배정에 필요한 정보가 이미 IR 에 실려 있다.
part({ …, name: '맨홀1_전력구_구체',
material: '구체 콘크리트 fck=27MPa' })
매핑 초안
| 부재 | IFC 클래스 | 재질 |
|---|---|---|
| 벽체 | IfcWall |
Concrete C27 |
| 슬래브 | IfcSlab |
Concrete C27 |
| 기초 | IfcFooting |
Concrete C18 |
| 잡석·토목섬유 | civil 계열 (IFC4.3 엔티티명 확인 필요) | — |
| 집합 요소 | IfcBuiltElement 또는 civil 계열 |
— |
- 재질 속성 →
IfcMaterial+Pset_MaterialConcrete(CompressiveStrength) - 층상 구성(잡석 → 기초 → 구체) →
IfcMaterialLayerSet - 설계 정보(fck · fy · 설계법 · 하중) →
IfcProject속성
IfcWall/IfcSlab/IfcFooting/IfcMaterial*/Pset_MaterialConcrete는 IFC4 표준이라 그대로 써도 된다. 잡석·토목섬유용 IFC4.3 civil 엔티티 이름은 스키마를 직접 확인하고 확정할 것. 위 표의 후보는 검증 전이다.
할 일
part에ifcClass필드 추가 (지금은material만 있다)src/emit/ifc.mjs— IR → IFC4 STEP(.ifc)- 형상 표현:
IfcExtrudedAreaSolid가 지금 IR 의extrude와 1:1 로 맞는다.difference/union은IfcBooleanResult로 그대로 옮겨진다. IR 을 IFC 를 염두에 두고 설계해둔 게 여기서 값을 한다.
5. 우선순위 제안
2026-08-06 에 순서를 정했다 — 본체(A)를 좁혀서 먼저, 그 다음 파라메트릭(B).
근거는 parametric.md 11절.
✔ 0. 부피 측정 자동화 (measure.mjs) 손계산 → 회귀 검사. B 의 quantity 몸통
✔ 1. CIRCLE → circles() 헬퍼 손으로 적은 R450 이 도면 대조로 바뀌었다
2. manhole1-trans 를 본편으로 통합 지금 반쪽 모델이 둘이다. 기초·잡석 이관
3. 맨홀 #2 + 출구 스터브 제일 크다. 파라미터 표본을 대표성 있게 만든다
✔ 4. 파라메트릭 (parametric.md 10·12절) fit/build 분리 · 규칙 · 편집 UI 까지 완료
5. 뷰 설정 통합 (titles.views + anchors + viewBoxes → 한 덩어리) ← 아래 참고
6. emit/ifc.mjs IR 이 이미 준비돼 있다
7. 입면도 검증 경로 새 도면 종류를 받으려면 필요
8. Sweep 백엔드 (선형 곡선부·구배) Loft 는 완료
5 의 값이 올라갔다. 뷰 하나를 서술하는 자리가 이제 셋이다 —
titles.views(평면) · anchors(앵커·축척) · viewBoxes(영역·평면·축척).
unitMm 이 viewBoxes 와 anchors 양쪽에 있고, 뷰 분리 방식에 따라 어느 쪽이
읽히는지가 갈린다. 뷰 종류를 늘리기 전에 정리하는 편이 싸다 —
{ plane, box?, u0, v0, flip, flipV, swapUV, unitMm, role } 한 덩어리로.
교량군에서 새로 생긴 것 (전부 구현됨, 정리 필요):
cfg.unitMm DWG 모델단위. 도면군마다 다르다
cfg.entityFilter 레이어 말고 색·선종으로 거른다
cfg.viewBoxes 제목 없는/중복인 도면의 뷰 영역
cfg.datum.mode='none' 공통 기준선이 없는 도면
viewBoxes[뷰].unitMm 도형별 축척
rules[].needs 규칙 적용 범위 (부재 타입 태그의 임시 대용)
아직 없는 것 (교량 일반도를 받으면 바로 필요해진다):
G1.5 도면 적격 판정 도구 숫자/기호 치수 계수 + 윤곽 닫힘률. 지금은 손으로 센다
축척 역산 도구 표기 치수 2개 ↔ 기하 길이 대조. 지금은 손으로 잰다
부재 타입 태그 rules 를 파라미터 이름이 아니라 부재 종류에 붙인다
받침 기반 로컬 프레임 상부(선형) ↔ 하부(연직) 좌표계 전환 (methodology 11.1)
1 을 3 보다 앞에 두는 이유는 로드맵상 흔해서만이 아니다. 파라메트릭의
전제이기도 하다 — 지금 샤프트 보어 R450 은 원본 엔티티에서 눈으로 읽어 손으로
적은 값이라 도면과의 끈이 아예 없다. CIRCLE 지원이 들어와야 loop()/expect()
로 대조되고, 그제서야 보어 반지름이 정당한 파라미터가 된다.
1·2·3 은 서로 독립이라 순서를 바꿔도 된다.
Loft 백엔드는 끝났다 — 전이부(챔퍼·수직 단차·종방향 헌치)를 세워 부피
오차 0.0002% 로 검증했다. 배경은 2d-3d-conversion.md
교훈 #16. 남은 것은 rail 을 따라가는 스윕이다 (Sweep1 C=True V=True 가
IFC4.3 IfcSectionedSolidHorizontal 과 의미가 같다). 그러려면 IR 이 직선축
from/to 대신 측점(station) 을 다뤄야 한다.
4 는 실제 입면도가 있는 도면을 하나 받아야 설계가 확정된다.
6. 미완 목록 (맨홀 도면 기준)
| 항목 | 상태 |
|---|---|
| 스터브↔본체 전이부 | 완료. assembleDuct() 를 본편·trans 가 공유한다 |
| 관로↔맨홀 관통구 | 완료. 개구 기호에서 좌표가 나온다. 합치기 전에 뚫는다 |
| 구조물만 (기초·잡석 제외) | 완료. 5파트 |
| 맨홀 #2 부피 9.32 손실 | IR 은 맞고(74.68) 모델러가 흘린다(65.36). 원인은 면으로만 맞닿은 union — 교훈 #19 |
| 외부 헌치 5개 | 완료. 아래 참조 |
| 내부 헌치 (100×100·150×150) | 미구현. 맨홀을 수평 단면에서 Z 로 쌓아야 따라온다 |
| H/I/J 내부 링 끊김 | H-H 내부가 Y 1,800~3,700 만 닫힌다. 위 항목의 전제 |
| Ø100 관통 5개 | 위치 확인됨 (전선인입 ×2 · 우수관연결 ×2 · 유도배수관 ×1). 미구현 |
| 침사구 (0.8×0.8) | I-I 개구 기호로 잡힌다. opening('단 면 I-I', 800, 800) |
| 나선계단 · 방호난간 | 현 IR 연산으로 표현 불가 |
| 기초 · 잡석 · 보도 | 뺐다. 되살리는 데 필요한 값은 manhole1.mjs 주석에 있다 |
외부 헌치 — 완료 (2026-08-06)
평면도 대각선 21개 중 외부 표면 모서리인 5개를 세 종류로 나눠 넣었다. Z 구간은 도면에서 뽑았지 지어내지 않았다.
| 종류 | 도면 근거 | 구현 | 부피 변화 |
|---|---|---|---|
| 출구 스터브 챔퍼 | A-A (18200,-4607)→(18500,-4907) 300×300 · (18200,-8007)→(18550,-7657) 350×350 |
loft 2단 | +0.577 |
| 전력구↔맨홀 접합 | 평면 (15100,1900)→(15400,2200) 300×300 |
XY 삼각형 → Z 압출 → union | +0.224 |
| 챔버↔환기구 다리 | 평면 (15400,4100)→(15500,4200) 100×100 ×2 |
XY 사각 쐐기 → Z 압출 → 커터 | −0.029 |
3D 검증 완료 — modelCount 5, 의도 vs 결과가 셋 다 맞는다.
파트 실측 IR 의도 차이
맨홀1_전력구_구체 100.7473 100.7592 −0.0119 ✓ 접합 헌치 들어감
맨홀1_전력구_출구스터브 3.5474 3.5490 −0.0016 ✓ 출구 챔퍼 2단 들어감
맨홀1_사다리샤프트_1·2 3.3217/3.2805 ✓ 건드리지 않은 것 확인
맨홀1_맨홀2_구체 66.0875 74.6527 −8.5652 ✗ 기존 손실 (수평단면 재구성 대기)
출구는 입구와 대칭이 아니다. 위·옆은 300×300(X 18,20018,500)인데 아래는
350×350(18,20018,550)이라 꺾이는 X 가 다르다. loft 하나로 이으면 아래 챔퍼가
300 짜리로 짧아진다 — 입구에서 이미 겪은 교훈 #16 이 그대로 반복됐다.
검산: 격자 +0.5765 vs 심프슨 해석 +0.5749 — 0.3% 일치.
평면 방향 헌치는 XZ 단면에 안 나타난다. 다리 100×100 의 Z 범위를 F-F·G-G 에서
찾으려 했지만 없다(거기 있는 150×150 은 다리 내부 헌치다). 그래서 fit() 이
E-E 외곽 링에서 Y>4,200 구간의 Z 범위를 코드로 뽑는다 → −5,257 ~ 176.
다리 테이퍼의 부피 변화가 작은(−0.029) 데는 이유가 있다. E-E 링을 보면 하부 블록이
Y=4,100 에서 끝나고([4100,-10007]→[4100,-5557]) 그 위로 다리가 선다. 그래서
테이퍼가 걸리는 Y 4,100~4,200 구간에는 재료가 100mm 높이밖에 없다.
맨홀 #2 를 수평 단면 기반으로 다시 세우면 셋이 한꺼번에 풀린다
부피 9.32 손실 조각이 Z 로 진짜 겹쳐 union 이 한 덩어리가 된다
내부 헌치 H/I/J 의 XY 프로파일에 모따기가 이미 들어 있다
층별 정확도 E-E 치수 사슬이 각 층의 Z 범위를 그대로 준다
전제는 H/I/J 의 내부 링 끊김 수리다. 조사는 끝났다.
gaps.mjs 는 H-H·I-I 에 끊김 0 이라고 한다 — 선이 없는 게 아니라 개구부
윤곽이 안 닫혀 있어 면이 새는 것이다(교훈 #12 와 같은 종류). 선분을 직접 뽑아
실태를 확정했다.
H-H 내부는 격벽으로 3칸이다 (전부 X 15,800~17,800, 모서리 150×150 모따기)
A Y -1,500 ~ 1,500 3,000 ← 환기 OPEN부가 들어 있어 안 닫힘
B Y 1,800 ~ 3,700 1,900 ← 유일하게 폐곡선으로 잡힌다 (#2)
C Y 3,700 ~ 8,000 4,300 ← 점검구·방호난간이 들어 있어 안 닫힘
격벽 Y 1,500~1,800 (300)
A·C 가 안 닫히는 이유는 개구부 좌측 변이 000-구조물실선 에 Y -1,000~1,000
로만 그려져 있기 때문이다(개구는 Y -500~1,500). 대응은 교훈 #12 대로
rect()/opening() 으로 재구성 — 위 좌표가 그 재료다.
7. 검증 기준선
baselines/<도면>.volumes.json 은 커밋한다. out/ 과 달리 재생성으로
복구되지 않기 때문이다 — 사람이 한 번 확인한 부피가 남아 있어야 다음 변경이
형상을 건드렸는지 알 수 있다.
| 도면 | 파트 | 부피 m³ | 확인 |
|---|---|---|---|
manhole1-trans |
3 | 107.1425 | 원시 파트 합으로 교차검증 |
manhole1 |
11 | — | 기준선 없음. 통합 후 뜬다 |