docs: doxygen annotations for spatial + boolean + collision

This commit is contained in:
茂之钳
2026-07-24 11:02:06 +00:00
parent 10847e61ad
commit b97b0415f5
11 changed files with 1262 additions and 76 deletions
+158 -14
View File
@@ -1,3 +1,13 @@
/**
* @file boolean_mesh.h
* @brief 三维网格布尔运算
*
* 基于半边的网格布尔操作:并集、交集、差集、对称差。
* 通过面片重心内外判定 (ray-casting) 实现拓扑分类。
*
* @ingroup boolean
*/
#pragma once
#include "vde/boolean/boolean_2d.h"
#include "vde/core/polygon.h"
@@ -8,40 +18,174 @@ using core::Point2D;
using core::Polygon2D;
using mesh::HalfedgeMesh;
/// ── Core 3D mesh boolean operations ──────────────────────
// ── Core 3D mesh boolean operations ──────────────────────────────
/// Union: A B — keep faces of each mesh whose centroids lie outside the other
/**
* @brief 网格并集 A B
*
* 保留网格 A 中重心在网格 B 外的面片,
* 以及网格 B 中重心在网格 A 外的面片。
* 合并后形成两个网格的并集体积。
*
* 原理:对每个面片计算重心坐标,用射线投射判断
* 该点是否在对方网格内部,据此决定保留或剔除。
*
* @param a 网格 A
* @param b 网格 B
* @return A B 的合并网格
*
* @code{.cpp}
* HalfedgeMesh result = mesh_union(cube, sphere);
* @endcode
*
* @see mesh_intersection, mesh_difference, is_point_inside_mesh
*/
HalfedgeMesh mesh_union(const HalfedgeMesh& a, const HalfedgeMesh& b);
/// Intersection: A ∩ B — keep faces whose centroids lie inside the other
/**
* @brief 网格交集 A ∩ B
*
* 保留网格 A 中重心在网格 B 内的面片,
* 以及网格 B 中重心在网格 A 内的面片。
*
* @param a 网格 A
* @param b 网格 B
* @return A ∩ B 的交集网格
*
* @note 结果体积为两网格公共区域
*
* @see mesh_union, mesh_difference
*/
HalfedgeMesh mesh_intersection(const HalfedgeMesh& a, const HalfedgeMesh& b);
/// Difference: A B — keep A-faces outside B
/**
* @brief 网格差集 A B
*
* 保留网格 A 中重心在网格 B 外的面片,
* 以及网格 B 中重心在网格 A 内的面片(翻转法线)。
*
* @param a 网格 A
* @param b 网格 B
* @return A B 的差集网格
*
* @note 结果中来自 B 的面片会被翻转法线以保持内-外一致性
*
* @see mesh_union, mesh_intersection, mesh_sym_diff
*/
HalfedgeMesh mesh_difference(const HalfedgeMesh& a, const HalfedgeMesh& b);
/// Symmetric difference: (A B) (B A)
/**
* @brief 网格对称差 (A B) (B A)
*
* 等价于:
* @code{.cpp}
* mesh_union(mesh_difference(a, b), mesh_difference(b, a))
* @endcode
*
* @param a 网格 A
* @param b 网格 B
* @return 对称差网格
*
* @see mesh_difference, mesh_union
*/
HalfedgeMesh mesh_sym_diff(const HalfedgeMesh& a, const HalfedgeMesh& b);
/// ── Helpers ──────────────────────────────────────────────
// ── Helpers ─────────────────────────────────────────────────────
/// Crop mesh `a` by mesh `b`'s boundary: keep faces of `a` whose
/// centroids lie OUTSIDE the volume of `b`.
/// If `invert_b` is true, test against the flipped-volume (inside↔outside) of `b`.
/**
* @brief 用网格 B 裁剪网格 A
*
* 保留网格 A 中位于 B 体外的面片。
* 是 mesh_difference 的简化变体,仅输出来自 A 的面片。
*
* @param a 待裁剪网格
* @param b 裁剪体网格
* @param invert_b 若为 true,将 B 的内外判定取反(裁剪外部)
* @return 裁剪后的网格(仅包含 A 的面片)
*
* @code{.cpp}
* // 裁剪 cube 外部的 sphere 面片
* auto clipped = clip_mesh(sphere, cube, /*invert_b=*/false);
* // 保留 cube 内部的 sphere 面片
* auto inner = clip_mesh(sphere, cube, /*invert_b=*/true);
* @endcode
*
* @see mesh_difference, is_point_inside_mesh
*/
HalfedgeMesh clip_mesh(const HalfedgeMesh& a, const HalfedgeMesh& b,
bool invert_b = false);
/// Invert all face orientations in the mesh
/**
* @brief 翻转网格所有面片的法线方向
*
* 遍历所有面片,反转其顶点环绕顺序。
* 常用于生成负体积(反向外壳)或差集操作中。
*
* @param m 原始网格
* @return 法线翻转后的网格
*
* @see mesh_difference
*/
HalfedgeMesh invert_mesh(const HalfedgeMesh& m);
/// Merge two meshes into one (concatenate vertices and faces)
/**
* @brief 合并两个网格
*
* 将两个网格的顶点和面片直接拼接,不做布尔操作。
* 用于将分离的网格组件合并到单个数据结构中。
*
* @param a 网格 A
* @param b 网格 B
* @return 包含 A 和 B 全部顶点和面片的合并网格
*
* @note 不处理重叠区域;仅做纯几何拼接
*
* @see mesh_union(做布尔合并)
*/
HalfedgeMesh merge_meshes(const HalfedgeMesh& a, const HalfedgeMesh& b);
/// Convenience dispatcher — route by BooleanOp enum
/**
* @brief 网格布尔运算统一接口
*
* 根据布尔操作类型分发到对应的具体函数。
*
* @param a 网格 A
* @param b 网格 B
* @param op 布尔操作类型
* @return 结果网格
*
* @code{.cpp}
* auto result = mesh_boolean(cube, sphere, BooleanOp::Intersection);
* @endcode
*
* @see BooleanOp, mesh_union, mesh_intersection, mesh_difference, mesh_sym_diff
*/
HalfedgeMesh mesh_boolean(const HalfedgeMesh& a, const HalfedgeMesh& b, BooleanOp op);
/// ── Point classification ─────────────────────────────────
// ── Point classification ────────────────────────────────────────
/// Test whether point `p` is inside `mesh` using ray-casting
/**
* @brief 判断三维点是否在封闭网格内部
*
* 使用射线投射法:从点 p 向任意方向射出射线,
* 统计与网格面片的交点数量。
* 奇数表示在内部,偶数表示在外部。
*
* 算法:
* 1. 构造从 p 出发沿 +x 方向的射线
* 2. 遍历所有三角形进行射线-三角形求交
* 3. 统计交点数量
* 4. 返回奇偶性判定结果
*
* @param p 待判定点
* @param mesh 封闭网格
* @return 点在网格内部返回 true
*
* @note 网格必须是封闭(水密)的,否则结果不可靠。
* 点恰好落在面上时行为未定义。
*
* @see clip_mesh, mesh_difference
*/
bool is_point_inside_mesh(const core::Point3D& p, const HalfedgeMesh& mesh);
} // namespace vde::boolean