#pragma once #include "vde/mesh/halfedge_mesh.h" #include "vde/mesh/point_cloud.h" #include "vde/curves/nurbs_surface.h" #include #include namespace vde::mesh { using core::Point3D; using core::Vector3D; using core::AABB3D; using curves::NurbsSurface; // ─────────────────────────────────────────────────────────── // 参数结构体 // ─────────────────────────────────────────────────────────── /** * @brief Poisson 曲面重建参数 * @ingroup mesh */ struct PoissonReconParams { int max_depth = 8; ///< 八叉树最大深度(越高越精细) int min_depth = 3; ///< 八叉树最小深度 double point_weight = 4.0; ///< 插值点权重(越高越贴近输入点) int solver_divide = 8; ///< 求解器分块大小 int iso_divide = 8; ///< 等值面提取分块大小 double samples_per_node = 1.5; ///< 每节点采样数 bool scale_fit = true; ///< 是否缩放到单位立方体 double confidence = 0.0; ///< 点置信度(0=均匀权重) }; /** * @brief 四边形重网格化参数 * @ingroup mesh */ struct QuadRemeshParams { int target_quads = 400; ///< 目标四边形数量 double edge_length = 0.0; ///< 目标边长(0=自动) double regularity = 0.5; ///< 规则性权重 [0,1] double sharpness = 0.5; ///< 特征保持权重 [0,1] int iterations = 10; ///< 迭代次数 bool adaptive_size = false; ///< 自适应边长(曲率区域更密) }; /** * @brief NURBS 拟合参数 * @ingroup mesh */ struct NURBSFitParams { int degree_u = 3; ///< u 向阶次 int degree_v = 3; ///< v 向阶次 int num_cp_u = 8; ///< u 向控制点数(≥ degree_u+1) int num_cp_v = 8; ///< v 向控制点数(≥ degree_v+1) double smoothness = 0.001; ///< 平滑项权重(Tikhonov 正则化) int max_iterations = 50; ///< 最小二乘迭代上限 double tolerance = 1e-6; ///< 收敛容差 bool use_weights = true; ///< 是否使用有理权重拟合(NURBS vs B-spline) }; /** * @brief 点云→网格综合参数 * @ingroup mesh */ struct PointCloudToMeshParams { int knn = 10; ///< 法线估计 kNN double voxel_size = 0.0; ///< 预降采样体素尺寸(0=跳过) bool remove_outliers = true; ///< 是否先剔除统计离群点 PoissonReconParams poisson; ///< Poisson 重建参数 }; /** * @brief 网格→NURBS 综合参数 * @ingroup mesh */ struct MeshToNURBSParams { QuadRemeshParams quad; ///< 四边形重网格化参数 NURBSFitParams nurbs; ///< NURBS 拟合参数 bool smooth_before_remesh = false; ///< 重网格化前是否平滑 }; // ─────────────────────────────────────────────────────────── // 拟合结果 // ─────────────────────────────────────────────────────────── /// 平面拟合结果 struct PlaneFitResult { Point3D origin; ///< 平面上一点(点云质心) Vector3D normal; ///< 平面法向量(单位向量) double rms_error; ///< RMS 拟合误差 bool valid; ///< 拟合是否有效 }; /// 曲面片拟合结果 struct PatchFitResult { NurbsSurface surface; ///< 拟合的 NURBS 曲面 double rms_error; ///< RMS 拟合误差 double max_error; ///< 最大偏差 bool valid; ///< 拟合是否有效 }; // ─────────────────────────────────────────────────────────── // 核心函数声明 // ─────────────────────────────────────────────────────────── /** * @brief 点云 → 三角网格(Poisson 曲面重建) * * 完整流水线:法线估计 → Poisson 隐式曲面重建 → 等值面提取。 * * @param cloud 输入点云(可无法线,内部自动估计) * @param params 控制参数 * @return 重建的三角网格 * * @code{.cpp} * PointCloudToMeshParams p; * p.knn = 10; p.voxel_size = 0.02; * auto mesh = point_cloud_to_mesh(cloud, p); * @endcode * @ingroup mesh */ HalfedgeMesh point_cloud_to_mesh(const PointCloud& cloud, const PointCloudToMeshParams& params = {}); /** * @brief 网格 → NURBS 曲面 * * 流水线:四边形重网格化 → 参数化 → 控制点最小二乘拟合。 * * @param mesh 输入三角网格 * @param params 控制参数 * @return 拟合的 NURBS 曲面 * * @code{.cpp} * MeshToNURBSParams p; * p.quad.target_quads = 200; * p.nurbs.num_cp_u = 6; p.nurbs.num_cp_v = 6; * auto surf = mesh_to_nurbs_surface(mesh, p); * @endcode * @ingroup mesh */ NurbsSurface mesh_to_nurbs_surface(const HalfedgeMesh& mesh, const MeshToNURBSParams& params = {}); /** * @brief 点云平面拟合(SVD 最小二乘) * * @param points 输入点列表 * @return 平面拟合结果(origin, normal, rms_error) * * @code{.cpp} * auto plane = fit_plane(points); * // plane.normal 是单位法向量,plane.origin 是质心 * @endcode * @ingroup mesh */ PlaneFitResult fit_plane(const std::vector& points); /** * @brief 点云曲面片 NURBS 拟合 * * 将点云拟合为指定阶次的 NURBS 曲面片:先将点投影到拟合平面上, * 在参数域中均匀采样构造控制网格,再用最小二乘优化控制点位置。 * * @param points 输入点列表 * @param degree_u u 向阶次 * @param degree_v v 向阶次 * @param num_cp_u u 向控制点数 * @param num_cp_v v 向控制点数 * @return 拟合结果(NURBS 曲面 + 误差) * * @ingroup mesh */ PatchFitResult fit_patch(const std::vector& points, int degree_u = 3, int degree_v = 3, int num_cp_u = 8, int num_cp_v = 8); /** * @brief 点云曲率感知采样 * * 计算局部曲率近似,高曲率区域保留更多点,低曲率区域用较少点表示。 * * @param points 输入点列表 * @param target_count 目标保留点数 * @return 采样后的点索引数组 * * @ingroup mesh */ std::vector curvature_aware_sampling(const std::vector& points, size_t target_count); /** * @brief 网格孔洞填充 * * 检测边界环,对每个孔洞用 fan 三角化(或最小面积三角化)填充。 * * @param mesh 输入网格 * @param max_hole_edges 最大孔洞边界边数(超过此数的孔洞不填充,0=无限制) * @return 填充后的网格 * * @ingroup mesh */ HalfedgeMesh hole_filling(const HalfedgeMesh& mesh, int max_hole_edges = 0); /** * @brief 点云平滑滤波 * * 对点云位置进行各向同性拉普拉斯 + 双边滤波去噪。 * * @param points 输入点列表 * @param sigma 高斯核 σ(控制平滑强度) * @param iterations 迭代次数 * @return 平滑后的点列表 * * @ingroup mesh */ std::vector smoothing_filter(const std::vector& points, double sigma = 0.5, int iterations = 3); // ─────────────────────────────────────────────────────────── // 法线估计(独立函数) // ─────────────────────────────────────────────────────────── /** * @brief 点云法线估计(kNN + PCA) * * @param points 输入点列表 * @param k 最近邻点数 * @return 估计的法线向量列表 * * @ingroup mesh */ std::vector estimate_normals(const std::vector& points, int k = 10); } // namespace vde::mesh