models: consume .rdbview bundles (extract at load time)

A .rdbview is a zip of model.rdb/ (the lossy IFC data DB — the rdb
serializer skips IfcRepresentationItem) + model.ifcview (baked geometry).
The viewer could produce them but not open them.

- extractRdbview(): unzip a .rdbview (QZipReader) into a session temp dir
  keyed by a hash of path+mtime+size (reused on re-open), returning the
  extracted model.rdb. The producer's layout means sidecarPath(model.rdb)
  resolves the sibling model.ifcview automatically, so it then loads exactly
  like any pure .rdb: geometry from the sidecar, data from the .rdb via
  ifcopenshell::file(FT_AUTODETECT). No SceneLoader/engine changes.
- detail::loadModels() resolves each source path through it before
  queueModels (both fresh-open and project reload go through here), so the
  Federation persists the .rdbview while the loader gets the extracted .rdb.
- cleanupRdbviewCache() clears stale extractions at startup.
- .rdbview is offered under "Add Geometry" (the file picker; "Add IFC
  Database" is a directory picker), not "Add IFC File" — it's a lossy viewer
  bundle, not a source IFC.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-07-09 20:36:51 +10:00
parent db884047e1
commit 79d8408684
4 changed files with 85 additions and 6 deletions
+4
View File
@@ -21,6 +21,7 @@
#include "MainWindow.h"
#include "ViewerSettings.h"
#include "components/Style.h"
#include "modules/models/Commands.h"
#include <QApplication>
#include <QCommandLineParser>
@@ -55,6 +56,9 @@ int main(int argc, char* argv[]) {
app.setApplicationName("Bonsai Viewer");
app.setOrganizationName("IfcOpenShell");
// Clear any .rdbview extractions left in temp by a previous session.
bonsaiviewer::modules::models::commands::cleanupRdbviewCache();
QSurfaceFormat fmt;
fmt.setVersion(4, 5);
fmt.setProfile(QSurfaceFormat::CoreProfile);