#pragma once /** * @file interference_check.h * @brief 装配体干涉检查 * * 对装配体进行碰撞/干涉检测,利用 GJK/EPA 算法和 BVH 加速。 * 支持全装配批量检测和零件对检测。 * * @ingroup brep */ #include "vde/brep/assembly.h" #include "vde/collision/gjk.h" #include "vde/spatial/bvh.h" #include #include namespace vde::brep { /** * @brief 单对零件干涉详情 */ struct InterferencePair { std::string part_a; ///< 零件 A 名称 std::string part_b; ///< 零件 B 名称 bool interfering = false; ///< 是否干涉 double penetration = 0.0; ///< 穿透深度(EPA 估算,干涉时 > 0) double overlap_volume = 0.0; ///< 干涉体积估算(AABB 近似) }; /** * @brief 干涉检查完整结果 */ struct InterferenceResult { bool has_interference = false; ///< 是否存在干涉 int total_pairs_checked = 0; ///< 检查的零件对数 int interfering_pairs = 0; ///< 干涉零件对数 std::vector pairs; ///< 所有检查的零件对详情 std::vector conflicts; ///< 仅干涉的零件对(便捷访问) /// 获取干涉摘要 [[nodiscard]] std::string summary() const; }; // ═══════════════════════════════════════════════════════════ // API // ═══════════════════════════════════════════════════════════ /** * @brief 全装配体干涉检查 * * 遍历装配体树中所有零件对,检测干涉。 * 使用 AABB 预检跳过远距离对,再用 GJK/EPA 精确检测。 * * @param assembly 目标装配体 * @param coarse_only 仅做 AABB 粗检测(更快但可能有误报),默认 false * @return 干涉检查结果 * * @code{.cpp} * Assembly assy("robot"); * // ... 添加零件 ... * auto result = check_interference(assy); * if (result.has_interference) { * for (auto& c : result.conflicts) { * std::cout << c.part_a << " ↔ " << c.part_b * << " pen=" << c.penetration << "\n"; * } * } * @endcode */ [[nodiscard]] InterferenceResult check_interference( const Assembly& assembly, bool coarse_only = false); /** * @brief 两零件干涉检测 * * 检测两个 B-Rep 模型在世界空间中的干涉。 * * @param model_a 零件 A 的 B-Rep 模型 * @param model_b 零件 B 的 B-Rep 模型 * @param transform_a 零件 A 的世界变换 * @param transform_b 零件 B 的世界变换 * @return 干涉对信息 */ [[nodiscard]] InterferencePair check_pair( const BrepModel& model_a, const BrepModel& model_b, const core::Transform3D& transform_a, const core::Transform3D& transform_b); /** * @brief 计算两模型的穿透深度(EPA) * * 仅在两模型已确认干涉时调用。 * * @param model_a 零件 A * @param model_b 零件 B * @param transform_a A 的世界变换 * @param transform_b B 的世界变换 * @return 穿透深度(≥0),不相交时为 0 */ [[nodiscard]] double penetration_depth( const BrepModel& model_a, const BrepModel& model_b, const core::Transform3D& transform_a, const core::Transform3D& transform_b); } // namespace vde::brep