ifcviewer-web: streaming loading bar (metadata → geometry progress)

Users had no feedback during the seconds before/while a model streams. Add a
top progress strip + caption driven by the streaming state:
- "Loading model… N MB" while the critical metadata downloads (no chunks yet),
- "Loading geometry — R / T chunks · N MB" as chunks go resident,
- "Loaded — T chunks · N MB", then it hides.

ViewportCore::streamingProgress(resident, total) sums chunk residency across
models; main_web exports ifcv_chunks_resident_c / ifcv_chunks_total_c for
shell.html to poll each RAF. The EM_JS range reader accumulates
Module.__ifcvBytesLoaded so the caption can show MB downloaded. Shown only for
streamed loads (?model= URL / picked file), not the embedded sample.

6/6 web smoke pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-07-01 08:54:42 +10:00
parent 41a85a70ba
commit 13ec2be807
5 changed files with 86 additions and 2 deletions
+12
View File
@@ -216,6 +216,18 @@ extern "C" EMSCRIPTEN_KEEPALIVE void load_sidecar_from_url_c(const char* url) {
g_app->core.loadSidecarFromUrlWeb(url);
}
// Streaming progress for the loading bar (shell.html polls these each frame).
// total == 0 while still fetching metadata; resident climbs to total as
// geometry chunks arrive.
extern "C" EMSCRIPTEN_KEEPALIVE int ifcv_chunks_resident_c() {
if (!g_app) return 0;
int r = 0, t = 0; g_app->core.streamingProgress(r, t); return r;
}
extern "C" EMSCRIPTEN_KEEPALIVE int ifcv_chunks_total_c() {
if (!g_app) return 0;
int r = 0, t = 0; g_app->core.streamingProgress(r, t); return t;
}
int main(int /*argc*/, char** /*argv*/) {
Log::info() << "ifcviewer-web: starting";
g_app = new AppState();