Files
ViewDesignEngine/tests/regression/regression_large_model.cpp
T
茂之钳 7b76689ea1
CI / Build & Test (push) Failing after 41s
CI / Release Build (push) Failing after 30s
Build & Test / build-and-test (push) Has been cancelled
Build & Test / python-bindings (push) Has been cancelled
feat(v11): CI/CD + regression tests + fuzzing + benchmarks + code quality
v11.1 — Test Infrastructure (14 files):
- .github/workflows/ci.yml: Ubuntu 22.04 + GCC 11, auto ctest on push
- tests/regression/: degenerate geometry, extreme coords, thin wall, large models
- tests/fuzz/: SDF random CSG, random booleans, format round-trip, continuous mode
- tests/benchmark/: boolean perf, MC perf, IO perf benchmarks
- docs/benchmark-report.md: benchmark template

v11.2 — Code Quality + Docs:
- .clang-tidy: 15 check categories, 22 exclusions
- .github/workflows/static-analysis.yml: clang-tidy CI scan
- CODEOWNERS, SECURITY.md
- docs: API overview, testing guide, contributing guide
- README: module capability overview table

Pending: binary formats + curve projection (retrying)
2026-07-27 01:10:58 +08:00

189 lines
6.5 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.
/// @file regression_large_model.cpp
/// @brief 大面数回归测试(1000+ 面模型)
///
/// 覆盖场景:
/// 1. 通过高细分球体/圆柱产生 1000+ 面的模型
/// 2. 大面数模型的布尔运算
/// 3. 大面数模型的验证(validate
/// 4. 大面数模型的修复
///
/// 每个测试:构造大面数体 → 布尔/修复/验证 → 断言不崩溃
#include <gtest/gtest.h>
#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 <cmath>
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();
});
}