#pragma once /** * @file sheet_metal.h * @brief 钣金设计模块 — 对标 Parasolid Sheet Metal * * 提供钣金件的展开、折弯扣除、法兰创建和 K-factor 计算功能。 * 对标业界标准钣金设计工作流。 * * ## 功能概览 * * | 操作 | 对标 Parasolid 功能 | * |------------------------|---------------------------------------| * | unfold_sheet_metal | Unbend / Flatten | * | bend_deduction_table | Bend Allowance / Deduction Table | * | create_flange | Flange / Edge Flange | * | compute_k_factor | K-Factor Calculation | * * ## 钣金术语 * * - **K-Factor**: 中性轴位置比例 (0~1),通常取 0.33~0.5 * - K = t_neutral_axis / t (t = 板厚) * - **Bend Allowance (BA)**: 折弯区展开长度 * - BA = (π × (R + K×T) × A) / 180 * - **Bend Deduction (BD)**: 折弯扣除值 * - BD = 2 × OSSB - BA * - OSSB = (R + T) × tan(A/2) (外侧退让量) * * @ingroup brep */ #include "vde/brep/brep.h" #include "vde/brep/direct_modeling.h" #include "vde/core/point.h" #include "vde/core/transform.h" #include #include #include #include namespace vde::brep { // ═══════════════════════════════════════════════════════════ // 材料与折弯表 // ═══════════════════════════════════════════════════════════ /** * @brief 钣金材料定义 * * 包含材料的力学特性,用于 K-factor 计算和折弯扣除。 */ struct SheetMetalMaterial { std::string name; ///< 材料名称(如 "Steel_A36", "Aluminum_6061") double yield_strength_mpa = 250.0; ///< 屈服强度 (MPa) double tensile_strength_mpa = 400.0; ///< 抗拉强度 (MPa) double elastic_modulus_gpa = 200.0; ///< 弹性模量 (GPa) double poisson_ratio = 0.3; ///< 泊松比 }; /** * @brief 折弯扣除表条目 * * 记录特定材料/厚度/角度/半径组合下的折弯扣除值。 */ struct BendDeductionEntry { double thickness = 1.0; ///< 板厚 (mm) double bend_radius = 1.0; ///< 折弯内半径 (mm) double bend_angle_deg = 90.0; ///< 折弯角度(度) double bend_deduction = 0.0; ///< 折弯扣除值 (mm) double k_factor = 0.33; ///< 使用的 K-factor }; /** * @brief 折弯扣除表 * * 材料/厚度 → 折弯扣除值的查找表。 * 支持精确半径匹配和插值逼近。 */ class BendDeductionTable { public: /// 添加一条记录 void add_entry(const BendDeductionEntry& entry); /// 通过精确匹配查找 [[nodiscard]] BendDeductionEntry lookup( double thickness, double bend_radius, double bend_angle_deg) const; /// 通过插值查找(未找到精确匹配时) [[nodiscard]] BendDeductionEntry lookup_interpolated( double thickness, double bend_radius, double bend_angle_deg) const; /// 获取表大小 [[nodiscard]] size_t size() const { return entries_.size(); } /// 获取所有条目 [[nodiscard]] const std::vector& entries() const { return entries_; } private: std::vector entries_; }; // ═══════════════════════════════════════════════════════════ // K-Factor 计算 // ═══════════════════════════════════════════════════════════ /** * @brief 计算 K-Factor * * K-Factor = 中性轴到内表面的距离 / 板厚 * * 使用经验公式,基于材料屈服强度和板厚: * - 软材料 (低碳钢): K ≈ 0.33 * - 中等材料: K ≈ 0.40 * - 硬材料 (不锈钢): K ≈ 0.45~0.50 * * 更精确的计算考虑 R/T 比率: * - R/T < 1.0: K = 0.25 + 0.1 × (R/T) * - 1.0 ≤ R/T < 3.0: K = 0.33 + 0.05 × (R/T) * - R/T ≥ 3.0: K = 0.45 + 0.02 × (R/T), 上限 0.5 * * @param material 材料属性 * @param thickness 板厚 (mm) * @param bend_radius 折弯内半径 (mm) * @return K-factor 值 (0.0 ~ 0.5) */ [[nodiscard]] double compute_k_factor( const SheetMetalMaterial& material, double thickness, double bend_radius); /** * @brief 快速 K-Factor 估算(材料无关) * * @param thickness 板厚 (mm) * @param bend_radius 折弯半径 (mm) * @return 估算的 K-factor */ [[nodiscard]] double compute_k_factor_simple( double thickness, double bend_radius); // ═══════════════════════════════════════════════════════════ // 折弯计算 // ═══════════════════════════════════════════════════════════ /** * @brief 计算折弯余量 (Bend Allowance) * * BA = (π/180) × (R + K×T) × A * * @param bend_radius 折弯内半径 * @param thickness 板厚 * @param bend_angle_deg 折弯角度(度) * @param k_factor K-factor * @return 折弯余量长度 (mm) */ [[nodiscard]] double compute_bend_allowance( double bend_radius, double thickness, double bend_angle_deg, double k_factor); /** * @brief 计算折弯扣除 (Bend Deduction) * * BD = 2 × OSSB - BA * OSSB = (R + T) × tan(A/2) * * @param bend_radius 折弯内半径 * @param thickness 板厚 * @param bend_angle_deg 折弯角度(度) * @param k_factor K-factor * @return 折弯扣除值 (mm) */ [[nodiscard]] double compute_bend_deduction( double bend_radius, double thickness, double bend_angle_deg, double k_factor); // ═══════════════════════════════════════════════════════════ // 折弯扣除表生成 // ═══════════════════════════════════════════════════════════ /** * @brief 为指定材料和厚度范围生成折弯扣除表 * * 自动计算 90° 折弯在不同板厚和内半径下的扣除值。 * 使用该材料的 compute_k_factor 确定 K-factor。 * * @param material 钣金材料 * @param thickness 板厚 (mm) * @param radii 要计算的内半径列表 * @return 生成的折弯扣除表 */ [[nodiscard]] BendDeductionTable bend_deduction_table( const SheetMetalMaterial& material, double thickness, const std::vector& radii = {0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 5.0, 6.0}); /** * @brief 为指定材料和折弯角生成折弯扣除表(多角度) * * @param material 钣金材料 * @param thickness 板厚 (mm) * @param radius 折弯内半径 (mm) * @param angles_deg 角度列表 * @return 生成的折弯扣除表 */ [[nodiscard]] BendDeductionTable bend_deduction_table_angles( const SheetMetalMaterial& material, double thickness, double radius, const std::vector& angles_deg = {30, 45, 60, 90, 120, 135, 150}); // ═══════════════════════════════════════════════════════════ // 钣金展开 // ═══════════════════════════════════════════════════════════ /** * @brief 钣金展开结果 */ struct UnfoldResult { /** @brief 是否成功 */ bool success = false; /** @brief 展开后的平面 B-Rep */ BrepModel flattened_body; /** @brief 折弯面列表(展开前) */ std::vector bend_faces; /** @brief 各折弯的展开信息 */ struct BendUnfoldInfo { int bend_face_id = -1; ///< 折弯面 ID double bend_angle_deg = 0.0; ///< 折弯角度 double bend_radius = 0.0; ///< 折弯半径 double unbend_length = 0.0; ///< 展开长度 }; std::vector bend_details; /** @brief 使用的 K-Factor */ double k_factor_used = 0.33; /** @brief 错误/警告 */ std::vector errors; std::vector warnings; }; /** * @brief 钣金展开 * * 对标 Parasolid Unbend/Flatten。 * 将钣金件的折弯面展开为平面布局。 * * 算法: * 1. 识别基准面(face_id 指定的面) * 2. BFS 遍历相邻面,识别折弯面(柱面或锥面) * 3. 对每个折弯面计算展开长度(使用 K-factor) * 4. 将折弯面映射到基准面所在平面 * 5. 重建平坦拓扑 * * @param body 钣金 B-Rep 模型 * @param face_id 基准面索引(展开时的固定参考面) * @param material 钣金材料(用于 K-factor 计算) * @param thickness 板厚 (mm),0 表示自动从模型估算 * @return UnfoldResult 含展开后的平面模型 */ [[nodiscard]] UnfoldResult unfold_sheet_metal( const BrepModel& body, int face_id, const SheetMetalMaterial& material = SheetMetalMaterial{}, double thickness = 0.0); // ═══════════════════════════════════════════════════════════ // 法兰创建 // ═══════════════════════════════════════════════════════════ /** * @brief 法兰创建结果 */ struct FlangeResult { bool success = false; BrepModel body; ///< 含新法兰的结果体 std::vector new_face_ids; ///< 新创建的面 ID 列表 std::vector new_edge_ids; ///< 新创建的边 ID 列表 std::vector errors; std::vector warnings; }; /** * @brief 沿边创建法兰 * * 对标 Parasolid Flange / Edge Flange。 * 沿钣金件的一条边创建折弯法兰。 * * 算法: * 1. 确定边所属的基面 * 2. 计算折弯线(沿边的偏移) * 3. 生成折弯区的柱面 * 4. 生成法兰面的平面曲面 * 5. 通过布尔或拓扑编辑将法兰附加到模型 * * @param body 输入钣金 B-Rep 模型 * @param edge_id 附着边索引 * @param angle_deg 法兰折弯角度(度),90=标准法兰 * @param length 法兰长度(从折弯线到法兰自由边的距离) * @param material 钣金材料 * @param thickness 板厚 (mm),0 表示自动估算 * @return FlangeResult 含新模型 */ [[nodiscard]] FlangeResult create_flange( const BrepModel& body, int edge_id, double angle_deg, double length, const SheetMetalMaterial& material = SheetMetalMaterial{}, double thickness = 0.0); } // namespace vde::brep