feat(v4.0): assembly interference checking — GJK + AABB broad-phase
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user