Use IfcMapConversion.Scale as the source of truth for converting map coordinates to metres, instead of deriving that scale from IfcProjectedCRS.MapUnit. Bump the sidecar version because cached georef matrices and unit scales may differ under the new interpretation.
Generated with the assistance of an AI coding tool.
Keep placement transformations in double precision through streaming, sidecar caching, and viewport recomposition so large coordinates can be cancelled before the final GPU float upload.
Generated with the assistance of an AI coding tool.
Previously, applyCoordinateOperationToViewport — which pushes both
CoordinateOperation and ModelTransformation — was only called on
paths that required the IFC source to be loaded
(onLoadedFromStream and onDataSourceReady). Sidecar-only loads
(loadDataSource off, or no .ifc/.rdb sibling) silently lost both
stages.
Cache the per-model georef + unit scales in the sidecar itself so
the IFC source isn't needed to apply them:
SidecarData gains
coordinate_operation_meters[16] // column-major
project_length_to_meters
map_unit_to_meters
has_coordinate_operation
148 B fixed block written/read between instances and elements.
SIDECAR_VERSION 10 -> 11; existing sidecars rebuild on next load.
MainWindow::writeSidecarForModel populates the block from
loader_->modelGeoref(mid) before writeSidecar.
SceneLoader::applySidecarData restores it into the model's
ModelGeoref + sets has_georef = true, so subsequent
loader_->modelGeoref(mid) calls return the cached data without
needing the IFC.
MainWindow::onLoadedFromSidecar now calls
applyCoordinateOperationToViewport(mid) directly — both
CoordinateOperation and ModelTransformation land at sidecar-load
time, no longer waiting on a possibly-never-arriving data source.
Edits to the IFC's IfcMapConversion don't invalidate the cache —
delete the .ifcview manually if the source's georef changes. This
matches the existing cache-invalidation contract.
Tests: round-trip the new fields through the existing sidecar
fixture; assert SIDECAR_VERSION == 11.
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.