feat(v5-M4): industrial formats + GPU acceleration + Python bindings
M4.1 — 工业格式 (Agent #0): - JT parser: ISO 14306 Segment→Part→Mesh/LOD, XT B-Rep decode - Parasolid XT: text/binary parser, Body→BrepModel mapping - ACIS SAT: text format parser with version handling - IFC: SPF parser, IfcWall/Slab/Beam/Column entities - STEP AP242: PMI annotation + tolerance export - 47 tests covering all formats + edge cases M4.2 — GPU 加速 (Agent #1): - CUDA kernels: mc_kernel, qem_cost_kernel, tri_intersect_kernel - __constant__ memory for edge tables, atomic triangle collection - CPU fallback when CUDA unavailable (seamless degradation) - VDE_USE_CUDA CMake option, .cu compilation support - 9 tests with CPU path validation M4.3 — Python 绑定 (Agent #2): - vde_brep: BrepModel, make_*, boolean, STEP/IGES, heal, validate - vde_sdf: primitives, operations, to_mesh, gradient descent - vde_cam: roughing/finishing/drilling, Tool, ToolLibrary - vde_assembly: Assembly, AssemblyNode, interference, explode - Version: 3.3.0 synced across pyproject/setup/__init__ 13 files, ~5200 lines, 56+ tests
This commit is contained in:
@@ -1,11 +1,310 @@
|
||||
#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 {
|
||||
[[nodiscard]] brep::BrepModel import_jt(const std::string& path);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
// 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 文件导入 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 将 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, ///< 可传输中性格式
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 从 Parasolid XT 文件导入 B-Rep 模型
|
||||
*
|
||||
* 支持二进制 (.x_b) 和文本 (.x_t) 两种格式。
|
||||
* 解析 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 将 B-Rep 模型导出为 Parasolid XT 文本格式
|
||||
*
|
||||
* @param body B-Rep 模型
|
||||
* @param path 输出 XT 文件路径
|
||||
*/
|
||||
void export_parasolid_xt(const brep::BrepModel& body, const std::string& path);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
// ACIS SAT
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* @brief ACIS SAT 版本
|
||||
*/
|
||||
enum class ACISVersion {
|
||||
V7 = 700,
|
||||
V16 = 1600,
|
||||
V21 = 2100,
|
||||
V27 = 2700,
|
||||
R2024 = 2900,
|
||||
};
|
||||
|
||||
/**
|
||||
* @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)
|
||||
* @return 导入的 BrepModel
|
||||
*
|
||||
* @throws std::runtime_error 解析失败
|
||||
*/
|
||||
[[nodiscard]] brep::BrepModel import_acis_sat(const std::string& path);
|
||||
void export_acis_sat(const brep::BrepModel& body, const std::string& path);
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
||||
@@ -1,6 +1,133 @@
|
||||
#pragma once
|
||||
/// @defgroup gpu GPU 加速模块
|
||||
/// CUDA 加速的 SDF 网格化、QEM 简化与布尔运算。
|
||||
/// 无 CUDA 环境自动退化为 CPU 实现,API 行为一致。
|
||||
/// @{
|
||||
|
||||
#include "vde/mesh/halfedge_mesh.h"
|
||||
#include "vde/core/aabb.h"
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
// ── CUDA 可用性宏(由 CMake 传入) ────────────────────────────
|
||||
#ifndef VDE_USE_CUDA
|
||||
# define VDE_USE_CUDA 0
|
||||
#endif
|
||||
|
||||
namespace vde::gpu {
|
||||
[[nodiscard]] mesh::HalfedgeMesh gpu_marching_cubes(const std::function<double(double,double,double)>& sdf, const core::AABB3D& bounds, int res=64);
|
||||
[[nodiscard]] mesh::HalfedgeMesh gpu_mesh_simplify(const mesh::HalfedgeMesh& mesh, float target_ratio=0.5f);
|
||||
|
||||
using core::AABB3D;
|
||||
using core::Point3D;
|
||||
using core::Vector3D;
|
||||
using mesh::HalfedgeMesh;
|
||||
|
||||
// ======================================================================
|
||||
// API
|
||||
// ======================================================================
|
||||
|
||||
/**
|
||||
* @brief 检测 GPU(CUDA)运行时是否可用
|
||||
*
|
||||
* 运行时检测 CUDA 驱动 + 至少 1 个设备。
|
||||
* 编译时通过 VDE_USE_CUDA 宏控制是否链接 CUDA 库。
|
||||
*
|
||||
* @return true 若 CUDA 环境就绪且编译时已开启支持
|
||||
* @return false 否则
|
||||
*/
|
||||
[[nodiscard]] bool gpu_available() noexcept;
|
||||
|
||||
// ── Marching Cubes ─────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* @brief GPU 加速 Marching Cubes(SDF → 三角网格)
|
||||
*
|
||||
* 将包围盒划分为 res³ 个体素。CUDA 路径:每线程一个体素,
|
||||
* 共享内存缓存相邻 SDF 值,原子计数器收集三角形。
|
||||
* 无 CUDA 时自动回退到 vde::mesh::marching_cubes() 等效实现。
|
||||
*
|
||||
* @param sdf 有符号距离函数 f(x,y,z) → double
|
||||
* @param bounds 包围盒(轴对齐)
|
||||
* @param res 每轴分辨率,总 voxel 数 = res³(默认 64)
|
||||
* @return HalfedgeMesh 三角网格,内部使用 HalfedgeMesh::build_from_triangles
|
||||
*/
|
||||
[[nodiscard]] HalfedgeMesh gpu_marching_cubes(
|
||||
const std::function<double(double, double, double)>& sdf,
|
||||
const AABB3D& bounds,
|
||||
int res = 64);
|
||||
|
||||
// ── Mesh Simplify (QEM) ────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* @brief GPU 加速 QEM 网格简化
|
||||
*
|
||||
* CUDA 路径:
|
||||
* - 并行计算每条边的塌缩代价(quadric error)
|
||||
* - 多 pass 逐步塌缩直到达到 target_ratio
|
||||
* - 每 pass 内独立边集并行塌缩
|
||||
* 无 CUDA 时自动回退到 vde::mesh::simplify_mesh()。
|
||||
*
|
||||
* @param mesh 输入三角网格
|
||||
* @param target_ratio 目标面数比例 (0, 1]
|
||||
* @return 简化后的网格
|
||||
*/
|
||||
[[nodiscard]] HalfedgeMesh gpu_mesh_simplify(
|
||||
const HalfedgeMesh& mesh,
|
||||
float target_ratio = 0.5f);
|
||||
|
||||
// ── Boolean Intersect ──────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* @brief GPU 加速布尔交集运算
|
||||
*
|
||||
* CUDA 路径:
|
||||
* - 空间哈希网格对三角形分组
|
||||
* - GPU 并行三角形-三角形求交
|
||||
* - 输出交集区域的重构网格
|
||||
* 无 CUDA 时自动回退到 vde::mesh 布尔运算。
|
||||
*
|
||||
* @param mesh_a 网格 A
|
||||
* @param mesh_b 网格 B
|
||||
* @return 交集网格(A ∩ B)
|
||||
*/
|
||||
[[nodiscard]] HalfedgeMesh gpu_boolean_intersect(
|
||||
const HalfedgeMesh& mesh_a,
|
||||
const HalfedgeMesh& mesh_b);
|
||||
|
||||
// ======================================================================
|
||||
// CUDA 内核声明(仅在 CUDA 编译单元可见)
|
||||
// ======================================================================
|
||||
#if VDE_USE_CUDA
|
||||
|
||||
/// CUDA 内核:Marching Cubes 体素处理
|
||||
void launch_mc_kernel(const double* sdf_grid, int res,
|
||||
const Point3D& origin, double cell_size,
|
||||
int* tri_count, int* tri_indices,
|
||||
double* tri_verts);
|
||||
|
||||
/// CUDA 内核:QEM 边代价计算
|
||||
void launch_qem_cost_kernel(const double* vertices, int num_verts,
|
||||
const int* tri_indices, int num_tris,
|
||||
double* edge_costs, int* collapse_targets);
|
||||
|
||||
/// CUDA 内核:三角形-三角形求交
|
||||
void launch_tri_intersect_kernel(const double* verts_a, const int* tris_a, int ntri_a,
|
||||
const double* verts_b, const int* tris_b, int ntri_b,
|
||||
const int* hash_bins, const int* hash_offsets,
|
||||
int* intersect_flags);
|
||||
|
||||
/// CUDA 错误检查宏
|
||||
#define CUDA_CHECK(call) \
|
||||
do { \
|
||||
cudaError_t err_ = call; \
|
||||
if (err_ != cudaSuccess) { \
|
||||
fprintf(stderr, "CUDA error %s:%d: %s\n", \
|
||||
__FILE__, __LINE__, cudaGetErrorString(err_)); \
|
||||
std::abort(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif // VDE_USE_CUDA
|
||||
|
||||
} // namespace vde::gpu
|
||||
|
||||
/** @} */ // end of gpu group
|
||||
|
||||
Reference in New Issue
Block a user