Files
ViewDesignEngine/include/vde/mesh/mesh_quality.h
T
茂之钳 4c9ee4f760
CI / Build & Test (push) Failing after 29s
CI / Release Build (push) Failing after 38s
docs: doxygen annotations for curves + mesh + sketch
2026-07-24 11:04:04 +00:00

217 lines
7.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include "vde/mesh/halfedge_mesh.h"
#include <cmath>
#include <vector>
#include <string>
#include <array>
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<size_t, kBins> 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