# Project: 4D BIM Ông Đèn Box Culvert Simulation & Interactive Site Diary

## Architecture
- **Rendering & 3D Engine**: WebGL via Three.js r128 (`app/static/bim/index.html`, `three.min.js`, `OrbitControls.js`).
- **Parametric Alignment Engine**: $L_{TOTAL} = 146.46\text{ m}$, 4 geometric segments along curved centerline with Frenet frame $(\vec{t}, \vec{u}_y, \vec{n})$ via `getAlignment(s)` and `getPointAt(s, u, y)`.
- **Annotation & Callout Engine**: `THREE.Sprite` with supersampled 2D `CanvasTexture` (Dark Slate pill capsule `#0f172a`, border `#38bdf8`, text `#f8fafc`), combined with `THREE.LineSegments` (45° architectural slash ticks) in `groupDimensions`.
- **4D Phasing Simulation Engine**: 90-day parametric timeline player (Play/Pause, 1x/2x/5x, slider 1 to 90), driving 6 construction phases per Sheet 04 using 3 culvert/slab segment meshes, `InstancedMesh.count` for bamboo piles, and material opacity/visibility tweening.
- **Interactive Site Diary Dock**: Collapsible 4-panel bottom dock (`.site-diary-dock`) per `enterprise-ui-darkslate` standards (Bloomberg density, zero sidebar occlusion with `right: 390px`, dark slate palette), synchronized in real time ($< 0.2\text{ms}$) with the timeline.
- **Lifetime Video Export Engine**: HTML5 Canvas `captureStream(30)` and `MediaRecorder` API (`video/mp4;codecs=avc1` with fallback `video/webm;codecs=vp9`), buffer resolution $1920 \times 1080$ (Full HD 1080p), automated camera pan sweep along the 146.46m alignment, and direct instant blob download.
- **Backend & Delivery**: FastAPI static file mount at `/static`, Uvicorn with `--reload`.
- **Automated QA & Regression**: Pytest backend suite (461 tests, boundary enforcement gate) + Playwright browser automation verification (`tools/verification/test_ong_den_4d_bim_and_video_export.py`).

## Feature Inventory
| # | Feature | Description | Milestone | Source |
|---|---------|-------------|-----------|--------|
| F1 | Clearance & Culvert Cross-Section Dimensions | 2.5m x 2.5m clearance, 250mm wall/slab thickness, 3.0m x 3.0m outer envelope | M1 | ORIGINAL_REQUEST §R1 |
| F2 | Foundation & Larsen Shoring Dimensions | 3.4m foundation width, 200mm clearance from culvert edge to Larsen sheet pile | M1 | ORIGINAL_REQUEST §R1 |
| F3 | Strut Pitch & Bamboo Pile Density Callouts | Strut spacing $s = 6.0\text{m}$ (span 3.4m), bamboo pile density 25 piles/m² ($1.0\text{m} \times 0.45\text{m}$ grid) | M1 | ORIGINAL_REQUEST §R1 |
| F4 | Longitudinal Segments & V250 Joints | Segments 1 (50.0m), 2 (51.46m), 3 (45.0m) and 2 expansion joints V250 at $s=50.0\text{m}, 101.46\text{m}$ | M1 | ORIGINAL_REQUEST §R1 |
| F5 | 3D Dimension Layer Toggle | Checkbox `#chkDimensions` in sidebar layer list and quick toggle `#btnDims` in floating toolbar | M1 | ORIGINAL_REQUEST §R1 |
| F6 | Camera-Aligned Billboard Text Sprites | `THREE.Sprite` with 2D Canvas texture, 100% camera-facing without distortion, captured in WebGL stream | M1 | ORIGINAL_REQUEST §R1 |
| F7 | 4D BIM Player Controls | Play/Pause, speed multipliers 1x/2x/5x, Day 1 to 90 timeline slider, phase badges | M2 | ORIGINAL_REQUEST §R2 |
| F8 | 6-Phase Phasing Simulation | Sheet 04 sequence: Site Prep (1-10), Shoring (11-25), Excavation & Bamboo (26-45), Culvert Walls (46-70), Slabs & Manholes (71-82), Backfill & Pull Larsen (83-90) | M2 | ORIGINAL_REQUEST §R2 |
| F9 | Interactive Site Diary Dock | Collapsible 4-panel bottom dock (Date/Weather, Workforce/Machinery, 5D Volumes, Safety/Monitoring), Zero sidebar occlusion | M2 | ORIGINAL_REQUEST §R3 |
| F10 | Real-Time Timeline Synchronization | Timeline slider / playback instantaneously ($< 0.2\text{ms}$) updates Site Diary data from 90-day grounded dataset | M2 | ORIGINAL_REQUEST §R3 |
| F11 | Lifetime Video Export | HTML5 Canvas MediaRecorder API, HD 1080p ($1920\times1080$), camera pan sweep, WebM/MP4 download | M3 | ORIGINAL_REQUEST §R4 |
| F12 | Browser & Regression QA Gate | 0 console errors, stable > 30 FPS, Pytest boundary enforcement passing 100%, E2E test verification | M4 | ORIGINAL_REQUEST §Verification |

