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)
This commit is contained in:
+49
-38
@@ -1,50 +1,61 @@
|
||||
# ViewDesignEngine 性能基准报告
|
||||
|
||||
> 生成: 2026-07-24 | 环境: ECS 4核 2.5GHz, Ubuntu 22.04, GCC 11.4
|
||||
> 自动生成于: 2026-07-27
|
||||
> 下一更新: CI 每次运行后自动更新
|
||||
|
||||
## BVH (包围盒层次)
|
||||
---
|
||||
|
||||
| 指标 | 规模 | 耗时 | 吞吐 |
|
||||
|------|------|------|------|
|
||||
| BVH 构建 | 500 tris | 73.9 µs | 6.8M tris/s |
|
||||
| BVH 构建 | 1000 tris | 253 µs | 4.0M tris/s |
|
||||
| BVH 构建 | 2000 tris | 656 µs | 3.1M tris/s |
|
||||
| 射线查询 | 500 tris | 1.38 ms | 726k queries/s |
|
||||
| 射线查询 | 1000 tris | 2.06 ms | 488k queries/s |
|
||||
| 射线查询 | 2000 tris | 3.21 ms | 313k queries/s |
|
||||
## 1. 布尔运算性能
|
||||
|
||||
## Delaunay 三角剖分
|
||||
测试不同面数模型的布尔运算(并集/交集/差集)耗时。
|
||||
|
||||
| 指标 | 规模 | 耗时 | 吞吐 |
|
||||
|------|------|------|------|
|
||||
| Delaunay 2D | 100 pts | 64.8 µs | 1.55M pts/s |
|
||||
| Delaunay 2D | 1000 pts | 3.97 ms | 253k pts/s |
|
||||
| Delaunay 2D | 10000 pts | 659 ms | 15.2k pts/s |
|
||||
| 测试名称 | 耗时 (ms) | 模型A面数 | 模型B面数 | 结果面数 |
|
||||
|----------|-----------|-----------|-----------|----------|
|
||||
| Boolean.Union/Small | - | - | - | - |
|
||||
| Boolean.Union/Medium | - | - | - | - |
|
||||
| Boolean.Union/Large | - | - | - | - |
|
||||
| Boolean.Intersection/Small | - | - | - | - |
|
||||
| Boolean.Intersection/Medium | - | - | - | - |
|
||||
| Boolean.Intersection/Large | - | - | - | - |
|
||||
| Boolean.Difference/Small | - | - | - | - |
|
||||
| Boolean.Difference/Medium | - | - | - | - |
|
||||
| Boolean.Difference/Large | - | - | - | - |
|
||||
|
||||
## 曲线求值
|
||||
## 2. MC / Tessellation 性能
|
||||
|
||||
| 指标 | 规模 | 耗时 | 吞吐 |
|
||||
|------|------|------|------|
|
||||
| Bézier 求值 | 10K evals | 277 µs | 36M evals/s |
|
||||
| Bézier 求值 | 100K evals | 2.64 ms | 38M evals/s |
|
||||
| B-Spline 求值 | 10K evals | 720 µs | 14M evals/s |
|
||||
| B-Spline 求值 | 100K evals | 7.14 ms | 14M evals/s |
|
||||
测试 SDF 求值和 B-Rep→Mesh 的 tessellation 耗时。
|
||||
|
||||
## 空间索引
|
||||
| 测试名称 | 耗时 (ms) | 分辨率 | 输出三角形数 |
|
||||
|----------|-----------|--------|-------------|
|
||||
| MC.Evaluate/LowRes-10pts | - | 10 | - |
|
||||
| MC.Evaluate/MediumRes-1000pts | - | 1000 | - |
|
||||
| MC.BrepToMesh/LowDeflection | - | - | - |
|
||||
| MC.BrepToMesh/MediumDeflection | - | - | - |
|
||||
| MC.BrepToMesh/HighDeflection | - | - | - |
|
||||
| MC.BrepToMesh/ComplexModel | - | - | - |
|
||||
|
||||
| 指标 | 规模 | 耗时 | 吞吐 |
|
||||
|------|------|------|------|
|
||||
| R-Tree 构建 | 500 items | 19.2 µs | 26.1M items/s |
|
||||
| R-Tree 构建 | 1000 items | 35.7 µs | 28.2M items/s |
|
||||
| R-Tree 构建 | 2000 items | 151 µs | 13.3M items/s |
|
||||
| R-Tree kNN | 500 items | 23.9 µs | 842k queries/s |
|
||||
| R-Tree kNN | 1000 items | 27.5 µs | 731k queries/s |
|
||||
## 3. 导入/导出性能
|
||||
|
||||
## 网格布尔运算
|
||||
测试 IGES/STEP 格式的序列化和反序列化耗时。
|
||||
|
||||
| 指标 | 规模 | 耗时 | 吞吐 |
|
||||
|------|------|------|------|
|
||||
| Union | ~100 faces | 2.00 ms | 501 ops/s |
|
||||
| Union | ~500 faces | 9.69 ms | 104 ops/s |
|
||||
| Intersection | ~100 faces | 1.85 ms | 544 ops/s |
|
||||
| Intersection | ~500 faces | 8.32 ms | 121 ops/s |
|
||||
| 测试名称 | 耗时 (ms) | 数据大小 (bytes) |
|
||||
|----------|-----------|-----------------|
|
||||
| IO.IGES.Export/SingleBox | - | - |
|
||||
| IO.IGES.Export/Sphere16x8 | - | - |
|
||||
| IO.IGES.Import/SingleBox | - | - |
|
||||
| IO.STEP.Export/SingleBox | - | - |
|
||||
| IO.STEP.Export/Sphere16x8 | - | - |
|
||||
| IO.STEP.Export/Cylinder32 | - | - |
|
||||
| IO.STEP.Import/SingleBox | - | - |
|
||||
| IO.STEP.Export/LargeSphere32x16 | - | - |
|
||||
| IO.IGES.Export/LargeSphere32x16 | - | - |
|
||||
| IO.STEP.Export/MultiBody(4) | - | - |
|
||||
|
||||
---
|
||||
|
||||
## 说明
|
||||
|
||||
- 表内 `-` 表示尚未运行基准测试,请通过 `ctest -R Benchmark` 运行后更新
|
||||
- 所有耗时取 3~5 次迭代的最佳值
|
||||
- 模型面数基于 `BrepModel::num_faces()` 统计
|
||||
- 环境: Ubuntu 22.04, GCC 11, Release 模式编译
|
||||
|
||||
@@ -165,6 +165,81 @@ ViewDesignEngine 提供 C++17 头文件 API,所有公开接口位于 `include/
|
||||
|
||||
详见 [插件系统设计](plugin-system.md)。
|
||||
|
||||
## 模块间依赖关系
|
||||
|
||||
ViewDesignEngine 采用分层架构,模块间依赖严格单向,杜绝循环依赖。
|
||||
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ vde (聚合接口库) │
|
||||
└──────────────┬──────────────────┘
|
||||
┌────────────────────────┼────────────────────────┐
|
||||
│ │ │
|
||||
┌────────┴────────┐ ┌────────┴────────┐ ┌────────┴────────┐
|
||||
│ vde_capi │ │ vde_brep │ │ vde_plugin │
|
||||
│ (C ABI 出口) │ │ (B-Rep 建模) │ │ (v6.0+ 插件) │
|
||||
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
|
||||
│ │ │
|
||||
┌─────────┼───────────────┬───────┼───────┬───────────────┘
|
||||
│ │ │ │ │
|
||||
▼ ▼ ▼ ▼ ▼
|
||||
┌──────────┐┌──────────┐┌──────────┐┌──────────┐┌──────────┐
|
||||
│ vde_sdf ││vde_sketch││vde_curves││vde_mesh ││vde_ │
|
||||
│隐式建模 ││草图约束 ││曲线曲面 ││网格处理 ││collision │
|
||||
└────┬─────┘└────┬─────┘└────┬─────┘└────┬─────┘└────┬─────┘
|
||||
│ │ │ │ │
|
||||
└───────────┴───────────┼───────────┴───────────┘
|
||||
│
|
||||
┌─────────┴──────────┐
|
||||
│ │
|
||||
┌─────┴─────┐ ┌─────┴─────┐
|
||||
│ vde_core │ │vde_spatial│
|
||||
│ 几何核心 │ │ 空间索引 │
|
||||
└─────┬─────┘ └─────┬─────┘
|
||||
│ │
|
||||
└──────────┬─────────┘
|
||||
│
|
||||
┌──────────┴──────────┐
|
||||
│ vde_foundation │
|
||||
│ 基础设施层 │
|
||||
└──────────┬──────────┘
|
||||
│
|
||||
┌──────────┴──────────┐
|
||||
│ Eigen3 (外部依赖) │
|
||||
└─────────────────────┘
|
||||
```
|
||||
|
||||
### 依赖矩阵
|
||||
|
||||
| 模块 | foundation | core | spatial | curves | mesh | collision | boolean | brep | sdf | sketch |
|
||||
|------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||
| **foundation** | — | — | — | — | — | — | — | — | — | — |
|
||||
| **core** | ✅ | — | — | — | — | — | — | — | — | — |
|
||||
| **spatial** | — | ✅ | — | — | — | — | — | — | — | — |
|
||||
| **curves** | — | ✅ | — | — | — | — | — | — | — | — |
|
||||
| **mesh** | — | ✅ | — | — | — | — | — | ✅¹ | — | — |
|
||||
| **collision** | — | ✅ | ✅ | — | — | — | — | — | — | — |
|
||||
| **boolean** | — | ✅ | ✅ | — | ✅ | — | — | — | — | — |
|
||||
| **brep** | — | — | — | ✅ | ✅ | ✅ | — | — | — | — |
|
||||
| **sdf** | — | ✅ | — | — | ✅ | — | — | — | — | — |
|
||||
| **sketch** | — | ✅ | — | — | — | — | — | — | — | — |
|
||||
| **capi** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| **plugin** | ✅ | — | — | — | — | — | — | — | — | — |
|
||||
|
||||
> ¹ vde_mesh → vde_brep 依赖仅用于拓扑转换(BrepModel → HalfedgeMesh),是单向弱依赖。
|
||||
|
||||
### 层次说明
|
||||
|
||||
| 层 | 模块 | 职责 | 上游依赖数 |
|
||||
|----|------|------|:--------:|
|
||||
| L0 基础 | foundation | 数学类型、I/O、公差、精确谓词 | 0 (仅 Eigen) |
|
||||
| L1 核心 | core, spatial | 几何算法 + 空间索引 | 1 |
|
||||
| L2 曲面 | curves | 曲线曲面计算 | 1 |
|
||||
| L3 网格 | mesh | 网格处理与重建 | 2 |
|
||||
| L4 检测 | collision, boolean | 碰撞检测、布尔运算 | 2–3 |
|
||||
| L5 领域 | brep, sdf, sketch | 高层建模 | 3–4 |
|
||||
| L6 出口 | capi, plugin | 跨语言接口、扩展机制 | 0–10 |
|
||||
|
||||
## 核心类型速查
|
||||
|
||||
| 类型 | 命名空间 | 说明 |
|
||||
|
||||
@@ -204,6 +204,108 @@ Closes #42
|
||||
|
||||
## 6. Code Review 流程
|
||||
|
||||
### 6.1 Pull Request 规范
|
||||
|
||||
所有代码变更必须通过 PR (Pull Request) 提交至 `main` 分支。PR 审核通过后方可合并。
|
||||
|
||||
#### PR 标题格式
|
||||
|
||||
```
|
||||
<type>(<scope>): <简短描述>
|
||||
|
||||
# 示例
|
||||
feat(brep): 添加变径圆角支持
|
||||
fix(mesh): 修复 Delaunay 3D 退化四面体崩溃
|
||||
docs(api): 更新 B-Rep 模块 API 文档
|
||||
refactor(core): 将 Polygon2D 迁移到 SoA 布局
|
||||
test(sdf): 增加 SDF 梯度计算精度测试
|
||||
perf(spatial): BVH SAH 构建改用 OpenMP 并行化
|
||||
```
|
||||
|
||||
#### PR 描述模板
|
||||
|
||||
```markdown
|
||||
## 变更概述
|
||||
<!-- 用一两句话描述这个 PR 做了什么 -->
|
||||
|
||||
## 变更类型
|
||||
- [ ] Bug 修复
|
||||
- [ ] 新功能
|
||||
- [ ] 重构
|
||||
- [ ] 性能优化
|
||||
- [ ] 文档
|
||||
- [ ] 测试
|
||||
- [ ] CI/构建
|
||||
|
||||
## 关联 Issue
|
||||
Closes #
|
||||
|
||||
## 测试计划
|
||||
- [ ] 新增测试用例 N 个
|
||||
- [ ] 已有测试全部通过
|
||||
- [ ] ASan/UBSan 通过
|
||||
- [ ] 性能基准无退化
|
||||
|
||||
## 影响范围
|
||||
<!-- 变更影响了哪些模块/API -->
|
||||
|
||||
## 截图/日志(如适用)
|
||||
|
||||
## Checklist
|
||||
- [ ] 代码符合 [代码规范](contributing.md#4-代码规范)
|
||||
- [ ] 通过了 `cmake --build build -j$(nproc)` 零错误零警告
|
||||
- [ ] 新公开 API 有 Doxygen 注释
|
||||
- [ ] CHANGELOG 已更新
|
||||
- [ ] 文档已更新(如有必要)
|
||||
```
|
||||
|
||||
#### PR 分支命名
|
||||
|
||||
| 前缀 | 用途 | 示例 |
|
||||
|------|------|------|
|
||||
| `feat/` | 新功能 | `feat/variable-radius-fillet` |
|
||||
| `fix/` | Bug 修复 | `fix/delaunay-degenerate-tet` |
|
||||
| `refactor/` | 重构 | `refactor/polygon-soa-layout` |
|
||||
| `perf/` | 性能优化 | `perf/bvh-sah-openmp` |
|
||||
| `docs/` | 文档 | `docs/api-reference-update` |
|
||||
| `test/` | 测试补充 | `test/sdf-gradient-precision` |
|
||||
| `ci/` | CI/构建 | `ci/add-clang-tidy-check` |
|
||||
| `release/` | 发布准备 | `release/v5.5.0` |
|
||||
|
||||
#### PR 生命周期
|
||||
|
||||
```
|
||||
创建 PR → CI 自动检查 → Reviewer 审核 → 修改迭代 → 批准 → Squash Merge
|
||||
│ │ │ │ │ │
|
||||
│ ┌────┴────┐ ┌────┴────┐ ┌────┴────┐ │ ┌────┴────┐
|
||||
│ │编译测试 │ │代码逻辑 │ │force push│ │ │单 commit│
|
||||
│ │clang-tidy│ │风格规范 │ │amend │ │ │合入 main│
|
||||
│ │ASan/UBSan│ │测试覆盖 │ │rebase │ │ │删除分支 │
|
||||
│ └─────────┘ └─────────┘ └─────────┘ │ └─────────┘
|
||||
└── 每个 PR 一个分支,从 main 最新 commit 分出
|
||||
```
|
||||
|
||||
#### PR 大小限制
|
||||
|
||||
| 类型 | 建议行数 | 审核时间 |
|
||||
|------|:------:|:------:|
|
||||
| 小型 PR | < 200 行 | 1 天内 |
|
||||
| 中型 PR | 200–800 行 | 1–3 天 |
|
||||
| 大型 PR | > 800 行 | 需拆分提交 |
|
||||
|
||||
> 大型功能应拆分为多个小型 PR,每个 PR 独立可测试、可合并。禁止一次提交多个不相关功能。
|
||||
|
||||
#### 合并策略
|
||||
|
||||
- **Squash Merge**:所有 commit 合并为一个,保持 `main` 历史整洁
|
||||
- **合并条件**:
|
||||
- [x] CI 全部通过(编译 + 测试 + clang-tidy + ASan)
|
||||
- [x] 至少 1 名 Reviewer 批准
|
||||
- [x] 无未解决的 Review 意见
|
||||
- [x] 分支与 main 无冲突(rebase 解决)
|
||||
|
||||
### 6.2 Code Review 流程
|
||||
|
||||
1. **提交者**: 创建 PR,填写描述,关联 Issue
|
||||
2. **CI 检查**: 自动编译 + 测试必须通过
|
||||
3. **Reviewer**: 检查代码逻辑、风格、测试覆盖
|
||||
|
||||
@@ -111,6 +111,101 @@ docker run --rm --cpus=4 --memory=8g \
|
||||
|
||||
## 3. 编写测试
|
||||
|
||||
### 3.0 如何添加新测试(完整步骤)
|
||||
|
||||
向 ViewDesignEngine 添加新测试遵循以下标准工作流:
|
||||
|
||||
**步骤 1: 创建测试文件**
|
||||
|
||||
在对应模块的测试目录下创建 `test_<feature>.cpp`:
|
||||
|
||||
```bash
|
||||
# 例如:为 brep 模块的新功能添加测试
|
||||
touch tests/brep/test_new_feature.cpp
|
||||
```
|
||||
|
||||
**步骤 2: 编写测试代码**
|
||||
|
||||
```cpp
|
||||
// tests/brep/test_new_feature.cpp
|
||||
#include <gtest/gtest.h>
|
||||
#include "vde/brep/modeling.h"
|
||||
#include "vde/brep/new_feature.h" // 被测头文件
|
||||
|
||||
using namespace vde::brep;
|
||||
using namespace vde::core;
|
||||
|
||||
// 基本功能测试
|
||||
TEST(NewFeatureTest, BasicOperation) {
|
||||
auto box = make_box(2, 2, 2);
|
||||
auto result = new_feature_operation(box, /* params */);
|
||||
EXPECT_TRUE(result.is_valid());
|
||||
}
|
||||
|
||||
// 边界条件测试
|
||||
TEST(NewFeatureTest, EmptyInput) {
|
||||
BrepModel empty;
|
||||
EXPECT_THROW(new_feature_operation(empty), std::invalid_argument);
|
||||
}
|
||||
|
||||
// 数值精度测试
|
||||
TEST(NewFeatureTest, NumericalPrecision) {
|
||||
auto sphere = make_sphere(1.0);
|
||||
auto result = new_feature_operation(sphere, /* params */);
|
||||
EXPECT_NEAR(result.volume(), 4.18879, 1e-5);
|
||||
}
|
||||
```
|
||||
|
||||
**步骤 3: 注册到 CMake**
|
||||
|
||||
编辑 `tests/<module>/CMakeLists.txt`,使用标准宏:
|
||||
|
||||
```cmake
|
||||
# tests/brep/CMakeLists.txt
|
||||
|
||||
# 方式 A:使用 add_vde_test 宏(自动链接聚合库 vde)
|
||||
add_vde_test(test_new_feature)
|
||||
|
||||
# 方式 B:如需精确控制链接(避免聚合库中其他模块的预存错误)
|
||||
add_executable(test_new_feature test_new_feature.cpp)
|
||||
target_link_libraries(test_new_feature PRIVATE
|
||||
vde_brep vde_curves vde_core vde_foundation
|
||||
GTest::gtest GTest::gtest_main
|
||||
)
|
||||
add_test(NAME test_new_feature COMMAND test_new_feature)
|
||||
```
|
||||
|
||||
**步骤 4: 本地验证**
|
||||
|
||||
```bash
|
||||
# 配置构建
|
||||
cmake -B build -DBUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
# 只编译新测试目标
|
||||
cmake --build build --target test_new_feature -j$(nproc)
|
||||
|
||||
# 运行新测试
|
||||
./build/tests/brep/test_new_feature
|
||||
|
||||
# 运行特定用例
|
||||
./build/tests/brep/test_new_feature --gtest_filter="*BasicOperation*"
|
||||
|
||||
# 确认不破坏已有测试
|
||||
cd build && ctest --output-on-failure -j$(nproc)
|
||||
```
|
||||
|
||||
**步骤 5: Docker 环境验证(推荐)**
|
||||
|
||||
```bash
|
||||
docker run --rm --cpus=2 --memory=8g \
|
||||
-v /root/workspace:/ws -w /ws/ViewDesignEngine \
|
||||
vde-builder:latest bash -c "
|
||||
cmake -B build_verify -DBUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Release &&
|
||||
cmake --build build_verify --target test_new_feature -j2 &&
|
||||
./build_verify/tests/brep/test_new_feature
|
||||
"
|
||||
```
|
||||
|
||||
### 3.1 基本模板
|
||||
|
||||
```cpp
|
||||
|
||||
Reference in New Issue
Block a user