2026-07-24 07:20:45 +00:00
|
|
|
|
#pragma once
|
2026-07-24 11:09:45 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* @file sdf_torch.h
|
|
|
|
|
|
* @brief SDF 批量求值与梯度计算(CPU 后端)
|
|
|
|
|
|
*
|
|
|
|
|
|
* 提供吞吐量优化的 SDF 批量求值接口,适合大量点或实时场景。
|
|
|
|
|
|
*
|
|
|
|
|
|
* ## 设计意图
|
|
|
|
|
|
*
|
|
|
|
|
|
* 虽然命名为 sdf_torch,但本头的实现是纯 C++ CPU 版本,
|
|
|
|
|
|
* 不依赖 PyTorch。接口设计为"可替换为 CUDA/Torch 后端"的占位,
|
|
|
|
|
|
* 函数签名与假设的 GPU 版本保持一致。
|
|
|
|
|
|
*
|
|
|
|
|
|
* ## 数据布局
|
|
|
|
|
|
*
|
|
|
|
|
|
* - **输入数组:** x,y,z 交替存储(SoA 未使用),n 个点 × 3 个 double
|
|
|
|
|
|
* - **输出距离:** 连续 n 个 double
|
|
|
|
|
|
* - **输出梯度:** 连续 3n 个 double,x,y,z 交替存储
|
|
|
|
|
|
*
|
|
|
|
|
|
* ## 使用场景
|
|
|
|
|
|
*
|
|
|
|
|
|
* - Ray-marching:沿射线采样大量点
|
|
|
|
|
|
* - 网格求值:Marching Cubes 前的密集采样
|
|
|
|
|
|
* - 可视化:距离场的 heatmap 生成
|
|
|
|
|
|
* - 物理仿真:碰撞检测批量查询
|
|
|
|
|
|
*
|
|
|
|
|
|
* @ingroup sdf
|
|
|
|
|
|
*/
|
2026-07-24 07:20:45 +00:00
|
|
|
|
#include "vde/sdf/sdf_gradient.h"
|
|
|
|
|
|
#include "vde/sdf/sdf_tree.h"
|
|
|
|
|
|
#include "vde/core/point.h"
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
|
|
// This header is optional — only compiled if Torch is available
|
|
|
|
|
|
|
|
|
|
|
|
namespace vde::sdf {
|
|
|
|
|
|
|
2026-07-24 11:09:45 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 在批处理模式下求值 SDF
|
|
|
|
|
|
*
|
|
|
|
|
|
* 对 n 个三维点逐一求值 SDF 树,将距离值写入预分配的输出数组。
|
|
|
|
|
|
*
|
|
|
|
|
|
* **性能特征:**
|
|
|
|
|
|
* - O(n) 时间复杂度,每个点独立求值
|
|
|
|
|
|
* - 内存访问模式: 顺序读取 3n 个 double,顺序写入 n 个 double
|
|
|
|
|
|
* - 无 SIMD 优化(当前 CPU 后端)
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param root SDF 表达式树根节点
|
|
|
|
|
|
* @param points 点数组,length = 3·n,x,y,z 交替存储
|
|
|
|
|
|
* @param n 点数
|
|
|
|
|
|
* @param distances 输出数组,length = n,写入有符号距离值
|
|
|
|
|
|
*
|
|
|
|
|
|
* @pre points 和 distances 必须非空,且各自有足够长度
|
|
|
|
|
|
*
|
|
|
|
|
|
* @code{.cpp}
|
|
|
|
|
|
* std::vector<double> pts = {0,0,0, 1,0,0, 2,0,0}; // 3 points
|
|
|
|
|
|
* std::vector<double> dists(3);
|
|
|
|
|
|
* evaluate_batch(root, pts.data(), 3, dists.data());
|
|
|
|
|
|
* @endcode
|
|
|
|
|
|
*
|
|
|
|
|
|
* @see evaluate 单点求值
|
|
|
|
|
|
* @see gradient_batch 批量梯度计算
|
|
|
|
|
|
*/
|
2026-07-24 07:20:45 +00:00
|
|
|
|
void evaluate_batch(const SdfNodePtr& root,
|
|
|
|
|
|
const double* points, int n,
|
|
|
|
|
|
double* distances);
|
|
|
|
|
|
|
2026-07-24 11:09:45 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 在批处理模式下求值 SDF 的空间梯度
|
|
|
|
|
|
*
|
|
|
|
|
|
* 对 n 个点逐一计算空间梯度 ∇f = (df/dx, df/dy, df/dz),
|
|
|
|
|
|
* 结果写入预分配的梯度数组。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param root SDF 表达式树根节点
|
|
|
|
|
|
* @param points 点数组,length = 3·n
|
|
|
|
|
|
* @param n 点数
|
|
|
|
|
|
* @param gradients 输出数组,length = 3·n,x,y,z 梯度分量交替存储
|
|
|
|
|
|
*
|
|
|
|
|
|
* @pre points 和 gradients 必须非空,且有足够长度
|
|
|
|
|
|
*
|
|
|
|
|
|
* @see evaluate_batch 批量距离求值
|
|
|
|
|
|
* @see evaluate_with_gradient_batch 同时获取距离和梯度(减少重复采样)
|
|
|
|
|
|
*/
|
2026-07-24 07:20:45 +00:00
|
|
|
|
void gradient_batch(const SdfNodePtr& root,
|
|
|
|
|
|
const double* points, int n,
|
|
|
|
|
|
double* gradients);
|
|
|
|
|
|
|
2026-07-24 11:09:45 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 一次遍历同时求值 SDF 值和梯度
|
|
|
|
|
|
*
|
|
|
|
|
|
* 相比于分别调用 evaluate_batch + gradient_batch,
|
|
|
|
|
|
* 本函数在一次遍历中完成两者,避免重复遍历树。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param root SDF 表达式树根节点
|
|
|
|
|
|
* @param points 点数组,length = 3·n
|
|
|
|
|
|
* @param n 点数
|
|
|
|
|
|
* @param distances 输出距离数组,length = n
|
|
|
|
|
|
* @param gradients 输出梯度数组,length = 3·n
|
|
|
|
|
|
*
|
|
|
|
|
|
* @note 对于大量点的场景(n > 1000),推荐使用本函数以获得 ~2× 速度提升。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @code{.cpp}
|
|
|
|
|
|
* int n = 10000;
|
|
|
|
|
|
* std::vector<double> pts(3*n), dists(n), grads(3*n);
|
|
|
|
|
|
* // ... fill pts ...
|
|
|
|
|
|
* evaluate_with_gradient_batch(root, pts.data(), n, dists.data(), grads.data());
|
|
|
|
|
|
* @endcode
|
|
|
|
|
|
*
|
|
|
|
|
|
* @see evaluate_batch 仅求距离
|
|
|
|
|
|
* @see gradient_batch 仅求梯度
|
|
|
|
|
|
*/
|
2026-07-24 07:20:45 +00:00
|
|
|
|
void evaluate_with_gradient_batch(const SdfNodePtr& root,
|
|
|
|
|
|
const double* points, int n,
|
|
|
|
|
|
double* distances,
|
|
|
|
|
|
double* gradients);
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace vde::sdf
|