#pragma once /** * @file step_import.h * @brief STEP 文件导入(ISO 10303) * * 解析 STEP AP203/AP214 格式文件并转换为 B-Rep 模型。 * * ## STEP 格式概述 * * STEP (STandard for the Exchange of Product model data) 是 ISO 10303 标准 * 定义的 CAD 数据交换格式。AP203 和 AP214 是最常用子集,支持: * - 实体和曲面几何体 * - 产品结构和装配关系 * - 材料、颜色等元数据 * * ## 支持的实体类型 * * - **曲线**: LINE, CIRCLE, B_SPLINE_CURVE_WITH_KNOTS * - **曲面**: PLANE, CYLINDRICAL_SURFACE, B_SPLINE_SURFACE_WITH_KNOTS * - **拓扑**: CLOSED_SHELL, ADVANCED_FACE, FACE_OUTER_BOUND, EDGE_LOOP, ORIENTED_EDGE, VERTEX_POINT * * ## 错误处理 * * 使用 step_last_error() 和 step_last_error_message() 检查最近一次导入的失败原因。 * * @ingroup brep */ #include "vde/brep/brep.h" #include #include namespace vde::brep { /** * @brief STEP 导入错误码 * * 枚举 import_step() 和 import_step_from_string() 可能返回的所有错误类型。 */ enum class StepError { Ok = 0, ///< 导入成功 FileNotFound, ///< 文件不存在或无法读取 ParseError, ///< STEP 语法错误(令牌/格式异常) InvalidHeader, ///< HEADER 段格式无效 UnsupportedSchema, ///< 不支持的 SCHEMA(非 AP203/AP214) MissingEntity, ///< 引用了未定义的实体 EntityTypeError, ///< 实体类型未识别或类型不匹配 }; /** * @brief 从文件导入 STEP(AP203/AP214) * * 解析 .step / .stp 文件并提取所有 PRODUCT 对应的 B-Rep 体。 * 每个 PRODUCT 定义对应返回向量的一个元素。 * * **算法概要:** * 1. 读取文件并分割为 HEADER, DATA 段 * 2. 解析 DATA 段中的实体定义(#ID = TYPE(params);) * 3. 构建实体依赖图并按拓扑层次重建模型 * 4. 将每个 CLOSED_SHELL 转换为 BrepModel * * @param filepath .step 或 .stp 文件路径 * @return B-Rep 体列表(每个文件中的 PRODUCT 一个) * * @note 大型 STEP 文件(> 100 MB)可能需要数秒到数十秒进行解析。 * * @code{.cpp"} * auto bodies = import_step("assembly.step"); * for (auto& body : bodies) { * auto mesh = body.to_mesh(); * // 渲染或处理 mesh * } * @endcode * * @see import_step_from_string 从内存字符串导入(测试用) * @see step_last_error 获取错误码 */ [[nodiscard]] std::vector import_step(const std::string& filepath); /** * @brief 从字符串导入 STEP(用于测试和嵌入式场景) * * 与 import_step() 功能完全相同,但从内存中的 STEP 数据字符串解析。 * * @param step_data 完整的 STEP 文件内容(字符串形式) * @return B-Rep 体列表 * * @code{.cpp} * std::string step_str = R"( * ISO-10303-21; * HEADER; ... ENDSEC; * DATA; ... ENDSEC; * END-ISO-10303-21; * )"; * auto bodies = import_step_from_string(step_str); * @endcode * * @see import_step 从文件导入 */ [[nodiscard]] std::vector import_step_from_string(const std::string& step_data); /** * @brief 获取最近一次 STEP 导入的错误码 * * 线程安全的:返回当前线程最近一次导入的错误。 * * @return StepError 枚举值 * * @see step_last_error_message 获取可读的错误描述 */ [[nodiscard]] StepError step_last_error(); /** * @brief 获取最近一次 STEP 导入的可读错误描述 * * @return 错误描述字符串(如 "Missing entity reference #42") * * @code{.cpp} * auto bodies = import_step("nonexistent.step"); * if (bodies.empty()) { * std::cerr << "Import failed: " << step_last_error_message() << std::endl; * } * @endcode * * @see step_last_error 获取枚举错误码 */ [[nodiscard]] const std::string& step_last_error_message(); // ═══════════════════════════════════════════════════════════ // Import diagnostics (new in v3.3) // ═══════════════════════════════════════════════════════════ /** * @brief STEP 导入诊断报告 * * 记录最近一次 STEP 导入的详细诊断信息,包括: * - 跳过的损坏实体数 * - 跳过的非标实体数 * - 近似处理的曲面数 * - 从破损数据中恢复的面数 * - 警告消息列表 */ struct StepImportReport { int total_entities = 0; ///< 成功解析的实体总数 int skipped_damaged = 0; ///< 跳过的损坏实体数 int skipped_unsupported = 0; ///< 跳过的非标实体数 int approximated_surfaces = 0; ///< 近似处理的曲面数 int recovered_faces = 0; ///< 从破损数据中恢复的面数 std::vector warnings; ///< 警告消息列表 /// 是否有任何异常 [[nodiscard]] bool has_issues() const { return skipped_damaged > 0 || skipped_unsupported > 0 || approximated_surfaces > 0 || recovered_faces > 0 || !warnings.empty(); } /// 生成可读的诊断报告 [[nodiscard]] std::string report() const; }; /** * @brief 获取最近一次 STEP 导入的诊断报告 * * 线程安全:返回当前线程最近一次导入的诊断信息。 * * @return StepImportReport 诊断报告 * * @see step_last_error 获取错误码 */ [[nodiscard]] StepImportReport step_import_diagnostic(); } // namespace vde::brep