
Thatopen Syntax Ifc Loading
- 5 installs
- 17 repo stars
- Updated July 8, 2026
- openaec-foundation/thatopen-claude-skill-package
Helps with ai & agent building tasks.
About
thatopen-syntax-ifc-loading is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- thatopen-syntax-ifc-loading
- AI & Agent Building
- AI-coding skill
Thatopen Syntax Ifc Loading by the numbers
- 5 all-time installs (skills.sh)
- Ranked #13,046 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Jul 21, 2026 (Skillselion catalog sync)
npx skills add https://github.com/openaec-foundation/thatopen-claude-skill-package --skill thatopen-syntax-ifc-loadingAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 5 |
|---|---|
| repo stars | ★ 17 |
| Last updated | July 8, 2026 |
| Repository | openaec-foundation/thatopen-claude-skill-package ↗ |
What it does
Helps with ai & agent building tasks.
Files
IFC Loading: IfcLoader & IfcImporter
Overview
IFC loading in ThatOpen converts IFC files into the internal Fragments binary format for high-performance 3D rendering. There are two approaches:
1. IfcLoader (high-level, @thatopen/components) — The standard component for loading IFC files in a ThatOpen application. Wraps web-ifc and handles WASM setup, conversion to fragments, and scene integration. 2. IfcImporter (low-level, @thatopen/fragments) — Direct fragment conversion without the component framework. Useful for server-side processing, Web Workers, or custom pipelines.
The time-consuming part is the IFC-to-Fragments conversion, not the actual fragment loading. ALWAYS convert once and store the Fragments binary for fast reloading.
---
Critical Rules
1. ALWAYS call `setup()` before `load()` — IfcLoader implements Configurable. Calling load() before setup() causes WASM initialization failures. 2. ALWAYS match WASM path version to installed web-ifc version — A version mismatch between the WASM files and the web-ifc npm package causes silent parsing failures or crashes. 3. NEVER hardcode a web-ifc version in the WASM path without checking package.json — the installed version may differ. 4. ALWAYS initialize FragmentsManager before loading IFC — Call fragmentsManager.init(workerURL) before any IFC loading to enable fragment processing. 5. ALWAYS pass IFC data as `Uint8Array` — The load() method does not accept ArrayBuffer, string, or File objects directly. 6. NEVER skip disposal — Call components.dispose() on teardown. IfcLoader holds a webIfc: IfcAPI instance that allocates WASM heap memory.
---
IfcLoader Component
Setup
import * as OBC from "@thatopen/components";
const components = new OBC.Components();
// Create world (scene, camera, renderer)
const worlds = components.get(OBC.Worlds);
const world = worlds.create();
world.scene = new OBC.SimpleScene(components);
world.renderer = new OBC.SimpleRenderer(components, container);
world.camera = new OBC.OrthoPerspectiveCamera(components);
// Initialize FragmentsManager with worker
const fragmentsManager = components.get(OBC.FragmentsManager);
fragmentsManager.init(workerURL);
// Get and configure IfcLoader
const ifcLoader = components.get(OBC.IfcLoader);
await ifcLoader.setup(); // uses autoSetWasm (default: true)WASM Configuration
Two approaches for WASM path configuration:
Automatic (default):
await ifcLoader.setup(); // autoSetWasm: true (default)
// Automatically resolves WASM path from the web-ifc packageManual (CDN or custom path):
await ifcLoader.setup({
autoSetWasm: false,
wasm: {
path: "https://unpkg.com/web-ifc@0.0.77/",
absolute: true,
},
});Manual (local files):
await ifcLoader.setup({
autoSetWasm: false,
wasm: {
path: "/static/wasm/",
absolute: false,
},
});When using a local path, the directory MUST contain web-ifc.wasm (and web-ifc-mt.wasm for multi-threaded mode). Copy these from node_modules/web-ifc/.
Loading IFC Files
// Fetch IFC file as ArrayBuffer, convert to Uint8Array
const response = await fetch("/models/building.ifc");
const buffer = await response.arrayBuffer();
const data = new Uint8Array(buffer);
// Load into the viewer
const model = await ifcLoader.load(data, true, "MyBuilding");
// Add to scene
world.scene.three.add(model.object);load() Parameters
| Parameter | Type | Description |
|---|---|---|
data | Uint8Array | IFC file contents as byte array |
coordinate | boolean | Apply coordination matrix to align with other models |
name | string | Display name for the model |
config | object (optional) | Advanced options: instanceCallback, processData, userData |
- Set
coordinate: truewhen loading multiple models that must align spatially. - Set
coordinate: falsefor single-model scenarios or when manual positioning is needed.
readIfcFile(): Low-Level Access
const modelID = await ifcLoader.readIfcFile(data);
// Now access raw web-ifc API:
const line = ifcLoader.webIfc.GetLine(modelID, expressID);
ifcLoader.cleanUp(); // ALWAYS clean up after raw accessUse readIfcFile() when you need raw web-ifc queries without full fragment conversion.
---
IfcFragmentSettings
The settings property on IfcLoader controls loading behavior.
| Property | Type | Default | Description |
|---|---|---|---|
autoSetWasm | boolean | true | Auto-resolve WASM path from web-ifc package |
wasm.path | string | — | Directory containing WASM files |
wasm.absolute | boolean | — | Whether path is an absolute URL |
wasm.logLevel | LogLevel | — | web-ifc logging verbosity |
webIfc | LoaderSettings | — | web-ifc LoaderSettings passed to OpenModel() |
customLocateFileHandler | `LocateFileHandlerFn \ | null` | null |
web-ifc LoaderSettings (via settings.webIfc)
| Setting | Type | Default | Description |
|---|---|---|---|
COORDINATE_TO_ORIGIN | boolean | false | Translate model geometry to origin |
USE_FAST_BOOLS | boolean | false | Faster but less accurate boolean operations |
CIRCLE_SEGMENTS_LOW | number | — | Tessellation for small curves |
CIRCLE_SEGMENTS_MEDIUM | number | — | Tessellation for medium curves |
CIRCLE_SEGMENTS_HIGH | number | — | Tessellation for large curves |
BOOL_ABORT_THRESHOLD | number | — | Timeout (ms) for boolean operations |
MEMORY_LIMIT | number | — | WASM memory limit in bytes |
Use COORDINATE_TO_ORIGIN: true for models with large real-world coordinates to prevent floating-point precision issues.
Configuring Settings After Setup
await ifcLoader.setup();
// Modify web-ifc settings before loading
ifcLoader.settings.webIfc.COORDINATE_TO_ORIGIN = true;
ifcLoader.settings.webIfc.USE_FAST_BOOLS = true;---
Events
| Event | Type | When |
|---|---|---|
onSetup | Event<void> | After setup() completes |
onIfcStartedLoading | Event<void> | When IFC file parsing begins |
onIfcImporterInitialized | Event<IfcImporter> | When the internal IfcImporter is created |
onDisposed | Event<string> | When the component is disposed |
Customizing Default Imports
Use onIfcImporterInitialized to modify which IFC entity types are converted:
ifcLoader.onIfcImporterInitialized.add((importer) => {
// Add a category that is not imported by default
importer.classes.elements.add(WEBIFC.IFCSPACE);
// Remove a category to save memory
importer.classes.elements.delete(WEBIFC.IFCFURNISHINGELEMENT);
});By default, IfcLoader imports common building elements (walls, slabs, beams, columns, doors, windows, roofs, stairs, etc.) but excludes some categories like IFCSPACE and IFCOPENINGELEMENT for performance. Use this event to customize the import set.
---
IfcImporter (Low-Level, @thatopen/fragments)
IfcImporter operates at the fragments level without requiring the component framework. Use it for server-side conversion, Web Worker pipelines, or when you need fine-grained control.
import { IfcImporter } from "@thatopen/fragments";
const importer = new IfcImporter();
// Configure WASM
importer.wasm.path = "https://unpkg.com/web-ifc@0.0.77/";
importer.wasm.absolute = true;
// Process IFC file → Fragments binary
const fragmentsData = await importer.process(ifcData); // Uint8Array in, Uint8Array outIfcImporter Properties
| Property | Type | Default | Description |
|---|---|---|---|
wasm | { path, absolute } | — | WASM configuration |
classes.elements | Set<number> | common building types | Physical IFC elements to import |
classes.abstract | Set<number> | materials, properties | Abstract types (properties, materials, classifications) |
relations | Map<number, object> | key relations | Entity relationship mappings |
distanceThreshold | `number \ | null` | 100000 |
includeRelationNames | boolean | false | Include relation names in output |
includeUniqueAttributes | boolean | false | Include unique attributes in output |
replaceSiteElevation | boolean | true | Replace site elevation with absolute meters |
replaceStoreyElevation | boolean | true | Replace storey elevation with absolute meters |
attributesToExclude | Set<string> | — | Attributes filtered from serialization |
IfcImporter Methods
| Method | Description |
|---|---|
process(data: Uint8Array) | Convert IFC to Fragments binary (Uint8Array) |
addAllAttributes() | Include all IFC attributes (increases output size) |
addAllRelations() | Include all IFC relations (increases output size) |
---
Fragment Conversion Workflow
The recommended production pattern: convert once, store fragments, reload fast.
// Step 1: Convert IFC → FragmentsModel (slow, one-time)
const model = await ifcLoader.load(data, true, "Building");
world.scene.three.add(model.object);
// Step 2: Export to Fragments binary (fast serialization)
const fragmentsData = model.export(); // Uint8Array
// Step 3: Store the binary (IndexedDB, server, file system)
await saveToStorage("building.frg", fragmentsData);
// Step 4: Reload from Fragments binary (fast, skips IFC parsing)
const stored = await loadFromStorage("building.frg");
const reloaded = fragmentsManager.load(stored);
world.scene.three.add(reloaded.object);This workflow avoids re-parsing IFC on every page load. The Fragments binary format loads orders of magnitude faster than IFC conversion.
---
Relationship to Other Skills
| Skill | Relationship |
|---|---|
thatopen-core-web-ifc | Low-level WASM engine beneath IfcLoader. Use when you need raw IfcAPI access. |
thatopen-core-architecture | Component framework that IfcLoader plugs into (components.get()). |
thatopen-core-fragments | Fragment system that stores and renders loaded models. |
thatopen-syntax-properties | Querying IFC properties after loading. |
thatopen-syntax-streaming | Streaming large IFC files (alternative to full load()). |
---
References
references/methods.md— Complete IfcLoader and IfcImporter API signaturesreferences/examples.md— Working examples: basic load, CDN WASM, IfcImporter, fragment workflowreferences/anti-patterns.md— Common failures: WASM misconfig, version mismatch, missing setup
Sources
- API docs: https://docs.thatopen.com/api/@thatopen/components/classes/IfcLoader
- Tutorial: https://docs.thatopen.com/Tutorials/Components/Core/IfcLoader
- GitHub: https://github.com/ThatOpen/engine_components
- IfcImporter: https://docs.thatopen.com/api/@thatopen/fragments/classes/IfcImporter
IfcLoader — Anti-Patterns & Common Failures
AP-1: Calling load() Before setup()
Symptom: WASM initialization error, Cannot read properties of undefined, or silent failure returning no model.
Wrong:
const ifcLoader = components.get(OBC.IfcLoader);
// MISSING: await ifcLoader.setup();
const model = await ifcLoader.load(data, true, "Building"); // FAILSCorrect:
const ifcLoader = components.get(OBC.IfcLoader);
await ifcLoader.setup(); // ALWAYS call setup() first
const model = await ifcLoader.load(data, true, "Building");Rule: ALWAYS call setup() and await it before calling load(). IfcLoader implements Configurable — WASM initialization happens in setup(), not in the constructor.
---
AP-2: WASM Version Mismatch
Symptom: RuntimeError: unreachable, CompileError, garbled geometry, or silent parsing failures.
Wrong:
await ifcLoader.setup({
autoSetWasm: false,
wasm: {
path: "https://unpkg.com/web-ifc@0.0.74/", // WRONG: installed version is 0.0.77
absolute: true,
},
});Correct:
// Option A: Let autoSetWasm handle it
await ifcLoader.setup(); // autoSetWasm: true (default)
// Option B: Match the installed version explicitly
await ifcLoader.setup({
autoSetWasm: false,
wasm: {
path: "https://unpkg.com/web-ifc@0.0.77/", // matches package.json
absolute: true,
},
});Rule: NEVER hardcode a web-ifc version in the WASM path without verifying it matches the installed web-ifc npm package version. The WASM binary and the JavaScript API must be from the same version.
---
AP-3: Missing FragmentsManager Initialization
Symptom: FragmentsManager not initialized, model loads but does not appear, or worker errors.
Wrong:
const ifcLoader = components.get(OBC.IfcLoader);
await ifcLoader.setup();
// MISSING: fragmentsManager.init(workerURL)
const model = await ifcLoader.load(data, true, "Building");Correct:
const fragmentsManager = components.get(OBC.FragmentsManager);
fragmentsManager.init(workerURL); // ALWAYS init before loading
const ifcLoader = components.get(OBC.IfcLoader);
await ifcLoader.setup();
const model = await ifcLoader.load(data, true, "Building");Rule: ALWAYS initialize FragmentsManager with a worker URL before any IFC loading. The fragment system requires a Web Worker for processing.
---
AP-4: Passing Wrong Data Type to load()
Symptom: TypeError, empty model, or Invalid IFC file error.
Wrong:
// Passing ArrayBuffer directly
const buffer = await response.arrayBuffer();
const model = await ifcLoader.load(buffer, true, "Building"); // FAILS
// Passing a string
const text = await response.text();
const model = await ifcLoader.load(text, true, "Building"); // FAILS
// Passing a File object
const model = await ifcLoader.load(file, true, "Building"); // FAILSCorrect:
const buffer = await response.arrayBuffer();
const data = new Uint8Array(buffer); // Convert to Uint8Array
const model = await ifcLoader.load(data, true, "Building");Rule: ALWAYS pass IFC data as Uint8Array. Convert ArrayBuffer with new Uint8Array(buffer). For File objects, use new Uint8Array(await file.arrayBuffer()).
---
AP-5: Not Adding Model to Scene
Symptom: Model loads successfully (no errors) but nothing appears in the viewer.
Wrong:
const model = await ifcLoader.load(data, true, "Building");
// MISSING: add to sceneCorrect:
const model = await ifcLoader.load(data, true, "Building");
world.scene.three.add(model.object); // ALWAYS add model.object to sceneRule: ALWAYS add model.object to the Three.js scene after loading. The load() method creates the model but does not automatically add it to any scene.
---
AP-6: Forgetting cleanUp() After readIfcFile()
Symptom: Memory leak, subsequent loads fail, or stale data from previous model.
Wrong:
const modelID = await ifcLoader.readIfcFile(data);
const walls = ifcLoader.webIfc.GetLineIDsWithType(modelID, WEBIFC.IFCWALL);
// MISSING: ifcLoader.cleanUp()Correct:
const modelID = await ifcLoader.readIfcFile(data);
const walls = ifcLoader.webIfc.GetLineIDsWithType(modelID, WEBIFC.IFCWALL);
ifcLoader.cleanUp(); // ALWAYS clean up after raw accessRule: ALWAYS call cleanUp() after using readIfcFile(). The load() method calls cleanUp() automatically, but readIfcFile() does not.
---
AP-7: Hardcoding WASM Path Without Trailing Slash
Symptom: 404 errors loading WASM files, web-ifc.wasm not found.
Wrong:
await ifcLoader.setup({
autoSetWasm: false,
wasm: {
path: "https://unpkg.com/web-ifc@0.0.77", // MISSING trailing slash
absolute: true,
},
});Correct:
await ifcLoader.setup({
autoSetWasm: false,
wasm: {
path: "https://unpkg.com/web-ifc@0.0.77/", // trailing slash required
absolute: true,
},
});Rule: ALWAYS include a trailing slash in WASM path strings. The path is used as a directory prefix — web-ifc.wasm is appended to it.
---
AP-8: Re-Parsing IFC on Every Page Load
Symptom: Slow startup, unnecessary CPU usage, poor user experience.
Wrong:
// Every page load re-parses the IFC file
const data = new Uint8Array(await fetch("/model.ifc").then(r => r.arrayBuffer()));
const model = await ifcLoader.load(data, true, "Building"); // slow every timeCorrect:
// Convert once, cache as fragments
const cached = await loadFromCache("building.frg");
if (cached) {
const model = fragmentsManager.load(cached); // fast reload
world.scene.three.add(model.object);
} else {
const data = new Uint8Array(await fetch("/model.ifc").then(r => r.arrayBuffer()));
const model = await ifcLoader.load(data, true, "Building");
world.scene.three.add(model.object);
await saveToCache("building.frg", model.export());
}Rule: ALWAYS convert IFC to Fragments binary once and cache the result. Fragment loading is orders of magnitude faster than IFC parsing.
---
AP-9: Missing components.init() Call
Symptom: Model loads and is added to scene, but nothing renders. Viewer shows black or empty.
Wrong:
const components = new OBC.Components();
// ... world setup, loader setup ...
const model = await ifcLoader.load(data, true, "Building");
world.scene.three.add(model.object);
// MISSING: components.init()Correct:
const components = new OBC.Components();
// ... world setup, loader setup ...
components.init(); // starts the render loop
const model = await ifcLoader.load(data, true, "Building");
world.scene.three.add(model.object);Rule: ALWAYS call components.init() to start the requestAnimationFrame render loop. Without it, the scene never draws.
---
AP-10: Using Deprecated Packages
Symptom: Import errors, missing APIs, incompatible types.
Wrong:
import { IfcViewerAPI } from "web-ifc-viewer"; // DEPRECATED
import { IFCLoader } from "web-ifc-three"; // DEPRECATEDCorrect:
import * as OBC from "@thatopen/components"; // current
import { IfcImporter } from "@thatopen/fragments"; // current (low-level)Rule: NEVER use web-ifc-viewer or web-ifc-three packages. They are deprecated and incompatible with ThatOpen v3. Use @thatopen/components (IfcLoader) or @thatopen/fragments (IfcImporter).
IfcLoader & IfcImporter — Working Examples
Example 1: Basic IFC Loading
The minimal setup for loading an IFC file into a ThatOpen viewer.
import * as OBC from "@thatopen/components";
// 1. Create component framework
const components = new OBC.Components();
// 2. Create world with scene, camera, renderer
const worlds = components.get(OBC.Worlds);
const world = worlds.create();
world.scene = new OBC.SimpleScene(components);
world.renderer = new OBC.SimpleRenderer(components, container);
world.camera = new OBC.OrthoPerspectiveCamera(components);
// 3. Initialize FragmentsManager
const fragmentsManager = components.get(OBC.FragmentsManager);
fragmentsManager.init(workerURL);
// 4. Setup IfcLoader (autoSetWasm is true by default)
const ifcLoader = components.get(OBC.IfcLoader);
await ifcLoader.setup();
// 5. Start rendering
components.init();
// 6. Load IFC file
const response = await fetch("/models/building.ifc");
const buffer = await response.arrayBuffer();
const data = new Uint8Array(buffer);
const model = await ifcLoader.load(data, true, "Building");
world.scene.three.add(model.object);
// 7. Frame camera to fit model
world.camera.fit([model.object]);---
Example 2: Custom WASM Path (CDN)
When autoSetWasm does not work (e.g., bundler issues) or you want explicit control.
const ifcLoader = components.get(OBC.IfcLoader);
await ifcLoader.setup({
autoSetWasm: false,
wasm: {
path: "https://unpkg.com/web-ifc@0.0.77/",
absolute: true,
},
});NEVER hardcode the version without checking package.json. To stay in sync:
// Read version from package.json or define as a constant
import { version as webIfcVersion } from "web-ifc/package.json";
await ifcLoader.setup({
autoSetWasm: false,
wasm: {
path: `https://unpkg.com/web-ifc@${webIfcVersion}/`,
absolute: true,
},
});---
Example 3: Custom WASM Path (Local Files)
For offline/air-gapped deployments, serve WASM files from your own static directory.
// Copy from node_modules/web-ifc/:
// web-ifc.wasm
// web-ifc-mt.wasm (for multi-threaded mode)
// to your public/static/wasm/ directory
await ifcLoader.setup({
autoSetWasm: false,
wasm: {
path: "/static/wasm/",
absolute: false,
},
});---
Example 4: Configuring web-ifc LoaderSettings
Apply web-ifc settings for coordinate origin translation and faster boolean operations.
const ifcLoader = components.get(OBC.IfcLoader);
await ifcLoader.setup();
// Configure before calling load()
ifcLoader.settings.webIfc.COORDINATE_TO_ORIGIN = true;
ifcLoader.settings.webIfc.USE_FAST_BOOLS = true;
const model = await ifcLoader.load(data, true, "GeoModel");---
Example 5: Customizing Imported IFC Classes
Control which IFC entity types are converted to fragments.
import * as WEBIFC from "web-ifc";
const ifcLoader = components.get(OBC.IfcLoader);
await ifcLoader.setup();
// Modify classes when the importer initializes
ifcLoader.onIfcImporterInitialized.add((importer) => {
// Add spaces (excluded by default)
importer.classes.elements.add(WEBIFC.IFCSPACE);
// Add openings (excluded by default)
importer.classes.elements.add(WEBIFC.IFCOPENINGELEMENT);
// Remove furniture to save memory
importer.classes.elements.delete(WEBIFC.IFCFURNISHINGELEMENT);
// Skip items far from origin (georeferenced models)
importer.distanceThreshold = 50000;
});
const model = await ifcLoader.load(data, true, "CustomImport");---
Example 6: IfcImporter (Low-Level, Without Components)
Use IfcImporter directly for server-side or Web Worker IFC conversion.
import { IfcImporter } from "@thatopen/fragments";
const importer = new IfcImporter();
// Configure WASM (required)
importer.wasm.path = "https://unpkg.com/web-ifc@0.0.77/";
importer.wasm.absolute = true;
// Optional: customize what gets imported
importer.classes.elements.add(WEBIFC.IFCSPACE);
importer.distanceThreshold = null; // no distance filtering
// Convert IFC → Fragments binary
const ifcData = new Uint8Array(await fetch("/model.ifc").then(r => r.arrayBuffer()));
const fragmentsData = await importer.process(ifcData);
// Store fragmentsData (Uint8Array) for later loading via FragmentsManager
await saveToIndexedDB("model.frg", fragmentsData);---
Example 7: Convert Once, Reload Fast (Fragment Caching)
The recommended production workflow to avoid re-parsing IFC on every page load.
const fragmentsManager = components.get(OBC.FragmentsManager);
const ifcLoader = components.get(OBC.IfcLoader);
await ifcLoader.setup();
async function loadModel(ifcUrl: string, cacheKey: string) {
// Try loading cached fragments first
const cached = await loadFromIndexedDB(cacheKey);
if (cached) {
const model = fragmentsManager.load(cached);
world.scene.three.add(model.object);
return model;
}
// No cache: convert IFC → Fragments
const response = await fetch(ifcUrl);
const data = new Uint8Array(await response.arrayBuffer());
const model = await ifcLoader.load(data, true, cacheKey);
world.scene.three.add(model.object);
// Cache the fragments binary for next time
const fragmentsData = model.export();
await saveToIndexedDB(cacheKey, fragmentsData);
return model;
}---
Example 8: Loading Multiple Models with Coordination
Load multiple IFC files that align spatially using the coordination matrix.
const ifcLoader = components.get(OBC.IfcLoader);
await ifcLoader.setup();
const files = [
{ url: "/models/architecture.ifc", name: "Architecture" },
{ url: "/models/structure.ifc", name: "Structure" },
{ url: "/models/mep.ifc", name: "MEP" },
];
for (const file of files) {
const response = await fetch(file.url);
const data = new Uint8Array(await response.arrayBuffer());
// coordinate: true ensures all models align to the same origin
const model = await ifcLoader.load(data, true, file.name);
world.scene.three.add(model.object);
}---
Example 9: Using readIfcFile for Raw Access
When you need web-ifc queries without full fragment conversion.
const ifcLoader = components.get(OBC.IfcLoader);
await ifcLoader.setup();
const data = new Uint8Array(await fetch("/model.ifc").then(r => r.arrayBuffer()));
const modelID = await ifcLoader.readIfcFile(data);
// Direct web-ifc access
const schema = ifcLoader.webIfc.GetModelSchema(modelID);
console.log("IFC Schema:", schema); // "IFC2X3", "IFC4", or "IFC4X3"
const wallIDs = ifcLoader.webIfc.GetLineIDsWithType(modelID, WEBIFC.IFCWALL);
console.log("Number of walls:", wallIDs.size());
// ALWAYS clean up after raw access
ifcLoader.cleanUp();IfcLoader & IfcImporter — API Reference
IfcLoader (from @thatopen/components)
Class Definition
class IfcLoader extends Component implements Disposable, Configurable<IfcFragmentSettings> {
static readonly uuid: string; // "a659add7-1418-4771-a0d6-7d4d438e4624"
enabled: boolean; // default: true
settings: IfcFragmentSettings;
webIfc: WEBIFC.IfcAPI;
// Events
onDisposed: Event<string>;
onSetup: Event<void>;
onIfcStartedLoading: Event<void>;
onIfcImporterInitialized: Event<IfcImporter>;
}Methods
setup(config?: Partial<IfcFragmentSettings>): Promise<void>
Initializes the IfcLoader with WASM configuration. MUST be called before load().
- When
autoSetWasmistrue(default), automatically resolves the WASM path from the installedweb-ifcpackage. - When
autoSetWasmisfalse, useswasm.pathandwasm.absolutefrom the provided config. - Fires
onSetupevent on completion.
// Auto WASM (default)
await ifcLoader.setup();
// Manual WASM
await ifcLoader.setup({
autoSetWasm: false,
wasm: { path: "https://unpkg.com/web-ifc@0.0.77/", absolute: true },
});load(data: Uint8Array, coordinate: boolean, name: string, config?: object): Promise<FragmentsModel>
Converts an IFC file into a FragmentsModel for 3D rendering.
| Parameter | Type | Required | Description |
|---|---|---|---|
data | Uint8Array | Yes | IFC file contents |
coordinate | boolean | Yes | Apply coordination matrix for multi-model alignment |
name | string | Yes | Display name for the model |
config | object | No | { instanceCallback?, processData?, userData? } |
Returns: Promise<FragmentsModel> — The loaded model, ready to add to a scene.
Fires onIfcStartedLoading at the beginning of parsing. Fires onIfcImporterInitialized when the internal IfcImporter is created (use this to customize import classes).
readIfcFile(data: Uint8Array): Promise<number>
Opens an IFC file in the internal web-ifc instance without converting to fragments. Returns the modelID for direct web-ifc API access via ifcLoader.webIfc.
ALWAYS call cleanUp() after using readIfcFile().
cleanUp(): void
Resets the internal web-ifc state and clears maps. Called automatically after load(). Call manually after readIfcFile().
dispose(): void
Releases all resources including the web-ifc WASM instance.
---
IfcFragmentSettings
interface IfcFragmentSettings {
autoSetWasm: boolean; // default: true
wasm: {
path: string; // directory containing WASM files
absolute: boolean; // true = absolute URL, false = relative
logLevel?: LogLevel; // web-ifc log verbosity
};
webIfc: LoaderSettings; // passed to web-ifc OpenModel()
customLocateFileHandler: LocateFileHandlerFn | null; // default: null
}LoaderSettings (web-ifc)
interface LoaderSettings {
COORDINATE_TO_ORIGIN?: boolean; // translate geometry to origin
USE_FAST_BOOLS?: boolean; // faster but less accurate booleans
CIRCLE_SEGMENTS_LOW?: number; // tessellation: small curves
CIRCLE_SEGMENTS_MEDIUM?: number; // tessellation: medium curves
CIRCLE_SEGMENTS_HIGH?: number; // tessellation: large curves
BOOL_ABORT_THRESHOLD?: number; // timeout (ms) for boolean ops
MEMORY_LIMIT?: number; // WASM memory limit in bytes
}---
IfcImporter (from @thatopen/fragments)
Class Definition
class IfcImporter {
wasm: { path: string; absolute: boolean };
classes: {
elements: Set<number>; // physical IFC element types to import
abstract: Set<number>; // abstract types (materials, properties)
};
relations: Map<number, { forRelating: number[]; forRelated: number[] }>;
distanceThreshold: number | null; // default: 100000
includeRelationNames: boolean; // default: false
includeUniqueAttributes: boolean; // default: false
replaceSiteElevation: boolean; // default: true
replaceStoreyElevation: boolean; // default: true
attributesToExclude: Set<string>;
}Methods
process(data: Uint8Array): Promise<Uint8Array>
Converts an IFC file to Fragments binary format. Input is IFC file bytes, output is Fragments binary bytes.
addAllAttributes(): void
Populates the importer to include all IFC attributes in the output. Use cautiously — significantly increases output size.
addAllRelations(): void
Populates the importer to include all IFC relations in the output. Use cautiously — significantly increases output size.
---
FragmentsModel (return type of load())
Key properties and methods of the loaded model:
class FragmentsModel {
object: THREE.Object3D; // add this to your scene
export(): Uint8Array; // serialize to Fragments binary
dispose(): void; // free GPU and CPU resources
}---
Event Types
| Event | Payload | Description |
|---|---|---|
onSetup | void | Fired after setup() completes |
onIfcStartedLoading | void | Fired when IFC parsing begins in load() |
onIfcImporterInitialized | IfcImporter | Fired when the IfcImporter instance is created; use to modify classes |
onDisposed | string | Fired when the component is disposed |
Event Usage Pattern
// Listen for setup completion
ifcLoader.onSetup.add(() => {
console.log("IfcLoader ready");
});
// Customize import classes before conversion begins
ifcLoader.onIfcImporterInitialized.add((importer) => {
importer.classes.elements.add(WEBIFC.IFCSPACE);
importer.classes.elements.delete(WEBIFC.IFCFURNISHINGELEMENT);
});
// Track loading progress
ifcLoader.onIfcStartedLoading.add(() => {
console.log("IFC parsing started...");
});