Files
ViewDesignEngine/tests/brep/test_step_export.cpp
T
茂之钳 8a19e265cd
CI / Build & Test (push) Failing after 40s
CI / Release Build (push) Failing after 1m31s
feat(v2.0.0): Sprint 10 — B-Rep完善 + STEP导入/导出 + 布尔运算 + 验证
S10-A: B-Rep modeling 补齐
- fillet: 恒定半径滚动球倒圆(NURBS 曲面构建 + 相邻面裁剪)
- chamfer: 等距倒角(平面偏移 + 倒角面构建)
- shell: 完整抽壳(顶点偏移 + 内外面 + 开口侧壁)

S10-B: STEP AP203/AP214 导入
- ISO 10303-21 解析器(1,424 行)
- 支持 14 种几何实体 → NurbsCurve/NurbsSurface 转换
- 完整拓扑链:VERTEX_POINT → EDGE_CURVE → EDGE_LOOP → ADVANCED_FACE → CLOSED_SHELL → MANIFOLD_SOLID_BREP
- 装配支持:NEXT_ASSEMBLY_USAGE_OCCURRENCE + CONTEXT_DEPENDENT_SHAPE_REPRESENTATION

S10-C.1: STEP AP214 导出
- export_step / export_step_file
- 曲线/曲面类型自动检测简化输出

S10-C.2: B-Rep 级布尔运算
- brep_union / brep_intersection / brep_difference
- 面-面求交 + 内/外分类 + 面缝合

S10-C.3: B-Rep 工程验证
- ValidationResult: 水密性/悬边/自相交/方向一致性/欧拉示性数

测试: 5 个新测试文件,47 项测试(modeling/STEP导入/导出/布尔/验证)

修改: 7 files (+576/-47) | 新增: 13 files (4,141 行)
总计: +4,670 行
2026-07-24 05:18:52 +00:00

