ifcviewer-web: mint session model ids when a load is requested

A federated pick could be attributed to the wrong file. The model slot a
host sees — ElementRef::model_index, modelProgress's index — is a rank in
session_model_id order, and on web that id was minted at the END of the
sidecar read chain, after three network round trips. So the ranking was
the order the models' reads happened to finish in, not the order the host
added them. With ~40 similarly-sized models over HTTP, adjacent models
swapped and a click reported its neighbour's file; the host page then
asked for a GUID the file does not contain.

Mint the id at the top of loadSidecarMetadataWeb instead, which runs
synchronously from load_sidecar_from_source_c and therefore in the order
the host asked for its models. A load that fails partway just abandons
its id, and the ranks compact over the surviving models as before.

Positions are still positions, though: if one model fails to load, every
later index shifts down one and a host mapping index into its own list
silently drifts again. So also carry the source id — the handle the host
minted itself when it registered the file — through ElementRef into the
pick payload and getObjects rows, and document it as the way to attribute
an object to a file. ModelGpuData::web_source_id defaults to -1 now, since
0 is a real source id and cannot double as "none".

The test server grows a ?delay=<ms> knob so a test can force the losing
interleaving: georef-a is added first and served slowly, and its objects
must still come back as model 0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-08-21 11:30:56 +10:00
parent d86f89090b
commit 2c1d445d5b
7 changed files with 162 additions and 30 deletions
+3 -1
View File
@@ -319,7 +319,9 @@ struct ModelGpuData {
// (Module.__ifcvSources[id] = a picked File or a remote URL) this model's
// chunk + element metadata reads pull from. Lets several federated models stream
// from different files at once, mirroring the desktop per-model path.
int web_source_id = 0;
// -1 when the model came from somewhere else (a path read on desktop, the
// embedded sample) — source id 0 is a real source, so it can't mean "none".
int web_source_id = -1;
// v15 element metadata (web, on-demand). The IFC element metadata
// (elements + string_table — names/GUIDs, for UI/picking, never