mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 18:16:40 +00:00
ifcviewer: key sidecar on path stem, drop staleness check
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>
This commit is contained in:
@@ -17,16 +17,12 @@
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// v6 layout (all multi-byte fields native-endian; endianness marker in header).
|
||||
// Same sequence as v5; the only change is that vertex data is now raw bytes
|
||||
// at the 16 B/vertex quantized layout (see InstancedGeometry.h).
|
||||
//
|
||||
// v8 layout (all multi-byte fields native-endian; endianness marker in header).
|
||||
//
|
||||
// SidecarHeader (16 bytes)
|
||||
// uint64_t source_file_size
|
||||
//
|
||||
// uint32_t num_vertex_bytes
|
||||
// uint8_t[] vertex data (16 B/vertex: pos u16x3 + pad2 + oct-normal i16x2 + rgba8)
|
||||
// uint8_t[] vertex data (12 B/vertex: pos u16x3 + oct-normal i8x2 + rgba8)
|
||||
// uint32_t num_indices
|
||||
// uint32_t[] index data (mesh-local indices; base_vertex applied at draw time)
|
||||
//
|
||||
@@ -53,8 +49,20 @@ struct SidecarHeader {
|
||||
uint32_t reserved;
|
||||
};
|
||||
|
||||
// foo.ifc -> foo.ifcview
|
||||
// foo.ifcdb/ -> foo.ifcview
|
||||
// foo.ifcdb -> foo.ifcview
|
||||
// foo (no ext) -> foo.ifcview
|
||||
static std::string sidecarPath(const std::string& ifc_path) {
|
||||
return ifc_path + ".ifcview";
|
||||
std::string p = ifc_path;
|
||||
while (!p.empty() && (p.back() == '/' || p.back() == '\\')) p.pop_back();
|
||||
auto slash = p.find_last_of("/\\");
|
||||
auto dot = p.find_last_of('.');
|
||||
std::string stem = (dot != std::string::npos &&
|
||||
(slash == std::string::npos || dot > slash))
|
||||
? p.substr(0, dot)
|
||||
: p;
|
||||
return stem + ".ifcview";
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -74,16 +82,13 @@ static bool readVec(FILE* f, std::vector<T>& v) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool writeSidecar(const std::string& ifc_path,
|
||||
const SidecarData& data,
|
||||
uint64_t ifc_file_size) {
|
||||
bool writeSidecar(const std::string& ifc_path, const SidecarData& data) {
|
||||
std::string path = sidecarPath(ifc_path);
|
||||
FILE* f = fopen(path.c_str(), "wb");
|
||||
if (!f) return false;
|
||||
|
||||
SidecarHeader hdr = { SIDECAR_MAGIC, SIDECAR_VERSION, SIDECAR_ENDIAN, 0 };
|
||||
if (fwrite(&hdr, sizeof(hdr), 1, f) != 1) { fclose(f); return false; }
|
||||
if (fwrite(&ifc_file_size, 8, 1, f) != 1) { fclose(f); return false; }
|
||||
|
||||
if (!writeVec(f, data.vertices)) { fclose(f); return false; }
|
||||
if (!writeVec(f, data.indices)) { fclose(f); return false; }
|
||||
@@ -101,8 +106,7 @@ bool writeSidecar(const std::string& ifc_path,
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<SidecarData> readSidecar(const std::string& ifc_path,
|
||||
uint64_t ifc_file_size) {
|
||||
std::optional<SidecarData> readSidecar(const std::string& ifc_path) {
|
||||
std::string path = sidecarPath(ifc_path);
|
||||
FILE* f = fopen(path.c_str(), "rb");
|
||||
if (!f) return std::nullopt;
|
||||
@@ -115,10 +119,6 @@ std::optional<SidecarData> readSidecar(const std::string& ifc_path,
|
||||
hdr.version != SIDECAR_VERSION ||
|
||||
hdr.endian != SIDECAR_ENDIAN) return fail();
|
||||
|
||||
uint64_t stored_size;
|
||||
if (fread(&stored_size, 8, 1, f) != 1) return fail();
|
||||
if (stored_size != ifc_file_size) return fail();
|
||||
|
||||
SidecarData data;
|
||||
if (!readVec(f, data.vertices)) return fail();
|
||||
if (!readVec(f, data.indices)) return fail();
|
||||
|
||||
Reference in New Issue
Block a user