From 9e9d66451177950c7f78f52fcaaacecb871858e4 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Mon, 17 Nov 2025 18:25:51 +0100 Subject: [PATCH] .glb --separate-z-up-node option --- src/ifcgeom/ConversionSettings.h | 2 +- src/ifcgeom/GeometrySerializer.h | 9 ++++++-- src/serializers/GltfSerializer.cpp | 36 +++++++++++++++++++----------- src/serializers/GltfSerializer.h | 2 +- 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/ifcgeom/ConversionSettings.h b/src/ifcgeom/ConversionSettings.h index 720d25ba66..eb405a9e7c 100644 --- a/src/ifcgeom/ConversionSettings.h +++ b/src/ifcgeom/ConversionSettings.h @@ -647,7 +647,7 @@ namespace ifcopenshell { }; class Settings : public SettingsContainer< - std::tuple + std::tuple > {}; } diff --git a/src/ifcgeom/GeometrySerializer.h b/src/ifcgeom/GeometrySerializer.h index deef2c59c2..d8d4605de5 100644 --- a/src/ifcgeom/GeometrySerializer.h +++ b/src/ifcgeom/GeometrySerializer.h @@ -87,12 +87,17 @@ inline namespace settings { static constexpr const char* const description = "Use a geometrical section rather than full polyhedral output and footprint in TTL WKT"; static constexpr bool defaultvalue = false; }; + + struct SeparateZUpNode : public SettingBase { + static constexpr const char* const name = "separate-z-up-node"; + static constexpr const char* const description = "Introduce a separate Z-Up node into the GlTF hierarchy instead of multiplying the transform into the root node matrices"; + static constexpr bool defaultvalue = false; + }; } class SerializerSettings : public SettingsContainer < // @todo should we use tuple_cat here to unify the settings into a single class? - std::tuple -> + std::tuple> {}; } diff --git a/src/serializers/GltfSerializer.cpp b/src/serializers/GltfSerializer.cpp index 12627e0b39..3627106f42 100644 --- a/src/serializers/GltfSerializer.cpp +++ b/src/serializers/GltfSerializer.cpp @@ -215,7 +215,7 @@ void GltfSerializer::write(const IfcGeom::TriangulationElement* o) { json parent_node = json::object(); std::array matrix_flat; - if (settings_.get().get() || !is_root) { + if (settings_.get().get() || settings_.get().get() || !is_root) { // y-up transform is only accounted for on root matrix_flat = { mm(0,0), mm(1,0), mm(2,0), mm(3,0), @@ -258,7 +258,7 @@ void GltfSerializer::write(const IfcGeom::TriangulationElement* o) { json node; { std::array matrix_flat; - if (settings_.get().get() || !o->parents().empty()) { + if (settings_.get().get() || settings_.get().get() || !o->parents().empty()) { // y-up transform is only accounted for on root matrix_flat = { m(0,0), m(1,0), m(2,0), m(3,0), @@ -411,20 +411,30 @@ void write_block(std::ostream& fs, It begin, It end) { } void GltfSerializer::finalize() { + // separate z up + if (settings_.get().get()) { + z_up_transform_ = json::object(); + (*z_up_transform_)["name"] = "Z_UP"; + static const std::array z_up_matrix = { + 1, 0, 0, 0, + 0, 0, -1, 0, + 0, 1, 0, 0, + 0, 0, 0, 1}; + (*z_up_transform_)["matrix"] = z_up_matrix; + (*z_up_transform_)["children"] = roots_; + json_["nodes"].push_back(*z_up_transform_); + } + if (north_rotation_) { - (*north_rotation_)["children"] = json::array(); - for (int i = 0; i < json_["nodes"].size(); ++i) { - (*north_rotation_)["children"].push_back(i); - } - json_["nodes"].push_back(*north_rotation_); + (*north_rotation_)["children"] = roots_; } if (ecef_transform_) { - (*ecef_transform_)["children"] = json::array(); - for (int i = 0; i < json_["nodes"].size(); ++i) { - (*ecef_transform_)["children"].push_back(i); - } - json_["nodes"].push_back(*ecef_transform_); + (*ecef_transform_)["children"] = roots_; + } + + if (z_up_transform_) { + (*ecef_transform_)["children"] = roots_; } tmp_fstream1_.close(); @@ -447,7 +457,7 @@ void GltfSerializer::finalize() { json scene_0; if (geometry_settings().get().get()) { scene_0["nodes"] = roots_; - } else if (north_rotation_ || ecef_transform_) { + } else if (north_rotation_ || ecef_transform_ || z_up_transform_) { scene_0["nodes"] = std::array{json_["nodes"].size() - 1}; } else { scene_0["nodes"] = node_array_; diff --git a/src/serializers/GltfSerializer.h b/src/serializers/GltfSerializer.h index e08f2b55f1..d3754d90a0 100644 --- a/src/serializers/GltfSerializer.h +++ b/src/serializers/GltfSerializer.h @@ -36,7 +36,7 @@ private: std::ofstream fstream_, tmp_fstream1_, tmp_fstream2_; std::map materials_, meshes_; json json_, node_array_; - boost::optional ecef_transform_, north_rotation_; + boost::optional ecef_transform_, north_rotation_, z_up_transform_; int bufferViewId; std::map node_indices_; std::vector roots_;