Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
openaec-foundation avatar

Thatopen Core Web Ifc

  • 5 installs
  • 17 repo stars
  • Updated July 8, 2026
  • openaec-foundation/thatopen-claude-skill-package

Helps with ai & agent building tasks.

About

thatopen-core-web-ifc is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.

  • thatopen-core-web-ifc
  • AI & Agent Building
  • AI-coding skill

Thatopen Core Web Ifc by the numbers

  • 5 all-time installs (skills.sh)
  • Ranked #13,065 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
  • Data as of Jul 26, 2026 (Skillselion catalog sync)
npx skills add https://github.com/openaec-foundation/thatopen-claude-skill-package --skill thatopen-core-web-ifc

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs5
repo stars17
Last updatedJuly 8, 2026
Repositoryopenaec-foundation/thatopen-claude-skill-package

What it does

Helps with ai & agent building tasks.

Files

SKILL.mdMarkdownGitHub ↗

web-ifc Engine: Direct WASM IFC Parser

Overview

web-ifc is the WASM-powered IFC parsing engine beneath the ThatOpen component stack. It reads and writes IFC files at native speed in browser and Node.js environments. The central class is IfcAPI.

  • Package: web-ifc (npm)
  • Source: https://github.com/ThatOpen/engine_web-ifc
  • Environments: Browser, Node.js (single-threaded and multi-threaded WASM)
  • License: MPL-2.0
When using ThatOpen components (@thatopen/components), you rarely call web-ifc directly — the IfcLoader component wraps it. Use this skill when you need low-level IFC access, custom geometry extraction, or bulk property queries outside the component framework.

---

Critical Warnings

1. ALWAYS call `Init()` before any other method (except SetWasmPath). Every method silently fails or throws without WASM initialization. 2. ALWAYS call `CloseModel(modelID)` when done — each open model holds significant WASM heap memory. Forgetting this causes memory leaks that crash browser tabs. 3. ALWAYS use `.size()` and `.get(i)` for `Vector<T>` access — NEVER use array indexing ([]). WASM vectors are not JavaScript arrays. 4. ALWAYS call `Dispose()` when the IfcAPI instance is no longer needed — this releases the entire WASM module. 5. NEVER create multiple `IfcAPI` instances — one instance handles multiple models. Extra instances waste memory by loading duplicate WASM modules. 6. Vertex format is 6 floats per vertex: [x, y, z, nx, ny, nz] — position followed by normal. ALWAYS account for this interleaved layout when extracting geometry. 7. All 4x4 matrices are column-major (16 floats) — directly compatible with THREE.Matrix4.fromArray().

---

Quick Start

import * as WebIFC from "web-ifc";

const ifcApi = new WebIFC.IfcAPI();
ifcApi.SetWasmPath("/wasm/");       // MUST be called before Init()
await ifcApi.Init();

const data = new Uint8Array(buffer); // from fetch or fs.readFile
const modelID = ifcApi.OpenModel(data);

// Query walls
const wallIDs = ifcApi.GetLineIDsWithType(modelID, WebIFC.IFCWALL);
for (let i = 0; i < wallIDs.size(); i++) {
  const wall = ifcApi.GetLine(modelID, wallIDs.get(i));
  console.log(wall.Name?.value);
}

// Get geometry
const mesh = ifcApi.GetFlatMesh(modelID, wallIDs.get(0));

// Get coordination matrix
const matrix = ifcApi.GetCoordinationMatrix(modelID);

ifcApi.CloseModel(modelID); // ALWAYS free memory

---

Initialization

SetWasmPath(path: string, absolute?: boolean): void

Sets the directory containing WASM files. MUST be called before Init(). The directory MUST contain web-ifc.wasm (and web-ifc-mt.wasm for multi-threaded mode).

ifcApi.SetWasmPath("/static/wasm/");                         // relative
ifcApi.SetWasmPath("https://cdn.example.com/wasm/", true);   // absolute URL

NEVER hardcode a version in the WASM path — ALWAYS match the installed web-ifc npm version.

Init(customLocateFileHandler?, forceSingleThread?): Promise<void>

Initializes the WASM module. MUST be awaited before calling any other API method.

