66777e0839
v6.1.1 — 5-Axis CAM: - cam_5axis.h/.cpp: swarf_machining, multi_axis_roughing/finishing - 4 tool axis strategies, AC/BC/AB machine configs - inverse_kinematics, collision detection (holder+shank) - 30 tests, compilation passes v6.1.2 — Reverse Engineering: - point_cloud.h/.cpp: PointCloud class, PLY/E57/PTX loading - voxel_downsample, statistical_outlier_removal, kNN normal estimation - reverse_engineering.h/.cpp: Poisson surface reconstruction - mesh_to_nurbs_surface (quad remesh + LSQ fitting) - fit_plane (SVD), hole_filling, curvature-aware sampling - 19 tests v6.1.3 — FEA Mesh Generation: - fea_mesh.h/.cpp: tetrahedral (Delaunay 3D), boundary layer (prism) - hexahedral (sweep/extrude), adaptive refinement - MeshQuality: skewness, aspect_ratio, Jacobian, orthogonality - export_abaqus/ansys/nastran formats - 15 tests, 7/8 quality metrics verified
128 lines
5.0 KiB
C++
128 lines
5.0 KiB
C++
#pragma once
|
||
#include "vde/core/point.h"
|
||
#include "vde/core/aabb.h"
|
||
#include <vector>
|
||
#include <string>
|
||
#include <cstdint>
|
||
#include <array>
|
||
|
||
namespace vde::mesh {
|
||
using core::Point3D;
|
||
using core::Vector3D;
|
||
using core::AABB3D;
|
||
|
||
// ───────────────────────────────────────────────────────────
|
||
// PointCloud 点云类
|
||
// ───────────────────────────────────────────────────────────
|
||
|
||
/**
|
||
* @brief 点云数据结构
|
||
*
|
||
* 存储顶点位置、法线、颜色(可选)及包围盒信息。
|
||
* 支持 PLY/E57/PTX 加载,体素降采样、统计离群点剔除、kNN 法线估计。
|
||
*
|
||
* @ingroup mesh
|
||
*/
|
||
class PointCloud {
|
||
public:
|
||
std::vector<Point3D> vertices; ///< 顶点位置
|
||
std::vector<Vector3D> normals; ///< 顶点法线(归一化,空数组表示未计算)
|
||
std::vector<std::array<uint8_t, 3>> colors; ///< RGB 颜色(0-255,空数组表示无颜色)
|
||
|
||
PointCloud() = default;
|
||
|
||
/// 从顶点列表构造(无颜色/法线)
|
||
explicit PointCloud(std::vector<Point3D> pts) : vertices(std::move(pts)) {}
|
||
|
||
/// 顶点数
|
||
[[nodiscard]] size_t size() const { return vertices.size(); }
|
||
/// 是否有法线
|
||
[[nodiscard]] bool has_normals() const { return !normals.empty(); }
|
||
/// 是否有颜色
|
||
[[nodiscard]] bool has_colors() const { return !colors.empty(); }
|
||
|
||
/// 包围盒
|
||
[[nodiscard]] AABB3D bounds() const;
|
||
|
||
// ── I/O ──────────────────────────────────────────────
|
||
|
||
/// 加载 PLY 点云文件(ASCII 或 binary little-endian)
|
||
static PointCloud load_ply(const std::string& path);
|
||
|
||
/// 加载 E57 点云文件(简化解析:仅提取 CartesianBounds + points3D)
|
||
static PointCloud load_e57(const std::string& path);
|
||
|
||
/// 加载 PTX 格式点云(Leica 扫描仪原始格式)
|
||
static PointCloud load_ptx(const std::string& path);
|
||
|
||
/// 保存为 PLY 文件
|
||
bool save_ply(const std::string& path) const;
|
||
|
||
// ── 滤波 / 降采样 ────────────────────────────────────
|
||
|
||
/**
|
||
* @brief 体素降采样
|
||
* @param voxel_size 体素边长
|
||
* @return 降采样后的点云(每个体素用质心代替)
|
||
*/
|
||
[[nodiscard]] PointCloud voxel_downsample(double voxel_size) const;
|
||
|
||
/**
|
||
* @brief 统计离群点剔除(SOR)
|
||
* @param k 邻域点数(默认 6)
|
||
* @param std_ratio 标准差倍率阈值(默认 1.0),超过 mean+k*std_ratio 的点标记为离群
|
||
* @return 剔除离群点后的点云
|
||
*/
|
||
[[nodiscard]] PointCloud statistical_outlier_removal(int k = 6, double std_ratio = 1.0) const;
|
||
|
||
// ── 法线估计 ──────────────────────────────────────────
|
||
|
||
/**
|
||
* @brief kNN 法线估计
|
||
*
|
||
* 对每个点,找到 k 个最近邻点,用 PCA 估计法线(最小特征值对应方向)。
|
||
* 法线方向通过视角向量(点→原点方向)统一朝向。
|
||
*
|
||
* @param k 最近邻点数(≥ 3)
|
||
* @return 估计了法线的新点云
|
||
*/
|
||
[[nodiscard]] PointCloud normal_estimation(int k = 10) const;
|
||
|
||
// ── 曲率感知采样 ──────────────────────────────────────
|
||
|
||
/**
|
||
* @brief 曲率感知降采样
|
||
*
|
||
* 计算每点局部曲率近似,按曲率加权采样:高曲率区域保留更多点。
|
||
*
|
||
* @param target_count 目标点数
|
||
* @return 采样后的索引数组
|
||
*/
|
||
[[nodiscard]] std::vector<size_t> curvature_aware_sampling(size_t target_count) const;
|
||
|
||
// ── 平滑滤波 ──────────────────────────────────────────
|
||
|
||
/**
|
||
* @brief 双边滤波平滑
|
||
*
|
||
* 对点云位置进行法向加权的双边滤波去噪,保持尖锐特征。
|
||
*
|
||
* @param sigma_c 空间高斯 σ(0 = 自动按平均点距计算)
|
||
* @param sigma_n 法向高斯 σ(弧度)
|
||
* @param iterations 迭代次数
|
||
* @return 平滑后的新点云
|
||
*/
|
||
[[nodiscard]] PointCloud smoothing_filter(double sigma_c = 0.0,
|
||
double sigma_n = 0.3,
|
||
int iterations = 3) const;
|
||
|
||
private:
|
||
/** 构建 k-d 树索引,返回每个顶点的 k 最近邻索引 */
|
||
[[nodiscard]] std::vector<std::vector<size_t>> k_nearest_neighbors(size_t k) const;
|
||
|
||
/** 协方差矩阵 PCA:计算三个特征值,返回最小特征值对应的特征向量 */
|
||
[[nodiscard]] static Vector3D pca_normal(const std::vector<Point3D>& local_pts);
|
||
};
|
||
|
||
} // namespace vde::mesh
|