Exporting Data¶
Guide to exporting IFC data in various formats.
Quick Start: CDN Export (No Build Required)¶
Export IFC to GLB directly in the browser with zero setup:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>IFC to GLB Export</title>
</head>
<body>
<input type="file" id="file" accept=".ifc">
<div id="status"></div>
<script type="module">
import { GeometryProcessor } from "https://cdn.jsdelivr.net/npm/@ifc-lite/geometry@1.2.1/+esm";
import { GLTFExporter } from "https://cdn.jsdelivr.net/npm/@ifc-lite/export@1.2.1/+esm";
import initWasm from "https://cdn.jsdelivr.net/npm/@ifc-lite/wasm@1.2.1/+esm";
// Initialize WASM with explicit path for CDN
const wasmUrl = "https://cdn.jsdelivr.net/npm/@ifc-lite/wasm@1.2.1/pkg/ifc-lite_bg.wasm";
await initWasm({ module_or_path: wasmUrl });
document.getElementById("file").addEventListener("change", async (e) => {
const file = e.target.files[0];
if (!file) return;
try {
const processor = new GeometryProcessor();
await processor.init();
const buffer = new Uint8Array(await file.arrayBuffer());
const result = await processor.process(buffer);
const exporter = new GLTFExporter(result);
const glb = exporter.exportGLB();
// Download the GLB file
const blob = new Blob([glb], { type: "model/gltf-binary" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = file.name.replace(/\.ifc$/i, ".glb");
a.click();
URL.revokeObjectURL(url);
document.getElementById("status").textContent = "Done!";
processor.dispose();
} catch (error) {
document.getElementById("status").textContent = "Error: " + error.message;
}
});
</script>
</body>
</html>
HTTP Server Required
This file must be served from an HTTP server (not file://). Use npx serve . or python -m http.server 8000.
Overview¶
IFClite supports multiple export formats, as well as GLB import for loading existing 3D assets:
glTF Export¶
Export geometry for use in standard 3D viewers:
import { GltfExporter } from '@ifc-lite/export';
const exporter = new GltfExporter();
// Export to glTF (JSON + binary)
const gltf = await exporter.export(parseResult, {
format: 'gltf',
embedImages: true,
includeProperties: true
});
// Save files
await saveFile('model.gltf', gltf.json);
await saveFile('model.bin', gltf.binary);
// Export to GLB (single binary file)
const glb = await exporter.export(parseResult, {
format: 'glb'
});
await saveFile('model.glb', glb);
glTF Options¶
interface GltfExportOptions {
// Output format
format: 'gltf' | 'glb';
// Include IFC properties as extras
includeProperties?: boolean;
// Embed textures/images
embedImages?: boolean;
// Draco compression
useDraco?: boolean;
dracoOptions?: {
quantization?: number;
compressionLevel?: number;
};
// Filter entities
entityFilter?: (entity: Entity) => boolean;
// Coordinate system
yUp?: boolean; // Convert from Z-up to Y-up
}
glTF with Properties¶
const gltf = await exporter.export(parseResult, {
format: 'glb',
includeProperties: true
});
// Properties are stored in node extras:
// {
// "nodes": [{
// "name": "Wall-001",
// "extras": {
// "expressId": 123,
// "globalId": "2O2Fr$...",
// "type": "IFCWALL",
// "properties": {
// "Pset_WallCommon": {
// "IsExternal": true,
// "FireRating": 60
// }
// }
// }
// }]
// }
Parquet Export¶
Export to Apache Parquet for analytics with tools like DuckDB, Pandas, or Polars:
import { ParquetExporter } from '@ifc-lite/export';
const exporter = new ParquetExporter();
// Export entities
const entitiesParquet = await exporter.exportEntities(parseResult);
await saveFile('entities.parquet', entitiesParquet);
// Export properties
const propsParquet = await exporter.exportProperties(parseResult);
await saveFile('properties.parquet', propsParquet);
// Export quantities
const quantsParquet = await exporter.exportQuantities(parseResult);
await saveFile('quantities.parquet', quantsParquet);
// Export all tables
const bundle = await exporter.exportAll(parseResult);
await saveFile('entities.parquet', bundle.entities);
await saveFile('properties.parquet', bundle.properties);
await saveFile('quantities.parquet', bundle.quantities);
await saveFile('relationships.parquet', bundle.relationships);
Parquet Schema¶
Using Parquet with Python¶
import polars as pl
# Load exported data
entities = pl.read_parquet('entities.parquet')
properties = pl.read_parquet('properties.parquet')
quantities = pl.read_parquet('quantities.parquet')
# Analyze wall areas
wall_areas = (
entities
.filter(pl.col('type').str.contains('IFCWALL'))
.join(quantities, left_on='express_id', right_on='entity_id')
.filter(pl.col('name') == 'NetArea')
.group_by('type')
.agg([
pl.count('express_id').alias('count'),
pl.sum('value').alias('total_area'),
pl.mean('value').alias('avg_area')
])
)
print(wall_areas)
JSON-LD Export¶
Export as linked data for semantic web applications:
import { JsonLdExporter } from '@ifc-lite/export';
const exporter = new JsonLdExporter();
const jsonld = await exporter.export(parseResult, {
// Base URI for identifiers
baseUri: 'https://example.com/project/',
// Include geometry as GeoJSON
includeGeometry: false,
// IFC ontology namespace
ontology: 'https://standards.buildingsmart.org/IFC/DEV/IFC4/ADD2/OWL'
});
await saveFile('model.jsonld', JSON.stringify(jsonld, null, 2));
JSON-LD Structure¶
{
"@context": {
"ifc": "https://standards.buildingsmart.org/IFC/DEV/IFC4/ADD2/OWL#",
"schema": "https://schema.org/",
"geo": "http://www.opengis.net/ont/geosparql#"
},
"@graph": [
{
"@id": "https://example.com/project/wall-123",
"@type": "ifc:IfcWall",
"ifc:globalId": "2O2Fr$t4X7Zf8NOew3FL9r",
"ifc:name": "Wall-001",
"ifc:hasPropertySet": [
{
"@type": "ifc:IfcPropertySet",
"ifc:name": "Pset_WallCommon",
"ifc:hasProperty": [
{
"@type": "ifc:IfcPropertySingleValue",
"ifc:name": "IsExternal",
"ifc:value": true
}
]
}
]
}
]
}
CSV Export¶
Export tabular data for spreadsheet applications:
import { CsvExporter } from '@ifc-lite/export';
const exporter = new CsvExporter();
// Export entity list
const entitiesCsv = await exporter.exportEntities(parseResult, {
columns: ['expressId', 'type', 'globalId', 'name']
});
await saveFile('entities.csv', entitiesCsv);
// Export properties (pivoted)
const propsCsv = await exporter.exportPropertiesPivot(parseResult, {
psetName: 'Pset_WallCommon',
entityTypes: ['IFCWALL', 'IFCWALLSTANDARDCASE']
});
await saveFile('wall_properties.csv', propsCsv);
// Export quantities
const quantsCsv = await exporter.exportQuantities(parseResult);
await saveFile('quantities.csv', quantsCsv);
CSV Output Example¶
expressId,type,globalId,name,IsExternal,FireRating,LoadBearing
123,IFCWALL,2O2Fr$t4X7Zf8NOew3FL9r,Wall-001,true,60,true
456,IFCWALLSTANDARDCASE,3P3Gs$u5Y8Ag9PQfx4GM0s,Wall-002,false,30,false
IFC Export¶
Export back to IFC format for roundtrip workflows and interoperability with other BIM tools:
import { StepExporter } from '@ifc-lite/export';
const exporter = new StepExporter(dataStore, sourceBuffer);
// Full export
const result = exporter.export();
await saveFile('model.ifc', result.content);
// Visible-only export (exclude hidden entities)
const visibleResult = exporter.export({
visibleOnly: true,
hiddenEntityIds: hiddenSet, // Set<number> of local expressIds
isolatedEntityIds: isolatedSet, // Set<number> | null
});
await saveFile('visible_only.ifc', visibleResult.content);
Visible-Only Export¶
When visibleOnly is enabled, the exporter:
- Always includes infrastructure (units, owner history) and spatial structure
- Checks each product entity against
hiddenEntityIds/isolatedEntityIds - Walks
#IDreferences transitively to include all dependent geometry, properties, and materials - Collects
IfcStyledItementities via reverse reference pass (preserves colors/materials) - Propagates visibility to openings via
IfcRelVoidsElement(hidden slab = hidden openings)
Supports all 202 IfcProduct subtypes from IFC4 and IFC4X3 schemas, including infrastructure types (bridges, roads, railways, marine facilities).
Multi-Model Merged Export¶
Merge multiple IFC models into a single file:
import { MergedExporter } from '@ifc-lite/export';
const exporter = new MergedExporter();
const result = await exporter.export([
{ dataStore: store1, source: buffer1, name: 'Architecture' },
{ dataStore: store2, source: buffer2, name: 'Structure' },
], {
visibleOnly: true,
hiddenEntityIds: hiddenSet,
isolatedEntityIds: isolatedSet,
});
await saveFile('merged.ifc', result.content);
GLB Import¶
Load existing GLB files for viewing alongside IFC models:
import { GlbImporter } from '@ifc-lite/import';
const importer = new GlbImporter();
const glbBuffer = await fetch('model.glb').then(r => r.arrayBuffer());
const meshes = await importer.import(new Uint8Array(glbBuffer));
// Add imported meshes to the renderer
renderer.addMeshes(meshes);
Arrow Export¶
Export to Apache Arrow for in-memory analytics and streaming pipelines:
import { ArrowExporter } from '@ifc-lite/export';
const exporter = new ArrowExporter();
const arrowBuffer = await exporter.exportEntities(parseResult);
// Use with Arrow-compatible tools (DuckDB, DataFusion, etc.)
await saveFile('entities.arrow', arrowBuffer);
Custom Export¶
Create custom export formats:
import { ExportPipeline } from '@ifc-lite/export';
import { extractPropertiesOnDemand, extractQuantitiesOnDemand } from '@ifc-lite/parser';
// Define custom exporter
class CustomExporter {
export(store: IfcDataStore, buffer: Uint8Array): CustomFormat {
const output: CustomFormat = {
metadata: {
schema: store.schemaVersion,
timestamp: new Date().toISOString()
},
elements: []
};
// Get all wall expressIds
const wallIds = store.entityIndex.byType.get('IFCWALL') ?? [];
for (const expressId of wallIds) {
const entityRef = store.entityIndex.byId.get(expressId);
if (entityRef) {
output.elements.push({
id: expressId,
name: entityRef.name,
properties: extractPropertiesOnDemand(store, expressId, buffer),
quantities: extractQuantitiesOnDemand(store, expressId, buffer)
});
}
}
return output;
}
}
// Use custom exporter
const exporter = new CustomExporter();
const custom = exporter.export(store, buffer);
Filtered Export¶
Export only specific entities:
import { GltfExporter } from '@ifc-lite/export';
import { IfcQuery } from '@ifc-lite/query';
// Filter entities with query
const query = new IfcQuery(parseResult);
const externalWalls = query
.walls()
.whereProperty('Pset_WallCommon', 'IsExternal', '=', true)
.toArray();
// Export filtered set
const exporter = new GltfExporter();
const glb = await exporter.export(parseResult, {
format: 'glb',
entityFilter: (entity) =>
externalWalls.some(w => w.expressId === entity.expressId)
});
Export Pipeline¶
Chain multiple exports:
import { ExportPipeline } from '@ifc-lite/export';
const pipeline = new ExportPipeline(parseResult);
// Run multiple exports in parallel
const results = await pipeline.export([
{ format: 'glb', options: { useDraco: true } },
{ format: 'parquet', tables: ['entities', 'properties'] },
{ format: 'csv', columns: ['expressId', 'type', 'name'] }
]);
// Save all results
await saveFile('model.glb', results.glb);
await saveFile('entities.parquet', results.parquet.entities);
await saveFile('entities.csv', results.csv);
Next Steps¶
- Query Guide - Filter data before export
- API Reference - Complete API docs