Inspect connections between building models
View the structural frame, facade and stairs together, then hide the facade to inspect where the models meet.
Open in new tab
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Inspect connections between building models</title>
<meta name="description" content="View the structural frame, facade and stairs together, then hide the facade to inspect where the models meet.">
<style>
html, body { height: 100%; margin: 0; }
#example-viewer-mount { position: fixed; inset: 0; }
bim-grid#ifc-viewer { display: block; position: absolute; inset: 0; width: 100%; height: 100%; min-width: 0; min-height: 0; }
.example-ui { position: fixed; z-index: 10; box-sizing: border-box; color: #253041; font: 12px/1.4 system-ui, sans-serif; }
.example-ui.example-task { right: 10px; bottom: 64px; width: 224px; max-width: calc(100vw - 64px); display: grid; gap: 6px; padding: 10px; background: #fff; border: 1px solid #dfe3e8; border-radius: 4px; box-shadow: 0 1px 5px #14203310; }
.example-ui :is(h2, p) { margin: 0; }
.example-ui h2 { font-size: 13px; line-height: 1.3; font-weight: 650; }
.example-ui p { color: #5a6575; }
.example-ui button { box-sizing: border-box; min-width: 0; max-width: 100%; font: inherit; padding: 5px 7px; border: 1px solid #cbd2dc; border-radius: 3px; background: #fff; color: #253041; cursor: pointer; }
.example-ui button:hover { background: #f3f6fa; }
.example-ui button:focus-visible { outline: 2px solid #3568ba; outline-offset: 2px; }
.example-ui [hidden] { display: none; }
.example-ui.example-credit { right: 8px; bottom: 32px; width: max-content; max-width: calc(100vw - 64px); padding: 2px 5px; background: #ffffffdf; border-radius: 2px; font-size: 9px; text-align: right; overflow-wrap: anywhere; }
.example-ui.example-credit a { color: #566171; }
@media (max-width: 600px) {
.example-ui.example-task { right: 8px; padding: 8px; }
.example-ui button { min-height: 30px; }
}
</style>
<!-- generated:example-seo:start -->
<link rel="canonical" href="https://viewer.flinker.app/examples/s1-structure/index.html">
<meta name="robots" content="index,follow">
<meta property="og:title" content="Inspect connections between building models">
<meta property="og:description" content="View the structural frame, facade and stairs together, then hide the facade to inspect where the models meet.">
<meta property="og:url" content="https://viewer.flinker.app/examples/s1-structure/index.html"><meta property="og:type" content="article">
<meta property="og:site_name" content="Flinker IFC Viewer"><meta property="og:image" content="https://viewer.flinker.app/examples/s1-structure/thumbnail.webp">
<meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="Inspect connections between building models">
<meta name="twitter:description" content="View the structural frame, facade and stairs together, then hide the facade to inspect where the models meet."><meta name="twitter:image" content="https://viewer.flinker.app/examples/s1-structure/thumbnail.webp">
<script type="application/ld+json">{"@context":"https://schema.org","@type":"TechArticle","headline":"Inspect connections between building models","description":"View the structural frame, facade and stairs together, then hide the facade to inspect where the models meet.","url":"https://viewer.flinker.app/examples/s1-structure/index.html","mainEntityOfPage":"https://viewer.flinker.app/examples/s1-structure/index.html","image":"https://viewer.flinker.app/examples/s1-structure/thumbnail.webp","inLanguage":"en","author":{"@type":"Organization","name":"Flinker","url":"https://www.flinker.app/"}}</script>
<!-- generated:example-seo:end -->
<script type="application/json" id="example-data">
{
"category": "Buildings",
"formats": [
"IFC"
],
"capabilities": [
"Federation",
"Structure",
"Facade",
"Visibility"
],
"audience": "BIM workflow",
"order": 20,
"viewer": {
"assetIds": [
"s1-structure",
"s1-facade",
"s1-stairs"
],
"presentation": "default"
},
"assets": [
{
"id": "s1-structure",
"name": "O-S1-CON-Structural engineering - Constructie.ifc",
"format": "IFC",
"bytes": 7305371,
"url": "https://raw.githubusercontent.com/Geonovum/GeoBIM_Georefereren/0fe0f5e89676de3d21fc3219eb5805b36e29e032/data/voorbeeldmodellen_B%26U/Project%20S1/O-S1-CON-Structural%20engineering%20-%20Constructie.ifc",
"sourceUrl": "https://github.com/Geonovum/GeoBIM_Georefereren/blob/0fe0f5e89676de3d21fc3219eb5805b36e29e032/data/voorbeeldmodellen_B%26U/Project%20S1/O-S1-CON-Structural%20engineering%20-%20Constructie.ifc",
"license": "W3C",
"licenseUrl": "https://github.com/Geonovum/GeoBIM_Georefereren/blob/0fe0f5e89676de3d21fc3219eb5805b36e29e032/LICENSE",
"noticeUrl": "https://viewer.flinker.app/examples/s1-structure/index.html#example-notices",
"attribution": "Geonovum GeoBIM georeferencing practice dataset and original model authors. W3C Software and Document license as published in the source repository. Sixty5 / Building Field S1, Strijp-S.",
"notes": "Original source bytes; contents unchanged."
},
{
"id": "s1-facade",
"name": "O-S1-BWK-BIM prefab facade - BIM prefabgevel.ifc",
"format": "IFC",
"bytes": 5984438,
"url": "https://raw.githubusercontent.com/Geonovum/GeoBIM_Georefereren/0fe0f5e89676de3d21fc3219eb5805b36e29e032/data/voorbeeldmodellen_B%26U/Project%20S1/O-S1-BWK-BIM%20prefab%20facade%20-%20BIM%20prefabgevel.ifc",
"sourceUrl": "https://github.com/Geonovum/GeoBIM_Georefereren/blob/0fe0f5e89676de3d21fc3219eb5805b36e29e032/data/voorbeeldmodellen_B%26U/Project%20S1/O-S1-BWK-BIM%20prefab%20facade%20-%20BIM%20prefabgevel.ifc",
"license": "W3C",
"licenseUrl": "https://github.com/Geonovum/GeoBIM_Georefereren/blob/0fe0f5e89676de3d21fc3219eb5805b36e29e032/LICENSE",
"noticeUrl": "https://viewer.flinker.app/examples/s1-structure/index.html#example-notices",
"attribution": "Geonovum GeoBIM georeferencing practice dataset and original model authors. W3C Software and Document license as published in the source repository. Sixty5 / Building Field S1, Strijp-S.",
"notes": "Original source bytes; contents unchanged."
},
{
"id": "s1-stairs",
"name": "E-S1-AFB-JONKERS-TRAPPEN EN BALUSTRADEN.IFC",
"format": "IFC",
"bytes": 11680774,
"url": "https://raw.githubusercontent.com/Geonovum/GeoBIM_Georefereren/0fe0f5e89676de3d21fc3219eb5805b36e29e032/data/voorbeeldmodellen_B%26U/Project%20S1/E-S1-AFB-JONKERS-TRAPPEN%20EN%20BALUSTRADEN.IFC",
"sourceUrl": "https://github.com/Geonovum/GeoBIM_Georefereren/blob/0fe0f5e89676de3d21fc3219eb5805b36e29e032/data/voorbeeldmodellen_B%26U/Project%20S1/E-S1-AFB-JONKERS-TRAPPEN%20EN%20BALUSTRADEN.IFC",
"license": "W3C",
"licenseUrl": "https://github.com/Geonovum/GeoBIM_Georefereren/blob/0fe0f5e89676de3d21fc3219eb5805b36e29e032/LICENSE",
"noticeUrl": "https://viewer.flinker.app/examples/s1-structure/index.html#example-notices",
"attribution": "Geonovum GeoBIM georeferencing practice dataset and original model authors. W3C Software and Document license as published in the source repository. Sixty5 / Building Field S1, Strijp-S.",
"notes": "Original source bytes; contents unchanged."
}
]
}
</script>
</head>
<body>
<main id="example-viewer-mount" aria-label="Model viewer"><bim-grid id="ifc-viewer"></bim-grid></main>
<aside class="example-ui example-task" aria-label="Inspect the frame">
<h2>Inspect the frame</h2>
<p>Open <strong>Files</strong> (folder) on the left toolbar. Clear the checkbox beside the <strong>BIM prefab facade</strong> file to reveal the frame.</p>
<p>Select a component, then click <strong>1 element selected</strong> at the top left to read its properties and source model.</p>
<button id="sample-retry" type="button" hidden>Retry sample</button>
</aside>
<div class="example-ui example-credit" aria-label="Sample source and license"><a href="https://github.com/Geonovum/GeoBIM_Georefereren/blob/0fe0f5e89676de3d21fc3219eb5805b36e29e032/data/voorbeeldmodellen_B%26U/Project%20S1/O-S1-CON-Structural%20engineering%20-%20Constructie.ifc" target="_blank" rel="noopener noreferrer">Geonovum / W3C</a> · <a href="https://github.com/Geonovum/GeoBIM_Georefereren/blob/0fe0f5e89676de3d21fc3219eb5805b36e29e032/LICENSE" target="_blank" rel="noopener noreferrer">W3C</a></div>
<template id="example-guide">
<h2 data-example-title>Inspect connections between building models</h2>
<p data-example-description>View the structural frame, facade and stairs together, then hide the facade to inspect where the models meet.</p>
<h3>Try it</h3><ol><li>Open Files (folder) on the left toolbar and clear the checkbox beside the BIM prefab facade file to identify the frame behind it.</li><li>Compare a facade panel with the nearby floor and structural components.</li><li>Select a component, then click 1 element selected at the top left to inspect its properties and source model. Repeat with a component from another discipline.</li></ol><h2>Developer integration</h2><p>Use repeated <code>viewer.add()</code> calls to federate the three IFCs. File visibility and properties remain SDK controls. This example focuses on discipline interfaces and imports the original source files unchanged.</p><p>Copy this folder and serve it over HTTP, for example <code>python -m http.server 8080</code>. Open <code>http://localhost:8080/</code>; the SDK and sample downloads require internet access.</p>
<h3>Model notes</h3><p>The original IFC source is imported unchanged.</p>
</template>
<template id="example-notices">
<h2>Sources and license notices</h2><p><a href="https://github.com/Geonovum/GeoBIM_Georefereren/tree/0fe0f5e89676de3d21fc3219eb5805b36e29e032/data/voorbeeldmodellen_B%26U/Project%20S1" target="_blank" rel="noopener noreferrer">Geonovum and original model authors</a> · <a href="https://github.com/Geonovum/GeoBIM_Georefereren/blob/0fe0f5e89676de3d21fc3219eb5805b36e29e032/LICENSE" target="_blank" rel="noopener noreferrer">W3C</a></p>
<p>The original source files are imported unchanged.</p>
</template>
<script type="module">
import { Viewer } from "https://cdn.flinker.app/ifc-viewer/v4.0.3/ifc-viewer.es.js";
// Example-only download feedback. All file parsing remains in the published SDK.
async function loadExampleFile(name, url, load = blob => viewer.add(name, blob), size = 0) {
const show = stage => viewer.setMessage(name + ': ' + stage, { type: 'loading' });
const chunks = [], chunkSize = 4 * 1024 * 1024;
let offset = 0, attempts = 0, action = 'download', type = '';
try {
await show('Downloading');
while (!size || offset < size) {
try {
const end = Math.min(offset + chunkSize, size || Infinity) - 1;
const response = await fetch(url, {
headers: { Range: 'bytes=' + offset + '-' + end },
cache: 'no-store', signal: AbortSignal.timeout(60000),
});
if (!response.ok) {
await response.body?.cancel();
// GitHub raw hides Content-Range from browser JavaScript: probe EOF.
if (response.status === 416 && offset && !size) break;
throw Object.assign(new Error('HTTP ' + response.status), { retry: [408, 429].includes(response.status) || response.status >= 500 });
}
const range = response.headers.get('content-range')?.match(/^bytes (\d+)-(\d+)\/(\d+)$/);
if (range && Number(range[1]) !== offset) throw new TypeError('Unexpected byte range');
size ||= Number(range?.[3]) || 0;
const bytes = await response.arrayBuffer();
const expected = response.status === 206 ? (size ? Math.min(chunkSize, size - offset) : 0) : size;
if (!bytes.byteLength || (expected && bytes.byteLength !== expected) || (response.status === 206 && bytes.byteLength > chunkSize))
throw new TypeError('Incomplete download at byte ' + offset);
if (response.status === 200) chunks.length = 0; // Server ignored Range.
chunks.push(bytes);
offset = response.status === 200 ? bytes.byteLength : offset + bytes.byteLength;
type = response.headers.get('content-type') || '';
attempts = 0;
if (response.status === 200) break;
await show('Downloading' + (size ? ' ' + Math.round(offset / size * 100) + '%' : ''));
}
catch (error) {
if (error.retry === false || ++attempts === 3) throw error;
await show('Retrying download');
await new Promise(resolve => setTimeout(resolve, 500 * 2 ** (attempts - 1)));
}
}
action = 'open';
const result = await load(new Blob(chunks, { type }), show);
if (result?.isError) throw new Error('The viewer could not open the file');
await viewer.setMessage(null);
return result;
}
catch (error) {
throw new Error('Could not ' + action + ' ' + name + (action === 'download' ? ' from ' + url : '') + ': ' + error.message, { cause: error });
}
}
const { assets } = JSON.parse(document.getElementById("example-data").textContent);
const viewer = new Viewer('#ifc-viewer');
window.exampleViewer = viewer;
document.body.dataset.exampleState = 'loading';
const imported = new Set();
const retry = document.querySelector('#sample-retry');
let running = false;
async function load() {
if (running)
return;
running = true;
retry.hidden = true;
document.body.dataset.exampleState = 'loading';
try {
await viewer.ready;
for (const asset of assets) {
if (imported.has(asset.id))
continue;
await loadExampleFile(asset.name, asset.url, blob => {
return viewer.add(asset.name, blob);
}, asset.bytes);
imported.add(asset.id);
}
document.body.dataset.exampleState = 'loaded';
}
catch (error) {
document.body.dataset.exampleState = 'error';
await viewer.setMessage(error instanceof Error ? error.message : String(error), { type: 'error' });
retry.hidden = false;
}
finally {
running = false;
}
}
retry.addEventListener('click', () => { void load(); });
void load();
</script>
</body>
</html>
How it works
Try it
- Open Files (folder) on the left toolbar and clear the checkbox beside the BIM prefab facade file to identify the frame behind it.
- Compare a facade panel with the nearby floor and structural components.
- Select a component, then click 1 element selected at the top left to inspect its properties and source model. Repeat with a component from another discipline.
Developer integration
Use repeated viewer.add() calls to federate the three IFCs. File visibility and properties remain SDK controls. This example focuses on discipline interfaces and imports the original source files unchanged.
Copy this folder and serve it over HTTP, for example python -m http.server 8080. Open http://localhost:8080/; the SDK and sample downloads require internet access.
Model notes
The original IFC source is imported unchanged.
Sources and license notices
Geonovum and original model authors · W3C
The original source files are imported unchanged.