# OVEN — measured model and construction phases

Standalone, no-build Three.js **0.169.0**, with matching pinned addons. All implementation files stay inside `output/3d/`; the parent page is untouched. One unit is one centimetre: `P(x,y,z) = (x,z,−y)`. Existing datum z 0 = peil 0.47 m; the new finished floor is **z −4 = peil 0.43 m**.

## Verification

Use the coordinator’s existing server for `/3d/index.html` and `/3d/tools/browser-check.html`. No server or browser was started during this implementation.

Run every check from this directory:

```sh
node tools/sync-data.mjs
node tools/sync-phases.mjs
node tools/verify-geometry.mjs
node tools/verify-round2.mjs
node tools/verify-round3.mjs
node tools/verify-round4.mjs
node tools/verify-round5.mjs
node tools/verify-review.mjs
node tools/verify-phases.mjs
node tools/check-modules.mjs
node tools/check-glsl.mjs
```

**233 check groups pass:** 52 geometry + 10/37/38/26 earlier rounds + 26 independent review + 44 phases. **55 modules, 218 imports, 48 pinned r169 symbols and 182 GLSL declarations** pass static audits. Logs are in `checks/*.txt`; findings are in [checks/review.md](checks/review.md), with current status in [checks/status.md](checks/status.md).

The coordinator verified the preceding revision in Chromium: 302 High Iso calls, zero console warnings/errors and failed programs (152 total), 5.4 s ready, unchanged measured bounds, and Cutaway flicker reduced to 18 near / 0 other supplied poses. Those results precede the phase feature. **This revision still requires Chromium validation** of appearance, flicker, colour guards, runtime controls, console/shaders and High ≤400 / Low ≤250 full-frame draw calls. Static GLSL checks are not GPU compilation.

## Fasen

`../../analyse/phases.json` is the canonical source. `tools/sync-phases.mjs` copies its bytes to `data/phases.json` and its verbatim payload to `js/phases-data.js`. All three are checked. The final copied file is **3,963 bytes**, SHA-256 `5e8fe5947597a633a3f367527db1ff547b4e26f3a35e27c35a3af9a28df2af50`.

| Phase | Cumulative state |
|---|---|
| 0 Huidig | Default: excavated earth around −35 ±8, rubble, oven/flue, existing joists and boards |
| 1 Bakoven weg | Entire oven/base/flue/collar/flashing/cap removed; four complete replacement tiles close the penetration |
| 2 Uitgraven | Flat earth at −43, earth cut sides, existing walls to −55 and footings −85…−55 |
| 3 Beton | 15 cm, −43…−28 |
| 4 PUR | 14 cm, −28…−14, yellow sprayed texture |
| 5 Chape | 8 cm, −14…−6 |
| 6 Parket | 2 cm, −6…−4; jointed oak stops 10 cm short of masonry, leaving the future stud zone visible |
| 7 Muurisolatie | 4.5 ×10 studs at 60 cm c/c, 10 cm wool, −6…238; framed D1/W1/G1 and boxed pilaster/header returns |
| 8 Dakisolatie | Assumed 19 cm wool between rafters, including end bays; foil hint; only boards hide by default |
| 9 Gyproc | 1.25 cm at 10…11.25 cm inward, −4…238; finished reveals; roof insulation remains exposed |

The client floor replaces the architect’s proposed −25…−10 slab. That historical source helper remains for auditing, but is no longer rendered. Parket and floor layers are cut around the source pilasters. Studs stand on chape; gyproc stands at the parquet edge. Roof wool is trimmed at wall-plate joints; wall/roof contact faces have one owner. Existing **joists remain in every phase** unless the user hides them or a section removes them. Board removal from phase 8 is an explicit assumption; `Boards over joists` can restore them. No roof finish has been specified.

Fasen includes previous/next, slider, ten chips, remembered current/final comparison, layer labels/legend and Doorsnede-on-change. A phase change normally animates to the low three-quarter x360 section; selecting a normal viewpoint restores that viewpoint. Section A takes precedence at x235 when enabled. Cutaway z200 can combine with either. Caps slice 0.1 cm inside the retained solid and use each layer’s colour. Per-material batches and per-plane caps are cached. X-ray leaves the phase construction opaque.

The exact final envelope is **554.5002868 cm rear width / 569.0504781 front width**, and **389.8790877 cm street depth / 399.2840014 garage depth**. Clear height from finished floor is **219 cm to joists / 368 cm to the ridge-piece underside**. Net floor area after boxed pilaster returns is 22.0246157 m². Four new phase dimensions supplement all sixteen earlier dimensions. The section depth dimension measures its actual section x coordinate, so its value varies along the skewed room.

## API and embedding

