107 lines
3.4 KiB
C++
107 lines
3.4 KiB
C++
#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 <vector>
|
|
#include <string>
|
|
|
|
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<InterferencePair> pairs; ///< 所有检查的零件对详情
|
|
std::vector<InterferencePair> 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
|