await ifcApi.Init();                        // default (auto-detect threading)
await ifcApi.Init(undefined, true);         // force single-threaded
await ifcApi.Init((path, prefix) => "/custom/" + path); // custom file locator

Dispose(): void

Releases the entire WASM module and all resources. Call when the IfcAPI instance is no longer needed.

---

Model Lifecycle

MethodSignaturePurpose
OpenModel(data: Uint8Array, settings?: LoaderSettings) => numberLoad IFC from buffer, returns modelID
OpenModels(dataSets: Uint8Array[], settings?) => number[]Load multiple IFC files at once
OpenModelFromCallback(callback: ModelLoadCallback, settings?) => numberStream-load without full buffer in memory
CreateModel(model: NewIfcModel, settings?) => numberCreate empty IFC model
SaveModel(modelID: number) => Uint8ArraySerialize model to IFC bytes
CloseModel(modelID: number) => voidFree all WASM memory for this model
IsModelOpen(modelID: number) => booleanCheck if model is open

LoaderSettings

interface LoaderSettings {
  COORDINATE_TO_ORIGIN?: boolean;    // translate model to origin (recommended)
  USE_FAST_BOOLS?: boolean;          // faster but less accurate boolean ops
  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
}

ALWAYS use COORDINATE_TO_ORIGIN: true for models with large world coordinates — prevents floating-point precision issues in rendering.

---

Data Queries

Core Query Methods

MethodReturnsPurpose
GetAllLines(modelID)Vector<number>All expressIDs in the model
GetLineIDsWithType(modelID, type, includeInherited?)Vector<number>ExpressIDs by IFC type
GetLine(modelID, expressID, flatten?, inverse?, inversePropKey?)anySingle entity by expressID
GetLines(modelID, expressIDs, flatten?, inverse?, inversePropKey?)any[]Batch entity retrieval
GetRawLineData(modelID, expressID)RawLineDataRaw unparsed data (faster)
GetLineType(modelID, expressID)numberIFC type code only
GetMaxExpressID(modelID)numberHighest expressID
GetNextExpressID(modelID, expressID)numberNext valid expressID

GetLine Parameters

ParameterTypeDefaultDescription
flattenbooleanfalseRecursively resolve all references inline
inversebooleanfalseInclude inverse relationships
inversePropKeystring?nullFilter inverse props to specific key

NEVER use flatten: true on large models without limiting scope — it recursively resolves every reference and causes severe performance degradation.

Schema & Type Information

MethodReturnsPurpose
GetModelSchema(modelID)stringSchema version ("IFC2X3", "IFC4", "IFC4X3")
GetAllTypesOfModel(modelID)IfcType[]All IFC types present in model
GetHeaderLine(modelID, headerType)anyIFC header info

---

Geometry Extraction

Single-Element Geometry

const flatMesh = ifcApi.GetFlatMesh(modelID, expressID);

for (let i = 0; i < flatMesh.geometries.size(); i++) {
  const pg = flatMesh.geometries.get(i);
  const geom = ifcApi.GetGeometry(modelID, pg.geometryExpressID);
  const verts = ifcApi.GetVertexArray(geom.GetVertexData(), geom.GetVertexDataSize());
  const indices = ifcApi.GetIndexArray(geom.GetIndexData(), geom.GetIndexDataSize());

  // verts: Float32Array — 6 floats per vertex [x, y, z, nx, ny, nz]
  // indices: Uint32Array — triangle indices
  // pg.color: { x, y, z, w } — RGBA (w = alpha)
  // pg.flatTransformation: number[] — 4x4 column-major transform matrix
}

Geometry Streaming (Memory-Efficient)

ALWAYS prefer streaming over LoadAllGeometry for models with more than a few hundred elements.

MethodPurpose
StreamAllMeshes(modelID, callback)Stream ALL meshable entities
StreamAllMeshesWithTypes(modelID, types[], callback)Stream filtered by IFC types
StreamMeshes(modelID, expressIDs[], callback)Stream specific elements
LoadAllGeometry(modelID)Load all at once (AVOID for large models)

