feat: IFC → Pascal converter (package + app)

Brings the IFC-to-Pascal converter into the monorepo as a pure-logic
package plus a Next.js app, replacing the standalone repo that consumed
published @pascal-app/* packages (and drifted from their schemas).

packages/ifc-converter — pure conversion. Parses IFC via web-ifc and
maps elements onto @pascal-app/core node schemas (workspace-linked, so
no more version drift). Builds doors/windows, walls, slabs, columns,
roofs, stairs, sites/buildings/levels. Validates each node via the real
Zod schemas at build time (tryParse) and strips undefined metadata.

apps/ifc-converter — the UI: drop zone, example picker, element search,
JSON download, and a 3D preview rendered through the real
@pascal-app/viewer (registry bootstrap + read-only scene) with a custom
toolbar (camera/level/wall/grid/theme), level selector with
camera-focus, auto-fit, and selection bridged to an inspector.

Conversion specifics worth noting:
- Door/window vertical centering (height/2; windows + sill).
- Nearest-wall hosting fallback for files lacking IFCRELFILLSELEMENT,
  preferring walls long enough to contain the opening and clamping the
  along-wall position so cutouts can't overflow and break wall CSG.
- Plain IFCWALL (Brep/mapped geometry) falls back to default
  height/thickness instead of collapsing to zero-height slivers.
- Columns convert as plain structural shafts (no decorative
  base/capital) sized from the IFC profile.
- Beams + items are skipped for now (no Pascal beam type; items need a
  catalog asset) — counted in the conversion summary.

Large example IFCs are fetched from a public bucket at runtime; the four
small ones are committed. web-ifc.wasm is copied into public/ on
install/dev/build. README flags early-alpha + invites contributions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Wassim SAMAD
2026-05-21 10:45:12 -04:00
co-authored by Claude Opus 4.7
parent 8505d6cdfa
commit 0df51219d0
27 changed files with 150847 additions and 0 deletions
+44
View File
@@ -0,0 +1,44 @@
{
"name": "ifc-converter-app",
"version": "0.1.0",
"type": "module",
"private": true,
"scripts": {
"predev": "node scripts/copy-web-ifc-wasm.mjs",
"prebuild": "node scripts/copy-web-ifc-wasm.mjs",
"postinstall": "node scripts/copy-web-ifc-wasm.mjs",
"dev": "next dev --port 3003",
"build": "next build",
"start": "next start",
"lint": "biome lint",
"check-types": "next typegen && tsc --noEmit"
},
"dependencies": {
"@pascal-app/core": "*",
"@pascal-app/ifc-converter": "*",
"@pascal-app/nodes": "*",
"@pascal-app/viewer": "*",
"lucide-react": "^1.7.0",
"@react-three/drei": "^10.7.7",
"@react-three/fiber": "^9.5.0",
"@tailwindcss/postcss": "^4.2.1",
"clsx": "^2.1.1",
"next": "16.2.1",
"postcss": "^8.5.6",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"tailwind-merge": "^3.5.0",
"tailwindcss": "^4.2.1",
"three": "^0.184.0",
"web-ifc": "^0.0.77",
"zod": "^4.3.5"
},
"devDependencies": {
"@pascal/typescript-config": "*",
"@types/node": "^22.19.12",
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.3",
"@types/three": "^0.184.0",
"typescript": "6.0.2"
}
}