#include #include "vde/mesh/mesh_quality.h" #include "vde/mesh/halfedge_mesh.h" using namespace vde::mesh; TEST(MeshQualityTest, EquilateralTriangle_PerfectQuality) { HalfedgeMesh mesh; // Equilateral triangle side length ≈ 1.155 for area ≈ 0.577 double h = std::sqrt(3.0) / 2.0; mesh.build_from_triangles( {Point3D(0, 0, 0), Point3D(1, 0, 0), Point3D(0.5, h, 0)}, {{0, 1, 2}} ); auto q = evaluate_mesh_quality(mesh); // Equilateral triangle: all angles = 60° EXPECT_NEAR(q.min_angle_deg, 60.0, 1.0); EXPECT_NEAR(q.max_angle_deg, 60.0, 1.0); // Aspect ratio ~1 for equilateral EXPECT_NEAR(q.avg_aspect_ratio, 1.0, 0.1); EXPECT_EQ(q.degenerate_faces, 0u); } TEST(MeshQualityTest, DegenerateTriangle_ZeroArea) { HalfedgeMesh mesh; // Collinear points → zero area mesh.build_from_triangles( {Point3D(0, 0, 0), Point3D(1, 0, 0), Point3D(2, 0, 0)}, {{0, 1, 2}} ); auto q = evaluate_mesh_quality(mesh); EXPECT_EQ(q.degenerate_faces, 1u); } TEST(MeshQualityTest, ObtuseTriangle_LargeMaxAngle) { HalfedgeMesh mesh; // Very flat obtuse triangle: (0,0), (10,0), (0,0.1) mesh.build_from_triangles( {Point3D(0, 0, 0), Point3D(10, 0, 0), Point3D(0, 0.1, 0)}, {{0, 1, 2}} ); auto q = evaluate_mesh_quality(mesh); // Max angle should be very close to 180 (or at least > 90) EXPECT_GT(q.max_angle_deg, 90.0); // Min angle should be very small EXPECT_LT(q.min_angle_deg, 10.0); } TEST(MeshQualityTest, RightTriangle) { HalfedgeMesh mesh; // 3-4-5 right triangle mesh.build_from_triangles( {Point3D(0, 0, 0), Point3D(3, 0, 0), Point3D(0, 4, 0)}, {{0, 1, 2}} ); auto q = evaluate_mesh_quality(mesh); // Right triangle: one angle ~90°, others ~36.87° and ~53.13° EXPECT_NEAR(q.max_angle_deg, 90.0, 2.0); EXPECT_GT(q.min_angle_deg, 30.0); EXPECT_EQ(q.degenerate_faces, 0u); } TEST(MeshQualityTest, MultipleTriangles_Mixed) { HalfedgeMesh mesh; // Two triangles: one good, one degenerate double h = std::sqrt(3.0) / 2.0; mesh.build_from_triangles( { Point3D(0, 0, 0), Point3D(1, 0, 0), Point3D(0.5, h, 0), // equilateral Point3D(10, 0, 0), Point3D(11, 0, 0), Point3D(12, 0, 0), // degenerate }, {{0, 1, 2}, {3, 4, 5}} ); auto q = evaluate_mesh_quality(mesh); EXPECT_EQ(q.degenerate_faces, 1u); // Average aspect ratio should reflect the mix EXPECT_GT(q.avg_aspect_ratio, 0.5); // mixed quality, should be > 0.5 } TEST(MeshQualityTest, EmptyMesh) { HalfedgeMesh mesh; auto q = evaluate_mesh_quality(mesh); EXPECT_EQ(q.degenerate_faces, 0u); // Default values for empty mesh EXPECT_DOUBLE_EQ(q.min_angle_deg, 0.0); EXPECT_DOUBLE_EQ(q.max_angle_deg, 0.0); } TEST(MeshQualityTest, HighAspectRatioTriangle) { HalfedgeMesh mesh; // Very thin triangle mesh.build_from_triangles( {Point3D(0, 0, 0), Point3D(100, 0, 0), Point3D(0, 0.01, 0)}, {{0, 1, 2}} ); auto q = evaluate_mesh_quality(mesh); // Aspect ratio should be very high EXPECT_GT(q.max_aspect_ratio, 10.0); }