#include #include "vde/brep/brep_drawing.h" #include "vde/brep/modeling.h" #include #include #include using namespace vde::brep; using namespace vde::core; // ═══════════════════════════════════════════════════════════ // generate_views — 基本测试 // ═══════════════════════════════════════════════════════════ TEST(BrepDrawingTest, GenerateViews_Box_ReturnsFourViews) { auto box = make_box(2, 3, 4); auto views = generate_views(box); EXPECT_EQ(views.size(), 4u); EXPECT_EQ(views[0].name, "front"); EXPECT_EQ(views[1].name, "top"); EXPECT_EQ(views[2].name, "right"); EXPECT_EQ(views[3].name, "iso"); } TEST(BrepDrawingTest, GenerateViews_Box_EachViewHasSegments) { auto box = make_box(2, 3, 4); auto views = generate_views(box); for (const auto& v : views) { EXPECT_GT(v.total_segments(), 0u) << "View " << v.name << " should have segments"; } } TEST(BrepDrawingTest, GenerateViews_Box_FrontViewHasExpectedContent) { auto box = make_box(2, 2, 2); auto views = generate_views(box); const auto& front = views[0]; EXPECT_EQ(front.name, "front"); // Front view: XY plane projection, should show X=[-1,1], Y=[-1,1] EXPECT_GT(front.total_segments(), 0u); } TEST(BrepDrawingTest, GenerateViews_Box_ViewDirections) { auto box = make_box(1, 1, 1); auto views = generate_views(box); // Front: looking down -Z EXPECT_NEAR(views[0].view_direction.z(), -1.0, 1e-6); // Top: looking down -Y EXPECT_NEAR(views[1].view_direction.y(), -1.0, 1e-6); // Right: looking down -X EXPECT_NEAR(views[2].view_direction.x(), -1.0, 1e-6); } TEST(BrepDrawingTest, GenerateViews_EmptyBody_ReturnsEmpty) { BrepModel empty; auto views = generate_views(empty); EXPECT_TRUE(views.empty()); } TEST(BrepDrawingTest, GenerateViews_Cylinder_ReturnsFourViews) { auto cyl = make_cylinder(1.0, 3.0, 16); auto views = generate_views(cyl); EXPECT_EQ(views.size(), 4u); for (const auto& v : views) { EXPECT_GT(v.total_segments(), 0u); } } TEST(BrepDrawingTest, GenerateViews_Sphere_ReturnsFourViews) { auto sphere = make_sphere(2.0, 16, 8); auto views = generate_views(sphere); EXPECT_EQ(views.size(), 4u); // 球所有视图的主要轮廓应类似 for (const auto& v : views) { ASSERT_GT(v.total_segments(), 0u); } } // ═══════════════════════════════════════════════════════════ // section_view — 测试 // ═══════════════════════════════════════════════════════════ TEST(BrepDrawingTest, SectionView_Box_AtCenter) { auto box = make_box(4, 4, 4); // 截平面 z = 0(XY 平面,法向量沿 Z) auto view = section_view(box, Point3D(0, 0, 0), Vector3D(0, 0, 1)); EXPECT_EQ(view.name, "section"); // 截面应为矩形轮廓,至少有 4 个交点形成轮廓线段 // + hatch 线,总数应 > 4 ASSERT_GT(view.total_segments(), 4u); } TEST(BrepDrawingTest, SectionView_Box_HorizontalPlane) { auto box = make_box(4, 4, 4); // z = 1 的水平截面(穿过盒子) auto view = section_view(box, Point3D(0, 0, 1), Vector3D(0, 0, 1)); ASSERT_GT(view.total_segments(), 4u); } TEST(BrepDrawingTest, SectionView_Box_PlaneOutside) { auto box = make_box(2, 2, 2); // 截平面在盒子之外(z = 5) auto view = section_view(box, Point3D(0, 0, 5), Vector3D(0, 0, 1)); // 交点不足 3 个 → 无法形成截面 EXPECT_LT(view.total_segments(), 3u); } TEST(BrepDrawingTest, SectionView_EmptyBody_ReturnsEmpty) { BrepModel empty; auto view = section_view(empty, Point3D(0, 0, 0), Vector3D(0, 0, 1)); EXPECT_EQ(view.name, "section"); EXPECT_EQ(view.total_segments(), 0u); } TEST(BrepDrawingTest, SectionView_Cylinder_Midplane) { auto cyl = make_cylinder(2.0, 6.0, 32); // 垂直圆柱的 z=0 截面 → 圆形截面 auto view = section_view(cyl, Point3D(0, 0, 0), Vector3D(0, 0, 1)); ASSERT_GT(view.segments.size(), 3u); } // ═══════════════════════════════════════════════════════════ // DXF 导出 — 测试 // ═══════════════════════════════════════════════════════════ TEST(BrepDrawingTest, ExportDxf_CreatesFile) { auto box = make_box(2, 2, 2); auto views = generate_views(box); const char* filepath = "test_output.dxf"; std::remove(filepath); // 清理旧文件 bool ok = export_dxf(filepath, views); EXPECT_TRUE(ok); // 验证文件存在 std::ifstream in(filepath); EXPECT_TRUE(in.is_open()); std::string content((std::istreambuf_iterator(in)), std::istreambuf_iterator()); in.close(); // 验证关键结构 EXPECT_NE(content.find("SECTION"), std::string::npos); EXPECT_NE(content.find("ENTITIES"), std::string::npos); EXPECT_NE(content.find("LINE"), std::string::npos); EXPECT_NE(content.find("ENDSEC"), std::string::npos); EXPECT_NE(content.find("EOF"), std::string::npos); // 验证有至少一条 LINE 实体 EXPECT_NE(content.find("LINE"), std::string::npos); std::remove(filepath); } TEST(BrepDrawingTest, ExportDxf_HasLayers) { auto box = make_box(2, 2, 2); auto views = generate_views(box); const char* filepath = "test_layers.dxf"; std::remove(filepath); export_dxf(filepath, views); std::ifstream in(filepath); std::string content((std::istreambuf_iterator(in)), std::istreambuf_iterator()); in.close(); EXPECT_NE(content.find("visible"), std::string::npos); EXPECT_NE(content.find("DASHED"), std::string::npos); std::remove(filepath); } TEST(BrepDrawingTest, ExportDxf_EmptyViews_StillWritesSkeleton) { std::vector empty_views; const char* filepath = "test_empty.dxf"; std::remove(filepath); bool ok = export_dxf(filepath, empty_views); EXPECT_TRUE(ok); std::ifstream in(filepath); std::string content((std::istreambuf_iterator(in)), std::istreambuf_iterator()); in.close(); EXPECT_NE(content.find("SECTION"), std::string::npos); EXPECT_NE(content.find("EOF"), std::string::npos); std::remove(filepath); } TEST(BrepDrawingTest, ExportDxf_InvalidPath_ReturnsFalse) { auto box = make_box(1, 1, 1); auto views = generate_views(box); bool ok = export_dxf("/nonexistent_dir_xyz/test.dxf", views); EXPECT_FALSE(ok); } // ═══════════════════════════════════════════════════════════ // 隐藏线 — 测试 // ═══════════════════════════════════════════════════════════ TEST(BrepDrawingTest, HiddenLines_Box_HasHiddenEdges) { auto box = make_box(2, 2, 2); auto views = generate_views(box); // 每个标准视图均应有隐藏边 for (size_t i = 0; i < std::min(views.size(), 3u); ++i) { // 前/俯/右视图都应该有隐藏线 EXPECT_GE(views[i].hidden_lines.size() + views[i].segments.size(), 1u); } } TEST(BrepDrawingTest, DrawSegment_DefaultNotHidden) { DrawSegment seg{0, 0, 1, 1}; EXPECT_FALSE(seg.hidden); } TEST(BrepDrawingTest, DrawSegment_Hidden) { DrawSegment seg{0, 0, 1, 1, true}; EXPECT_TRUE(seg.hidden); } TEST(BrepDrawingTest, ProjectionView_TotalSegments) { ProjectionView v; v.segments = {{0,0,1,0}, {1,0,1,1}}; v.hidden_lines = {{0,1,0,0, true}}; EXPECT_EQ(v.total_segments(), 3u); }