Files
ViewDesignEngine/include/vde/sdf/sdf_to_mesh.h
T
茂之钳 4c9ee4f760
CI / Build & Test (push) Failing after 29s
CI / Release Build (push) Failing after 38s
docs: doxygen annotations for curves + mesh + sketch
2026-07-24 11:04:04 +00:00

95 lines
3.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
/**
* @file sdf_to_mesh.h
* @brief SDF 到三角网格的转换
*
* 使用 Marching Cubes 算法将隐式曲面(SDF)转换为显式三角网格。
*
* ## Marching Cubes 算法
*
* 在指定的包围盒内以固定分辨率采样 SDF 场,通过查表确定每个体素内的等值面三角形配置。
*
* **流程:**
* 1. 在 `[bmin, bmax]` 范围内构建分辨率 `res³` 的三维规则网格
* 2. 在每个网格点求值 SDF
* 3. 利用 Marching Cubes 查找表在等值面处生成三角形
* 4. 返回包含顶点和三角形索引的 MCMesh
*
* ## 注意事项
*
* - 分辨率越高网格越精细,但计算量按 O(res³) 增长
* - 推荐分辨率 64~256,取决于几何复杂度
* - 结果网格需在 Marching Cubes 模块中定义(vde::mesh::MCMesh
*
* @ingroup sdf
*/
#include "vde/sdf/sdf_tree.h"
#include "vde/mesh/marching_cubes.h"
#include <functional>
namespace vde::sdf {
/**
* @brief 将 SDF 表达式树转换为三角网格
*
* 使用 Marching Cubes 算法在 SDF 树的包围盒内采样并生成网格。
* 包围盒由 estimate_bbox() 自动确定。
*
* **算法步骤:**
* 1. 调用 estimate_bbox(root) 确定采样范围
* 2. 构建分辨率 `resolution³` 体素网格
* 3. 在每个体素角点求值 SDF
* 4. 用 Marching Cubes 提取 iso_level 等值面
*
* @param root SDF 表达式树的根节点
* @param resolution 每轴的网格分辨率(例如 64 表示 64³ 体素网格)
* @param iso_level 等值面水平(0.0 = 隐式表面)
* @return 包含顶点和三角形索引的 MCMesh
*
* @note 分辨率推荐为 2 的幂(32, 64, 128, 256)以获得最佳缓存性能。
* @note 对于大尺寸但细节少的几何体,使用较低的 resolution 即可获得光滑结果。
*
* @code{.cpp}
* auto root = SdfNode::sphere(2.0);
* auto mesh = sdf_to_mesh(root, 128); // 128³ 体素网格
* // mesh.vertices 和 mesh.indices 可直接用于渲染或导出
* @endcode
*
* @see sdf_to_mesh_lambda Lambda 版本的 SDF 转网格(Python 友好)
* @see estimate_bbox 包围盒估算
*/
[[nodiscard]] mesh::MCMesh sdf_to_mesh(const SdfNodePtr& root,
int resolution = 64,
double iso_level = 0.0);
/**
* @brief 将 Lambda SDF 函数转换为三角网格
*
* 接受 C++ lambda 或 std::function 作为 SDF 定义,适合 Python 绑定场景。
* 与 sdf_to_mesh() 不同,本函数需要调用方显式提供包围盒。
*
* @param f SDF 函数,签名为 double(double x, double y, double z) → 有符号距离
* @param bmin 采样包围盒最小角点
* @param bmax 采样包围盒最大角点
* @param resolution 每轴分辨率
* @param iso_level 等值面水平(默认 0.0
* @return MCMesh 三角网格
*
* @code{.cpp}
* // 球体 lambda
* auto sphere_lambda = [](double x, double y, double z) {
* return std::sqrt(x*x + y*y + z*z) - 1.0;
* };
* auto mesh = sdf_to_mesh_lambda(sphere_lambda,
* Point3D(-1.5, -1.5, -1.5), Point3D(1.5, 1.5, 1.5), 64);
* @endcode
*
* @see sdf_to_mesh 基于 SDF 树的网格转换
*/
[[nodiscard]] mesh::MCMesh sdf_to_mesh_lambda(
const std::function<double(double, double, double)>& f,
const Point3D& bmin, const Point3D& bmax,
int resolution = 64, double iso_level = 0.0);
} // namespace vde::sdf