Files
茂之钳 853070f668
CI / Build & Test (push) Failing after 33s
CI / Release Build (push) Failing after 26s
Build & Test / build-and-test (push) Has been cancelled
Build & Test / python-bindings (push) Has been cancelled
feat(v11.3): binary format support — Parasolid XT binary + ACIS SAB + JT binary
- industrial_formats.h: +46 lines (XtBinaryHeader, SabHeader, JtSegmentHeader structs + binary API)
- industrial_formats.cpp: +310 lines (XT binary encode/decode, SAB parse, JT binary stream, auto-detect)
- test_industrial_formats.cpp: +187 lines (12 binary tests)
- 44/44 tests passing, zero regressions

Auto-detect: magic bytes check before text parsing for all formats
2026-07-27 01:37:29 +08:00

431 lines
14 KiB
C++
Raw Permalink 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 industrial_formats.h
* @brief 工业 CAD 格式导入导出
*
* 支持的格式:
* - JT (ISO 14306) — Siemens PLM 轻量化/精确几何
* - Parasolid XT — Siemens 内核原生格式
* - ACIS SAT — Dassault Spatial 内核原生格式
* - IFC (ISO 16739) — BIM 交换格式
* - STEP AP242 — 带 PMI 的产品制造信息
* - PDF 3D — 嵌入式 U3D/PRC
*
* @ingroup foundation
*/
#include "vde/brep/brep.h"
#include <string>
#include <vector>
#include <cstdint>
namespace vde::io {
// ═══════════════════════════════════════════════════════════════
// JT (ISO 14306)
// ═══════════════════════════════════════════════════════════════
/**
* @brief JT 文件段类型
*
* JT 文件由 LSG (Logical Scene Graph) 组织,包含多个段。
*/
enum class JTSegmentType : uint8_t {
LogicalSceneGraph = 1, ///< LSG 根段
Part = 2, ///< 零件段
Instance = 3, ///< 实例引用段
MeshLOD = 4, ///< 网格 LOD 段
Brep = 5, ///< B-Rep 精确几何段
MetaData = 6, ///< 元数据段
PMI = 7, ///< PMI 标注段
};
/**
* @brief JT 导入选项
*/
struct JTOptions {
bool load_brep = true; ///< 是否加载精确 B-Rep 几何
bool load_mesh = true; ///< 是否加载三角网格
int max_lod = 3; ///< 最大 LOD 级别
bool load_pmi = false; ///< 是否加载 PMI 标注
bool load_meta = false; ///< 是否加载元数据
};
/**
* @brief JT TOC 条目 / 段头
*
* JT 文件通过 TOC (Table of Contents) 组织段数据,
* 每个 TOC 条目定位一个段。
*/
struct JtSegmentHeader {
uint32_t segment_type; ///< 段类型 (JTSegmentType 枚举值)
uint32_t segment_offset; ///< 段数据偏移
uint32_t segment_length; ///< 段数据长度
uint32_t attributes; ///< 段属性标志
};
/**
* @brief 从 JT 文件导入 B-Rep 模型
*
* 解析 ISO 14306 JT 文件格式,提取 B-Rep 段中的精确几何或
* 将网格 LOD 转换为 BrepModel。
*
* JT 文件结构:TOC → Segment → Part/Mesh/B-Rep
*
* @param path JT 文件路径 (.jt)
* @param opts 导入选项
* @return 导入的 BrepModel
*
* @throws std::runtime_error 文件无效或无法解析
*/
[[nodiscard]] brep::BrepModel import_jt(const std::string& path,
const JTOptions& opts = {});
/**
* @brief 从内存解析 JT 二进制数据
*
* 直接解析 JT 二进制格式数据流,提取 B-Rep 段和网格 LOD。
*
* @param data 指向 JT 二进制数据的指针
* @param size 数据大小(字节)
* @param opts 导入选项
* @return 导入的 BrepModel
*
* @throws std::runtime_error 数据无效
*/
[[nodiscard]] brep::BrepModel import_jt_binary(const uint8_t* data, size_t size,
const JTOptions& opts = {});
/**
* @brief 将 B-Rep 模型导出为 JT 文件
*
* 写入包含 B-Rep 段和网格 LOD 的 JT 文件。
*
* @param body B-Rep 模型
* @param path 输出 JT 文件路径
*
* @throws std::runtime_error 写入失败
*/
void export_jt(const brep::BrepModel& body, const std::string& path);
// ═══════════════════════════════════════════════════════════════
// Parasolid XT
// ═══════════════════════════════════════════════════════════════
/**
* @brief Parasolid XT 格式类型
*/
enum class ParasolidFormat {
Binary, ///< 二进制 X_B / X_T 格式
Text, ///< 文本格式 (ASCII)
Neutral, ///< 可传输中性格式
};
// ═══════════════════════════════════════════════════════════════
// Parasolid XT 二进制结构体
// ═══════════════════════════════════════════════════════════════
/**
* @brief Parasolid XT 二进制文件头 (40 bytes)
*
* XT 二进制 (.x_b) 格式头部结构:
* - magic: "PARA" 标识符
* - version: 版本号
* - 表统计和偏移
*/
struct XtBinaryHeader {
char magic[4]; ///< "PARA" 魔术字节
uint32_t version; ///< 架构版本
uint32_t float_count; ///< 浮点数表条目数
uint32_t int_count; ///< 整数表条目数
uint32_t entity_count; ///< 实体记录数
uint32_t float_offset; ///< 浮点表偏移
uint32_t int_offset; ///< 整数表偏移
uint32_t entity_offset; ///< 实体表偏移
uint32_t endian_check; ///< 字节序标记 (0x00000001 = LE)
/// 解析头部字节
static XtBinaryHeader parse(const uint8_t* data, size_t size);
/// 编码头部为 40 字节
void encode(std::string& buf) const;
};
/**
* @brief Parasolid XT 二进制实体记录
*/
struct XtBinaryEntity {
uint32_t type; ///< 实体类型编码
uint32_t float_start, float_len; ///< 浮点表索引范围
uint32_t int_start, int_len; ///< 整数表索引范围
std::vector<uint32_t> refs; ///< 引用实体索引
};
/**
* @brief 从 Parasolid XT 文件导入 B-Rep 模型
*
* 支持二进制 (.x_b) 和文本 (.x_t) 两种格式。
* 自动检测 magic bytes 选择解析路径。
* 解析 body 实体,包括:
* - lump → shell → face → loop → edge → vertex 拓扑链
* - surface (plane, cylinder, cone, sphere, torus, NURBS)
* - curve (line, circle, ellipse, NURBS)
*
* @param path XT 文件路径 (.x_t / .x_b)
* @return 导入的 BrepModel
*
* @throws std::runtime_error 解析失败
*/
[[nodiscard]] brep::BrepModel import_parasolid_xt(const std::string& path);
/**
* @brief 从内存解析 Parasolid XT 二进制数据
*
* @param data 指向二进制 XT 数据的指针
* @param size 数据大小(字节)
* @return 导入的 BrepModel
*
* @throws std::runtime_error 数据无效
*/
[[nodiscard]] brep::BrepModel import_parasolid_xt_binary(const uint8_t* data, size_t size);
/**
* @brief 将 B-Rep 模型导出为 Parasolid XT 文本格式
*
* @param body B-Rep 模型
* @param path 输出 XT 文件路径
*/
void export_parasolid_xt(const brep::BrepModel& body, const std::string& path);
/**
* @brief 将 B-Rep 模型导出为 Parasolid XT 二进制格式(文件)
*
* @param body B-Rep 模型
* @param path 输出 XB 文件路径 (.x_b)
*/
void export_parasolid_xt_binary(const brep::BrepModel& body, const std::string& path);
/**
* @brief 将 B-Rep 模型导出为 Parasolid XT 二进制字符串
*
* @param body B-Rep 模型
* @return XT 二进制数据字符串
*/
[[nodiscard]] std::string export_parasolid_xt_binary_str(const brep::BrepModel& body);
// ═══════════════════════════════════════════════════════════════
// ACIS SAT
// ═══════════════════════════════════════════════════════════════
/**
* @brief ACIS SAT 版本
*/
enum class ACISVersion {
V7 = 700,
V16 = 1600,
V21 = 2100,
V27 = 2700,
R2024 = 2900,
};
/**
* @brief ACIS SAB 二进制文件头
*/
struct SabHeader {
char magic[4]; ///< "SAB " 魔术字节
uint32_t data_size; ///< 数据块大小
uint32_t version; ///< ACIS 版本
uint32_t str_table_size; ///< 字符串表大小
};
/**
* @brief 从 ACIS SAT 文件导入 B-Rep 模型
*
* 解析 SAT (Save As Text) 格式,支持:
* - body → lump → shell → face → loop → coedge → edge → vertex
* - surface: plane, cone, sphere, torus, spline
* - curve: straight, ellipse, intcurve
*
* @param path SAT 文件路径 (.sat 或 .sab)
* @return 导入的 BrepModel
*
* @throws std::runtime_error 解析失败
*/
[[nodiscard]] brep::BrepModel import_acis_sat(const std::string& path);
/**
* @brief 从内存解析 ACIS SAB 二进制数据
*
* SAB (Standard ACIS Binary) 格式:
* - Header: "SAB " + data_size + version + str_table_size
* - 字符串表 + 浮点数表 + 整数表 + 实体记录
*
* @param data 指向二进制 SAB 数据的指针
* @param size 数据大小(字节)
* @return 导入的 BrepModel
*
* @throws std::runtime_error 数据无效
*/
[[nodiscard]] brep::BrepModel import_acis_sat_binary(const uint8_t* data, size_t size);
/**
* @brief 将 B-Rep 模型导出为 ACIS SAT 文本格式
*
* @param body B-Rep 模型
* @param path 输出 SAT 文件路径
* @param version ACIS 版本号
*/
void export_acis_sat(const brep::BrepModel& body, const std::string& path,
ACISVersion version = ACISVersion::V27);
// ═══════════════════════════════════════════════════════════════
// IFC (ISO 16739)
// ═══════════════════════════════════════════════════════════════
/**
* @brief IFC 实体类型(常用)
*/
enum class IfcEntityType {
Unknown,
IfcProject,
IfcSite,
IfcBuilding,
IfcBuildingStorey,
IfcWall,
IfcSlab,
IfcBeam,
IfcColumn,
IfcDoor,
IfcWindow,
IfcRoof,
IfcStair,
IfcRailing,
IfcPlate,
IfcMember,
IfcBuildingElementProxy,
IfcProductDefinitionShape,
IfcShapeRepresentation,
IfcExtrudedAreaSolid,
IfcFacetedBrep,
IfcPolyLoop,
IfcFaceOuterBound,
IfcFace,
IfcClosedShell,
IfcCartesianPoint,
IfcDirection,
IfcAxis2Placement3D,
IfcLocalPlacement,
IfcPolyline,
IfcArbitraryClosedProfileDef,
IfcRectangleProfileDef,
IfcCircleProfileDef,
IfcMaterial,
IfcRelAssociatesMaterial,
IfcOwnerHistory,
IfcPerson,
IfcOrganization,
IfcApplication,
IfcUnitAssignment,
IfcSIUnit,
IfcGeometricRepresentationContext,
IfcGeometricRepresentationSubContext,
};
/**
* @brief 从 IFC 文件导入 B-Rep 模型列表
*
* 解析 IFC-SPF (ISO 10303-21) 格式,提取 IfcProduct 实体:
* - IfcWall, IfcSlab, IfcBeam, IfcColumn
* - IfcDoor, IfcWindow, IfcPlate, IfcMember
* - 支持 IfcExtrudedAreaSolid 和 IfcFacetedBrep
*
* @param path IFC 文件路径 (.ifc)
* @return 导入的 BrepModel 列表(每个产品一个元素)
*
* @throws std::runtime_error 解析失败
*/
[[nodiscard]] std::vector<brep::BrepModel> import_ifc(const std::string& path);
// ═══════════════════════════════════════════════════════════════
// STEP AP242
// ═══════════════════════════════════════════════════════════════
/**
* @brief STEP AP242 PMI 标注类型
*/
struct StepPMIAnnotation {
std::string type; ///< 标注类型(linear_dimension, angular_dimension, etc.
std::string id; ///< 标注 ID
std::string description; ///< 描述文本
double nominal_value = 0.0; ///< 名义尺寸
double upper_tolerance = 0.0; ///< 上偏差
double lower_tolerance = 0.0; ///< 下偏差
std::string datum_system; ///< 基准系统引用
};
/**
* @brief STEP AP242 导出选项
*/
struct StepAP242Options {
bool include_pmi = true; ///< 是否包含 PMI 标注
bool include_tolerance = true; ///< 是否包含公差信息
bool include_material = true; ///< 是否包含材料信息
bool include_validation = true; ///< 是否包含验证属性
};
/**
* @brief 将 B-Rep 模型导出为 STEP AP242 字符串
*
* 在 AP214 基础上扩展,新增:
* - PRODUCT_MANUFACTURING_INFORMATION (PMI)
* - DIMENSIONAL_CHARACTERISTIC_REPRESENTATION
* - SHAPE_DIMENSION_REPRESENTATION
* - GEOMETRIC_TOLERANCE
* - DATUM_SYSTEM
*
* @param bodies B-Rep 体列表
* @param annotations PMI 标注列表(可为空)
* @param opts 导出选项
* @return STEP AP242 格式字符串
*/
[[nodiscard]] std::string export_step_ap242(
const std::vector<brep::BrepModel>& bodies,
const std::vector<StepPMIAnnotation>& annotations = {},
const StepAP242Options& opts = {});
/**
* @brief 将 B-Rep 模型导出为 STEP AP242 文件
*
* @param path 输出文件路径 (.stp / .step)
* @param bodies B-Rep 体列表
* @param annotations PMI 标注
* @param opts 导出选项
*/
void export_step_ap242_file(const std::string& path,
const std::vector<brep::BrepModel>& bodies,
const std::vector<StepPMIAnnotation>& annotations = {},
const StepAP242Options& opts = {});
// ═══════════════════════════════════════════════════════════════
// PDF 3D
// ═══════════════════════════════════════════════════════════════
/**
* @brief 将 B-Rep 模型导出为 PDF 3D (U3D 嵌入)
*
* 生成包含 U3D 模型嵌入的 PDF 文件。
* U3D 是 ECMA-363 标准,支持精确几何和三角网格。
*
* @param body B-Rep 模型
* @return PDF 文件二进制数据
*/
[[nodiscard]] std::vector<uint8_t> export_pdf3d(const brep::BrepModel& body);
/**
* @brief 将 B-Rep 模型导出为 PDF 3D 文件
*
* @param path 输出 PDF 文件路径
* @param body B-Rep 模型
*/
void export_pdf3d_file(const std::string& path, const brep::BrepModel& body);
} // namespace vde::io