Files
ViewDesignEngine/tests/curves/test_advanced_intersection.cpp
T
茂之钳 921c29cb22
CI / Build & Test (push) Failing after 33s
CI / Release Build (push) Failing after 29s
Build & Test / build-and-test (push) Has been cancelled
Build & Test / python-bindings (push) Has been cancelled
feat(v7): B-Rep deep attack + Class-A surfacing + CAM deep + performance tuning
v7.1 — B-Rep 深度攻坚 (对标 Parasolid 95%):
- advanced_healing: auto_heal_pipeline, face_splitting/merging, topology_optimization
- watertight_verification, tolerance_analysis, tolerance diagnostic report
- sheet_metal: unfold_sheet_metal (K-Factor/BFS), bend_deduction_table, create_flange
- direct_modeling enhanced: draft_face_advanced (hinge), scale_body (non-uniform), mirror_body
- 32 tests (17 healing + 15 sheet metal), syntax-check passed

v7.2 — Class-A 曲面攻坚 (对标 CGM 95%):
- class_a_surfacing: g3_blend (4-row CP), curvature_matching (Levenberg-Marquardt)
- highlight_lines, reflection_lines, iso_photes, surface_diagnosis, shape_modification
- advanced_intersection: robust_ssi (3-stage: AABB+subdivision→Newton 1e-12→singularity)
- curve_surface_intersection, self_intersection_detection (BVH)
- 30 tests (18 class-A + 12 intersection), zero compile errors

v7.3 — CAM 深化 + 性能优化:
- cam_advanced: adaptive_clearing, trochoidal_milling, rest_machining, pencil_tracing
- tool_holder_collision_check, toolpath_optimization, feed_rate_optimization
- performance_tuning: parallel_task_graph (DAG+Kahn), work_stealing_scheduler
- memory_pool_integration, cache_optimization_hints, profile_guided_layout
- Fixed BrepModel API compatibility (body.bounds()/to_mesh() instead of .faces())
- 20 tests

12 files, ~5200 lines, 82 tests
2026-07-26 22:54:46 +08:00