167 lines
7.1 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.
#include <gtest/gtest.h>
#include "vde/brep/brep.h"
#include "vde/brep/modeling.h"
#include "vde/brep/step_export.h"
#include <fstream>
#include <sstream>
#include <algorithm>
using namespace vde::brep;
using namespace vde::core;
// ═══════════════════════════════════════════════════════════
// STEP export basic tests
// ═══════════════════════════════════════════════════════════
TEST(StepExportTest, ExportBox_ProducesValidStructure) {
auto box = make_box(2, 3, 4);
std::string step = export_step({box});
// Must start with ISO-10303-21 header
EXPECT_TRUE(step.find("ISO-10303-21;") != std::string::npos);
// Must contain HEADER section
EXPECT_TRUE(step.find("HEADER;") != std::string::npos);
EXPECT_TRUE(step.find("ENDSEC;") != std::string::npos);
// Must contain DATA section
EXPECT_TRUE(step.find("DATA;") != std::string::npos);
// Must contain CARTESIAN_POINT entities
EXPECT_TRUE(step.find("CARTESIAN_POINT") != std::string::npos);
// Must contain topology entities
EXPECT_TRUE(step.find("CLOSED_SHELL") != std::string::npos ||
step.find("ADVANCED_FACE") != std::string::npos);
// Must end properly
EXPECT_TRUE(step.find("END-ISO-10303-21;") != std::string::npos);
}
TEST(StepExportTest, ExportBox_ContainsManifoldSolidBrep) {
auto box = make_box(1, 1, 1);
std::string step = export_step({box});
EXPECT_TRUE(step.find("MANIFOLD_SOLID_BREP") != std::string::npos);
}
TEST(StepExportTest, ExportBox_ContainsPlanes) {
auto box = make_box(2, 2, 2);
std::string step = export_step({box});
// Box faces are degree 1×1 → should export as PLANE
EXPECT_TRUE(step.find("PLANE") != std::string::npos ||
step.find("B_SPLINE_SURFACE") != std::string::npos);
}
TEST(StepExportTest, ExportBox_ContainsEdgeCurve) {
auto box = make_box(1, 1, 1);
std::string step = export_step({box});
EXPECT_TRUE(step.find("EDGE_CURVE") != std::string::npos);
}
TEST(StepExportTest, ExportBox_ContainsOrientedEdge) {
auto box = make_box(1, 1, 1);
std::string step = export_step({box});
EXPECT_TRUE(step.find("ORIENTED_EDGE") != std::string::npos);
}
TEST(StepExportTest, ExportBox_HasProperEntityNumbering) {
auto box = make_box(1, 1, 1);
std::string step = export_step({box});
// Should have at least entity #1
EXPECT_TRUE(step.find("#1 =") != std::string::npos);
// Count entity occurrences to ensure numbering is sequential
int entity_count = 0;
size_t pos = 0;
while ((pos = step.find("= ", pos)) != std::string::npos) {
entity_count++;
pos += 2;
}
EXPECT_GT(entity_count, 5);
}
// ═══════════════════════════════════════════════════════════
// Sphere STEP export
// ═══════════════════════════════════════════════════════════
TEST(StepExportTest, ExportSphere_ProducesValidOutput) {
auto sphere = make_sphere(2.0);
std::string step = export_step({sphere});
EXPECT_TRUE(step.find("ISO-10303-21;") != std::string::npos);
EXPECT_TRUE(step.find("CARTESIAN_POINT") != std::string::npos);
EXPECT_TRUE(step.find("MANIFOLD_SOLID_BREP") != std::string::npos ||
step.find("CLOSED_SHELL") != std::string::npos);
}
// ═══════════════════════════════════════════════════════════
// Cylinder STEP export
// ═══════════════════════════════════════════════════════════
TEST(StepExportTest, ExportCylinder_ProducesValidOutput) {
auto cyl = make_cylinder(1.0, 4.0);
std::string step = export_step({cyl});
EXPECT_TRUE(step.find("ISO-10303-21;") != std::string::npos);
EXPECT_TRUE(step.find("CARTESIAN_POINT") != std::string::npos);
}
// ═══════════════════════════════════════════════════════════
// Multiple bodies
// ═══════════════════════════════════════════════════════════
TEST(StepExportTest, ExportMultipleBodies_ProducesValidOutput) {
auto box1 = make_box(1, 1, 1);
auto box2 = make_box(2, 2, 2);
std::string step = export_step({box1, box2});
EXPECT_TRUE(step.find("ISO-10303-21;") != std::string::npos);
EXPECT_TRUE(step.find("MANIFOLD_SOLID_BREP") != std::string::npos);
}
// ═══════════════════════════════════════════════════════════
// File export
// ═══════════════════════════════════════════════════════════
TEST(StepExportTest, ExportFile_WritesToDisk) {
auto box = make_box(1, 1, 1);
std::string path = "/tmp/test_vde_export.stp";
export_step_file(path, {box});
std::ifstream in(path);
EXPECT_TRUE(in.good());
std::string content((std::istreambuf_iterator<char>(in)),
std::istreambuf_iterator<char>());
EXPECT_TRUE(content.find("ISO-10303-21;") != std::string::npos);
}
// ═══════════════════════════════════════════════════════════
// Empty model
// ═══════════════════════════════════════════════════════════
TEST(StepExportTest, ExportEmptyModel_ProducesMinimalOutput) {
BrepModel empty;
std::string step = export_step({empty});
EXPECT_TRUE(step.find("ISO-10303-21;") != std::string::npos);
EXPECT_TRUE(step.find("DATA;") != std::string::npos);
}
// ═══════════════════════════════════════════════════════════
// AP214 schema check
// ═══════════════════════════════════════════════════════════
TEST(StepExportTest, UsesAP214Schema) {
auto box = make_box(1, 1, 1);
std::string step = export_step({box});
EXPECT_TRUE(step.find("AUTOMOTIVE_DESIGN") != std::string::npos ||
step.find("AP214") != std::string::npos ||
step.find("10303 214") != std::string::npos);
}