Files
ViewDesignEngine/include/vde/foundation/vde_format.h
T
茂之钳 4b90438315
CI / Build & Test (push) Failing after 24s
CI / Release Build (push) Failing after 31s
Build & Test / build-and-test (push) Has been cancelled
Build & Test / python-bindings (push) Has been cancelled
feat(v1.0.1): P2 improvements — TolerantEdge + .vde format + boolean fallback
P2 — TolerantEdge (ACIS):
- TolerantEdge: tube_radius, path_tolerance, is_within_tube, intersects
- detect_tolerance_conflicts: VertexInSphere/EdgeInTube/FaceGap
- resolve_tolerance_conflicts: auto merge vertices/edges/gaps

P2 — .vde Native Format (ACIS):
- Binary format: VdeHeader(32B), 6 SerializationSections
- save_vde/load_vde: full B-Rep topology + geometry + tolerance + attributes
- save_vde_json: debuggable JSON export

P2 — Boolean Fallback Ladder (Parasolid):
- 4-level cascade: SSI → tolerant → mesh → SDF
- Level 4 never fails (SDF + MC mathematical guarantee)
- BooleanFallbackResult with per-level diagnostics

Total: +~2650 lines across 8 files
2026-07-27 21:01:33 +08:00

244 lines
8.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
/**
* @file vde_format.h
* @brief VDE 原生格式(.vde)二进制读写
*
* VDE 原生格式是一种自包含的二进制格式,用于高效保存和加载
* B-Rep 模型的完整数据(拓扑、几何、容差、属性、建模历史)。
*
* ## 文件结构
*
* ```
* VdeHeader (32 bytes)
* ├─ magic[4] = "VDE1"
* ├─ version (u32) = 1
* ├─ flags (u32)
* └─ data_offset (u32)
*
* SerializationSection 数据块:
* ├─ SECTION_TOPOLOGY — B-Rep 拓扑(V/E/L/F/S/B
* ├─ SECTION_GEOMETRY — 几何数据(顶点坐标/曲面控制点/裁剪参数/NURBS曲线)
* ├─ SECTION_TOLERANCE — ToleranceConfig
* ├─ SECTION_ATTRIBUTES — 面/边/顶点/体属性(颜色/名称/自定义数据)
* └─ SECTION_HISTORY — 建模历史 FeatureNode 列表(可选)
* ```
*
* ## 使用示例
*
* @code{.cpp}
* #include "vde/foundation/vde_format.h"
* using namespace vde::foundation;
*
* // 保存
* brep::BrepModel body = make_box(10, 5, 3);
* save_vde(body, "output.vde");
*
* // 加载
* auto loaded = load_vde("output.vde");
*
* // JSON 调试
* save_vde_json(body, "output.vde.json");
* @endcode
*
* @ingroup foundation
*/
#include "vde/brep/brep.h"
#include "vde/brep/tolerance.h"
#include "vde/brep/feature_tree.h"
#include <string>
#include <vector>
#include <cstdint>
namespace vde::foundation {
// ═══════════════════════════════════════════════════════════════
// VDE 头部
// ═══════════════════════════════════════════════════════════════
/// VDE 文件魔术字节
constexpr uint32_t VDE_MAGIC_FOURCC = 0x31454456; // "VDE1" (little-endian)
/// VDE 文件当前版本号
constexpr uint32_t VDE_FILE_VERSION = 1;
/// VDE 标志位:是否包含建模历史
constexpr uint32_t VDE_FLAG_HAS_HISTORY = 0x00000001;
/// VDE 标志位:是否包含属性数据
constexpr uint32_t VDE_FLAG_HAS_ATTRIBUTES = 0x00000002;
/// VDE 标志位:是否包含裁剪曲面
constexpr uint32_t VDE_FLAG_HAS_TRIMMED = 0x00000004;
/**
* @brief VDE 文件头(32 字节)
*
* 二进制布局(小端序):
* - 字节 03: magic "VDE1" (uint32, 0x31454456)
* - 字节 47: version (uint32)
* - 字节 811: flags (uint32)
* - 字节 1215: data_offset (uint32, 数据区起始偏移)
* - 字节 1631: reserved (16 bytes, 当前填充 0)
*/
struct VdeHeader {
uint32_t magic; ///< 魔术数字 0x31454456 ("VDE1")
uint32_t version; ///< 格式版本号
uint32_t flags; ///< 标志位(VDE_FLAG_* 组合)
uint32_t data_offset; ///< 数据区相对于文件头的偏移(字节)
uint8_t reserved[16];///< 保留字段
/// 构造默认头部(版本=1,标志=0,偏移=32)
VdeHeader();
/// 从内存解析头部
static VdeHeader parse(const uint8_t* data, size_t size);
/// 将头部编码写入缓冲区
void encode(std::vector<uint8_t>& buf) const;
/// 验证头部有效性
[[nodiscard]] bool is_valid() const;
};
// ═══════════════════════════════════════════════════════════════
// 序列化段枚举
// ═══════════════════════════════════════════════════════════════
/**
* @brief 序列化段类型标识
*
* 每个段由 [section_id:uint16][section_size:uint64][data...] 组成。
* 段按顺序写入,读取时按需跳过未知段。
*/
enum class SerializationSection : uint16_t {
SECTION_HEADER = 0, ///< 文件头(不在数据区重复)
SECTION_TOPOLOGY = 1, ///< B-Rep 拓扑(V/E/L/F/S/B
SECTION_GEOMETRY = 2, ///< 几何数据(曲面/曲线/裁剪参数)
SECTION_TOLERANCE = 3, ///< ToleranceConfig 容差配置
SECTION_ATTRIBUTES = 4, ///< 面/边/顶点/体属性
SECTION_HISTORY = 5, ///< 建模历史 FeatureNode 列表
};
// ═══════════════════════════════════════════════════════════════
// 属性数据结构
// ═══════════════════════════════════════════════════════════════
/// 顶点属性
struct VdeVertexAttribute {
int vertex_id = -1;
std::string name;
uint32_t color_rgba = 0xFFFFFFFF; ///< RGBA 颜色
std::string custom_data; ///< 自定义数据(键值对或 JSON)
};
/// 边属性
struct VdeEdgeAttribute {
int edge_id = -1;
std::string name;
uint32_t color_rgba = 0xFFFFFFFF;
std::string custom_data;
};
/// 面属性
struct VdeFaceAttribute {
int face_id = -1;
std::string name;
uint32_t color_rgba = 0xFFFFFFFF;
std::string custom_data;
};
/// 体属性
struct VdeBodyAttribute {
int body_id = -1;
std::string name;
std::string custom_data;
};
/// 属性集合
struct VdeAttributes {
std::vector<VdeVertexAttribute> vertex_attrs;
std::vector<VdeEdgeAttribute> edge_attrs;
std::vector<VdeFaceAttribute> face_attrs;
std::vector<VdeBodyAttribute> body_attrs;
};
// ═══════════════════════════════════════════════════════════════
// VDE 格式主 API
// ═══════════════════════════════════════════════════════════════
/**
* @brief 将 B-Rep 模型保存为 VDE 二进制文件
*
* 写入完整的模型数据,包括拓扑、几何、容差、属性和建模历史。
*
* @param body B-Rep 模型
* @param path 输出文件路径(.vde
* @param attrs 面/边/顶点/体属性(可选,默认空)
* @param history 建模历史节点列表(可选,默认空)
* @return true 保存成功
*
* @throws std::runtime_error 写入失败
*/
bool save_vde(const brep::BrepModel& body,
const std::string& path,
const VdeAttributes& attrs = {},
const std::vector<brep::FeatureNode>* history = nullptr);
/**
* @brief 从 VDE 二进制文件加载 B-Rep 模型
*
* 读取并解析 .vde 格式文件,恢复完整的 B-Rep 模型数据。
*
* @param path 输入文件路径(.vde
* @return 加载的 BrepModel
*
* @throws std::runtime_error 文件无效或解析失败
*/
[[nodiscard]] brep::BrepModel load_vde(const std::string& path);
/**
* @brief 从 VDE 二进制文件加载 B-Rep 模型及属性
*
* @param path 输入文件路径(.vde
* @param out_attrs 输出属性数据
* @return 加载的 BrepModel
*/
[[nodiscard]] brep::BrepModel load_vde_with_attrs(const std::string& path,
VdeAttributes& out_attrs);
/**
* @brief 将 B-Rep 模型保存为 VDE JSON 文件(可调试格式)
*
* 以人类可读的 JSON 格式导出模型数据,方便调试和检查。
* JSON 版本不包含二进制段,而是以键值对形式组织。
*
* @param body B-Rep 模型
* @param path 输出文件路径(.vde.json 或 .json
* @param attrs 属性数据(可选)
* @return true 保存成功
*/
bool save_vde_json(const brep::BrepModel& body,
const std::string& path,
const VdeAttributes& attrs = {});
/**
* @brief 将 B-Rep 模型序列化为 VDE 二进制缓冲区
*
* @param body B-Rep 模型
* @param attrs 属性数据(可选)
* @param history 建模历史节点(可选)
* @return 二进制数据
*/
[[nodiscard]] std::vector<uint8_t> serialize_vde(
const brep::BrepModel& body,
const VdeAttributes& attrs = {},
const std::vector<brep::FeatureNode>* history = nullptr);
/**
* @brief 从二进制缓冲区反序列化 VDE 模型
*
* @param data 二进制数据
* @return 加载的 BrepModel
*/
[[nodiscard]] brep::BrepModel deserialize_vde(const std::vector<uint8_t>& data);
} // namespace vde::foundation