From bdfa70468eee0c3c799163e82605ba96bc72e8f8 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Thu, 2 Jul 2026 14:24:18 +1000 Subject: [PATCH] ifcviewer-web: frame the first model only on load, matching desktop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit applyCachedModel already does a one-time viewAll gated by initial_view_applied_ (desktop + web) — it frames the FIRST model loaded and never re-frames as more arrive. Two web-only divergences from the desktop viewer, fixed here: - loadSidecarMetadataWeb called viewAll() AGAIN, unconditionally, per model, so every federated model that streamed in yanked the camera back to fit the whole scene. Drop the redundant call; the shared gate handles first-model framing. - Nothing ever cleared initial_view_applied_. On web the embedded sample sets it at startup, so after clear_scene_c (a ?model= federation load) the gate was already tripped and the loaded models never got framed — the camera stayed on the prior view. (The redundant per-model viewAll above masked this until it was removed.) Clear the flag in resetScene: a fresh scene should auto-frame its first model — correct for desktop fresh-opens too. 113/113 desktop + 6/6 web smoke pass. Co-Authored-By: Claude Opus 4.8 --- src/ifcviewer/ViewportCore.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ifcviewer/ViewportCore.cpp b/src/ifcviewer/ViewportCore.cpp index 9a3c55f8d3..8c307bbf7d 100644 --- a/src/ifcviewer/ViewportCore.cpp +++ b/src/ifcviewer/ViewportCore.cpp @@ -111,6 +111,11 @@ void ViewportCore::removeModel(uint32_t model_id) { void ViewportCore::resetScene() { for (auto& [mid, m] : models_gpu_) releaseWgpuModelGpuData(m, pool_); models_gpu_.clear(); + // A fresh scene should auto-frame its first model. Without this the flag + // stays set from the previous scene (on web, the embedded sample sets it at + // startup), so the next load — e.g. a ?model= federation after clear_scene_c + // — would never get framed. + initial_view_applied_ = false; host_->requestFrame(); } @@ -3587,7 +3592,11 @@ void ViewportCore::loadSidecarMetadataWeb(int source_id, std::string source_labe mit->second.deferred_raw_size = dr; } } - viewAll(); + // NOTE: no viewAll() here — applyCachedModel + // already frames the FIRST model (gated by + // initial_view_applied_), matching desktop. + // Reframing per model would jump the camera + // as each federated model streams in. host_->requestFrame(); Log::info() << "ifcviewer-web: loaded sidecar (" << source_label << ", id " << mid << ", " << n_meshes << " meshes, "