226 lines
7.0 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/curves/advanced_intersection.h"
#include "vde/curves/nurbs_curve.h"
#include "vde/curves/nurbs_surface.h"
#include <cmath>
using namespace vde::curves;
using namespace vde::core;
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
/// 平面 XY 平面 [0,1]×[0,1]
static NurbsSurface plane_surface() {
std::vector<std::vector<Point3D>> grid = {
{Point3D(0,0,0), Point3D(0,1,0)},
{Point3D(1,0,0), Point3D(1,1,0)}
};
return NurbsSurface(grid, {0,0,1,1}, {0,0,1,1}, {{1,1},{1,1}}, 1, 1);
}
/// 倾斜平面(对角线方向)
static NurbsSurface tilted_plane() {
std::vector<std::vector<Point3D>> grid = {
{Point3D(0,0,0), Point3D(0,1,0.5)},
{Point3D(1,0,0.5), Point3D(1,1,1)}
};
return NurbsSurface(grid, {0,0,1,1}, {0,0,1,1}, {{1,1},{1,1}}, 1, 1);
}
/// 抛物面
static NurbsSurface quad_surface() {
std::vector<std::vector<Point3D>> grid = {
{Point3D(0,0,0), Point3D(0,1,0.5), Point3D(0,2,0)},
{Point3D(1,0,0.5), Point3D(1,1,1), Point3D(1,2,0.5)},
{Point3D(2,0,0), Point3D(2,1,0.5), Point3D(2,2,0)}
};
return NurbsSurface(grid,
{0,0,0,1,1,1}, {0,0,0,1,1,1},
{{1,1,1},{1,1,1},{1,1,1}}, 2, 2);
}
/// 构造简单 NURBS 曲线
static NurbsCurve line(double x0, double y0, double z0, double x1, double y1, double z1) {
return NurbsCurve(
{Point3D(x0, y0, z0), Point3D(x1, y1, z1)},
{0, 0, 1, 1}, {1, 1}, 1);
}
/// 三次 NURBS 曲线
static NurbsCurve cubic_curve() {
return NurbsCurve(
{Point3D(0,0,0), Point3D(1,2,0), Point3D(2,1,0), Point3D(3,0,0)},
{0,0,0,0,1,1,1,1}, {1,1,1,1}, 3);
}
// ---------------------------------------------------------------------------
// Test: Robust SSI — 鲁棒曲面求交
// ---------------------------------------------------------------------------
TEST(AdvancedIntersectionTest, RobustSSI_NonIntersectingPlanes) {
auto a = plane_surface();
// 平面在 Z=5,与 XY 平面无交
std::vector<std::vector<Point3D>> grid2 = {
{Point3D(0,0,5), Point3D(0,1,5)},
{Point3D(1,0,5), Point3D(1,1,5)}
};
auto b = NurbsSurface(grid2, {0,0,1,1}, {0,0,1,1}, {{1,1},{1,1}}, 1, 1);
SSIOptions opts;
auto result = robust_ssi(a, b, opts);
EXPECT_TRUE(result.success);
EXPECT_EQ(0u, result.segments.size());
}
TEST(AdvancedIntersectionTest, RobustSSI_CoincidentPlanes) {
auto a = plane_surface();
auto b = plane_surface(); // 完全相同
auto result = robust_ssi(a, b);
EXPECT_TRUE(result.success);
// 重合面应检测到交线(可能多个)
EXPECT_GT(result.phase1_subdivisions, 0);
}
TEST(AdvancedIntersectionTest, RobustSSI_CrossingPlanes) {
// XY 平面
auto a = plane_surface();
// XZ 平面(法向量为 Y 方向)
std::vector<std::vector<Point3D>> grid2 = {
{Point3D(0,0.5,0), Point3D(0,0.5,1)},
{Point3D(1,0.5,0), Point3D(1,0.5,1)}
};
auto b = NurbsSurface(grid2, {0,0,1,1}, {0,0,1,1}, {{1,1},{1,1}}, 1, 1);
auto result = robust_ssi(a, b);
EXPECT_TRUE(result.success);
// 两相交平面应有交线
EXPECT_GT(result.segments.size(), 0u);
}
TEST(AdvancedIntersectionTest, RobustSSI_PhaseStatistics) {
auto a = tilted_plane();
auto b = plane_surface();
auto result = robust_ssi(a, b);
// 阶段统计应合理
EXPECT_GE(result.phase1_subdivisions, 0);
EXPECT_GE(result.phase2_converged + result.phase2_diverged,
static_cast<int>(result.segments.size()));
EXPECT_GE(result.total_time_ms, 0.0);
}
TEST(AdvancedIntersectionTest, RobustSSI_NewtonPrecision) {
auto a = tilted_plane();
auto b = plane_surface();
SSIOptions opts;
opts.newton_tolerance = 1e-10;
opts.max_newton_iter = 25;
auto result = robust_ssi(a, b, opts);
// 检查结果精度
for (const auto& seg : result.segments) {
for (size_t i = 0; i < seg.points.size(); ++i) {
auto pa = a.evaluate(seg.params_a[i].first, seg.params_a[i].second);
auto pb = b.evaluate(seg.params_b[i].first, seg.params_b[i].second);
EXPECT_LT((pa - pb).norm(), 1e-4);
}
}
}
// ---------------------------------------------------------------------------
// Test: Curve-Surface Intersection — 曲线-曲面求交
// ---------------------------------------------------------------------------
TEST(AdvancedIntersectionTest, CurveSurfaceIntersection_LineThroughPlane) {
auto surf = plane_surface();
auto curve = line(0.5, 0.5, -1, 0.5, 0.5, 2); // 垂直穿过的线
auto pts = curve_surface_intersection(curve, surf);
// 应检测到1个交点
EXPECT_GE(pts.size(), 1u);
if (!pts.empty()) {
EXPECT_NEAR(pts[0].position.z(), 0.0, 1e-4);
}
}
TEST(AdvancedIntersectionTest, CurveSurfaceIntersection_LineParallelToPlane) {
auto surf = plane_surface();
// 平行于 XY 平面的线(在 z=5 处)
auto curve = line(0, 0, 5, 1, 1, 5);
auto pts = curve_surface_intersection(curve, surf);
// 平行线不应有交点(除非重合)
for (const auto& p : pts) {
EXPECT_NEAR(p.position.z(), 5.0, 1e-3);
}
}
TEST(AdvancedIntersectionTest, CurveSurfaceIntersection_SortedByT) {
auto surf = quad_surface();
// 斜穿曲面的线(应在多处相交)
auto curve = line(0.5, 0.5, -1, 1.5, 1.5, 2);
auto pts = curve_surface_intersection(curve, surf);
// 交点应按 t 排序
for (size_t i = 1; i < pts.size(); ++i) {
EXPECT_GE(pts[i].t, pts[i-1].t);
}
}
TEST(AdvancedIntersectionTest, CurveSurfaceIntersection_TangentContact) {
auto surf = plane_surface();
// 在平面内的线
auto curve = line(0, 0, 0, 1, 1, 0);
auto pts = curve_surface_intersection(curve, surf);
// 平面内的线可能有切线接触
// (实现可能返回多个交点或标记为切线)
for (const auto& p : pts) {
EXPECT_NEAR(p.distance, 0.0, 1e-8);
}
}
// ---------------------------------------------------------------------------
// Test: Self-Intersection Detection — 自交检测
// ---------------------------------------------------------------------------
TEST(AdvancedIntersectionTest, SelfIntersection_PlaneNoSelfIntersection) {
auto s = plane_surface();
auto result = self_intersection_detection(s);
// 平面不应自交
EXPECT_FALSE(result.has_self_intersection);
EXPECT_EQ(0u, result.regions.size());
EXPECT_GT(result.total_checks, 0);
}
TEST(AdvancedIntersectionTest, SelfIntersection_QuadSurfaceNoSelfIntersection) {
auto s = quad_surface();
auto result = self_intersection_detection(s, 1e-6);
// 规则曲面不应自交
EXPECT_FALSE(result.has_self_intersection);
EXPECT_GT(result.total_checks, 0);
}
TEST(AdvancedIntersectionTest, SelfIntersection_DetectionTime) {
auto s = quad_surface();
auto result = self_intersection_detection(s, 1e-8);
EXPECT_GE(result.detection_time_ms, 0.0);
EXPECT_GT(result.total_checks, 0);
}