Files
ViewDesignEngine/tests/brep/test_brep_validate.cpp
T

181 lines
7.5 KiB
C++
Raw Normal View History

#include <gtest/gtest.h>
#include "vde/brep/brep.h"
#include "vde/brep/modeling.h"
#include "vde/brep/brep_validate.h"
using namespace vde::brep;
using namespace vde::core;
// ═══════════════════════════════════════════════════════════
// Validation: Basic structural checks
// ═══════════════════════════════════════════════════════════
TEST(BrepValidateTest, ValidateBox_ProducesResult) {
auto box = make_box(2, 3, 4);
auto result = validate(box);
// Box should validate (within the limitations of our non-shared-edge topology)
EXPECT_TRUE(result.total_faces == box.num_faces());
EXPECT_TRUE(result.total_edges == box.num_edges());
}
TEST(BrepValidateTest, ValidateBox_HasEdgeLengthBounds) {
auto box = make_box(2, 2, 2);
auto result = validate(box);
EXPECT_GT(result.max_edge_length, 0.0);
EXPECT_LT(result.min_edge_length, std::numeric_limits<double>::max());
// Box with side 2 should have edges of length ~2
EXPECT_NEAR(result.max_edge_length, 2.0, 0.1);
}
TEST(BrepValidateTest, ValidateBox_ComputesWatertightness) {
auto box = make_box(2, 2, 2);
auto result = validate(box);
EXPECT_GE(result.watertightness, 0.0);
EXPECT_LE(result.watertightness, 1.0);
}
TEST(BrepValidateTest, ValidateBox_ComputesSelfIntersection) {
auto box = make_box(2, 2, 2);
auto result = validate(box);
EXPECT_GE(result.self_intersection_free, 0.0);
EXPECT_LE(result.self_intersection_free, 1.0);
}
TEST(BrepValidateTest, ValidateBox_HasCounts) {
auto box = make_box(2, 2, 2);
auto result = validate(box);
EXPECT_GE(result.total_faces, 0u);
EXPECT_GE(result.total_edges, 0u);
}
// ═══════════════════════════════════════════════════════════
// Validation: Sphere
// ═══════════════════════════════════════════════════════════
TEST(BrepValidateTest, ValidateSphere_ProducesResult) {
auto sphere = make_sphere(2.0);
auto result = validate(sphere);
// Sphere should produce valid counts
EXPECT_GT(result.total_faces, 0u);
EXPECT_GT(result.total_edges, 0u);
}
TEST(BrepValidateTest, ValidateSphere_HasNonZeroEdgeLengths) {
auto sphere = make_sphere(1.0);
auto result = validate(sphere);
EXPECT_GT(result.max_edge_length, 0.0);
}
// ═══════════════════════════════════════════════════════════
// Validation: Cylinder
// ═══════════════════════════════════════════════════════════
TEST(BrepValidateTest, ValidateCylinder_ProducesResult) {
auto cyl = make_cylinder(1.0, 3.0);
auto result = validate(cyl);
EXPECT_GT(result.total_faces, 0u);
}
TEST(BrepValidateTest, ValidateCylinder_ComputesMetrics) {
auto cyl = make_cylinder(1.0, 5.0);
auto result = validate(cyl);
EXPECT_GE(result.watertightness, 0.0);
EXPECT_LE(result.watertightness, 1.0);
EXPECT_GE(result.self_intersection_free, 0.0);
}
// ═══════════════════════════════════════════════════════════
// Validation: Extruded body
// ═══════════════════════════════════════════════════════════
TEST(BrepValidateTest, ValidateExtrude_ProducesResult) {
vde::curves::NurbsCurve profile(
{Point3D(0,0,0), Point3D(1,0,0), Point3D(1,1,0), Point3D(0,1,0)},
{0,0,0,0,1,1,1,1}, {1,1,1,1}, 3);
auto ext = extrude(profile, Vector3D(0, 0, 2));
auto result = validate(ext);
EXPECT_GT(result.total_faces, 0u);
EXPECT_TRUE(ext.is_valid());
}
// ═══════════════════════════════════════════════════════════
// Validation: Empty model
// ═══════════════════════════════════════════════════════════
TEST(BrepValidateTest, ValidateEmptyModel_IsValid) {
BrepModel empty;
auto result = validate(empty);
EXPECT_TRUE(result.valid);
EXPECT_EQ(result.total_faces, 0u);
EXPECT_EQ(result.total_edges, 0u);
}
// ═══════════════════════════════════════════════════════════
// Validation: Result structure
// ═══════════════════════════════════════════════════════════
TEST(BrepValidateTest, ValidationResult_ContainsExpectedFields) {
auto box = make_box(2, 2, 2);
auto result = validate(box);
// Check that all fields are initialized
EXPECT_TRUE(result.valid || !result.valid); // just exists
EXPECT_GE(result.watertightness, 0.0);
EXPECT_GE(result.self_intersection_free, 0.0);
EXPECT_GE(result.min_edge_length, 0.0);
EXPECT_GT(result.max_edge_length, 0.0);
}
TEST(BrepValidateTest, ValidationResult_HasDiagnosticOutput) {
auto box = make_box(2, 2, 2);
auto result = validate(box);
// At minimum, the result structure should have errors/warnings vectors
// (they can be empty)
EXPECT_TRUE(true); // just verifying the struct compiles and runs
}
// ═══════════════════════════════════════════════════════════
// Validation: Detection of dangling edges
// ═══════════════════════════════════════════════════════════
TEST(BrepValidateTest, DanglingEdgeDetection_Works) {
auto box = make_box(2, 2, 2);
auto result = validate(box);
// In a box with non-shared edges (current implementation), there will
// be many dangling edges. This test just verifies the field is computed.
EXPECT_GE(result.dangling_edges, 0u);
EXPECT_GE(result.non_manifold_edges, 0u);
}
// ═══════════════════════════════════════════════════════════
// Validation: Edge count sanity
// ═══════════════════════════════════════════════════════════
TEST(BrepValidateTest, ValidateBox_EdgeCountMatches) {
auto box = make_box(2, 2, 2);
auto result = validate(box);
// total_edges should match body.num_edges()
EXPECT_EQ(result.total_edges, box.num_edges());
}
TEST(BrepValidateTest, ValidateBox_FaceCountMatches) {
auto box = make_box(2, 2, 2);
auto result = validate(box);
EXPECT_EQ(result.total_faces, box.num_faces());
}