拆分导出为两步:遍历(后台线程)+导出(UI线程)

- SectionBoxExporter 新增 ValidateAndTraverse / ExportTraversalToNwd
- ViewModel 拆为两个 await 间有喘息,避免第二次导出时 UI 线程拥塞
This commit is contained in:
tian 2026-05-18 19:37:58 +08:00
parent b34d17f2d1
commit 595f5225b5
2 changed files with 112 additions and 9 deletions

View File

@ -14,6 +14,8 @@ namespace NavisworksTransport.Core
/// </summary>
public class SectionBoxExporter
{
private SectionBoxTraversalResult _lastTraversal;
/// <summary>
/// 导出结果
/// </summary>
@ -27,6 +29,99 @@ namespace NavisworksTransport.Core
public string ErrorMessage { get; set; }
}
/// <summary>
/// 验证剖面盒并遍历模型树(不含导出,适合后台线程执行)
/// </summary>
public ExportSectionBoxResult ValidateAndTraverse(Document document)
{
var result = new ExportSectionBoxResult();
if (document == null)
{
result.ErrorMessage = "没有活动的文档!";
return result;
}
var viewpoint = document.CurrentViewpoint.Value;
var clipPlanes = viewpoint.ClipPlanes;
if (clipPlanes == null || !clipPlanes.Enabled)
{
result.ErrorMessage = "当前没有活动的剖面盒!";
return result;
}
if (clipPlanes.Mode != ClipPlaneSetMode.Box)
{
result.ErrorMessage = "请切换为剖面盒模式Box 模式)。";
return result;
}
if (!GetSectionBoxBounds(clipPlanes, out BoundingBox3D bounds))
{
result.ErrorMessage = "无法获取剖面盒边界。";
return result;
}
var traversal = GetObjectsAndHiddenItems(document, bounds);
_lastTraversal = traversal;
result.ObjectCount = traversal.ObjectsInBox.Count;
result.HiddenNodeCount = traversal.ItemsToHide.Count;
if (traversal.ObjectsInBox.Count == 0)
{
result.ErrorMessage = "剖面盒内没有找到对象!";
return result;
}
result.Success = true;
return result;
}
/// <summary>
/// 导出遍历结果到 NWD必须在 UI 线程调用)
/// </summary>
public ExportSectionBoxResult ExportTraversalToNwd(Document document, string filePath)
{
var result = new ExportSectionBoxResult();
if (_lastTraversal == null || _lastTraversal.ObjectsInBox.Count == 0)
{
result.ErrorMessage = "没有可导出的遍历结果,请先调用 ValidateAndTraverse。";
return result;
}
result.ObjectCount = _lastTraversal.ObjectsInBox.Count;
result.HiddenNodeCount = _lastTraversal.ItemsToHide.Count;
LogManager.Info($"[SectionBoxExporter] 剖面盒内找到 {result.ObjectCount} 个对象,可隐藏 {result.HiddenNodeCount} 个节点");
try
{
var exportedPath = NwdExportHelper.ExportToNwdWithPrecomputedHiddenItems(
_lastTraversal.ObjectsInBox,
_lastTraversal.ItemsToHide,
filePath,
"剖面盒导出");
if (string.IsNullOrEmpty(exportedPath) || !File.Exists(exportedPath))
{
result.ErrorMessage = "导出失败:未生成文件。";
return result;
}
result.Success = true;
result.FilePath = exportedPath;
result.FileSize = new FileInfo(exportedPath).Length;
}
catch (Exception ex)
{
result.ErrorMessage = $"导出失败:{ex.Message}";
}
return result;
}
/// <summary>
/// 从当前视点导出剖面盒到 NWD完整业务流程验证→遍历→导出
/// </summary>

View File

@ -1946,23 +1946,31 @@ namespace NavisworksTransport.UI.WPF.ViewModels
if (string.IsNullOrEmpty(saveFilePath))
return;
// 委托给业务层:验证剖面盒 → 遍历模型树 → 导出
// 第一步:验证剖面盒 + 遍历模型树(后台线程)
CurrentOperationText = "正在查找剖面盒内的对象...";
var result = await Task.Run(() =>
{
var exporter = new SectionBoxExporter();
return exporter.ExportSectionBoxFromActiveView(document, saveFilePath);
});
var exporter = new SectionBoxExporter();
SectionBoxExporter.ExportSectionBoxResult traverseResult = await Task.Run(() =>
exporter.ValidateAndTraverse(document));
if (result.Success)
if (!traverseResult.Success)
{
MessageBox.Show(traverseResult.ErrorMessage, "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
// 第二步导出UI 线程,内部通过 Dispatcher.Invoke 执行)
CurrentOperationText = "正在导出...";
var exportResult = exporter.ExportTraversalToNwd(document, saveFilePath);
if (exportResult.Success)
{
MessageBox.Show(
$"NWD导出成功\n\n文件: {result.FilePath}\n大小: {result.FileSize / 1024} KB\n对象数: {result.ObjectCount}",
$"NWD导出成功\n\n文件: {exportResult.FilePath}\n大小: {exportResult.FileSize / 1024} KB\n对象数: {exportResult.ObjectCount}",
"导出结果", MessageBoxButton.OK, MessageBoxImage.Information);
}
else
{
MessageBox.Show(result.ErrorMessage, "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
MessageBox.Show(exportResult.ErrorMessage, "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
}
}
catch (Exception ex)