Files
ViewDesignEngine/include/vde/curves/tessellation.h
T

71 lines
2.5 KiB
C++
Raw Normal View History

#pragma once
#include "vde/core/point.h"
#include <vector>
#include <array>
2026-07-23 12:36:39 +00:00
#include <functional>
namespace vde::curves {
using core::Point3D;
using core::Vector3D;
/**
* @brief 均匀参数化曲面三角化
*
* 在参数域 [0,1]×[0,1] 上生成 res_u×res_v 均匀采样点,
* 调用 eval(u,v) 求值后将每个四边形拆为两个三角形。
*
* @param eval 曲面求值函数 eval(u,v) -> Point3D,参数 (u,v) ∈ [0,1]×[0,1]
* @param res_u u 方向子分段数(≥ 1)
* @param res_v v 方向子分段数(≥ 1)
* @return {顶点数组, 三角形索引数组},三角形为 {i0,i1,i2}
*
* @note 总顶点数 = (res_u+1)×(res_v+1),三角形数 = 2×res_u×res_v
* @code{.cpp}
* auto [verts, tris] = tessellate(
* [&](double u, double v) { return surface.evaluate(u,v); },
* 20, 20);
* @endcode
* @see adaptive_tessellate
* @ingroup curves
*/
std::pair<std::vector<Point3D>, std::vector<std::array<int, 3>>>
tessellate(const std::function<Point3D(double,double)>& eval,
int res_u, int res_v);
/**
* @brief 自适应曲面三角化
*
* 基于法向角度偏差的自适应细分策略:
* 从 min_res×min_res 初始网格开始,对每个四边形检查四个角点的法向偏差。
* 若任意相邻角点间的法向夹角超过 angle_threshold_deg,则将该四边形四分细分。
*
* 相比均匀 tessellate() 的优点:
* - 曲率大的区域自动增加采样密度
* - 平坦区域保持粗糙网格,节省面数
*
* @param eval 曲面求值函数 eval(u,v) -> Point3D
* @param normal_fn 单位法向函数 normal_fn(u,v) -> Vector3D
* @param min_res 初始每向子分段数(≥ 1),默认 2
* @param max_depth 最大递归深度,限制总面数,默认 6
* @param angle_threshold_deg 法向角度偏差阈值(度),默认 5.0
* @return {顶点数组, 三角形索引数组}
*
* @note 最终面数上限约为 2·min_res²·4^max_depth(实际远小于此上限)
* @code{.cpp}
* auto [verts, tris] = adaptive_tessellate(
* [&](double u, double v) { return surf.evaluate(u,v); },
* [&](double u, double v) { return surf.normal(u,v); },
* 2, 5, 3.0); // 3° 偏差阈值,最大深度 5
* @endcode
* @see tessellate
* @ingroup curves
*/
2026-07-23 12:36:39 +00:00
std::pair<std::vector<Point3D>, std::vector<std::array<int, 3>>>
adaptive_tessellate(
const std::function<Point3D(double,double)>& eval,
const std::function<Vector3D(double,double)>& normal_fn,
int min_res = 2, int max_depth = 6,
double angle_threshold_deg = 5.0);
} // namespace vde::curves