Per aothms's request on #8605: QtViewer is being superseded by the new
Bonsai Viewer, so its remains are deleted here (src/qtviewer, its
BUILD_QTVIEWER cmake option and add_subdirectory, and its references in
ci.yml's path filter, .gitignore, the conda recipe's license table, and
README's library table).
src/ifcopenshell-python/ifcopenshell/geom/app.py's qtViewer3d is
unrelated (pythonocc-core's own OCC.Display widget class, a name
coincidence) and is untouched.
Generated with the assistance of an AI coding tool.
IfcConvert --version reported 0.8.0 on a plain source build even though the
VERSION file says 0.8.6 (#8164). buildinfo.cpp already falls back to the
IFCOPENSHELL_VERSION_STRING macro and CMake already passes it as
${RELEASE_VERSION}, but RELEASE_VERSION was only read from the VERSION file
when VERSION_OVERRIDE was on. A default build (VERSION_OVERRIDE off,
ADD_COMMIT_SHA off, as the nixpkgs package builds it) fell through to the
hardcoded "0.8.0", so the fallback macro carried the stale value.
Read the VERSION file unconditionally so RELEASE_VERSION is always the real
version. VERSION_OVERRIDE still governs the branch name embedded when
ADD_COMMIT_SHA is on, and project()/CPack now also reflect the true version.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
When ADD_COMMIT_SHA is off (the default for release tarballs), buildinfo.cpp
fell back to a hardcoded "0.8.0", so a 0.8.5/0.8.6 build reported 0.8.0 from
IfcConvert --version and in written file headers. Pass CMake's RELEASE_VERSION
(read from the VERSION file) to IfcParse as IFCOPENSHELL_VERSION_STRING and use
it as the fallback, mirroring how the branch/commit defines are handled. The
commit-sha build and the last-resort literal are unchanged.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Some distributions (e.g. Fedora) ship only a shared RocksDB that exports
RocksDB::rocksdb-shared rather than RocksDB::rocksdb. The CMake target
selection now falls back to the shared target when the static one is absent.
Newer RocksDB also changed DB::Open and DB::OpenForReadOnly to take
std::unique_ptr<DB>* instead of DB**. IfcFile.cpp uses SFINAE tag dispatch
to build against both old and new APIs without version detection.
Some distributions (e.g. Fedora) ship only a shared RocksDB that exports
RocksDB::rocksdb-shared rather than RocksDB::rocksdb. The CMake target
selection now falls back to the shared target when the static one is absent.
Newer RocksDB also changed DB::Open and DB::OpenForReadOnly to take
std::unique_ptr<DB>* instead of DB**. IfcFile.cpp uses SFINAE tag dispatch
to build against both old and new APIs without version detection.
When HDF5 is found via its CMake config file, the code previously hardcoded
the hdf5_cpp-static target. On distributions that ship only shared HDF5
(e.g. Fedora rawhide where the config file was added in a newer package),
this caused a link failure. Now checks for hdf5_cpp-static, hdf5_cpp-shared,
and hdf5::hdf5_cpp-shared in order, falling back to module-mode discovery.
Unit / Geolocation / Placement are schema-agnostic IFC helpers ported
from ifcopenshell.util.{unit,geolocation,placement}. Nothing about
them is viewer-specific: pure IfcParse + Eigen, no Qt, no IfcGeom, no
renderer. Living under src/ifcviewer/ implies an unwanted dependency
direction every time a non-viewer caller (test_federation, the bonsai
SettingsView georef readout, a future standalone IFC tool) wants to
use them.
Move them to a new `src/ifcutil/` static lib (IfcUtil). The lib has
PUBLIC `target_include_directories(${CMAKE_CURRENT_SOURCE_DIR})` so
callers that link IfcUtil can keep `#include "Unit.h"` etc. without
relative-path adjustments — the include dir propagates transitively
via IfcViewer's PUBLIC link.
## Changes
* `git mv src/ifcviewer/{Geolocation,Placement,Unit}.{h,cpp}
→ src/ifcutil/` (history follows the rename).
* `src/ifcutil/CMakeLists.txt`: IfcUtil static lib, PUBLIC links
IfcParse + Eigen3::Eigen, PUBLIC include dir.
* `cmake/CMakeLists.txt`: `add_subdirectory(../src/ifcutil ifcutil)`
before ifcviewer/ so the link target exists when IfcViewer's
CMakeLists runs.
* `src/ifcviewer/CMakeLists.txt`: IfcUtil added to IfcViewer's PUBLIC
link_libraries.
* `src/ifcviewer/tests/CMakeLists.txt`: test_federation drops the
explicit `${IFCVIEWER_SRC}/{Unit,Geolocation,Placement}.cpp`
source list and links `IfcUtil` instead (matches how production
code resolves the symbols).
* `src/bonsaiviewer/modules/models/SettingsView.cpp`: the two
explicit `#include "../../../ifcviewer/{Geolocation,Unit}.h"`
paths swap to `../../../ifcutil/…`. All other callers use bare
`#include "Unit.h"` style and continue to work via the propagated
include dir.
## Verification
* `ninja -C build-viewer` builds clean: IfcUtil + IfcViewer +
IfcViewerMinimal + BonsaiViewer + all four pre-existing
ifcviewer tests + the two from-wgpu tests.
* `test_federation` runs green: 226 assertions in 22 test cases
pass with IfcUtil linked instead of the explicit-source compile.
* `git log --follow` traces e.g. `Geolocation.cpp` back through the
rename to its prior location in src/ifcviewer/.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The GL backend is gone (task #53). The wgpu/non-wgpu folder split and
the Wgpu* class prefix were both disambiguation artefacts from the
overlap period — now pure dead weight.
## Folder + library merge
* `src/ifcviewer-wgpu/` → folded into `src/ifcviewer/` (git mv tracks
every file as a rename so blame/log history survives).
* `src/ifcviewer-wgpu-minimal/` → `src/ifcviewer-minimal/` (the exe was
already named `IfcViewerMinimal`; this just brings the folder + CMake
target name into line).
* `src/ifcviewer-wgpu/tests/test_wgpu_{selection,visibility}.cpp` →
`src/ifcviewer/tests/test_{selection,visibility}.cpp`, folded into
the existing `add_ifcviewer_unit_test(...)` helper.
* The `IfcViewerWgpu` static library is dissolved — its sources become
part of the unified `IfcViewer` static library, which now bundles
scene/loader + renderer in one target. The pre-merge circular
dependency (IfcViewer linking IfcViewerWgpu just to get the
ViewportWindow.h include path that SceneLoader.h needs) goes away.
* The wgpu-native FetchContent block, the Cocoa/QuartzCore link on
Apple, the OBJCXX-enabled `.mm` source, and the wgpu-native runtime
install all move into `src/ifcviewer/CMakeLists.txt` unchanged.
## Type renames (Wgpu prefix dropped from every Wgpu* identifier)
WgpuAreaMeasurement → AreaMeasurement
WgpuBufferPool → BufferPool
WgpuLengthMeasurement → LengthMeasurement
WgpuMetalSurface → MetalSurface
WgpuModelGpuData → ModelGpuData
WgpuOverlayFrame → OverlayFrame
WgpuOverlayRenderer → OverlayRenderer
WgpuSectionPlane → SectionPlane
WgpuSelectionState → SelectionState
WgpuStreamingLoader → StreamingLoader
WgpuStreamingThread → StreamingThread
WgpuViewportWindow → ViewportWindow
WgpuVisibilityState → VisibilityState
CMake target IfcViewerWgpuMinimal → IfcViewerMinimal (exe name was
already this since wgpu shipped as default).
Deliberately kept: `onWgpuLog` (wgpu-native log callback — names a
binding to an external API, not one of *our* types), and the WGPU*
enum/struct prefixes from wgpu-native's own headers. `WgpuMemProbe`
lives in the separate `src/wgpu-mem-probe/` standalone diagnostic
project and isn't touched.
## Include-path updates
Every `#include "../ifcviewer-wgpu/Wgpu<X>.h"` → `"../ifcviewer/<X>.h"`,
every in-directory `#include "Wgpu<X>.h"` → `"<X>.h"`. Includes from
sibling subdirectories (modules/, etc.) are updated to point at
`../../../ifcviewer/` instead of `../../../ifcviewer-wgpu/`.
## cmake/CMakeLists.txt simplification
The redundant `add_subdirectory(ifcviewer-wgpu)` blocks (one inside
the BUILD_BONSAIVIEWER fan-in, one in the BONSAIVIEWER-less standalone
block) collapse into a single unconditional
`add_subdirectory(../src/ifcviewer ifcviewer)`. The standalone block
keeps only `wgpu-mem-probe` (the diagnostic tool, unrelated to the
viewer lib).
## Verification
* Full build green: `IfcViewer` static lib, `IfcViewerMinimal` exe,
`BonsaiViewer` exe, all four pre-existing ifcviewer unit tests, and
the two new-location tests (`test_selection`, `test_visibility`).
* No stray `Wgpu<X>` identifier remains across `src/ifcviewer/`,
`src/bonsaiviewer/`, `src/ifcviewer-minimal/` (verified by grep).
* Renames tracked by git as `R` entries — `git log --follow` on
ViewportWindow.cpp etc. continues to show history through the move.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Lightweight workflow that compiles IfcViewerWgpu (the static lib) on
macOS arm64 + runs the wgpu state tests. Skips IfcViewerWgpuMinimal
because createSurface has no Metal path yet (task #32); the platform
surface blocks in WgpuViewportWindow.cpp are wrapped in
#if defined(Q_OS_LINUX) so the lib itself compiles cleanly on macOS.
Goal: catch portability regressions in the wgpu source on Apple
Silicon without paying for build_osx.yml's full IfcGeom + OCCT +
Python wheel pipeline. ~5 min vs hours.
Triggers on push/PR that touches src/ifcviewer-wgpu, the shared
headers it depends on, the top-level CMake, or this workflow itself.
Also workflow_dispatch for manual runs.
Hoists the Catch2 fetch in cmake/CMakeLists.txt out of the
BUILD_BONSAIVIEWER gate so the standalone wgpu config
(BUILD_BONSAIVIEWER=OFF + BUILD_BONSAIVIEWER_WGPU=ON +
BUILD_BONSAIVIEWER_TESTS=ON) can build tests without dragging the
whole bonsai/IfcGeom tree in. Default remains OFF, so default builds
stay offline-capable.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bonsai now drives the wgpu viewport for both sidecar and direct-IFC
loads. The GL viewer and its supporting state classes are gone.
SceneLoader rewire:
- Takes WgpuViewportWindow* instead of ViewportWindow*.
- Sidecar path reads metadata only (readSidecarMetadataOnly) and hands
the StreamingSidecar off to the new applyCachedModel. Field accesses
inside applySidecarData go through .meta.
- Direct-IFC path uses the wgpu A-path (upload{Mesh,Instance}Chunk +
finalizeModel). The applyLodExtension call is dropped — wgpu has no
live LOD1 splice; LOD1 still lands in the on-disk sidecar for the
next open.
Bonsai migration:
- ViewportWindow → WgpuViewportWindow across MainWindow, Measurement,
SessionState, and every modules/*/{Commands,Panel,View}.{h,cpp} —
116 sites total. Same s/OverlayRenderer::/WgpuOverlayRenderer::/
rename, 12 sites.
- Includes flipped from ../ifcviewer/ViewportWindow.h to
../ifcviewer-wgpu/WgpuViewportWindow.h. OverlayRenderer.h include
dropped (transitively reached via the viewport header).
- BonsaiViewer links IfcViewerWgpu in addition to IfcViewer for the
duration of the migration; the GL-side IfcViewer also publicly links
IfcViewerWgpu so SceneLoader can resolve WgpuViewportWindow.
GL backend deletion:
- src/ifcviewer/ViewportWindow.{cpp,h}, BvhAccel.*, OverlayRenderer.*,
Selection.*, Visibility.* all gone.
- src/ifcviewer-minimal/ removed entirely (MinimalWindow drove the GL
viewport).
- src/ifcviewer/tests: test_bvh_accel, test_selection, test_visibility
removed. The first has no replacement (wgpu doesn't use a per-instance
BVH); the latter two are ported separately. test_lod_builder,
test_sidecar_cache, test_instanced_geometry, test_federation remain
(backend-agnostic).
- IfcViewer's CMakeLists drops OpenGL, Qt::OpenGL, Qt::Widgets — none
of the surviving translation units reach for them.
Build flag plumbing:
- BUILD_BONSAIVIEWER now auto-enables BUILD_BONSAIVIEWER_WGPU since
SceneLoader requires the wgpu lib for its WgpuViewportWindow* arg.
- The wgpu subprojects add_subdirectory ahead of the GL one so
IfcViewerWgpu exists when IfcViewer's link evaluates.
- src/ifcviewer-minimal subdir reference removed from cmake/CMakeLists.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
New headless wgpu probe app — no Qt, no surface, just initializes a
device and stress-tests buffer allocations. Reports:
1. Adapter + device limits (maxBufferSize, maxStorageBufferBindingSize).
2. Single-allocation probe: descending sizes, each released, finds
the largest single buffer the driver will grant.
3. Cumulative probe: halve-on-failure, finds total VRAM the runtime
will let us park behind one device across multiple sub-buffers.
4. Fixed-size cumulative probe: 1 GB / 512 MB / 256 MB uniform sizes,
to detect whether the "big-first" strategy leaves VRAM on the table.
Findings on a GTX 1650 (4 GB physical) + wgpu-native + Vulkan:
- maxStorageBufferBindingSize = 2 GB (driver cap, not wgpu-native).
- Any single storage buffer > 2 GB is REFUSED.
- Total available across N sub-buffers = ~3 GB, INVARIANT under
allocation pattern (2+1+0.06, 3×1 GB, 6×512 MB, 12×256 MB all
reach 3.00 GB). Driver hands out a fixed VRAM slice; pattern
doesn't matter.
- Remaining ~1 GB is held by the desktop compositor + OS.
- GL's higher "4 GB+ resident" claim is overcommit into host RAM,
which wgpu/Vulkan don't do.
The +50% (2 → 3 GB) improvement is real and worth chasing — a
follow-up halve-on-failure addSubBuffer in WgpuBufferPool will
extract that on this card. On 8/16/24 GB GPUs the same code gets
us proportionally more.
Build: ninja -C build-viewer-wgpu WgpuMemProbe
Run: ./build-viewer-wgpu/wgpu-mem-probe/WgpuMemProbe
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds src/ifcviewer-wgpu/ and src/ifcviewer-wgpu-minimal/ behind a new
BUILD_BONSAIVIEWER_WGPU option (default OFF), gated independently of
BUILD_BONSAIVIEWER. Stage 1 brings up a Qt window with a wgpu-native
v29 surface (X11) and clears to the background colour — no rendering
beyond that yet. Mirrors the lifecycle of the GL ViewportWindow so
subsequent stages (vertex-pulling renderer, pick, cull, HiZ, overlay)
slot in without restructuring the host.
wgpu-native is fetched as a pre-built binary release via FetchContent;
its .so SONAME is patched in at configure time so dependents get a
clean DT_NEEDED. The X11 native handle is obtained via the public
QNativeInterface::QX11Application API; Wayland and macOS/Windows
surface creation are stubbed with explicit "not wired yet" warnings.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace the old IFC viewer build switch with BUILD_BONSAIVIEWER in CMake, the Linux workflows, and the nix build script.
Generated with the assistance of an AI coding tool.
Directory src/ifcviewer-full -> src/bonsaiviewer, CMake target
IfcViewerFull -> BonsaiViewer, namespace ifcviewerfull -> bonsaiviewer,
QApplication / window titles / connector path now use the new brand.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Wire the AddModelDialog "Convert IFC File to Database" button to a new
ConvertToDatabase source mode handled by ModelsPanelController, which
prompts for an .ifc input and .rdb output then runs the existing
document_serializer_registry "rdb" plugin on a background QThread with
a modal progress dialog.
Build the src/serializers subdir for BUILD_IFCVIEWER so the rdb plugin
is produced, and align serializer plugin runtime output with the
kernel/mapping plugins by writing them into $<TARGET_FILE_DIR:IfcGeom>
so default plugin discovery finds them in both dev and install layouts.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Covers the pure-logic modules with no Qt event loop or GL context: BVH
build, LOD decimation, sidecar round-trip, instanced-geometry layout
constants, and Federation save/load + relative-path policy. Each test
binary compiles only the production source(s) under test, so the unit
tier doesn't pull Qt/OpenCASCADE/IfcGeom into the test build.
Gated behind BUILD_IFCVIEWER_TESTS=OFF; default builds remain offline.
Catch2 v3.5.4 is fetched on demand via FetchContent.
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>