```js
await oven.ready;
await oven.setPhase(6);                         // integer 0…9
oven.state.phase;
oven.phaseMetrics();
await oven.comparePhases();                     // current ↔ final; second call restores prior phase
oven.configurePhases({section: false, labels: true});
await oven.setView('Interior', {photo: 'IMG_0159'}); // also IMG_0160 / IMG_0161
await oven.setView('Front', {ortho: true, instant: true});
oven.set('boards', true);                       // explicit preference persists across phases
oven.set('earthFloor', true);                   // compatibility alias → phase 0
oven.set('earthFloor', false);                  // compatibility alias → phase 6
oven.set('xray', true);
oven.set('cutaway', true);                      // z ≤200
oven.set('section', true);                      // x ≤235
await oven.setQuality('low');
oven.setSun({hour: 10, date: '2026-06-21'});
oven.measure();
oven.stats();
oven.programs();
oven.debug.flickerProbe();
await oven.debug.colorProbe('rearRoof');
```

`#fase=N` initializes the model and updates via `history.replaceState`. Embedded instances send `{type:'bakoven:ready'}` once after the first frame. They accept `{type:'bakoven:phase',phase:N}` only from their parent, for integer N 0–9. UI/API phase changes emit that message to the parent; received messages do not echo. Standalone instances emit neither. No parent-file changes are required here.

All seven presets remain: Front, Rear, Side street, Side garage, Top, Iso, Interior. Layer keys are `roof`, `xray`, `cutaway`, `section`, `joists`, `earthFloor`, `garage`, `dims`, plus `boards`. The former earth-floor control remains visibly inside Fasen and selects phases rather than an independent floor. `roof:false` means Hide roof. Orthographic, quality, hour and season controls remain; orthographic preserves an active phase section. `oven.controlsInventory` exposes the inventories.

The existing `THREE`, `scene`, `renderer`, `controls`, `data`, `camera`, `views`, `ready`, `measure`, `stats`, `programs` and debug API remain. `ready` resolves after a successful frame and sets `body.dataset.ready="true"`.

## Interior and rendering

Three photo buttons use the supplied approximate camera positions. Current/removal-phase Interior views show the absent/open D1 leaf like the photos and enable its opening-sized fill; later closed-door states have no D1 emitter. Existing W1/G1 and fluorescent lights remain, with High area lights / Low soft spots. Uniform Interior fill is reduced to 0.18 hemisphere / 0.14 environment; the 2.3× exposure is retained. This is a lighting approximation requiring visual comparison, not measured illumination.

Block coursing, exposed lower brick and rubble are retained. Plaster now has an irregular damp/peeling band around 30–40 cm, broad grey/ochre ageing and less regular timber grain. Exterior thin-wash patches are rare and muted, with soft sill/gutter runoff. D1 keeps solid 2 cm-proud ledges/braces and V-jointed board geometry; W1 gains inside beads while preserving surveyed frame bounds/reveals. Garage context glazing is lighter and mildly reflective.

| Setting | High | Low |
|---|---|---|
| Pipeline | 4× MSAA → half-resolution GTAO → OutputPass | Direct antialiased renderer |
| Pixel ratio | ≤1.5, adaptive down to 1 | ≤1.5 |
| Shadows | 4096 | 1024 |
| Masonry maps | 2048 | 1024 |
| Foliage / rubble | Full | 42% / 35% of allocated instances |
| Pavers | Individual pieces | Continuous same-slope surface |
| Draw budget | ≤400 | ≤250 |

ACES and sRGB remain applied once. All texture maps use mipmaps, trilinear filtering and maximum anisotropy. Positive tile instance transforms, the existing arch/cap fixes, irregular garden material and exact quality restoration remain. Stats include all passes; the harness refreshes shadows for budget measurements. Triangle counts may vary with camera/frustum/pass work; instance allocations do not depend on viewport size.

## Architecture and limitations

- `phase-state.js`: pure validation, hash, compare and message guards.
- `phase-model.js`: canonical levels, exact inward offsets, frames, wall/roof build-up and metrics.
- `phase-solids.js` / `phase-surfaces.js`: actual render volumes and contact-face ownership, shared with numeric tests.
- `clipping-data.js`, `section-data.js`, `section.js`: shared cut policy, parameterized masonry caps and cached solid contours.
- `phase-geometry.js`, `phase-ui.js`, `phase-labels.js`: batched rendering, controls and collision-aware label column.
- `tile-data.js`: complete roof patch data used by both rendering and semantic checks.
- `model-data.js` / `assumptions.js`: measured source calculations and declared visual/construction assumptions.

The inherited gable-clearance interpretation still lowers the traced masonry outline by 6.632 / 7.586 / 7.874 cm. It is documented in review finding 12; it was not changed during the phase work. Measured roof/ridge/gutter/flue and opening bounds remain guarded. Timber dimensions/spacing, material appearance, services, plank layout, local boxing and footing longitudinal ends contain declared assumptions. Exact footing cross-sections come from `dimensions.json` (phases.json does not duplicate them).

The Chromium harness retains all previous mode/quality/colour checks and adds actual cap-coordinate checks, ten phases with every X-ray/Cutaway/Section/Hide-roof mask on both qualities, photo cameras, compare/hash and parent-message guards. The coordinator should additionally inspect phase 6/9 temporal flicker, photo realism, all labels and controls at 390 px. No new browser screenshot or performance/colour measurement is claimed.
