diff --git a/features/construction-pmis/bim-viewer.md b/features/construction-pmis/bim-viewer.md index e1ddeca..e2b0341 100644 --- a/features/construction-pmis/bim-viewer.md +++ b/features/construction-pmis/bim-viewer.md @@ -1,7 +1,7 @@ -# BIM 뷰어 — Three.js 기반 웹 3D 건물 모델 뷰어 +# BIM 뷰어 — Three.js + web-ifc 기반 웹 3D BIM 뷰어 > **작성일**: 2026-03-12 -> **상태**: Phase 1 완료 (프로토타입) +> **상태**: Phase 2 완료 (IFC 업로드 + 다운로드) > **소스**: `mng/resources/views/juil/bim-viewer.blade.php` --- @@ -12,97 +12,216 @@ 건설PMIS(Construction Project Management Information System)의 BIM(Building Information Modeling) 뷰어 기능이다. 웹 브라우저에서 별도 플러그인 없이 3D 건물 모델을 렌더링하고, 요소를 선택하여 속성 정보를 조회할 수 있다. -### 1.2 핵심 기술 스택 +### 1.2 주요 기능 -| 기술 | 역할 | CDN | -|------|------|-----| -| **Three.js r128** | WebGL 기반 3D 렌더링 엔진 | `cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js` | -| **OrbitControls** | 카메라 회전/줌/팬 조작 | `cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.js` | +| 기능 | 설명 | Phase | +|------|------|-------| +| 데모 건물 렌더링 | 물류센터 3D 모델 (BoxGeometry 조합) | Phase 1 | +| 요소 클릭 선택 | Raycaster로 3D 요소 선택 → 속성 조회 | Phase 1 | +| 시점 전환 | 투시도/정면/우측/상부/배면 프리셋 | Phase 1 | +| 요소 토글 & 와이어프레임 | 요소 유형별 표시/숨김, 와이어프레임 모드 | Phase 1 | +| **IFC 파일 업로드** | `.ifc` 파일 업로드 → 실제 BIM 모델 렌더링 | **Phase 2** | +| **IFC 파일 다운로드** | 현재 모델을 IFC 파일로 내보내기 | **Phase 2** | +| **드래그 앤 드롭** | IFC 파일을 뷰포트에 드래그하여 로드 | **Phase 2** | + +### 1.3 핵심 기술 스택 + +| 기술 | 역할 | 버전/CDN | +|------|------|----------| +| **Three.js** | WebGL 기반 3D 렌더링 엔진 | r128 (CDN) | +| **OrbitControls** | 카메라 회전/줌/팬 조작 | r128 (CDN) | +| **web-ifc** | IFC 파일 파싱 (WASM 기반) | 0.0.66 (CDN, 지연 로드) | | **React 18** | UI 컴포넌트 (사이드바, 툴바, 정보 패널) | CDN + Babel 브라우저 트랜스파일 | | **Tailwind CSS** | UI 스타일링 | CDN | -### 1.3 아키텍처 +### 1.4 아키텍처 ``` -┌─────────────────────────────────────────────────┐ -│ Blade 템플릿 (@extends layouts.app) │ -│ ┌─────────────────────────────────────────────┐│ -│ │ React (CDN + Babel) ││ -│ │ ┌──────┐ ┌──────────────┐ ┌───────────┐ ││ -│ │ │사이드 │ │ Three.js │ │ 정보 패널 │ ││ -│ │ │ 바 │ │ 3D Viewport │ │ (React) │ ││ -│ │ │(React)│ │ (WebGL) │ │ │ ││ -│ │ └──────┘ └──────────────┘ └───────────┘ ││ -│ │ ┌──────────────┐ ││ -│ │ │ 툴바(React) │ ││ -│ │ └──────────────┘ ││ -│ └─────────────────────────────────────────────┘│ -└─────────────────────────────────────────────────┘ +┌─────────────────────────────────────────────────────────┐ +│ Blade 템플릿 (@extends layouts.app) │ +│ ┌─────────────────────────────────────────────────────┐│ +│ │ React (CDN + Babel) ││ +│ │ ┌──────┐ ┌──────────────────┐ ┌───────────────┐ ││ +│ │ │사이드 │ │ Three.js │ │ 정보 패널 │ ││ +│ │ │ 바 │ │ 3D Viewport │ │ (모델/선택/ │ ││ +│ │ │(React)│ │ (WebGL) │ │ 통계) │ ││ +│ │ └──────┘ └──────────────────┘ └───────────────┘ ││ +│ │ ┌──────────────────┐ ││ +│ │ │ 툴바 (React) │ ││ +│ │ │ IFC업로드/다운로드│ ││ +│ │ └──────────────────┘ ││ +│ └─────────────────────────────────────────────────────┘│ +│ │ +│ ┌─────────────────┐ ┌──────────────────────────────┐ │ +│ │ IFCHelper │ │ generateDemoIFC() │ │ +│ │ (web-ifc 래퍼) │ │ (Three.js → IFC2X3 변환) │ │ +│ └─────────────────┘ └──────────────────────────────┘ │ +└─────────────────────────────────────────────────────────┘ ``` - **React**: UI 컴포넌트 관리 (사이드바, 툴바, 정보 패널) - **Three.js**: 3D 렌더링 (건물, 조명, 그림자, 카메라) +- **web-ifc**: IFC 파일 파싱 → 지오메트리 추출 (WASM, 지연 로드) - **연결 방식**: React `useRef`로 DOM 요소를 Three.js에 전달, `useEffect`로 생명주기 관리 --- -## 2. Three.js 렌더링 파이프라인 +## 2. 듀얼 모드 — 데모 / IFC -### 2.1 기본 구조 +BIM 뷰어는 두 가지 모드로 동작한다: + +| 항목 | 데모 모드 (`demo`) | IFC 모드 (`ifc`) | +|------|-------------------|------------------| +| 진입 방식 | 기본 (페이지 로드 시) | IFC 파일 업로드/드래그 시 | +| 모델 원본 | `createDemoBuilding()` (코드 내 하드코딩) | 사용자 업로드 `.ifc` 파일 | +| 지오메트리 | `BoxGeometry` 조합 (~200개) | web-ifc `StreamAllMeshes` → `BufferGeometry` | +| 요소 선택 시 | `userData` (type, name, material, floor 등) | `IFCHelper.getElementInfo()` (IFC 속성) | +| 요소 토글 | 유형별 Group 표시/숨김 | 미지원 (전체 모델 표시) | +| IFC 다운로드 | `generateDemoIFC()` → IFC2X3 STEP 생성 | 원본 버퍼 그대로 재다운로드 | + +모드 전환 흐름: + +``` +[페이지 로드] → 데모 모드 + │ + ├── IFC 업로드 ──→ IFC 모드 (데모 숨김) + │ │ + │ ├── "데모 모델" 버튼 ──→ 데모 모드 복귀 + │ └── 다른 IFC 업로드 ──→ 새 IFC 로드 + │ + └── IFC 다운로드 → generateDemoIFC() 실행 → .ifc 파일 다운로드 +``` + +--- + +## 3. IFC 파일 처리 (Phase 2) + +### 3.1 web-ifc 지연 로드 + +web-ifc WASM 번들은 약 7MB이다. 페이지 로드 시 다운로드하지 않고, IFC 파일을 처음 업로드할 때만 로드한다: + +```javascript +// 동적 module script 주입 방식 +function loadWebIFCLib() { + const s = document.createElement('script'); + s.type = 'module'; + s.textContent = ` + import * as WebIFC from '${WEBIFC_CDN}web-ifc-api.js'; + window._WebIFC = WebIFC; + window.dispatchEvent(new CustomEvent('_wifcOk')); + `; + document.head.appendChild(s); +} +``` + +> Babel `text/babel` 컨텍스트에서 동적 `import()`가 불안정하므로, 별도 `