/// @file regression_large_model.cpp /// @brief 大面数回归测试(1000+ 面模型) /// /// 覆盖场景: /// 1. 通过高细分球体/圆柱产生 1000+ 面的模型 /// 2. 大面数模型的布尔运算 /// 3. 大面数模型的验证(validate) /// 4. 大面数模型的修复 /// /// 每个测试:构造大面数体 → 布尔/修复/验证 → 断言不崩溃 #include #include "vde/brep/brep.h" #include "vde/brep/modeling.h" #include "vde/brep/brep_boolean.h" #include "vde/brep/brep_validate.h" #include "vde/brep/brep_heal.h" #include "vde/core/point.h" #include using namespace vde::brep; using namespace vde::core; /// 生成一个高面数的球体 /// seg_u × seg_v 段 → 大约 2 * seg_u * seg_v 个面 /// 例如 seg_u=50, seg_v=50 → 约 5000 面 static BrepModel make_highres_sphere(double radius, int seg_u, int seg_v) { return make_sphere(radius, seg_u, seg_v); } /// 生成一个高面数的圆柱体 /// segments 段 → 侧面有 segments * 1 个面,加上顶/底面 static BrepModel make_highres_cylinder(double radius, double height, int segments) { return make_cylinder(radius, height, segments); } // ═══════════════════════════════════════════════ // 1000+ 面模型 - 球体 // ═══════════════════════════════════════════════ TEST(RegressionLargeModel, Sphere_1000PlusFaces) { // seg_u=25, seg_v=20 → 2*25*20 = 1000 faces EXPECT_NO_THROW({ auto sphere = make_sphere(10.0, 25, 20); EXPECT_TRUE(sphere.is_valid()); EXPECT_GE(sphere.num_faces(), 800u); // 至少 800 面 // 验证 auto result = validate(sphere); (void)result; // 导出网格 auto mesh = sphere.to_mesh(0.05); (void)mesh; }); } TEST(RegressionLargeModel, Sphere_5000PlusFaces) { // seg_u=55, seg_v=50 → 2*55*50 = 5500 faces EXPECT_NO_THROW({ auto sphere = make_sphere(5.0, 55, 50); EXPECT_TRUE(sphere.is_valid()); EXPECT_GE(sphere.num_faces(), 4000u); auto result = validate(sphere); (void)result; auto mesh = sphere.to_mesh(0.01); (void)mesh; }); } // ═══════════════════════════════════════════════ // 1000+ 面模型 - 圆柱体 // ═══════════════════════════════════════════════ TEST(RegressionLargeModel, Cylinder_1000PlusFaces) { // segments=1000 → 侧面有很多面 EXPECT_NO_THROW({ auto cyl = make_cylinder(5.0, 10.0, 1000); EXPECT_TRUE(cyl.is_valid()); // seg=1000 时侧面有 1000 个面 + 上下各 1(或更多)面 EXPECT_GE(cyl.num_faces(), 900u); auto result = validate(cyl); (void)result; auto mesh = cyl.to_mesh(); (void)mesh; }); } // ═══════════════════════════════════════════════ // 大面数模型布尔运算 // ═══════════════════════════════════════════════ TEST(RegressionLargeModel, Boolean_LargeSphereUnion) { auto s1 = make_sphere(5.0, 30, 24); // ~1440 faces auto s2 = make_sphere(3.0, 20, 16); // ~640 faces EXPECT_NO_THROW({ auto u = brep_union(s1, s2); EXPECT_TRUE(u.is_valid()); auto result = validate(u); (void)result; }); } TEST(RegressionLargeModel, Boolean_LargeSphereIntersection) { auto s1 = make_sphere(5.0, 30, 24); auto s2 = make_sphere(3.0, 24, 20); EXPECT_NO_THROW({ auto i = brep_intersection(s1, s2); EXPECT_TRUE(i.is_valid()); }); } TEST(RegressionLargeModel, Boolean_LargeCylinders) { // 高分辨率圆柱布尔运算 auto c1 = make_cylinder(3.0, 10.0, 500); auto c2 = make_cylinder(2.0, 8.0, 300); EXPECT_NO_THROW({ auto u = brep_union(c1, c2); EXPECT_TRUE(u.is_valid()); auto d = brep_difference(c1, c2); EXPECT_TRUE(d.is_valid()); }); } // ═══════════════════════════════════════════════ // 大面数模型修复 // ═══════════════════════════════════════════════ TEST(RegressionLargeModel, Heal_LargeModel) { auto sphere = make_sphere(10.0, 30, 24); EXPECT_GE(sphere.num_faces(), 1000u); EXPECT_NO_THROW({ // 修复大面数模型 heal_gaps(sphere, 1e-6); heal_slivers(sphere); bool ok = heal_topology(sphere, 1e-4); (void)ok; }); } // ═══════════════════════════════════════════════ // 多体布尔链式操作(压力测试) // ═══════════════════════════════════════════════ TEST(RegressionLargeModel, Stress_ChainedBooleans) { auto box = make_box(10.0, 10.0, 10.0); auto cyl = make_cylinder(0.5, 15.0, 128); // 连续执行多次布尔运算,最终模型可能包含大量面 EXPECT_NO_THROW({ auto u = brep_union(box, cyl); for (int i = 0; i < 3; ++i) { auto d = brep_difference(u, make_sphere(0.3 + i * 0.1, 16, 8)); u = d; // chain } EXPECT_TRUE(u.is_valid()); auto result = validate(u); (void)result; auto mesh = u.to_mesh(0.05); (void)mesh; }); } // ═══════════════════════════════════════════════ // 大面数模型导出 // ═══════════════════════════════════════════════ TEST(RegressionLargeModel, Export_LargeMesh) { auto sphere = make_sphere(10.0, 40, 32); // ~2560 faces EXPECT_GE(sphere.num_faces(), 2000u); EXPECT_NO_THROW({ // 导出为精细网格 auto mesh = sphere.to_mesh(0.001); (void)mesh.num_vertices(); (void)mesh.num_faces(); }); }