#pragma once #include "vde/mesh/halfedge_mesh.h" #include #include #include #include namespace vde::mesh { using core::Point2D; using core::Point3D; using core::Vector3D; // ════════════════════════════════════════════════════════ // Triangle quality // ════════════════════════════════════════════════════════ /** * @brief 三角网格质量指标 * @ingroup mesh */ struct MeshQuality { double min_angle_deg = 0; ///< 最小三角形内角(度),≥ 0 double max_angle_deg = 0; ///< 最大三角形内角(度),≤ 180 double avg_aspect_ratio = 0; ///< 平均长宽比(外接圆半径 / 最短边) double max_aspect_ratio = 0; ///< 最大长宽比 size_t degenerate_faces = 0; ///< 退化面数(面积 ≈ 0) }; /** * @brief 评估三角网格质量 * * 对网格中每个三角面计算内角、长宽比,统计全局最值及平均值。 * 质量好的三角网格应有: * - min_angle > 20°(CFD 模拟要求 > 25°) * - max_angle < 120°(避免狭长退化) * - avg_aspect_ratio 接近 1 * * @param mesh 输入三角网格 * @return MeshQuality 质量指标汇总 * * @code{.cpp} * auto q = evaluate_mesh_quality(mesh); * if (q.min_angle_deg < 15.0) { * // 需要 remesh 或优化 * } * @endcode * @ingroup mesh */ MeshQuality evaluate_mesh_quality(const HalfedgeMesh& mesh); // ════════════════════════════════════════════════════════ // Tetrahedron quality // ════════════════════════════════════════════════════════ /** * @brief 四面体网格质量指标 * @ingroup mesh */ struct TetQuality { double min_jacobian = 0.0; ///< 最小归一化 Jacobian [0, 1],0=退化 1=正四面体 double max_jacobian = 0.0; ///< 最大归一化 Jacobian double avg_jacobian = 0.0; ///< 平均归一化 Jacobian double min_dihedral_deg = 0.0; ///< 最小二面角(度),太小会导致刚度矩阵病态 double max_dihedral_deg = 0.0; ///< 最大二面角(度),接近 180° 表示退化 double max_aspect_ratio = 0.0; ///< 最大长宽比(外接球半径 / 最短边) size_t degenerate_tets = 0; ///< 退化四面体数(体积 ≈ 0 或 Jacobian ≈ 0) size_t total_tets = 0; ///< 四面体总数 }; /** * @brief 评估三角网格作为四面体边界的质量 * * 将每个三角面与其面重心构造虚拟四面体,评估这些四面体的质量。 * 适用于将封闭三角表面解释为体积边界时的质量检测。 * * @param mesh 封闭三角网格(volume boundary) * @return TetQuality 四面体质量指标 * * @note 这不是真正的四面体网格质量评估——仅用于表面网格的代理指标 * @ingroup mesh */ TetQuality evaluate_tet_quality(const HalfedgeMesh& mesh); // ════════════════════════════════════════════════════════ // Generic element quality // ════════════════════════════════════════════════════════ /** * @brief 单元类型枚举 * @ingroup mesh */ enum class ElementType { Tri, ///< 三角形 Quad, ///< 四边形(Stub) Tet, ///< 四面体 Hex ///< 六面体(Stub) }; /** * @brief 通用单元质量指标 * @ingroup mesh */ struct ElemQuality { double min_jacobian = 0.0; ///< 最小归一化 Jacobian double max_jacobian = 0.0; ///< 最大归一化 Jacobian double avg_jacobian = 0.0; ///< 平均归一化 Jacobian size_t total_elements = 0; ///< 单元总数 size_t degenerate = 0; ///< 退化单元数 }; /** * @brief 按单元类型分派的网格质量评估 * * @param mesh 输入网格 * @param type 单元类型 * @return ElemQuality 质量指标 * * @note 目前仅 Tri 和 Tet 完整实现;Quad / Hex 返回 stub(全零) * @ingroup mesh */ ElemQuality evaluate_element_quality(const HalfedgeMesh& mesh, ElementType type); // ════════════════════════════════════════════════════════ // Quality report // ════════════════════════════════════════════════════════ /** * @brief 详细质量报告 * @ingroup mesh */ struct QualityReport { std::string element_type; ///< "triangle" 或 "tetrahedron" size_t total = 0; ///< 单元总数 size_t degenerate = 0; ///< 退化单元数 /// 质量直方图(k=10 个区间,[0,0.1), [0.1,0.2), ..., [0.9,1.0]) static constexpr int kBins = 10; std::array histogram{}; /// 分级计数(A=优秀 B=良好 C=合格 D=差 F=不合格) size_t grade_A = 0, grade_B = 0, grade_C = 0, grade_D = 0, grade_F = 0; double min_quality = 0.0; ///< 最低质量值 double max_quality = 0.0; ///< 最高质量值 double avg_quality = 0.0; ///< 平均质量值 double stddev_quality = 0.0; ///< 质量标准差 }; /** * @brief 生成三角网格的完整质量报告 * * 包含直方图、分级统计及基本统计量。 * 分级标准(按归一化 Jacobian): * - A: [0.9, 1.0] — 优秀 * - B: [0.7, 0.9) — 良好 * - C: [0.5, 0.7) — 合格 * - D: [0.3, 0.5) — 差 * - F: [0.0, 0.3) — 不合格 * * @param mesh 输入三角网格 * @return QualityReport 完整质量报告 * * @ingroup mesh */ QualityReport mesh_quality_report(const HalfedgeMesh& mesh); /** * @brief 生成四面体网格的完整质量报告 * * 将表面网格的面解释为四面体单元的边界(面 + 面心 = 虚拟四面体)。 * * @param mesh 封闭三角网格 * @return QualityReport 完整质量报告 * * @ingroup mesh */ QualityReport mesh_quality_report_tet(const HalfedgeMesh& mesh); // ════════════════════════════════════════════════════════ // Utility // ════════════════════════════════════════════════════════ /** * @brief 三角形归一化 Jacobian * * 计算三角形 (a,b,c) 的带符号面积,归一化到 [-1, 1]。 * 值 1 = 等边三角形(最优),0 = 退化(共线),-1 = 翻转(法向反了)。 * * 公式:J = det([b-a, c-a, n]) / (|b-a|·|c-a|·|b-c|? or area-based?) * 实际实现使用面积与理想等边三角形面积之比。 * * @param a,b,c 三角形三个顶点 * @return 归一化 Jacobian [-1, 1] * * @ingroup mesh */ double tri_scaled_jacobian(const Point3D& a, const Point3D& b, const Point3D& c); /** * @brief 四面体归一化 Jacobian * * 计算四面体 (a,b,c,d) 的体积 Jacobian,归一化到 [0, 1]。 * 值 1 = 正四面体(最优),0 = 退化(共面)。 * * 公式:J = det([b-a, c-a, d-a]) / (归一化因子) * * @param a,b,c,d 四面体四个顶点 * @return 归一化 Jacobian [0, 1] * * @ingroup mesh */ double tet_scaled_jacobian(const Point3D& a, const Point3D& b, const Point3D& c, const Point3D& d); } // namespace vde::mesh