2026-07-26 18:41:28 +08:00
|
|
|
|
#pragma once
|
2026-07-26 21:34:44 +08:00
|
|
|
|
/// @defgroup gpu GPU 加速模块
|
|
|
|
|
|
/// CUDA 加速的 SDF 网格化、QEM 简化与布尔运算。
|
|
|
|
|
|
/// 无 CUDA 环境自动退化为 CPU 实现,API 行为一致。
|
|
|
|
|
|
/// @{
|
|
|
|
|
|
|
2026-07-26 18:41:28 +08:00
|
|
|
|
#include "vde/mesh/halfedge_mesh.h"
|
2026-07-26 21:34:44 +08:00
|
|
|
|
#include "vde/core/aabb.h"
|
|
|
|
|
|
#include <functional>
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
|
|
// ── CUDA 可用性宏(由 CMake 传入) ────────────────────────────
|
|
|
|
|
|
#ifndef VDE_USE_CUDA
|
|
|
|
|
|
# define VDE_USE_CUDA 0
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2026-07-26 18:41:28 +08:00
|
|
|
|
namespace vde::gpu {
|
2026-07-26 21:34:44 +08:00
|
|
|
|
|
|
|
|
|
|
using core::AABB3D;
|
|
|
|
|
|
using core::Point3D;
|
|
|
|
|
|
using core::Vector3D;
|
|
|
|
|
|
using mesh::HalfedgeMesh;
|
|
|
|
|
|
|
|
|
|
|
|
// ======================================================================
|
|
|
|
|
|
// API
|
|
|
|
|
|
// ======================================================================
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 检测 GPU(CUDA)运行时是否可用
|
|
|
|
|
|
*
|
|
|
|
|
|
* 运行时检测 CUDA 驱动 + 至少 1 个设备。
|
|
|
|
|
|
* 编译时通过 VDE_USE_CUDA 宏控制是否链接 CUDA 库。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @return true 若 CUDA 环境就绪且编译时已开启支持
|
|
|
|
|
|
* @return false 否则
|
|
|
|
|
|
*/
|
|
|
|
|
|
[[nodiscard]] bool gpu_available() noexcept;
|
|
|
|
|
|
|
|
|
|
|
|
// ── Marching Cubes ─────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief GPU 加速 Marching Cubes(SDF → 三角网格)
|
|
|
|
|
|
*
|
|
|
|
|
|
* 将包围盒划分为 res³ 个体素。CUDA 路径:每线程一个体素,
|
|
|
|
|
|
* 共享内存缓存相邻 SDF 值,原子计数器收集三角形。
|
|
|
|
|
|
* 无 CUDA 时自动回退到 vde::mesh::marching_cubes() 等效实现。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param sdf 有符号距离函数 f(x,y,z) → double
|
|
|
|
|
|
* @param bounds 包围盒(轴对齐)
|
|
|
|
|
|
* @param res 每轴分辨率,总 voxel 数 = res³(默认 64)
|
|
|
|
|
|
* @return HalfedgeMesh 三角网格,内部使用 HalfedgeMesh::build_from_triangles
|
|
|
|
|
|
*/
|
|
|
|
|
|
[[nodiscard]] HalfedgeMesh gpu_marching_cubes(
|
|
|
|
|
|
const std::function<double(double, double, double)>& sdf,
|
|
|
|
|
|
const AABB3D& bounds,
|
|
|
|
|
|
int res = 64);
|
|
|
|
|
|
|
|
|
|
|
|
// ── Mesh Simplify (QEM) ────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief GPU 加速 QEM 网格简化
|
|
|
|
|
|
*
|
|
|
|
|
|
* CUDA 路径:
|
|
|
|
|
|
* - 并行计算每条边的塌缩代价(quadric error)
|
|
|
|
|
|
* - 多 pass 逐步塌缩直到达到 target_ratio
|
|
|
|
|
|
* - 每 pass 内独立边集并行塌缩
|
|
|
|
|
|
* 无 CUDA 时自动回退到 vde::mesh::simplify_mesh()。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param mesh 输入三角网格
|
|
|
|
|
|
* @param target_ratio 目标面数比例 (0, 1]
|
|
|
|
|
|
* @return 简化后的网格
|
|
|
|
|
|
*/
|
|
|
|
|
|
[[nodiscard]] HalfedgeMesh gpu_mesh_simplify(
|
|
|
|
|
|
const HalfedgeMesh& mesh,
|
|
|
|
|
|
float target_ratio = 0.5f);
|
|
|
|
|
|
|
|
|
|
|
|
// ── Boolean Intersect ──────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief GPU 加速布尔交集运算
|
|
|
|
|
|
*
|
|
|
|
|
|
* CUDA 路径:
|
|
|
|
|
|
* - 空间哈希网格对三角形分组
|
|
|
|
|
|
* - GPU 并行三角形-三角形求交
|
|
|
|
|
|
* - 输出交集区域的重构网格
|
|
|
|
|
|
* 无 CUDA 时自动回退到 vde::mesh 布尔运算。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param mesh_a 网格 A
|
|
|
|
|
|
* @param mesh_b 网格 B
|
|
|
|
|
|
* @return 交集网格(A ∩ B)
|
|
|
|
|
|
*/
|
|
|
|
|
|
[[nodiscard]] HalfedgeMesh gpu_boolean_intersect(
|
|
|
|
|
|
const HalfedgeMesh& mesh_a,
|
|
|
|
|
|
const HalfedgeMesh& mesh_b);
|
|
|
|
|
|
|
|
|
|
|
|
// ======================================================================
|
|
|
|
|
|
// CUDA 内核声明(仅在 CUDA 编译单元可见)
|
|
|
|
|
|
// ======================================================================
|
|
|
|
|
|
#if VDE_USE_CUDA
|
|
|
|
|
|
|
|
|
|
|
|
/// CUDA 内核:Marching Cubes 体素处理
|
|
|
|
|
|
void launch_mc_kernel(const double* sdf_grid, int res,
|
|
|
|
|
|
const Point3D& origin, double cell_size,
|
|
|
|
|
|
int* tri_count, int* tri_indices,
|
|
|
|
|
|
double* tri_verts);
|
|
|
|
|
|
|
|
|
|
|
|
/// CUDA 内核:QEM 边代价计算
|
|
|
|
|
|
void launch_qem_cost_kernel(const double* vertices, int num_verts,
|
|
|
|
|
|
const int* tri_indices, int num_tris,
|
|
|
|
|
|
double* edge_costs, int* collapse_targets);
|
|
|
|
|
|
|
|
|
|
|
|
/// CUDA 内核:三角形-三角形求交
|
|
|
|
|
|
void launch_tri_intersect_kernel(const double* verts_a, const int* tris_a, int ntri_a,
|
|
|
|
|
|
const double* verts_b, const int* tris_b, int ntri_b,
|
|
|
|
|
|
const int* hash_bins, const int* hash_offsets,
|
|
|
|
|
|
int* intersect_flags);
|
|
|
|
|
|
|
|
|
|
|
|
/// CUDA 错误检查宏
|
|
|
|
|
|
#define CUDA_CHECK(call) \
|
|
|
|
|
|
do { \
|
|
|
|
|
|
cudaError_t err_ = call; \
|
|
|
|
|
|
if (err_ != cudaSuccess) { \
|
|
|
|
|
|
fprintf(stderr, "CUDA error %s:%d: %s\n", \
|
|
|
|
|
|
__FILE__, __LINE__, cudaGetErrorString(err_)); \
|
|
|
|
|
|
std::abort(); \
|
|
|
|
|
|
} \
|
|
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
|
|
|
|
#endif // VDE_USE_CUDA
|
|
|
|
|
|
|
2026-07-26 18:41:28 +08:00
|
|
|
|
} // namespace vde::gpu
|
2026-07-26 21:34:44 +08:00
|
|
|
|
|
|
|
|
|
|
/** @} */ // end of gpu group
|