ifcviewer-full: hide and remove model actions

Right-click a model root in the Elements tree to get Hide/Show and
Remove.  Hide flips the federation's per-model visible flag (already
round-tripped to .ifcfed), pushes ViewportWindow::hideModel/showModel,
and italicises + greys the tree root as a visual cue.  Remove drops
the model from the viewport, the SceneLoader (streamer + caches), the
MainWindow UI maps and tree, and the Federation — disabled while the
model is the active load.

Visibility is reapplied on each model's load completion (sidecar or
stream), so a federation saved with hidden models opens with them
hidden.  clearScene() now also drops SceneLoader state so streamers
no longer leak across federation transitions.

API additions:
- Federation::setModelVisible + modelVisibilityChanged signal
- SceneLoader::removeModel + isLoadingModel

Tests cover the setter (dirty + signal + idempotence + unknown id);
extends the existing round-trip test to actually exercise the
visibility load/save it always claimed to.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-05-04 12:22:14 +10:00
parent 4597be7fda
commit de5eb9641f
7 changed files with 183 additions and 0 deletions
+19
View File
@@ -123,6 +123,25 @@ void SceneLoader::connectStreamer(GeometryStreamer* streamer) {
this, &SceneLoader::onStreamerError, Qt::QueuedConnection);
}
void SceneLoader::removeModel(uint32_t mid) {
// Refuse while the model is the active load: the streamer thread is still
// running and would race with the deleteLater(). UI gates Remove on
// isLoading(), but guard here too.
if (loading_model_id_ == mid) return;
for (auto it = load_queue_.begin(); it != load_queue_.end();) {
if (*it == mid) it = load_queue_.erase(it);
else ++it;
}
auto it = models_.find(mid);
if (it == models_.end()) return;
if (it->second.streamer) {
it->second.streamer->deleteLater();
}
models_.erase(it);
}
void SceneLoader::cancelCurrentLoad() {
if (loading_model_id_ == 0) return;
auto it = models_.find(loading_model_id_);