mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 02:02:22 +00:00
ifcviewer: cache CoordinateOperation in sidecar (v10 -> v11)
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>
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// v9 layout (all multi-byte fields native-endian; endianness marker in header).
|
||||
// v11 layout (all multi-byte fields native-endian; endianness marker in header).
|
||||
//
|
||||
// SidecarHeader (12 bytes)
|
||||
//
|
||||
@@ -30,7 +30,12 @@
|
||||
// MeshInfo[num_meshes]
|
||||
//
|
||||
// uint32_t num_instances
|
||||
// InstanceCpu[num_instances] (already sorted by mesh_id)
|
||||
// InstanceCpu[num_instances] (already sorted by mesh_id; v10 layout)
|
||||
//
|
||||
// uint32_t has_coordinate_operation (v11+)
|
||||
// double[16] coordinate_operation_meters (v11+; column-major)
|
||||
// double project_length_to_meters (v11+)
|
||||
// double map_unit_to_meters (v11+)
|
||||
//
|
||||
// uint32_t num_elements
|
||||
// PackedElementInfo[num_elements]
|
||||
@@ -93,6 +98,16 @@ bool writeSidecar(const std::string& ifc_path, const SidecarData& data) {
|
||||
if (!writeVec(f, data.indices)) { fclose(f); return false; }
|
||||
if (!writeVec(f, data.meshes)) { fclose(f); return false; }
|
||||
if (!writeVec(f, data.instances)) { fclose(f); return false; }
|
||||
|
||||
// v11 georef block (148 B).
|
||||
if (fwrite(&data.has_coordinate_operation, 4, 1, f) != 1) { fclose(f); return false; }
|
||||
if (fwrite(data.coordinate_operation_meters,
|
||||
sizeof(double), 16, f) != 16) { fclose(f); return false; }
|
||||
if (fwrite(&data.project_length_to_meters,
|
||||
sizeof(double), 1, f) != 1) { fclose(f); return false; }
|
||||
if (fwrite(&data.map_unit_to_meters,
|
||||
sizeof(double), 1, f) != 1) { fclose(f); return false; }
|
||||
|
||||
if (!writeVec(f, data.elements)) { fclose(f); return false; }
|
||||
|
||||
uint32_t stbl_len = static_cast<uint32_t>(data.string_table.size());
|
||||
@@ -123,6 +138,16 @@ std::optional<SidecarData> readSidecar(const std::string& ifc_path) {
|
||||
if (!readVec(f, data.indices)) return fail();
|
||||
if (!readVec(f, data.meshes)) return fail();
|
||||
if (!readVec(f, data.instances)) return fail();
|
||||
|
||||
// v11 georef block.
|
||||
if (fread(&data.has_coordinate_operation, 4, 1, f) != 1) return fail();
|
||||
if (fread(data.coordinate_operation_meters,
|
||||
sizeof(double), 16, f) != 16) return fail();
|
||||
if (fread(&data.project_length_to_meters,
|
||||
sizeof(double), 1, f) != 1) return fail();
|
||||
if (fread(&data.map_unit_to_meters,
|
||||
sizeof(double), 1, f) != 1) return fail();
|
||||
|
||||
if (!readVec(f, data.elements)) return fail();
|
||||
|
||||
uint32_t stbl_len;
|
||||
|
||||
Reference in New Issue
Block a user