#pragma once /** * @file topology_compression.h * @brief B-Rep 拓扑压缩 & Edgebreaker 三角网格压缩 & 顶点量化 * * 三类压缩策略: * 1. B-Rep 拓扑压缩 — 将 BrepModel 的拓扑结构序列化为紧凑二进制格式 * 2. Edgebreaker — 三角网格连通性无损压缩(CLERS 编码) * 3. 顶点坐标量化 — 将浮点坐标压入定点整数区间 * * @ingroup core */ #include "vde/core/point.h" #include "vde/brep/brep.h" #include "vde/mesh/halfedge_mesh.h" #include #include #include namespace vde::core { // ═══════════════════════════════════════════════════════════ // B-Rep 拓扑压缩 // ═══════════════════════════════════════════════════════════ /** * @brief B-Rep 拓扑压缩结果 */ struct BrepCompressed { std::vector data; ///< 压缩二进制数据 size_t body_count; ///< Body 数量 size_t face_count; ///< Face 总数 size_t edge_count; ///< Edge 总数 size_t vertex_count; ///< Vertex 总数 size_t original_bytes; ///< 原始估算字节数 double compression_ratio; ///< 压缩比 (compressed/original) }; /** * @brief 压缩 BrepModel 为紧凑二进制格式 * * 将拓扑连接关系压入变长整数,几何数据独立存储。 * * @param body BrepModel 引用 * @return BrepCompressed 压缩结果 * @ingroup core */ BrepCompressed compress_brep(const vde::brep::BrepModel& body); /** * @brief 解压为 BrepModel * * @param data 压缩数据 * @return 重构的 BrepModel * @ingroup core */ vde::brep::BrepModel decompress_brep(const BrepCompressed& data); // ═══════════════════════════════════════════════════════════ // Edgebreaker 三角网格压缩 // ═══════════════════════════════════════════════════════════ /// CLERS 操作码 enum class EdgebreakerOp : uint8_t { C = 0, ///< C — 封闭边界环 L = 1, ///< L — 左相邻面 E = 2, ///< E — 对面顶点 R = 3, ///< R — 右相邻面 S = 4 ///< S — 分裂操作 }; /** * @brief Edgebreaker 压缩结果 */ struct EdgebreakerResult { std::vector clers; ///< CLERS 操作序列 std::vector vertices; ///< 解压所需顶点偏移(S/E 操作附参) size_t face_count; ///< 面数 size_t vertex_count; ///< 顶点数 }; /** * @brief 使用 Edgebreaker 压缩三角网格连通性 * * 输入网格的连通性(面索引),输出 CLERS 操作序列。 * 仅压缩拓扑,不含几何坐标。 * * @param mesh 三角网格 * @return EdgebreakerResult * @ingroup core */ EdgebreakerResult edgebreaker_compress(const vde::mesh::HalfedgeMesh& mesh); /** * @brief Edgebreaker 解压 * * 从 CLERS 序列重建三角网格连通性。 * * @param result Edgebreaker 压缩结果 * @return 重建的三角网格(仅拓扑,顶点坐标为占位) * @ingroup core */ vde::mesh::HalfedgeMesh edgebreaker_decompress(const EdgebreakerResult& result); // ═══════════════════════════════════════════════════════════ // 顶点坐标量化压缩 // ═══════════════════════════════════════════════════════════ /// 量化模式 enum class QuantMode { Uniform8, ///< 8 位均匀量化(每分量 1 字节) Uniform16, ///< 16 位均匀量化(每分量 2 字节) Uniform32, ///< 32 位均匀量化(每分量 4 字节) }; /** * @brief 顶点量化结果 */ struct VertexQuantResult { std::vector data; ///< 量化后的字节数据 Point3D bbox_min; ///< 包围盒最小点 Point3D bbox_max; ///< 包围盒最大点 QuantMode mode; ///< 量化模式 size_t vertex_count; ///< 顶点数 double max_error; ///< 最大量化误差 double avg_error; ///< 平均量化误差 }; /** * @brief 顶点坐标量化压缩 * * 将顶点坐标相对于包围盒的浮点值映射到 [0, 2^bits-1] 整数区间。 * * @param vertices 顶点坐标列表 * @param mode 量化模式(决定每分量位数) * @return VertexQuantResult * @ingroup core */ VertexQuantResult quantize_vertices(const std::vector& vertices, QuantMode mode = QuantMode::Uniform16); /** * @brief 顶点坐标反量化 * * @param result 量化结果 * @return 还原的顶点坐标 * @ingroup core */ std::vector dequantize_vertices(const VertexQuantResult& result); } // namespace vde::core