## Milestones
| # | Name | Scope | Dependencies | Status |
|---|------|-------|-------------|--------|
| M1 | 3D Dimensions & Billboard Annotations | F1, F2, F3, F4, F5, F6 | none | DONE |
| M2 | 4D BIM Simulation & Site Diary Dock | F7, F8, F9, F10 | M1 | DONE |
| M3 | Lifetime Video Export Engine | F11 | M2 | IN_PROGRESS |
| M4 | Final Integration & E2E Acceptance | F12 | M1, M2, M3 | PLANNED |

## Interface Contracts
### 3D Scene ↔ Dimension System (Milestone 1 - DONE)
- `groupDimensions`: `THREE.Group` containing all dimension lines and text sprites.
- `toggleLayer('dimensions', visible: boolean)`: Toggles visibility of `groupDimensions`.
- `addLinearDimension3D(pA: Vector3, pB: Vector3, extDir: Vector3, offset: number, label: string, options: object)`: Adds extension lines, dimension line, 45° ticks, and billboard sprite.
- `addAlignmentSegmentDimension(sStart: number, sEnd: number, yElev: number, label: string)`: Adds longitudinal polyline and label along centerline.

### 4D BIM Player ↔ 3D Scene Components (Milestone 2 - DONE)
- `setTimelineDay(day: number)`: Updates scene component visibility, opacity, and pile counts for given day ($1 \le \text{day} \le 90$).
- `play4D()`, `pause4D()`, `setSpeed(multiplier: number)`: Controls playback loop.
- `culvertSeg1`, `culvertSeg2`, `culvertSeg3`: Individual segment meshes for culvert bottom/walls and top slabs.
- `bambooInstanced.count`: Dynamically sets rendered pile count (up to 13,042 piles).

### 4D BIM Player ↔ Site Diary Dock (Milestone 2 - DONE)
- `SITE_DIARY_SCHEDULE_90_DAYS`: Array of 90 daily records grounded in HĐ-2026 contract.
- `renderSiteDiaryDock(day: number)`: Updates DOM panels for meteorological conditions, workforce, heavy machinery, cumulative volumes, and safety notes in $< 0.2\text{ms}$.
- `toggleDockCollapse()`: Expands / collapses bottom dock between 195px and 32px height.
- Zero Occlusion: Dock container CSS `left: 0; right: 390px; bottom: 0; z-index: 8;` strictly avoiding overlap with 390px sidebar.
- Mobile Safeguard: `Math.max(w, 1)` to prevent division by zero in camera aspect ratio.

### Video Export ↔ WebGL Canvas (Milestone 3 - TARGET)
- `startVideoExport()`: Sets buffer to $1920 \times 1080$, animates camera along 6 waypoints while advancing timeline Day 1 $\to$ 90, captures canvas stream via `MediaRecorder`, and triggers direct download.
- Button: `#btnExportVideo` with label `🎬 Quay Video Lifetime (1080p)`.

## Code Layout
- `app/static/bim/index.html`: WebGL 3D/4D BIM viewer, Three.js scene, UI overlays, player dock, site diary dock, video export.
- `app/api/middleware/security_middleware.py`: Security headers (CSP `media-src 'self' blob: data:;`).
- `tools/verification/test_ong_den_4d_bim_and_video_export.py`: Playwright automated verification suite.
- `tests/`: Pytest regression test suite (`test_architecture_boundary_enforcement.py`, `test_ong_den_drawing_and_hsmt_grounding.py`).
