Files
ViewDesignEngine/tests/curves/test_iga_prep.cpp
T

152 lines
6.1 KiB
C++
Raw Normal View History

#include <gtest/gtest.h>
#include "vde/curves/iga_prep.h"
#include "vde/curves/nurbs_surface.h"
using namespace vde::curves;
// ═══════════════════════════════════════════════════════════
// Helper: create simple NURBS surfaces
// ═══════════════════════════════════════════════════════════
static NurbsSurface make_plane_surface() {
// 2×2 control points, degree 1×1, flat plane z=0
std::vector<std::vector<Point3D>> cp = {
{Point3D(0,0,0), Point3D(2,0,0)},
{Point3D(0,2,0), Point3D(2,2,0)}
};
std::vector<double> knots_u = {0, 0, 1, 1};
std::vector<double> knots_v = {0, 0, 1, 1};
std::vector<std::vector<double>> weights = {{1,1},{1,1}};
return NurbsSurface(cp, knots_u, knots_v, weights, 1, 1);
}
static NurbsSurface make_quadratic_surface() {
std::vector<std::vector<Point3D>> cp = {
{Point3D(0,0,0), Point3D(1,0,1), Point3D(2,0,0)},
{Point3D(0,1,1), Point3D(1,1,2), Point3D(2,1,1)},
{Point3D(0,2,0), Point3D(1,2,1), Point3D(2,2,0)},
};
std::vector<double> knots_u = {0, 0, 0, 1, 1, 1};
std::vector<double> knots_v = {0, 0, 0, 1, 1, 1};
std::vector<std::vector<double>> weights(3, std::vector<double>(3, 1.0));
return NurbsSurface(cp, knots_u, knots_v, weights, 2, 2);
}
// ═══════════════════════════════════════════════════════════
// NURBS → IGA
// ═══════════════════════════════════════════════════════════
TEST(IGAPrepTest, NurbsToIgaBasic) {
auto surf = make_plane_surface();
IGAMesh iga = nurbs_to_iga(surf);
EXPECT_EQ(iga.degree_u, surf.degree_u());
EXPECT_EQ(iga.degree_v, surf.degree_v());
EXPECT_GT(iga.num_elements, 0);
EXPECT_FALSE(iga.elements.empty());
}
TEST(IGAPrepTest, NurbsToIgaQuadratic) {
auto surf = make_quadratic_surface();
IGAMesh iga = nurbs_to_iga(surf);
EXPECT_EQ(iga.degree_u, 2);
EXPECT_EQ(iga.degree_v, 2);
EXPECT_GT(iga.num_elements, 0);
for (const auto& el : iga.elements) {
EXPECT_GT(el.cp_indices.size(), 0u);
EXPECT_FALSE(el.is_degenerate);
}
}
TEST(IGAPrepTest, NurbsToIgaElementCP) {
auto surf = make_plane_surface();
IGAMesh iga = nurbs_to_iga(surf);
int expected_spans_u = std::max(1, static_cast<int>(iga.knots_u.size()) - 1);
int expected_spans_v = std::max(1, static_cast<int>(iga.knots_v.size()) - 1);
EXPECT_EQ(iga.num_elements, expected_spans_u * expected_spans_v);
}
// ═══════════════════════════════════════════════════════════
// 节点插入
// ═══════════════════════════════════════════════════════════
TEST(KnotInsertionTest, BasicInsert) {
auto surf = make_plane_surface();
std::vector<double> new_u = {0.5};
auto result = knot_insertion(surf, new_u, {});
EXPECT_EQ(result.new_knots_u.size(), 1u);
EXPECT_EQ(result.new_knots_u[0], 0.5);
EXPECT_GT(result.old_cp_count, 0);
}
TEST(KnotInsertionTest, NoKnots) {
auto surf = make_plane_surface();
auto result = knot_insertion(surf, {}, {});
EXPECT_EQ(result.new_knots_u.size(), 0u);
EXPECT_EQ(result.new_knots_v.size(), 0u);
}
TEST(KnotInsertionTest, BothDirections) {
auto surf = make_plane_surface();
auto result = knot_insertion(surf, {0.33, 0.67}, {0.5});
EXPECT_EQ(result.new_knots_u.size(), 2u);
EXPECT_EQ(result.new_knots_v.size(), 1u);
}
// ═══════════════════════════════════════════════════════════
// 升阶
// ═══════════════════════════════════════════════════════════
TEST(DegreeElevationTest, BasicElevation) {
auto surf = make_plane_surface();
auto result = degree_elevation(surf, 1, 1);
EXPECT_EQ(result.old_degree_u, 1);
EXPECT_EQ(result.old_degree_v, 1);
EXPECT_EQ(result.new_degree_u, 2);
EXPECT_EQ(result.new_degree_v, 2);
}
TEST(DegreeElevationTest, NoElevation) {
auto surf = make_plane_surface();
auto result = degree_elevation(surf, 0, 0);
EXPECT_EQ(result.new_degree_u, result.old_degree_u);
EXPECT_EQ(result.new_degree_v, result.old_degree_v);
}
// ═══════════════════════════════════════════════════════════
// Bézier 提取
// ═══════════════════════════════════════════════════════════
TEST(BezierExtractionTest, PlaneExtraction) {
auto surf = make_plane_surface();
auto result = bezier_extraction(surf);
EXPECT_EQ(result.degree_u, surf.degree_u());
EXPECT_EQ(result.degree_v, surf.degree_v());
EXPECT_GT(result.num_elements, 0);
EXPECT_EQ(static_cast<int>(result.operators.size()), result.num_elements);
EXPECT_FALSE(result.cp_coords.empty());
}
TEST(BezierExtractionTest, QuadraticExtraction) {
auto surf = make_quadratic_surface();
auto result = bezier_extraction(surf);
EXPECT_EQ(result.degree_u, 2);
EXPECT_EQ(result.degree_v, 2);
EXPECT_GT(result.num_elements, 0);
if (!result.operators.empty()) {
int n = result.degree_u + 1;
auto& C = result.operators[0];
EXPECT_EQ(static_cast<int>(C.size()), n);
for (const auto& row : C)
EXPECT_EQ(static_cast<int>(row.size()), n);
}
}