159 lines
6.1 KiB
C++
159 lines
6.1 KiB
C++
|
|
#include <gtest/gtest.h>
|
||
|
|
#include "vde/brep/advanced_blend.h"
|
||
|
|
#include "vde/brep/modeling.h"
|
||
|
|
#include "vde/brep/brep_validate.h"
|
||
|
|
#include "vde/brep/brep.h"
|
||
|
|
#include <cmath>
|
||
|
|
|
||
|
|
using namespace vde::brep;
|
||
|
|
using namespace vde::core;
|
||
|
|
|
||
|
|
// ═══════════════════════════════════════════════
|
||
|
|
// variable_radius_blend 测试 (4项)
|
||
|
|
// ═══════════════════════════════════════════════
|
||
|
|
|
||
|
|
TEST(VariableRadiusBlendTest, BoxEdgeGrowRadius) {
|
||
|
|
auto box = make_box(4, 4, 4);
|
||
|
|
auto result = variable_radius_blend(box, 0, 0.3, 0.8, 16);
|
||
|
|
// Blend adds blend-strip faces → more faces than original
|
||
|
|
EXPECT_GT(result.num_faces(), box.num_faces());
|
||
|
|
EXPECT_GT(result.num_edges(), box.num_edges());
|
||
|
|
EXPECT_GT(result.num_vertices(), 0u);
|
||
|
|
EXPECT_TRUE(result.is_valid());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST(VariableRadiusBlendTest, BoxEdgeShrinkRadius) {
|
||
|
|
auto box = make_box(4, 4, 4);
|
||
|
|
auto result = variable_radius_blend(box, 0, 0.8, 0.3, 12);
|
||
|
|
EXPECT_GT(result.num_faces(), box.num_faces());
|
||
|
|
EXPECT_TRUE(result.is_valid());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST(VariableRadiusBlendTest, BoxEdgeSymmetric) {
|
||
|
|
auto box = make_box(4, 4, 4);
|
||
|
|
// Equal start and end radius → constant-radius blend
|
||
|
|
auto r1 = variable_radius_blend(box, 0, 0.5, 0.5, 8);
|
||
|
|
auto r2 = variable_radius_blend(box, 0, 0.5, 0.5, 16);
|
||
|
|
EXPECT_GT(r1.num_faces(), box.num_faces());
|
||
|
|
// More samples = more blend strips = more faces
|
||
|
|
EXPECT_GT(r2.num_faces(), r1.num_faces());
|
||
|
|
EXPECT_TRUE(r1.is_valid());
|
||
|
|
EXPECT_TRUE(r2.is_valid());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST(VariableRadiusBlendTest, SmallRadiusNearZero) {
|
||
|
|
auto box = make_box(4, 4, 4);
|
||
|
|
auto result = variable_radius_blend(box, 1, 0.05, 0.5, 8);
|
||
|
|
EXPECT_GT(result.num_faces(), box.num_faces());
|
||
|
|
EXPECT_TRUE(result.is_valid());
|
||
|
|
}
|
||
|
|
|
||
|
|
// ═══════════════════════════════════════════════
|
||
|
|
// multi_face_blend 测试 (3项)
|
||
|
|
// ═══════════════════════════════════════════════
|
||
|
|
|
||
|
|
TEST(MultiFaceBlendTest, TwoFaces) {
|
||
|
|
auto box = make_box(4, 4, 4);
|
||
|
|
auto result = multi_face_blend(box, {0, 1}, 0.5);
|
||
|
|
EXPECT_GT(result.num_vertices(), 0u);
|
||
|
|
EXPECT_TRUE(result.is_valid());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST(MultiFaceBlendTest, ThreeFacesCorner) {
|
||
|
|
// Blend 3 faces meeting at a corner — spherical corner fill added
|
||
|
|
auto box = make_box(4, 4, 4);
|
||
|
|
auto result = multi_face_blend(box, {0, 2, 4}, 0.4);
|
||
|
|
EXPECT_GT(result.num_vertices(), 0u);
|
||
|
|
EXPECT_TRUE(result.is_valid());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST(MultiFaceBlendTest, AllFaces) {
|
||
|
|
auto box = make_box(4, 4, 4);
|
||
|
|
std::vector<int> all_faces;
|
||
|
|
for (size_t i = 0; i < box.num_faces(); ++i)
|
||
|
|
all_faces.push_back(static_cast<int>(i));
|
||
|
|
auto result = multi_face_blend(box, all_faces, 0.3);
|
||
|
|
EXPECT_GT(result.num_vertices(), 0u);
|
||
|
|
EXPECT_TRUE(result.is_valid());
|
||
|
|
}
|
||
|
|
|
||
|
|
// ═══════════════════════════════════════════════
|
||
|
|
// rolling_ball_blend 测试 (4项)
|
||
|
|
// ═══════════════════════════════════════════════
|
||
|
|
|
||
|
|
TEST(RollingBallBlendTest, StraightEdge) {
|
||
|
|
auto box = make_box(4, 4, 4);
|
||
|
|
auto result = rolling_ball_blend(box, 0, 0.5, 20);
|
||
|
|
EXPECT_GT(result.num_faces(), box.num_faces());
|
||
|
|
EXPECT_TRUE(result.is_valid());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST(RollingBallBlendTest, ConvexCorner) {
|
||
|
|
// Box edge is a convex corner
|
||
|
|
auto box = make_box(4, 4, 4);
|
||
|
|
auto result = rolling_ball_blend(box, 3, 0.6, 16);
|
||
|
|
EXPECT_GT(result.num_faces(), box.num_faces());
|
||
|
|
EXPECT_TRUE(result.is_valid());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST(RollingBallBlendTest, DifferentEdges) {
|
||
|
|
auto box = make_box(4, 4, 4);
|
||
|
|
// Test rolling ball on first 4 edges
|
||
|
|
for (int ei = 0; ei < 4; ++ei) {
|
||
|
|
auto result = rolling_ball_blend(box, ei, 0.3, 10);
|
||
|
|
EXPECT_GT(result.num_faces(), box.num_faces()) << "edge " << ei;
|
||
|
|
EXPECT_TRUE(result.is_valid()) << "edge " << ei;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST(RollingBallBlendTest, VaryingSamples) {
|
||
|
|
auto box = make_box(4, 4, 4);
|
||
|
|
auto r1 = rolling_ball_blend(box, 0, 0.5, 8);
|
||
|
|
auto r2 = rolling_ball_blend(box, 0, 0.5, 20);
|
||
|
|
// More samples => more blend strip faces
|
||
|
|
EXPECT_GT(r2.num_faces(), r1.num_faces());
|
||
|
|
EXPECT_TRUE(r1.is_valid());
|
||
|
|
EXPECT_TRUE(r2.is_valid());
|
||
|
|
}
|
||
|
|
|
||
|
|
// ═══════════════════════════════════════════════
|
||
|
|
// face_face_blend 测试 (4项)
|
||
|
|
// ═══════════════════════════════════════════════
|
||
|
|
|
||
|
|
TEST(FaceFaceBlendTest, AdjacentFaces) {
|
||
|
|
auto box = make_box(4, 4, 4);
|
||
|
|
// face 0 (-Z) and face 2 (-Y) share an edge
|
||
|
|
auto result = face_face_blend(box, 0, 2, 0.5, 16);
|
||
|
|
EXPECT_GT(result.num_faces(), box.num_faces());
|
||
|
|
EXPECT_TRUE(result.is_valid());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST(FaceFaceBlendTest, DifferentAdjacentPair) {
|
||
|
|
auto box = make_box(4, 4, 4);
|
||
|
|
auto result = face_face_blend(box, 1, 4, 0.4, 12);
|
||
|
|
EXPECT_GT(result.num_faces(), box.num_faces());
|
||
|
|
EXPECT_TRUE(result.is_valid());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST(FaceFaceBlendTest, MultiplePairs) {
|
||
|
|
auto box = make_box(4, 4, 4);
|
||
|
|
auto r1 = face_face_blend(box, 0, 2, 0.3, 8);
|
||
|
|
auto r2 = face_face_blend(box, 1, 4, 0.4, 10);
|
||
|
|
auto r3 = face_face_blend(box, 3, 5, 0.35, 12);
|
||
|
|
EXPECT_GT(r1.num_faces(), box.num_faces());
|
||
|
|
EXPECT_GT(r2.num_faces(), box.num_faces());
|
||
|
|
EXPECT_GT(r3.num_faces(), box.num_faces());
|
||
|
|
EXPECT_TRUE(r1.is_valid());
|
||
|
|
EXPECT_TRUE(r2.is_valid());
|
||
|
|
EXPECT_TRUE(r3.is_valid());
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST(FaceFaceBlendTest, NonSharedEdgeFallback) {
|
||
|
|
// Opposite faces — no shared edge, falls back gracefully
|
||
|
|
auto box = make_box(4, 4, 4);
|
||
|
|
auto result = face_face_blend(box, 0, 1, 0.2, 8);
|
||
|
|
// Should return a valid model (may be original if no common edge)
|
||
|
|
EXPECT_GT(result.num_faces(), 0u);
|
||
|
|
EXPECT_TRUE(result.is_valid());
|
||
|
|
}
|