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:
co-authored by
Claude Opus 4.7
parent
8505d6cdfa
commit
0df51219d0
@@ -0,0 +1,24 @@
|
||||
import { type AnyNodeDefinition, nodeRegistry, registerNode } from '@pascal-app/core'
|
||||
import { builtinPlugin } from '@pascal-app/nodes'
|
||||
|
||||
// Mirrors apps/editor/lib/bootstrap.ts — registers every built-in node
|
||||
// kind synchronously so the registry is populated before the first
|
||||
// `<Viewer>` mounts. Without this every NodeRenderer resolves to null
|
||||
// and the preview is empty. HMR-safe via the closure-scoped flag.
|
||||
let builtinsLoaded = false
|
||||
|
||||
export function loadBuiltins(): void {
|
||||
if (builtinsLoaded) return
|
||||
builtinsLoaded = true
|
||||
for (const def of builtinPlugin.nodes ?? []) {
|
||||
registerNode(def as AnyNodeDefinition)
|
||||
}
|
||||
if (typeof console !== 'undefined') {
|
||||
const kinds = Array.from(nodeRegistry.entries(), ([k]) => k)
|
||||
console.info(
|
||||
`[pascal:registry] loaded ${builtinPlugin.id} v${builtinPlugin.apiVersion} (${kinds.length} kinds)`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
loadBuiltins()
|
||||
Reference in New Issue
Block a user