Callback signature: (mesh: FlatMesh, index: number, total: number) => void

Coordination & Transforms

MethodPurpose
GetCoordinationMatrix(modelID)4x4 matrix for multi-model alignment
SetGeometryTransformation(modelID, matrix)Apply global transform to all geometry output
GetWorldTransformMatrix(modelID, placementExpressId)Transform for specific placement

---

Properties Helper

The ifcApi.properties object provides high-level async methods for property queries.

MethodReturnsPurpose
getItemProperties(modelID, id, recursive?, inverse?)Promise<any>All properties for an element
getPropertySets(modelID, elementID?, recursive?)Promise<any[]>Property sets (Psets)
getTypeProperties(modelID, elementID?, recursive?)Promise<any[]>Type object properties
getMaterialsProperties(modelID, elementID?, recursive?)Promise<any[]>Material definitions
getSpatialStructure(modelID, includeProperties?)Promise<Node>Full spatial hierarchy tree

The spatial structure returns a tree: { expressID, type, children: [...] }.

---

GUID Utilities

MethodPurpose
GetExpressIdFromGuid(modelID, guid)Convert IFC GUID string to expressID
GetGuidFromExpressId(modelID, expressID)Convert expressID to IFC GUID string
CreateIfcGuidToExpressIdMapping(modelID)Pre-build mapping for faster lookups

ALWAYS call CreateIfcGuidToExpressIdMapping first if performing many GUID lookups — it builds an index that makes subsequent calls faster.

---

Writing Data

MethodPurpose
WriteLine(modelID, lineObject)Write or update a single entity
WriteLines(modelID, lineObjects[])Batch write
DeleteLine(modelID, expressID)Remove entity from model
CreateIfcEntity(modelID, type, ...args)Create new IFC entity

After modifications, use SaveModel(modelID) to serialize back to IFC format.

---

Logging

import { LogLevel } from "web-ifc";
ifcApi.SetLogLevel(LogLevel.LOG_LEVEL_OFF);    // silent (recommended for production)
ifcApi.SetLogLevel(LogLevel.LOG_LEVEL_ERROR);  // errors only
ifcApi.SetLogLevel(LogLevel.LOG_LEVEL_DEBUG);  // verbose debugging

---

Key Types

See references/methods.md for complete type definitions.

TypeDescription
FlatMeshTriangulated geometry result: { expressID, geometries: Vector<PlacedGeometry> }
PlacedGeometrySingle geometry piece: color (RGBA), transform (4x4), geometryExpressID
IfcGeometryRaw WASM geometry: GetVertexData/Size(), GetIndexData/Size()
Vector<T>WASM vector: access via .size() and .get(i) ONLY
RawLineDataUnparsed entity: { ID, type, arguments }
LoaderSettingsModel loading configuration
IfcTypeType descriptor: { typeID, typeName }

---

Common IFC Type Constants

import {
  // Structural
  IFCWALL, IFCWALLSTANDARDCASE, IFCSLAB, IFCBEAM, IFCCOLUMN,
  // Openings
  IFCDOOR, IFCWINDOW, IFCOPENINGELEMENT,
  // Building elements
  IFCROOF, IFCSTAIR, IFCFURNISHINGELEMENT,
  // Spatial hierarchy
  IFCPROJECT, IFCSITE, IFCBUILDING, IFCBUILDINGSTOREY, IFCSPACE,
  // Properties & relations
  IFCPROPERTYSET, IFCPROPERTYSINGLEVALUE,
  IFCRELDEFINESBYPROPERTIES, IFCRELCONTAINEDINSPATIALSTRUCTURE,
  IFCRELAGGREGATES, IFCRELVOIDSELEMENT,
} from "web-ifc";

---

References

  • references/methods.md — Complete IfcAPI method signatures and type definitions
  • references/examples.md — Full working examples: init, load, query, geometry, properties
  • references/anti-patterns.md — Common failures: WASM init, memory leaks, Vector access

Sources

  • GitHub: https://github.com/ThatOpen/engine_web-ifc
  • Docs: https://thatopen.github.io/engine_web-ifc/docs/
  • npm: https://www.npmjs.com/package/web-ifc

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.