#pragma once #include "vde/core/point.h" #include #include #include 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>> tessellate(const std::function& 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 */ std::pair, std::vector>> adaptive_tessellate( const std::function& eval, const std::function& normal_fn, int min_res = 2, int max_depth = 6, double angle_threshold_deg = 5.0); } // namespace vde::curves