ifc-commit/docs/wasm.md
2026-03-25 10:36:30 +01:00

162 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# IFC in the Browser: WASM Options
## Goal
Run `ifc-commit` logic (IFC extraction, modification, merge) client-side in a browser — no server, no Python install.
---
## Option 1 — IfcOpenShell via Pyodide (closest drop-in)
**Repo:** https://github.com/IfcOpenShell/wasm-wheels
**Wheel index:** https://ifcopenshell.github.io/wasm-wheels/
IfcOpenShell ships WASM as Pyodide wheels — Python packages compiled to `wasm32` via Emscripten. The full Python API runs inside a browser through the Pyodide runtime.
### Setup
```html
<script src="https://cdn.jsdelivr.net/pyodide/v0.27/full/pyodide.js"></script>
```
```javascript
const pyodide = await loadPyodide();
await pyodide.loadPackage("micropip");
await pyodide.runPythonAsync(`
import micropip
await micropip.install(
"https://ifcopenshell.github.io/wasm-wheels/"
"ifcopenshell-0.8.3+34a1bc6-cp313-cp313-emscripten_4_0_9_wasm32.whl"
)
`);
```
### Usage
```python
# Identical to desktop ifccommit.py
import ifcopenshell
import ifcpatch
model = ifcopenshell.open("input.ifc")
result = ifcpatch.execute({
"input": "input.ifc",
"file": model,
"recipe": "ExtractElements",
"arguments": [["IfcWall", "IfcSlab"]],
})
ifcpatch.write(result, "output.ifc")
```
### Available wheels (early 2026)
| Wheel | Python | Emscripten |
|-------|--------|------------|
| `ifcopenshell-0.8.3+34a1bc6-cp313-cp313-emscripten_4_0_9_wasm32.whl` | 3.13 | 4.0.9 |
| `ifcopenshell-0.8.2+d50e806-cp312-cp312-emscripten_3_1_58_wasm32.whl` | 3.12 | 3.1.58 |
### Pros / Cons
| + | - |
|---|---|
| Identical API to desktop — `ifcpatch` recipes work as-is | Requires loading Pyodide (~10 MB) + Python interpreter overhead |
| `ifcpatch`, `ifcclash`, `ifctester` all available | Not on PyPI; must install from CDN wheel URL |
| Zero code changes to `ifccommit.py` | Slower than native due to WASM + Python layers |
| Models stay in browser (no server upload) | Large initial download |
**Best fit:** A browser version that mirrors the CLI exactly — same `ExtractElements`, `PatchIfc` recipes, same Python logic.
---
## Option 2 — web-ifc (C++/JS, no Python)
**npm:** `web-ifc`
**Repo:** https://github.com/ThatOpen/engine_web-ifc (by That Open Company, formerly IFCjs)
C++ IFC parser compiled to WASM via Emscripten, with a TypeScript API. The dominant ecosystem for browser IFC tools.
```bash
npm install web-ifc
```
```javascript
import { IfcAPI } from "web-ifc";
const api = new IfcAPI();
await api.Init();
const bytes = new Uint8Array(await file.arrayBuffer());
const modelID = api.OpenModel(bytes);
const walls = api.GetLineIDsWithType(modelID, api.IFCWALL);
api.CloseModel(modelID);
```
### Pros / Cons
| + | - |
|---|---|
| Native JS/TS — no Python runtime | No `ifcpatch` recipe system |
| Smaller footprint than Pyodide | Lower-level API — more code to replicate `ifccommit` logic |
| Actively maintained, large ecosystem | No `ifcclash`, `ifctester`, `ifcdiff` equivalents |
| Runs in Web Workers (multi-threaded) | Write support is lower-level |
**Best fit:** A rewrite of `ifc-commit` as a TypeScript/JS app, or integration into a larger BIM web app (Three.js, React, etc.).
---
## Option 3 — ifc-lite (Rust/WASM + WebGPU)
**Repo:** https://github.com/louistrue/ifc-lite
**npm scope:** `@ifc-lite/*` (e.g. `@ifc-lite/parser`, `@ifc-lite/geometry`, `@ifc-lite/query`)
Rust-based IFC parser compiled to WASM via `wasm-bindgen`, with WebGPU rendering. Claims 5× faster geometry processing than alternatives. Supports IFC4, IFC4X3, and IFC5 (IFCX alpha).
```bash
npm install @ifc-lite/parser @ifc-lite/query
```
### Pros / Cons
| + | - |
|---|---|
| Fastest option (Rust + WebGPU) | Very new — alpha-stage API stability |
| Supports IFC5/IFCX | No `ifcpatch` equivalent |
| No Rust toolchain needed (pre-built WASM) | Requires rewriting all `ifc-commit` logic in TS |
**Best fit:** Performance-critical geometry/visualization use cases.
---
## Option 4 — IFCflow (inspiration, not a library)
**URL:** https://ifcflow.com
**Docs repo:** https://github.com/louistrue/IfcFlow-Docs
A browser-based visual node editor for IFC pipelines. Uses the IfcOpenShell WASM wheels (Pyodide) for on-device processing. Not a reusable library — a hosted web app — but demonstrates that the Pyodide approach works end-to-end for extract/filter/export workflows similar to `ifc-commit`.
---
## Recommended Path for ifc-commit
### Phase 1 — Pyodide prototype (zero code changes)
1. Create `web/index.html` with Pyodide bootstrapped.
2. On file drop/upload, pass the `ArrayBuffer` into Python as bytes.
3. Call `ifccommit.py` functions directly via `pyodide.runPythonAsync()`.
4. Offer the output `.ifc` as a download via a `Blob` URL.
This requires no changes to `ifccommit.py`.
### Phase 2 — web-ifc rewrite (optional, for performance)
If Pyodide startup time (~35 s) or bundle size is a problem, rewrite the core operations using `web-ifc` TypeScript API. This is a significant effort — `ifcpatch` recipes must be re-implemented.
---
## References
- IfcOpenShell WASM wheels: https://github.com/IfcOpenShell/wasm-wheels
- Wheel CDN: https://ifcopenshell.github.io/wasm-wheels/
- Pyodide: https://pyodide.org
- web-ifc: https://github.com/ThatOpen/engine_web-ifc
- ifc-lite: https://github.com/louistrue/ifc-lite
- IFCflow: https://ifcflow.com