ifcviewer: load rdb/ifc as property data source on sidecar hit

Sidecar hits skipped opening the underlying .rdb/.ifc, so ifcFile() was
null and the property panel only showed cached name/type/guid. Now, after
a sidecar hit, a background thread opens <stem>.rdb (preferred) or
<stem>.ifc and hands the file to GeometryStreamer via setIfcFile(), with
a dataSourceReady signal so the UI refreshes the current selection.

Gated behind a new AppSettings::loadDataSource toggle (default on) so
users can opt into geometry-only viewing; when off, the sidecar-hit
thread is skipped and the stream-path ifc_file_ is released after
the sidecar write completes.

Also adds *.ifcview to the Add Files dialog filter so a cache can be
opened directly without its source file present.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-04-24 13:45:04 +10:00
parent eea2398e07
commit 8f7c8dc1d2
10 changed files with 153 additions and 1 deletions
+11
View File
@@ -77,6 +77,11 @@ signals:
std::string string_table);
void loadedFromSidecar(uint32_t mid, qint64 elapsed_ms);
// Fired after a sidecar-hit model has its .rdb/.ifc opened as a
// property data source in the background. Consumers can refresh
// any UI that queries ifcFile(mid) for attributes/properties.
void dataSourceReady(uint32_t mid);
// Fired repeatedly while streaming, as the worker thread produces
// elements. Each batch contains whatever accumulated since the last
// poll tick.
@@ -113,7 +118,9 @@ private:
void startNextLoad();
void connectStreamer(GeometryStreamer* streamer);
void joinSidecarThread();
void joinDataSourceThreads();
void applySidecarData(uint32_t mid, SidecarData data);
void startDataSourceLoad(uint32_t mid);
ViewportWindow* viewport_ = nullptr;
std::map<uint32_t, Entry> models_;
@@ -122,6 +129,10 @@ private:
uint32_t next_object_id_ = 1;
uint32_t loading_model_id_ = 0;
std::thread sidecar_read_thread_;
// One thread per sidecar-hit model while its .rdb/.ifc opens in the
// background. Joined only at destruction so a slow SPF parse on model
// A never blocks the sidecar-hit path of model B.
std::vector<std::thread> data_source_threads_;
QTimer element_poll_timer_;
};