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>
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>
The viewer can now open a .rdb directory (as produced by
RocksDbSerializer / convert_path_to_rocksdb) anywhere it accepts an
.ifc file. The full GUI gets an "Add Database..." File menu entry
that opens a directory chooser; the streamer lets the file
constructor autodetect the format and opens the store read-only so
multiple viewers can share a database without taking the exclusive
RocksDB lock.
Parallel mapping on RocksDB-backed files still produces
non-deterministic shape counts (the race is outside the instance
cache), so force num_threads=1 for the iterator when the storage is
RocksDB. Serial RocksDB (~2.6s) and parallel SPF (~0.7s) both
produce 107 shapes on AC20-FZK-Haus; @todo in-source points at the
remaining thread-safety work.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Previously readSidecar/writeSidecar were keyed on (path, file_size) with
staleness rejected at read time. Switch to pure path-stem keying: foo.ifc
and foo.ifcdb/ both resolve to foo.ifcview, so the same cache serves either
source format. Staleness is user-managed (delete the sidecar to force a
rebuild), which also lets sidecars be copied or moved independently of the
source.
v8 header drops the source_file_size field.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Handle streamer success, failure, and cancellation as distinct terminal states so failed or cancelled loads do not finalize as successful models. Clean up partial model/UI state in the full and minimal viewer apps when a load is cancelled or fails.
Generated with the assistance of an AI coding tool.
MainWindow and MinimalWindow each carried ~150 lines of mirrored
load-queue, sidecar-thread, streamer-wiring, and ID-rebase code. Lift
all of it into a SceneLoader QObject in the library; both apps now
consume it via signals. Sidecar writes stay on the full-app side since
they need the consumer's element metadata strings.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Turn src/ifcviewer into libIfcViewer.so holding the rendering engine +
geometry pipeline (ViewportWindow, GeometryStreamer, BvhAccel,
InstancedGeometry, SidecarCache, LodBuilder, AppSettings). Move the
existing UI shell (MainWindow, SettingsWindow, main.cpp) into
src/ifcviewer-full as the IfcViewerFull executable. Add a new
src/ifcviewer-minimal target with a MinimalWindow that hosts only the
viewport and reuses the sidecar fast-path for benchmark/debug runs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>