进行剖面盒的bug修复
This commit is contained in:
parent
73c26601fd
commit
9caf3c9461
@ -1963,7 +1963,8 @@ namespace NavisworksTransport.Core.Animation
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 安全获取ModelItem的DisplayName,避免访问已释放对象的警告
|
||||
/// 安全获取ModelItem的显示名称,避免访问已释放对象的警告
|
||||
/// 优先使用ClassName,其次DisplayName
|
||||
/// </summary>
|
||||
/// <param name="item">ModelItem对象</param>
|
||||
/// <returns>安全的显示名称</returns>
|
||||
@ -1976,8 +1977,9 @@ namespace NavisworksTransport.Core.Animation
|
||||
return "NULL";
|
||||
}
|
||||
|
||||
// 尝试访问DisplayName,如果对象已被释放会抛出异常
|
||||
return item.DisplayName ?? "未命名对象";
|
||||
// 优先使用ClassName,其次DisplayName
|
||||
// 某些几何体DisplayName为空但ClassName有值(如"Pipe", "Column"等)
|
||||
return item.ClassName ?? item.DisplayName ?? "未命名对象";
|
||||
}
|
||||
catch (System.ObjectDisposedException)
|
||||
{
|
||||
@ -3952,17 +3954,31 @@ namespace NavisworksTransport.Core.Animation
|
||||
continue; // 跳过该节点及其子节点(剪枝)
|
||||
}
|
||||
|
||||
// 相交:如果是复合对象或有几何数据,加入列表
|
||||
// 相交:处理对象
|
||||
// 🔥 策略:复合对象作为整体添加(有名字),不遍历子节点
|
||||
// 只有独立几何对象(无复合父级)才添加
|
||||
if (item.IsComposite)
|
||||
{
|
||||
objectsInClipBox.Add(item);
|
||||
intersectCount++;
|
||||
// 复合对象不遍历子节点
|
||||
// 复合对象:用棱上采样精筛,排除地基等(自适应采样)
|
||||
bool edgeIntersects = SectionClipHelper.IntersectsByEdgeSampling(itemBox, clipBox, minSamplesPerEdge: 3);
|
||||
|
||||
if (edgeIntersects)
|
||||
{
|
||||
objectsInClipBox.Add(item);
|
||||
intersectCount++;
|
||||
}
|
||||
// 复合对象不遍历子节点(已作为整体添加)
|
||||
}
|
||||
else if (item.HasGeometry)
|
||||
{
|
||||
objectsInClipBox.Add(item);
|
||||
intersectCount++;
|
||||
// 独立几何对象(叶子节点):精筛后添加(自适应采样)
|
||||
bool edgeIntersects = SectionClipHelper.IntersectsByEdgeSampling(itemBox, clipBox, minSamplesPerEdge: 3);
|
||||
|
||||
if (edgeIntersects)
|
||||
{
|
||||
objectsInClipBox.Add(item);
|
||||
intersectCount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -2667,7 +2667,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
|
||||
foreach (var stat in objectStats)
|
||||
{
|
||||
var objectName = stat.Object.DisplayName ?? "未知对象";
|
||||
// 获取对象名称(如果当前节点无名,向上查找有名字的父节点)
|
||||
var objectName = GetEffectiveObjectName(stat.Object);
|
||||
var reason = GetHotspotReason(objectName, stat.Object);
|
||||
|
||||
hotspots.Add(new CollisionHotspotInfo
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@ -1907,8 +1908,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
sb.AppendLine("✅ 剖面盒设置成功(10m x 10m x 5m)");
|
||||
sb.AppendLine();
|
||||
|
||||
// 3. 统计对象数量
|
||||
sb.AppendLine("【3. 对象数量统计】");
|
||||
// 3. 统计对象数量(包围盒相交)
|
||||
sb.AppendLine("【3. 对象数量统计(包围盒相交)】");
|
||||
int totalCount, insideCount, outsideCount;
|
||||
SectionClipHelper.CountObjectsInClipBox(out totalCount, out insideCount, out outsideCount);
|
||||
|
||||
@ -1921,6 +1922,46 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
sb.AppendLine($"过滤率: {filterRate:F1}%");
|
||||
}
|
||||
sb.AppendLine();
|
||||
|
||||
// 3b. 统计对象数量(角点检测)
|
||||
sb.AppendLine("【3b. 对象数量统计(角点检测)】");
|
||||
int totalCount2, insideCount2, outsideCount2, largeBoxFiltered;
|
||||
SectionClipHelper.CountObjectsInClipBoxByCorners(out totalCount2, out insideCount2, out outsideCount2, out largeBoxFiltered);
|
||||
|
||||
sb.AppendLine($"总对象数: {totalCount2}");
|
||||
sb.AppendLine($"剖面盒内(角点): {insideCount2}");
|
||||
sb.AppendLine($"剖面盒外: {outsideCount2}");
|
||||
sb.AppendLine($"大包围盒过滤: {largeBoxFiltered}");
|
||||
if (totalCount2 > 0)
|
||||
{
|
||||
double filterRate2 = (double)outsideCount2 / totalCount2 * 100;
|
||||
sb.AppendLine($"过滤率: {filterRate2:F1}%");
|
||||
}
|
||||
if (largeBoxFiltered > 0)
|
||||
{
|
||||
sb.AppendLine($"⚠️ 发现 {largeBoxFiltered} 个大包围盒对象被过滤(如地基等)");
|
||||
}
|
||||
sb.AppendLine();
|
||||
|
||||
// 3c. 统计对象数量(棱上采样)
|
||||
sb.AppendLine("【3c. 对象数量统计(棱上采样 - 用于检测穿过剖面盒的物体)】");
|
||||
int totalCount3, insideCount3, outsideCount3, edgeMissed;
|
||||
CountObjectsInClipBoxByEdgeSampling(out totalCount3, out insideCount3, out outsideCount3, out edgeMissed);
|
||||
|
||||
sb.AppendLine($"总对象数: {totalCount3}");
|
||||
sb.AppendLine($"剖面盒内(棱采样): {insideCount3}");
|
||||
sb.AppendLine($"剖面盒外: {outsideCount3}");
|
||||
sb.AppendLine($"8角点漏检: {edgeMissed}");
|
||||
if (totalCount3 > 0)
|
||||
{
|
||||
double filterRate3 = (double)outsideCount3 / totalCount3 * 100;
|
||||
sb.AppendLine($"过滤率: {filterRate3:F1}%");
|
||||
}
|
||||
if (edgeMissed > 0)
|
||||
{
|
||||
sb.AppendLine($"✅ 发现 {edgeMissed} 个物体被8角点漏检,但被棱采样检出(如穿过剖面盒的柱子)");
|
||||
}
|
||||
sb.AppendLine();
|
||||
|
||||
// 4. 测试相交检测
|
||||
sb.AppendLine("【4. 相交检测测试】");
|
||||
@ -1957,9 +1998,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
LogManager.Info("剖面盒功能测试完成");
|
||||
UpdateMainStatus("剖面盒测试完成");
|
||||
|
||||
// 显示结果
|
||||
System.Windows.MessageBox.Show(sb.ToString(), "剖面盒功能测试",
|
||||
System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Information);
|
||||
// 显示结果(使用可复制的窗口)
|
||||
ShowCopyableMessageBox(sb.ToString(), "剖面盒功能测试");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -1971,6 +2011,169 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
}, "剖面盒测试");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 显示可复制文本的消息框
|
||||
/// </summary>
|
||||
private void ShowCopyableMessageBox(string message, string title)
|
||||
{
|
||||
var window = new System.Windows.Window
|
||||
{
|
||||
Title = title,
|
||||
Width = 600,
|
||||
Height = 700,
|
||||
WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen,
|
||||
ResizeMode = System.Windows.ResizeMode.CanResize
|
||||
};
|
||||
|
||||
var grid = new System.Windows.Controls.Grid();
|
||||
grid.RowDefinitions.Add(new System.Windows.Controls.RowDefinition { Height = new System.Windows.GridLength(1, System.Windows.GridUnitType.Star) });
|
||||
grid.RowDefinitions.Add(new System.Windows.Controls.RowDefinition { Height = System.Windows.GridLength.Auto });
|
||||
|
||||
// 可滚动的文本框
|
||||
var scrollViewer = new System.Windows.Controls.ScrollViewer
|
||||
{
|
||||
VerticalScrollBarVisibility = System.Windows.Controls.ScrollBarVisibility.Auto,
|
||||
HorizontalScrollBarVisibility = System.Windows.Controls.ScrollBarVisibility.Auto,
|
||||
Margin = new System.Windows.Thickness(10)
|
||||
};
|
||||
|
||||
// 使用 TextBox 以便选择和复制
|
||||
var textBox = new System.Windows.Controls.TextBox
|
||||
{
|
||||
Text = message,
|
||||
IsReadOnly = true,
|
||||
TextWrapping = System.Windows.TextWrapping.Wrap,
|
||||
AcceptsReturn = true,
|
||||
VerticalScrollBarVisibility = System.Windows.Controls.ScrollBarVisibility.Disabled,
|
||||
BorderThickness = new System.Windows.Thickness(0),
|
||||
Background = System.Windows.Media.Brushes.White,
|
||||
FontFamily = new System.Windows.Media.FontFamily("Consolas"),
|
||||
FontSize = 12
|
||||
};
|
||||
|
||||
scrollViewer.Content = textBox;
|
||||
System.Windows.Controls.Grid.SetRow(scrollViewer, 0);
|
||||
grid.Children.Add(scrollViewer);
|
||||
|
||||
// 确定按钮
|
||||
var buttonPanel = new System.Windows.Controls.StackPanel
|
||||
{
|
||||
Orientation = System.Windows.Controls.Orientation.Horizontal,
|
||||
HorizontalAlignment = System.Windows.HorizontalAlignment.Right,
|
||||
Margin = new System.Windows.Thickness(10)
|
||||
};
|
||||
|
||||
var okButton = new System.Windows.Controls.Button
|
||||
{
|
||||
Content = "确定",
|
||||
Width = 80,
|
||||
Height = 28,
|
||||
Margin = new System.Windows.Thickness(5, 0, 0, 0)
|
||||
};
|
||||
okButton.Click += (s, e) => window.Close();
|
||||
|
||||
// 复制按钮
|
||||
var copyButton = new System.Windows.Controls.Button
|
||||
{
|
||||
Content = "复制全部",
|
||||
Width = 80,
|
||||
Height = 28,
|
||||
Margin = new System.Windows.Thickness(0, 0, 5, 0)
|
||||
};
|
||||
copyButton.Click += (s, e) =>
|
||||
{
|
||||
System.Windows.Clipboard.SetText(message);
|
||||
copyButton.Content = "已复制!";
|
||||
System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
copyButton.Content = "复制全部";
|
||||
}), System.Windows.Threading.DispatcherPriority.Background);
|
||||
};
|
||||
|
||||
buttonPanel.Children.Add(copyButton);
|
||||
buttonPanel.Children.Add(okButton);
|
||||
System.Windows.Controls.Grid.SetRow(buttonPanel, 1);
|
||||
grid.Children.Add(buttonPanel);
|
||||
|
||||
window.Content = grid;
|
||||
window.ShowDialog();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 统计对象数量(使用棱上采样检测)
|
||||
/// 能检测穿过剖面盒的物体(如柱子),而8角点检测可能漏检
|
||||
/// </summary>
|
||||
private void CountObjectsInClipBoxByEdgeSampling(out int totalCount, out int insideCount, out int outsideCount, out int edgeMissed)
|
||||
{
|
||||
totalCount = 0;
|
||||
insideCount = 0;
|
||||
outsideCount = 0;
|
||||
edgeMissed = 0;
|
||||
|
||||
try
|
||||
{
|
||||
if (!SectionClipHelper.TryGetCurrentClipBox(out var clipBox))
|
||||
{
|
||||
LogManager.Warning("[剖面盒棱采样统计] 剖面盒未启用");
|
||||
return;
|
||||
}
|
||||
|
||||
var stack = new Stack<ModelItem>();
|
||||
foreach (var model in Autodesk.Navisworks.Api.Application.ActiveDocument.Models)
|
||||
{
|
||||
stack.Push(model.RootItem);
|
||||
}
|
||||
|
||||
while (stack.Count > 0)
|
||||
{
|
||||
var item = stack.Pop();
|
||||
totalCount++;
|
||||
|
||||
BoundingBox3D itemBox = item.BoundingBox();
|
||||
|
||||
// 先检查包围盒是否相交(快速排除)
|
||||
if (!clipBox.Intersects(itemBox))
|
||||
{
|
||||
outsideCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 8角点检测
|
||||
bool hasCornerInside = SectionClipHelper.IntersectsByCornerPoints(itemBox, clipBox);
|
||||
// 棱上采样检测(自适应)
|
||||
bool hasEdgeSampleInside = SectionClipHelper.IntersectsByEdgeSampling(itemBox, clipBox, minSamplesPerEdge: 3);
|
||||
|
||||
if (hasEdgeSampleInside)
|
||||
{
|
||||
insideCount++;
|
||||
// 记录被棱采样检出但8角点漏检的物体
|
||||
if (!hasCornerInside)
|
||||
{
|
||||
edgeMissed++;
|
||||
LogManager.Debug($"[棱采样检出] 8角点漏检但被棱采样检出: {item.DisplayName}, 包围盒: X[{itemBox.Min.X:F2},{itemBox.Max.X:F2}], Y[{itemBox.Min.Y:F2},{itemBox.Max.Y:F2}], Z[{itemBox.Min.Z:F2},{itemBox.Max.Z:F2}]");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
outsideCount++;
|
||||
}
|
||||
|
||||
// 继续遍历子节点
|
||||
foreach (var child in item.Children)
|
||||
{
|
||||
stack.Push(child);
|
||||
}
|
||||
}
|
||||
|
||||
LogManager.Info($"[剖面盒棱采样统计] 总数: {totalCount}, 盒内(棱采样): {insideCount}, 盒外: {outsideCount}, 8角点漏检: {edgeMissed}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[剖面盒棱采样统计] 失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 清理资源和IDisposable实现
|
||||
|
||||
@ -270,6 +270,201 @@ namespace NavisworksTransport.Utils
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用采样点(8个角点)检测对象是否真正与剖面盒相交
|
||||
/// 用于排除大包围盒但实际几何体远离剖面盒的对象(如地基)
|
||||
/// </summary>
|
||||
public static bool IntersectsByCornerPoints(BoundingBox3D itemBox, BoundingBox3D clipBox)
|
||||
{
|
||||
// 获取对象包围盒的8个角点
|
||||
var corners = new Point3D[]
|
||||
{
|
||||
new Point3D(itemBox.Min.X, itemBox.Min.Y, itemBox.Min.Z),
|
||||
new Point3D(itemBox.Min.X, itemBox.Min.Y, itemBox.Max.Z),
|
||||
new Point3D(itemBox.Min.X, itemBox.Max.Y, itemBox.Min.Z),
|
||||
new Point3D(itemBox.Min.X, itemBox.Max.Y, itemBox.Max.Z),
|
||||
new Point3D(itemBox.Max.X, itemBox.Min.Y, itemBox.Min.Z),
|
||||
new Point3D(itemBox.Max.X, itemBox.Min.Y, itemBox.Max.Z),
|
||||
new Point3D(itemBox.Max.X, itemBox.Max.Y, itemBox.Min.Z),
|
||||
new Point3D(itemBox.Max.X, itemBox.Max.Y, itemBox.Max.Z)
|
||||
};
|
||||
|
||||
// 检查是否有任何角点在剖面盒内
|
||||
foreach (var corner in corners)
|
||||
{
|
||||
if (clipBox.Contains(corner))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用棱上自适应采样检测对象是否与剖面盒相交
|
||||
/// 根据物体大小和剖面盒尺寸动态计算采样点数,确保长物体(如管道)不会漏检
|
||||
/// 采样间距小于剖面盒最小边长,确保任何穿过剖面盒的物体都能被检测到
|
||||
/// </summary>
|
||||
/// <param name="itemBox">对象包围盒</param>
|
||||
/// <param name="clipBox">剖面盒</param>
|
||||
/// <param name="minSamplesPerEdge">每条棱的最小采样点数(默认3个)</param>
|
||||
/// <returns>是否有采样点在剖面盒内</returns>
|
||||
public static bool IntersectsByEdgeSampling(BoundingBox3D itemBox, BoundingBox3D clipBox, int minSamplesPerEdge = 3)
|
||||
{
|
||||
// 计算剖面盒的最小边长(作为采样间距上限)
|
||||
double clipBoxMinSize = Math.Min(
|
||||
Math.Min(clipBox.Max.X - clipBox.Min.X, clipBox.Max.Y - clipBox.Min.Y),
|
||||
clipBox.Max.Z - clipBox.Min.Z
|
||||
);
|
||||
|
||||
// 计算物体包围盒的三边长度
|
||||
double itemSizeX = itemBox.Max.X - itemBox.Min.X;
|
||||
double itemSizeY = itemBox.Max.Y - itemBox.Min.Y;
|
||||
double itemSizeZ = itemBox.Max.Z - itemBox.Min.Z;
|
||||
|
||||
// 根据边长动态计算每条棱的采样点数
|
||||
// 采样间距 = 边长 / (采样点数 - 1),确保间距 < 剖面盒最小边长
|
||||
int GetSampleCount(double edgeLength)
|
||||
{
|
||||
if (edgeLength <= 0) return minSamplesPerEdge;
|
||||
// 需要的采样点数 = 边长 / 剖面盒尺寸 + 1,至少minSamplesPerEdge个
|
||||
int count = (int)Math.Ceiling(edgeLength / clipBoxMinSize) + 1;
|
||||
return Math.Max(count, minSamplesPerEdge);
|
||||
}
|
||||
|
||||
int samplesX = GetSampleCount(itemSizeX);
|
||||
int samplesY = GetSampleCount(itemSizeY);
|
||||
int samplesZ = GetSampleCount(itemSizeZ);
|
||||
|
||||
// 12条棱的端点定义(索引对应8个角点)和采样点数
|
||||
// 0: (0,0,0) 1: (0,0,1) 2: (0,1,0) 3: (0,1,1)
|
||||
// 4: (1,0,0) 5: (1,0,1) 6: (1,1,0) 7: (1,1,1)
|
||||
var edges = new (int start, int end, int samples)[]
|
||||
{
|
||||
// X方向棱(4条),用samplesX
|
||||
(0, 4, samplesX), (1, 5, samplesX), (2, 6, samplesX), (3, 7, samplesX),
|
||||
// Y方向棱(4条),用samplesY
|
||||
(0, 2, samplesY), (1, 3, samplesY), (4, 6, samplesY), (5, 7, samplesY),
|
||||
// Z方向棱(4条),用samplesZ
|
||||
(0, 1, samplesZ), (2, 3, samplesZ), (4, 5, samplesZ), (6, 7, samplesZ)
|
||||
};
|
||||
|
||||
// 8个角点的坐标
|
||||
var cornerPoints = new Point3D[]
|
||||
{
|
||||
new Point3D(itemBox.Min.X, itemBox.Min.Y, itemBox.Min.Z),
|
||||
new Point3D(itemBox.Min.X, itemBox.Min.Y, itemBox.Max.Z),
|
||||
new Point3D(itemBox.Min.X, itemBox.Max.Y, itemBox.Min.Z),
|
||||
new Point3D(itemBox.Min.X, itemBox.Max.Y, itemBox.Max.Z),
|
||||
new Point3D(itemBox.Max.X, itemBox.Min.Y, itemBox.Min.Z),
|
||||
new Point3D(itemBox.Max.X, itemBox.Min.Y, itemBox.Max.Z),
|
||||
new Point3D(itemBox.Max.X, itemBox.Max.Y, itemBox.Min.Z),
|
||||
new Point3D(itemBox.Max.X, itemBox.Max.Y, itemBox.Max.Z)
|
||||
};
|
||||
|
||||
// 在每条棱上采样
|
||||
foreach (var edge in edges)
|
||||
{
|
||||
var start = cornerPoints[edge.start];
|
||||
var end = cornerPoints[edge.end];
|
||||
int samples = edge.samples;
|
||||
|
||||
for (int i = 0; i < samples; i++)
|
||||
{
|
||||
double t = (double)i / (samples - 1); // 0.0 到 1.0
|
||||
var samplePoint = new Point3D(
|
||||
start.X + t * (end.X - start.X),
|
||||
start.Y + t * (end.Y - start.Y),
|
||||
start.Z + t * (end.Z - start.Z)
|
||||
);
|
||||
|
||||
if (clipBox.Contains(samplePoint))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 统计对象数量(使用采样点检测)
|
||||
/// 与 CountObjectsInClipBox 的区别:使用8个角点检测,排除大包围盒假阳性
|
||||
/// </summary>
|
||||
public static void CountObjectsInClipBoxByCorners(out int totalCount, out int insideCount, out int outsideCount, out int largeBoxFiltered, List<string> debugDetails = null)
|
||||
{
|
||||
totalCount = 0;
|
||||
insideCount = 0;
|
||||
outsideCount = 0;
|
||||
largeBoxFiltered = 0;
|
||||
|
||||
try
|
||||
{
|
||||
if (!TryGetCurrentClipBox(out var clipBox))
|
||||
{
|
||||
LogManager.Warning("[剖面盒角点统计] 剖面盒未启用");
|
||||
return;
|
||||
}
|
||||
|
||||
var stack = new Stack<ModelItem>();
|
||||
foreach (var model in Application.ActiveDocument.Models)
|
||||
{
|
||||
stack.Push(model.RootItem);
|
||||
}
|
||||
|
||||
while (stack.Count > 0)
|
||||
{
|
||||
var item = stack.Pop();
|
||||
totalCount++;
|
||||
|
||||
BoundingBox3D itemBox = item.BoundingBox();
|
||||
|
||||
// 先检查包围盒是否相交(快速排除)
|
||||
if (!clipBox.Intersects(itemBox))
|
||||
{
|
||||
outsideCount++;
|
||||
continue; // 跳过子节点(剪枝)
|
||||
}
|
||||
|
||||
// 相交:再用角点检测确认
|
||||
bool hasCornerInside = IntersectsByCornerPoints(itemBox, clipBox);
|
||||
|
||||
if (hasCornerInside)
|
||||
{
|
||||
insideCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
outsideCount++;
|
||||
largeBoxFiltered++;
|
||||
|
||||
// 记录被过滤的大对象
|
||||
if (item.HasGeometry)
|
||||
{
|
||||
LogManager.Debug($"[剖面盒角点过滤] 大包围盒但无角点在盒内: {item.DisplayName}, 包围盒: X[{itemBox.Min.X:F2},{itemBox.Max.X:F2}], Y[{itemBox.Min.Y:F2},{itemBox.Max.Y:F2}], Z[{itemBox.Min.Z:F2},{itemBox.Max.Z:F2}]");
|
||||
}
|
||||
|
||||
// 注意:这里继续遍历子节点,因为父对象可能只是外壳,子对象可能在盒内
|
||||
}
|
||||
|
||||
// 继续遍历子节点
|
||||
foreach (var child in item.Children)
|
||||
{
|
||||
stack.Push(child);
|
||||
}
|
||||
}
|
||||
|
||||
LogManager.Info($"[剖面盒角点统计] 总数: {totalCount}, 盒内(角点): {insideCount}, 盒外: {outsideCount}, 大包围盒过滤: {largeBoxFiltered}, " +
|
||||
$"过滤率: {(outsideCount * 100.0 / totalCount):F1}%");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[剖面盒角点统计] 失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试包围盒相交检测(用于验证)
|
||||
/// </summary>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user