ifcviewer-full: add .ifcfed federation save/load

Federation (JSON) tracks an ordered list of model sources plus an
optional home-view camera state. Sources are stored relative when
under the federation file's directory, absolute otherwise.

File menu now exposes New / Open / Save / Save As; Add Files moves
to Ctrl+Shift+O. View menu gains Set/Go to Home View. Window title
binds to dirty state via setWindowModified, and the close-window
prompt offers Save/Discard/Cancel.

Per-model transform (4x4 column-major) and visible round-trip
through load/save but are not yet applied at the viewport — the
georeferencing work uses them.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-04-27 18:31:59 +10:00
parent 81a7c5b50e
commit 7bc64bef1a
7 changed files with 669 additions and 8 deletions
+22
View File
@@ -34,6 +34,7 @@
#include "ViewportWindow.h"
#include "SceneLoader.h"
class Federation;
class SettingsWindow;
class MainWindow : public QMainWindow {
@@ -43,12 +44,22 @@ public:
~MainWindow();
void addFiles(const QStringList& paths);
bool openFederation(const QString& path);
void setPendingCamera(const QString& params);
void setPendingBenchmark(int frames);
protected:
void closeEvent(QCloseEvent* event) override;
private slots:
void onFileOpen();
void onDatabaseOpen();
void onFederationNew();
void onFederationOpen();
bool onFederationSave();
bool onFederationSaveAs();
void onSetHomeView();
void onGoHomeView();
void onFileSettings();
void onObjectPicked(uint32_t object_id);
void onTreeSelectionChanged();
@@ -69,6 +80,11 @@ private slots:
private:
void setupUi();
void setupMenus();
void loadModelsFromPaths(const QStringList& paths,
const QStringList& fed_ids);
void clearScene();
bool confirmDiscardIfDirty();
void updateWindowTitle();
void populateProperties(uint32_t object_id);
void appendElementToTree(uint32_t model_id,
uint32_t object_id,
@@ -84,6 +100,7 @@ private:
ViewportWindow* viewport_ = nullptr;
SceneLoader* loader_ = nullptr;
Federation* federation_ = nullptr;
SettingsWindow* settings_ = nullptr;
QWidget* viewport_container_ = nullptr;
QTreeWidget* element_tree_ = nullptr;
@@ -95,6 +112,11 @@ private:
// Per-model tree roots, keyed by model_id.
std::map<uint32_t, QTreeWidgetItem*> tree_roots_;
// Bidirectional federation_id <-> model_id map. Federation owns the
// persistent ids; SceneLoader owns the runtime model_ids.
std::unordered_map<QString, uint32_t> fed_id_to_model_id_;
std::unordered_map<uint32_t, QString> model_id_to_fed_id_;
// Display-side element registry for tree + property lookup.
std::unordered_map<uint32_t, ElementInfo> element_map_;
std::unordered_map<uint32_t, QTreeWidgetItem*> tree_items_;