重构剖面盒导出代码

This commit is contained in:
tian 2026-03-11 23:48:01 +08:00
parent 8b4afcfe04
commit e495ea4620
2 changed files with 72 additions and 114 deletions

View File

@ -142,9 +142,9 @@ namespace NavisworksTransport.Core
}
/// <summary>
/// 获取剖面盒内的所有对象
/// 获取剖面盒内的所有对象(公开方法供外部调用)
/// </summary>
private List<ModelItem> GetObjectsInSectionBox(Document document, BoundingBox3D sectionBox)
public List<ModelItem> GetObjectsInSectionBox(Document document, BoundingBox3D sectionBox)
{
var result = new List<ModelItem>();
@ -164,7 +164,7 @@ namespace NavisworksTransport.Core
/// <summary>
/// 递归遍历模型项 - 剪枝策略:遇到几何体就停止向下遍历
/// </summary>
private void TraverseModelItem(ModelItem item, BoundingBox3D sectionBox, List<ModelItem> result)
public void TraverseModelItem(ModelItem item, BoundingBox3D sectionBox, List<ModelItem> result)
{
if (item == null) return;
@ -338,9 +338,9 @@ namespace NavisworksTransport.Core
}
/// <summary>
/// 导出为NWD文件
/// 导出为NWD文件(公开方法供外部调用)
/// </summary>
private string ExportToNwd(Document document, List<ModelItem> objects, string filePath)
public string ExportToNwd(Document document, List<ModelItem> objects, string filePath)
{
// 必须在主线程执行Navisworks API操作
string result = null;
@ -370,6 +370,40 @@ namespace NavisworksTransport.Core
return result;
}
/// <summary>
/// 导出为JSON文件公开方法供外部调用
/// </summary>
public string ExportToJson(Document document, List<ModelItem> objects, string filePath)
{
try
{
// 获取当前剖面盒边界用于JSON中的元数据
var viewpoint = document.CurrentViewpoint.Value;
var clipPlanes = viewpoint.ClipPlanes;
BoundingBox3D sectionBox = default;
if (clipPlanes?.Enabled == true && clipPlanes.Mode == ClipPlaneSetMode.Box && clipPlanes.Box != null)
{
var box = clipPlanes.Box;
sectionBox = new BoundingBox3D(
new Point3D(box.Min.X, box.Min.Y, box.Min.Z),
new Point3D(box.Max.X, box.Max.Y, box.Max.Z)
);
}
var exportData = BuildExportData(sectionBox, objects, document);
string json = JsonConvert.SerializeObject(exportData, Formatting.Indented);
File.WriteAllText(filePath, json);
LogManager.Info($"[SectionBoxExporter] JSON导出完成: {objects.Count} 个对象 -> {filePath}");
return filePath;
}
catch (Exception ex)
{
LogManager.Error($"[SectionBoxExporter] JSON导出失败: {ex.Message}");
return null;
}
}
/// <summary>
/// 显示保存文件对话框
/// </summary>

View File

@ -16,6 +16,8 @@ using Autodesk.Navisworks.Api;
using NavisApplication = Autodesk.Navisworks.Api.Application;
using NavisworksTransport.Utils;
using NavisworksTransport.Core;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace NavisworksTransport.UI.WPF.ViewModels
{
@ -1834,14 +1836,15 @@ namespace NavisworksTransport.UI.WPF.ViewModels
var document = Autodesk.Navisworks.Api.Application.ActiveDocument;
var originalSelection = restoreSelection ? document.CurrentSelection.SelectedItems.ToList() : null;
// 获取保存路径
// 获取保存路径和导出格式
string saveFilePath = null;
bool exportAsJson = false;
System.Windows.Application.Current.Dispatcher.Invoke(() =>
{
var saveDialog = new Microsoft.Win32.SaveFileDialog
{
Title = dialogTitle,
Filter = "Navisworks文件 (*.nwd)|*.nwd",
Filter = "Navisworks文件 (*.nwd)|*.nwd|JSON文件 (*.json)|*.json",
DefaultExt = "nwd",
FileName = defaultFileName
};
@ -1849,6 +1852,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
if (saveDialog.ShowDialog() == true)
{
saveFilePath = saveDialog.FileName;
// 如果用户选择了JSONFilterIndex为2或文件扩展名为json
exportAsJson = (saveDialog.FilterIndex == 2 ||
saveFilePath.EndsWith(".json", StringComparison.OrdinalIgnoreCase));
}
});
@ -1860,67 +1866,27 @@ namespace NavisworksTransport.UI.WPF.ViewModels
bool exportResult = false;
string errorMessage = "";
// 在主线程执行导出显示Navisworks系统进度条
await Task.Run(() =>
// 使用 SectionBoxExporter 进行导出
var exporter = new SectionBoxExporter();
if (exportAsJson)
{
System.Windows.Application.Current.Dispatcher.Invoke(() =>
// JSON导出
await Task.Run(() =>
{
// 设置等待光标
System.Windows.Input.Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;
// 开始Navisworks系统进度条
var progress = Autodesk.Navisworks.Api.Application.BeginProgress(
dialogTitle,
$"正在导出 {items.Count} 个对象到 NWD 文件...");
try
{
CurrentOperationText = $"正在导出 {items.Count} 个对象...";
progress.Update(0.2);
// 收集要导出的项目
var itemsToExport = new ModelItemCollection();
itemsToExport.AddRange(items);
LogManager.Info($"[LayerManagementViewModel] 准备导出 {itemsToExport.Count} 个节点");
progress.Update(0.4);
// 在隔离模式下执行导出,自动恢复可见性
VisibilityHelper.ExecuteInIsolation(itemsToExport, () =>
{
progress.Update(0.6);
// 导出选项
var exportOptions = new Autodesk.Navisworks.Api.NwdExportOptions
{
ExcludeHiddenItems = true,
EmbedXrefs = EmbedXrefs,
PreventObjectPropertyExport = PreventObjectPropertyExport
};
progress.Update(0.8);
document.ExportToNwd(saveFilePath, exportOptions);
exportResult = true;
LogManager.Info("[LayerManagementViewModel] ExportToNwd API调用完成");
});
progress.Update(1.0);
}
catch (Exception ex)
{
LogManager.Error($"[LayerManagementViewModel] 导出异常: {ex.Message}", ex);
errorMessage = ex.Message;
exportResult = false;
}
finally
{
// 确保进度条被关闭
Autodesk.Navisworks.Api.Application.EndProgress();
// 恢复光标
System.Windows.Input.Mouse.OverrideCursor = null;
}
var result = exporter.ExportToJson(document, items, saveFilePath);
exportResult = !string.IsNullOrEmpty(result);
});
});
}
else
{
// NWD导出
await Task.Run(() =>
{
var result = exporter.ExportToNwd(document, items, saveFilePath);
exportResult = !string.IsNullOrEmpty(result);
});
}
// 恢复原始选择(如果需要)
if (restoreSelection && originalSelection != null)
@ -1945,14 +1911,16 @@ namespace NavisworksTransport.UI.WPF.ViewModels
if (File.Exists(saveFilePath))
{
var fileInfo = new FileInfo(saveFilePath);
string format = exportAsJson ? "JSON" : "NWD";
MessageBox.Show(
$"导出成功!\n\n文件: {saveFilePath}\n大小: {fileInfo.Length / 1024} KB",
$"{format}导出成功!\n\n文件: {saveFilePath}\n大小: {fileInfo.Length / 1024} KB",
"导出结果", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
else
{
MessageBox.Show($"导出失败: {errorMessage}", "导出错误", MessageBoxButton.OK, MessageBoxImage.Error);
string format = exportAsJson ? "JSON" : "NWD";
MessageBox.Show($"{format}导出失败: {errorMessage}", "导出错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
catch (Exception ex)
@ -2054,56 +2022,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
/// <summary>
/// 获取剖面盒内的所有对象
/// 获取剖面盒内的所有对象 - 委托给 SectionBoxExporter
/// </summary>
private List<ModelItem> GetObjectsInSectionBox(Document document, BoundingBox3D sectionBox)
{
var result = new List<ModelItem>();
foreach (var model in document.Models)
{
var rootItem = model.RootItem;
if (rootItem != null)
{
TraverseModelItem(rootItem, sectionBox, result);
}
}
return result;
}
/// <summary>
/// 递归遍历模型项 - 剪枝策略
/// </summary>
private void TraverseModelItem(ModelItem item, BoundingBox3D sectionBox, List<ModelItem> result)
{
if (item == null) return;
if (item.IsHidden) return;
// 如果有几何体信息,检查并添加
if (item.HasGeometry)
{
var bbox = item.BoundingBox();
// 检查是否有体积
double sizeX = bbox.Max.X - bbox.Min.X;
double sizeY = bbox.Max.Y - bbox.Min.Y;
double sizeZ = bbox.Max.Z - bbox.Min.Z;
bool hasVolume = sizeX > 0.0001 && sizeY > 0.0001 && sizeZ > 0.0001;
// 有体积且与剖面盒相交才添加
if (hasVolume && BoundingBoxGeometryUtils.BoundingBoxesIntersect(bbox, sectionBox))
{
result.Add(item);
}
return;
}
// 没有几何体,继续遍历子节点
foreach (var child in item.Children)
{
TraverseModelItem(child, sectionBox, result);
}
var exporter = new SectionBoxExporter();
return exporter.GetObjectsInSectionBox(document, sectionBox);
}
/// <summary>