mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 14:23:53 +00:00
ifcviewer-web: multi-file loading (federation) via a per-model byte-source
The scene core is already multi-model — models_gpu_ is a map, applyCachedModel APPENDS, and per-model model_id / object_id rebasing / georef+transformation are how the desktop federates today. The only web-specific gap was the byte source: web had ONE global source (__ifcvFile/__ifcvUrl) and reset the scene on every load, so it could show one file at a time. Desktop meanwhile carries a per-model source (streaming_file_path). Mirror that on web: give each model its own web_source_id into a JS source registry (Module.__ifcvSources[id] = a picked File or a sized remote URL). beginWebChunkLoad, the metadata bootstrap, and the on-demand deferred fetch all read from the owning model's source, so several files stream concurrently into one federated scene — reusing all the shared machinery (viewAll, picking, the GUID fetch) untouched. - webReadRangesAsync / ifcvReadRangeInto / ifcvSourceSize take a source id. - loadSidecarMetadataWeb(source_id, …) appends (no resetScene); main_web exposes load_sidecar_from_source_c(id) + clear_scene_c(). - URL size resolution moved to JS (shell.html registers + sizes sources via HEAD/Range), retiring the C-side ifcvBeginUrlSource / ifcv_source_ready dance. - shell.html: source registry + "Open" (replace) / "Add" (append) buttons, multi-file selection; ?model= registers a URL source then loads. Verified: two sidecars from two sources stream into one scene, both fully resident, zero GPU errors. 111/111 unit + 6/6 web smoke pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -167,7 +167,7 @@ test('loads a user-picked sidecar through the Blob.slice byte-range path', async
|
||||
// side to confirm the blob load landed (logged to stderr → console).
|
||||
const samplePath = resolve(__dirname, '..', 'sample.ifcview');
|
||||
const loaded = page.waitForEvent('console', {
|
||||
predicate: (m) => /loaded sidecar \(blob:/.test(m.text()),
|
||||
predicate: (m) => /loaded sidecar \(source/.test(m.text()),
|
||||
timeout: 15_000,
|
||||
});
|
||||
await page.locator('#file-input').setInputFiles(samplePath);
|
||||
@@ -208,7 +208,7 @@ test('streams a remote sidecar over HTTP Range (?model= URL backend)', async ({
|
||||
|
||||
// Wait for the C side to confirm the URL-sourced load landed.
|
||||
const loaded = page.waitForEvent('console', {
|
||||
predicate: (m) => /loaded sidecar \(net:/.test(m.text()),
|
||||
predicate: (m) => /loaded sidecar \(source/.test(m.text()),
|
||||
timeout: 20_000,
|
||||
});
|
||||
await page.goto('/IfcViewerWeb.html?model=/sample.ifcview');
|
||||
|
||||
Reference in New Issue
Block a user