STP/STEP 3D viewer (WPF, .NET 8) - CADability + HelixToolkit.Wpf: - Multi-file import (STEP/STL/DXF) with STEP assembly tree (per-node visibility/color cascade, zoom-to) - Measurements: point / distance / edge / face / circle / angle / face-to-face distance (B-rep exact where available) - Assembly verification: two-point align (translate), 3-point align (rotate+translate via RigidAlign), axis rotate 90, interference check (tri-tri intersection + min gap) - Section view (CPU mesh clipping, originals preserved) - mm/inch toggle, CSV export (UTF-8 BOM), 2x PNG screenshot - Performance: per-file merged edge lines, per-leaf merged mesh in browse mode, no BackMaterial on closed solids, edge suspend during camera interaction, parallel leaf triangulation with retry - SmokeTest CLI: import pipeline, --tree, --clip-test, --interference-test, --align-test (all passing) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
67 lines
2.6 KiB
C#
67 lines
2.6 KiB
C#
// 干涉檢查數學驗證:相交 / 分離 / 貼合三種情境
|
||
using System.Windows.Media;
|
||
using System.Windows.Media.Media3D;
|
||
using STPViewer.Services;
|
||
|
||
namespace SmokeTest;
|
||
|
||
internal static class InterferenceTest
|
||
{
|
||
public static int Run()
|
||
{
|
||
int failures = 0;
|
||
|
||
// 兩個互穿的四面體(B 比 A 平移 +5,邊長 10 → 必相交)
|
||
MeshGeometry3D a = Tetra(new Vector3D(0, 0, 0));
|
||
MeshGeometry3D b = Tetra(new Vector3D(5, 0, 0));
|
||
InterferenceResult r1 = InterferenceService.Check(new[] { a }, new[] { b });
|
||
failures += Check("互穿 → 相交", r1.Intersects, true);
|
||
failures += Check("互穿 → 有交線段", r1.Segments.Count > 0, true);
|
||
|
||
// 分離(B 平移 +30,gap 應 ≈ 30 - 10 = 20)
|
||
MeshGeometry3D c = Tetra(new Vector3D(30, 0, 0));
|
||
InterferenceResult r2 = InterferenceService.Check(new[] { a }, new[] { c });
|
||
failures += Check("分離 → 不相交", r2.Intersects, false);
|
||
bool gapOk = Math.Abs(r2.GapDistance - 20.0) < 0.01;
|
||
Console.WriteLine($" {(gapOk ? "PASS" : "FAIL")}: 分離 gap = {r2.GapDistance:F4}(期望 ≈ 20)");
|
||
if (!gapOk) failures++;
|
||
|
||
// 貼合(B 平移 +10,頂點剛好接觸 → 不算穿透、gap ≈ 0)
|
||
MeshGeometry3D d = Tetra(new Vector3D(10, 0, 0));
|
||
InterferenceResult r3 = InterferenceService.Check(new[] { a }, new[] { d });
|
||
failures += Check("貼合 → 不算穿透", r3.Intersects, false);
|
||
bool touchOk = r3.GapDistance < 0.01;
|
||
Console.WriteLine($" {(touchOk ? "PASS" : "FAIL")}: 貼合 gap = {r3.GapDistance:F6}(期望 ≈ 0)");
|
||
if (!touchOk) failures++;
|
||
|
||
Console.WriteLine(failures == 0 ? "InterferenceTest: 全部通過" : $"InterferenceTest: {failures} 項失敗");
|
||
return failures;
|
||
}
|
||
|
||
private static int Check(string name, bool actual, bool expected)
|
||
{
|
||
bool ok = actual == expected;
|
||
Console.WriteLine($" {(ok ? "PASS" : "FAIL")}: {name}({actual})");
|
||
return ok ? 0 : 1;
|
||
}
|
||
|
||
/// <summary>邊長 10 的四面體,offset 平移</summary>
|
||
private static MeshGeometry3D Tetra(Vector3D offset)
|
||
{
|
||
Point3D P(double x, double y, double z) => new Point3D(x, y, z) + offset;
|
||
var m = new MeshGeometry3D
|
||
{
|
||
Positions = new Point3DCollection
|
||
{
|
||
P(0, 0, 0), P(10, 0, 0), P(0, 10, 0), P(0, 0, 10),
|
||
},
|
||
TriangleIndices = new Int32Collection
|
||
{
|
||
0, 1, 2, 0, 1, 3, 0, 2, 3, 1, 2, 3,
|
||
},
|
||
};
|
||
m.Freeze();
|
||
return m;
|
||
}
|
||
}
|